Skip to content
Snippets Groups Projects
Commit 57a6005b authored by Greg Quinn's avatar Greg Quinn
Browse files

Refactor some functions into CrisScienceApidInfo

parent 9518e649
No related branches found
No related tags found
No related merge requests found
......@@ -16,83 +16,6 @@ from edosl0util.jpssrdr import (
from edosl0util.stream import jpss_packet_stream
class GetJpssPacketTime(object):
def __init__(self):
self._viirs_tracker = ViirsGroupedPacketTimeTracker()
def __call__(self, pkt):
if self._viirs_tracker.handles(pkt.apid):
return self._viirs_tracker.get_iet(pkt)
else:
return get_packet_iet(pkt)
class ViirsGroupedPacketTimeTracker(object):
grouped_apids = list(range(800, 824)) + [825]
@classmethod
def handles(cls, apid):
return apid in cls.grouped_apids
def __init__(self):
self._db = {}
def get_iet(self, pkt):
if not self.handles(pkt.apid):
raise ValueError('APID {} not a VIIRS grouped packet type'.format(pkt.apid))
if pkt.is_first():
obs_iet = get_packet_iet(pkt)
self._db[pkt.apid] = (obs_iet, pkt.seqid)
return obs_iet
else:
last_obs_iet, last_seq = self._db[pkt.apid]
group_size = ViirsScienceApidInfo.get_packets_per_scan(pkt.apid)
if not self.check_sequence_number(pkt.seqid, last_seq, group_size):
raise OrphanedViirsPacket(pkt)
if not self.check_packet_iet(self.get_viirs_iet(pkt), last_obs_iet):
raise OrphanedViirsPacket(pkt)
return last_obs_iet
@staticmethod
def get_viirs_iet(pkt):
if pkt.is_standalone():
idx = 18
elif pkt.is_first():
idx = 20
else:
idx = 10
arr = np.frombuffer(pkt.bytes()[idx:idx+8], 'B')
days = arr[0:2].view('>u2')[0]
ms = arr[2:6].view('>u4')[0]
us = arr[6:8].view('>u2')[0]
return timecode_parts_to_iet(days, ms, us)
@staticmethod
def check_sequence_number(nonfirst_seq_num, first_seq_num, group_size):
seq_limit = 2**14
group_end = first_seq_num + group_size
# the 2nd check below is needed to handle wrap-around
return (first_seq_num < nonfirst_seq_num < group_end
or first_seq_num < nonfirst_seq_num + seq_limit < group_end)
@staticmethod
def check_packet_iet(pkt_iet, obs_iet):
# this can be a pretty loose check since it is only needed to prevent
# the very rare case where the sequence number check yields a false
# positive
permitted_lag = 5 # seconds
lag = (pkt_iet - obs_iet) * 1e-6
return 0 <= lag <= permitted_lag
class OrphanedViirsPacket(Exception):
def __init__(self, pkt):
self.packet = pkt
def __str__(self):
return repr(self.packet)
def packets_to_rdrs(sat, pkt_files):
# FIXME: refactor!!!
rdr_pkt_files = {}
......@@ -292,6 +215,17 @@ def build_rdr_blob(sat, pkt_stream):
return buf
class GetJpssPacketTime(object):
def __init__(self):
self._viirs_tracker = ViirsGroupedPacketTimeTracker()
def __call__(self, pkt):
if self._viirs_tracker.tracks_apid(pkt.apid):
return self._viirs_tracker.get_iet(pkt)
else:
return get_packet_iet(pkt)
class ViirsScienceApidInfo(object):
apids = list(x for x in range(800, 827) if x != 824)
names = ['M04', 'M05', 'M03', 'M02', 'M01', 'M06', 'M07', 'M09', 'M10',
......@@ -326,39 +260,43 @@ class ViirsScienceApidInfo(object):
return 33
def get_cris_science_apids():
return ([ApidSpec(1289, 'EIGHT_S_SCI', 5), ApidSpec(1290, 'ENG', 1)]
+ get_cris_obs_apids())
def get_cris_obs_apids():
view_types = ['N', 'S', 'C'] # "normal", "space", "calibration"
bands = ['LW', 'MW', 'SW']
num_fovs = 9
base_apid = 1315
apids = []
for i in range(len(view_types) * len(bands) * num_fovs):
apid = base_apid + i
view_type = view_types[i // (num_fovs * len(bands))]
band = bands[i // num_fovs % len(bands)]
fov = str(i % num_fovs + 1)
apid_name = view_type + band + fov
max_expected = get_max_expected_cris_packets(apid_name)
apids.append(ApidSpec(apid, apid_name, max_expected))
return apids
def get_max_expected_cris_packets(apid_name):
if apid_name == 'EIGHT_S_SCI':
return 5
elif apid_name == 'ENG':
return 1
else:
view_type = apid_name[0]
if view_type == 'N':
return 121
class CrisScienceApidInfo(object):
apids = [1289, 1290] + list(range(1315, 1396))
@classmethod
def get_specs(cls):
return [ApidSpec(apid, cls.get_name(apid), cls.get_max_expected(apid))
for apid in cls.apids]
@classmethod
def get_name(cls, apid):
if apid == 1289:
return 'EIGHT_S_SCI'
elif apid == 1290:
return 'ENG'
else:
return 9
offset = apid - 1315
view_types = ['N', 'S', 'C']
bands = ['LW', 'MW', 'SW']
num_fovs = 9
view_type = view_types[offset // (num_fovs * len(bands))]
band = bands[offset // num_fovs % len(bands)]
fov = str(offset % num_fovs + 1)
return view_type + band + fov
@classmethod
def get_max_expected(cls, apid):
name = cls.get_name(apid)
if name == 'EIGHT_S_SCI':
return 5
elif name == 'ENG':
return 1
else:
view_type = name[0]
if view_type == 'N':
return 121
else:
return 9
@attr.s
......@@ -407,7 +345,7 @@ class CrisScienceRdrType(object):
sensor = 'cris'
type_id = 'SCIENCE'
document = '474-00448-02-03_JPSS-DD-Vol-II-Part-3_0200B.pdf'
apids = get_cris_science_apids()
apids = CrisScienceApidInfo.get_specs()
@rdr_type_spec
......@@ -423,6 +361,72 @@ class SpacecraftDiaryRdrType(object):
ApidSpec(11, 'DIARY', max_expected=21)]
class ViirsGroupedPacketTimeTracker(object):
grouped_apids = list(range(800, 824)) + [825]
@classmethod
def tracks_apid(cls, apid):
return apid in cls.grouped_apids
def __init__(self):
self._db = {}
def get_iet(self, pkt):
if not self.tracks_apid(pkt.apid):
raise ValueError('APID {} not a VIIRS grouped packet type'.format(pkt.apid))
if pkt.is_first():
obs_iet = get_packet_iet(pkt)
self._db[pkt.apid] = (obs_iet, pkt.seqid)
return obs_iet
else:
last_obs_iet, last_seq = self._db[pkt.apid]
group_size = ViirsScienceApidInfo.get_packets_per_scan(pkt.apid)
if not self.check_sequence_number(pkt.seqid, last_seq, group_size):
raise OrphanedViirsPacket(pkt)
if not self.check_packet_iet(self.get_viirs_iet(pkt), last_obs_iet):
raise OrphanedViirsPacket(pkt)
return last_obs_iet
@staticmethod
def get_viirs_iet(pkt):
if pkt.is_standalone():
idx = 18
elif pkt.is_first():
idx = 20
else:
idx = 10
arr = np.frombuffer(pkt.bytes()[idx:idx+8], 'B')
days = arr[0:2].view('>u2')[0]
ms = arr[2:6].view('>u4')[0]
us = arr[6:8].view('>u2')[0]
return timecode_parts_to_iet(days, ms, us)
@staticmethod
def check_sequence_number(nonfirst_seq_num, first_seq_num, group_size):
seq_limit = 2**14
group_end = first_seq_num + group_size
# the 2nd check below is needed to handle wrap-around
return (first_seq_num < nonfirst_seq_num < group_end
or first_seq_num < nonfirst_seq_num + seq_limit < group_end)
@staticmethod
def check_packet_iet(pkt_iet, obs_iet):
# this can be a pretty loose check since it is only needed to prevent
# the very rare case where the sequence number check yields a false
# positive
permitted_lag = 5 # seconds
lag = (pkt_iet - obs_iet) * 1e-6
return 0 <= lag <= permitted_lag
class OrphanedViirsPacket(Exception):
def __init__(self, pkt):
self.packet = pkt
def __str__(self):
return repr(self.packet)
def make_rdr_filename(prod_id, sat, gran_time, gran_end_time, orbit_num, creation_time,
origin, domain, compressed):
sat_strs = {'snpp': 'npp'}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment