OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l0gen_hawkeye.cpp
Go to the documentation of this file.
1 #include <stdint.h>
2 #include <libgen.h>
3 #include <iostream>
4 #include <fstream>
5 #include <sstream>
6 #include <string>
7 #include <iomanip>
8 
9 #include "hawkeyeUtil.h"
10 
11 #define VERSION "0.85"
12 
13 // Modification history:
14 // Programmer Organization Date Ver Description of change
15 // ---------- ------------ ---- --- ---------------------
16 // Joel Gales FutureTech 08/08/18 0.10 Original development
17 // Joel Gales FutureTech 08/30/18 0.11 Output L0 filenames generated
18 // from image start time, Add
19 // support for text output files
20 //
21 // Joel Gales FutureTech 09/20/18 0.20 Add duration to textfile,
22 // generate output name from
23 // starttime
24 // Joel Gales FutureTech 09/27/18 0.30 Add Start/Stop HWK time to
25 // textfile (Delete duration).
26 // Pass through StartTime code
27 // only once.
28 // Joel Gales SAIC 10/26/18 0.40 Code cleanup, Prepend tlm
29 // filename, exposure ID, and
30 // image counter to HWK L0 name
31 // Joel Gales SAIC 11/16/18 0.50 Add support for GPS telemetry
32 // output telemetry file
33 // Joel Gales SAIC 03/07/19 0.55 Fix error in last L0 outfile
34 // name
35 // Joel Gales SAIC 05/23/19 0.60 Overhaul to handle frame drops
36 // Joel Gales SAIC 06/19/19 0.70 Force new frame read if bad
37 // packet header
38 // Joel Gales SAIC 07/09/19 0.71 Trap negative dataLen
39 // filename
40 // Joel Gales SAIC 07/29/19 0.80 Trap bad framePtr value in
41 // getSHpacket. Check for
42 // output filesize
43 // Liang Hong SAIC 07/13/21 0.82 Handle EOI packet crossing frames
44 // Liang Hong SAIC 08/06/21 0.83 Handle missing EOI packet images
45 // Liang Hong SAIC 08/12/21 0.84 Updated frame pointer initialization,
46 // packet reading, and EOI detections
47 // Liang Hong SAIC 09/01/21 0.85 Updated End of Exposure detection
48 
49 using namespace std;
50 
51 int getZuluTime_L0Name( double tlm_time,
52  string *zuluTime, string *packetOutName);
53 
54 #define SWAP_2(x) ( (((x) & 0xff) << 8) | ((unsigned short)(x) >> 8) )
55 
56 int main (int argc, char* argv[])
57 {
58  cout << "l0gen_hawkeye" << VERSION << " ("
59  << __DATE__ << " " << __TIME__ << ")" << endl;
60 
61  if ( argc == 1) {
62  cout << endl <<
63  "l0gen_hawkeye_new input_telemetry_filename" << endl;
64 
65  return 0;
66  }
67 
68  ifstream framefile;
69  framefile.open( argv[1], ios::binary );
70  // int lastpos = framefile.tellg();
71 
72  ofstream packetOut;
73  ofstream gpsOut;
74  ofstream textOut;
75 
76  string packetOutname="TBD";
77  string zuluStartTime, zuluStopTime;
78  string prePend;
79 
80  double startHWKTime=0.0;
81  double stopHWKTime=0.0;
82 
83  uint32_t exposureID;
84  //uint32_t deltaTime;
85  //uint32_t imageRow;
86  //uint32_t finderNumber;
87 
88  uint32_t prevExposureID=999999999;
89  //uint32_t prevRow;
90  //uint32_t prevFinder;
91  //int prevDeltaTime;
92 
93  int packetLength;
94 
95  // get length of input framefile:
96  // framefile.seekg (0, ios::end);
97  // uint32_t granuleLength = framefile.tellg();
98  // framefile.seekg (0, ios::beg);
99 
100  uint8_t **packet = new uint8_t*;
101 
102  // int write=0;
103  int firstGPS=1;
104 
105  // int imageCounter=0;
106 
107  uint8_t frame[892];
108 
109  // Skip fill records and find first good packet
110  int framePtr = 2046;
111  while (framePtr == 2046 || framePtr == 2047) {
112  framefile.read( (char *) frame, 892);
113  framePtr = (frame[4] % 8)*256 + frame[5];
114  }
115  framePtr += 6;
116 
117  int frameDrop = 0;
118 
119  int prevFrameCnt = frame[2];
120 
121  // int framePtr = 6;
122 
123  // packet[7]
124  // ---------
125  // 253 -- Image data
126  // 254 -- GPS data
127  // 255 -- ADCS data
128 
129  // Image Data (packet[8])
130  // ----------
131  // 1 -- Uncompressed Image Data
132  // 2 -- Compressed Image Data
133  // 3 -- Image parameters
134  // 4 -- Telemetry
135  // 5 -- End of File
136  // 6 -- Mission Log
137 
138  packetOut.open("tempL0_0", ios::out | ios::trunc | ios::binary);
139  int tempCnt = 0;
140  int exposureCount = 0;
141  while (1) {
142  frameDrop = 0; // V0.84
143 
144  int result_getSHpacket = getSHpacket( &framefile, frame, framePtr, packet, packetLength,
145  prevFrameCnt, frameDrop);
146 
147  // V0.82, End of exposure packet detected at frame boundary
148  if (result_getSHpacket==1){
149  cout<<"exposureID="<<exposureID<<endl;
150  cout << "end of exposure" << endl;
151  packetOut.close();
152 
153  tempCnt++;
154  string tempName;
155  tempName.assign("tempL0_");
156  tempName.append(to_string(tempCnt));
157  packetOut.open(tempName.c_str(), ios::out | ios::trunc | ios::binary);
158 
159  //prevRow = 0;
160  //prevFinder = 0;
161 
162  framefile.read( (char *) frame, 892);
163 
164  // int priPacketLen = (frame[4] % 8) * 256 + frame[5];
165  framePtr = (frame[4] % 8) * 256 + frame[5];
166  while (framePtr == 2046 || framePtr == 2047) {
167  framefile.read( (char *) frame, 892);
168  framePtr = (frame[4] % 8) * 256 + frame[5];
169  }
170  prevFrameCnt = frame[2];
171  framePtr += 6; // V0.84
172  prevExposureID = 999999999;
173  continue;
174  } else {
175  if (frameDrop == -1) continue;
176 
177  long long int pos = framefile.tellg();
178  // cout << "pos: " << pos << endl;
179  if ( framefile.eof() || pos == -1) break;
180 
181  // frame drop
182  if (frameDrop == 1) {
183  frameDrop = 2;
184  continue;
185  }
186 
187  if ((frame[4] % 8)*256 + frame[5] == 2046) {
188  continue;
189  }
190  }
191 
195  //int apid = ((*packet)[0] % 8) * 256 + (*packet)[1]; // V0.85
196  //if (apid == 2047) { // V0.85
197  if ((*packet)[0]==7 && (*packet)[1]==255) { // updated End of Exposure detection, V0.85
198  cout<<"exposureID="<<exposureID<<endl; // V0.82
199  cout << "end of exposure" << endl;
200  packetOut.close();
201 
202  tempCnt++;
203  string tempName;
204  tempName.assign("tempL0_");
205  tempName.append(to_string(tempCnt));
206  packetOut.open(tempName.c_str(), ios::out | ios::trunc | ios::binary);
207 
208  //prevRow = 0;
209  //prevFinder = 0;
210 
211  framefile.read( (char *) frame, 892);
212 
213  // int priPacketLen = (frame[4] % 8) * 256 + frame[5];
214  framePtr = (frame[4] % 8) * 256 + frame[5];
215  while (framePtr == 2046 || framePtr == 2047) {
216  framefile.read( (char *) frame, 892);
217  framePtr = (frame[4] % 8) * 256 + frame[5];
218  }
219  prevFrameCnt = frame[2];
220  framePtr += 6; // V0.84
221  prevExposureID = 999999999;
222  continue;
223  }
224 
225 
229  if ((*packet)[7] == 253 && (*packet)[8] == 3) {
230 
231  uint64_t ll;
232  uint32_t ul;
233 
234  // Decode Exposure ID
235  ul = (uint32_t) (*packet)[15] << 24;
236  ul += (uint32_t) (*packet)[16] << 16;
237  ul += (uint32_t) (*packet)[17] << 8;
238  ul += (*packet)[18];
239  exposureID = ul;
240  cout<<"read exposureID="<<exposureID<<endl;
241 
242  // Decode Epoch Time
243  // Code taken from DecodeImageParams() in HawkeyeDecode.c
244  ll = (uint64_t) (*packet)[26] << 40;
245  ll += (uint64_t) (*packet)[27] << 32;
246  ll += (uint64_t) (*packet)[28] << 24;
247  ll += (uint64_t) (*packet)[29] << 16;
248  ll += (uint64_t) (*packet)[30] << 8;
249  ll += (*packet)[31];
250  ll = (ll & 0x0FFFFFFFFFF0) >> 4;
251 
252  // double tlm_time;
253 
254  //tlm_time = ll * 0.001;
255  //tlm_time -= (53*24*3600 + 14788.224);
256  //cout << "imag tepoch: " << setprecision(11) << setw(15) << tlm_time << endl;
257 
258  if (exposureID<310000000 && exposureID>180000000) { // V0.85, avoid bogus exposure id
259  //if (frameDrop == 2) {
260  if (prevExposureID != 999999999 && prevExposureID != exposureID) frameDrop = 3;
261  //}
262  prevExposureID = exposureID;
263  }
264  }
265 
266 
270  if ((*packet)[7] == 253 && (*packet)[8] == 2) {
271  uint16_t row;
272  memcpy(&row, &(*packet)[20], 2);
273  row = SWAP_2(row);
274 
275  //uint8_t infoByte = (*packet)[15];
276  //uint8_t sb = infoByte & 0x1f;
277 
278  // sd_f: 0 - finder, 1 - spectral (image)
279  //uint8_t sd_f = (infoByte & 0x40) >> 6;
280  // uint8_t dark = (infoByte & 0x80) >> 7;
281 
282  //uint32_t ul;
283 
284  //Decode Delta-Hawkeye time
285  //ul = (uint32_t) (*packet)[16] << 24;
286  //ul += (uint32_t) (*packet)[17] << 16;
287  //ul += (uint32_t) (*packet)[18] << 8;
288  //ul += (*packet)[19];
289  //deltaTime = (ul >> 4) & 0xFFFFFF;
290 
291 /* V0.84
292  if (frameDrop == 2) {
293  if (sd_f == 1 && row < prevRow)
294  frameDrop = 3;
295  if (sd_f == 0 && sb < prevFinder)
296  frameDrop = 3;
297  // if (sd_f == 1 && (((int) deltaTime) - prevDeltaTime) > 100*1000)
298  // frameDrop = 3;
299  }
300 
301  if (sd_f == 1) {
302  // cout << "band, row: " << (int) sb << " " << (int) row << endl;
303  prevRow = row;
304  } else {
305  //cout << "find, row: " << (int) sb << " " << (int) row << endl;
306  prevFinder = sb;
307  }
308  //if (sd_f == 1) prevDeltaTime = deltaTime;
309 */
310 
311  }
312 
313 
317  if ((*packet)[7] == 254) {
318 
319  // cout << "GPS Packet" << (int) (*packet)[8] << " " << packetLength << endl;
320 
321  if (firstGPS) {
322  string gpsName;
323  gpsName.assign(basename(argv[1]));
324  size_t strpos = gpsName.find(".tlm");
325  gpsName = gpsName.substr(0, strpos);
326  gpsName.append(".gps");
327 
328  gpsOut.open(gpsName.c_str(), ios::out | ios::trunc | ios::binary);
329  firstGPS = 0;
330  }
331 
332  gpsOut.write( (char *) &(*packet)[0], 161);
333 
334 
338  } else if ((*packet)[7] == 255) {
339  // ADCS packet
340  // cout << "ADCS packet: " << (int) (*packet)[3] << " " <<
341  // (int) (*packet)[8] << " " << packetLength << endl;
342 
343 
344  int16_t i16;
345  int32_t i32;
346  int32_t iyr, idy;
347  double sec;
348 
349  // Get time
350 
351  // JD 2015/01/01 = 2457023.5
352  // JD 1980/01/06 = 2444244.5
353  // delta sec = (2457023.5-2444244.5) * 24 * 3600 = 1104105600
354  // Add 16 leapsecs between 1980/01/06 and 2015/01/01
355 
356  memcpy(&i32, &(*packet)[9], 4);
357  double tepoch = (double) __builtin_bswap32(i32) - (1104105600+16);
358  // cout << "adcs tepoch: " << setprecision(11) << setw(20) << tepoch << endl;
359  tepoch2yds( tepoch, &iyr, &idy, &sec);
360  memcpy(&i32, &(*packet)[13], 4);
361  sec += ((double) __builtin_bswap32(i32)) / 4294967296.0;
362  memcpy(&i16, &(*packet)[17], 2);
363  sec -= ((double) SWAP_2(i16)) / 1000;
364  //cout << "adcs sec: " << sec << endl;
365  }
366 
367 
368  if ( frameDrop == 3) {
369  packetOut.close();
370  cout<<"exposureID="<<exposureID<<endl; // V0.82
371  cout << "Close image file" << endl; // V0.82
372 
373  tempCnt++;
374  string tempName;
375  tempName.assign("tempL0_");
376  tempName.append(to_string(tempCnt));
377 
378  packetOut.open(tempName.c_str(), ios::out | ios::trunc | ios::binary);
379 
380  //prevRow = 0;
381  //prevFinder = 0;
382 
383  frameDrop = 0;
384  // prevExposureID = 999999999; V0.85
385  }
386 
387 
388  if ((*packet)[7] != 0) {
389  packetOut.write( (char *) (*packet), packetLength);
390  delete[] (*packet);
391  }
392  } // end main loop
393 
394  delete packet;
395 
396  tempCnt++;
397  for (int i=0; i<tempCnt; i++) {
398  string tempName;
399  tempName.assign("tempL0_");
400  tempName.append(to_string(i));
401 
402  ifstream tempFile;
403  uint8_t sndpus[9];
404  uint8_t *data;
405 
406  tempFile.open( tempName.c_str(), ios::binary );
407 
408  // Check file size -- Skip if 4503 bytes
409  int fsize = tempFile.tellg();
410  tempFile.seekg( 0, std::ios::end);
411  fsize = (int) tempFile.tellg() - fsize;
412  // cout << fsize << endl;
413  if ( fsize == 4503 || fsize <= 10000000) {
414  remove( tempName.c_str());
415  continue;
416  }
417 
418  tempFile.seekg( 0, std::ios::beg);
419 
420  while (!tempFile.eof()) {
421  tempFile.read( (char *) sndpus, 9);
422  int datalen = sndpus[4]*256 + sndpus[5] - 2;
423  data = new uint8_t[datalen];
424  tempFile.read( (char *) data, datalen);
425 
426  if (sndpus[7] == 253 && sndpus[8] == 3) {
427  // Parameter Packet
428 
429  uint64_t ll;
430  uint32_t ul;
431 
432  // Decode Exposure ID
433  ul = (uint32_t) data[15-9] << 24;
434  ul += (uint32_t) data[16-9] << 16;
435  ul += (uint32_t) data[17-9] << 8;
436  ul += data[18-9];
437  exposureID = ul;
438 
439  // Decode Epoch Time
440  // Code taken from DecodeImageParams() in HawkeyeDecode.c
441  ll = (uint64_t) data[26-9] << 40;
442  ll += (uint64_t) data[27-9] << 32;
443  ll += (uint64_t) data[28-9] << 24;
444  ll += (uint64_t) data[29-9] << 16;
445  ll += (uint64_t) data[30-9] << 8;
446  ll += data[31-9];
447  ll = (ll & 0x0FFFFFFFFFF0) >> 4;
448 
449  //Decode Delta-Hawkeye time
450  ul = (uint32_t) data[36-9] << 24;
451  ul += (uint32_t) data[37-9] << 16;
452  ul += (uint32_t) data[38-9] << 8;
453  ul += data[39-9];
454  ul = (ul >> 4) & 0xFFFFFF;
455 
456  double tlm_time;
457 
458  tlm_time = ll * 0.001;
459  tlm_time -= (53*24*3600 + 14788.224);
460  getZuluTime_L0Name( tlm_time, &zuluStartTime, &packetOutname);
461  startHWKTime = tlm_time;
462 
463  tlm_time = (ll + ul) * 0.001;
464  tlm_time -= (53*24*3600 + 14788.224);
465  getZuluTime_L0Name( tlm_time, &zuluStopTime, NULL);
466  stopHWKTime = tlm_time;
467 
468  break;
469  // Note HWK time is seconds from 2015/01/01
470  }
471  }
472  tempFile.close();
473 
474  // Generate prePend
475  prePend.assign(basename(argv[1]));
476  size_t strpos = prePend.find(".dec");
477  prePend = prePend.substr(0, strpos);
478  prePend.append("_");
479 
480  std::ostringstream ss;
481  exposureCount++;
482  ss << setw(4) << setfill('0') << exposureCount;
483  prePend.append(ss.str().c_str());
484  prePend.append("_");
485 
486  prePend.append(to_string(exposureID));
487  prePend.append("_");
488 
489  string outName;
490  outName.assign(prePend);
491  outName.append(packetOutname);
492 
493  rename( tempName.c_str(), outName.c_str());
494 
495  outName.append(".txt");
496 
497  textOut.open(outName.c_str(), ios::out | ios::trunc);
498  textOut << "TlmFile=" << basename( argv[1]) << endl;
499  textOut << "StartTime=" << zuluStartTime.c_str() << endl;
500  textOut << "StopTime =" << zuluStopTime.c_str() << endl;
501  textOut << "ExposureID=" << to_string(exposureID).c_str() << endl;
502  textOut << "StartHWKTime=" << to_string(startHWKTime).c_str() << endl;
503  textOut << "StopHWKTime =" << to_string(stopHWKTime).c_str() << endl;
504  textOut.close();
505  } // for (int i=0; i<tempCnt; i++)
506 
507  framefile.close();
508  gpsOut.close();
509 
510  return 0;
511 }
512 
513 
514 int getZuluTime_L0Name( double tlm_time,
515  string *zuluTime, string *packetOutName) {
516 
517  int32_t iyr, idy;
518  int16_t mon, idm, hr, min;
519  double sec;
520 
521  tepoch2yds( tlm_time, &iyr, &idy, &sec);
522  yd2md((int16_t) iyr, (int16_t) idy, &mon, &idm);
523 
524  // cout << iyr << " " << idy << " " << sec << endl;
525 
526  stringstream ss;
527 
528  // yyyy-mn-dyThr:mn:ss.sss
529  ss = stringstream();
530  ss << setw(4) << to_string(iyr) << "-";
531  ss << setw(2) << setfill('0') << mon << "-";
532  ss << setw(2) << setfill('0') << idm << "T";
533  hr = (int) sec/3600;
534  min = (int) ((sec - hr*3600) / 60);
535  sec = sec - hr*3600 - min*60;
536  ss << setw(2) << setfill('0') << hr << ":";
537  ss << setw(2) << setfill('0') << min << ":";
538  ss << fixed << setw(6) << setprecision(3) << setfill('0') << sec;
539 
540  zuluTime->assign( ss.str());
541 
542  // HWKyyyydoyhrmnsc.L0_SE1
543  if (packetOutName != NULL) {
544  ss = stringstream();
545  ss << "HWK" << setw(4) << to_string(iyr);
546  ss << setw(3) << setfill('0') << to_string(idy);
547  ss << setw(2) << setfill('0') << hr;
548  ss << setw(2) << setfill('0') << min;
549  ss << setw(2) << setfill('0') << (int) sec;
550  ss << ".L0_SE1";
551  packetOutName->assign( ss.str());
552  }
553 
554  return 0;
555 }
These are used to scale the SD before writing it to the HDF4 file The default is and which means the product is not scaled at all Since the product is usually stored as a float inside of this is a way to write the float out as a integer l2prod min
#define VERSION
#define NULL
Definition: decode_rs.h:63
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in out
Definition: HISTORY.txt:422
float32 * pos
Definition: l1_czcs_hdf.c:35
def remove(file_to_delete)
Definition: ProcUtils.py:319
int tepoch2yds(double tepoch, int32_t *iyr, int32_t *idy, double *sec)
void yd2md(int16_t year, int16_t doy, int16_t *month, int16_t *dom)
Definition: yd2md.c:6
int main(int argc, char *argv[])
int getZuluTime_L0Name(double tlm_time, string *zuluTime, string *packetOutName)
integer, parameter double
#define SWAP_2(x)
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
#define basename(s)
Definition: l0chunk_modis.c:29
double trunc(double)
int getSHpacket(ifstream *framefile, uint8_t frame[892], int &framePtr, uint8_t **packet, int &packetLength, int &prevFrameCnt, int &frameDrop)
int32_t idy
Definition: atrem_corl1.h:161
int i
Definition: decode_rs.h:71
int32_t iyr
Definition: atrem_corl1.h:161