{
  "api_version": "v1",
  "dataset_version": "AdityaNet_v2_dataset_r1",
  "dataset_sha256": "43fd0e228b28ae6bc7e468c3acf68722768bd62b73798eb6631e9e6233b71ed9",
  "generated_at": "2026-07-29T13:34:17.768939+00:00",
  "source_commit": "99af630",
  "data": {
    "title": "Data Dictionary \u2014 `AdityaNet_v2_dataset_r1`",
    "date": "2026-07-18",
    "lead": "Every column of every canonical table. **No scientific interpretation** \u2014 field definitions, units, derivations, and missing-value semantics only.\n\n**Universal conventions**\n\n| Convention | Rule |\n|---|---|\n| Time | All timestamps `datetime64[ns, UTC]`, timezone-aware, minute-aligned (T1\u2013T5) |\n| Missing | **NaN only.** Never imputed, filled, interpolated, or dropped. Zero is a valid measurement, never \"missing\" |\n| Quality flags | `q_*` are boolean, **True = problem** |\n| Aggregation | Minute statistics are over **finite observations only**; one NaN never voids a minute; a minute with no finite observation is NaN |\n| Provenance | Every row carries `src_file` + `src_sha256`; joins to T7 |\n| Channels | **Ordinal indices, not energies.** No RMF/ARF exists in the archive; no keV mapping is possible or provided |\n\n---",
    "sections": [
      {
        "heading": "T1 \u2014 `solexs_lc_1min` (610,560 rows \u00b7 424 files)",
        "body": "One row per minute of a SoLEXS observing day. Source: `.lc` (light curve) + `.gti`, SDD2.\n\n| Column | Type | Units | Source / derivation | Allowed values | Missing semantics |\n|---|---|---|---|---|---|\n| `timestamp` | datetime64[ns,UTC] | \u2014 | minute index of the observation day | 1,440/day, monotonic, unique | never missing |\n| `counts_total` | float64 | counts | \u03a3 of `.lc COUNTS` over **finite** seconds in the minute | \u2265 0 | NaN \u27fa no finite second (`q_no_data`) |\n| `live_time_s` | float64 | s | GTI-covered seconds in the minute (**inclusive** endpoints, `STOP\u2212START+1`) | 0 \u2026 60 | never missing; 0 = fully excluded |\n| `rate_total` | float64 | counts/s | `counts_total / live_time_s` | \u2265 0 | NaN where `live_time_s == 0` \u2014 **not imputed** |\n| `gti_fraction` | float64 | \u2014 | `live_time_s / 60` | 0.0 \u2026 1.0 | never missing |\n| `n_seconds_present` | int16 | count | number of **finite** `.lc` seconds in the minute | 0 \u2026 60 | never missing |\n| `q_no_data` | bool | \u2014 | `n_seconds_present == 0` | True/False | flag |\n| `q_partial` | bool | \u2014 | `0 < gti_fraction < 1` | True/False | flag |\n| `detector` | category | \u2014 | SoLEXS detector | `SDD2` only | never missing |\n| `src_file` | object | \u2014 | source `.lc` path | \u2014 | never missing |\n| `src_sha256` | object | \u2014 | SHA-256 of the source archive (Phase 0.5.1 manifest) | 64 hex | never missing |\n| `archive_version` | object | \u2014 | ISSDC archive variant | `v1.0`, `v1.1` | never missing |\n\n> `counts_total` (light curve) is **band-limited** and is **not** \u03a3(T2 `counts`) \u2014 see `SCIENTIFIC_FINDINGS.md` F-1. The two are carried independently; neither is derived from the other."
      },
      {
        "heading": "T2 \u2014 `solexs_spec_1min` (610,560 rows \u00b7 424 files)",
        "body": "One row per minute; the full SoLEXS spectrum. Source: `.pi` (OGIP Type II PHA) + `.gti`, SDD2.\n\n| Column | Type | Units | Source / derivation | Allowed values | Missing semantics |\n|---|---|---|---|---|---|\n| `timestamp` | datetime64[ns,UTC] | \u2014 | minute index | 1,440/day | never missing |\n| `counts` | object \u2192 **array[340]** float64 | counts | per-channel \u03a3 over **finite** seconds in the minute | \u2265 0 per channel | NaN per channel where no finite second |\n| `live_time_s` | float64 | s | GTI-covered seconds (inclusive) | 0 \u2026 60 | never missing |\n| `gti_fraction` | float64 | \u2014 | `live_time_s / 60` | 0.0 \u2026 1.0 | never missing |\n| `n_seconds_present` | int16 | count | finite spectra contributing | 0 \u2026 60 | never missing |\n| `q_no_data` | bool | \u2014 | no finite spectrum in the minute | True/False | flag |\n| `q_partial` | bool | \u2014 | partial GTI coverage | True/False | flag |\n| `detector` | category | \u2014 | SoLEXS detector | `SDD2` | never missing |\n| `chantype` | category | \u2014 | channel type from `CHANTYPE` | `PI` | never missing |\n| `src_file`, `src_sha256`, `archive_version` | object | \u2014 | provenance | \u2014 | never missing |\n\n**Channel axis:** `counts[i]` is PI channel `i`, `i \u2208 [0, 339]` \u2014 an **ordinal** index. **No `channel_energy_keV` column exists, by design:** the archive contains no response matrix, so no channel\u2192energy mapping is possible. Do not assume linearity in energy."
      },
      {
        "heading": "T3 \u2014 `hel1os_lc_1min` (1,027,773 rows \u00b7 373 files)",
        "body": "**LONG form (spec r6): one row per (minute, detector)**, keyed uniquely by that pair. Source: HEL1OS `lightcurve_*.fits`, ownership from the Version Resolution Engine.\n\n| Column | Type | Units | Source / derivation | Allowed values | Missing semantics |\n|---|---|---|---|---|---|\n| `timestamp` | datetime64[ns,UTC] | \u2014 | minute index | \u2014 | never missing |\n| `detector` | object | \u2014 | the detector this row describes | `CZT1`,`CZT2`,`CDTE1`,`CDTE2` | never missing |\n| `{det}_{lo}_{hi}_rate` | float64 | **counts/s** | mean of `CTR` over the minute's samples | \u2265 0 | **NaN when `{det}` \u2260 this row's `detector`** (structural) |\n| `{det}_{lo}_{hi}_stat_err` | float64 | counts/s | mean of `STAT_ERR` | \u2265 0 | as above |\n| `{det}_{lo}_{hi}_n_samples` | float64 | count | samples contributing to the minute | \u2265 1 | as above |\n| `orbit_id` | object | \u2014 | owning orbit (version-resolved) | `HLS_\u2026_V###` | never missing |\n| `orbit_version` | object | \u2014 | orbit product version | `V111`,`V211`,`V112`,`V311` | never missing |\n| `src_file`, `src_sha256`, `archive_version` | object | \u2014 | provenance | \u2014 | never missing |\n\n**Band columns present** (edges parsed from `EXTNAME`, allowlist-validated):\n- **CZT1/CZT2:** `20_40`, `40_60`, `60_80`, `80_150`, `18_160` (keV)\n- **CDTE1/CDTE2:** `5_20`, `20_30`, `30_40`, `40_60`, `1p8_90` (keV; `1p8` = 1.8)\n\n> **Structural NaN:** because the table is long-form, each row populates only its own detector's band columns; the other three detectors' columns are NaN **by construction, not by missing data**. Filter by `detector` before using band columns. A wide view may be derived, but the canonical form is long (spec r6) because ownership is per (minute, detector)."
      },
      {
        "heading": "T4 \u2014 `hel1os_hk_1min` (277,054 rows \u00b7 389 files)",
        "body": "One row per minute of HEL1OS housekeeping. Source: `aux/hk.fits`.\n\n| Column | Type | Units | Derivation | Notes |\n|---|---|---|---|---|\n| `timestamp` | datetime64[ns,UTC] | \u2014 | minute index | never missing |\n| `czt1temp`, `czt2temp`, `cdte1temp`, `cdte2temp` | float64 | \u00b0C | minute **mean** | detector temperatures |\n| `czthvmon`, `cdtehvmon` | float64 | V | minute **mean** | high-voltage monitors |\n| `czt1ctr`, `czt2ctr`, `cdte1ctr`, `cdte2ctr` | float64 | counts/s | minute **mean** | per-detector rate monitors |\n| `czt1enth` | float64 | keV | minute **mean** | energy threshold |\n| `cdte1enerthr`, `cdte2enerthr` | float64 | *(undeclared)* | minute **mean** | energy thresholds; unit not declared in the archive |\n| `cdte1pilectr`, `cdte2pilectr` | float64 | count | minute **max** | pile-up counters |\n| `czt1satctr1`, `czt2satctr1` | float64 | count | minute **max** | saturation counters |\n| `czt1hotpixcnt`, `czt2hotpixcnt` | float64 | count | minute **max** | hot-pixel counters |\n| `sunradeg`, `sundecdeg` | float64 | degrees | minute **mean** | Sun pointing |\n| `fehkstat` | float64 | \u2014 | minute **mean** | front-end housekeeping status word |\n| `suninfov` | bool | \u2014 | minute **min** (conservative: True only if **every** sample is True) | Sun-in-field-of-view |\n| `n_samples` | int64 | count | HK records in the minute | \u2265 1 |\n| `orbit_id`, `src_file`, `src_sha256`, `archive_version` | object | \u2014 | provenance | never missing |\n\n> **Ordering:** the parser preserves **archive (telemetry-arrival) order** and never sorts. Source records contain sub-second out-of-order steps (`SCIENTIFIC_FINDINGS.md` F-3). All aggregations used here are order-independent. A consumer needing chronological order must call `app.v2.utils.timeseries.chronological_sort()` explicitly."
      },
      {
        "heading": "T5 \u2014 `hel1os_spec_1min` (1,026,816 rows \u00b7 373 files)",
        "body": "One row per (minute, detector); HEL1OS spectra. Source: `hel1os_*_spectra_*.fits`.\n\n| Column | Type | Units | Derivation | Allowed values | Missing semantics |\n|---|---|---|---|---|---|\n| `timestamp` | datetime64[ns,UTC] | \u2014 | minute index | \u2014 | never missing |\n| `detector` | object | \u2014 | spectra detector | `CZT1`,`CZT2`,`CDTE1`,`CDTE2` | never missing |\n| `counts` | object \u2192 **array[`detchans`]** float64 | counts | per-channel \u03a3 over finite spectra in the minute | \u2265 0 | NaN per channel where absent |\n| `stat_err` | object \u2192 array[`detchans`] float64 | counts | per-channel \u03a3 of `STAT_ERR` | \u2265 0 | as above |\n| `live_time_s` | float64 | s | \u03a3 `EXPOSURE` of contributing spectra | \u2265 0 | never missing |\n| `n_spectra` | int64 | count | spectra contributing to the minute | \u2265 1 | never missing |\n| `chantype` | category | \u2014 | from `CHANTYPE` | `PHA` | never missing |\n| **`detchans`** | int16 | count | channel-space size \u2014 **carried explicitly (r5)** | **341** (CZT) or **511** (CdTe) | never missing |\n| `orbit_id`, `src_file`, `src_sha256`, `archive_version` | object | \u2014 | provenance | \u2014 | never missing |\n\n> **Three incommensurable channel spaces** (F-4): SoLEXS PI **340**, HEL1OS CZT PHA **341**, HEL1OS CdTe PHA **511**. **Never concatenate `counts` arrays across families or instruments** \u2014 always filter by `detchans`/`detector` first. Channel indices are ordinal; no response matrix exists."
      },
      {
        "heading": "T6 \u2014 `gti_intervals` (2,130 rows \u00b7 1 file)",
        "body": "Long-form good-time intervals, one row per interval.\n\n| Column | Type | Units | Derivation | Notes |\n|---|---|---|---|---|\n| `instrument` | object | \u2014 | source instrument | `solexs` |\n| `detector` | object | \u2014 | detector | `SDD2` (SDD1 contributes no intervals \u2014 F-12 inactive) |\n| `start_utc` | datetime64[ns,UTC] | \u2014 | interval start | **inclusive** |\n| `stop_utc` | datetime64[ns,UTC] | \u2014 | interval stop | **inclusive** |\n| `duration_s` | float64 | s | `stop \u2212 start + 1` (**inclusive** convention) | > 0 always |\n| `src_file`, `src_sha256` | object | \u2014 | provenance | never missing |\n\n> A GTI-excluded second **may** carry a finite count (spec r5). The invariant is one-directional: `NaN(counts) \u21d2 GTI-excluded`. The excess is unexplained (A-14 / F-2)."
      },
      {
        "heading": "T7 \u2014 `provenance_manifest` (5,199 rows \u00b7 1 file)",
        "body": "One row per parsed source file. Every canonical row traces here via `src_file`.\n\n| Column | Type | Derivation | Notes |\n|---|---|---|---|\n| `src_file` | object | source path | join key; unique with (`product`,`detector`) |\n| `src_sha256` | object | archive SHA-256 (Phase 0.5.1 manifest) | 64 hex |\n| `instrument` | object | `solexs` / `hel1os` | \u2014 |\n| `detector` | object | e.g. `SDD1`,`SDD2`,`CZT1`,`CDTE2` | `None` for whole-orbit products |\n| `product` | object | `lc`,`pi`,`gti`,`hk`,`spectra`,`lightcurve`,`events` | \u2014 |\n| `archive_version` | object | `v1.0`,`v1.1`,`V111`,\u2026 | \u2014 |\n| `obs_date` | object | `YYYYMMDD` | \u2014 |\n| `orbit_id` | object | HEL1OS orbit, else `None` | \u2014 |\n| `creator` | object | producing pipeline, from the FITS header | e.g. `solexs_pipeline-1.4` |\n| `processing_date` | object | header `DATE` | `None` for HEL1OS (no `DATE` header) |\n| `rows_in` / `rows_out` | int64 | source rows / emitted rows | `0/0` legal for F-12 inactive detectors |\n| `parser_version` | object | parser identity | `v2-0.5.2` |\n| **`parsed_at_utc`** | object | **build wall-clock time** | **the one non-reproducible field** \u2014 excluded from content hashes |\n| `time_epoch_resolution` | object | resolved time convention | `unix_seconds` (SoLEXS) / `relative_seconds` (HEL1OS spectra) / `mjd_days` |\n| `assumptions_applied` | object \u2192 array[str] | assumptions recorded at parse | audit trail |\n\n---"
      },
      {
        "heading": "Provenance behaviour (all tables)",
        "body": "1. Every canonical row carries `src_file` + `src_sha256`; **no row lacks provenance** (verified: 0 orphans, 0 duplicates, 0 missing).\n2. `src_sha256` is the **archive** SHA-256 from the Phase 0.5.1 manifest \u2014 it pins the input, not the output.\n3. HEL1OS tables additionally carry `orbit_id`, resolved by the Version Resolution Engine per (minute, detector). Two detectors in the same minute may legitimately have different `orbit_id`s at orbit boundaries.\n4. Provenance columns are **not** measurements; they must not be used as features."
      }
    ],
    "source": "artifacts/v2/phase05/DATA_DICTIONARY.md"
  }
}
