diff --git a/changelog/187.bugfix.rst b/changelog/187.bugfix.rst new file mode 100644 index 00000000..2be113cf --- /dev/null +++ b/changelog/187.bugfix.rst @@ -0,0 +1,4 @@ +Fix metadata key mismatch between ``SpectrogramFactory`` and ``RFSSpectrogram``. +The factory stored CDF global attributes under ``"cdf_globals"`` but ``RFSSpectrogram.level`` +and ``RFSSpectrogram.version`` expected ``"cdf_meta"``, causing a ``KeyError`` when accessing +these properties on spectrograms created from real CDF files. diff --git a/radiospectra/spectrogram/sources/psp_rfs.py b/radiospectra/spectrogram/sources/psp_rfs.py index 8e0fb848..a50c07e7 100644 --- a/radiospectra/spectrogram/sources/psp_rfs.py +++ b/radiospectra/spectrogram/sources/psp_rfs.py @@ -26,11 +26,17 @@ def __init__(self, data, meta, **kwargs): @property def level(self): - return self.meta["cdf_meta"]["Data_type"].split(">")[0] + data_type = self.meta["cdf_meta"]["Data_type"] + if isinstance(data_type, list) or hasattr(data_type, "tolist"): + data_type = data_type[0] + return data_type.split(">")[0] @property def version(self): - return int(self.meta["cdf_meta"]["Data_version"]) + data_version = self.meta["cdf_meta"]["Data_version"] + if isinstance(data_version, list) or hasattr(data_version, "tolist"): + data_version = data_version[0] + return int(data_version) @classmethod def is_datasource_for(cls, data, meta, **kwargs): diff --git a/radiospectra/spectrogram/sources/tests/test_psp_rfs.py b/radiospectra/spectrogram/sources/tests/test_psp_rfs.py index 15e9f1f3..1fdb8aaa 100644 --- a/radiospectra/spectrogram/sources/tests/test_psp_rfs.py +++ b/radiospectra/spectrogram/sources/tests/test_psp_rfs.py @@ -227,3 +227,25 @@ def test_psp_rfs_hfr(parse_path_moc): assert spec.wavelength.max == 19171.876 * u.kHz assert spec.level == "L2" assert spec.version == 1 + + +import pytest + +from sunpy.net import Fido + +import radiospectra.net # NOQA + + +@pytest.mark.remote_data +def test_psp_rfs_real_data(): + """ + Test that reading a real PSP RFS file successfully parses the metadata dictionary + and allows access to properties like 'level' without throwing a KeyError. + + This ensures that the SpectrogramFactory outputs 'cdf_meta' rather than 'cdf_globals'. + """ + query = Fido.search(a.Time("2020/01/01", "2020/01/31"), a.Instrument("rfs")) + files = Fido.fetch(query[0, 0]) + spec = Spectrogram(files[0]) + assert spec.level == "L2" + assert spec.version is not None diff --git a/radiospectra/spectrogram/spectrogram_factory.py b/radiospectra/spectrogram/spectrogram_factory.py index 70d3fad6..c7dd27d2 100644 --- a/radiospectra/spectrogram/spectrogram_factory.py +++ b/radiospectra/spectrogram/spectrogram_factory.py @@ -430,7 +430,7 @@ def _read_cdf(file): freqs = freqs[0, :] << u.Hz data = data.T << u.Unit("Volt**2/Hz") meta = { - "cdf_globals": cdf_globals, + "cdf_meta": cdf_globals, "detector": detector, "instrument": "FIELDS/RFS", "observatory": "PSP", @@ -458,7 +458,7 @@ def _read_cdf(file): data = np.squeeze(data).T << sfu detector = cdf_globals.get("Instrument", [""])[0].split(">")[0] meta = { - "cdf_globals": cdf_globals, + "cdf_meta": cdf_globals, "detector": detector, "instrument": "RPW", "observatory": "SOLO", @@ -561,7 +561,7 @@ def _read_cdf(file): res = [] if np.any(agc1): meta1 = { - "cdf_globals": cdf_globals, + "cdf_meta": cdf_globals, "detector": "RPW-AGC1", "instrument": "RPW", "observatory": "SOLO", @@ -574,7 +574,7 @@ def _read_cdf(file): res.append((specs[0].T, meta1)) if np.any(agc2): meta2 = { - "cdf_globals": cdf_globals, + "cdf_meta": cdf_globals, "detector": "RPW-AGC2", "instrument": "RPW", "observatory": "SOLO",