edges.io.spectra

Functions for reading lists of spectrum files.

edges.io.spectra.acq_time_ranges(times: Time, max_cycle_duration: Annotated[Quantity, Unit('s')] | None = None, max_gap_factor: float = 1.5) → Time | None[source]

Compute the time range of each switch position from ACQ time stamps.

ACQ files have one time stamp per switch cycle (shared by all switch positions), marking the start of the cycle. Each cycle is taken to last until the next cycle starts, and is split equally between its switch positions, in order. The resulting time ranges tile the observation with no gaps or overlaps.

The last cycle has no following time stamp, and a gap in the data (e.g. between files, or from dropped cycles) would make a cycle look too long. These cycles, and any whose following time stamp is not later than its own, are assigned the median cycle duration instead. The median is taken over cycles no longer than max_cycle_duration, so that it is not set by the gaps between files when each file has only a few cycles.

Parameters:
  • times – The time stamps of the data, with shape (ntimes, nloads), where the loads are in the order of the switch positions.

  • max_cycle_duration – The longest plausible cycle. Longer intervals between time stamps are treated as gaps. By default, there is no limit.

  • max_gap_factor – Cycles longer than this factor times the median cycle duration are assigned the median duration.

Returns:

Time or None – The time ranges, with shape (ntimes, nloads, 2). None if the cycle duration cannot be determined, i.e. no two consecutive time stamps are a plausible cycle apart.

edges.io.spectra.get_acq_integration_time(meta: dict) → Annotated[Quantity, Unit('s')] | None[source]

Get the effective integration time per switch position from an ACQ header.

This is the number of ADC samples accumulated into each spectrum divided by the sampling rate. It does not include switching or processing overhead, so it is shorter than the wall-clock time spent on each switch position.

Parameters:

meta – The header of the file, as returned by read_acq_header().

Returns:

Quantity or None – The integration time, or None if the header does not define it (e.g. for files written by pxspec).

edges.io.spectra.infer_telescope_from_acq_header(meta: dict) → str | None[source]

Infer the telescope that wrote an ACQ file from its header, if possible.

Only EDGES-3 at MRO (edges3) and on Devon Island (edges3-devon) can be identified. Files written by pxspec have no header, and fastspec headers from EDGES-2, lab measurements and other EDGES-3 systems do not identify a telescope that has a preset in KNOWN_TELESCOPES.

Parameters:

meta – The header of the file, as returned by read_acq_header().

Returns:

str or None – The key of the telescope in KNOWN_TELESCOPES, or None if it cannot be determined.

edges.io.spectra.read_acq_header(path: str | Path) → dict[source]

Read the metadata header of an ACQ file.

Parameters:

path – The ACQ file to read.

Returns:

dict – The header items. Files written by fastspec have entries such as site, instrument, datadir, samples_per_accumulation and acquisition_rate. Older files written by pxspec have no header, so these entries are missing.

edges.io.spectra.read_spectra(files: Sequence[Path], telescope: Telescope | str | None = None) → GSData[source]

Read common spectrum file formats.

Parameters:
  • files – The files to read. All must have the same format, and they are concatenated along the time axis.

  • telescope – The telescope that took the data, either as a pygsdata.Telescope or the name of one in KNOWN_TELESCOPES. Only used for .acq files (other formats store the telescope). If not given, it is inferred from the header of each .acq file (see infer_telescope_from_acq_header()). If that fails, edges-low is assumed and a warning is raised.

Returns:

GSData – The data. For .acq files, the time ranges are derived from the time stamps (see acq_time_ranges()), and for files written by fastspec the effective integration time is read from the header. Neither is taken from the telescope, except as a fallback.