NNJAObsSat¶
Global
Import path: earth2studio.data.NNJAObsSat
Documentation¶
NNJA historical NCEP aggregate satellite observations.
This source reads the NCEP satellite microwave (ATMS, MHS, AMSU-A,
AMSU-B) and hyperspectral infrared sounder (AIRS, IASI, CrIS) BUFR
products from the NNJA archive. It returns one long-format row per
decoded channel, a missing value being a null observation.
sensor_index is the physical CHNM channel number, not a dense index
into a selected channel list.
The IR sounders are returned in brightness temperature (K) regardless of
how the archive stores them: AIRS is encoded as brightness temperature
(TMBR) directly, while IASI (scaled integer radiance, SCRA) and
CrIS (float radiance, SRAD) are converted via Planck inversion. The
wavenumber column carries the channel centre wavenumber in cmโปยน,
computed from the instrument grids for IASI/CrIS and looked up per channel
for ATMS (SCCF) and AIRS (LOGRCW) from the values the aggregates
encode; it is null for MHS, AMSU-A and AMSU-B.
The aggregates carry the NCEP channel subsets (281 AIRS, 616 IASI, 431
CrIS) numbered on the instrument grids; cris routes to the
full-spectral-resolution crisf4 product whose channel numbers live
on the 2211-channel FSR grid; SAT_CHANNELS in
earth2studio.data.utils_ncep lists them. Archive periods: AMSU-A and
AMSU-B from 1998-10-26 (AMSU-B to 2014-06-06), MHS from 2005-02-01T12, ATMS
from 2012-02-15, AIRS 2002-08-31 to 2023-01-18T06 (NASA/Aqua route), IASI from
2008-01-01, CrIS (FSR) from 2018-01-16T18. A cycle outside its sensor's period
is skipped like a missing file, with one warning per sensor; a request with no
cycle in the period returns an empty frame. available(time, sensor) checks
the period.
All archived channels are returned by default; pass sensor_indices to
narrow at decode time or subset downstream via the sensor_index
column.
atms returns the encoded 22-channel TMBR scene brightness
temperature. atms_antenna_temperature returns the corresponding
encoded TMANT antenna temperature. No conversion is performed between
those two ATMS products.
mhs (5 channels), amsua (15 channels), and amsub (5 channels)
return their normal-feed TMBR values as encoded by NCEP. For these
legacy products the mnemonic does not always mean the same physical
antenna-correction state. GSI treats normal-feed TMBR as antenna
temperature for AMSU-A, AMSU-B, and MHS, except for NOAA-15/16, which its
reader treats as already converted upstream. NOAA satingest independently
confirms that exception for AMSU-A. The platform identity is retained so a
downstream transform can apply the appropriate convention explicitly.
scan_position is the one-based cross-track position: the encoded
FOVN for the microwave sensors, AIRS (1-90), and IASI (1-120, a
composite of 30 fields of regard x 4 detectors), and the encoded
FORN (1-30) for CrIS, whose FOVN, the 1-9 detector index within
the 3x3 field of regard, is the detector column (null for the other
sensors). scan_angle is
the signed nominal instrument look angle derived from the FOV for the
microwave sensors; it is always null for the IR sounders, whose scan
geometry is sensor-specific โ use satellite_za (the unsigned
Earth-view zenith magnitude) for view-angle screening.
elev (surface elevation) is populated only for CrIS, whose template
carries HOLS; the AIRS and IASI templates carry no surface-elevation
field at all, so elev is null for them. (Their SELV field is the
platform's orbital altitude, ~700-840 km, and must not be mistaken for
surface elevation.) scan_line is the encoded SLNM, a
granule-local counter that repeats within a cycle file; pair it with
time to address a scan.
quality carries the per-channel provider flags. The footprint-level
flags are scan_quality (ATMS 0-33-080, CrIS NSQF),
granule_quality (ATMS 0-33-079) and footprint_quality (IASI
QGFQ), each as encoded and null for sensors whose template lacks it.
Parameters:
-
time_tolerance(TimeTolerance, default:timedelta64(10, 'm')) โTime tolerance window for filtering observations. Accepts a single value (symmetric +/- window) or a tuple (lower, upper) for asymmetric windows, by default np.timedelta64(10, 'm').
-
satellites(list[str] | None, default:None) โSatellite platforms to include.
Noneincludes every platform in the requested aggregate files. -
cache(bool, default:True) โCache downloaded files in the local filesystem cache, by default True.
-
verbose(bool, default:True) โShow progress bars, by default True.
-
async_timeout(int, default:600) โTimeout in seconds for downloading the files, by default 600. Decoding them is not bounded.
-
async_workers(int, default:8) โMaximum number of concurrent async fetch tasks, by default 8.
-
decode_workers(int, default:8) โNumber of threads transforming decoded BUFR batches, by default 8. Decoding runs on earth2bufr's process-wide thread pool. Unless
EARTH2BUFR_NUM_THREADSis set, the first fetch sets it to 8 threads, the fastest setting measured on 16-112 cores. -
retries(int, default:3) โNumber of retry attempts per failed fetch task with exponential backoff, by default 3.
-
sensor_indices(dict[str, Sequence[int]] | None, default:None) โPer-sensor channel-number subsets for the IR sounders, e.g.
{"cris": [19, 24], "iasi": [16]}. Named after thesensor_indicesselection of the JPSS/METOP sources and applied at decode time like theirs, but keyed per sensor since this source spans several instruments. Selections must be non-empty, unique channel numbers the sensor's archive carries (SAT_CHANNELS). Sensors absent from the dict (and all microwave sensors) return every archived channel. By default None (all channels). -
layout(('long', 'wide'), default:"long") โ"long"returns one row per (footprint, channel) with the columns ofSCHEMA."wide"returns one sensor per call, one row per footprint: the footprint columns ofSCHEMAthat sensor fills and its per-channel values as fixed-size lists over its channel axis (sensor_indices[sensor]ascending, else every archived channel),qualityand oneobservation_<variable>per variable, null in a slot whose channel the footprint lacks. [channel_axis][earth2studio.data.utils_ncep.channel_axis] returns a frame's axis; the wavenumber follows from the channel number. Request several sensors concurrently, one call each, e.g.asyncio.gather(*(source.fetch(time, [s]) for s in sensors)); the calls share the source's decode slots. By default "long".
Warning
Aggregate cycle files contain millions of footprints, and hyperspectral
IR requests return one long-format row per (footprint, channel). At all
channels a single 6-hour cycle is on the order of 10โธ-10โน rows per
sensor (CrIS ~940 M across its three platforms, IASI ~400 M, AIRS
~210 M), which does not fit in memory on ordinary machines. All-channel
requests are for narrow time windows and diagnostics; use
sensor_indices to select a channel subset for anything larger โ the
narrowing is applied before rows are built, so a 32-channel CrIS
request costs roughly 32/431 of the above. A finite archived value is
not a QC decision: historical files may retain passive or degraded
channels even when the aggregate carries no usable quality flag.
Training pipelines should apply an explicit platform/channel validity
policy.
Note
Additional information on the archive and microwave product semantics:
- psl.noaa.gov/data/nnja_obs/
- registry.opendata.aws/noaa-reanalyses-pds/
- github.com/NOAA-EMC/GSI/blob/860d13740352004fca0136a8c3d0ac9dea30e0da/src/gsi/read_bufrtovs.f90#L754-L823
- github.com/NOAA-EMC/GSI/blob/860d13740352004fca0136a8c3d0ac9dea30e0da/src/gsi/radinfo.f90#L1523-L1643
- github.com/NOAA-EMC/satingest/blob/3bb883d931d2cbdbd8c5871c30ac25941918c882/ush/ingest_script_atovs1b.sh#L188-L231
- github.com/NOAA-EMC/satingest/blob/3bb883d931d2cbdbd8c5871c30ac25941918c882/sorc/bufr_tranamsua.fd/tranamsua.f#L887-L910
- www.star.nesdis.noaa.gov/jpss/documents/ATBD/D0001-M01-S01-001_JPSS_ATBD_ATMS_SDR_D.pdf
- user.eumetsat.int/s3/ope-eup-strapi-media/ATOVS_Level_1b_Product_Guide_f89971ac20.pdf
- www.ncei.noaa.gov/pub/data/cdo/documentation/podguides/N-15%20thru%20N-19/pdf/APPENDIX%20J%20Instrument%20Scan%20Properties.pdf
__call__ ¶
__call__(
time: datetime | list[datetime] | TimeArray,
variable: str | list[str] | VariableArray,
fields: str | list[str] | Schema | None = None,
) -> DataFrame
Fetch observations for a set of timestamps.
fetch
async
¶
fetch(
time: datetime | list[datetime] | TimeArray,
variable: str | list[str] | VariableArray,
fields: str | list[str] | Schema | None = None,
) -> DataFrame
Async function to get data.
available
classmethod
¶
available(
time: datetime | datetime64, sensor: str | None = None
) -> bool
Check if given date time is available, for sensor if given.
A time is available for a sensor when its cycle file (the nearest six-hourly cycle) lies in the sensor's archive period. Only the period is checked, not whether that file exists.
Parameters:
-
time(datetime | datetime64) โDate time to check
-
sensor(str | None, default:None) โSensor, e.g.
"airs", by default None (any)
Returns:
-
boolโIf date time is available
Raises:
-
ValueErrorโIf
sensoris not an NNJA satellite sensor