13 #include <boost/algorithm/string.hpp>
22 using namespace netCDF;
23 using namespace netCDF::exceptions;
31 memcpy(&ui32, cctime, 4);
34 double dsec = (
double)ccsec;
38 *iday = ccsec / 86400;
39 int32_t
jday = *iday + 2436205;
43 int32_t
msec = cctime[4] * 256 + cctime[5];
44 int32_t isec = ccsec % 86400;
45 *sec = isec +
msec / 65536.0;
50 #define VERSION "1.18.00_2024-06-12"
163 <<
"l1agen_oci OCI_packet_file granule_len\n"
164 <<
" [-g | --maxgap maximum missing scans allowed in an output file]\n"
166 " [-k | --hktlist SC_HKT_input_list]\n"
168 " [-s | --swir_loff_set SWIR_LOFF_config, list of 9 comma separated integers]\n"
169 <<
" [-t | --start_time YYYYmmddTHHMMSS or YYYY-mm-ddTHH:MM:SS]\n"
170 <<
" [-o | --outlist output_list_file]\n"
171 <<
" [-f | --outfile output_file_name]\n"
172 <<
" [-p | --nametag first part of filename (default=PACE_OCI)]\n"
173 <<
" [-d | --doi doi_string]\n"
174 <<
" [-v | --pversion processing_version]\n"
175 <<
" [-n | --noSPW no space wire header]\n\n"
176 <<
"Return 1 Fatal error\n"
177 <<
" 110 No ancillary packets found in file\n"
178 <<
" 120 No L1A file was generated\n";
186 cout <<
"Packet too big (" << len <<
") for buffer (" <<
PKTSIZE <<
")" << endl;
192 cout <<
"l1agen_oci " <<
VERSION <<
" (" << __DATE__ <<
" " << __TIME__ <<
")" << endl;
202 int return_status = 0;
205 string swir_loff_set =
"";
208 string outfname =
"";
211 string pversion =
"Unspecified";
214 static struct option long_options[] = {{
"maxgap", required_argument, 0,
'g'},
215 {
"hktlist", required_argument, 0,
'k'},
216 {
"swir_loff_set", optional_argument, 0,
's'},
217 {
"start_time", required_argument, 0,
't'},
218 {
"outlist", required_argument, 0,
'o'},
219 {
"outfile", required_argument, 0,
'f'},
220 {
"nametag", required_argument, 0,
'p'},
221 {
"doi", required_argument, 0,
'd'},
222 {
"pversion", required_argument, 0,
'v'},
223 {
"noSPW", no_argument, 0,
'n'},
227 int option_index = 0;
229 c = getopt_long(
argc, argv,
"g:k:s:t:o:f:p:d:v:n", long_options, &option_index);
237 maxgap = atoi(optarg);
243 hktlist.assign(optarg);
247 swir_loff_set.assign(optarg);
256 outlist.assign(optarg);
260 outfname.assign(optarg);
264 nametag.assign(optarg);
272 pversion.assign(optarg);
284 string l0Path = argv[optind];
285 string granuleLengthStr = argv[optind + 1];
291 if ((strcmp(granuleLengthStr.c_str(),
"0") != 0) && (
time_start.empty()) && (outfname.compare(
"") != 0)) {
292 cout <<
"Set granule length parameter to 0 or provide start time when specifying output file name."
299 std::regex time_pattern0(
"([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})");
300 std::regex time_pattern1(
"([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})");
303 strptime(
time_start.c_str(),
"%Y-%m-%dT%H:%M:%S", &tm_start);
304 }
else if (regex_match(
time_start, time_pattern1)) {
305 strptime(
time_start.c_str(),
"%Y%m%dT%H%M%S", &tm_start);
307 cout <<
"Start time format is wrong. Use YYYY-mm-ddTHH:MM:SS or YYYYmmddTHHMMSS." << endl;
313 if (outlist.compare(
"") != 0)
314 fout.open(outlist.c_str());
316 vector<string> fileNames;
324 if (fileNames.size() == 0) {
325 cout <<
"Error - No L0 files found" << endl;
328 if (tfileStream.
fail())
329 cout <<
"Failed to open tfileStream at line " << __LINE__ << endl;
337 uint32_t maxpkts = 30000;
341 uint8_t **pbuffer0 =
new uint8_t *[maxpkts];
342 pbuffer0[0] =
new uint8_t[
PKTSIZE * maxpkts];
343 for (
size_t i = 1;
i < maxpkts;
i++)
346 uint8_t **pbuffer1 =
new uint8_t *[maxpkts];
347 pbuffer1[0] =
new uint8_t[
PKTSIZE * maxpkts];
348 for (
size_t i = 1;
i < maxpkts;
i++)
354 int32_t spn0, spn, spnp;
355 vector<int32_t> tlmind0;
359 read_packet(&tfileStream, fpacket, len, apid, endfile, isSPW);
362 apid = (fpacket[0] % 8) * 256 + fpacket[1];
364 while (apid != 636 && apid != 700 && apid != 720 && !endfile) {
367 read_packet(&tfileStream, fpacket, len, apid, endfile, isSPW);
368 apid = (fpacket[0] % 8) * 256 + fpacket[1];
371 cout <<
"No science packets found in file" << endl;
375 cout << nsk <<
" packets skipped" << endl;
386 istringstream(granuleLengthStr) >> mper;
389 string dtypes[] = {
"",
"",
"_DARK",
"_SOL",
"_SPCA",
"_LIN",
"_LUN",
390 "_DIAG",
"_STAT",
"_SPEC",
"",
"_SNAP-X",
"_SNAP-I",
"_NBSB"};
391 string smodes[] = {
"",
"_SDIAG",
"_SRAW",
"_STEST"};
393 uint8_t **pbuffer =
new uint8_t *[maxpkts];
394 pbuffer[0] =
new uint8_t[
PKTSIZE * maxpkts];
395 for (
size_t i = 1;
i < maxpkts;
i++)
398 uint16_t ncps, nbbs, nrbs, nsps, ndcs, ndss, btaps[16], rtaps[16], msps;
400 int8_t *linerr =
new int8_t[maxpkts];
401 uint8_t *seqerr =
new uint8_t[maxpkts];
402 for (
size_t i = 0;
i < maxpkts;
i++) {
409 while ((ancind0 == -1) && !endfile) {
411 ancind0, tlmind0, noseq, endfile, isSPW);
415 cout <<
"No ancillary packets found in file" << endl;
424 double scanp = 0.1755;
440 memcpy(apacket0, &pbuffer0[ancind0][0],
ANCSIZE);
441 get_band_dims(apacket0, ncps, nbbs, nrbs, nsps, ndcs, ndss, btaps, rtaps, itable);
444 while ((ncps == 1 || ancind0 == -1) && !endfile) {
446 cout <<
"Ancillary packet has zero science pixels at spin " << spn0 << endl;
448 ancind0, tlmind0, noseq, endfile, isSPW);
450 memcpy(apacket0, &pbuffer0[ancind0][0],
ANCSIZE);
451 get_band_dims(apacket0, ncps, nbbs, nrbs, nsps, ndcs, ndss, btaps, rtaps, itable);
456 cout <<
"No ancillary packets for last granule" << endl;
461 cout <<
"ncps - number of CCD band pixels (ccd_pixels): " << ncps << endl;
462 cout <<
"nsps - number of SWIR band pixels: " << nsps << endl;
463 cout <<
"ndcs - number of dark collect pixels: " << ndcs << endl;
464 cout <<
"ndss - number of dark SWIR pixels: " << ndss << endl;
465 cout <<
"nbbs - number of blue bands: " << nbbs << endl;
466 cout <<
"nrbs - number of red bands: " << nrbs << endl;
470 double stimp = stime - scanp;
486 ltime = (int32_t)(tm_start.tm_hour * 3600 + tm_start.tm_min * 60 + tm_start.tm_sec);
488 ltime += (
jday(tm_start.tm_year + 1900, 1, tm_start.tm_yday + 1) -
jday(iyear, 1, iday)) * 86400;
494 mtime = mper > 0 ? ltime + mper * 60 : ltime + 600;
498 ? (uint16_t)((mper * 60 / scanp) + 2)
506 while (((stime < ltime) || (ncps == 1)) && !endfile) {
508 spn0, ancind0, tlmind0, noseq, endfile, isSPW);
510 memcpy(apacket0, &pbuffer0[ancind0][0],
ANCSIZE);
513 get_band_dims(apacket0, ncps, nbbs, nrbs, nsps, ndcs, ndss, btaps, rtaps, itable);
515 cout <<
"Ancillary packet has zero science pixels at spin " << spn0 << endl;
520 cout <<
"No science data in time range" << endl;
535 ltime = (int32_t)stime;
539 mtime = mper > 0 ? ltime + mper * 60 : ltime + 600;
543 ? (uint16_t)((mper * 60 / scanp) + 2)
550 nsps = ((nsps + 7) / 8) *
552 unsigned short nswb = 9;
554 int16_t cindex[32768];
555 int16_t sindex[32768 * nswb];
556 int16_t cdindex[32768];
557 int16_t sdindex[32768];
558 int16_t swir_loff[9];
560 for (
size_t i = 0;
i < 32768;
i++) {
562 for (
size_t j = 0;
j < nswb;
j++)
563 sindex[
i * nswb +
j] = -1;
568 if (!swir_loff_set.empty()) {
569 if (swir_loff_set.compare(
"ETU") == 0) {
572 vector<string>
parts;
573 boost::split(
parts, swir_loff_set, boost::is_any_of(
","));
574 if (
parts.size() != 9) {
575 cout <<
"Processing with single file option" << endl;
578 for (
size_t i = 0;
i < 9;
i++) {
579 swir_loff[
i] = atoi(
parts[
i].c_str());
598 uint16_t smodep = smode;
604 uint32_t jd0 =
jday(iyear, 1, iday);
605 int16_t yr16 = (int16_t)iyear;
606 int16_t doy = (int16_t)iday;
608 yd2md(yr16, doy, &month, &dom);
615 ih = (int32_t)(ltime / 3600);
616 mn = (int32_t)((ltime -
ih * 3600) / 60);
617 isec = (int32_t)(ltime -
ih * 3600 - mn * 60);
620 stringstream timestr, datestr;
621 timestr << setfill(
'0') << setw(2) <<
ih << setfill(
'0') << setw(2) << mn << setfill(
'0') << setw(2)
624 datestr << setfill(
'0') << setw(4) << iyear << setfill(
'0') << setw(2) << month << setfill(
'0')
629 char* tmpFileStr =
strdup(l0Path.c_str());
630 basenme.assign(
basename(tmpFileStr));
634 nametag.assign(
"PACE_OCI");
637 for (
size_t i = 0;
i < 10;
i++) {
638 if (itable[
i].
dtype > maxdtype)
639 maxdtype = itable[
i].
dtype;
642 if ((maxdtype != 2) && (maxdtype != 10)) {
645 cout <<
"\nWARNING: Non-Science Data is now being processed. Type: " << dtypes[
dtype] <<
"\n"
650 if ((jd0 < 2459000) &&
dtype == 11)
653 string l1a_name = outfname;
654 if (outfname.compare(
"") == 0) {
655 l1a_name = nametag + dtypes[
dtype] + smodes[smode];
658 l1a_name +=
"_" + basenme.substr(0, 4) + basenme.substr(5, 3) + basenme.substr(9, 3);
659 l1a_name +=
"." + datestr.str() +
"T" + timestr.str() +
".L1A.nc";
665 uint16_t **dark_b =
new uint16_t *[maxsc];
666 dark_b[0] =
new uint16_t[ndcs * (nbbs > 0 ? nbbs : 1) * maxsc];
667 for (
size_t i = 1;
i < maxsc;
i++)
668 dark_b[
i] = dark_b[
i - 1] + ndcs * (nbbs > 0 ? nbbs : 1);
671 uint16_t **dark_r =
new uint16_t *[maxsc];
672 dark_r[0] =
new uint16_t[ndcs * (nrbs > 0 ? nrbs : 1) * maxsc];
673 for (
size_t i = 1;
i < maxsc;
i++)
674 dark_r[
i] = dark_r[
i - 1] + ndcs * (nrbs > 0 ? nrbs : 1);
677 uint32_t **dark_s =
new uint32_t *[maxsc];
678 dark_s[0] =
new uint32_t[ndss * (nswb > 0 ? nswb : 1) * maxsc];
679 for (
size_t i = 1;
i < maxsc;
i++)
680 dark_s[
i] = dark_s[
i - 1] + ndss * (nswb > 0 ? nswb : 1);
682 uint16_t **bdark =
new uint16_t *[nbbs];
683 uint16_t **rdark =
new uint16_t *[nrbs];
684 uint32_t **sdark =
new uint32_t *[nswb];
686 uint16_t **bsci =
new uint16_t *[nbbs];
687 bsci[0] =
new uint16_t[ncps * (nbbs > 0 ? nbbs : 1)];
688 for (
size_t i = 1;
i < nbbs;
i++)
689 bsci[
i] = bsci[
i - 1] + ncps;
691 uint16_t **rsci =
new uint16_t *[nrbs];
692 rsci[0] =
new uint16_t[ncps * (nrbs > 0 ? nrbs : 1)];
693 for (
size_t i = 1;
i < nrbs;
i++)
694 rsci[
i] = rsci[
i - 1] + ncps;
696 uint32_t **ssci =
new uint32_t *[nswb];
697 ssci[0] =
new uint32_t[nsps * (nswb > 0 ? nswb : 1)];
698 for (
size_t i = 1;
i < nswb;
i++)
699 ssci[
i] = ssci[
i - 1] + nsps;
701 uint8_t **ancdata =
new uint8_t *[maxsc + 1];
702 ancdata[0] =
new uint8_t[
ANCSIZE * (maxsc + 1)];
703 for (
size_t i = 1;
i < (size_t)(maxsc + 1);
i++)
706 uint32_t maxtlm = maxsc * 10;
707 uint8_t **tlmdata =
new uint8_t *[maxtlm];
708 tlmdata[0] =
new uint8_t[
TLMSIZE * (maxtlm)];
709 for (
size_t i = 1;
i < (size_t)(maxtlm);
i++)
714 uint16_t ncpt = ncps;
715 uint16_t nspt0 = nsps;
718 uint16_t nspt = ((nspt0 + 7) / 8) * 8;
721 uint16_t **bbands =
new uint16_t *[ncpt];
722 uint16_t **rbands =
new uint16_t *[ncpt];
723 for (
size_t i = 0;
i < ncpt;
i++) {
728 int16_t *blines =
new int16_t[ncpt];
729 int16_t *rlines =
new int16_t[ncpt];
731 for (
size_t i = 0;
i < ncpt;
i++)
733 for (
size_t i = 0;
i < ncpt;
i++)
737 uint32_t **sbands =
new uint32_t *[msps];
738 for (
size_t i = 0;
i < msps;
i++) {
739 sbands[
i] =
new uint32_t[nswb];
742 int16_t *slines =
new int16_t[msps];
746 int8_t **sdfrms =
new int8_t *[maxsc];
747 sdfrms[0] =
new int8_t[ndss * maxsc];
748 for (
size_t i = 1;
i < maxsc;
i++)
749 sdfrms[
i] = sdfrms[
i - 1] + ndss;
750 memset(sdfrms[0], -1,
sizeof(int8_t) * ndss * maxsc);
752 int8_t *sfrm =
new int8_t[msps];
753 int8_t *sfrms =
new int8_t[msps];
756 cout <<
"Creating: " << l1a_name.c_str() << endl;
757 cout <<
"Starting at spin number " << spn0 << endl;
758 outfile.createl1((
char *)l1a_name.c_str(), maxsc, ncps, nbbs, nrbs, nsps, ndcs);
760 std::string maxgap_string = std::to_string(maxgap);
763 outfile.write_processing_control(hktlist, l0Path, time_start_copy, maxgap_string, nametag, swir_loff_set, outlist, l1a_name, doi, pversion, noSPW_string);
766 if (outlist.compare(
"") != 0) {
767 outlistpos = fout.tellp();
768 fout << l1a_name.c_str() <<
" ";
775 uint32_t npkts, npkt1;
777 vector<int32_t> tlmind;
783 uint16_t btype, rtype;
784 uint16_t bagg[16], ragg[16];
793 while (stime <
mtime && acomp && !enddata && scomp && (dspn <= maxgap) && isc < maxsc) {
795 if ((isc % 100) == 0) {
796 cout <<
"Processing scan " << isc << endl;
801 memcpy(&pbuffer1[0][0], &pbuffer0[0][0],
PKTSIZE * maxpkts);
811 ancind0, tlmind0, seqerr[isc], endfile, isSPW);
814 if (dspn >= 1 && npkt1 > 1) {
818 memcpy(ancdata[isc], pbuffer1[ancind],
ANCSIZE);
823 memcpy(&ancdata[isc][24], &ui32, 4);
827 memcpy(&ancdata[isc][0], &ui32, 4);
831 int ntind = tlmind.size();
832 if (ntind > 0 && ntlm < maxtlm) {
834 while (itt < ntind && ntlm < maxtlm) {
835 memcpy(tlmdata[ntlm], pbuffer1[tlmind[itt]],
TLMSIZE);
840 cout <<
"Maximum number of telemetry packets exceeded at spin: " << spn << endl;
844 for (
size_t i = 0;
i < msps;
i++) {
847 for (
size_t j = 0;
j < nswb;
j++)
852 npkts = npkt1 + npkts0;
853 if (npkts > maxpkts) {
854 cout <<
"Packets exceed max [" << maxpkts <<
"]." << endl;
856 npkts0 = npkts - npkt1;
858 memcpy(&pbuffer[0][0], &pbuffer1[0][0],
PKTSIZE * npkt1);
860 memcpy(&pbuffer[npkt1][0], &pbuffer0[0][0],
864 (uint8_t(*)[
PKTSIZE]) & pbuffer[0][0], bbands, rbands, sbands, blines, rlines,
865 slines, btype, bagg, rtype, ragg, sfrm, icheck);
867 cout <<
"Science data unpacking error in spin: " << spn << endl;
868 iret = iret | icheck;
870 bdark[0] = dark_b[isc];
871 for (
size_t i = 1;
i < nbbs;
i++)
872 bdark[
i] = bdark[
i - 1] + ndcs;
874 rdark[0] = dark_r[isc];
875 for (
size_t i = 1;
i < nrbs;
i++)
876 rdark[
i] = rdark[
i - 1] + ndcs;
878 sdark[0] = dark_s[isc];
879 for (
size_t i = 1;
i < nswb;
i++)
880 sdark[
i] = sdark[
i - 1] + ndss;
883 std::fill(bsci[0], bsci[0] + ncps * ((nbbs > 0) ? nbbs : 1), 65535);
884 std::fill(rsci[0], rsci[0] + ncps * ((nrbs > 0) ? nrbs : 1), 65535);
885 std::fill(ssci[0], ssci[0] + nsps * ((nswb > 0) ? nswb : 1), 1048575);
886 memset(sfrms, -1,
sizeof(int8_t) * msps);
889 std::fill(bdark[0], bdark[0] + ndcs * ((nbbs > 0) ? nbbs : 1), 65535);
890 std::fill(rdark[0], rdark[0] + ndcs * ((nrbs > 0) ? nrbs : 1), 65535);
891 std::fill(sdark[0], sdark[0] + ndss * ((nswb > 0) ? nswb : 1), 1048575);
894 if ((blines[0] != -1) || (rlines[0] != -1) || (slines[0] != -1)) {
896 dtype, ncpt, nsps, ndcs, ndss, nbbs, nrbs, nswb,
897 cindex, sindex, cdindex, sdindex, bbands, rbands, sbands, blines, rlines, slines,
898 bsci, rsci, ssci, bdark, rdark, sdark, linerr[isc], icheck);
900 cout <<
"Science data checking error in spin: " << spn << endl;
901 iret = iret | icheck;
904 for (
size_t i = 0;
i < msps;
i++) {
905 if (sindex[slines[
i] * nswb] > -1) {
906 sfrms[sindex[slines[
i] * nswb]] = sfrm[
i];
910 for (
size_t i = 0;
i < msps;
i++) {
911 if (sdindex[slines[
i]] > -1) {
912 sdfrms[isc][sdindex[slines[
i]]] = sfrm[
i];
917 outfile.write_oci_science_data(isc, nbbs, nrbs, nswb, ncps, nsps, bsci, rsci, ssci,
924 endtime.
iyear = iyear;
927 while (endtime.
sec > 86400)
928 endtime.
sec -= 86400;
932 ih = (int32_t)(stime / 3600);
933 mn = (int32_t)((stime -
ih * 3600) / 60);
934 isec = (int32_t)(stime -
ih * 3600 - mn * 60);
936 if (stime <= stimp && ancind != -1)
937 cout <<
"Scan " << spn <<
" out of order at" <<
ih <<
" " << mn <<
" " << isec << endl;
941 if (!enddata && ancind0 != -1) {
942 memcpy(apacket, &pbuffer0[ancind0][0],
ANCSIZE);
944 uint32_t
jd =
jday(iyear, 1, iday);
945 stime += (
jd - jd0) * 86400;
949 scomp = (smode == smodep);
952 ih = (int32_t)(stime / 3600);
953 mn = (int32_t)((stime -
ih * 3600) / 60);
954 isec = (int32_t)(stime -
ih * 3600 - mn * 60);
955 cout <<
"SWIR data mode change at: " <<
ih <<
" " << mn <<
" " << isec << endl;
963 cout <<
"Spin number gap at spin " << spnp << endl;
970 if (mper > 0 && isc < (
size_t)(maxsc - 10) && acomp) {
974 cout <<
"Scans in file: " << isc << endl;
975 cout <<
"Complete flag: " << iret << endl;
980 memcpy(ancdata[isc], apacket,
ANCSIZE);
983 outfile.write_oci_cal_data(isc, nbbs, nrbs, nswb, ndcs, ndss, dark_b[0], dark_r[0], dark_s[0],
988 int32_t *spinID =
new int32_t[isc + 100];
989 for (
size_t i = 0;
i < (isc + 100);
i++)
991 outfile.write_oci_scan_metadata(isc, ancdata[0], seqerr, linerr, spinID,
starttime);
994 outfile.write_oci_ancil_data(isc, ancdata[0]);
998 int ntind = tlmind0.size();
999 if (tlmind0.size() != 0 && dspn <= maxgap && !endfile) {
1001 while (itt < ntind && ntlm < maxtlm) {
1002 memcpy(tlmdata[ntlm], pbuffer0[tlmind0[itt]],
TLMSIZE);
1009 cout << ntlm <<
" HKT packets" << endl;
1010 outfile.write_oci_tlm_data(itable, ntlm, (uint8_t(*)[
TLMSIZE]) & tlmdata[0][0], spinID,
1016 if (hktlist.compare(
"") != 0)
1023 string sdir =
"Ascending";
1024 string edir =
"Ascending";
1025 outfile.write_oci_global_metadata(
starttime, endtime, l1a_name, sdir, edir, isc,
1027 smode, cdsmode, fout);
1031 if (outlist.compare(
"") != 0) {
1036 }
else if (
dtype == 0) {
1038 }
else if (dtypes[
dtype].substr(0, 1) ==
"_") {
1039 fout <<
" " << dtypes[
dtype].substr(1);
1056 cout <<
"Removing 0-scan file: " << l1a_name.c_str() << endl;
1057 if (outlist.compare(
"") != 0)
1058 fout.seekp(outlistpos);
1060 cout <<
"Error removing " << l1a_name.c_str() << endl;
1083 for (
size_t i = 0;
i < ncpt;
i++)
1084 if (bbands[
i] !=
NULL)
1088 for (
size_t i = 0;
i < ncpt;
i++)
1089 if (rbands[
i] !=
NULL)
1093 for (
size_t i = 0;
i < msps;
i++)
1094 if (sbands[
i] !=
NULL)
1109 delete[] ancdata[0];
1112 delete[] tlmdata[0];
1123 if (outlist.compare(
"") != 0) {
1124 if (fout.tellp() == 0) {
1126 fout.open(outlist.c_str());
1127 fout <<
"No L1A file was generated.";
1128 return_status = 120;
1137 delete[] pbuffer0[0];
1139 delete[] pbuffer1[0];
1141 delete[] pbuffer[0];
1147 return return_status;
1154 int16_t *cdindex, int16_t *sdindex, int16_t *swir_loff) {
1155 const uint16_t maxlines = 32768;
1156 const uint16_t nagg[4] = {1, 2, 4, 8};
1157 const uint16_t nswb = 9;
1158 const size_t n_table = 10;
1159 const size_t n_aggr_size = 8;
1169 for (
size_t i = 0;
i < n_table;
i++) {
1171 if ((itable[
i].
dtype != 0) && (itable[
i].
dtype != n_table)) {
1172 if (itable[
i].
lines > 0) {
1174 if (itable[
i].iagg > 3 || itable[
i].iagg < 0) {
1176 "--Error-- : the value of itable at i = %d is an out of range index %d. See %s at "
1178 int(
i), itable[
i].iagg, __FILE__, __LINE__);
1181 uint16_t iagg = nagg[itable[
i].
iagg];
1182 uint16_t
lines = itable[
i].lines;
1184 if ((loff +
lines) > maxlines) {
1185 cout <<
"Mode table entry " <<
i <<
" exceeds max lines" << endl;
1186 lines = maxlines - loff - iagg;
1189 uint16_t cp =
lines / iagg;
1190 for (
size_t j = 0;
j < cp;
j++) {
1191 uint16_t cind = loff +
j * iagg;
1192 cindex[cind] = cpix +
j;
1197 uint16_t sp =
lines / n_aggr_size;
1198 for (
size_t j = 0;
j < sp;
j++) {
1199 uint16_t sind = (loff / n_aggr_size +
j) * n_aggr_size;
1201 for (
size_t k = 0;
k < nswb;
k++) {
1204 if (itable[
i].
dtype != 2) {
1205 sloff = swir_loff[
k];
1207 if ((sind - sloff) < 0) {
1208 printf(
"--Error-- : %s:%d : SWIR line offset caused a negative index\n", __FILE__,
1212 sindex[(sind - sloff) * nswb +
k] =
spix +
j;
1218 if (itable[
i].
dtype == 2) {
1219 for (
size_t j = 0;
j < cp;
j++) {
1220 uint16_t cind = loff +
j * iagg;
1221 cdindex[cind] = cdpix +
j;
1225 for (
size_t j = 0;
j < sp;
j++) {
1226 uint16_t sind = loff +
j * n_aggr_size;
1227 sdindex[sind] = sdpix +
j;
1232 cout <<
"Data zone " <<
i <<
" type " << itable[
i].
dtype <<
" has zero lines" << endl;
1236 if (loff >= maxlines)
1244 uint16_t &
nbands, uint16_t btaps[16], uint16_t rtaps[16], uint8_t (*pbuffer)[
PKTSIZE],
1245 uint16_t **bbands, uint16_t **rbands, uint32_t **sbands, int16_t *blines, int16_t *rlines,
1246 int16_t *slines, uint16_t &btype, uint16_t bagg[16], uint16_t &rtype, uint16_t ragg[16],
1247 int8_t *sfrm,
int &iret) {
1251 for (
size_t i = 0;
i < ncps;
i++) {
1255 for (
size_t i = 0;
i < msps;
i++)
1258 std::vector<int> iswav = {0, 1, 2, 3, 4, 5, 6, 7, 8};
1269 uint16_t **ccddata =
new uint16_t *;
1270 uint16_t ossdata[16];
1287 iswav = {3, 0, 1, 2, 8, 6, 7, 5, 4};
1290 for (
size_t ipkt = 0; ipkt < npkts; ipkt++) {
1291 apid = (pbuffer[ipkt][0] % 8) * 256 + pbuffer[ipkt][1];
1292 uint16_t
dtype = (pbuffer[ipkt][12] % 64) / 4;
1293 memcpy(&ui32, &pbuffer[ipkt][6], 4);
1297 if (apid == 700 &&
dtype > 0 && spn ==
spin) {
1298 unpack_ccd_packet(pbuffer[ipkt], btaps, rtaps, ccdid,
line,
dtype, iagg, jagg,
nbands, ccddata,
1309 memcpy(bagg, jagg, 16 *
sizeof(uint16_t));
1310 for (
size_t i = 0;
i < ncps;
i++) {
1313 bbands[
i] =
new uint16_t[
nbands];
1315 bbands[
i][
j] = 65535;
1321 for (
size_t i = 0;
i < 16;
i++)
1322 if (jagg[
i] != bagg[
i])
1327 cout <<
"Data type or spectral aggregation error, CCDID: " << ccdid
1328 <<
" Line: " <<
line << endl;
1337 memcpy(bbands[ibpix], &(*ccddata)[0],
nb *
sizeof(uint16_t));
1338 blines[ibpix] = (
line / iagg) * iagg;
1342 cout <<
"Number of blue pixels exceeded in spin: " <<
spin
1343 <<
" in packet (0-based): " << ipkt << endl;
1351 memcpy(ragg, jagg, 16 *
sizeof(uint16_t));
1352 for (
size_t i = 0;
i < ncps;
i++) {
1355 rbands[
i] =
new uint16_t[
nbands];
1357 rbands[
i][
j] = 65535;
1362 for (
size_t i = 0;
i < 16;
i++)
1363 if (jagg[
i] != ragg[
i])
1368 cout <<
"Data type or spectral aggregation error, CCDID: " << ccdid
1369 <<
" Line: " <<
line << endl;
1379 memcpy(rbands[irpix], &(*ccddata)[0],
nb *
sizeof(uint16_t));
1380 rlines[irpix] = (
line / iagg) * iagg;
1384 cout <<
"Number of red pixels exceeded in spin: " <<
spin
1385 <<
" in packet (0-based): " << ipkt << endl;
1398 if (apid == 720 && (ispix + 7) < msps && spn ==
spin) {
1401 uint32_t swirdata[8 * 9];
1406 for (
size_t i = 0;
i < 8;
i++) {
1407 slines[ispix +
i] = (
lines[
i] / 8) * 8;
1408 for (
size_t j = 0;
j < 9;
j++)
1409 sbands[ispix +
i][
j] = swirdata[iswav[
j] + 9 *
i];
1411 memcpy(&sfrm[ispix], swirfrm, 8 *
sizeof(uint8_t));
1416 if ((ibpix <= 0) || (ibpix > ncps))
1418 if ((irpix <= 0) || (irpix > ncps))
1420 if ((ispix <= 0) || (ispix > msps))
1432 uint32_t &
line, uint16_t &
dtype, uint16_t &iagg, uint16_t jagg[16], uint16_t &
nbands,
1433 uint16_t **ccddata, uint16_t ossdata[16]) {
1435 ccdid = (packet[12] & 64) / 64;
1436 line = packet[10] * 256 + packet[11];
1437 dtype = (packet[12] % 64) / 4;
1438 uint16_t oss = packet[17] % 16;
1439 iagg = packet[12] % 4;
1440 uint16_t agg[4] = {1, 2, 4, 8};
1451 uint16_t its[4] = {0, 4, 8, 12};
1453 for (
size_t i = 0;
i < 4;
i++) {
1454 jagg[its[
i]] = agg[(packet[13 +
i] & 192) / 64];
1455 jagg[its[
i] + 1] = agg[(packet[13 +
i] & 48) / 16];
1456 jagg[its[
i] + 2] = agg[(packet[13 +
i] & 12) / 4];
1457 jagg[its[
i] + 3] = agg[(packet[13 +
i] & 3)];
1459 for (
size_t i = 0;
i < 16;
i++)
1460 taps[
i] = 32 * ftaps[
i] / jagg[
i];
1464 for (
size_t i = 0;
i < 16;
i++)
1468 *ccddata =
new uint16_t[
nbands];
1471 uint16_t ibnd =
nbands - 1;
1474 for (
size_t j = 0;
j < 16;
j++) {
1478 for (
size_t i = 0;
i < taps[
j];
i++) {
1480 memcpy(&ui16, &packet[
ioff + 2 *
i], 2);
1482 memcpy(&(*ccddata)[ibnd -
i], &ui16, 2);
1485 ioff += 2 * taps[
j];
1490 for (
size_t j = 0;
j < 16;
j++) {
1492 memcpy(&ui16, &packet[
ioff + 2 *
j], 2);
1494 memcpy(&ossdata[
j], &ui16, 2);
1512 for (
size_t i = 0;
i < 8;
i++) {
1514 if ((
unsigned(packet[
ioff]) == 255) && (
unsigned(packet[
ioff + 1]) == 255)) {
1518 slines[
i] = packet[
ioff] * 256 + packet[
ioff + 1];
1521 smeta = packet[
ioff + 2];
1522 swirfrm[
i] = smeta % 8;
1534 uint16_t nbbs, uint16_t nrbs, uint16_t nswb, int16_t *cindex, int16_t *sindex,
1535 int16_t *cdindex, int16_t *sdindex, uint16_t **bbands, uint16_t **rbands,
1536 uint32_t **sbands, int16_t *blines, int16_t *rlines, int16_t *slines, uint16_t **bsci,
1537 uint16_t **rsci, uint32_t **ssci, uint16_t **bdark, uint16_t **rdark,
1538 uint32_t **sdark, int8_t &linerr,
int &icheck) {
1542 bool linchk = (
dtype != 5);
1546 bool bb = ((bbands[0] !=
NULL) && (blines[0] != -1));
1548 bool rb = ((rbands[0] !=
NULL) && (rlines[0] != -1));
1550 bool sb = ((sbands[0] !=
NULL) && (slines[0] != -1));
1554 if (bbands[0] ==
NULL)
1562 for (
size_t i = 0;
i < ncpt;
i++) {
1563 if (blines[
i] == -1)
1565 if (cindex[blines[
i]] == -1)
1568 for (
size_t i = 0;
i < ncpt;
i++)
1569 if (cindex[blines[
i]] != (cindex[blines[0]] + (
int)
i)) {
1570 cout <<
"Blue CCD line sequence error" << endl;
1579 for (
size_t i = 0;
i < ncpt;
i++) {
1580 if (blines[
i] == -1)
1583 if (cindex[blines[
i]] > -1)
1586 if ((nbs < ncpt - ndcs) && linchk) {
1587 cout <<
"Missing blue band science pixels" << endl;
1591 for (
size_t i = 0;
i < ncpt;
i++) {
1592 if (blines[
i] == -1)
1595 if (cindex[blines[
i]] > -1) {
1596 for (
size_t j = 0;
j < nbb;
j++) {
1597 bsci[
j][cindex[blines[
i]]] = bbands[
i][
j];
1604 for (
size_t i = 0;
i < ncpt;
i++) {
1605 if (blines[
i] == -1)
1608 if (cdindex[blines[
i]] > -1)
1612 cout <<
"Missing blue band dark pixels" << endl;
1616 for (
size_t i = 0;
i < ncpt;
i++) {
1617 if (blines[
i] == -1)
1620 if (cdindex[blines[
i]] > -1) {
1622 int k = cdindex[blines[
i]];
1623 if (
k >= ndcs ||
k < 0) {
1628 for (
size_t j = 0;
j < nbb;
j++) {
1629 bdark[
j][
k] = bbands[
i][
j];
1637 if (rbands[0] ==
NULL)
1645 for (
size_t i = 0;
i < ncpt;
i++) {
1646 if (rlines[
i] == -1)
1648 if (cindex[rlines[
i]] == -1)
1651 for (
size_t i = 0;
i < ncpt;
i++) {
1652 if (rlines[
i] == -1)
1654 if (cindex[rlines[
i]] != (cindex[rlines[0]] + (
int)
i)) {
1655 cout <<
"Red CCD line sequence error" << endl;
1665 for (
size_t i = 0;
i < ncpt;
i++) {
1666 if (rlines[
i] == -1)
1669 if (cindex[rlines[
i]] > -1)
1673 if ((nrs < ncpt - ndcs) && linchk) {
1674 cout <<
"Missing red band science pixels" << endl;
1678 for (
size_t i = 0;
i < ncpt;
i++) {
1680 if (rlines[
i] == -1)
1682 if (rlines[
i] > -1 && cindex[rlines[
i]] > -1) {
1683 for (
size_t j = 0;
j < nrb;
j++) {
1684 rsci[
j][cindex[rlines[
i]]] = rbands[
i][
j];
1691 for (
size_t i = 0;
i < ncpt;
i++) {
1692 if (rlines[
i] == -1)
1695 if (cdindex[rlines[
i]] > -1)
1700 cout <<
"Missing red band dark pixels" << endl;
1704 for (
size_t i = 0;
i < ncpt;
i++) {
1705 if (rlines[
i] == -1)
1708 if (cdindex[rlines[
i]] > -1) {
1710 int k = cdindex[rlines[
i]];
1711 if (
k >= ndcs ||
k < 0) {
1716 for (
size_t j = 0;
j < nrb;
j++) {
1717 rdark[
j][
k] = rbands[
i][
j];
1723 if (mb != -1 || mr != -1) {
1725 cout <<
"Invalid line numbers" << endl;
1735 for (
size_t i = 0;
i < nspt0;
i++) {
1736 if (slines[
i] > -1) {
1738 for (
size_t j = 0;
j < nswb;
j++) {
1739 if (sindex[slines[
i] * nswb +
j] >
1741 ssci[
j][sindex[slines[
i] * nswb +
j]] = sbands[
i][
j];
1747 if (nss < nspt0 - ndss) {
1748 cout <<
"Missing SWIR band science pixels" << endl;
1754 for (
size_t i = 0;
i < nspt0;
i++) {
1755 if (slines[
i] == -1)
1758 if (sdindex[slines[
i]] > -1)
1766 for (
size_t i = 0;
i < nspt0;
i++) {
1768 if (slines[
i] == -1)
1770 if (sdindex[slines[
i]] > -1) {
1772 int k = sdindex[slines[
i]];
1773 if (
k >= ndss ||
k < 0) {
1774 cout <<
"sdark indice out of bounds: " <<
k << endl;
1778 for (
size_t j = 0;
j < nswb;
j++) {
1779 sdark[
j][
k] = sbands[
i][
j];
1791 uint8_t chks[4],
tmp[4];
1792 memcpy(chks, &dat[0], 4);
1794 for (
int i = 1;
i < nc;
i++) {
1795 memcpy(&
tmp, &dat[4 *
i], 4);
1796 for (
int j = 0;
j < 4;
j++)
1797 chks[
j] = chks[
j] ^
tmp[
j];
1801 for (
int i = 0;
i < 4;
i++)
1812 int l1aFile::createl1(
char *l1_filename, uint16_t maxsc, uint16_t ncps, uint16_t nbbs, uint16_t nrbs,
1813 uint16_t nsps, uint16_t ndcs) {
1815 l1afile =
new NcFile(l1_filename, NcFile::replace);
1816 }
catch (NcException &e) {
1817 cerr << e.what() <<
"\nFailure creating OCI L1A file: " << l1_filename << endl;
1821 fileName.assign(l1_filename);
1823 ifstream oci_l1a_data_structure;
1825 string dataStructureFile;
1826 dataStructureFile.assign(
"$OCDATAROOT/oci/OCI_Level-1A_Data_Structure.cdl");
1829 oci_l1a_data_structure.open(dataStructureFile.c_str(), ifstream::in);
1830 if (oci_l1a_data_structure.fail() ==
true) {
1831 cout <<
"\"" << dataStructureFile.c_str() <<
"\" not found" << endl;
1837 getline(oci_l1a_data_structure,
line);
1839 size_t pos =
line.find(
"dimensions:");
1848 getline(oci_l1a_data_structure,
line);
1850 if (
line.substr(0, 2) ==
"//")
1853 size_t pos =
line.find(
" = ");
1854 size_t semi =
line.find(
" ;");
1855 if (
pos == string::npos)
1861 string dimString =
line.substr(
pos + 2, semi - (
pos + 2));
1862 if (dimString.find(
"UNLIMITED") == string::npos) {
1866 dimSize = NC_UNLIMITED;
1871 iss >> skipws >>
line;
1876 if (
line.compare(
"ccd_pixels") == 0) {
1880 if (
line.compare(
"SWIR_pixels") == 0) {
1884 if (
line.compare(
"DC_pixels") == 0) {
1888 if (
line.compare(
"blue_bands") == 0) {
1892 if (
line.compare(
"red_bands") == 0) {
1897 ncDims[ndims++] = l1afile->addDim(
line, dimSize);
1898 }
catch (NcException &e) {
1900 cerr <<
"Failure creating dimension: " <<
line.c_str() << endl;
1908 getline(oci_l1a_data_structure,
line);
1910 size_t pos =
line.find(
"// global attributes");
1916 getline(oci_l1a_data_structure,
line);
1917 size_t pos =
line.find(
" = ");
1918 if (
pos == string::npos)
1921 string attValue =
line.substr(
pos + 3);
1924 attValue.erase(attValue.length() - 2);
1925 size_t begQuote = attValue.find(
'"');
1926 size_t endQuote = attValue.find_last_of(
'"');
1927 if (begQuote == string::npos)
1929 attValue = attValue.substr(begQuote + 1, endQuote - begQuote - 1);
1931 istringstream iss(
line.substr(
pos + 2));
1934 iss >> skipws >>
line;
1937 if (
line.substr(0, 2) ==
"//")
1941 attName.assign(
line.substr(1).c_str());
1944 l1afile->putAtt(attName, attValue);
1945 }
catch (NcException &e) {
1947 cerr <<
"Failure creating attribute: " + attName << endl;
1956 getline(oci_l1a_data_structure,
line);
1960 if (
line.substr(0, 1).compare(
"}") == 0) {
1961 oci_l1a_data_structure.close();
1966 size_t pos =
line.find(
"group:");
1971 istringstream iss(
line.substr(6, string::npos));
1972 iss >> skipws >>
line;
1974 ncGrps[ngrps++] = l1afile->addGroup(
line);
1982 string flag_meanings;
1986 double fill_value = 0.0;
1988 vector<NcDim> varVec;
1994 getline(oci_l1a_data_structure,
line);
1996 getline(oci_l1a_data_structure,
line);
1999 if (
line.substr(0, 2) ==
"//")
2001 if (
line.length() == 0)
2003 if (
line.substr(0, 1).compare(
"\r") == 0)
2005 if (
line.substr(0, 1).compare(
"\n") == 0)
2011 if (
pos == string::npos) {
2016 units.c_str(), (
void *)&fill_value, flag_values.c_str(),
2020 flag_values.assign(
"");
2021 flag_meanings.assign(
"");
2022 reference.assign(
"");
2031 if (
line.substr(0, 10).compare(
"} // group") == 0)
2036 istringstream iss(
line);
2037 iss >> skipws >> varType;
2040 if (varType.compare(
"char") == 0)
2042 else if (varType.compare(
"byte") == 0)
2044 else if (varType.compare(
"short") == 0)
2046 else if (varType.compare(
"int") == 0)
2048 else if (varType.compare(
"long") == 0)
2050 else if (varType.compare(
"float") == 0)
2052 else if (varType.compare(
"real") == 0)
2054 else if (varType.compare(
"double") == 0)
2056 else if (varType.compare(
"ubyte") == 0)
2058 else if (varType.compare(
"ushort") == 0)
2060 else if (varType.compare(
"uint") == 0)
2062 else if (varType.compare(
"ulong") == 0)
2064 else if (varType.compare(
"int64") == 0)
2066 else if (varType.compare(
"uint64") == 0)
2071 size_t posSname =
line.substr(0,
pos).rfind(
" ");
2072 sname.assign(
line.substr(posSname + 1,
pos - posSname - 1));
2076 this->
parseDims(line.substr(
pos + 1, string::npos), varVec);
2077 numDims = varVec.size();
2081 size_t posEql =
line.find(
"=");
2082 size_t pos1qte =
line.find(
"\"");
2083 size_t pos2qte =
line.substr(pos1qte + 1, string::npos).find(
"\"");
2089 if (
attrName.compare(
"long_name") == 0) {
2090 lname.assign(
line.substr(pos1qte + 1, pos2qte));
2095 else if (
attrName.compare(
"units") == 0) {
2096 units.assign(
line.substr(pos1qte + 1, pos2qte));
2101 else if (
attrName.compare(
"_FillValue") == 0) {
2103 iss.str(
line.substr(posEql + 1, string::npos));
2108 else if (
attrName.compare(
"flag_values") == 0) {
2109 flag_values.assign(
line.substr(pos1qte + 1, pos2qte));
2110 }
else if (
attrName.compare(
"flag_masks") == 0) {
2111 flag_values.assign(
line.substr(pos1qte + 1, pos2qte));
2115 else if (
attrName.compare(
"flag_meanings") == 0) {
2116 flag_meanings.assign(
line.substr(pos1qte + 1, pos2qte));
2120 else if (
attrName.compare(
"reference") == 0) {
2121 reference.assign(
line.substr(pos1qte + 1, pos2qte));
2125 else if (
attrName.compare(
"valid_min") == 0) {
2127 iss.str(
line.substr(posEql + 1, string::npos));
2133 else if (
attrName.compare(
"valid_max") == 0) {
2135 iss.str(
line.substr(posEql + 1, string::npos));
2154 size_t pos = dimString.find(
",", curPos);
2155 if (
pos == string::npos)
2156 pos = dimString.find(
")");
2159 istringstream iss(dimString.substr(curPos,
pos - curPos));
2160 iss >> skipws >> varDimName;
2162 for (
int i = 0;
i < ndims;
i++) {
2164 dimName = ncDims[
i].getName();
2165 }
catch (NcException &e) {
2167 cerr <<
"Failure accessing dimension: " + dimName << endl;
2171 if (varDimName.compare(dimName) == 0) {
2173 varDims.push_back(ncDims[
i]);
2177 if (dimString.substr(
pos, 1).compare(
")") == 0)
2187 uint16_t nsps, uint16_t **bsci, uint16_t **rsci, uint32_t **ssci,
2195 vector<size_t>
start;
2196 vector<size_t> count_b;
2197 vector<size_t> count_r;
2198 vector<size_t> count_s;
2199 vector<size_t> count_0;
2201 vector<size_t> start_frms;
2202 vector<size_t> count_frms;
2204 NcGroup gid = l1afile->getGroup(
"science_data");
2205 blu_bands = gid.getVar(
"sci_blue");
2206 red_bands = gid.getVar(
"sci_red");
2207 swir_bands = gid.getVar(
"sci_SWIR");
2208 swir_frms = gid.getVar(
"frm_type_SWIR");
2214 count_b.push_back(1);
2215 count_b.push_back(nbbs);
2216 count_b.push_back(ncps);
2218 count_r.push_back(1);
2219 count_r.push_back(nrbs);
2220 count_r.push_back(ncps);
2222 count_s.push_back(1);
2223 count_s.push_back(nswb);
2224 count_s.push_back(nsps);
2226 count_0.push_back(1);
2227 count_0.push_back(1);
2228 count_0.push_back(1);
2238 (count_b[1] > 0) ? blu_bands.putVar(
start, count_b, &bsci[0][0])
2239 : blu_bands.putVar(
start, count_0, &bsci[0][0]);
2240 (count_r[1] > 0) ? red_bands.putVar(
start, count_r, &rsci[0][0])
2241 : red_bands.putVar(
start, count_0, &rsci[0][0]);
2242 (count_s[1] > 0) ? swir_bands.putVar(
start, count_s, &ssci[0][0])
2243 : swir_bands.putVar(
start, count_0, &ssci[0][0]);
2245 start_frms.push_back(isc);
2246 start_frms.push_back(0);
2248 count_frms.push_back(1);
2249 count_frms.push_back(nsps);
2251 if (count_frms[1] > 0)
2252 swir_frms.putVar(start_frms, count_frms, sfrms);
2258 uint16_t ndss, uint16_t *dark_b, uint16_t *dark_r, uint32_t *dark_s,
2263 vector<size_t>
start;
2264 vector<size_t> count_b;
2265 vector<size_t> count_r;
2266 vector<size_t> count_s;
2267 vector<size_t> count_0;
2273 count_b.push_back(isc);
2274 count_b.push_back(nbbs);
2275 count_b.push_back(ndcs);
2277 count_r.push_back(isc);
2278 count_r.push_back(nrbs);
2279 count_r.push_back(ndcs);
2281 count_s.push_back(isc);
2282 count_s.push_back(nswb);
2283 count_s.push_back(ndss);
2285 count_0.push_back(1);
2286 count_0.push_back(1);
2287 count_0.push_back(1);
2289 NcGroup gid = l1afile->getGroup(
"onboard_calibration_data");
2290 blu_dark = gid.getVar(
"DC_blue");
2291 red_dark = gid.getVar(
"DC_red");
2292 swr_dark = gid.getVar(
"DC_SWIR");
2295 (count_b[1] > 0) ? blu_dark.putVar(
start, count_b, dark_b) : blu_dark.putVar(
start, count_0, dark_b);
2296 (count_r[1] > 0) ? red_dark.putVar(
start, count_r, dark_r) : red_dark.putVar(
start, count_0, dark_r);
2297 (count_s[1] > 0) ? swr_dark.putVar(
start, count_s, dark_s) : swr_dark.putVar(
start, count_0, dark_s);
2300 vector<size_t> start_sdfrm;
2301 vector<size_t> count_sdfrm;
2303 start_sdfrm.push_back(0);
2304 start_sdfrm.push_back(0);
2305 count_sdfrm.push_back(isc);
2306 count_sdfrm.push_back(ndss);
2308 sdfrm_dark = gid.getVar(
"frm_type_DC_SWIR");
2310 if (count_sdfrm[1] > 0)
2311 sdfrm_dark.putVar(start_sdfrm, count_sdfrm, sdfrms);
2318 vector<size_t>
start;
2319 vector<size_t>
count;
2321 count.push_back(isc);
2323 uint32_t ancap = 636;
2325 int32_t iyear, iday;
2330 double *stimes =
new double[isc];
2331 short int toff = 24;
2332 uint32_t *scss =
new uint32_t[isc];
2333 int32_t *scsu =
new int32_t[isc];
2335 double firstGoodTime =
BAD_FLT;
2336 for (
size_t i = 0;
i < isc;
i++) {
2337 uint32_t apid = (ancdata[
i *
ANCSIZE] % 8) * 256 + ancdata[
i *
ANCSIZE + 1];
2338 if (apid == ancap) {
2341 firstGoodTime = stime;
2342 if (stime < firstGoodTime)
2349 memcpy(&ui32, &ancdata[
i *
ANCSIZE + toff + 4], 4);
2351 memcpy(&ui32, &ancdata[
i *
ANCSIZE + toff + 8], 4);
2352 scsu[
i] =
SWAP_4(ui32) / 4096;
2360 NcGroup gid = l1afile->getGroup(
"scan_line_attributes");
2365 var = gid.getVar(
"scan_start_time");
2369 timeStr = timeStr.substr(0, 10);
2370 timeStr.insert(0,
"seconds since ");
2371 var.putAtt(
"units", timeStr);
2376 var = gid.getVar(
"scan_start_CCSDS_sec");
2380 var = gid.getVar(
"scan_start_CCSDS_usec");
2384 uint8_t *hamSide =
new uint8_t[isc];
2386 for (
size_t i = 0;
i < isc;
i++) {
2394 hamSide[
i] = (uint8_t)ham;
2396 var = gid.getVar(
"HAM_side");
2402 for (
size_t i = 0;
i < isc;
i++) {
2404 memcpy(&ui32, &ancdata[
i *
ANCSIZE + toff], 4);
2407 var = gid.getVar(
"spin_ID");
2411 var = gid.getVar(
"pseq_flag");
2413 var = gid.getVar(
"line_flag");
2426 vector<size_t>
start;
2427 vector<size_t>
count;
2434 int16_t *anctlm =
new int16_t[6 * isc];
2435 for (
size_t i = 0;
i < 6 * isc;
i++)
2437 for (
size_t i = 0;
i < isc;
i++) {
2438 for (
size_t j = 0;
j < 6;
j++) {
2448 short nagg[4] = {1, 2, 4, 8};
2451 int32_t iyear, iday;
2454 uint32_t
jd =
jday(iyear, 1, iday);
2456 for (
size_t i = 0;
i < 10;
i++) {
2458 if ((
jd < 2459000) && (
dtype[
i] == 11))
2460 iagg[
i] = ancdata[
ioff + 2] % 4;
2462 iagg[
i] = nagg[iagg[
i]];
2471 uint16_t btap = ancdata[
ioff + 2] * 256 + ancdata[
ioff + 3];
2472 uint16_t rtap = ancdata[
ioff + 0] * 256 + ancdata[
ioff + 1];
2478 memcpy(&ui32, &ancdata[
ioff + 8], 4);
2479 uint32_t bagg =
SWAP_4(ui32);
2481 memcpy(&ui32, &ancdata[
ioff + 4], 4);
2482 uint32_t ragg =
SWAP_4(ui32);
2484 int16_t baggs[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2485 int16_t raggs[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2492 for (
size_t i = 0;
i < 16;
i++) {
2493 uint16_t btaps = (btap & ken) / ken;
2495 baggs[15 -
i] = nagg[(bagg & kag) / lag];
2496 uint16_t rtaps = (rtap & ken) / ken;
2498 raggs[15 -
i] = nagg[(ragg & kag) / lag];
2510 gid = l1afile->getGroup(
"spatial_spectral_modes");
2512 count.push_back(10);
2515 var = gid.getVar(
"spatial_zone_data_type");
2519 var = gid.getVar(
"spatial_aggregation");
2523 var = gid.getVar(
"spatial_zone_lines");
2527 count.push_back(16);
2530 var = gid.getVar(
"blue_spectral_mode");
2534 var = gid.getVar(
"red_spectral_mode");
2540 gid = l1afile->getGroup(
"engineering_data");
2543 count.push_back(isc);
2548 var = gid.getVar(
"ancillary_tlm");
2555 int32_t *aggcon =
new int32_t[isc];
2556 for (
size_t i = 0;
i < isc;
i++) {
2560 var = gid.getVar(
"agg_control");
2565 uint16_t *bagerr =
new uint16_t[isc];
2566 uint16_t *ragerr =
new uint16_t[isc];
2567 for (
size_t i = 0;
i < isc;
i++) {
2568 memcpy(&ui16, &ancdata[(
i + 1) *
ANCSIZE +
ioff + 12], 2);
2571 memcpy(&ui16, &ancdata[(
i + 1) *
ANCSIZE +
ioff + 14], 2);
2574 var = gid.getVar(
"blue_agg_error");
2576 var = gid.getVar(
"red_agg_error");
2582 int32_t *digerr =
new int32_t[isc];
2583 for (
size_t i = 0;
i < isc;
i++) {
2584 memcpy(&i32, &ancdata[(
i + 1) *
ANCSIZE +
ioff + 20], 4);
2587 var = gid.getVar(
"dig_card_error");
2607 const uint16_t dauapid = 723;
2608 const uint16_t ddcapid = 701;
2609 const uint16_t mceapid = 713;
2610 const uint16_t encapid = 712;
2611 const uint16_t scaapid = 717;
2612 const uint16_t senapid = 716;
2613 const uint16_t tcapid = 656;
2614 const uint16_t ddctapid = 703;
2615 const uint16_t dauctapid = 744;
2616 const uint16_t icdumcetapid = 745;
2622 uint16_t nicthrm = 74;
2623 uint16_t ndctmps = 69;
2624 uint16_t nimtmps = 16;
2625 uint16_t nadclat = 4;
2636 int16_t *tlmzs =
new int16_t[2];
2637 int16_t *tlmzd =
new int16_t[2];
2638 uint16_t tditime = 0;
2641 string l1afile_epoch_str =
unix2isodate(l1afile_epoch,
'G');
2642 l1afile_epoch_str = l1afile_epoch_str.substr(0, 10);
2643 l1afile_epoch_str.insert(0,
"seconds since ");
2645 double *dausec =
new double[ntlm];
2646 for (
size_t i = 0;
i < ntlm;
i++)
2648 int32_t *dauspin =
new int32_t[ntlm];
2649 for (
size_t i = 0;
i < ntlm;
i++)
2651 uint8_t *dautlm =
new uint8_t[620 * ntlm];
2652 for (
size_t i = 0;
i < 620 * ntlm;
i++)
2654 double *ddcsec =
new double[ntlm];
2655 for (
size_t i = 0;
i < ntlm;
i++)
2657 uint8_t *ddctlm =
new uint8_t[524 * ntlm];
2658 for (
size_t i = 0;
i < 524 * ntlm;
i++)
2660 int32_t *mcespin =
new int32_t[ntlm];
2661 for (
size_t i = 0;
i < ntlm;
i++)
2663 uint8_t *mcetlm =
new uint8_t[480 * ntlm];
2664 for (
size_t i = 0;
i < 480 * ntlm;
i++)
2666 int32_t *encspin =
new int32_t[ntlm];
2667 for (
size_t i = 0;
i < ntlm;
i++)
2669 int16_t *encoder =
new int16_t[4 * 200 * ntlm];
2670 for (
size_t i = 0;
i < 4 * 200 * ntlm;
i++)
2672 int16_t *auxparms =
new int16_t[33];
2673 for (
size_t i = 0;
i < 33;
i++)
2675 int32_t *scaspin =
new int32_t[ntlm];
2676 for (
size_t i = 0;
i < ntlm;
i++)
2678 uint8_t *scatlm =
new uint8_t[480 * ntlm];
2679 for (
size_t i = 0;
i < 480 * ntlm;
i++)
2681 double *scasec =
new double[ntlm];
2682 for (
size_t i = 0;
i < ntlm;
i++)
2684 float *scapos =
new float[ntlm];
2685 for (
size_t i = 0;
i < ntlm;
i++)
2687 int32_t *senspin =
new int32_t[ntlm];
2688 for (
size_t i = 0;
i < ntlm;
i++)
2690 int16_t *sencoder =
new int16_t[4 * 200 * ntlm];
2691 for (
size_t i = 0;
i < 4 * 200 * ntlm;
i++)
2693 double *tcsec =
new double[ntlm];
2694 for (
size_t i = 0;
i < ntlm;
i++)
2696 uint8_t *tctlm =
new uint8_t[1216 * ntlm];
2697 for (
size_t i = 0;
i < 1216 * ntlm;
i++)
2699 double *dauctsec =
new double[ntlm];
2700 for (
size_t i = 0;
i < ntlm;
i++)
2702 double *icdumcetsec =
new double[ntlm];
2703 for (
size_t i = 0;
i < ntlm;
i++)
2705 uint8_t *icdumcettlm =
new uint8_t[76 * ntlm];
2706 for (
size_t i = 0;
i < 76 * ntlm;
i++)
2718 float *icdutherm =
new float[nicthrm * ntlm];
2719 for (
size_t i = 0;
i < nicthrm * ntlm;
i++)
2721 float *dauctemp =
new float[ndctmps * ntlm];
2722 for (
size_t i = 0;
i < ndctmps * ntlm;
i++)
2724 float *icdumcetemp =
new float[nimtmps * ntlm];
2725 for (
size_t i = 0;
i < nimtmps * ntlm;
i++)
2727 uint8_t *adclat =
new uint8_t[nadclat * ntlm];
2728 for (
size_t i = 0;
i < nadclat * ntlm;
i++)
2730 uint8_t *cdsdis =
new uint8_t[ntlm];
2731 for (
size_t i = 0;
i < ntlm;
i++)
2733 uint8_t *hamside =
new uint8_t[ntlm];
2734 uint32_t redmask[16];
2735 uint32_t bluemask[16];
2736 double sca_enc_scal = 360.0 / pow(2, 32);
2738 for (
size_t i = 0;
i < ntlm;
i++) {
2739 uint32_t apid = ((uint8_t)tlmdata[
i][0] % 8) * 256 + (uint8_t)tlmdata[
i][1];
2742 uint8_t cctime[8] = {0, 0, 0, 0, 0, 0, 0, 0};
2752 memcpy(cctime, &tlmdata[
i][6], 6);
2754 dausec[ndau] =
yds2unix(iy,
idy, sc) - l1afile_epoch;
2755 memcpy(&ui32, &tlmdata[
i][12], 4);
2756 dauspin[ndau] =
SWAP_4(ui32);
2757 memcpy(&dautlm[ndau * 620], &tlmdata[
i][16], 620);
2816 memcpy(cctime, &tlmdata[
i][6], 6);
2818 ddcsec[nddc] =
yds2unix(iy,
idy, sc) - l1afile_epoch;
2819 memcpy(&ddctlm[nddc * 524], &tlmdata[
i][12], 524);
2820 cdsdis[nddc] = tlmdata[
i][29];
2821 memcpy(&adclat[nddc * nadclat], &tlmdata[
i][176], nadclat);
2823 for (
size_t j = 0;
j < 16;
j++) {
2824 memcpy(&ui32, &tlmdata[
i][196 +
j * 4], 4);
2825 redmask[
j] = (uint32_t)
SWAP_4(ui32);
2827 memcpy(&ui32, &tlmdata[
i][260 +
j * 4], 4);
2828 bluemask[
j] = (uint32_t)
SWAP_4(ui32);
2836 memcpy(&ui32, &tlmdata[
i][12], 4);
2837 mcespin[nmce] =
SWAP_4(ui32);
2838 memcpy(&mcetlm[nmce * 480], &tlmdata[
i][16], 480);
2839 hamside[nmce] = (tlmdata[
i][49] & 8) / 8;
2845 memcpy(&ui32, &tlmdata[
i][12], 4);
2846 encspin[nenc] =
SWAP_4(ui32);
2848 for (
size_t j = 0;
j < 4 * 200;
j++) {
2849 memcpy(&i16, &tlmdata[
i][16 + 2 *
j], 2);
2850 encoder[nenc * 4 * 200 +
j] =
SWAP_2(i16);
2857 memcpy(cctime, &tlmdata[
i][6], 6);
2859 scasec[nsca] =
yds2unix(iy,
idy, sc) - l1afile_epoch;
2860 memcpy(&ui32, &tlmdata[
i][12], 4);
2861 scaspin[nsca] =
SWAP_4(ui32);
2862 memcpy(&scatlm[nsca * 480], &tlmdata[
i][16], 480);
2863 memcpy(&ui32, &tlmdata[
i][348], 4);
2864 float sca_abs_enc_count;
2867 scapos[nsca] = 330.0 - sca_abs_enc_count * sca_enc_scal;
2873 memcpy(&ui32, &tlmdata[
i][12], 4);
2874 senspin[nsen] =
SWAP_4(ui32);
2875 for (
size_t j = 0;
j < 4 * 200;
j++) {
2876 memcpy(&i16, &tlmdata[
i][16 + 2 *
j], 2);
2877 sencoder[nsen * 4 * 200 +
j] =
SWAP_2(i16);
2884 memcpy(cctime, &tlmdata[
i][6], 6);
2886 tcsec[ntc] =
yds2unix(iy,
idy, sc) - l1afile_epoch;
2887 memcpy(&tctlm[ntc * 1216], &tlmdata[
i][12], 1216);
2888 for (
size_t j = 0;
j < nicthrm;
j++) {
2889 memcpy(&
f32, &tlmdata[
i][184 + 4 *
j], 4);
2899 for (
size_t j = 0;
j < 33;
j++) {
2900 memcpy(&ui32, &tlmdata[
i][64 +
j * 4], 4);
2901 auxparms[
j] = (int16_t)
SWAP_4(ui32);
2909 memcpy(cctime, &tlmdata[
i][6], 6);
2911 dauctsec[ndct] =
yds2unix(iy,
idy, sc) - l1afile_epoch;
2912 for (
size_t j = 0;
j < ndctmps;
j++) {
2913 memcpy(&
f32, &tlmdata[
i][12 + 4 *
j], 4);
2921 memcpy(cctime, &tlmdata[
i][6], 6);
2923 icdumcetsec[nimt] =
yds2unix(iy,
idy, sc) - l1afile_epoch;
2924 memcpy(&icdumcettlm[nimt * 76], &tlmdata[
i][12], 76);
2925 for (
size_t j = 0;
j < nimtmps;
j++) {
2926 memcpy(&
f32, &tlmdata[
i][24 + 4 *
j], 4);
2937 vector<size_t>
start;
2938 vector<size_t>
count;
2942 gid = l1afile->getGroup(
"engineering_data");
2949 count.push_back(ndau);
2951 var = gid.getVar(
"DAU_tlm_time");
2953 var.putAtt(
"units", l1afile_epoch_str);
2955 var = gid.getVar(
"DAU_spin_ID");
2959 count.push_back(620);
2961 var = gid.getVar(
"DAU_telemetry");
2991 tlmzs[0] = dautlm[123];
2992 tlmzs[1] = dautlm[125];
2993 tlmzd[0] = dautlm[122];
2994 tlmzd[1] = dautlm[124];
2998 for (
size_t i = 0;
i < 16;
i++) {
2999 redmask[
i] = 4294967295;
3000 bluemask[
i] = 4294967295;
3008 count.push_back(nddc);
3011 var = gid.getVar(
"DDC_tlm_time");
3013 var.putAtt(
"units", l1afile_epoch_str);
3016 var = gid.getVar(
"CDS_disable");
3020 count.push_back(524);
3023 var = gid.getVar(
"DDC_telemetry");
3027 count.push_back(nadclat);
3030 var = gid.getVar(
"ADC_latency");
3037 count.push_back(16);
3038 var = gid.getVar(
"blue_channel_mask");
3040 var = gid.getVar(
"red_channel_mask");
3044 cdsmode = cdsdis[0] * (adclat[0] - 14);
3048 memcpy(&ui16, &ddctlm[346], 2);
3058 count.push_back(nmce);
3061 var = gid.getVar(
"MCE_spin_ID");
3066 uint8_t *
mside =
new uint8_t[isc];
3067 for (
size_t i = 0;
i < isc;
i++)
3069 for (
size_t i = 0;
i < isc;
i++) {
3070 for (
size_t j = 0;
j < ntlm;
j++) {
3071 if ((
int)mcespin[
j] == spinID[
i]) {
3080 count.push_back(isc);
3081 NcGroup scgid = l1afile->getGroup(
"scan_line_attributes");
3083 var = scgid.getVar(
"HAM_side");
3091 count.push_back(nmce);
3092 count.push_back(480);
3095 var = gid.getVar(
"MCE_telemetry");
3105 count.push_back(nenc);
3108 var = gid.getVar(
"encoder_spin_ID");
3112 count.push_back(200);
3117 var = gid.getVar(
"MCE_encoder_data");
3126 count.push_back(nsca);
3128 var = gid.getVar(
"SCA_spin_ID");
3135 count.push_back(nsca);
3136 count.push_back(480);
3138 var = gid.getVar(
"SCA_telemetry");
3145 count.push_back(nsca);
3147 var = gid.getVar(
"SCA_tlm_time");
3149 var.putAtt(
"units", l1afile_epoch_str);
3152 var = gid.getVar(
"SCA_diffuser_position");
3160 count.push_back(nsen);
3163 var = gid.getVar(
"SCA_encoder_spin_ID");
3168 count.push_back(200);
3173 var = gid.getVar(
"SCA_encoder_data");
3182 count.push_back(ntc);
3185 var = gid.getVar(
"TC_tlm_time");
3187 var.putAtt(
"units", l1afile_epoch_str);
3190 count.push_back(1216);
3193 var = gid.getVar(
"TC_telemetry");
3197 count.push_back(nicthrm);
3200 var = gid.getVar(
"ICDU_thermisters");
3205 gid = l1afile->getGroup(
"spatial_spectral_modes");
3211 count.push_back(33);
3213 var = gid.getVar(
"aux_param_table");
3222 count.push_back(ndct);
3224 gid = l1afile->getGroup(
"engineering_data");
3227 var = gid.getVar(
"DAUC_temp_time");
3229 var.putAtt(
"units", l1afile_epoch_str);
3232 count.push_back(ndctmps);
3235 var = gid.getVar(
"DAUC_temperatures");
3243 count.push_back(nimt);
3246 var = gid.getVar(
"ICDU_MCE_temp_time");
3248 var.putAtt(
"units", l1afile_epoch_str);
3251 count.push_back(76);
3254 var = gid.getVar(
"ICDU_MCE_temp_tlm");
3258 count.push_back(nimtmps);
3261 var = gid.getVar(
"ICDU_MCE_temperatures");
3266 string conflict =
"No";
3267 gid = l1afile->getGroup(
"engineering_data");
3269 if ((tlmzd[0] == 0) && (tlmzd[1] == 0)) {
3270 cout <<
"No telemetry zone fields in file" << endl;
3271 gid.putAtt(
"science_telemetry_zone_conflict", conflict);
3273 float clock = 136000;
3274 float secpline = (tditime + 1) / clock;
3277 float *znd =
new float[2 * 10];
3278 float *zndcp =
new float[2 * 10];
3281 for (
size_t i = 0;
i < 10;
i++) {
3283 znd[ndz] =
line * secpline;
3284 znd[1 * 10 + ndz] = (
line + itable[
i].
lines) * secpline;
3286 if ((ndz > 0) && (znd[ndz] == znd[1 * 10 + ndz - 1])) {
3287 znd[1 * 10 + ndz - 1] = znd[1 * 10 + ndz];
3294 memcpy(zndcp, znd, 20);
3296 for (
int i = 0;
i < ndz;
i++)
3297 znd[ndz +
i] = znd[10 +
i];
3300 if ((itable[0].
dtype == 0) || (itable[0].
dtype == 10))
3301 znd[1 * ndz + ndz - 1] += znd[1 * ndz + 0];
3305 for (
size_t i = 0;
i < 2;
i++) {
3307 int16_t tlmze = tlmzs[
i] + tlmzd[
i] + 3;
3309 for (
k = ndz - 1;
k >= 0;
k--) {
3314 if ((
k == -1) || (tlmzs[
i] < znd[
k]) || (tlmze > znd[1 * ndz +
k])) {
3316 cout <<
"Telemetry zone " << tlmzs[
i] <<
", " << tlmze << endl;
3317 cout <<
"No-data zone " << znd[
k] <<
", " << znd[1 * ndz +
k] << endl;
3325 NcGroup gid = l1afile->getGroup(
"engineering_data");
3326 gid.putAtt(
"science_telemetry_zone_conflict", conflict);
3345 delete[] icdumcetsec;
3346 delete[] icdumcettlm;
3347 delete[] icdumcetemp;
3370 int find_nav_index(
char *hkt_t_start,
double usec_l1a_start,
double usec_l1a_end,
double *nav_t,
size_t n_nav,
3371 int &ind_start,
int &ind_end) {
3373 int hkt_yr, hkt_mon, hkt_day;
3374 sscanf(hkt_t_start,
"%4d-%2d-%2d", &hkt_yr, &hkt_mon, &hkt_day);
3376 for (
size_t i = 0;
i < n_nav;
i++) {
3377 usec_hkt =
ymds2unix(hkt_yr, hkt_mon, hkt_day, nav_t[
i]);
3378 if ((usec_hkt > usec_l1a_start - 10) && (ind_start == 1e6)) {
3384 for (
size_t i = n_nav - 1;
i >= 0;
i--) {
3385 usec_hkt =
ymds2unix(hkt_yr, hkt_mon, hkt_day, nav_t[
i]);
3386 if ((usec_hkt < usec_l1a_end + 10) && (ind_end == -1)) {
3404 netCDF::NcGroup processCtrlGrp = l1afile->addGroup(
"processing_control");
3407 netCDF::NcGroup inputParaGrp = processCtrlGrp.addGroup(
"input_parameter");
3411 inputParaGrp.putAtt(
"OCI_packet_file", l0List);
3412 inputParaGrp.putAtt(
"maxgap", maxgap);
3413 inputParaGrp.putAtt(
"hktlist_iFile", hktList);
3414 inputParaGrp.putAtt(
"swir_loff_set", swir_loff_set);
3415 inputParaGrp.putAtt(
"start_time",
time_start);
3416 inputParaGrp.putAtt(
"outlist", outlist);
3417 inputParaGrp.putAtt(
"outfile",
outfile);
3418 inputParaGrp.putAtt(
"nametag", nametag);
3419 inputParaGrp.putAtt(
"doi", doi);
3420 inputParaGrp.putAtt(
"pversion", pversion);
3421 inputParaGrp.putAtt(
"isSPW", isSPW);
3424 processCtrlGrp.putAtt(
"software_name",
"l1agen_oci");
3425 processCtrlGrp.putAtt(
"software_version",
VERSION);
3430 string hktString =
"";
3431 for (
size_t i = 0;
i < hktFiles.size();
i++) {
3433 if (
i < hktFiles.size() - 1) {
3434 hktString.append(hktFiles[
i]);
3435 hktString.append(
", ");
3439 hktString.append(hktFiles[
i]);
3441 processCtrlGrp.putAtt(
"hkt_list", hktString);
3445 string l0String =
"";
3446 for (
size_t i = 0;
i < l0Files.size();
i++) {
3447 if (
i < l0Files.size() - 1) {
3448 l0String.append(l0Files[
i]);
3449 l0String.append(
", ");
3452 l0String.append(l0Files[
i]);
3454 processCtrlGrp.putAtt(
"l0_list", l0String);
3456 }
catch (std::exception &e) {
3457 std::cerr <<
"--Error-- writing processing control group. what: " << e.what() << endl;
3465 uint16_t nnavmax = 10000;
3466 size_t iatt = 0, iorb = 0, itilt = 0;
3468 double usec_l1a_start, usec_l1a_end;
3473 string l1afile_epoch_str =
unix2isodate(l1afile_epoch,
'G');
3474 l1afile_epoch_str = l1afile_epoch_str.substr(0, 10);
3475 l1afile_epoch_str.insert(0,
"seconds since ");
3478 ifstream
file(hktlist);
3481 double *atime =
new double[nnavmax];
3482 for (
size_t i = 0;
i < nnavmax;
i++)
3484 double *otime =
new double[nnavmax];
3485 for (
size_t i = 0;
i < nnavmax;
i++)
3487 double *ttime =
new double[nnavmax];
3488 for (
size_t i = 0;
i < nnavmax;
i++)
3491 float *arate =
new float[3 * nnavmax];
3492 for (
size_t i = 0;
i < 3 * nnavmax;
i++)
3494 float *quat =
new float[4 * nnavmax];
3495 for (
size_t i = 0;
i < 4 * nnavmax;
i++)
3497 float *
pos =
new float[3 * nnavmax];
3498 for (
size_t i = 0;
i < 3 * nnavmax;
i++)
3500 float *vel =
new float[3 * nnavmax];
3501 for (
size_t i = 0;
i < nnavmax;
i++)
3503 for (
size_t i = nnavmax;
i < 3 * nnavmax;
i++)
3505 float *tlt =
new float[nnavmax];
3506 for (
size_t i = 0;
i < nnavmax;
i++)
3508 uint8_t *tltflg =
new uint8_t[nnavmax];
3509 for (
size_t i = 0;
i < nnavmax;
i++)
3514 char *hkt_t_start =
new char[100];
3515 char *hkt_t_end =
new char[100];
3517 while (getline(
file, strHKTfile)) {
3521 int atttid, attqid, attrid;
3522 int orbpid, orbtid, orbvid;
3523 int tid, ttid, tfid;
3524 size_t natt = 0, norb = 0, ntilt = 0;
3526 nc_open(strHKTfile.c_str(), NC_NOWRITE, &ncid);
3529 nc_get_att_text(ncid, NC_GLOBAL,
"time_coverage_start",
3532 nc_inq_attlen(ncid, NC_GLOBAL,
"time_coverage_start", &length);
3533 hkt_t_start[length] =
'\0';
3535 nc_get_att_text(ncid, NC_GLOBAL,
"time_coverage_end", hkt_t_end);
3536 nc_inq_attlen(ncid, NC_GLOBAL,
"time_coverage_end", &length);
3537 hkt_t_end[length] =
'\0';
3540 int hkt_yr, hkt_mon, hkt_day, hkt_hr, hkt_min, hk_sec;
3542 sscanf(hkt_t_start,
"%4d-%2d-%2dT%2d:%2d:%2d", &hkt_yr, &hkt_mon, &hkt_day, &hkt_hr, &hkt_min,
3544 usec_hkt =
ymds2unix(hkt_yr, hkt_mon, hkt_day, hkt_hr * 3600 + hkt_min * 60 + hk_sec);
3545 double hktfile_epoch =
ymds2unix(hkt_yr, hkt_mon, hkt_day, 0.0);
3546 if (usec_hkt > usec_l1a_end + 10)
3548 sscanf(hkt_t_end,
"%4d-%2d-%2dT%2d:%2d:%2d", &hkt_yr, &hkt_mon, &hkt_day, &hkt_hr, &hkt_min,
3550 usec_hkt =
ymds2unix(hkt_yr, hkt_mon, hkt_day, hkt_hr * 3600 + hkt_min * 60 + hk_sec);
3551 if (usec_hkt < usec_l1a_start - 10)
3556 nc_inq_grp_ncid(ncid,
"navigation_data", &gid);
3558 nc_type attt_type, orbt_type, tiltt_type;
3559 int attt_ndims, orbt_ndims, tiltt_ndims;
3560 int attt_dimids[NC_MAX_VAR_DIMS], orbt_dimids[NC_MAX_VAR_DIMS], tiltt_dimids[NC_MAX_VAR_DIMS];
3561 int attt_natts, orbt_natts, tiltt_natts;
3563 status = nc_inq_varid(gid,
"att_time", &atttid);
3564 if (
status == NC_NOERR) {
3565 nc_inq_var(gid, atttid, 0, &attt_type, &attt_ndims, attt_dimids, &attt_natts);
3566 nc_inq_dimlen(gid, attt_dimids[0], &natt);
3569 status = nc_inq_varid(gid,
"orb_time", &orbtid);
3570 if (
status == NC_NOERR) {
3571 nc_inq_var(gid, orbtid, 0, &orbt_type, &orbt_ndims, orbt_dimids, &orbt_natts);
3572 nc_inq_dimlen(gid, orbt_dimids[0], &norb);
3575 status = nc_inq_varid(gid,
"tilt_time", &ttid);
3576 if (
status == NC_NOERR) {
3577 nc_inq_var(gid, ttid, 0, &tiltt_type, &tiltt_ndims, tiltt_dimids, &tiltt_natts);
3578 nc_inq_dimlen(gid, tiltt_dimids[0], &ntilt);
3583 int ind_att_start = 1e6, ind_att_end = -1;
3584 int ind_orb_start = 1e6, ind_orb_end = -1;
3585 int ind_tilt_start = 1e6, ind_tilt_end = -1;
3588 double *at =
new double[natt];
3589 nc_get_var(gid, atttid, at);
3590 float *
r =
new float[3 * natt];
3591 float *
q =
new float[4 * natt];
3592 find_nav_index(hkt_t_start, usec_l1a_start, usec_l1a_end, at, natt, ind_att_start,
3595 if ((ind_att_end - ind_att_start) > 0) {
3596 nc_inq_varid(gid,
"att_quat", &attqid);
3597 nc_get_var(gid, attqid,
q);
3598 nc_inq_varid(gid,
"att_rate", &attrid);
3599 nc_get_var(gid, attrid,
r);
3602 if (l1afile_epoch != hktfile_epoch) {
3603 double epoch_diff = hktfile_epoch - l1afile_epoch;
3604 for (
size_t i = 0;
i < natt;
i++) {
3605 at[
i] += epoch_diff;
3610 size_t nnav = ind_att_end - ind_att_start + 1;
3611 memcpy(atime + iatt, at + ind_att_start, nnav *
sizeof(
double));
3612 memcpy(quat + iatt * 4,
q + ind_att_start * 4, 4 * nnav *
sizeof(
float));
3613 memcpy(arate + iatt * 3,
r + ind_att_start * 3, 3 * nnav *
sizeof(
float));
3623 double *ot =
new double[norb];
3624 nc_get_var(gid, orbtid, ot);
3625 float *
p =
new float[3 * norb];
3626 float *
v =
new float[3 * norb];
3627 find_nav_index(hkt_t_start, usec_l1a_start, usec_l1a_end, ot, norb, ind_orb_start,
3630 if ((ind_orb_end - ind_orb_start) > 0) {
3631 nc_inq_varid(gid,
"orb_pos", &orbpid);
3632 nc_get_var(gid, orbpid,
p);
3633 nc_inq_varid(gid,
"orb_vel", &orbvid);
3634 nc_get_var(gid, orbvid,
v);
3637 if (l1afile_epoch != hktfile_epoch) {
3638 double epoch_diff = hktfile_epoch - l1afile_epoch;
3639 for (
size_t i = 0;
i < norb;
i++) {
3640 ot[
i] += epoch_diff;
3645 size_t nnav = ind_orb_end - ind_orb_start + 1;
3646 memcpy(otime + iorb, ot + ind_orb_start, nnav *
sizeof(
double));
3647 memcpy(
pos + iorb * 3,
p + ind_orb_start * 3, 3 * nnav *
sizeof(
float));
3648 memcpy(vel + iorb * 3,
v + ind_orb_start * 3, 3 * nnav *
sizeof(
float));
3659 double *
tt =
new double[ntilt];
3660 nc_get_var(gid, ttid,
tt);
3661 float *
t =
new float[ntilt];
3662 uint8_t *tf =
new uint8_t[ntilt];
3663 find_nav_index(hkt_t_start, usec_l1a_start, usec_l1a_end,
tt, ntilt, ind_tilt_start,
3666 if ((ind_tilt_end - ind_tilt_start) > 0) {
3667 nc_inq_varid(gid,
"tilt", &tid);
3668 nc_get_var(gid, tid,
t);
3671 if (l1afile_epoch != hktfile_epoch) {
3672 double epoch_diff = hktfile_epoch - l1afile_epoch;
3673 for (
size_t i = 0;
i < ntilt;
i++) {
3674 tt[
i] += epoch_diff;
3679 size_t nnav = ind_tilt_end - ind_tilt_start + 1;
3680 memcpy(ttime + itilt,
tt + ind_tilt_start, nnav *
sizeof(
double));
3681 memcpy(tlt + itilt,
t + ind_tilt_start, nnav *
sizeof(
float));
3684 status = nc_inq_varid(gid,
"tilt_flag", &tfid);
3685 if (
status == NC_NOERR) {
3686 nc_get_var(gid, tfid, tf);
3687 memcpy(tltflg + itilt, tf + ind_tilt_start, nnav);
3690 for (
size_t itf = itilt; itf < itilt + nnav; itf++) {
3691 if (tltflg[itf] > 0) {
3708 }
catch (NcException &e) {
3710 cout <<
"Error reading " << strHKTfile <<
"!" << endl;
3719 vector<size_t>
start;
3720 vector<size_t>
count;
3722 NcGroup l1a_gid = l1afile->getGroup(
"navigation_data");
3727 count.push_back(iatt);
3728 var = l1a_gid.getVar(
"att_time");
3730 var.putAtt(
"units", l1afile_epoch_str);
3734 var = l1a_gid.getVar(
"att_quat");
3739 var = l1a_gid.getVar(
"att_rate");
3744 count.push_back(iorb);
3745 var = l1a_gid.getVar(
"orb_time");
3747 var.putAtt(
"units", l1afile_epoch_str);
3751 var = l1a_gid.getVar(
"orb_pos");
3754 var = l1a_gid.getVar(
"orb_vel");
3760 count.push_back(itilt);
3761 var = l1a_gid.getVar(
"tilt_time");
3763 var.putAtt(
"units", l1afile_epoch_str);
3765 var = l1a_gid.getVar(
"tilt");
3768 delete[] hkt_t_start;
3786 uint16_t smode, uint16_t cdsmode, std::ofstream &fout) {
3787 string dtypes[] = {
"",
3798 "External Snapshot Trigger",
3799 "Internal Snapshot Trigger",
3800 "Earth Collect with Non-Baseline Spectral Bands"};
3802 string smodes[] = {
"Science",
"Diagnostic",
"Single-image raw",
"Test pattern"};
3804 string cdsmodes[] = {
"CDS",
"Reset",
"Video"};
3820 ss = stringstream();
3821 ss << setw(4) << to_string(
starttime.iyear) <<
"-";
3822 ss << setw(2) << setfill(
'0') << mon <<
"-";
3823 ss << setw(2) << setfill(
'0') << idm <<
"T";
3825 ss << setw(2) << setfill(
'0') <<
ih <<
":";
3826 ss << setw(2) << setfill(
'0') << mn <<
":";
3827 ss << fixed << setw(6) << setprecision(3) << setfill(
'0') <<
starttime.sec;
3830 l1afile->putAtt(
"time_coverage_start", ss.str() +
"Z");
3834 fout << ss.str().c_str() <<
" ";
3836 yd2md((int16_t)endtime.
iyear, (int16_t)endtime.
iday, &mon, &idm);
3839 floor(endtime.
sec * 1000) / 1000;
3841 endtime.
sec -=
ih * 3600;
3842 mn = (
int)(endtime.
sec / 60);
3843 endtime.
sec -= mn * 60;
3846 ss = stringstream();
3847 ss << setw(4) << to_string(endtime.
iyear) <<
"-";
3848 ss << setw(2) << setfill(
'0') << mon <<
"-";
3849 ss << setw(2) << setfill(
'0') << idm <<
"T";
3851 ss << setw(2) << setfill(
'0') <<
ih <<
":";
3852 ss << setw(2) << setfill(
'0') << mn <<
":";
3853 ss << fixed << setw(6) << setprecision(3) << setfill(
'0') << endtime.
sec;
3856 l1afile->putAtt(
"time_coverage_end", ss.str() +
"Z");
3859 l1afile->putAtt(
"product_name", l1a_name.c_str());
3862 l1afile->putAtt(
"startDirection", sdir.c_str());
3863 l1afile->putAtt(
"endDirection", edir.c_str());
3866 l1afile->putAtt(
"data_collect_mode", dtypes[
dtype].c_str());
3867 l1afile->putAtt(
"SWIR_data_mode", smodes[smode].c_str());
3868 l1afile->putAtt(
"CDS_mode", cdsmodes[cdsmode].c_str());
3872 fout << ss.str().c_str() <<
" ";
3880 }
catch (NcException &e) {
3881 cout << e.what() << endl;
3882 cerr <<
"Failure closing: " + fileName << endl;
3890 const char *
units,
void *fill_value,
const char *flag_values,
const char *flag_meanings,
3891 const char *reference,
double low,
double high,
int nt, vector<NcDim> &varVec) {
3895 ncVar = ncGrp.addVar(sname, nt, varVec);
3896 }
catch (NcException &e) {
3897 cout << e.what() << endl;
3898 cerr <<
"Failure creating variable: " << sname << endl;
3903 double fill_value_dbl;
3904 memcpy(&fill_value_dbl, fill_value,
sizeof(
double));
3914 if (low != fill_value_dbl) {
3915 if (nt == NC_BYTE) {
3916 i8 = fill_value_dbl;
3917 ncVar.setFill(
true, (
void *)&i8);
3918 }
else if (nt == NC_UBYTE) {
3919 ui8 = fill_value_dbl;
3920 ncVar.setFill(
true, (
void *)&ui8);
3921 }
else if (nt == NC_SHORT) {
3922 i16 = fill_value_dbl;
3923 ncVar.setFill(
true, (
void *)&i16);
3924 }
else if (nt == NC_USHORT) {
3925 ui16 = fill_value_dbl;
3926 ncVar.setFill(
true, (
void *)&ui16);
3927 }
else if (nt == NC_INT) {
3928 i32 = fill_value_dbl;
3929 ncVar.setFill(
true, (
void *)&i32);
3930 }
else if (nt == NC_UINT) {
3931 ui32 = fill_value_dbl;
3932 ncVar.setFill(
true, (
void *)&ui32);
3933 }
else if (nt == NC_FLOAT) {
3934 f32 = fill_value_dbl;
3935 ncVar.setFill(
true, (
void *)&
f32);
3937 ncVar.setFill(
true, (
void *)&fill_value_dbl);
3944 if (varVec.size() == 3 && (strncmp(sname,
"sci_", 4) == 0)) {
3946 size_t dimBands = varVec[1].getSize();
3947 size_t dimPixels = varVec[2].getSize();
3952 chunkVec[1] = dimBands;
3954 chunkVec[2] = dimPixels;
3963 ncVar.setChunking(ncVar.nc_CHUNKED, chunkVec);
3964 }
catch (NcException &e) {
3966 cerr <<
"Failure setting chunking: " << sname << endl;
3971 ncVar.setCompression(
true,
true, 5);
3972 }
catch (NcException &e) {
3974 cerr <<
"Failure setting compression: " << sname << endl;
3981 ncVar.putAtt(
"long_name", lname);
3982 }
catch (NcException &e) {
3984 cerr <<
"Failure creating 'long_name' attribute: " << lname << endl;
3988 if (strcmp(flag_values,
"") != 0) {
3992 fv.assign(flag_values);
3993 size_t pos = fv.find(
"=", curPos);
3994 fv = fv.substr(
pos + 1);
3996 size_t semicln = fv.find(
";");
4001 while (
pos != semicln) {
4002 pos = fv.find(
",", curPos);
4003 if (
pos == string::npos)
4007 istringstream iss(fv.substr(curPos,
pos - curPos));
4008 iss >> skipws >> flag_value;
4009 vec[n++] = atoi(flag_value.c_str());
4014 ncVar.putAtt(
"flag_values", nt, n, vec);
4015 }
catch (NcException &e) {
4017 cerr <<
"Failure creating 'flag_values' attribute: " << lname << endl;
4023 if (strcmp(flag_meanings,
"") != 0) {
4025 ncVar.putAtt(
"flag_meanings", flag_meanings);
4026 }
catch (NcException &e) {
4028 cerr <<
"Failure creating 'flag_meanings' attribute: " << flag_meanings << endl;
4034 if (strcmp(reference,
"") != 0) {
4036 ncVar.putAtt(
"reference", reference);
4037 }
catch (NcException &e) {
4039 cerr <<
"Failure creating 'reference' attribute: " << reference << endl;
4049 vr[0] = (uint8_t)low;
4050 vr[1] = (uint8_t)high;
4053 ncVar.putAtt(
"valid_min", NC_BYTE, 1, &vr[0]);
4054 }
catch (NcException &e) {
4056 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
4061 ncVar.putAtt(
"valid_max", NC_BYTE, 1, &vr[1]);
4062 }
catch (NcException &e) {
4064 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
4070 vr[0] = (uint8_t)low;
4071 vr[1] = (uint8_t)high;
4074 ncVar.putAtt(
"valid_min", NC_UBYTE, 1, &vr[0]);
4075 }
catch (NcException &e) {
4077 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
4082 ncVar.putAtt(
"valid_max", NC_UBYTE, 1, &vr[1]);
4083 }
catch (NcException &e) {
4085 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
4091 vr[0] = (int16_t)low;
4092 vr[1] = (int16_t)high;
4095 ncVar.putAtt(
"valid_min", NC_SHORT, 1, &vr[0]);
4096 }
catch (NcException &e) {
4098 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
4103 ncVar.putAtt(
"valid_max", NC_SHORT, 1, &vr[1]);
4104 }
catch (NcException &e) {
4106 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
4112 vr[0] = (uint16_t)low;
4113 vr[1] = (uint16_t)high;
4116 ncVar.putAtt(
"valid_min", NC_USHORT, 1, &vr[0]);
4117 }
catch (NcException &e) {
4119 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
4124 ncVar.putAtt(
"valid_max", NC_USHORT, 1, &vr[1]);
4125 }
catch (NcException &e) {
4127 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
4133 vr[0] = (int32_t)low;
4134 vr[1] = (int32_t)high;
4137 ncVar.putAtt(
"valid_min", NC_INT, 1, &vr[0]);
4138 }
catch (NcException &e) {
4140 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
4145 ncVar.putAtt(
"valid_max", NC_INT, 1, &vr[1]);
4146 }
catch (NcException &e) {
4148 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
4155 vr[0] = (uint32_t)low;
4156 vr[1] = (uint32_t)high;
4159 ncVar.putAtt(
"valid_min", NC_UINT, 1, &vr[0]);
4160 }
catch (NcException &e) {
4162 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
4167 ncVar.putAtt(
"valid_max", NC_UINT, 1, &vr[1]);
4168 }
catch (NcException &e) {
4170 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
4178 vr[1] = (
float)high;
4181 ncVar.putAtt(
"valid_min", NC_FLOAT, 1, &vr[0]);
4182 }
catch (NcException &e) {
4184 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
4189 ncVar.putAtt(
"valid_max", NC_FLOAT, 1, &vr[1]);
4190 }
catch (NcException &e) {
4192 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
4202 ncVar.putAtt(
"valid_min", NC_DOUBLE, 1, &vr[0]);
4203 }
catch (NcException &e) {
4205 cerr <<
"Failure creating 'valid_min' attribute: " << vr[0] << endl;
4210 ncVar.putAtt(
"valid_max", NC_DOUBLE, 1, &vr[1]);
4211 }
catch (NcException &e) {
4213 cerr <<
"Failure creating 'valid_max' attribute: " << vr[1] << endl;
4218 fprintf(
stderr,
"-E- %s line %d: ", __FILE__, __LINE__);
4219 fprintf(
stderr,
"Got unsupported number type (%d) ", nt);
4220 fprintf(
stderr,
"while trying to create NCDF variable, \"%s\", ", sname);
4228 ncVar.putAtt(
"units",
units);
4229 }
catch (NcException &e) {
4231 cerr <<
"Failure creating 'units' attribute: " <<
units << endl;
4240 }
catch (NcException &e) {
4242 cerr <<
"Failure creating 'standard_name' attribute: " <<
standard_name << endl;
4250 int eight20(uint8_t *inbytes, uint32_t *outsamples) {
4254 for (
size_t i = 0;
i < 5;
i++) {
4255 outsamples[
i * 2] = 4096 * inbytes[
i * 5] + 16 * inbytes[
i * 5 + 1] + inbytes[
i * 5 + 2] / 16;
4258 for (
size_t i = 0;
i < 4;
i++) {
4259 outsamples[
i * 2 + 1] =
4260 65536 * (inbytes[
i * 5 + 2] % 16) + 256 * inbytes[
i * 5 + 3] + inbytes[
i * 5 + 4];