diff --git a/imap_processing/ancillary/ancillary_dataset_combiner.py b/imap_processing/ancillary/ancillary_dataset_combiner.py index 01819a9d12..104255f876 100644 --- a/imap_processing/ancillary/ancillary_dataset_combiner.py +++ b/imap_processing/ancillary/ancillary_dataset_combiner.py @@ -338,7 +338,7 @@ def __init__( ): super().__init__(ancillary_input, expected_end_date) - def convert_file_to_dataset(self, filepath: str | Path) -> xr.Dataset: + def convert_file_to_dataset(self, filepath: str | Path) -> xr.Dataset: # noqa: PLR0911 """ Convert GLOWS ancillary .dat files to xarray datasets. @@ -364,6 +364,19 @@ def convert_file_to_dataset(self, filepath: str | Path) -> xr.Dataset: if "excluded-regions" in filename: # Handle excluded regions (2 columns: longitude, latitude) data = np.loadtxt(filepath, comments="#") + if data.size == 0: + return xr.Dataset( + { + "ecliptic_longitude_deg": ( + ["region"], + np.array([], dtype=float), + ), + "ecliptic_latitude_deg": ( + ["region"], + np.array([], dtype=float), + ), + } + ) return xr.Dataset( { "ecliptic_longitude_deg": (["region"], data[:, 0]), @@ -412,6 +425,19 @@ def convert_file_to_dataset(self, filepath: str | Path) -> xr.Dataset: } ) + elif "l2-calibration" in filename: + # Handle calibration file (timestamp + cps_per_R float value) + with open(filepath) as f: + lines = [line.strip() for line in f if not line.startswith("#")] + identifiers = [line.split(" ", 1)[0] for line in lines] + values = [float(line.split(" ", 1)[1]) for line in lines] + return xr.Dataset( + { + "start_time_utc": (["time_block"], identifiers), + "cps_per_r": (["time_block"], values), + } + ) + elif filename.endswith(".json"): # Handle pipeline settings JSON file using the generic read_json method return self.convert_json_to_dataset(filepath) diff --git a/imap_processing/tests/ancillary/test_ancillary_dataset_combiner.py b/imap_processing/tests/ancillary/test_ancillary_dataset_combiner.py index fb45059fab..f7d3f0020e 100644 --- a/imap_processing/tests/ancillary/test_ancillary_dataset_combiner.py +++ b/imap_processing/tests/ancillary/test_ancillary_dataset_combiner.py @@ -236,6 +236,19 @@ def test_glows_excluded_regions_combiner(glows_ancillary_filepath): assert dataset["ecliptic_latitude_deg"].dims == ("region",) +def test_glows_excluded_regions_combiner_empty_file(tmp_path): + file_path = tmp_path / "imap_glows_l1b-map-of-excluded-regions_20251112_v001.dat" + file_path.write_text("# header only\n") + + combiner = GlowsAncillaryCombiner([], "20251115") + dataset = combiner.convert_file_to_dataset(file_path) + + assert "ecliptic_longitude_deg" in dataset.data_vars + assert "ecliptic_latitude_deg" in dataset.data_vars + assert len(dataset["ecliptic_longitude_deg"]) == 0 + assert len(dataset["ecliptic_latitude_deg"]) == 0 + + def test_glows_uv_sources_combiner(glows_ancillary_filepath): file_path = ( glows_ancillary_filepath / "imap_glows_map-of-uv-sources_20250923_v002.dat" @@ -300,6 +313,21 @@ def test_glows_exclusions_by_instr_team_combiner(glows_ancillary_filepath): assert combiner.timestamped_data[0].version == "v002" +def test_glows_l2_calibration_combiner(tmp_path): + file_path = tmp_path / "imap_glows_l2-calibration_20251112_v001.dat" + file_path.write_text( + "# header\n2025-11-13T18:12:48 1.020\n2025-11-14T09:58:04 0.849\n" + ) + + combiner = GlowsAncillaryCombiner([], "20251115") + dataset = combiner.convert_file_to_dataset(file_path) + + assert "start_time_utc" in dataset.data_vars + assert "cps_per_r" in dataset.data_vars + assert len(dataset["cps_per_r"]) == 2 + assert dataset["cps_per_r"].values[0] == pytest.approx(1.020) + + def test_ancillary_combiner_empty_input(): """Test AncillaryCombiner with empty input list.""" combiner = AncillaryCombiner([], "20251031")