OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l0info_oci.cpp
Go to the documentation of this file.
1 #include <cstdio>
2 #include <sstream>
3 #include <string.h>
4 #include <unistd.h>
5 
6 #include <iomanip>
7 
8 #include "l0info_oci.h"
9 
10 using namespace std;
11 
12 
13 #define VERSION "0.68"
14 
15 // Modification history:
16 // Programmer Organization Date Ver Description of change
17 // ---------- ------------ ---- --- ---------------------
18 // Joel Gales SAIC 04/26/19 0.10 Original development
19 // based on l1agen_oci
20 // Joel Gales SAIC 06/07/19 0.20 Incorporate code changes from
21 // F.Patt
22 // Joel Gales SAIC 06/19/19 0.30 Fix single file processing
23 // Joel Gales SAIC 07/24/19 0.40 Incorporate code changes from
24 // F.Patt
25 // Joel Gales SAIC 08/02/19 0.50 Flag and ignore packets
26 // greater than 1200 bytes.
27 // Remove common routines and
28 // Place in common.cpp
29 // Joel Gales SAIC 10/25/19 0.51 Exit if EOF before finding
30 // good packet
31 // Joel Gales SAIC 11/20/19 0.60 Implement code changes from
32 // F. Patt
33 // Joel Gales SAIC 11/25/19 0.61 Change 60 to maxsc fpr dspn
34 // comparison
35 // Joel Gales SAIC 11/27/19 0.62 Change L1A name to standard
36 // Trap granules with no ancillary
37 // granules
38 // Joel Gales SAIC 01/03/20 0.63 Update call to
39 // read_oci_scan_packets
40 // Joel Gales SAIC 01/22/20 0.65 Don't break for gaps
41 // Joel Gales SAIC 01/23/20 0.66 Check for EOF when checking
42 // for zero science pixels
43 // Joel Gales SAIC 01/28/20 0.67 Bug fixes and updates
44 // Joel Gales SAIC 04/02/20 0.68 Fix scomp statement
45 
46 int main (int argc, char* argv[])
47 {
48 
49  cout << "l0info_oci " << VERSION << " ("
50  << __DATE__ << " " << __TIME__ << ")" << endl;
51 
52  if ( argc == 1) {
53  cout << endl <<
54  "l0info_oci OCI_packet_file granule_len" << endl;
55  return 0;
56  }
57 
58  fstream tfileStream;
59 
60  // OCI packet file
61  tfileStream.open( argv[optind+0], fstream::in | fstream::binary);
62  if ( tfileStream.fail()) {
63  cout << argv[optind+0] << " not found" << endl;
64  exit(1);
65  }
66 
67  uint32_t apid = 0;
68  uint32_t len = 0;
69  int32_t endfile=0;
70  uint8_t fpacket[PKTSIZE];
71  uint8_t apacket[ANCSIZE];
72  uint8_t apacket0[ANCSIZE];
73  uint32_t maxpkts = 15000;
74  int acomp = 1;
75  // int maxgap = 2000;
76 
77  uint8_t **pbuffer0 = new uint8_t *[maxpkts];
78  pbuffer0[0] = new uint8_t[PKTSIZE*maxpkts];
79  for (size_t i=1; i<maxpkts; i++) pbuffer0[i] = pbuffer0[i-1] + PKTSIZE;
80 
81  uint32_t npkts0;
82  int32_t ancind0;
83  int32_t spn0, spn;
84  vector<int32_t> tlmind0;
85 
86 
87  // Get first science or ancillary packet
88  read_packet( &tfileStream, NULL, len, apid, endfile);
89  if (len > PKTSIZE) {
90  cout << "Packet too big (" << len << ") for buffer (" << PKTSIZE << ")"
91  << endl;
92  exit(1);
93  }
94  read_packet( &tfileStream, fpacket, len, apid, endfile);
95  apid = (fpacket[0] % 8)*256 + fpacket[1];
96  int nsk=0;
97  while (apid != 636 && apid != 700 && apid != 720 && !endfile) {
98  nsk++;
99  read_packet( &tfileStream, NULL, len, apid, endfile);
100  if (len > PKTSIZE) {
101  cout << "Packet too big (" << len << ") for buffer (" << PKTSIZE << ")"
102  << endl;
103  exit(1);
104  }
105  read_packet( &tfileStream, fpacket, len, apid, endfile);
106  apid = (fpacket[0] % 8)*256 + fpacket[1];
107  //cout << "apid: " << apid << " " << nsk << endl;
108  }
109  if (endfile) {
110  cout << "No science packets found in file" << endl;
111  exit(1);
112  }
113  if (nsk > 0) cout << nsk << " packets skipped" << endl;
114 
115 
116  // Read first scan and check for ancillary packet
117  ancind0 = -1;
118  tlmind0.clear();
119 
120  int32_t iyear, iday;
121  double stime;
122 
123  // Get granule period in minutes
124  int32_t mper;
125 
126  if (argc == 3) {
127  string str = argv[optind+1];
128  istringstream( str) >> mper;
129  } else {
130  mper = 0;
131  }
132 
133  itab itable[10];
134  string dtypes[] = {"", "", "_DARK", "_SOL-D", "_SOL-M", "_LIN", "_LUN",
135  "_DIAG", "_SNAP-T", "_SNAP-S", "_STAT", "_SPEC"};
136  string smodes[] = {"", "_SDIAG", "_SRAW", "_STEST"};
137 
138  uint8_t **pbuffer = new uint8_t *[maxpkts];
139  pbuffer[0] = new uint8_t[PKTSIZE*maxpkts];
140  for (size_t i=1; i<maxpkts; i++) pbuffer[i] = pbuffer[i-1] + PKTSIZE;
141 
142  uint16_t ncps, nbbs, nrbs, nsps, ndcs, ndss, btaps[16], rtaps[16];
143 
144  uint8_t *seqerr = new uint8_t[maxpkts];
145  for (size_t i=1; i<maxpkts; i++) {
146  seqerr[i] = 0;
147  }
148  uint8_t noseq=255;
149 
151  while (!endfile) {
152 
153  while (ancind0 == -1) {
154  read_oci_scan_packets( &tfileStream, fpacket,
155  (uint8_t (*)[PKTSIZE]) &pbuffer0[0][0],
156  npkts0, spn0, ancind0, tlmind0, noseq, endfile);
157  if ( endfile) {
158  cout << "No ancillary packets found in file" << endl;
159  exit(1);
160  }
161  }
162 
163  // Check for zero science pixels
164  memcpy( apacket0, &pbuffer0[ancind0][0], ANCSIZE);
165  get_band_dims( apacket0, ncps, nbbs, nrbs, nsps, ndcs, ndss,
166  btaps, rtaps, itable);
167 
168  while (((ncps == 1 && ndcs == 1) || ancind0 == -1) && !endfile) {
169  // while ((ncps == 0 || ancind0 == -1) && !endfile) {
170  read_oci_scan_packets( &tfileStream, fpacket,
171  (uint8_t (*)[PKTSIZE]) &pbuffer0[0][0],
172  npkts0, spn0, ancind0, tlmind0, noseq, endfile);
173  //cout << ancind0 << " " << endfile << endl;
174  if (ancind0 != -1) {
175  memcpy( apacket0, &pbuffer0[ancind0][0], ANCSIZE);
176  get_band_dims( apacket0, ncps, nbbs, nrbs, nsps, ndcs, ndss,
177  btaps, rtaps, itable);
178  }
179  }
180  if (ancind0 == -1) {
181  cout << "No ancillary packets for last granule" << endl;
182  break;
183  }
184 
185  get_anc_packet_time( apacket0, iyear, iday, stime);
186 
187  double scanp = 1.0 / 5.737;
188  double stimp = stime - scanp;
189 
190  time_struct starttime, endtime;
191  starttime.iyear = iyear;
192  starttime.iday = iday;
193  starttime.sec = stime;
194 
195  uint32_t ltime;
196  //uint32_t mtime;
197  int32_t maxsc;
198 
199  if (mper > 0) {
200  ltime = (((int32_t) (stime)) / 60 / mper) * (mper*60);
201  //mtime = ltime + mper*60;
202  maxsc = mper*400; // increased for I&T
203  if (!acomp) {
204  ltime = (int32_t) stime;
205  }
206  } else {
207  cout << "Processing with single file option" << endl;
208  ltime = (int32_t) stime;
209  //mtime = ltime + 600*25;
210  maxsc = 3600*25;
211  }
212  acomp = 1;
213 
214  // Get SWIR band data mode
215  uint16_t smode;
216  get_swir_mode( (uint8_t (*)[PKTSIZE]) &pbuffer0[0][0], npkts0, smode);
217  uint16_t smodep = smode;
218  int scomp = 1;
219 
220  // Determine start and end time of granule
221  uint32_t jd0 = jday(iyear, 1, iday);
222 
223  int16_t yr16 = (int16_t) iyear;
224  int16_t doy = (int16_t) iday;
225  int16_t month, dom;
226  yd2md( yr16, doy, &month, &dom);
227 
228  int32_t ih = (int32_t) (ltime / 3600);
229  int32_t mn = (int32_t) ((ltime - ih*3600) / 60);
230  int32_t isec = (int32_t) (ltime - ih*3600 - mn*60);
231 
232  stringstream timestr, datestr;
233  timestr << setfill('0') << setw(2) << ih
234  << setfill('0') << setw(2) << mn
235  << setfill('0') << setw(2) << isec;
236 
237  // datestr << setfill('0') << setw(4) << iyear
238  // << setfill('0') << setw(3) << iday;
239  datestr << setfill('0') << setw(4) << iyear
240  << setfill('0') << setw(2) << month
241  << setfill('0') << setw(2) << dom;
242 
243  string l1a_name = string("PACE_OCI") +
244  dtypes[itable[1].dtype] + smodes[smode] + "." +
245  datestr.str() + "T" + timestr.str() + ".L1A.nc";
246 
247  // string l1a_name = string("OCI") + datestr.str() + timestr.str() +
248  // ".L1A_PACE" + dtypes[itable[1].dtype] + ".nc";
249  cout << endl << l1a_name.c_str() << endl;
250 
251  uint8_t **ancdata = new uint8_t *[maxsc+1];
252  ancdata[0] = new uint8_t[ANCSIZE*(maxsc+1)];
253  for (size_t i=1; i< (size_t) (maxsc+1); i++)
254  ancdata[i] = ancdata[i-1] + ANCSIZE;
255 
256  // Read and process OCI scans
257  uint32_t isc = 0;
258  uint32_t npkts;
259  int32_t ancind;
260  int32_t enddata = 0;
261  int dspn = 1;
262 
263  //while ( stime < mtime && acomp && !enddata && scomp && (dspn <= maxgap)) {
264  while ( !enddata && scomp) {
265  //while ( !enddata) {
266  // if ((isc % 100) == 0) cout << "Processing scan " << isc << endl;
267 
268  memcpy( &pbuffer[0][0], &pbuffer0[0][0], PKTSIZE*maxpkts);
269  ancind = ancind0;
270  npkts = npkts0;
271  spn = spn0;
272  enddata = endfile;
273 
274  // Read next scan
275  read_oci_scan_packets( &tfileStream, fpacket,
276  (uint8_t (*)[PKTSIZE]) &pbuffer0[0][0],
277  npkts0, spn0, ancind0, tlmind0, seqerr[isc],
278  endfile);
279 
280 
281  // Check for backward time jump
282  // if (stime > stimp && npkts > 1 && isc < maxsc) {
283  if (stime > stimp && npkts > 1) {
284 
285  // Save ancillary packet in array
286  if (ancind != -1) memcpy(ancdata[isc], pbuffer[ancind], ANCSIZE);
287 
288  isc++;
289  stimp = stime;
290  endtime.iyear = iyear;
291  endtime.iday = iday;
292  endtime.sec = stime;
293  } // if (stime > stimp ...
294 
295  // cout << "stime: " << stime << endl;
296 
297  // Get scan time and band dimensions for next scan
298  if (!enddata && ancind0 != -1) {
299  memcpy( apacket, &pbuffer0[ancind0][0], ANCSIZE);
300  get_anc_packet_time( apacket, iyear, iday, stime);
301  uint32_t jd = jday(iyear, 1, iday);
302  stime += (jd - jd0) * 86400;
303 
304  get_swir_mode( (uint8_t (*)[PKTSIZE]) &pbuffer0[0][0], npkts0, smode);
305  scomp = (smode == smodep);
306 
307  if ( !scomp) {
308  ih = (int32_t) (stime / 3600);
309  mn = (int32_t) ((stime - ih*3600) / 60);
310  isec = (int32_t) (stime - ih*3600 - mn*60);
311  cout << "SWIR data mode change at: "
312  << ih << " " << mn << " " << isec << endl;
313  }
314 
315  acomp = anc_compare( apacket0, apacket);
316  }
317 
318  dspn = spn0 - spn;
319  if (dspn > maxsc) cout << "Spin number gap: " << spn << " " << spn0
320  << endl;
321  } // while ( stime < mtime && acomp && !enddata)
322 
323  cout << "Scans in file: " << isc << endl;
324 
325  if (isc > 0) {
326 
327  // Need to include ancillary packet from next scan
328  if (ancind0 != -1) memcpy(ancdata[isc], apacket, ANCSIZE);
329 
330  // if ((endfile && mper <= 0) || !acomp)
331  // mtime = (uint32_t) floor(stime);
332  }
333 
334  string startstring, endstring;
335  gen_time_string( starttime, endtime, startstring, endstring);
336  cout << "Start Time=" << startstring.c_str() << endl;
337  cout << "End Time =" << endstring.c_str() << endl;
338 
339  delete[] ancdata[0];
340  delete[] ancdata;
341 
342  } // while (!endfile)
343 
345 
346  tfileStream.close();
347 
348  return 0;
349 }
350 
351 
353  string &startstring, string &endstring) {
354 
355  int16_t mon, idm;
356  int32_t ih, mn;
357  stringstream ss;
358 
359  yd2md((int16_t) starttime.iyear, (int16_t) starttime.iday, &mon, &idm);
360 
361  ih = (int) (starttime.sec/3600);
362  starttime.sec -= ih * 3600;
363  mn = (int) (starttime.sec/60);
364  starttime.sec -= mn * 60;
365 
366  // yyyy-mn-dyThr:mn:ss
367  ss = stringstream();
368  ss << setw(4) << to_string(starttime.iyear) << "-";
369  ss << setw(2) << setfill('0') << mon << "-";
370  ss << setw(2) << setfill('0') << idm << "T";
371 
372  ss << setw(2) << setfill('0') << ih << ":";
373  ss << setw(2) << setfill('0') << mn << ":";
374  ss << fixed << setw(6) << setprecision(3) <<
375  setfill('0') << starttime.sec;
376 
377  startstring = ss.str();
378 
379 
380  yd2md((int16_t) endtime.iyear, (int16_t) endtime.iday, &mon, &idm);
381 
382  ih = (int) (endtime.sec/3600);
383  endtime.sec -= ih * 3600;
384  mn = (int) (endtime.sec/60);
385  endtime.sec -= mn * 60;
386 
387  // yyyy-mn-dyThr:mn:ss.sss
388  ss = stringstream();
389  ss << setw(4) << to_string(endtime.iyear) << "-";
390  ss << setw(2) << setfill('0') << mon << "-";
391  ss << setw(2) << setfill('0') << idm << "T";
392 
393  ss << setw(2) << setfill('0') << ih << ":";
394  ss << setw(2) << setfill('0') << mn << ":";
395  ss << fixed << setw(6) << setprecision(3) <<
396  setfill('0') << endtime.sec;
397 
398  endstring = ss.str();
399 
400  return 0;
401 }
402 
int gen_time_string(time_struct &starttime, time_struct &endtime, string &startstring, string &endstring)
Definition: l0info_oci.cpp:352
int main(int argc, char *argv[])
Definition: l0info_oci.cpp:46
int get_swir_mode(uint8_t(*pbuffer)[PKTSIZE], uint32_t npkts, uint16_t &smode)
Definition: common.cpp:370
#define NULL
Definition: decode_rs.h:63
short dtype
Definition: common.h:10
int32_t jday(int16_t i, int16_t j, int16_t k)
Definition: jday.c:4
@ string
int32_t iday
Definition: l0info_oci.h:7
void yd2md(int16_t year, int16_t doy, int16_t *month, int16_t *dom)
Definition: yd2md.c:6
int get_anc_packet_time(uint8_t *apacket, int32_t &iyear, int32_t &iday, double &stime)
Definition: common.cpp:97
#define ANCSIZE
Definition: l0info_oci.h:3
int read_packet(FILE *infile, uint8_t packet[], int *len, long int *endfile)
Definition: read_packet.c:18
Definition: jd.py:1
int32_t iyear
Definition: l0info_oci.h:6
int32_t ih
Definition: atrem_corl1.h:161
int anc_compare(uint8_t *apacket0, uint8_t *apacket)
Definition: common.cpp:285
const char * str
Definition: l1c_msi.cpp:35
int read_oci_scan_packets(fstream *tfileStream, uint8_t *apacket, uint8_t(*pbuffer)[PKTSIZE], uint32_t &npkts, int32_t &spnum, int32_t &ancind, vector< int32_t > &tlmind, uint8_t &seqerr, int32_t &endfile)
Definition: common.cpp:132
Definition: common.h:9
double sec
Definition: l0info_oci.h:8
int i
Definition: decode_rs.h:71
#define PKTSIZE
Definition: common.h:7
int get_band_dims(uint8_t *apacket, uint16_t &ncp, uint16_t &nbb, uint16_t &nrb, uint16_t &nsp, uint16_t &ndc, uint16_t &nds, uint16_t *btaps, uint16_t *rtaps, itab *itable)
Definition: common.cpp:17
#define VERSION
Definition: l0info_oci.cpp:13