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