Creating a CDF FileΒΆ
This module provides an example for creating a CDF File using the HermesData
class. This class is an abstraction of underlying data structures to make the handling of
measurement data easier when reading and writing CDF data.
>>> from pathlib import Path
>>> from collections import OrderedDict
>>> import numpy as np
>>> import astropy.units as u
>>> from astropy.timeseries import TimeSeries
>>> from astropy.nddata import NDData
>>> from astropy.wcs import WCS
>>> from ndcube import NDCube, NDCollection
>>> import tempfile
>>>
>>> # Import the `hermes_core` Package
>>> from hermes_core.timedata import HermesData
>>>
>>> # Create a np.ndarray of example measurement data
>>> bx = np.random.choice(a=[-1, 0, 1], size=1000).cumsum(0)
>>> by = np.random.choice(a=[-1, 0, 1], size=1000).cumsum(0)
>>>
>>> # Create a TimeSeries with the example measurement and a Time column
>>> ts = TimeSeries(
... time_start="2016-03-22T12:30:31",
... time_delta=3 * u.s,
... data={"Bx GSE": u.Quantity(value=bx, unit="nanoTesla", dtype=np.int16)},
... )
>>>
>>> # You can also add new measurements to the TimeSeries directly
>>> ts.add_column(col=u.Quantity(value=by, unit="nanoTesla", dtype=np.int16),
... name="By GSE"
... )
>>>
>>> # Create support data or non-time-varying (time invariant) data
>>> support_data = {
... "data_mask": NDData(data=np.eye(100, 100, dtype=np.uint16), meta={"CATDESC": "Data Mask", "VAR_TYPE": "metadata"})
... }
>>>
>>> # Create high-dimensional data leveraging the API of NDCube
>>> spectra = NDCollection(
... [
... (
... "example_spectra",
... NDCube(
... data=np.random.random(size=(1000, 10)),
... wcs=WCS(naxis=2),
... meta={"CATDESC": "Example Spectra Variable"},
... unit="eV",
... ),
... )
... ]
... )
>>>
>>> # To make the creation of global metadata easier you can use the static
>>> # `HermesData.global_attribute_template()` function.
>>> global_attrs_template = HermesData.global_attribute_template()
>>>
>>> global_attrs_template["DOI"] = "https://doi.org/<PREFIX>/<SUFFIX>"
>>> global_attrs_template["Data_level"] = "L1>Level 2"
>>> global_attrs_template["Data_version"] = "0.0.1"
>>> global_attrs_template[
... "Descriptor"
... ] = "nemisis>Noise Eliminating Magnetometer Instrument in a Small Integrated System"
>>> global_attrs_template["Instrument_mode"] = "default"
>>> global_attrs_template["Instrument_type"] = "Magnetic Fields (space)"
>>> global_attrs_template["Data_product_descriptor"] = "odpd"
>>>
>>> global_attrs_template["HTTP_LINK"] = [
... "https://science.nasa.gov/missions/hermes",
... "https://github.com/HERMES-SOC",
... "https://github.com/HERMES-SOC/hermes_nemisis",
... ]
>>> global_attrs_template["LINK_TEXT"] = ["HERMES homepage",
... "HERMES SOC Github", "NEMISIS Analysis Tools"]
>>> global_attrs_template["LINK_TITLE"] = ["HERMES homepage",
... "HERMES SOC Github", "NEMISIS Analysis Tools"]
>>>
>>> global_attrs_template["MODS"] = ["v0.0.1 - Original version."]
>>> global_attrs_template["PI_affiliation"] = "NASA Goddard Space Flight Center"
>>> global_attrs_template["PI_name"] = "Dr. Eftyhia Zesta"
>>> global_attrs_template["TEXT"] = "Sample HERMES NEMISIS CDF File"
>>>
>>> example_data = HermesData(
... timeseries=ts,
... support=support_data,
... spectra=spectra,
... meta=global_attrs_template
... )
>>>
>>> # To make the creation of variable metadata easier you can use the static
>>> # `HermesData.measurement_attribute_template()` function.
>>> template = HermesData.measurement_attribute_template()
>>>
>>> # Update the Metadata for each of the Measurements
>>> example_data.timeseries["Bx GSE"].meta.update(
... OrderedDict({"CATDESC": "X component of magnetic Field GSE"}))
>>> example_data.timeseries["By GSE"].meta.update(
... OrderedDict({"CATDESC": "Y component of magnetic Field GSE"}))
>>>
>>> # You can add new scalar time-variant measurements to the HermesData container
>>> bz = np.random.choice(a=[-1, 0, 1], size=1000).cumsum(0)
>>> example_data.add_measurement(
... measure_name="Bz GSE",
... data=u.Quantity(value=bz, unit="nanoTesla", dtype=np.int16),
... meta={
... "VAR_TYPE": "data",
... "CATDESC": "Z component of magnetic Field GSE",
... },
... )
>>>
>>> # You can add new time-invariant data to the HermesData container
>>> example_data.add_support(
... name="calibration_const",
... data=NDData(data=[1e-1]),
... meta={
... "CATDESC": "Calibration Factor",
... "VAR_TYPE": "metadata"
... },
... )
>>>
>>> # You can ass new spectral or high-dimensional data to the HermesData container
>>> data = NDCube(
... data=np.random.random(size=(1000, 10)),
... wcs=WCS(naxis=2),
... meta={"CATDESC": "Example Spectra Variable"},
... unit="eV",
... )
>>> example_data.add_spectra(
... name="added_spectra",
... data=data,
... meta={"VAR_TYPE": "data"},
... )
>>>
>>> # create the CDF File
>>> DRYRUN=True
>>> if DRYRUN:
... with tempfile.TemporaryDirectory() as tmpdirname:
... tmp_path = Path(tmpdirname)
... cdf_file_path = example_data.save(output_path=tmp_path)
... else:
... cdf_file_path = example_data.save(output_path=Path("./"), overwrite=True)
The file that this code generates is made available as a sample file in this
repository in hermes_core/data/sample/hermes_nem_default_l1_20160322T123031_v0.0.1.cdf
.