""" NASA EOS mission specific data References: 1. MODIS Command, Telemetry, Science and Engineering Description, Document Number 151840, May 1997, Appendix C https://directreadout.sci.gsfc.nasa.gov/documents/satellite_gen/MODIS_UG.pdf """ packet_types = { 0: "day", 1: "night", 2: "eng1", 4: "eng2", } packet_sources = { 0: "solar-diff", 1: "srca-cal", 2: "bb-cal", 3: "space-cal", } packets_per_scan = { "day": 3032, "night": 326, } def sourceid(p): if p.data[0] >> 7 == 0: return "earthdata" return packet_sources[p.data[0] >> 5 & 0x3] def mirrorside(p): return ["side1", "side2"][bytes(p.secondary_header)[8] & 0x1] def scancount(p): return bytes(p.secondary_header)[8] >> 1 & 0x7 def pkttype(p): return packet_types[bytes(p.secondary_header)[8] >> 4 & 0x7] def frame_count(p): x = int.from_bytes(b"\x00\x00" + p.data[:2], "big") if sourceid(p) == "earthdata": return x >> 4 & 0x7FF return x >> 4 & 0x3F # Combination of source ids and packet types to their position within a scan. _sort_indexes = { "solar-diff": 1, "srca-cal": 2, "bb-cal": 3, "space-cal": 4, "earthdata": 5, "eng1": 6, "eng2": 7, } def _modis_sort_key(p): """Return a tuple that will maintain order for this packet in a stream of MODIS data. Intended to be used as a key func for sorting. Packets are sorted in the order defined in _sort_indexes. """ type_idx = _sort_indexes.get(pkttype(p), _sort_indexes[sourceid(p)]) return (p.stamp, 64, type_idx, frame_count(p), int(p.is_last())) def sort_modis(packets): return sorted(packets, key=_modis_sort_key) def collect_modis_scans(packets): scan = {"scantime": None, "packets": {}} scantimes = set() for p in packets: if p.apid not in (64, 957): continue tp = sourceid(p) if p.apid == 64 else "gbad" if tp == "solar-diff" and p.stamp not in scantimes: scantimes.add(p.stamp) if scan is not None: yield scan scan = {"scantime": p.stamp, "packets": {}} if tp not in scan["packets"]: scan["packets"][tp] = [] scan["packets"][tp].append(p)