OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l0info_harp.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 
3 # procedure to get start and end times from Level-0 fpacket files for HARP2
4 # The times are extracted from the detector image headers. The detector number
5 # (1, 2, 3 or All) is also determined
6 # Reference: HARP2 Telemetry Manual
7 
8 __version__ = '1.4.3_2023-01-26'
9 
10 import numpy as np
11 import os
12 import copy
13 from datetime import datetime
14 from l0info_utils import read_packet, read_apid, get_anc_packet_time, is_bad_packet
15 
16 # str_imhead = "HARP" # [72, 65, 82, 80] # Header start mark ASCII "HARP", \x48\x41\x52\x50
17 hex_imhead = "48415250"
18 
19 def is_fill_image(fpacket,packetLength,fh,firstfill):
20  if not np.any(np.frombuffer(fpacket[22:packetLength-1],dtype=np.uint8)-255):
21  # Routine to output location of first HARP2 image fill data
22  if firstfill:
23  firstfill = False
24  print("Image fill data at byte %d."%fh.tell())
25  return True, firstfill
26  else:
27  return False, firstfill
28 
29 def is_bad_apid(apid,fh):
30  if apid == -1:
31  return False
32  if (apid < 750) or (apid > 799):
33  print("Invalid packet or header at byte %d."%fh.tell())
34  return True
35  else:
36  return False
37 
38 def l0info_harp(args, fh, output):
39  print("Running l0info_harp (version: %s) \n" % __version__)
40 
41  status = 0
42  if args.verbose:
43  print("Reading HARP2 science data file.")
44 
45  file_size = os.fstat(fh.fileno()).st_size
46 
47  # Skip CFE header
48  fh.seek(64)
49  bSPW = True
50 
51  # Find first science fpacket (APID 751)
52  apid = 0
53  packetLength = 8
54  firstfill = True
55 
56 
57  while (apid != 751) and (packetLength > 7):
58  fpacket, packetLength = read_packet(fh, bSPW)
59  apid = read_apid(fpacket)
60  if is_bad_apid(apid,fh): return 104
61 
62  if packetLength > 7:
63  if is_bad_packet(packetLength,fh): return 104
64  isFillImage, firstfill = is_fill_image(fpacket,packetLength,fh,firstfill)
65 
66  # Get detector number from AP header
67  detnum = (fpacket[12] & 48)>>4
68 
69  # Find an image header
70  imhp = -1
71  while (imhp == -1) and (fh.tell() < file_size):
72  imhp = fpacket.hex().find(hex_imhead)
73 
74  if imhp == -1: # If no header in current fpacket, find next science fpacket
75  apid = 0
76  packetLength = 8
77  while (apid != 751) and (packetLength > 7):
78  fpacket, packetLength = read_packet(fh, bSPW)
79  apid = read_apid(fpacket)
80  if is_bad_apid(apid,fh): return 101
81 
82  if packetLength > 7:
83  if is_bad_packet(packetLength,fh): return 104
84  isFillImage, firstfill = is_fill_image(fpacket,packetLength,fh,firstfill)
85 
86  # Check for more than one detector in file
87  detn = (fpacket[12] & 48)>>4
88  if detn != detnum: detnum = 999
89  else:
90  imhp = int(imhp/2)
91 
92  if fh.tell() >= file_size:
93  print('No image headers found in file.')
94 
95  if args.verbose:
96  pctr = (fpacket[2] % 64)*256 + fpacket[3]
97  print(f"Image pointer {imhp}, detector {detn} in packet {pctr}")
98  else:
99  print("No science packets found in file.")
100 
101  # If no science packets, rewind and get times from HKT packets (APID 750)
102  if fh.tell() >= file_size:
103  status = 110
104  etime = datetime(2000,1,1)
105  stime = datetime(3000,1,1)
106 
107  fh.seek(64)
108  apid = 0
109  packetLength = 8
110  ccsec = 0
111  while ((fh.tell() < file_size) and (apid != 750) and (packetLength > 7)) or (ccsec < 2000000000):
112  fpacket, packetLength = read_packet(fh, bSPW)
113  apid = read_apid(fpacket)
114  if is_bad_apid(apid,fh): return 101
115 
116  # Check for invalid time stamp
117  ccsec = int.from_bytes(fpacket[6:10],'big') # swap_endian(long(packet[6:9],0))
118 
119  if is_bad_packet(packetLength,fh): return 104
120 
121  if fpacket:
122  mpacket = fpacket
123  try:
124  ctime = get_anc_packet_time(mpacket[6:12],0,'msec')
125  if ctime<stime:
126  stime = ctime
127  except Exception as e:
128  print(e)
129  return 120
130 
131  while fpacket and (packetLength > 7):
132  fpacket, packetLength = read_packet(fh, bSPW)
133  apid = read_apid(fpacket)
134  if apid == 750: mpacket = fpacket
135  ctime = get_anc_packet_time(mpacket[6:12],0,'msec')
136  # print(f"ctime={ctime.strftime('%Y-%m-%dT%H:%M:%S.%f')}")
137  if ctime<stime:
138  stime = ctime
139  if ctime>etime:
140  etime = ctime
141 
142  if is_bad_packet(packetLength,fh): return 104
143 
144  try:
145  print("start_time=%s" % stime.strftime('%Y-%m-%dT%H:%M:%S.%f'))
146  if output:
147  output.write("start_time=%s\n" % stime.strftime('%Y-%m-%dT%H:%M:%S.%f'))
148  print("stop_time=%s" % etime.strftime('%Y-%m-%dT%H:%M:%S.%f'))
149  if output:
150  output.write("stop_time=%s\n" % etime.strftime('%Y-%m-%dT%H:%M:%S.%f'))
151  except Exception as e:
152  print(e)
153  return 120
154  print(f"status={status}")
155  return status
156 
157  # Get start time
158  try:
159  stime = get_anc_packet_time(fpacket[imhp+7:imhp+13],0,'msec')
160  detnum = (fpacket[12] & 48)>>4
161  except:
162  return 120
163 
164  # Read to end of file
165  # Look for next image header
166  packetLength = 8
167  last_pct = 0
168  etime = stime
169  while fh.tell() < file_size:
170  apid = 0
171 
172  # Find next science fpacket
173  while (fh.tell() < file_size) and (apid != 751) and (packetLength > 7):
174  fpacket, packetLength = read_packet(fh, bSPW)
175  apid = read_apid(fpacket)
176  if is_bad_apid(apid,fh): return 104
177 
178  if fpacket:
179  if is_bad_packet(packetLength,fh): return 104
180  isFillImage, firstfill = is_fill_image(fpacket,packetLength,fh,firstfill)
181 
182  # Look for image header
183  imh = -1
184  while (imh == -1) and fh.tell() < file_size:
185  if args.verbose:
186  imh_pct = int(fh.tell()/file_size*100)
187  if imh_pct - last_pct > 9:
188  print("%d%% of packets read." % imh_pct)
189  last_pct = imh_pct
190  imh = fpacket.hex().find(hex_imhead)
191 
192  if (imh == -1): # If no header in current fpacket, find next science fpacket
193  apid = 0
194  while (fh.tell() < file_size) and (apid != 751) and (packetLength > 7):
195  fpacket, packetLength = read_packet(fh, bSPW)
196  apid = read_apid(fpacket)
197  if is_bad_apid(apid,fh): return 104
198  if (fh.tell() < file_size):
199  if is_bad_packet(packetLength,fh): return 104
200  isFillImage, firstfill = is_fill_image(fpacket,packetLength,fh,firstfill)
201  else:
202  imh = int(imh/2)
203 
204  # if is_bad_image(fpacket,packetLength,fh): return 111
205  if fpacket and (imh > -1): # fh.tell() < file_size:
206  # Check for more than one detector in file
207  detn = (fpacket[12] & 48)>>4
208  if detn != detnum: detnum = 999
209 
210  imhp = imh
211  if args.verbose:
212  pctr = (fpacket[2] % 64)*256 + fpacket[3]
213  print(f"Image pointer {imhp}, detector {detn} in packet {pctr}")
214 
215  if imhp < 8202:
216  ctime = get_anc_packet_time(fpacket[imhp+7:imhp+13],0,'msec')
217  if ctime<stime:
218  stime = ctime
219  if ctime>etime:
220  etime = ctime
221 
222  if args.verbose:
223  print("100% of packets read.")
224 
225  try:
226  if imhp <0:
227  status = 110
228  print("start_time=%s" % stime.strftime('%Y-%m-%dT%H:%M:%S.%f'))
229  print("stop_time=%s" % etime.strftime('%Y-%m-%dT%H:%M:%S.%f'))
230  if output:
231  output.write("start_time=%s\n" % stime.strftime('%Y-%m-%dT%H:%M:%S.%f'))
232  output.write("stop_time=%s\n" % etime.strftime('%Y-%m-%dT%H:%M:%S.%f'))
233  except Exception as e:
234  print(e)
235  return 120
236 
237  if detnum == 999:
238  print("detector=all")
239  if output:
240  output.write("detector=all\n")
241  else:
242  print("detector=%d"%detnum)
243  if output:
244  output.write("detector=%d\n"%detnum)
245 
246  return status
247 
def read_apid(fpacket)
Definition: l0info_utils.py:93
def is_bad_apid(apid, fh)
Definition: l0info_harp.py:29
def l0info_harp(args, fh, output)
Definition: l0info_harp.py:38
int get_anc_packet_time(uint8_t *apacket, int32_t &iyear, int32_t &iday, double &stime)
Definition: common.cpp:97
int read_packet(FILE *infile, uint8_t packet[], int *len, long int *endfile)
Definition: read_packet.c:18
def is_bad_packet(packetLength, fh)
def is_fill_image(fpacket, packetLength, fh, firstfill)
Definition: l0info_harp.py:19