diff --git a/src/pyfaradaycup/decommutator/README.md b/src/pyfaradaycup/decommutator/README.md index 16e604d..6dfd90b 100644 --- a/src/pyfaradaycup/decommutator/README.md +++ b/src/pyfaradaycup/decommutator/README.md @@ -44,7 +44,7 @@ It would also be useful to return the kernels and skeleton files that were used. Two runs that start in the same second with the same `--logdir` write to the same file. Including the name of the L0 file in the log file name would fix this. - **Remove the global state.** - The log file is the module-level global `logfile`, which `statusmsg` writes to. + The log file is the module-level global `logfile`, which `_statusmsg` writes to. SPICE kernels are loaded with `spiceypy.furnsh` on every call and are never unloaded. This is safe when each step runs in its own process, but not when `main` is called more than once in the same process. Pass the log file as an argument, and unload the kernels when the conversion finishes. @@ -53,7 +53,7 @@ It would also be useful to return the kernels and skeleton files that were used. Calling the conversion as a function is better suited to Dagster than starting a subprocess, since Dagster can then capture exceptions, log messages, and return values. -- **Use the `logging` module instead of `statusmsg` and `print`.** +- **Use the `logging` module instead of `_statusmsg` and `print`.** Dagster can then show the messages with their levels in its own logs. The warnings that `pfc_decommutator` prints for options that have no effect should use `logging` too. - **Keep `pfc_decommutator` as a thin wrapper.** @@ -72,7 +72,7 @@ Calling the conversion as a function is better suited to Dagster than starting a ### Test the `--spacecraft` option - **Add a test that converts a spacecraft L0 file with `--spacecraft`.** - The only test converts an instrument L0 file, so `read_file_sc`, `get_layout_sc`, and the code that writes the spacecraft housekeeping CDFs are never run. + The only test converts an instrument L0 file, so `read_file_sc`, `_get_layout_sc`, and the code that writes the spacecraft housekeeping CDFs are never run. Add a spacecraft L0 file to `tests/data`, along with the expected L1 CDF files, and compare them as the existing test does. Include a file for which the flight software version cannot be found from the packet header, so that the fallback to the file path, and then to the newest definition file, is also tested. diff --git a/src/pyfaradaycup/decommutator/ccsds_reader_pipeline.py b/src/pyfaradaycup/decommutator/ccsds_reader_pipeline.py index 235179c..2e6b9f7 100644 --- a/src/pyfaradaycup/decommutator/ccsds_reader_pipeline.py +++ b/src/pyfaradaycup/decommutator/ccsds_reader_pipeline.py @@ -9,17 +9,8 @@ __all__ = [ "apid_obj", - "choose_file", - "file2bytestr", - "get_layout", - "get_layout_sc", - "parse_ccsds_head", - "parse_pkt", - "read_bytestr", "read_file", "read_file_sc", - "read_stdin", - "wrapper_status", ] import datetime @@ -39,11 +30,11 @@ import os -def read_stdin(ptp: bool = False, verbose: bool = False) -> None: # ruff:ignore[FBT001, FBT002] +def _read_stdin(ptp: bool = False, verbose: bool = False) -> None: # ruff:ignore[FBT001, FBT002] """Parse binary stream on stdin""" # ruff:ignore[D400] -def file2bytestr( +def _file2bytestr( path: str | os.PathLike[str], verbose: bool = False, # ruff:ignore[ARG001, FBT001, FBT002] gzip: bool = False, # ruff:ignore[FBT001, FBT002] @@ -85,7 +76,7 @@ def file2bytestr( raise RuntimeError(msg) from exc -def choose_file( +def _choose_file( path: str | os.PathLike[str], ptp: bool = False, # ruff:ignore[ARG001, FBT001, FBT002] verbose: bool = False, # ruff:ignore[ARG001, FBT001, FBT002] @@ -128,7 +119,7 @@ def choose_file( return path -def wrapper_status( +def _wrapper_status( path: str | os.PathLike[str], verbose: bool = False, # ruff:ignore[ARG001, FBT001, FBT002] gzip: bool = False, # ruff:ignore[FBT001, FBT002] @@ -169,10 +160,10 @@ def wrapper_status( the headers are decoded, not the packet data. """ # make sure the file can be read - path = choose_file(path) + path = _choose_file(path) # convert file to a hex string - bytestr = file2bytestr(path, gzip=gzip) + bytestr = _file2bytestr(path, gzip=gzip) # define the apids that are ok wrapper_apids = range(0x348, 0x351) @@ -217,8 +208,8 @@ def wrapper_status( # Loop through each packet beginning and decommutate it for i_pointer, pointer in enumerate(pkt_starts): # ruff:ignore[B007] - wrap_cchead = parse_ccsds_head(bytestr[pointer : pointer + 10]) - data_cchead = parse_ccsds_head(bytestr[pointer + 12 : pointer + 22]) + wrap_cchead = _parse_ccsds_head(bytestr[pointer : pointer + 10]) + data_cchead = _parse_ccsds_head(bytestr[pointer + 12 : pointer + 22]) data["wrap_met"].append(wrap_cchead["CCSDS_MET"]) data["wrap_apid"].append(wrap_cchead["CCSDS_ApID"]) data["wrap_seq"].append(wrap_cchead["CCSDS_SeqCnt"]) @@ -236,10 +227,10 @@ def read_file( # ruff:ignore[C901] ) -> dict[int, dict[str, list]]: """Read a CCSDS File and return data structure""" # ruff:ignore[D400] # make sure the file can be read - path = choose_file(path) + path = _choose_file(path) # convert file to a hex string - bytestr = file2bytestr(path, gzip=gzip) + bytestr = _file2bytestr(path, gzip=gzip) # define the apids that are ok wrapper_apids = range(0x348, 0x351) @@ -251,7 +242,7 @@ def read_file( # ruff:ignore[C901] # store the format for each apid in a dictionary apidformat = {} for apid in ok_apids: - apidformat[apid] = get_layout(apid, verbose=verbose) + apidformat[apid] = _get_layout(apid, verbose=verbose) if apidformat[apid]: data[apid] = {} for name in apidformat[apid].names: # ty: ignore[unresolved-attribute] @@ -296,7 +287,7 @@ def read_file( # ruff:ignore[C901] # Loop through each packet beginning and decommutate it for i_pointer, pointer in enumerate(pkt_starts): - foo = read_bytestr( # ruff:ignore[F841] + foo = _read_bytestr( # ruff:ignore[F841] bytestr, pointer + 12, data, apidformat, pktcnt, verbose=verbose ) @@ -332,10 +323,10 @@ def read_file_sc( # ruff:ignore[C901, PLR0912, PLR0915] ) -> dict[int, dict[str, list]]: """Read a CCSDS File and return data structure""" # ruff:ignore[D400] # make sure the file can be read - path = choose_file(path) + path = _choose_file(path) # convert file to a hex string - bytestr = file2bytestr(path, gzip=gzip) + bytestr = _file2bytestr(path, gzip=gzip) # We'll need to find which apid dictionary to use, # based on which version of FSW was running @@ -362,9 +353,9 @@ def read_file_sc( # ruff:ignore[C901, PLR0912, PLR0915] # we'll assume the first bytes in the file are a header try: if ptp: # ruff:ignore[SIM108] - cchead = parse_ccsds_head(bytestr[17:]) + cchead = _parse_ccsds_head(bytestr[17:]) else: - cchead = parse_ccsds_head(bytestr) + cchead = _parse_ccsds_head(bytestr) if ( (cchead["CCSDS_Version"] != 0) | (cchead["CCSDS_PacketType"] != 0) @@ -415,7 +406,7 @@ def read_file_sc( # ruff:ignore[C901, PLR0912, PLR0915] # store the format for each apid in a dictionary apidformat = {} for apid in ok_apids: - apidformat[apid], lengths[apid] = get_layout_sc( + apidformat[apid], lengths[apid] = _get_layout_sc( apid, verbose=verbose, filename=data_dir / "sc_hk_def" / sc_hk_filename, @@ -493,7 +484,7 @@ def read_file_sc( # ruff:ignore[C901, PLR0912, PLR0915] # Loop through each packet beginning and decommutate it for i_pointer, pointer in enumerate(pkt_starts): - foo = read_bytestr( # ruff:ignore[F841] + foo = _read_bytestr( # ruff:ignore[F841] bytestr, pointer + offset_bytes, data, apidformat, pktcnt, verbose=verbose ) @@ -521,7 +512,7 @@ def read_file_sc( # ruff:ignore[C901, PLR0912, PLR0915] return data -def read_bytestr( # ruff:ignore[C901, PLR0912, PLR0913] +def _read_bytestr( # ruff:ignore[C901, PLR0912, PLR0913] bytestr: bytes, pointer, # ruff:ignore[ANN001] data: dict[int, dict[str, list]], @@ -532,7 +523,7 @@ def read_bytestr( # ruff:ignore[C901, PLR0912, PLR0913] """Take a hex string and find packets""" # ruff:ignore[D400] # Parse the CCSDS header try: - ccsds_head = parse_ccsds_head(bytestr[pointer : pointer + 10]) + ccsds_head = _parse_ccsds_head(bytestr[pointer : pointer + 10]) except ValueError: if verbose: print("Full CCSDS Header Not Present") # ruff:ignore[T201] @@ -571,7 +562,7 @@ def read_bytestr( # ruff:ignore[C901, PLR0912, PLR0913] pktcnt[0][apid] += 1 # parse the packet and add decommed values to data variable - parse_pkt( + _parse_pkt( thispkt, data, apidformat, apid, ccsds_head ) # could send this off to a parallel task? Might try that if too slow this way @@ -583,7 +574,7 @@ def read_bytestr( # ruff:ignore[C901, PLR0912, PLR0913] return () -def parse_ccsds_head(bytestr: bytes, verbose: bool = False) -> dict[str, int]: # ruff:ignore[ARG001, FBT001, FBT002] +def _parse_ccsds_head(bytestr: bytes, verbose: bool = False) -> dict[str, int]: # ruff:ignore[ARG001, FBT001, FBT002] """ Decode a 10-byte CCSDS packet header into its fields. @@ -636,7 +627,7 @@ def parse_ccsds_head(bytestr: bytes, verbose: bool = False) -> dict[str, int]: return head -def parse_pkt( # ruff:ignore[C901, PLR0912, PLR0913] +def _parse_pkt( # ruff:ignore[C901, PLR0912, PLR0913] bytestr: bytes, data: dict[int, dict[str, list]], apidformat, # ruff:ignore[ANN001] @@ -747,7 +738,7 @@ class apid_obj: # ruff:ignore[N801] """ Store the bit layout of one packet type (APID). - An empty instance is created by `get_layout` or `get_layout_sc`, + An empty instance is created by `_get_layout` or `_get_layout_sc`, which then fill in the attributes from a telemetry definition file. Attributes @@ -760,23 +751,23 @@ class apid_obj: # ruff:ignore[N801] bytestart, bitstart : list or numpy.ndarray of int Byte and bit position where each field starts. Set by - `get_layout`. + `_get_layout`. byteend, bitend : list or numpy.ndarray of int Byte and bit position where each field ends. Set by - `get_layout`. + `_get_layout`. startbyte, startbit : list of int Byte and bit position where each field starts, as listed in the - spacecraft housekeeping definition file. Set by `get_layout_sc`. + spacecraft housekeeping definition file. Set by `_get_layout_sc`. data : dict of str to list - An empty list for each mnemonic. Set by `get_layout`. + An empty list for each mnemonic. Set by `_get_layout`. Notes ----- - `get_layout` and `get_layout_sc` also add an ``apid`` attribute - (the APID as an int). `get_layout` adds a ``sw_data_vars`` + `_get_layout` and `_get_layout_sc` also add an ``apid`` attribute + (the APID as an int). `_get_layout` adds a ``sw_data_vars`` attribute (a list of mnemonics in the science data block) for packets that have one. """ @@ -796,7 +787,7 @@ def __init__(self) -> None: self.startbit: list[int] = [] -def get_layout(apid: int, verbose: bool = False) -> apid_obj | None: # ruff:ignore[C901, FBT001, FBT002] +def _get_layout(apid: int, verbose: bool = False) -> apid_obj | None: # ruff:ignore[C901, FBT001, FBT002] """ Read the bit layout for one SWEAP APID from ``sweap_tlm.blk``. @@ -889,7 +880,7 @@ def get_layout(apid: int, verbose: bool = False) -> apid_obj | None: # ruff:ign return None -def get_layout_sc( # ruff:ignore[C901] +def _get_layout_sc( # ruff:ignore[C901] apid: int, verbose: bool = False, # ruff:ignore[FBT001, FBT002] filename: str | os.PathLike[str] | None = None, diff --git a/src/pyfaradaycup/decommutator/swp_spc_l02l1.py b/src/pyfaradaycup/decommutator/swp_spc_l02l1.py index 0fba2c1..aad4c89 100644 --- a/src/pyfaradaycup/decommutator/swp_spc_l02l1.py +++ b/src/pyfaradaycup/decommutator/swp_spc_l02l1.py @@ -8,14 +8,7 @@ from __future__ import annotations __all__ = [ - "cdf35e_35f", - "cdf351_353_354", - "cdf352", - "get_newest_kernel", - "get_newest_skeleton", "main", - "secsubsec2scet", - "statusmsg", ] import datetime @@ -138,22 +131,22 @@ def main( # ruff:ignore[C901, PLR0912, PLR0913, PLR0915, PLR0917] msg = f"Could not open log file: {logpath}" raise RuntimeError(msg) from exc # Write some information to the log file - statusmsg("scriptname = swp_spc_l02l1.py", verbose=verbose) - statusmsg("timerun = " + nowdt.isoformat(), verbose=verbose) - statusmsg(f"l0file = {l0file}", verbose=verbose) - statusmsg(f"l1dir = {l1dir}", verbose=verbose) - statusmsg("spacecraft = " + repr(spacecraft), verbose=verbose) - statusmsg("ptp = " + repr(ptp), verbose=verbose) - statusmsg("gzip = " + repr(gzip), verbose=verbose) - statusmsg("apid = " + hex(apidreq), verbose=verbose) - statusmsg("overwrite = " + repr(overwrite), verbose=verbose) + _statusmsg("scriptname = swp_spc_l02l1.py", verbose=verbose) + _statusmsg("timerun = " + nowdt.isoformat(), verbose=verbose) + _statusmsg(f"l0file = {l0file}", verbose=verbose) + _statusmsg(f"l1dir = {l1dir}", verbose=verbose) + _statusmsg("spacecraft = " + repr(spacecraft), verbose=verbose) + _statusmsg("ptp = " + repr(ptp), verbose=verbose) + _statusmsg("gzip = " + repr(gzip), verbose=verbose) + _statusmsg("apid = " + hex(apidreq), verbose=verbose) + _statusmsg("overwrite = " + repr(overwrite), verbose=verbose) # Make sure the L0 file exists and is readable try: l0file.open().close() - statusmsg("L0 file exists and is readable") + _statusmsg("L0 file exists and is readable") except OSError: - statusmsg( + _statusmsg( "***ERROR*** [swp_spc_l02l1.py] Input L0 file could not be read...exiting", screen=True, verbose=verbose, @@ -161,52 +154,52 @@ def main( # ruff:ignore[C901, PLR0912, PLR0913, PLR0915, PLR0917] raise RuntimeError # ruff:ignore[B904] # Load in Leap Second Kernel - statusmsg("***INFO*** [swp_spc_l02l1.py] Finding newest leap second kernel...") - tls_path = get_newest_kernel(tls=True) + _statusmsg("***INFO*** [swp_spc_l02l1.py] Finding newest leap second kernel...") + tls_path = _get_newest_kernel(tls=True) if not tls_path: msg = "Could not find leap second kernel" - statusmsg(f"***ERROR*** [swp_spc_l02l1.py] {msg}") + _statusmsg(f"***ERROR*** [swp_spc_l02l1.py] {msg}") raise RuntimeError(msg) else: # ruff:ignore[RET506] try: - statusmsg(f"***INFO*** [swp_spc_l02l1.py] Using: {tls_path}") + _statusmsg(f"***INFO*** [swp_spc_l02l1.py] Using: {tls_path}") spiceypy.furnsh(tls_path) except Exception as exc: msg = f"Could not load leap second kernel: {tls_path}" - statusmsg(f"***ERROR*** [swp_spc_l02l1.py] {msg}") + _statusmsg(f"***ERROR*** [swp_spc_l02l1.py] {msg}") raise RuntimeError(msg) from exc # Load in S/C Clock Kernel - statusmsg("***INFO*** [swp_spc_l02l1.py] Finding newest S/C clock kernel...") - sclk_path = get_newest_kernel(sclk=True) + _statusmsg("***INFO*** [swp_spc_l02l1.py] Finding newest S/C clock kernel...") + sclk_path = _get_newest_kernel(sclk=True) if not sclk_path: msg = "Could not find SCLK kernel" - statusmsg(f"***ERROR*** [swp_spc_l02l1.py] {msg}") + _statusmsg(f"***ERROR*** [swp_spc_l02l1.py] {msg}") raise RuntimeError(msg) else: # ruff:ignore[RET506] try: - statusmsg(f"***INFO*** [swp_spc_l02l1.py] Using: {sclk_path}") + _statusmsg(f"***INFO*** [swp_spc_l02l1.py] Using: {sclk_path}") spiceypy.furnsh(sclk_path) except Exception as exc: msg = f"Could not load SCLK kernel: {sclk_path}" - statusmsg(f"***ERROR*** [swp_spc_l02l1.py] {msg}") + _statusmsg(f"***ERROR*** [swp_spc_l02l1.py] {msg}") raise RuntimeError(msg) from exc # Read in the L0 file into a python SPC data structure if spacecraft: - statusmsg("Event = Starting reading file: spacecraft") + _statusmsg("Event = Starting reading file: spacecraft") l0data = cc.read_file_sc(path=l0file, ptp=ptp, verbose=verbose, gzip=gzip) else: - statusmsg("Event = Starting reading file: non-spacecraft (instrument)") + _statusmsg("Event = Starting reading file: non-spacecraft (instrument)") l0data = cc.read_file(path=l0file, verbose=verbose, gzip=gzip) - statusmsg("Event = Finished reading file") + _statusmsg("Event = Finished reading file") # Loop through the APIDs that we got for apid in l0data.keys(): # ruff:ignore[SIM118] - statusmsg(f"Event = Beginning APID: {hex(apid)}") + _statusmsg(f"Event = Beginning APID: {hex(apid)}") if apid == 0x07B: # ruff:ignore[PLR2004] - statusmsg( + _statusmsg( "***WARNING*** [swp_spc_l02l1] APID 0x07B CDFs not yet implemented", screen=True, verbose=verbose, @@ -215,33 +208,33 @@ def main( # ruff:ignore[C901, PLR0912, PLR0913, PLR0915, PLR0917] # Make sure we need to do this apid if len(l0data[apid][list(l0data[apid].keys())[0]]) == 0: # ruff:ignore[RUF015] - statusmsg("No packets found for this apid.") + _statusmsg("No packets found for this apid.") continue # skip this apid if there were no packets received if (apidreq != 0) & (apidreq != apid): - statusmsg("This apid not requested by user") + _statusmsg("This apid not requested by user") continue # skip this apid if user only wanted one apid and this isn't it # Filename for the L1 file we're about to write for this apid l1path = ( l1dir / f"{l0file_noext}_APID{str(hex(apid)[2:].zfill(3)).upper()}_L1.cdf" # ruff:ignore[FURB116] ) - statusmsg(f"About to write: {l1path}") + _statusmsg(f"About to write: {l1path}") # Make sure the skeleton file exists and is readable try: - skeleton_filename = get_newest_skeleton(apid) + skeleton_filename = _get_newest_skeleton(apid) pathlib.Path(skeleton_filename).open().close() - statusmsg("Skeleton to be used: " + skeleton_filename) + _statusmsg("Skeleton to be used: " + skeleton_filename) except OSError: - statusmsg( + _statusmsg( "***ERROR*** [swp_spc_l02l1.py] Skeleton file could not be read...moving to next apid", screen=True, verbose=verbose, ) - statusmsg("Tried to use skeleton file: " + skeleton_filename) + _statusmsg("Tried to use skeleton file: " + skeleton_filename) continue except TypeError: - statusmsg( + _statusmsg( f"***ERROR*** [swp_spc_l02l1.py] Skeleton file for apid={hex(apid)} could not be found...moving to next apid", screen=True, verbose=verbose, @@ -251,17 +244,17 @@ def main( # ruff:ignore[C901, PLR0912, PLR0913, PLR0915, PLR0917] # See if the CDF file already exists try: # try to open and close it - statusmsg(f"Using L1 path: {l1path}", screen=True, verbose=verbose) + _statusmsg(f"Using L1 path: {l1path}", screen=True, verbose=verbose) l1path.open().close() # if we get here, this file already exists; so delete it, if desired - statusmsg( + _statusmsg( f"***INFO*** [swp_spc_l02l1] L1 CDF file ({l1path}) already exists", screen=True, verbose=verbose, ) if overwrite: - statusmsg( + _statusmsg( "***INFO*** [swp_spc_l02l1] Overwriting existing L1 CDF", screen=True, verbose=verbose, @@ -269,7 +262,7 @@ def main( # ruff:ignore[C901, PLR0912, PLR0913, PLR0915, PLR0917] l1path.unlink() else: msg = f"L1 CDF already exists and overwrite was not requested: {l1path}" - statusmsg( + _statusmsg( f"***ERROR*** [swp_spc_l02l1] {msg}", screen=True, verbose=verbose, @@ -281,7 +274,7 @@ def main( # ruff:ignore[C901, PLR0912, PLR0913, PLR0915, PLR0917] pass # Apparently the file did not exist already except Exception as exc: msg = f"Could not check existence of or delete L1 CDF file: {l1path}" - statusmsg( + _statusmsg( f"***ERROR*** [swp_spc_l02l1] {msg}", screen=True, verbose=verbose, @@ -294,34 +287,34 @@ def main( # ruff:ignore[C901, PLR0912, PLR0913, PLR0915, PLR0917] try: cdf = pycdf.CDF(str(l1path), skeleton_filename) except "CDFError": # ruff:ignore[B030] # ty: ignore[invalid-exception-caught] - statusmsg( + _statusmsg( f"\n***ERROR*** [swp_spc_l02l1] Could not create new CDF (APID={apid})...continuing to next APID\n).", screen=True, verbose=verbose, ) - statusmsg(sys.exc_info(), screen=True, verbose=verbose) # ty: ignore[invalid-argument-type] + _statusmsg(sys.exc_info(), screen=True, verbose=verbose) # ty: ignore[invalid-argument-type] continue # Run a different procedure to put data into CDF file depending on APID cdfproc = { - 0x081: cdf35e_35f, - 0x1DE: cdf35e_35f, - 0x254: cdf35e_35f, - 0x256: cdf35e_35f, - 0x257: cdf35e_35f, - 0x262: cdf35e_35f, - 0x351: cdf351_353_354, - 0x352: cdf352, - 0x353: cdf351_353_354, - 0x354: cdf351_353_354, - 0x35E: cdf35e_35f, - 0x35F: cdf35e_35f, + 0x081: _cdf35e_35f, + 0x1DE: _cdf35e_35f, + 0x254: _cdf35e_35f, + 0x256: _cdf35e_35f, + 0x257: _cdf35e_35f, + 0x262: _cdf35e_35f, + 0x351: _cdf351_353_354, + 0x352: _cdf352, + 0x353: _cdf351_353_354, + 0x354: _cdf351_353_354, + 0x35E: _cdf35e_35f, + 0x35F: _cdf35e_35f, } try: cdfproc[apid](cdf, l0data[apid], verbose=verbose) except: # ruff:ignore[E722] - statusmsg(repr(sys.exc_info()), screen=True, verbose=verbose) - statusmsg( + _statusmsg(repr(sys.exc_info()), screen=True, verbose=verbose) + _statusmsg( f"***WARNING*** [swp_spc_l02l1] CDF not processed for APID={hex(apid)}", screen=True, verbose=verbose, @@ -337,7 +330,7 @@ def main( # ruff:ignore[C901, PLR0912, PLR0913, PLR0915, PLR0917] ) cdf.close() - statusmsg( + _statusmsg( "***INFO*** [swp_spc_l02l1] Script complete.", screen=True, verbose=verbose ) @@ -345,7 +338,7 @@ def main( # ruff:ignore[C901, PLR0912, PLR0913, PLR0915, PLR0917] logfile.close() -def cdf35e_35f(cdf: pycdf.CDF, dat: dict[str, list], verbose: bool = False) -> None: # ruff:ignore[C901, FBT001, FBT002] +def _cdf35e_35f(cdf: pycdf.CDF, dat: dict[str, list], verbose: bool = False) -> None: # ruff:ignore[C901, FBT001, FBT002] """ Fill a CDF with housekeeping data, one row per packet. @@ -368,7 +361,7 @@ def cdf35e_35f(cdf: pycdf.CDF, dat: dict[str, list], verbose: bool = False) -> N Notes ----- - Unlike `cdf352` and `cdf351_353_354`, the data is not expanded: + Unlike `_cdf352` and `_cdf351_353_354`, the data is not expanded: each packet becomes one row in the CDF. ``"Epoch"`` (nanoseconds past J2000) is calculated from whichever @@ -385,40 +378,40 @@ def cdf35e_35f(cdf: pycdf.CDF, dat: dict[str, list], verbose: bool = False) -> N # Calculate MET from the variables in the L0 data # MET of each NYS if "CCSDS_MET" in dat.keys(): # ruff:ignore[SIM118] - scet = secsubsec2scet(dat["CCSDS_MET"], dat["SW_SPC_SUBSEC"]) + scet = _secsubsec2scet(dat["CCSDS_MET"], dat["SW_SPC_SUBSEC"]) elif "FSW_HK_HK_INST_TPSH_MET_SEC" in dat.keys(): # ruff:ignore[SIM118] - scet = secsubsec2scet( + scet = _secsubsec2scet( dat["FSW_HK_HK_INST_TPSH_MET_SEC"], dat["FSW_HK_HK_INST_TPSH_MET_SUBSEC"], spacecraft=True, ) elif "PDU_PRIO94_TPSH_MET_SEC" in dat.keys(): # ruff:ignore[SIM118] - scet = secsubsec2scet( + scet = _secsubsec2scet( dat["PDU_PRIO94_TPSH_MET_SEC"], dat["PDU_PRIO94_TPSH_MET_SUBSEC"], spacecraft=True, ) elif "HK_HIGH_TPSH_MET_SEC" in dat.keys(): # ruff:ignore[SIM118] - scet = secsubsec2scet( + scet = _secsubsec2scet( dat["HK_HIGH_TPSH_MET_SEC"], dat["HK_HIGH_TPSH_MET_SUBSEC"], spacecraft=True ) elif "HK_FSWL_TPSH_MET_SEC" in dat.keys(): # ruff:ignore[SIM118] - scet = secsubsec2scet( + scet = _secsubsec2scet( dat["HK_FSWL_TPSH_MET_SEC"], dat["HK_FSWL_TPSH_MET_SUBSEC"], spacecraft=True ) elif "HK_LOW_TPSH_MET_SEC" in dat.keys(): # ruff:ignore[SIM118] - scet = secsubsec2scet( + scet = _secsubsec2scet( dat["HK_LOW_TPSH_MET_SEC"], dat["HK_LOW_TPSH_MET_SUBSEC"], spacecraft=True ) elif "RIU_DERIVED_TPSH_MET_SEC" in dat.keys(): # ruff:ignore[SIM118] - scet = secsubsec2scet( + scet = _secsubsec2scet( dat["RIU_DERIVED_TPSH_MET_SEC"], dat["RIU_DERIVED_TPSH_MET_SUBSEC"], spacecraft=True, ) else: - statusmsg("Failed: could not create Epoch variable") + _statusmsg("Failed: could not create Epoch variable") return # Fill in values for each variable @@ -434,15 +427,15 @@ def cdf35e_35f(cdf: pycdf.CDF, dat: dict[str, list], verbose: bool = False) -> N except: # ruff:ignore[E722] raise RuntimeError # ruff:ignore[B904] - statusmsg( + _statusmsg( f"Failed : Key:{key} failed insert into CDF", screen=True, verbose=verbose, ) - statusmsg(sys.exc_info()) + _statusmsg(sys.exc_info()) -def cdf351_353_354( # ruff:ignore[C901, PLR0912, PLR0915, RET503] +def _cdf351_353_354( # ruff:ignore[C901, PLR0912, PLR0915, RET503] cdf: pycdf.CDF, dat: dict[str, list], nocdf: bool = False, # ruff:ignore[FBT001, FBT002] @@ -506,7 +499,7 @@ def cdf351_353_354( # ruff:ignore[C901, PLR0912, PLR0915, RET503] # Calculate MET from the variables in the L0 data # MET of each NYS - scet = secsubsec2scet(dat["CCSDS_MET"], dat["SW_SPCSUBSEC"]) + scet = _secsubsec2scet(dat["CCSDS_MET"], dat["SW_SPCSUBSEC"]) # MET of each measurement (to be filled in in the future) scet_exp = [] # ruff:ignore[F841] @@ -534,7 +527,7 @@ def cdf351_353_354( # ruff:ignore[C901, PLR0912, PLR0915, RET503] ticks_per_meas = 8 if not itst_warned: - statusmsg( + _statusmsg( "***WARNING*** [swp_spc_l02l1] The reported IT+ST is not an even power of 2. Using IT=6,ST=2...", screen=True, verbose=verbose, @@ -551,14 +544,14 @@ def cdf351_353_354( # ruff:ignore[C901, PLR0912, PLR0915, RET503] & (dat["SW_SPC_SERVTIME"][i] != dat["SW_SPC_SERVTIME"][i - 1]) & (dat["SW_SPC_SERVTIME"][i] != dat["SW_SPC_SERVTIME"][i + 1]) ): - statusmsg( + _statusmsg( "***WARNING***IT+ST not 2^n, and not same as prev. and next values...so skipping this packet.", screen=True, verbose=verbose, ) continue except IndexError: - statusmsg( + _statusmsg( "***WARNING***IT+ST not 2^n, and not same as prev. and next values...so skipping this packet.", screen=True, verbose=verbose, @@ -632,17 +625,17 @@ def cdf351_353_354( # ruff:ignore[C901, PLR0912, PLR0915, RET503] # insert data cdf[key] = dat_exp[key] except: # ruff:ignore[E722, PERF203] - statusmsg( + _statusmsg( f"Failed : Key:{key} failed insert into CDF", screen=True, verbose=verbose, ) - statusmsg(repr(sys.exc_info()), screen=True, verbose=verbose) + _statusmsg(repr(sys.exc_info()), screen=True, verbose=verbose) raise RuntimeError # ruff:ignore[B904] -def cdf352( # ruff:ignore[C901, PLR0912, PLR0915] +def _cdf352( # ruff:ignore[C901, PLR0912, PLR0915] cdf: pycdf.CDF, dat: dict[str, list], nocdf: bool = False, # ruff:ignore[FBT001, FBT002] @@ -697,7 +690,7 @@ def cdf352( # ruff:ignore[C901, PLR0912, PLR0915] """ try: # Calculate SCET from the variables in the L0 data - dt = secsubsec2scet(dat["CCSDS_MET"], dat["SW_SPCSUBSEC"]) + dt = _secsubsec2scet(dat["CCSDS_MET"], dat["SW_SPCSUBSEC"]) # Same keys as original data dictionary, but will hold one variable per key # instead of one for every NYS for every key @@ -778,10 +771,10 @@ def cdf352( # ruff:ignore[C901, PLR0912, PLR0915] dat_exp["VAR3"].extend(dat["G3_000"][i]) except: # ruff:ignore[E722] - statusmsg( + _statusmsg( "***ERROR*** Could not process 0x352 packet (probably it was a false positive ID of a 0x352 packet?)" ) - statusmsg(repr(sys.exc_info()), screen=True, verbose=verbose) + _statusmsg(repr(sys.exc_info()), screen=True, verbose=verbose) continue # Extend the expanded dt @@ -812,12 +805,12 @@ def cdf352( # ruff:ignore[C901, PLR0912, PLR0915] # insert data cdf[key] = dat_exp[key] except: # ruff:ignore[E722, PERF203] - statusmsg( + _statusmsg( f"Failed : Key:{key} failed insert into CDF", screen=True, verbose=verbose, ) - statusmsg(repr(sys.exc_info()), screen=True, verbose=verbose) + _statusmsg(repr(sys.exc_info()), screen=True, verbose=verbose) except: # ruff:ignore[E722] print(sys.exc_info()) # ruff:ignore[T201] raise RuntimeError # ruff:ignore[B904] @@ -825,7 +818,7 @@ def cdf352( # ruff:ignore[C901, PLR0912, PLR0915] return () -def secsubsec2scet( +def _secsubsec2scet( sec: list[int], subsec: list[int], spacecraft: bool = False, # ruff:ignore[FBT001, FBT002] @@ -884,7 +877,7 @@ def secsubsec2scet( return ephem_nanosec_j2000 # ruff:ignore[RET504] -def statusmsg( +def _statusmsg( string: str, screen: bool = False, # ruff:ignore[FBT001, FBT002] file: bool = True, # ruff:ignore[FBT001, FBT002] @@ -923,7 +916,7 @@ def statusmsg( print(string) # ruff:ignore[T201] -def get_newest_kernel( +def _get_newest_kernel( tls: bool = False, # ruff:ignore[FBT001, FBT002] sclk: bool = False, # ruff:ignore[FBT001, FBT002] verbose: bool = False, # ruff:ignore[ARG001, FBT001, FBT002] @@ -989,7 +982,7 @@ def get_newest_kernel( try: maxind = np.argmax(versions) except ValueError: - statusmsg("***ERROR*** Could not find kernel versions") + _statusmsg("***ERROR*** Could not find kernel versions") print(sys.exc_info()) # ruff:ignore[T201] raise RuntimeError("Could not find kernel versions") # ruff:ignore[B904, EM101, TRY003] @@ -998,7 +991,7 @@ def get_newest_kernel( return str(files[maxind]) -def get_newest_skeleton(apid: int, verbose: bool = False) -> str: # ruff:ignore[ARG001, FBT001, FBT002] +def _get_newest_skeleton(apid: int, verbose: bool = False) -> str: # ruff:ignore[ARG001, FBT001, FBT002] """ Return the path to the skeleton CDF file for an APID. @@ -1045,7 +1038,7 @@ def get_newest_skeleton(apid: int, verbose: bool = False) -> str: # ruff:ignore # try: # maxind = np.argmax(versions) # except ValueError: - # statusmsg('***ERROR*** Could not find skeleton versions') + # _statusmsg('***ERROR*** Could not find skeleton versions') # return(False) # return path to newest file