34 #include <GeographicLib/Geodesic.hpp>
35 #include <GeographicLib/GeodesicLine.hpp>
36 #include <GeographicLib/Constants.hpp>
37 #include <GeographicLib/Rhumb.hpp>
45 static size_t num_scans, num_pixels;
46 static size_t num_blue_bands, num_red_bands, num_SWIR_bands;
49 static short **
senz =
nullptr, **
sena =
nullptr;
56 static int16_t nswath;
59 using namespace boost::assign;
60 using namespace std::chrono;
61 using namespace GeographicLib;
63 using namespace netCDF;
64 using namespace netCDF::exceptions;
67 typedef bg::model::point<double, 2, bg::cs::geographic<bg::degree>>
Point_t;
69 typedef bg::model::box<Point_t>
Box_t;
83 int ncid_out,grp_pc,grp_ip;
86 if ((
status = nc_def_grp(ncid_out,
"processing_control", &grp_pc)))
90 status = nc_put_att_text(grp_pc,NC_GLOBAL,
str.c_str(),str2.size(),str2.c_str());
91 str=
"software_version";
93 str2=str2.substr(0,5);
94 status = nc_put_att_text(grp_pc,NC_GLOBAL,
str.c_str(),str2.size(),str2.c_str());
96 if ((
status = nc_def_grp(grp_pc,
"input_parameters", &grp_ip)))
100 int nfiles=l1cfile->
ifiles.size();
101 for(
int f=0;
f<nfiles;
f++)
103 if(
f==nfiles-1)str2=str2+l1cfile->
ifiles[
f];
else str2=str2+l1cfile->
ifiles[
f]+
",";
104 status = nc_put_att_text(grp_ip,NC_GLOBAL,
str.c_str(),str2.size(),str2.c_str());
107 status = nc_put_att_text(grp_ip,NC_GLOBAL,
str.c_str(),strlen(l1c_filename),l1c_filename);
112 status = nc_put_att_text(grp_ip,NC_GLOBAL,
str.c_str(),str2.size(),str2.c_str());
115 status = nc_put_att_text(grp_ip,NC_GLOBAL,
str.c_str(),str2.size(),str2.c_str());
117 str2=
"$OCDATAROOT/common/gebco_ocssw_v2020.nc";
118 status = nc_put_att_text(grp_ip,NC_GLOBAL,
str.c_str(),str2.size(),str2.c_str());
122 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
125 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
127 float value2=l1cinput->
north;
128 status = nc_put_att_float(grp_ip,NC_GLOBAL,
str.c_str(),NC_FLOAT,1,&value2);
130 value2=l1cinput->
south;
131 status = nc_put_att_float(grp_ip,NC_GLOBAL,
str.c_str(),NC_FLOAT,1,&value2);
133 value2=l1cinput->
east;
134 status = nc_put_att_float(grp_ip,NC_GLOBAL,
str.c_str(),NC_FLOAT,1,&value2);
136 value2=l1cinput->
west;
137 status = nc_put_att_float(grp_ip,NC_GLOBAL,
str.c_str(),NC_FLOAT,1,&value2);
139 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,10,l1cinput->
selgran);
142 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
145 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
148 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
151 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
154 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
157 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
158 str=
"start_timeflag";
160 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
163 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
164 str=
"grid_resolution";
166 status = nc_put_att_float(grp_ip,NC_GLOBAL,
str.c_str(),NC_FLOAT,1,&value2);
169 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
172 status = nc_put_att_text(grp_ip,NC_GLOBAL,
str.c_str(),str2.size(),str2.c_str());
177 status = nc_put_att_text(grp_ip,NC_GLOBAL,
str.c_str(),str2.size(),str2.c_str());
180 status = nc_put_att_text(grp_ip,NC_GLOBAL,
str.c_str(),str2.size(),str2.c_str());
183 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
186 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
189 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
190 str=
"terrain_correct";
192 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
195 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
198 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
201 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
204 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
207 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
210 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
213 status = nc_put_att_int(grp_ip,NC_GLOBAL,
str.c_str(),NC_INT,1,&
value);
216 status = nc_put_att_float(grp_ip,NC_GLOBAL,
str.c_str(),NC_FLOAT,1,&value2);
219 status = nc_put_att_float(grp_ip,NC_GLOBAL,
str.c_str(),NC_FLOAT,1,&value2);
222 status = nc_put_att_float(grp_ip,NC_GLOBAL,
str.c_str(),NC_FLOAT,1,&value2);
223 status = nc_close(ncid_out);
230 temp[0] = vector_a[1] * vector_b[2] - vector_a[2] * vector_b[1];
231 temp[1] = -(vector_a[0] * vector_b[2] - vector_a[2] * vector_b[0]);
232 temp[2] = vector_a[0] * vector_b[1] - vector_a[1] * vector_b[0];
236 double temp[3], nvec;
237 temp[0] = vector_a[1] * vector_b[2] - vector_a[2] * vector_b[1];
238 temp[1] = -(vector_a[0] * vector_b[2] - vector_a[2] * vector_b[0]);
239 temp[2] = vector_a[0] * vector_b[1] - vector_a[1] * vector_b[0];
241 nvec = sqrt(temp[0] * temp[0] + temp[1] * temp[1] + temp[2] * temp[2]);
246 double *ptime =
nullptr, *ptime_l1c =
nullptr;
247 const char* l1c_gran;
248 size_t num_ybin, num_xbin;
249 float **latpix =
nullptr, **lonpix =
nullptr, **l1clat =
nullptr, **l1clon =
nullptr, **l1calt =
nullptr;
250 float **lat_new =
nullptr, **lon_new =
nullptr;
252 float Xcorr,Ycorr, Zcorr;
253 float Rsurf, radius_ratio =
Re / Rpole;
256 float dv, Hsat = 676.5;
257 short **senapix =
nullptr, **senzpix =
nullptr;
258 float **cth =
nullptr, temp;
259 NcFile *nc_l1c, *nc_l1c_new, *nc_l12_new, *nc_l12;
265 cout <<
"cloud_correct is 0,thus no paralallax correction is needed!!..use 1 (constant cloud height) "
266 "or 2 (variable cloud height)....."
270 cout <<
"l1cinput->cloud_correct is: " << l1cinput->
cloud_correct
271 <<
".LIC->(L1C paralallax corrected)...cloud height in km is constant throughout the L1C grid "
272 "but different from zero so parallax correction id needed..."
275 cout <<
"ERROR cloud_height is NOT greater than 0..or was not provided as input:"
281 for (
unsigned int i = 0;
i < l1cinput->
files_l1c.size();
i++) {
288 cout <<
"Opening L1C granule .#.." <<
i + 1 <<
"...." <<
l1c_str
289 <<
"for parallax-cloud corrections......." << endl;
292 nc_l1c =
new NcFile(l1c_gran, NcFile::read);
293 }
catch (NcException& e) {
295 cerr <<
"l1cgen l1c_pflag= 8:: Failure write FULL L1C grid: " +
l1c_str << endl;
299 NcDim yd = nc_l1c->getDim(
"bins_along_track");
300 num_ybin = yd.getSize();
301 NcDim xd = nc_l1c->getDim(
"bins_across_track");
302 num_xbin = xd.getSize();
304 ptime_l1c = (
double*)calloc(num_ybin,
sizeof(
double));
309 NcGroup ba_grp = nc_l1c->getGroup(
"bin_attributes");
310 NcVar v1 = ba_grp.getVar(
"nadir_view_time");
311 v1.getVar(ptime_l1c);
313 NcGroup geo_grp = nc_l1c->getGroup(
"geolocation_data");
314 v1 = geo_grp.getVar(
"latitude");
315 v1.getVar(&l1clat[0][0]);
316 v1 = geo_grp.getVar(
"longitude");
317 v1.getVar(&l1clon[0][0]);
318 v1 = geo_grp.getVar(
"altitude");
319 v1.getVar(&l1calt[0][0]);
321 cout <<
"num along bins L1C..." << num_ybin <<
"num_across bins L1C...." << num_xbin
322 <<
"l1c time_ini.." << ptime_l1c[0] <<
"l1c time end.." << ptime_l1c[num_ybin - 1] << endl;
327 for (
size_t i = 0;
i < num_ybin;
i++) {
328 for (
size_t j = 0;
j < num_xbin;
j++) {
330 Rsurf =
Re / (sqrt(cos(l1clat[
i][
j] *
M_PI / 180) * cos(l1clat[
i][
j] *
M_PI / 180) +
331 radius_ratio * radius_ratio * sin(l1clat[
i][
j] *
M_PI / 180) *
332 sin(l1clat[
i][
j] *
M_PI / 180)));
334 sin(l1clon[
i][
j] *
M_PI / 180);
337 cos(l1clon[
i][
j] *
M_PI / 180);
339 latcorr = atan(Ycorr / sqrt(Xcorr * Xcorr + Zcorr * Zcorr));
340 lat_new[
i][
j] = atan(tan(latcorr) / radius_ratio * radius_ratio) * 180.0 /
M_PI;
341 lon_new[
i][
j] = atan2(Xcorr, Zcorr) * 180.0 /
M_PI;
342 lon_new[
i][
j] = atan2(Ycorr, Xcorr) * 180 /
M_PI;
344 if(l1cinput->
verbose) cout<<
"l1cinput->cloud_height.."<<l1cinput->
cloud_height<<
"latnew.."<<lat_new[
i][
j]<<
"lon_new.."<<lon_new[
i][
j]<<
"l1clat.."<<l1clat[
i][
j]<<
"l1clon.."<<l1clon[
i][
j]<<endl;
349 string gran_str = to_string(
gran);
351 string l1c_gran_new =
l1c_str.substr(0, 24) +
"_CTH" + cth_str +
".gran" + gran_str +
".nc";
352 if(l1cinput->
verbose)cout <<
"corrected L1C grid" << l1c_gran_new <<
" granule #" << gran_str << endl;
354 const char* l1c_gran = l1c_gran_new.c_str();
357 nc_l1c_new =
new NcFile(l1c_gran, NcFile::replace);
358 }
catch (NcException& e) {
360 cerr <<
"l1cgen l1c_pflag= 8:: Failure write FULL L1C grid: " + l1c_gran_new << endl;
364 char* gridchar =
strdup(l1c_gran);
369 nc_l1c_new->putAtt(
"processing_version", l1cinput->
pversion);
370 nc_l1c_new->putAtt(
"history", l1cinput->
history);
372 nc_l1c_new->putAtt(
"product_name", l1c_gran_new);
373 NcGroupAtt i1 = nc_l1c->getAtt(
"startDirection");
375 nc_l1c_new->putAtt(
"startDirection",
name);
376 i1 = nc_l1c->getAtt(
"endDirection");
378 nc_l1c_new->putAtt(
"endDirection",
name);
379 i1 = nc_l1c->getAtt(
"time_coverage_start");
381 nc_l1c_new->putAtt(
"time_coverage_start",
name);
382 i1 = nc_l1c->getAtt(
"time_coverage_end");
384 nc_l1c_new->putAtt(
"time_coverage_end",
name);
385 i1 = nc_l1c->getAtt(
"date_created");
387 nc_l1c_new->putAtt(
"date_created",
name);
389 ba_grp = nc_l1c_new->getGroup(
"bin_attributes");
390 v1 = ba_grp.getVar(
"nadir_view_time");
391 v1.putVar(&ptime_l1c[0]);
392 geo_grp = nc_l1c_new->getGroup(
"geolocation_data");
393 v1 = geo_grp.getVar(
"latitude");
394 v1.putVar(&lat_new[0][0]);
395 v1 = geo_grp.getVar(
"longitude");
396 v1.putVar(&lon_new[0][0]);
397 v1 = geo_grp.getVar(
"altitude");
398 v1.putVar(&l1calt[0][0]);
412 <<
"LIB->(L1B paralallax corrected)----cloud_height is constant between pixels......" << endl;
415 cout <<
"ERROR cloud_height is NOT greater than 0..or was not provided as input:"
420 for (
unsigned int i = 0;
i < l1cinput->
files.size();
i++) {
422 string l12_str = l1cinput->
files[0];
423 const char* l_12 = l12_str.c_str();
425 if(l1cinput->
verbose)cout <<
"Opening L1B/L2 granule ..." << l1cinput->
files[0]
426 <<
"....for parallax-cloud corrections......." << endl;
429 nc_l12 =
new NcFile(l_12, NcFile::read);
430 }
catch (NcException& e) {
432 cerr <<
"l1cgen l1c_pflag= 8:: Failure write FULL L1C grid: " + l12_str << endl;
437 NcDim yd = nc_l12->getDim(
"number_of_scans");
438 NcDim xd = nc_l12->getDim(
"ccd_pixels");
439 num_scans = yd.getSize();
440 num_pixels = xd.getSize();
445 if(l1cinput->
verbose)cout <<
"number of scans.." << num_scans <<
"num of pixels.." << num_pixels << endl;
449 ptime = (
double*)calloc(num_scans,
sizeof(
double));
454 for (
unsigned int i = 0;
i < num_scans;
i++) {
455 for (
unsigned int j = 0;
j < num_pixels;
j++) {
460 NcGroup ba_grp = nc_l12->getGroup(
"scan_line_attributes");
461 NcVar v1 = ba_grp.getVar(
"time");
463 NcGroup geo_grp = nc_l12->getGroup(
"geolocation_data");
464 v1 = geo_grp.getVar(
"latitude");
465 v1.getVar(&latpix[0][0]);
466 v1 = geo_grp.getVar(
"longitude");
467 v1.getVar(&lonpix[0][0]);
468 float fillval_geo, scale_factor;
469 short senz_min, senz_max, sena_min, sena_max;
470 NcVarAtt a1 = v1.getAtt(
"_FillValue");
471 a1.getValues(&fillval_geo);
472 v1 = geo_grp.getVar(
"sensor_azimuth_angle");
473 v1.getVar(&senapix[0][0]);
474 a1 = v1.getAtt(
"valid_min");
475 a1.getValues(&sena_min);
476 a1 = v1.getAtt(
"valid_max");
477 a1.getValues(&sena_max);
478 v1 = geo_grp.getVar(
"sensor_zenith_angle");
479 v1.getVar(&senzpix[0][0]);
480 a1 = v1.getAtt(
"valid_min");
481 a1.getValues(&senz_min);
482 a1 = v1.getAtt(
"valid_max");
483 a1.getValues(&senz_max);
484 a1 = v1.getAtt(
"scale_factor");
485 a1.getValues(&scale_factor);
487 senz_min *= scale_factor;
488 senz_max *= scale_factor;
489 sena_min *= scale_factor;
490 sena_max *= scale_factor;
492 if(l1cinput->
verbose)cout <<
"computing parallax for each pixel.............." << endl;
494 for (
unsigned int i = 0;
i < num_scans;
i++) {
495 for (
unsigned int j = 0;
j < num_pixels;
j++) {
497 temp = senapix[
i][
j] * scale_factor;
498 if (senzpix[
i][
j] * scale_factor >= senz_min &&
499 senzpix[
i][
j] * scale_factor <= senz_max && temp >= sena_min && temp <= sena_max) {
500 dv = Hsat * cth[
i][
j] * tan(senzpix[
i][
j] * scale_factor *
M_PI / 180) /
504 lonpix[
i][
j] *
M_PI / 180 -
505 dv * sin((temp *
M_PI / 180 +
M_PI)) / (
Re * cos(lat_new[
i][
j] *
M_PI / 180));
506 if (lon_new[
i][
j] * 180 /
M_PI > 180) {
507 lon_new[
i][
j] -= 2 *
M_PI;
509 if (lon_new[
i][
j] * 180 /
M_PI < -180) {
510 lon_new[
i][
j] += 2 *
M_PI;
512 lat_new[
i][
j] *= 180 /
M_PI;
513 lon_new[
i][
j] *= 180 /
M_PI;
515 lat_new[
i][
j] = fillval_geo;
516 lon_new[
i][
j] = fillval_geo;
522 string gran_str = to_string(
gran);
524 string l12_gran_new =
525 l12_str.substr(0, 24) +
"_CTH" + cth_str +
".L1B" +
".gran" + gran_str +
".nc";
527 if(l1cinput->
verbose)cout <<
"corrected L1B grid" << l12_gran_new <<
" granule #" << gran_str << endl;
529 const char* l12_gran = l12_gran_new.c_str();
532 nc_l12_new =
new NcFile(l12_gran, NcFile::replace);
533 }
catch (NcException& e) {
535 cerr <<
"l1cgen mode= 9:: Failure write FULL L1B parallax corrected: " + l12_gran_new << endl;
539 nc_l12_new->putAtt(
"title",
"PACE OCIS Level-1B Data");
540 nc_l12_new->putAtt(
"instrument",
"OCIS");
541 nc_l12_new->putAtt(
"processing_version", l1cinput->
pversion);
542 nc_l12_new->putAtt(
"Conventions",
"CF-1.8 ACDD-1.3");
543 nc_l12_new->putAtt(
"institution",
544 "NASA Goddard Space Flight Center, Ocean Biology Processing Group");
547 "https://science.nasa.gov/earth-science/earth-science-data/data-information-policy/");
548 nc_l12_new->putAtt(
"naming_authority",
"gov.nasa.gsfc.sci.oceancolor");
549 nc_l12_new->putAtt(
"keywords_vocabulary",
550 "NASA Global Change Master Directory (GCMD) Science Keywords");
551 nc_l12_new->putAtt(
"stdname_vocabulary",
"NetCDF Climate and Forecast (CF) Metadata Convention");
552 nc_l12_new->putAtt(
"creator_name",
"NASA/GSFC");
553 nc_l12_new->putAtt(
"creator_email",
"data@oceancolor.gsfc.nasa.gov");
554 nc_l12_new->putAtt(
"creator_url",
"https://oceancolor.gsfc.nasa.gov");
555 nc_l12_new->putAtt(
"project",
"PACE Project");
556 nc_l12_new->putAtt(
"publisher_name",
"NASA/GSFC");
557 nc_l12_new->putAtt(
"publisher_email",
"data@oceancolor.gsfc.nasa.gov");
558 nc_l12_new->putAtt(
"publisher_url",
"https://oceancolor.gsfc.nasa.gov");
559 nc_l12_new->putAtt(
"processing_level",
"L1B parallax");
560 nc_l12_new->putAtt(
"cdm_data_type",
"swath");
561 nc_l12_new->putAtt(
"normalizedLt",
"0LL");
562 nc_l12_new->putAtt(
"history", l1cinput->
history);
563 nc_l12_new->putAtt(
"product_name", l12_gran_new);
564 NcGroupAtt i1 = nc_l12->getAtt(
"startDirection");
566 nc_l12_new->putAtt(
"startDirection",
name);
567 i1 = nc_l12->getAtt(
"endDirection");
569 nc_l12_new->putAtt(
"endDirection",
name);
570 nc_l12_new->putAtt(
"sample_offset",
"0LL");
571 i1 = nc_l12->getAtt(
"time_coverage_start");
573 i1.getValues(timeStartStr);
574 nc_l12_new->putAtt(
"time_coverage_start", timeStartStr);
575 i1 = nc_l12->getAtt(
"time_coverage_end");
577 nc_l12_new->putAtt(
"time_coverage_end",
name);
578 i1 = nc_l12->getAtt(
"date_created");
580 nc_l12_new->putAtt(
"date_created",
name);
581 nc_l12_new->putAtt(
"earth_sun_distance_correction",ncFloat,FillValue);
583 NcDim ydim = nc_l12_new->addDim(
"number_of_scans", num_scans);
584 NcDim xdim = nc_l12_new->addDim(
"ccd_pixels", num_pixels);
586 std::vector<NcDim> dimvec2_geo;
587 dimvec2_geo.push_back(ydim);
588 dimvec2_geo.push_back(xdim);
590 nc_l12_new->addDim(
"SWIR_pixels", num_pixels);
591 num_blue_bands = 120;
594 size_t vector_elements = 3;
595 nc_l12_new->addDim(
"blue_bands", num_blue_bands);
596 nc_l12_new->addDim(
"red_bands", num_red_bands);
597 nc_l12_new->addDim(
"SWIR_bands", num_SWIR_bands);
598 nc_l12_new->addDim(
"vector_elements", vector_elements);
600 ba_grp = nc_l12_new->addGroup(
"bin_attributes");
601 geo_grp = nc_l12_new->addGroup(
"geolocation_data");
602 v1 = ba_grp.addVar(
"nadir_view_time", ncDouble, ydim);
604 string longName =
"Time bin was viewed at nadir view";
605 v1.putAtt(
"long_name", longName);
606 string units =
"seconds since " + timeStartStr.substr(0, 10);
607 v1.putAtt(
"units",
units);
608 v1.putAtt(
"_FillValue", ncDouble, FillValue2);
609 double valid_min_d = 0;
610 v1.putAtt(
"valid_min", ncDouble, valid_min_d);
611 double valid_max_d = 172800;
612 v1.putAtt(
"valid_max", ncDouble, valid_max_d);
613 v1.putVar(&ptime[0]);
615 v1 = geo_grp.addVar(
"latitude", ncFloat, dimvec2_geo);
616 longName =
"Latitudes of bin locations";
617 v1.putAtt(
"long_name", longName);
618 units =
"degrees_north";
619 v1.putAtt(
"units",
units);
620 v1.putAtt(
"_FillValue", ncFloat, FillValue);
622 v1.putAtt(
"valid_min", ncFloat,
valid_min);
624 v1.putAtt(
"valid_max", ncFloat,
valid_max);
625 v1.putVar(&lat_new[0][0]);
627 v1 = geo_grp.addVar(
"longitude", ncFloat, dimvec2_geo);
628 longName =
"Longitudes of bin locations";
629 v1.putAtt(
"long_name", longName);
630 units =
"degrees_east";
631 v1.putAtt(
"units",
units);
632 v1.putAtt(
"_FillValue", ncFloat, FillValue);
634 v1.putAtt(
"valid_min", ncFloat,
valid_min);
636 v1.putAtt(
"valid_max", ncFloat,
valid_max);
637 v1.putVar(&lon_new[0][0]);
652 cout <<
"l1cinput->cloud_correct WAS NOT setup!" << endl;
662 double* tswt,
double tcross,
double mgv,
double* tmgv) {
663 int16_t bina = 0, binb = 0, ngridlines, gd = 0;
664 double tg = 0., mot = 0, t_start = -1, t_end = -1;
667 t_end = tswt[norbs - 1];
677 if(l1cinput->
verbose)cout <<
"computing time series assuming mean swath velocity..for swath#." << swt << endl;
680 tg = tcross - mot / 2;
681 gd = ngridlines / 2 - 1;
687 while (tg >= t_start) {
697 tg = tcross + mot / 2;
702 while (tg <= t_end) {
709 if(l1cinput->
verbose)cout <<
"bina.." << bina <<
"binb.." << binb << endl;
713 if(l1cinput->
verbose)cout <<
"number of L1C gridlines along-track..." << l1cfile->
num_gridlines <<
"for swath #.." << swt
714 <<
"t_start.." << t_start <<
"t_end..." << t_end << endl;
717 if(l1cinput->
verbose)cout <<
"time series not possible for swath #.." << swt <<
"tcross<0...." << endl;
725 double tcross,
double mgv,
double* tmgv) {
726 int16_t bina = 0, binb = 0, ngridlines, gd = 0;
727 double tg = 0., mot = 0;
737 if(l1cinput->
verbose)cout <<
"computing time series assuming mean swath velocity..for swath#." << swt << endl;
739 tg = tcross - mot / 2;
740 gd = ngridlines / 2 - 1;
744 cout<<
"NEGATIVE FIRST TIME BEFORE CROSSING"<<tg<<
"in swtime_swt2 for mean vel tmgv calc "<<mgv<<
"mot/2 "<<mot/2<<
"tcross "<<tcross<<endl;
746 while (binb < ngridlines / 2) {
756 tg = tcross + mot / 2;
761 while (bina < ngridlines / 2 + 1) {
768 if(l1cinput->
verbose)cout <<
"bina.." << bina <<
"binb.." << binb << endl;
772 if(l1cinput->
verbose)cout <<
"number of L1C gridlines along-track..." << l1cfile->
num_gridlines <<
"for swath #.." << swt
776 if(l1cinput->
verbose)cout <<
"time series not possible for swath #.." << swt <<
"tcross<0...." << endl;
785 double* lonswt_tot,
double* ovel_tot,
double* gvel_tot,
double* tswt,
double* latswt,
786 double* lonswt,
float* tcross,
float* loncross,
double* ovel,
double* gvel) {
788 double t1 = -1, t2 = -1;
791 int scan_brack[2] = {-1, -1};
792 float lat1, lat2, lon1, lon2;
794 double sum1 = 0, sum3 = 0;
797 norbs = ix2 - ix1 + 1;
801 latswt[
c] = latswt_tot[kk];
802 lonswt[
c] = lonswt_tot[kk];
803 tswt[
c] = tswt_tot[kk];
805 sum1 += ovel_tot[kk];
806 sum3 += gvel_tot[kk];
812 if (latswt[0] > latswt[1])
818 for (
size_t i = 0;
i < norbs - 1;
i++) {
819 if (latswt[
i] < 0. && latswt[
i + 1] > 0.) {
821 scan_brack[0] =
i + 1;
822 scan_brack[1] =
i + 2;
824 lat2 = latswt[
i + 1];
826 lon2 = lonswt[
i + 1];
827 if(i<norbs - 2 && i>0)
829 if(lat1==latswt[
i-1] || lat2==latswt[
i + 2])
839 else if (latswt[
i] > 0. && latswt[
i + 1] < 0) {
841 scan_brack[0] =
i + 2;
842 scan_brack[1] =
i + 1;
843 lat1 = latswt[
i + 1];
845 lon1 = lonswt[
i + 1];
847 if(i<norbs - 2 && i>0)
849 if(lat2==latswt[
i-1] || lat1==latswt[
i + 2])
860 if(l1cfile->
verbose) cout<<
"computing equatorial crossing time and longitude at crossing for a specific swath..orbit direction 0: descending, 1: ascending..."<<asc_mode<<endl;
862 if (scan_brack[0] > -1) {
864 t2 = tswt[tindex + 1];
865 if(l1cfile->
verbose)cout <<
"lat1.." << lat1 <<
"lat2..." << lat2 <<
"t1.." << t1 <<
"t2..." << t2 << endl;
866 *tcross = t1 - lat1 * (t2 - t1) / (lat2 - lat1);
868 float dtcross = (*tcross - t1) / (t2 - t1);
869 *loncross = lon1 + (lon2 - lon1) * dtcross;
871 l1cfile->
eqt = *tcross;
876 l1cfile->
eqt = -999.0;
884 *ovel = (sum1 / norbs);
885 *gvel = (sum3 / norbs) * 1000;
890 int sunz_swt(
int ix1_swt,
int ix2_swt, int16_t* hour_swt, int16_t* day_swt, int16_t* year_swt,
double* olat,
894 int year1 = year_swt[ix1_swt];
895 int day1 = day_swt[ix1_swt];
896 float hour1 = hour_swt[ix1_swt];
897 float lat1 = olat[ix1_swt];
898 float lon1 = olon[ix1_swt];
900 sunangs_(&year1, &day1, &hour1, &lon1, &lat1, &sunz1, &suna1);
908 year1 = year_swt[ix2_swt];
909 day1 = day_swt[ix2_swt];
910 hour1 = hour_swt[ix2_swt];
911 lat1 = olat[ix2_swt];
912 lon1 = olon[ix2_swt];
914 sunangs_(&year1, &day1, &hour1, &lon1, &lat1, &sunz1, &suna1);
915 if (sunz1 <= 93 || day_mode == 1)
926 double tswt_end_sec,
string* tswt_ini,
string* tswt_ini_file,
string* tswt_mid,
string* tswt_end) {
927 int16_t oneyear, onemon, oneday, onehour, onemin;
928 double onesec,tswt_mid_sec;
929 string y_swt, mo_swt, d_swt, h_swt, mi_swt, s_swt, s_swt2;
932 unix2ymdhms(tswt_ini_sec, &oneyear, &onemon, &oneday, &onehour, &onemin, &onesec);
933 y_swt = std::to_string(oneyear);
934 mo_swt = std::to_string(onemon);
935 d_swt = std::to_string(oneday);
936 h_swt = std::to_string(onehour);
937 mi_swt = std::to_string(onemin);
938 s_swt2 = std::to_string(round(onesec));
940 length = (
int)floor(log10(onemon)) + 1;
942 mo_swt =
"0" + mo_swt;
943 length = (
int)floor(log10(oneday)) + 1;
950 length = (
int)floor(log10(onehour + logoff)) + 1;
957 length = (
int)floor(log10(onemin + logoff)) + 1;
959 mi_swt =
"0" + mi_swt;
964 length = (
int)floor(log10(round(onesec) + logoff)) + 1;
966 s_swt2 =
"0" + s_swt2;
967 if (s_swt2.substr(1, 1) ==
".")
970 *tswt_ini = y_swt +
"-" + mo_swt +
"-" + d_swt +
"T" + h_swt +
":" + mi_swt +
":" + s_swt2.substr(0, 2);
971 *tswt_ini_file = y_swt + mo_swt + d_swt +
"T" + h_swt + mi_swt + s_swt2.substr(0, 2);
973 tswt_end_sec = tfile_ini_sec + tmgvf[num_gridlines - 2];
974 unix2ymdhms(tswt_end_sec, &oneyear, &onemon, &oneday, &onehour, &onemin, &onesec);
976 y_swt = std::to_string(oneyear);
977 mo_swt = std::to_string(onemon);
978 d_swt = std::to_string(oneday);
979 h_swt = std::to_string(onehour);
980 mi_swt = std::to_string(onemin);
981 s_swt2 = std::to_string(round(onesec));
983 length = (
int)floor(log10(onemon)) + 1;
985 mo_swt =
"0" + mo_swt;
986 length = (
int)floor(log10(oneday)) + 1;
993 length = (
int)floor(log10(onehour + logoff)) + 1;
1000 length = (
int)floor(log10(onemin + logoff)) + 1;
1002 mi_swt =
"0" + mi_swt;
1007 length = (
int)floor(log10(round(onesec) + logoff)) + 1;
1009 s_swt2 =
"0" + s_swt2;
1010 if (s_swt2.substr(1, 1) ==
".")
1013 *tswt_end = y_swt +
"-" + mo_swt +
"-" + d_swt +
"T" + h_swt +
":" + mi_swt +
":" + s_swt2.substr(0, 2);
1015 tswt_mid_sec=(tswt_ini_sec+tswt_end_sec)/2;
1016 unix2ymdhms(tswt_mid_sec, &oneyear, &onemon, &oneday, &onehour, &onemin, &onesec);
1018 y_swt = std::to_string(oneyear);
1019 mo_swt = std::to_string(onemon);
1020 d_swt = std::to_string(oneday);
1021 h_swt = std::to_string(onehour);
1022 mi_swt = std::to_string(onemin);
1023 s_swt2 = std::to_string(round(onesec));
1025 length = (
int)floor(log10(onemon)) + 1;
1027 mo_swt =
"0" + mo_swt;
1028 length = (
int)floor(log10(oneday)) + 1;
1030 d_swt =
"0" + d_swt;
1035 length = (
int)floor(log10(onehour + logoff)) + 1;
1037 h_swt =
"0" + h_swt;
1042 length = (
int)floor(log10(onemin + logoff)) + 1;
1044 mi_swt =
"0" + mi_swt;
1049 length = (
int)floor(log10(round(onesec) + logoff)) + 1;
1051 s_swt2 =
"0" + s_swt2;
1052 if (s_swt2.substr(1, 1) ==
".")
1055 *tswt_mid = y_swt +
"-" + mo_swt +
"-" + d_swt +
"T" + h_swt +
":" + mi_swt +
":" + s_swt2.substr(0, 2);
1065 string str, ifile_str;
1066 int status = -1, status1 = -1, status2 = -1;
1067 unsigned char** hkpackets =
nullptr;
1068 uint8_t* apids =
nullptr;
1069 size_t number_hkpack, number_scpack, number_orecords, number_hkpack_tot=0, number_scpack_tot=0,
1070 number_orecords_tot, nr=0;
1071 uint8_t ubnum1, ubnum2;
1072 double *sec =
nullptr, *tai58_sec =
nullptr;
1073 int16_t *year =
nullptr, *mon =
nullptr, *
day =
nullptr, *hour =
nullptr, *
min =
nullptr;
1074 int16_t oneyear, onemon, oneday, onehour, onemin;
1076 double *orb_time =
nullptr, *orb_lat =
nullptr, *orb_lon =
nullptr;
1077 float **lat_gd =
nullptr, **lon_gd =
nullptr, **alt =
nullptr;
1078 double omeg = 7.29211585494e-5;
1080 string temp_str, tai_str;
1081 double vxyz = 0, mov1 = 0., mgv1 = 0., mov2 = 0, mgv2, *orb_vel =
nullptr, *grn_vel =
nullptr;
1082 int* orb_dir =
nullptr;
1083 int ix1 = -1, ix2 = -1, ix3 = -1, ix4 = -1, ix5 = -1, ix6 = -1;
1084 double *tmgv1 =
nullptr, *tmgv2 =
nullptr, *tmgvf =
nullptr, *tmgvf2 =
nullptr;
1085 int32_t num_gridlines = -1, norbs = -1;
1086 double *tswt =
nullptr, *latswt =
nullptr, *lonswt =
nullptr;
1087 double *tswt2 =
nullptr, *latswt2 =
nullptr, *lonswt2 =
nullptr;
1088 const char* outlist;
1089 string ofile_str, senstr;
1090 string y_swt, mo_swt, d_swt, h_swt, mi_swt, s_swt, tswt_ini, tswt_end,tswt_mid;
1091 int32_t gd_per_gran = -1, numgran = -1;
1092 double deltasec = -1;
1094 string tswt_ini_file;
1095 double rl2, pos_norm, clatg2, fe = 1 / 298.257;
1098 double tswt_ini_sec, tswt_end_sec;
1100 double tfile_ini, tfile_end;
1101 int16_t
syear, smon,
sday, shour, smin, syear2, smon2, sday2, shour2, smin2;
1102 double secs, second, secs2, second2;
1103 double tfile_ini_sec, tfile_end_sec;
1104 size_t ix_ini=-1,ix_end=-1;
1107 number_orecords_tot = 6000;
1108 size_t cc = 0,
c = 0;
1110 int16_t* year_tot = (int16_t*)calloc(number_orecords_tot,
sizeof(int16_t));
1111 int16_t* day_tot = (int16_t*)calloc(number_orecords_tot,
sizeof(int16_t));
1112 int16_t* hour_tot = (int16_t*)calloc(number_orecords_tot,
sizeof(int16_t));
1113 double* orb_time_tot = (
double*)calloc(number_orecords_tot,
sizeof(
double));
1114 double* orb_lat_tot = (
double*)calloc(number_orecords_tot,
sizeof(
double));
1115 double* orb_lon_tot = (
double*)calloc(number_orecords_tot,
sizeof(
double));
1116 int* orb_dir_tot = (
int*)calloc(number_orecords_tot,
sizeof(
int));
1119 double* orb_vel_tot = (
double*)calloc(number_orecords_tot,
sizeof(
double));
1120 double* grn_vel_tot = (
double*)calloc(number_orecords_tot,
sizeof(
double));
1123 ifile_str = l1cinput->
files[0];
1124 ifile_char = (
char*)ifile_str.c_str();
1125 ofile_str = ifile_str.substr(0, 24);
1126 outlist =
"list_l1c_granules.txt";
1128 if (l1cinput->
outlist[0] ==
'\0') {
1130 if(l1cinput->
verbose)cout <<
"L1C granules written to DEFAULT file........" << outlist << endl;
1132 if(l1cinput->
verbose)cout <<
"L1C granules written to "
1133 "file......................................................................................."
1140 if(l1cinput->
verbose)cout <<
"format.type.." << format.type << endl;
1144 if (l1cinput->
sensor == 34) {
1146 l1cfile->
nbinx = 29;
1148 }
else if (l1cinput->
sensor == 30) {
1150 l1cfile->
nbinx = 519;
1152 }
else if (l1cinput->
sensor == 35) {
1154 l1cfile->
nbinx = 457;
1157 if(l1cinput->
verbose)cout <<
"sensor by default is OCI option 2....." << endl;
1159 l1cfile->
nbinx = 514;
1163 if(l1cinput->
verbose)cout <<
"PACE sensor to be griddded....." << senstr << endl;
1165 n_files = l1cfile->
ifiles.size();
1166 if(l1cinput->
verbose)cout <<
"number of files in the list...." << n_files << endl;
1168 int32_t nfiles = l1cfile->
ifiles.size();
1172 for (
int fi = 0; fi < nfiles; fi++)
1174 if(fi==nfiles-1)FirsTerrain=1;
1176 ptstr =
str.c_str();
1179 cout <<
"********************************************************************************************"
1182 cout <<
"Opening L1A file ..." << ptstr <<
"for telemetry......." << endl;
1183 cout <<
"********************************************************************************************"
1190 nc_l1a =
new NcFile(ptstr, NcFile::read);
1191 }
catch (NcException& e) {
1193 cerr <<
"l1cgen l1c_pflag= 8:: Failure write FULL L1C grid: " +
str << endl;
1198 NcGroupAtt i1 = nc_l1a->getAtt(
"time_coverage_start");
1203 i1 = nc_l1a->getAtt(
"time_coverage_end");
1209 unix2ymds(tfile_end, &syear2, &smon2, &sday2, &secs2);
1211 if(l1cinput->
verbose)cout <<
"secs elapsed.." << secs <<
"initial granule #..." << round(secs / (l1cfile->
gransize * 60))
1214 if(l1cinput->
verbose)cout <<
"HKT file start time................."
1215 <<
"year.." <<
syear <<
"month..." << smon <<
"day..." <<
sday <<
"hour.." << shour <<
"min.."
1216 << smin <<
"sec..." << second << endl;
1217 unix2ymdhms(tfile_end, &syear2, &smon2, &sday2, &shour2, &smin2, &second2);
1218 if(l1cinput->
verbose)cout <<
"HKT file end time................."
1219 <<
"year.." << syear2 <<
"month..." << smon2 <<
"day..." << sday2 <<
"hour.." << shour2
1220 <<
"min.." << smin2 <<
"sec..." << second2 << endl;
1228 tfile_ini_sec + 49 * 60 * 3;
1230 int16_t y_ini, mo_ini, d_ini, h_ini, mi_ini;
1232 unix2ymdhms(tfile_ini_sec, &y_ini, &mo_ini, &d_ini, &h_ini, &mi_ini, &sec_ini);
1233 if(l1cinput->
verbose)cout <<
"tfile_ini_sec.."
1234 <<
"YEAR.." << y_ini <<
"MONTH.." << mo_ini <<
"DAY.." << d_ini <<
"HOUR.." << h_ini <<
"MIN.."
1235 << mi_ini <<
"SEC.." << sec_ini << endl;
1236 unix2ymdhms(tfile_end_sec, &y_ini, &mo_ini, &d_ini, &h_ini, &mi_ini, &sec_ini);
1237 if(l1cinput->
verbose)cout <<
"tfile_end_sec.."
1238 <<
"YEAR.." << y_ini <<
"MONTH.." << mo_ini <<
"DAY.." << d_ini <<
"HOUR.." << h_ini <<
"MIN.."
1239 << mi_ini <<
"SEC.." << sec_ini << endl;
1246 NcDim dimhp = nc_l1a->getDim(
"SC_hkt_pkts");
1247 NcDim dimtp = nc_l1a->getDim(
"max_SC_packet");
1248 NcDim dimor = nc_l1a->getDim(
"orb_records");
1250 number_hkpack = dimhp.getSize();
1251 number_scpack = dimtp.getSize();
1252 number_orecords = dimor.getSize();
1255 number_hkpack_tot += number_hkpack;
1256 number_scpack_tot += number_scpack;
1257 nr += number_orecords;
1259 if(l1cinput->
verbose)cout <<
"number_hkpack_tot.." << number_hkpack_tot <<
"number_scpack_tot.." << number_scpack_tot
1260 <<
"number of orbit records total.REAL." << nr << endl;
1265 apids = (uint8_t*)calloc(number_hkpack,
sizeof(uint8_t));
1267 orb_time = (
double*)calloc(number_orecords,
sizeof(
double));
1268 orb_lat = (
double*)calloc(number_orecords,
sizeof(
double));
1269 orb_lon = (
double*)calloc(number_orecords,
sizeof(
double));
1270 orb_dir = (
int*)calloc(number_orecords,
sizeof(
int));
1273 NcGroup telGrp = nc_l1a->getGroup(
"housekeeping_data");
1274 NcGroup navGrp = nc_l1a->getGroup(
"navigation_data");
1277 NcVar v1 = telGrp.getVar(
"SC_HKT_packets");
1278 v1.getVar(&hkpackets[0][0]);
1280 v1 = navGrp.getVar(
"orb_time");
1281 v1.getVar(&orb_time[0]);
1282 v1 = navGrp.getVar(
"orb_lat");
1283 v1.getVar(&orb_lat[0]);
1284 v1 = navGrp.getVar(
"orb_lon");
1285 v1.getVar(&orb_lon[0]);
1287 for (
size_t hk = 0; hk < number_hkpack; hk++) {
1288 ubnum1 = (uint8_t)hkpackets[hk][0];
1289 ubnum2 = (uint8_t)hkpackets[hk][1];
1291 apids[hk] = (ubnum1 % 8) * 256 + ubnum2;
1292 if (apids[hk] == 128) {
1297 if(l1cinput->
verbose)cout <<
"#number of ephem elements...." << ix.size() <<
"for HKT file..." << ptstr <<
"#orecords..."
1298 << number_orecords << endl;
1299 n_ephem = ix.size();
1305 orb_vel = (
double*)calloc(n_ephem,
sizeof(
double));
1306 grn_vel = (
double*)calloc(n_ephem,
sizeof(
double));
1308 sec = (
double*)calloc(n_ephem,
sizeof(
double));
1309 year = (int16_t*)calloc(n_ephem,
sizeof(int16_t));
1310 mon = (int16_t*)calloc(n_ephem,
sizeof(int16_t));
1311 day = (int16_t*)calloc(n_ephem,
sizeof(int16_t));
1312 hour = (int16_t*)calloc(n_ephem,
sizeof(int16_t));
1313 min = (int16_t*)calloc(n_ephem,
sizeof(int16_t));
1315 tai58_sec = (
double*)calloc(n_ephem,
sizeof(
double));
1322 while (
c < ix.size()) {
1323 double* tai_ptr = (
double*)(hkpackets[ix[
c]] + 16);
1330 unix2ymdhms(tai58unix, &oneyear, &onemon, &oneday, &onehour, &onemin, &onesec);
1339 tai58_sec[
c] = tai58unix;
1348 double dp1, dp2, dp3;
1352 while (
c < ix.size()) {
1353 double* posi = (
double*)(hkpackets[ix[
c]] + 120);
1354 double* veli = (
double*)(hkpackets[ix[
c]] + 144);
1355 double* ecmat = (
double*)(hkpackets[ix[
c]] + 176);
1364 dp1 = posi[0] * ecmat[0] + posi[1] * ecmat[1] + posi[2] * ecmat[2];
1365 dp2 = posi[0] * ecmat[3] + posi[1] * ecmat[4] + posi[2] * ecmat[5];
1366 dp3 = posi[0] * ecmat[6] + posi[1] * ecmat[7] + posi[2] * ecmat[8];
1373 dp1 = veli[0] * ecmat[0] + veli[1] * ecmat[1] + veli[2] * ecmat[2];
1374 dp2 = veli[0] * ecmat[3] + veli[1] * ecmat[4] + veli[2] * ecmat[5];
1375 dp3 = veli[0] * ecmat[6] + veli[1] * ecmat[7] + veli[2] * ecmat[8];
1381 velr[
c][0] = velr[
c][0] + posr[
c][1] * omeg;
1382 velr[
c][1] = velr[
c][1] - posr[
c][0] * omeg;
1385 vxyz = sqrt(velr[
c][0] * velr[
c][0] + velr[
c][1] * velr[
c][1] +
1386 velr[
c][2] * velr[
c][2]);
1389 pos_norm = sqrt(posr[
c][0] * posr[
c][0] + posr[
c][1] * posr[
c][1] + posr[
c][2] * posr[
c][2]);
1390 clatg2 = sqrt(posr[
c][0] * posr[
c][0] + posr[
c][1] * posr[
c][1]) / pos_norm;
1391 rl2 =
Re * (1 - fe) / (sqrt(1 - (2 - fe) * fe * clatg2 * clatg2));
1392 grn_vel[
c] = vxyz * rl2 / pos_norm;
1397 for (
short n = 0; n < n_ephem; n++) {
1398 orb_time_tot[cc] = orb_time[n];
1399 orb_lon_tot[cc] = orb_lon[n];
1400 orb_lat_tot[cc] = orb_lat[n];
1401 orb_vel_tot[cc] = orb_vel[n];
1402 grn_vel_tot[cc] = grn_vel[n];
1403 velr_tot[cc][0] = velr[n][0];
1404 velr_tot[cc][1] = velr[n][1];
1405 velr_tot[cc][2] = velr[n][2];
1406 posr_tot[cc][0] = posr[n][0];
1407 posr_tot[cc][1] = posr[n][1];
1408 posr_tot[cc][2] = posr[n][2];
1409 year_tot[cc] = year[n];
1410 day_tot[cc] =
day[n];
1411 hour_tot[cc] = hour[n];
1415 if (hkpackets !=
nullptr)
1417 hkpackets =
nullptr;
1419 if (apids !=
nullptr)
1425 if (tai58_sec !=
nullptr)
1427 tai58_sec =
nullptr;
1433 if (year !=
nullptr)
1445 if (hour !=
nullptr)
1453 if (orb_lat !=
nullptr)
1457 if (orb_lon !=
nullptr)
1461 if (orb_time !=
nullptr)
1465 if (orb_vel !=
nullptr)
1469 if (grn_vel !=
nullptr)
1473 if (orb_dir !=
nullptr)
1477 if (posr !=
nullptr)
1481 if (velr !=
nullptr)
1484 if (senz !=
nullptr)
1488 if (sena !=
nullptr)
1494 if(l1cinput->
verbose)cout<<
"total number or orbital records #"<<cc-1<<endl;
1495 number_orecords_tot=cc-1;
1496 l1cfile->
norb_rec=number_orecords_tot;
1498 for (
size_t k = 0;
k < number_orecords_tot - 1;
k++) {
1499 if (orb_lat_tot[
k + 1] > orb_lat_tot[
k])
1507 int tlimits_swt[2][2] = {{-1, -1}, {-1, -1}};
1508 tlimits_swt[swt - 1][0] = 0;
1510 for (
size_t k = 0;
k < number_orecords_tot - 1;
k++) {
1511 if (orb_dir_tot[
k] != orb_dir_tot[
k + 1]) {
1513 tlimits_swt[swt - 1][1] =
k;
1516 tlimits_swt[swt - 1][0] =
k + 1;
1517 }
else if (swt == 2) {
1518 tlimits_swt[swt - 1][1] =
k;
1519 tlimits_swt[swt - 2][1] = number_orecords_tot - 1;
1523 if (
k == number_orecords_tot - 2 && swt == 2)
1524 tlimits_swt[swt - 1][1] = number_orecords_tot - 1;
1529 if(l1cinput->
verbose)cout <<
"nswath...................." << nswath <<
"number_orecords_tot.." << number_orecords_tot << endl;
1532 for (
size_t sw = 0; sw < 2; sw++) {
1535 ix1 = tlimits_swt[sw][0];
1536 ix2 = tlimits_swt[sw][1];
1537 if(l1cinput->
verbose)cout <<
"nswath#2......swat#1...ix1" << ix1 <<
"ix2.." << ix2 << endl;
1538 }
else if (sw == 1) {
1539 ix3 = tlimits_swt[sw][0];
1541 ix4 = number_orecords_tot - 1;
1542 if(l1cinput->
verbose)cout <<
"nswath2.....swat#2...ix3" << ix3 <<
"ix4.." << ix4 << endl;
1544 }
else if (nswath == 3) {
1546 ix1 = tlimits_swt[sw][0];
1547 ix2 = tlimits_swt[sw + 1][0] - 1;
1548 ix3 = tlimits_swt[sw + 1][1] + 1;
1549 ix4 = tlimits_swt[sw][1];
1550 if(l1cinput->
verbose)cout <<
"nswath3....swat#1...ix1" << ix1 <<
"ix2.." << ix2 <<
"ix3.." << ix3 <<
"ix4..."
1552 }
else if (sw == 1) {
1553 ix5 = tlimits_swt[sw][0];
1559 ix6 = number_orecords_tot - 1;
1561 if(l1cinput->
verbose)cout <<
"nswath3....swat#2...ix5" << ix5 <<
"ix6.." << ix6 << endl;
1564 if(l1cinput->
verbose)cout <<
"number of swaths is less than 2..!! exit..." << endl;
1569 float tcross1 = -999., loncross1 = -999., tcross2 = -999., loncross2 = -999.;
1580 if (ix1 >= 0 && ix5 < 0) {
1581 norbs = ix2 - ix1 + 1;
1584 day_mode =
sunz_swt(ix1, ix2, hour_tot, day_tot, year_tot, orb_lat_tot, orb_lon_tot);
1586 if(l1cinput->
verbose)cout <<
"day_mode at nswath #2 SWATH1." << day_mode << endl;
1588 if (day_mode == 1) {
1590 l1cfile->
orb_dir = orb_dir_tot[ix1];
1593 tswt = (
double*)calloc(norbs,
sizeof(
double));
1594 latswt = (
double*)calloc(norbs,
sizeof(
double));
1595 lonswt = (
double*)calloc(norbs,
sizeof(
double));
1597 status =
ect_swt(l1cfile, ix1, ix2, orb_time_tot, orb_lat_tot, orb_lon_tot, orb_vel_tot,
1598 grn_vel_tot, tswt, latswt, lonswt, &tcross1, &loncross1, &mov1, &mgv1);
1600 if(l1cinput->
verbose)cout <<
"nswath==2 --tcross equat crossing in (s)..swath#1..." << tcross1 <<
"loncross1..."
1601 << loncross1 << endl;
1603 if (latswt !=
nullptr)
1606 if (lonswt !=
nullptr)
1612 tmgv1 = (
double*)calloc(l1cfile->
num_gridlines,
sizeof(
double));
1613 tmgvf = (
double*)calloc(l1cfile->
num_gridlines,
sizeof(
double));
1615 swtime_swt2(1, l1cinput, l1cfile, norbs, tswt, tcross1, mgv1, tmgv1);
1618 if(l1cinput->
verbose)cout <<
"number of across bins L1C grid...#.." << l1cfile->
nbinx <<
"l1cfile->n_views..."
1626 velr_tot, mgv1, tmgv1, tmgvf, lat_gd, lon_gd, alt,FirsTerrain);
1629 if (tmgv1 !=
nullptr)
1636 tswt_ini_sec = tfile_ini_sec + tmgvf[0];
1637 tswt_end_sec = tfile_ini_sec + tmgvf[num_gridlines - 2];
1638 create_time_swt(num_gridlines, tfile_ini_sec, tmgvf, tswt_ini_sec,tswt_end_sec,
1639 &tswt_ini, &tswt_ini_file,&tswt_mid, &tswt_end);
1647 }
else if (l1cinput->
grantype == 0) {
1651 deltasec = tmgvf[num_gridlines - 2] - tmgvf[0] + 1;
1652 if(l1cinput->
verbose)cout <<
"deltasec..swath." << deltasec << endl;
1654 if (tswt !=
nullptr)
1661 gd_per_gran = round(num_gridlines / 10);
1663 if(l1cinput->
verbose)cout <<
"estimated # of granules to be processed..." << numgran <<
"gd_per_gran..."
1664 << gd_per_gran <<
"#gridlines.." << num_gridlines << endl;
1666 if(FirsTerrain)
write_L1C_granule2(1, l1cfile, l1cinput, tmgvf, lat_gd, lon_gd, alt,orb_time_tot);
1668 cout <<
"ERROR selecting grantype, must be 0: granules or 1: "
1669 "swath........................."
1675 if (lat_gd !=
nullptr)
1678 if (lon_gd !=
nullptr)
1681 if (tmgvf !=
nullptr)
1692 if(l1cinput->
verbose)cout <<
"ERROR swath #1 day_mode = " << day_mode
1693 <<
"nightime...continue to swath2 (nswath#2).............." << endl;
1701 norbs = ix4 - ix3 + 1;
1703 day_mode =
sunz_swt(ix3, ix4, hour_tot, day_tot, year_tot, orb_lat_tot, orb_lon_tot);
1705 if(l1cinput->
verbose)cout <<
"day_mode at nswath #2 SWATH2" << day_mode << endl;
1707 if (day_mode == 1) {
1709 l1cfile->
orb_dir = orb_dir_tot[ix3];
1711 tswt2 = (
double*)calloc(norbs,
sizeof(
double));
1712 latswt2 = (
double*)calloc(norbs,
sizeof(
double));
1713 lonswt2 = (
double*)calloc(norbs,
sizeof(
double));
1715 status =
ect_swt(l1cfile, ix3, ix4, orb_time_tot, orb_lat_tot, orb_lon_tot, orb_vel_tot,
1716 grn_vel_tot, tswt2, latswt2, lonswt2, &tcross2, &loncross2, &mov2, &mgv2);
1718 if(l1cinput->
verbose)cout <<
"nswath==2 ---tcross equat crossing in (s)..swath#2..." << tcross2 <<
"loncross2..."
1719 << loncross2 << endl;
1721 if (latswt2 !=
nullptr)
1724 if (lonswt2 !=
nullptr)
1731 tmgv2 = (
double*)calloc(l1cfile->
num_gridlines,
sizeof(
double));
1732 tmgvf2 = (
double*)calloc(l1cfile->
num_gridlines,
sizeof(
double));
1734 swtime_swt2(2, l1cinput, l1cfile, norbs, tswt2, tcross2, mgv2, tmgv2);
1740 gd_per_gran = round(num_gridlines / 10);
1743 if(l1cinput->
verbose)cout <<
"# of granules to be processed..." << numgran <<
"gd_per_gran..." << gd_per_gran
1746 if (tswt2 !=
nullptr)
1750 if(l1cinput->
verbose)cout <<
"number of across bins L1C grid...#.." << l1cfile->
nbinx << endl;
1756 velr_tot, mgv2, tmgv2, tmgvf2, lat_gd, lon_gd, alt,FirsTerrain);
1759 if (tmgv2 !=
nullptr)
1766 tswt_ini_sec = tfile_ini_sec + tmgvf2[0];
1767 tswt_end_sec = tfile_ini_sec + tmgvf2[num_gridlines - 2];
1769 create_time_swt(num_gridlines, tfile_ini_sec, tmgvf2, tswt_ini_sec, tswt_end_sec,
1770 &tswt_ini, &tswt_ini_file, &tswt_mid,&tswt_end);
1778 }
else if (l1cinput->
grantype == 0) {
1782 deltasec = tmgvf2[num_gridlines - 2] - tmgvf2[0] + 1;
1783 if(l1cinput->
verbose)cout <<
"deltasec..swath." << deltasec << endl;
1787 gd_per_gran = round(num_gridlines / 10);
1790 if(l1cinput->
verbose)cout <<
"estimated # of granules to be processed..." << numgran <<
"gd_per_gran..."
1791 << gd_per_gran <<
"#gridlines.." << num_gridlines << endl;
1792 if(FirsTerrain)
write_L1C_granule2(2, l1cfile, l1cinput, tmgvf2, lat_gd, lon_gd, alt,orb_time_tot);
1794 cout <<
"ERROR selecting grantype, must be 0: granules or 1: "
1795 "swath........................."
1800 if (lat_gd !=
nullptr)
1803 if (lon_gd !=
nullptr)
1806 if (tmgvf2 !=
nullptr)
1814 if(l1cinput->
verbose)cout <<
"ERROR swath #2 does not cross the equator..NO L1C grid for swath #2" << endl;
1818 if(l1cinput->
verbose)cout <<
"day_mode = 0 nightime...no L1C grid produced--exit (swath#2 --- "
1819 "nswath#2).............."
1820 << day_mode << endl;
1834 if (ix1 >= 0 && ix5 > 0) {
1835 norbs = ix2 - ix1 + 1;
1837 day_mode =
sunz_swt(ix1, ix2, hour_tot, day_tot, year_tot, orb_lat_tot, orb_lon_tot);
1839 if(l1cinput->
verbose)cout <<
"day_mode at nswath #3 SWATH1--segment#1: " << day_mode << endl;
1841 if (day_mode == 1) {
1842 l1cfile->
orb_dir = orb_dir_tot[ix1];
1844 tswt = (
double*)calloc(norbs,
sizeof(
double));
1845 latswt = (
double*)calloc(norbs,
sizeof(
double));
1846 lonswt = (
double*)calloc(norbs,
sizeof(
double));
1848 status1 =
ect_swt(l1cfile, ix1, ix2, orb_time_tot, orb_lat_tot, orb_lon_tot, orb_vel_tot,
1849 grn_vel_tot, tswt, latswt, lonswt, &tcross1, &loncross1, &mov1, &mgv1);
1850 if(l1cinput->
verbose)cout <<
"nswath==3 --tcross equat crossing in (s)..swath#1.(segment #1).." << tcross1
1851 <<
"loncross1..." << loncross1 <<
"orbit direction.0 is descending." << l1cfile->
orb_dir
1852 <<
"mov1.." << mov1 <<
"mgv1.." << mgv1 << endl;
1856 if (tswt !=
nullptr)
1859 if (latswt !=
nullptr)
1862 if (lonswt !=
nullptr)
1866 norbs = ix4 - ix3 + 1;
1868 tswt = (
double*)calloc(norbs,
sizeof(
double));
1869 latswt = (
double*)calloc(norbs,
sizeof(
double));
1870 lonswt = (
double*)calloc(norbs,
sizeof(
double));
1872 tcross1 = -999, loncross1 = -999.;
1874 l1cfile->
orb_dir = orb_dir_tot[ix3];
1876 day_mode =
sunz_swt(ix3, ix4, hour_tot, day_tot, year_tot, orb_lat_tot, orb_lon_tot);
1878 if(l1cinput->
verbose)cout <<
"day_mode at nswath #3 SWATH1--segment#2: " << day_mode << endl;
1880 status2 =
ect_swt(l1cfile, ix3, ix4, orb_time_tot, orb_lat_tot, orb_lon_tot, orb_vel_tot,
1881 grn_vel_tot, tswt, latswt, lonswt, &tcross1, &loncross1, &mov1, &mgv1);
1882 if(l1cinput->
verbose)cout <<
"nswath==3 -swath1---tcross equat crossing in (s)..swath#1.(segment #2).."
1883 << tcross1 <<
"loncross1..." << loncross1 <<
"orbit direction.0 is descending."
1884 << l1cfile->
orb_dir <<
"mov1.." << mov1 <<
"mgv1.." << mgv1 << endl;
1889 if (status1 == 0 || status2 == 0 && day_mode == 1) {
1890 tmgv1 = (
double*)calloc(l1cfile->
num_gridlines,
sizeof(
double));
1892 if(l1cinput->
verbose)cout <<
"#gridlines..." << l1cfile->
num_gridlines <<
"norbs.." << norbs << endl;
1898 1, l1cinput, l1cfile, norbs, tswt, tcross1, mgv1,
1903 double* tmgv1_segment = (
double*)calloc(l1cfile->
num_gridlines,
sizeof(
double));
1904 tmgvf = (
double*)calloc(l1cfile->
num_gridlines,
sizeof(
double));
1907 for (
int i = 0;
i < num_gridlines;
i++) {
1908 if (tmgv1[
i] >= 0) {
1909 tmgv1_segment[ss] = tmgv1[
i];
1914 if(l1cinput->
verbose)cout <<
"#segment gridlines.ss counter.." << ss <<
"equal to num_gridlines..."
1915 << num_gridlines << endl;
1917 if (tswt !=
nullptr)
1920 if (latswt !=
nullptr)
1923 if (lonswt !=
nullptr)
1927 if(l1cinput->
verbose)cout <<
"number of across bins L1C grid...#.." << l1cfile->
nbinx <<
"l1cfile->n_views..."
1937 else if(status2==0){
1942 velr_tot, mgv1, tmgv1_segment, tmgvf, lat_gd, lon_gd, alt,FirsTerrain);
1945 if (tmgv1 !=
nullptr)
1948 if (tmgv1_segment !=
nullptr)
1949 free (tmgv1_segment);
1950 tmgv1_segment =
nullptr;
1955 if(l1cinput->
verbose)cout <<
"Processing swath--->" << endl;
1956 tswt_ini_sec = tfile_ini_sec + tmgvf[0];
1957 tswt_end_sec = tfile_ini_sec + tmgvf[num_gridlines - 2];
1959 create_time_swt(num_gridlines, tfile_ini_sec, tmgvf, tswt_ini_sec, tswt_end_sec,
1960 &tswt_ini, &tswt_ini_file, &tswt_mid,&tswt_end);
1967 create_SOCEA2(1, l1cinput, l1cfile, lat_gd, lon_gd, alt, tmgvf);
1968 }
else if (l1cinput->
grantype == 0) {
1969 if(l1cinput->
verbose)cout <<
"Processing granules--->" << endl;
1972 gd_per_gran = round(num_gridlines / 10);
1975 if(l1cinput->
verbose)cout <<
"estimated # of granules to be processed..." << numgran <<
"gd_per_gran..."
1976 << gd_per_gran <<
"#gridlines.." << num_gridlines << endl;
1977 if(FirsTerrain)
write_L1C_granule2(1, l1cfile, l1cinput, tmgvf, lat_gd, lon_gd, alt,orb_time_tot);
1979 cout <<
"ERROR selecting grantype, must be 0: granules or 1: "
1980 "swath........................."
1987 if (lat_gd !=
nullptr)
1990 if (lon_gd !=
nullptr)
1993 if (tmgvf !=
nullptr)
2003 cout <<
"ERROR swath #1 does not cross the equator..." << endl;
2004 cout <<
"checking swath segment #2..." << endl;
2010 cout <<
"day_mode==0 (nighttime)...." << day_mode << endl;
2011 cout <<
"checking swath segment #2..." << endl;
2021 norbs = ix6 - ix5 + 1;
2023 day_mode =
sunz_swt(ix5, ix6, hour_tot, day_tot, year_tot, orb_lat_tot, orb_lon_tot);
2025 if(l1cinput->
verbose)cout <<
"day_mode at nswath #3 SWATH#2: " << day_mode << endl;
2027 if (day_mode == 1) {
2028 l1cfile->
orb_dir = orb_dir_tot[ix5];
2030 tswt2 = (
double*)calloc(norbs,
sizeof(
double));
2031 latswt2 = (
double*)calloc(norbs,
sizeof(
double));
2032 lonswt2 = (
double*)calloc(norbs,
sizeof(
double));
2034 status =
ect_swt(l1cfile, ix5, ix6, orb_time_tot, orb_lat_tot, orb_lon_tot, orb_vel_tot,
2035 grn_vel_tot, tswt2, latswt2, lonswt2, &tcross2, &loncross2, &mov2, &mgv2);
2036 if(l1cinput->
verbose)cout <<
"nswath==3 -swath2--tcross equat crossing in (s)..swath#2..." << tcross2 <<
"loncross2..."
2037 << loncross2 <<
"orbit direction.0 is descending." << l1cfile->
orb_dir <<
"mov2.." << mov2
2038 <<
"mgv2.." << mgv2 << endl;
2040 if (latswt2 !=
nullptr)
2043 if (lonswt2 !=
nullptr)
2049 if (
status == 0 && day_mode == 1) {
2050 tmgv2 = (
double*)calloc(l1cfile->
num_gridlines,
sizeof(
double));
2051 tmgvf2 = (
double*)calloc(l1cfile->
num_gridlines,
sizeof(
double));
2053 swtime_swt2(2, l1cinput, l1cfile, norbs, tswt2, tcross2, mgv2, tmgv2);
2056 if (tswt2 !=
nullptr)
2060 if(l1cinput->
verbose)cout <<
"number of across bins L1C grid...#.." << l1cfile->
nbinx <<
"l1cfile->n_views..."
2067 velr_tot, mgv2, tmgv2, tmgvf2, lat_gd, lon_gd, alt,FirsTerrain);
2070 if (tmgv2 !=
nullptr)
2077 tswt_ini_sec = tfile_ini_sec + tmgvf2[0];
2078 tswt_end_sec = tfile_ini_sec + tmgvf2[num_gridlines - 2];
2080 create_time_swt(num_gridlines, tfile_ini_sec, tmgvf2, tswt_ini_sec, tswt_end_sec,
2081 &tswt_ini, &tswt_ini_file, &tswt_mid,&tswt_end);
2087 create_SOCEA2(2, l1cinput, l1cfile, lat_gd, lon_gd, alt, tmgvf2);
2088 }
else if (l1cinput->
grantype == 0) {
2089 deltasec = tmgvf2[num_gridlines - 2] - tmgvf2[0] + 1;
2090 if(l1cinput->
verbose)cout <<
"deltasec..swath." << deltasec << endl;
2094 gd_per_gran = round(num_gridlines / 10);
2097 if(l1cinput->
verbose)cout <<
"estimated # of granules to be processed..." << numgran <<
"gd_per_gran..."
2098 << gd_per_gran <<
"#gridlines.." << num_gridlines << endl;
2100 if(FirsTerrain)
write_L1C_granule2(2, l1cfile, l1cinput, tmgvf2, lat_gd, lon_gd, alt,orb_time_tot);
2102 cout <<
"ERROR selecting grantype, must be 0: granules or 1: "
2103 "swath........................."
2107 if (lat_gd !=
nullptr)
2110 if (lon_gd !=
nullptr)
2113 if (tmgvf2 !=
nullptr)
2121 if(l1cinput->
verbose) cout <<
"ERROR swath #2 does not cross the equator..NO L1C grid for swath #2" << endl;
2126 cout <<
"day_mode = 0 nightime...no L1C grid produced--exit (swath#2 ---nswath#3).............."
2127 << day_mode << endl;
2136 free (orb_time_tot);
2140 delete[] (posr_tot);
2141 delete[] (velr_tot);
2150 float** altitude,
double* time_nad) {
2151 string tswt_ini, tswt_end, tswt_ini_file, date_created;
2154 string dirstr, prodstr;
2155 const char* filename_lt;
2156 int Nwest = -1, Neast = -1, Ngring = -1, midix = -1,
dp = -1;
2158 float latemp = -1, lontemp1 = -1, lontemp2 = -1, dlat_gd = -1, dlon_gd = -1, dlat20 = -1, dlon20 = -1,
2160 int re = -1, rw = -1;
2161 int32_t iyear=0,iday=0,
msec=0;
2162 string datezerotime,yearstr,monstr,daystr;
2164 double tdate_ini,secs;
2167 if(l1cinput->
verbose)cout <<
"Creating SOCEA proj for the whole orbit......." << endl;
2169 if (l1cinput->
sensor == 34) {
2171 l1cfile->
nbinx = 29;
2175 }
else if (l1cinput->
sensor == 30 || l1cinput->
sensor == 31) {
2177 l1cfile->
nbinx = 519;
2181 }
else if (l1cinput->
sensor == 35) {
2183 l1cfile->
nbinx = 457;
2188 cout <<
"sensor by default is OCI option 2....." << endl;
2190 l1cfile->
nbinx = 519;
2203 prodstr =
"PACE." + tswt_ini_file +
".L1C" + extstr;
2205 l1cfile->
gridname = prodstr.c_str();
2207 filename_lt = prodstr.c_str();
2208 char* gridchar =
strdup(filename_lt);
2213 nc_output =
new NcFile(filename_lt, NcFile::replace);
2214 }
catch (NcException& e) {
2216 cerr <<
"l1cgen l1c_pflag= 5 : producing L1C grid: " +
l1c_str << endl;
2227 dirstr =
"Ascending";
2228 else if (asc_mode == 0)
2229 dirstr =
"Descending";
2233 nc_output->putAtt(
"processing_version", l1cinput->
pversion);
2234 nc_output->putAtt(
"history", l1cinput->
history);
2235 nc_output->putAtt(
"product_name", prodstr);
2236 nc_output->putAtt(
"startDirection", dirstr);
2237 nc_output->putAtt(
"endDirection", dirstr);
2238 nc_output->putAtt(
"time_coverage_start", tswt_ini);
2239 nc_output->putAtt(
"time_coverage_end", tswt_end);
2243 nc_output->putAtt(
"sun_earth_distance", ncFloat, dist_es);
2244 if(l1cinput->
verbose)cout <<
"sun_earth_distance -- mid gridline" <<dist_es<<endl;
2248 yearstr=std::to_string(
syear);
2249 monstr=std::to_string(smon);
2250 if(monstr.size() == 1)
2251 monstr =
"0" + monstr;
2252 daystr=std::to_string(
sday);
2253 if(daystr.size() == 1)
2254 daystr =
"0" + daystr;
2255 datezerotime=
"seconds since " + yearstr +
"-" + monstr +
"-" + daystr;
2257 NcGroup ba_grp = nc_output->getGroup(
"bin_attributes");
2258 NcVar v1 = ba_grp.getVar(
"nadir_view_time");
2262 time_nad[gd]+=3600*24;
2266 v1.putVar(&time_nad[0]);
2267 v1.putAtt(
"units",datezerotime);
2270 NcGroup geo_grp = nc_output->getGroup(
"geolocation_data");
2271 v1 = geo_grp.getVar(
"latitude");
2272 v1.putVar(&lat_gd[0][0]);
2273 v1 = geo_grp.getVar(
"longitude");
2274 v1.putVar(&lon_gd[0][0]);
2275 v1 = geo_grp.getVar(
"height");
2276 v1.putVar(&altitude[0][0]);
2284 Nwest = round((lat_gd[l1cfile->
num_gridlines - 1][0] - lat_gd[0][0]) / 20);
2289 Neast = (round(lat_gd[0][0] - lat_gd[l1cfile->
num_gridlines - 1][0]) / 20);
2295 Ngring = Nwest + Neast + 6;
2298 float* latarr = (
float*)calloc(Ngring,
sizeof(
float));
2299 float* lonarr = (
float*)calloc(Ngring,
sizeof(
float));
2300 int* p_west = (
int*)calloc(Ngring,
sizeof(
int));
2301 int* p_east = (
int*)calloc(Ngring,
sizeof(
int));
2309 latarr[3] = lat_gd[0][0];
2310 latarr[4] = lat_gd[0][midix];
2311 latarr[5] = lat_gd[0][l1cfile->
nbinx - 1];
2316 lonarr[3] = lon_gd[0][0];
2317 lonarr[4] = lon_gd[0][midix];
2318 lonarr[5] = lon_gd[0][l1cfile->
nbinx - 1];
2333 while (latemp > lat_gd[0][0]) {
2334 latarr[2 +
p] = latemp;
2335 if(l1cinput->
verbose)cout <<
"p west--" <<
p <<
"point# = " << 3 +
p <<
"lat20 = " << latemp << endl;
2344 latarr[2 +
p + 1] = lat_gd[0][0];
2345 latarr[2 +
p + 2] = lat_gd[0][midix];
2346 latarr[2 +
p + 3] = lat_gd[0][l1cfile->
nbinx - 1];
2348 lonarr[2 +
p + 1] = lon_gd[0][0];
2349 lonarr[2 +
p + 2] = lon_gd[0][midix];
2350 lonarr[2 +
p + 3] = lon_gd[0][l1cfile->
nbinx - 1];
2352 latemp = latarr[2 +
p + 3];
2360 latarr[5 +
p] = latemp;
2361 if(l1cinput->
verbose)cout <<
"p east--" <<
c <<
"point# = " << 6 +
p <<
"lat20 = " << latemp << endl;
2371 if(l1cinput->
verbose){cout <<
"mid points west.." << rw <<
"mid points east.." <<
re << endl;
2372 cout <<
"# points in GRING = " << 6 +
p <<
"# mid points west--" << rw
2373 <<
"# mid points east--" <<
re << endl;
2380 for (
int i = 0;
i < rw;
i++) {
2382 if(l1cinput->
verbose) cout<<
"lat:"<<latarr[ix]<<
"pwest--"<<p_west[
i]<<endl;
2383 for (
int row = 0; row < l1cfile->
num_gridlines - 1; row++) {
2384 if (latarr[ix] > lat_gd[row][0] && latarr[ix] <= lat_gd[row + 1][0]) {
2385 if(l1cinput->
verbose) cout<<
"mid point west# = "<<
i+1<<
"found index between #row= "<<row+1<<
"and row ="<<row+2<<endl;
2387 if (lon_gd[row][0] < 0.)
2388 lontemp1 = lon_gd[row][0] + 360;
2390 lontemp1 = lon_gd[row][0];
2391 if (lon_gd[row + 1][0] < 0.)
2392 lontemp2 = lon_gd[row + 1][0] + 360;
2394 lontemp2 = lon_gd[row + 1][0];
2396 dlat_gd =
abs(lat_gd[row + 1][0] - lat_gd[row][0]);
2397 dlon_gd =
abs(lontemp1 - lontemp2);
2398 dlat20 =
abs(latarr[ix] - lat_gd[row + 1][0]);
2399 dlon20 = dlat20 * dlon_gd / dlat_gd;
2401 if (lontemp1 > lontemp2)
2402 lon360 = lontemp2 + dlon20;
2404 lon360 = lontemp2 - dlon20;
2406 lon360 = lon360 - 360.;
2407 lonarr[ix] = lon360;
2408 if(l1cinput->
verbose) cout<<
"lon_gd row+1.."<<lon_gd[row+1][0]<<
"lon_gd row.."<<lon_gd[row][0]<<
"lon cring.."<<lonarr[ix]<<endl;
2414 for (
int i = 0;
i <
re;
i++) {
2416 if(l1cinput->
verbose)cout <<
"lat:" << latarr[ix] <<
"peast--" << p_east[
i] << endl;
2417 for (
int row = 0; row < l1cfile->
num_gridlines - 1; row++) {
2418 if (latarr[ix] > lat_gd[row][l1cfile->
nbinx - 1] &&
2419 latarr[ix] <= lat_gd[row + 1][l1cfile->
nbinx - 1]) {
2420 if(l1cinput->
verbose) cout<<
"mid point east# = "<<
i+1<<
"found index between #row= "<<row+1<<
"and row ="<<row+2<<endl;
2422 if (lon_gd[row][l1cfile->
nbinx - 1] < 0.)
2423 lontemp1 = lon_gd[row][l1cfile->
nbinx - 1] + 360;
2425 lontemp1 = lon_gd[row][l1cfile->
nbinx - 1];
2426 if (lon_gd[row + 1][l1cfile->
nbinx - 1] < 0.)
2427 lontemp2 = lon_gd[row + 1][l1cfile->
nbinx - 1] + 360;
2429 lontemp2 = lon_gd[row + 1][l1cfile->
nbinx - 1];
2432 abs(lat_gd[row + 1][l1cfile->
nbinx - 1] - lat_gd[row][l1cfile->
nbinx - 1]);
2433 dlon_gd =
abs(lontemp1 - lontemp2);
2434 dlat20 =
abs(latarr[ix] - lat_gd[row][l1cfile->
nbinx - 1]);
2435 dlon20 = dlat20 * dlon_gd / dlat_gd;
2436 if (lontemp1 > lontemp2)
2437 lon360 = lontemp1 - dlon20;
2439 lon360 = lontemp1 + dlon20;
2441 lon360 = lon360 - 360.;
2442 lonarr[ix] = lon360;
2443 if(l1cinput->
verbose) cout<<
"lon_gd row+1.."<<lon_gd[row+1][l1cfile->
nbinx-1]<<
"lon_gd row.."<<lon_gd[row][l1cfile->
nbinx-1]<<
"lon cring.."<<lonarr[ix]<<endl;
2456 latarr[3] = lat_gd[0][0];
2457 latarr[4] = lat_gd[0][midix];
2458 latarr[5] = lat_gd[0][l1cfile->
nbinx - 1];
2463 lonarr[3] = lon_gd[0][0];
2464 lonarr[4] = lon_gd[0][midix];
2465 lonarr[5] = lon_gd[0][l1cfile->
nbinx - 1];
2480 while (latemp < lat_gd[0][0]) {
2481 latarr[2 +
p] = latemp;
2482 if(l1cinput->
verbose)cout <<
"p west--" <<
p <<
"point# = " << 3 +
p <<
"lat20 = " << latemp << endl;
2491 latarr[2 +
p + 1] = lat_gd[0][0];
2492 latarr[2 +
p + 2] = lat_gd[0][midix];
2493 latarr[2 +
p + 3] = lat_gd[0][l1cfile->
nbinx - 1];
2495 lonarr[2 +
p + 1] = lon_gd[0][0];
2496 lonarr[2 +
p + 2] = lon_gd[0][midix];
2497 lonarr[2 +
p + 3] = lon_gd[0][l1cfile->
nbinx - 1];
2498 latemp = latarr[2 +
p + 3];
2506 latarr[5 +
p] = latemp;
2507 if(l1cinput->
verbose)cout <<
"p east--" <<
c <<
"point# = " << 6 +
p <<
"lat20 = " << latemp << endl;
2518 cout <<
"mid points west.." << rw <<
"mid points east.." <<
re << endl;
2519 cout <<
"# points in GRING = " << 6 +
p <<
"# mid points west--" << rw
2520 <<
"# mid points east--" <<
re << endl;
2528 for (
int i = 0;
i < rw;
i++) {
2530 if(l1cinput->
verbose) cout<<
"lat:"<<latarr[ix]<<
"pwest--"<<p_west[
i]<<endl;
2531 for (
int row = 0; row < l1cfile->
num_gridlines - 1; row++) {
2532 if (latarr[ix] <= lat_gd[row][0] && latarr[ix] > lat_gd[row + 1][0]) {
2533 if(l1cinput->
verbose) cout<<
"mid point west# = "<<
i+1<<
"found index between #row= "<<row+1<<
"and row ="<<row+2<<endl;
2534 if (lon_gd[row][0] < 0.)
2535 lontemp1 = lon_gd[row][0] + 360;
2537 lontemp1 = lon_gd[row][0];
2538 if (lon_gd[row + 1][0] < 0.)
2539 lontemp2 = lon_gd[row + 1][0] + 360;
2541 lontemp2 = lon_gd[row + 1][0];
2543 dlat_gd =
abs(lat_gd[row][0] - lat_gd[row + 1][0]);
2544 dlon_gd =
abs(lontemp1 - lontemp2);
2545 dlat20 =
abs(latarr[ix] - lat_gd[row + 1][0]);
2546 dlon20 = dlat20 * dlon_gd / dlat_gd;
2548 if (lontemp1 > lontemp2)
2549 lon360 = lontemp2 + dlon20;
2551 lon360 = lontemp2 - dlon20;
2553 lon360 = lon360 - 360.;
2554 lonarr[ix] = lon360;
2555 if(l1cinput->
verbose) cout<<
"lon_gd row+1.."<<lon_gd[row+1][0]<<
"lon_gd row.."<<lon_gd[row][0]<<
"lon cring.."<<lonarr[ix]<<endl;
2561 for (
int i = 0;
i <
re;
i++) {
2563 if(l1cinput->
verbose) cout<<
"lat:"<<latarr[ix]<<
"peast--"<<p_east[
i]<<endl;
2564 for (
int row = 0; row < l1cfile->
num_gridlines - 1; row++) {
2565 if (latarr[ix] <= lat_gd[row][l1cfile->
nbinx - 1] &&
2566 latarr[ix] > lat_gd[row + 1][l1cfile->
nbinx - 1]) {
2567 if(l1cinput->
verbose)cout<<
"mid point east# = "<<
i+1<<
"found index between #row= "<<row+1<<
"and row ="<<row+2<<endl;
2568 if (lon_gd[row][l1cfile->
nbinx - 1] < 0.)
2569 lontemp1 = lon_gd[row][l1cfile->
nbinx - 1] + 360;
2571 lontemp1 = lon_gd[row][l1cfile->
nbinx - 1];
2572 if (lon_gd[row + 1][l1cfile->
nbinx - 1] < 0.)
2573 lontemp2 = lon_gd[row + 1][l1cfile->
nbinx - 1] + 360;
2575 lontemp2 = lon_gd[row + 1][l1cfile->
nbinx - 1];
2578 abs(lat_gd[row][l1cfile->
nbinx - 1] - lat_gd[row + 1][l1cfile->
nbinx - 1]);
2579 dlon_gd =
abs(lontemp1 - lontemp2);
2580 dlat20 =
abs(latarr[ix] - lat_gd[row][l1cfile->
nbinx - 1]);
2581 dlon20 = dlat20 * dlon_gd / dlat_gd;
2582 if (lontemp1 > lontemp2)
2583 lon360 = lontemp1 - dlon20;
2585 lon360 = lontemp1 + dlon20;
2587 lon360 = lon360 - 360.;
2588 lonarr[ix] = lon360;
2589 if(l1cinput->
verbose) cout<<
"lon_gd row+1.."<<lon_gd[row+1][l1cfile->
nbinx-1]<<
"lon_gd row.."<<lon_gd[row][l1cfile->
nbinx-1]<<
"lon cring.."<<lonarr[ix]<<endl;
2602 string onelat,onelon,onecoor,firstcoor;
2604 string gring_polygon,gring_crs,gring_latmin,gring_latmax,gring_lonmin,gring_lonmax;
2606 for (
int s = 0;
s <
dp;
s++) {
2607 onelat=to_string(latarr[
s]);
2608 onelon=to_string(lonarr[
s]);
2611 onecoor=
"POLYGON(("+onelat+
" "+onelon+
",";
2612 firstcoor=onelat+
" "+onelon;
2614 else onecoor=onelat+
" "+onelon+
",";
2615 gring_polygon+=onecoor;
2618 gring_polygon+=firstcoor+
"))";
2619 float latpmin=999,latpmax=-999,lonpmin=999,lonpmax=-999;
2622 for(
int col=0;col<l1cfile->
nbinx;col++)
2624 if(lat_gd[row][col]<latpmin && lat_gd[row][col]!=
BAD_FLT) latpmin=lat_gd[row][col];
2625 if(lat_gd[row][col]>latpmax && lat_gd[row][col]!=
BAD_FLT) latpmax=lat_gd[row][col];
2626 if(lon_gd[row][col]<lonpmin && lon_gd[row][col]!=
BAD_FLT) lonpmin=lon_gd[row][col];
2627 if(lon_gd[row][col]>lonpmax && lon_gd[row][col]!=
BAD_FLT) lonpmax=lon_gd[row][col];
2630 gring_crs=
"EPSG:4326";
2631 nc_output->putAtt(
"geospatial_bounds", gring_polygon);
2632 nc_output->putAtt(
"geospatial_bounds_crs", gring_crs);
2635 nc_output->putAtt(
"geospatial_lat_min", ncFloat, latpmin);
2636 nc_output->putAtt(
"geospatial_lat_max", ncFloat, latpmax);
2637 nc_output->putAtt(
"geospatial_lon_min", ncFloat, lonpmin);
2638 nc_output->putAtt(
"geospatial_lon_max", ncFloat, lonpmax);
2646 cout <<
"ERROR EXTRACTING GRING coordinates!!-----" << endl;
2656 int32_t num_gridlines, nbinx;
2658 float gnvec[3], gvec[3], bvec[3];
2663 int irow = -1, col = -1;
2664 float bmcm, bm = 100;
2667 double fudge = 0.00001,
dotprod, dot_firstline, dot_lastline;
2671 nbinx = l1cfile->
nbinx;
2673 num_pixels = l1cfile->
npix;
2679 for (pix = 0; pix < num_pixels; pix++) {
2682 bvec[2] = sin(l1cstr->
latpix[pix] *
M_PI / 180);
2684 for (
i = 0;
i < num_gridlines;
i++) {
2685 if (l1cstr->
latpix[pix] > 90 || l1cstr->
latpix[pix] < -90 || l1cstr->
lonpix[pix] < -180 ||
2686 l1cstr->
lonpix[pix] > 180) {
2693 if (l1cfile->
lat_gd[
i][nbinx - 1] > 90 || l1cfile->
lat_gd[
i][nbinx - 1] < -90 ||
2694 l1cfile->
lon_gd[
i][nbinx - 1] < -180 || l1cfile->
lon_gd[
i][nbinx - 1] > 180) {
2695 cout <<
"lat lon out of the boundaries.." << endl;
2699 l1cfile->
lon_gd[
i][0] > 180) {
2700 cout <<
"lat lon out of the boundaries.." << endl;
2704 gnvec[0] = sin(l1cfile->
lon_gd[
i][nbinx - 1] *
M_PI / 180) *
2709 gnvec[1] = sin(l1cfile->
lat_gd[
i][nbinx - 1] *
M_PI / 180) *
2714 gnvec[2] = cos(l1cfile->
lon_gd[
i][nbinx - 1] *
M_PI / 180) *
2722 gnvm = sqrt(gnvec[0] * gnvec[0] + gnvec[1] * gnvec[1] + gnvec[2] * gnvec[2]);
2723 if (isnan(gnvm) == 1) {
2724 cout <<
"NAN value for gnvm.." << endl;
2728 cout <<
"ERROR gnvm == 0--- WE CANT NORMALIZE..." << endl;
2732 gnvec[0] = gnvec[0] / gnvm;
2733 gnvec[1] = gnvec[1] / gnvm;
2734 gnvec[2] = gnvec[2] / gnvm;
2738 dotprod = gnvec[0] * bvec[0] + gnvec[1] * bvec[1] + gnvec[2] * bvec[2];
2743 if (
i == num_gridlines - 1) {
2747 if (
dotprod - fudge <= db && dotprod + fudge > -
db) {
2748 gdindex[pix][0] =
i + 1;
2753 if (dot_firstline <= db && dot_lastline > -
db) {
2756 irow = gdindex[pix][0] - 1;
2758 cout <<
"ERROR icol in search_l1c..."
2759 <<
"at pix#.." << pix + 1 <<
"and irow#.." << irow << endl;
2763 for (
int j = 0;
j < nbinx;
j++) {
2768 gvec[2] = sin(l1cfile->
lat_gd[irow][
j] *
M_PI / 180);
2770 c1 = bvec[0] - gvec[0];
2771 c2 = bvec[1] - gvec[1];
2772 c3 = bvec[2] - gvec[2];
2774 bmcm = sqrt(c1 * c1 + c2 * c2 + c3 * c3);
2781 cout <<
"ERROR col in search_l1c..."
2782 <<
"at pix#.." << pix + 1 <<
"and row#.." << irow + 1 << endl;
2786 gdindex[pix][1] = col;
2790 gdindex[pix][0] = -1;
2791 gdindex[pix][1] = -1;
2797 for (pix = 0; pix < num_pixels; pix++) {
2798 if (gdindex[pix][0] > 0 && gdindex[pix][1] > 0) {
2801 if(l1cinput->
verbose) cout<<
"THIS LINE WILL BE SKIPPED -- NO PIXELS BINNED.............."<<endl;
2814 int32_t num_gridlines, nbinx;
2817 int32_t
NY = -1,
NX = -1;
2819 string gridname, azeast_name;
2820 string tswt_ini_file;
2821 std::string fname_out, senstr, monstr, daystr, yearstr, prodstr, gdstr, swtstr, extstr, granstr,
2822 timestr, azstr, missionstr, ofilestr;
2831 if(l1cinput->
verbose)cout <<
"projection type is SOCEA!!!........for grid file..:" << gridname << endl;
2834 gridname =
"/accounts/mamontes/images/OCIS/sean/out/FB_L1Cgrid.nc";
2837 if(l1cinput->
verbose)cout <<
"gridname.." << gridname << endl;
2838 ptstr = gridname.c_str();
2840 if(l1cinput->
verbose)cout <<
"Opening L1C grid ." << gridname <<
"for parallax-cloud corrections......." << endl;
2842 nc_l1c =
new NcFile(ptstr, NcFile::read);
2843 }
catch (NcException& e) {
2845 cerr <<
"l1cgen l1c_pflag= 8:: Failure write FULL L1C grid: " + gridname << endl;
2850 NcGroupAtt i1 = nc_l1c->getAtt(
"instrument");
2852 i1 = nc_l1c->getAtt(
"startDirection");
2854 i1 = nc_l1c->getAtt(
"endDirection");
2855 i1.getValues(l1cfile->
end_dir);
2856 i1 = nc_l1c->getAtt(
"time_coverage_start");
2858 i1 = nc_l1c->getAtt(
"time_coverage_end");
2860 i1 = nc_l1c->getAtt(
"nadir_bin");
2861 i1.getValues(l1cfile->
binstr);
2864 NcDim ydim = nc_l1c->getDim(
"bins_along_track");
2865 NcDim xdim = nc_l1c->getDim(
"bins_across_track");
2869 num_gridlines = ydim.getSize();
2870 nbinx = xdim.getSize();
2872 if(l1cinput->
verbose)cout <<
"num_gridlines..." << num_gridlines <<
"nbinx....." << nbinx << endl;
2880 NcGroup geo_grp = nc_l1c->getGroup(
"geolocation_data");
2881 NcVar v1 = geo_grp.getVar(
"latitude");
2882 v1.getVar(&l1cfile->
lat_gd[0][0]);
2883 v1 = geo_grp.getVar(
"longitude");
2884 v1.getVar(&l1cfile->
lon_gd[0][0]);
2885 v1 = geo_grp.getVar(
"altitude");
2886 v1.getVar(&l1cfile->
alt_gd[0][0]);
2897 vector<pair<float, int>> vp;
2900 if(l1cinput->
verbose)cout <<
"*********** SORTING LAT/LON GRIDPOINTS AND TRACKING INDEXES ********************" << endl;
2902 for (
int col = 0; col <
NX; col++) {
2903 for (
int row = 0; row <
NY; row++) {
2904 vp.push_back(make_pair(l1cfile->
lat_gd[row][col] + 90., row));
2907 stable_sort(vp.begin(), vp.end());
2909 for (
unsigned int i = 0;
i < vp.size();
i++) {
2922 float** lat_gd,
float** lon_gd,
float** alt_gd,
double *orb_time_tot) {
2923 int32_t num_gridlines, nbinx, NY1 = -1, NY2 = -1;
2925 const char* filename_lt;
2926 float **lat_out =
nullptr, **lon_out =
nullptr, **alt_out =
nullptr;
2927 double* time_nad_out =
nullptr;
2928 int asc_mode = l1cfile->
orb_dir;
2930 double tg_ini, tg_end,tg_mid;
2932 double tgridline=-1, tfile_ini_sec=-1, tfile_end_sec=-1;
2933 int16_t* granid =
nullptr;
2935 short** gdindex =
nullptr;
2936 double** gdtime =
nullptr;
2937 int16_t y_ini, mo_ini, d_ini, h_ini, mi_ini, y_end, mo_end, d_end, h_end, mi_end, y_mid, mo_mid, d_mid, h_mid, mi_mid,y_zero, mo_zero, d_zero,h_zero,mi_zero;
2938 double sec_ini, sec_end,sec_mid,sec_zero;
2939 string tswt_ini, tswt_end, tswt_ini_file;
2941 int16_t
syear, smon,
sday, syear2, smon2, sday2;
2943 double tgran_ini, tgran_ini_sec, tgran_end, tgran_end_sec;
2946 int Ngring = -1,
dp = -1;
2947 int32_t iyear=0,iday=0,
msec=0;
2948 int twodays=0,nadir_bin_index;
2949 Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
2952 double tfile_ini_offset=-1;
2954 if (l1cinput->
sensor == 34) {
2956 l1cfile->
nbinx = 29;
2959 }
else if (l1cinput->
sensor == 30 || l1cinput->
sensor == 31) {
2961 l1cfile->
nbinx = 519;
2962 nadir_bin_index=259;
2964 }
else if (l1cinput->
sensor == 35) {
2966 l1cfile->
nbinx = 457;
2967 nadir_bin_index=228;
2969 if(l1cinput->
verbose)cout <<
"sensor by default is OCI option 2....." << endl;
2971 l1cfile->
nbinx = 519;
2972 nadir_bin_index=259;
2979 if(l1cinput->
verbose)cout <<
"swath#....................................................................." << swtd
2980 <<
"asc_mode..." << asc_mode << endl;
2982 granid = (int16_t*)calloc(num_gridlines,
sizeof(int16_t));
2986 nbinx = l1cfile->
nbinx;
2992 tfile_ini_offset=tfile_ini_sec;
2994 double time_zero=tfile_ini_sec-24*3600;
2995 tg_ini = tfile_ini_sec;
2996 tg_end = tg_ini + gransize * 60;
3000 if(l1cinput->
verbose)cout <<
"Processing L1C granules between ........................" << l1cinput->
start_time
3001 <<
"and ........................." << l1cinput->
end_time << endl;
3005 unix2ymds(tgran_end, &syear2, &smon2, &sday2, &secs2);
3006 tgran_ini_sec = tgran_ini;
3008 tg_ini = tgran_ini_sec;
3009 tg_end = tg_ini + gransize * 60;
3010 tgran_end_sec = tgran_end;
3012 tfile_end_sec = tgran_end_sec + gransize * 60;
3014 unix2ymdhms(tgran_ini_sec, &y_ini, &mo_ini, &d_ini, &h_ini, &mi_ini, &sec_ini);
3015 if(l1cinput->
verbose)cout <<
"tgran_ini_sec.."
3016 <<
"YEAR.." << y_ini <<
"MONTH.." << mo_ini <<
"DAY.." << d_ini <<
"HOUR.." << h_ini <<
"MIN.."
3017 << mi_ini <<
"SEC.." << sec_ini << endl;
3018 unix2ymdhms(tgran_end_sec, &y_ini, &mo_ini, &d_ini, &h_ini, &mi_ini, &sec_ini);
3020 if (tgran_end_sec > tfile_end_sec) {
3021 cout <<
"ERROR--tgran_end_sec>tfile_end_sec...wrong command line (gran_end_time).gran_end_time "
3022 "beyond swath time limits.."
3027 if(l1cinput->
verbose)cout <<
"tgran_end_sec.."
3028 <<
"YEAR.." << y_ini <<
"MONTH.." << mo_ini <<
"DAY.." << d_ini <<
"HOUR.." << h_ini <<
"MIN.."
3029 << mi_ini <<
"SEC.." << sec_ini << endl;
3030 unix2ymdhms(tg_ini, &y_ini, &mo_ini, &d_ini, &h_ini, &mi_ini, &sec_ini);
3031 if(l1cinput->
verbose)cout <<
"tg_ini.."
3032 <<
"YEAR.." << y_ini <<
"MONTH.." << mo_ini <<
"DAY.." << d_ini <<
"HOUR.." << h_ini <<
"MIN.."
3033 << mi_ini <<
"SEC.." << sec_ini << endl;
3034 unix2ymdhms(tg_end, &y_ini, &mo_ini, &d_ini, &h_ini, &mi_ini, &sec_ini);
3035 if(l1cinput->
verbose)cout <<
"tg_end.."
3036 <<
"YEAR.." << y_ini <<
"MONTH.." << mo_ini <<
"DAY.." << d_ini <<
"HOUR.." << h_ini <<
"MIN.."
3037 << mi_ini <<
"SEC.." << sec_ini << endl;
3039 if(l1cinput->
verbose)cout <<
"ERROR Processing L1C granules between initial and final time --"
3040 <<
"start_time.." << l1cinput->
start_time <<
"end_time.." << l1cinput->
end_time <<
"grantype..."
3044 for (
int i = 0;
i < num_gridlines;
i++) {
3048 for (
int i = 0;
i < numgran;
i++) {
3049 for (
size_t j = 0;
j < 2;
j++) {
3055 int neg = 0, gmin = -1,
c = 0;
3056 if(tmgv[0]<0) twodays=1;
3060 for (
int i = 0;
i < num_gridlines;
i++) {
3062 tfile_ini_sec + tmgv[
i];
3063 if (tg_end > tgran_end_sec)
3064 tg_end = tgran_end_sec;
3065 if (tgridline >= tg_ini && tgridline < tg_end) {
3068 if (tg_ini >= tgran_ini_sec && tg_end <= tgran_end_sec + gransize * 60) {
3070 gdtime[
c][0] = tg_ini;
3071 if (
i == num_gridlines - 1)
3072 gdtime[
c][1] = tgridline;
3074 gdtime[
c][1] = tg_end;
3079 if (
i == num_gridlines - 1)
3080 gdtime[
c][1] = tgridline;
3082 gdtime[
c][1] = tg_end;
3087 gdtime[
c][0] = tg_ini;
3088 if (
i == num_gridlines - 1)
3089 gdtime[
c][1] = tgridline;
3091 gdtime[
c][1] = tg_end;
3096 if (
i == num_gridlines - 1)
3097 gdtime[
c][1] = tgridline;
3099 gdtime[
c][1] = tg_end;
3104 if (tmgv[
i] < 0 &&
gran == 0) {
3110 tg_end = tg_ini + gransize * 60;
3114 if (tg_ini > tgridline) {
3115 if(l1cinput->
verbose)cout <<
"gridlines with negative time..." << neg << endl;
3120 if (tg_ini >= tg_end || tg_ini >= tgran_end_sec || tg_end > (tgran_end_sec + gransize * 60)) {
3121 if(l1cfile->
verbose)cout<<
"ERROR : GRAN # "<<
c+1<<
"tg_ini >= tg_end || tg_ini >= tgran_end_sec || tg_end > (tgran_end_sec + gransize * 60"<<endl;
3128 std::string timestr, missionstr, fname_out, fname_out_nopath, pathstr, monstr, daystr, yearstr, secstr,
3129 mistr, hstr, prodstr, gdstr, swtstr, extstr, ofilestr, dirstr1, dirstr2,datetimestr1, datetimestr2,datetimestr3,
3130 fdatetimestr1, date_created,datezerotime;
3131 std::string y_create, m_create, d_create, t_create;
3134 missionstr =
"PACE";
3137 if(l1cinput->
outlist[0]==
'\0')
3139 string outxt(l1cinput->
outlist);
3141 outxt = pathstr + outxt;
3148 if(l1cinput->
verbose)cout <<
"writing L1C granules to outfile..." << outxt << endl;
3150 std::cerr <<
"output file.." << outxt <<
" could not be opened for writing!\n";
3157 int16_t ngridlines, totlines = 0;
3162 NY1 = gdindex[
gran][0];
3163 NY2 = gdindex[
gran][1];
3171 tfile_ini_offset=time_zero;
3172 if(l1cinput->
verbose==1) cout<<
"twodays flag is ON!! : "<<twodays<<
"tzero offset = "<< tfile_ini_offset<<endl;
3177 tg_ini = gdtime[
gran][0];
3178 tg_end = gdtime[
gran][1];
3179 unix2ymdhms(tg_ini, &y_ini, &mo_ini, &d_ini, &h_ini, &mi_ini, &sec_ini);
3180 unix2ymdhms(tg_end, &y_end, &mo_end, &d_end, &h_end, &mi_end, &sec_end);
3181 cout<<
"--------------------------"<<endl;
3182 cout<<
"gran# "<<
gran+1<<
"day ini "<<d_ini<<
"h ini "<<h_ini<<
"mi ini "<<mi_ini<<
"sec ini "<<sec_ini<<
"tgini "<<tg_ini<<endl;
3183 cout<<
"gran# "<<
gran+1<<
"day end "<<d_end<<
"h end "<<h_end<<
"mi end "<<mi_end<<
"sec end "<<sec_end<<
"tend "<<tg_end<<endl;
3184 tg_ini = tfile_ini_offset+orb_time_tot[0];
3185 tg_end = tfile_ini_sec+orb_time_tot[norb_rec-1];
3186 unix2ymdhms(tg_ini, &y_ini, &mo_ini, &d_ini, &h_ini, &mi_ini, &sec_ini);
3187 unix2ymdhms(tg_end, &y_end, &mo_end, &d_end, &h_end, &mi_end, &sec_end);
3188 cout<<
"orbital time limits ----------------- "<<endl;
3189 cout<<
"gran# "<<
gran+1<<
"day ini "<<d_ini<<
"h ini "<<h_ini<<
"mi ini "<<mi_ini<<
"sec ini "<<sec_ini<<
"tgini "<<tg_ini<<endl;
3190 cout<<
"gran# "<<
gran+1<<
"day end "<<d_end<<
"h end "<<h_end<<
"mi end "<<mi_end<<
"sec end "<<sec_end<<
"tend "<<tg_end<<endl;
3191 cout<<
"---------------------------"<<endl;
3196 if(tfile_ini_offset+orb_time_tot[0]>tfile_ini_sec+orb_time_tot[norb_rec-1]) orb_time_tot[0]-=24*3600;
3197 if(gdtime[
gran][1]>tfile_ini_sec+orb_time_tot[norb_rec-1]) torb_off=gdtime[
gran][1]-tfile_ini_sec-orb_time_tot[norb_rec-1];
3199 if(torb_off>2*60) torb_off=0;
3201 if (gdtime[
gran][0]>=(tfile_ini_offset+orb_time_tot[0]) && gdtime[
gran][1]<=(tfile_ini_sec+orb_time_tot[norb_rec-1]+torb_off))
3203 if(l1cinput->
verbose)cout <<
"gran #..." <<
gran + 1 <<endl;
3205 tg_ini = gdtime[
gran][0];
3206 tg_end = gdtime[
gran][1];
3207 tg_mid=(tg_ini+tg_end)/2;
3209 unix2ymdhms(tg_ini, &y_ini, &mo_ini, &d_ini, &h_ini, &mi_ini, &sec_ini);
3210 unix2ymdhms(tg_end, &y_end, &mo_end, &d_end, &h_end, &mi_end, &sec_end);
3211 unix2ymdhms(tg_mid, &y_mid, &mo_mid, &d_mid, &h_mid, &mi_mid, &sec_mid);
3213 if (mi_end * 60 == 0)
3215 gtime = ((60 * 60 + round(sec_end)) - mi_ini * 60 - round(sec_ini)) / 60;
3219 gtime = ((mi_end * 60 + round(sec_end)) - mi_ini * 60 - round(sec_ini)) / 60;
3222 if (l1cinput->
verbose && gtime > gransize)
3224 cout <<
"WARNING: rounding errors --gtime = " << gtime <<
" is greater than granule size = " << gransize << endl; }
3225 if ((gtime % gransize) == 0)
3229 if(l1cinput->
verbose)cout <<
"gtime.." << gtime <<
"gfull.." << gfull << endl;
3233 ngridlines = gdindex[
gran][1] - gdindex[
gran][0] + 1;
3234 totlines += ngridlines;
3235 if(l1cinput->
verbose)cout <<
"ngridlines..." << ngridlines <<
"tot gridlines..." << totlines << endl;
3242 unix2ymdhms(time_zero, &y_zero, &mo_zero, &d_zero, &h_zero, &mi_zero, &sec_zero);
3251 daystr = std::to_string(d_zero);
3252 if(daystr.size() == 1)
3253 daystr =
"0" + daystr;
3254 monstr = std::to_string(mo_zero);
3255 if(monstr.size() == 1)
3256 monstr =
"0" + monstr;
3257 yearstr = std::to_string(y_zero);
3259 datezerotime=
"seconds since " + yearstr +
"-" + monstr +
"-" + daystr;
3264 if(l1cinput->
verbose)cout <<
"sun_earth_distance -- mid gridline" <<dist_es<<endl;
3271 yearstr=dateini.substr(0,4);
3272 monstr=dateini.substr(5,2);
3273 daystr=dateini.substr(8,2);
3274 hstr=dateini.substr(11,2);
3275 mistr=dateini.substr(14,2);
3276 secstr=dateini.substr(17,2);
3278 fdatetimestr1 = yearstr + monstr + daystr +
"T" + hstr + mistr + secstr;
3279 fname_out = pathstr +
"PACE." + fdatetimestr1 +
".L1C" + extstr;
3280 fname_out_nopath =
"PACE." + fdatetimestr1 +
".L1C" + extstr;
3282 if(l1cinput->
verbose)cout <<
"granule filename.." << fname_out << endl;
3284 outf << fname_out_nopath <<
"," << dateini.substr(0,19) <<
"," << datend.substr(0,19) <<
"," << gfull <<
"\n";
3287 l1cfile->
gridname = fname_out.c_str();
3288 filename_lt = fname_out.c_str();
3289 char* gridchar =
strdup(filename_lt);
3294 nc_output =
new NcFile(filename_lt, NcFile::replace);
3295 }
catch (NcException& e) {
3297 cerr <<
"l1cgen l1c_pflag= 5 : producing L1C grid: " +
l1c_str << endl;
3306 nc_output->putAtt(
"processing_version", l1cinput->
pversion);
3307 if(l1cinput->
doi[0]) {
3308 nc_output->putAtt(
"identifier_product_doi", l1cinput->
doi);
3309 nc_output->putAtt(
"identifier_product_doi_authority",
"http://dx.doi.org");
3311 nc_output->putAtt(
"history", l1cinput->
history);
3312 nc_output->putAtt(
"product_name", fname_out_nopath);
3313 nc_output->putAtt(
"time_coverage_start", dateini.substr(0,19) +
"Z");
3314 nc_output->putAtt(
"time_coverage_end", datend.substr(0,19) +
"Z");
3315 nc_output->putAtt(
"sun_earth_distance", ncFloat, dist_es);
3322 time_nad_out = (
double*)calloc(
NY,
sizeof(
double));
3324 int cc = 0,ep_shift;
3326 if(tmgv[NY1]<0) ep_shift = 3600*24;
3328 if(l1cinput->
verbose) cout<<
"twodays flag : ep_shift :"<<ep_shift<<endl;
3329 for (
int i = NY1;
i < NY2 + 1;
i++) {
3330 for (
int j = 0;
j <
NX;
j++) {
3331 lat_out[cc][
j] = lat_gd[
i][
j];
3332 lon_out[cc][
j] = lon_gd[
i][
j];
3333 alt_out[cc][
j] = alt_gd[
i][
j];
3334 time_nad_out[cc] = tmgv[
i]+ep_shift;
3338 if(lat_gd[NY1+1][nadir_bin_index]>lat_gd[NY1][nadir_bin_index]) {dirstr1=
"Ascending";l1cfile->
orb_dir=1;}
else {dirstr1=
"Descending";l1cfile->
orb_dir=0;}
3339 if(lat_gd[NY2][nadir_bin_index]>lat_gd[NY2-1][nadir_bin_index]) dirstr2=
"Ascending";
else dirstr2=
"Descending";
3340 nc_output->putAtt(
"startDirection", dirstr1);
3341 nc_output->putAtt(
"endDirection", dirstr2);
3344 NcGroup ba_grp = nc_output->getGroup(
"bin_attributes");
3345 NcVar v1 = ba_grp.getVar(
"nadir_view_time");
3346 v1.putVar(&time_nad_out[0]);
3347 v1.putAtt(
"units",datezerotime);
3348 NcGroup geo_grp = nc_output->getGroup(
"geolocation_data");
3349 v1 = geo_grp.getVar(
"latitude");
3350 v1.putVar(&lat_out[0][0]);
3351 v1 = geo_grp.getVar(
"longitude");
3352 v1.putVar(&lon_out[0][0]);
3353 v1 = geo_grp.getVar(
"height");
3354 v1.putVar(&alt_out[0][0]);
3362 float* latarr = (
float*)calloc(Ngring,
sizeof(
float));
3363 float* lonarr = (
float*)calloc(Ngring,
sizeof(
float));
3367 latarr[0] = lat_gd[NY2][l1cfile->
nbinx - 1];
3368 latarr[1] = lat_gd[NY2][0];
3369 latarr[2] = lat_gd[NY1][0];
3370 latarr[3] = lat_gd[NY1][l1cfile->
nbinx - 1];
3372 lonarr[0] = lon_gd[NY2][l1cfile->
nbinx - 1];
3373 lonarr[1] = lon_gd[NY2][0];
3374 lonarr[2] = lon_gd[NY1][0];
3375 lonarr[3] = lon_gd[NY1][l1cfile->
nbinx - 1];
3379 latarr[0] = lat_gd[NY2][l1cfile->
nbinx - 1];
3380 latarr[1] = lat_gd[NY2][0];
3381 latarr[2] = lat_gd[NY1][0];
3382 latarr[3] = lat_gd[NY1][l1cfile->
nbinx - 1];
3384 lonarr[0] = lon_gd[NY2][l1cfile->
nbinx - 1];
3385 lonarr[1] = lon_gd[NY2][0];
3386 lonarr[2] = lon_gd[NY1][0];
3387 lonarr[3] = lon_gd[NY1][l1cfile->
nbinx - 1];
3391 string onelat,onelon,onecoor,firstcoor;
3393 string gring_polygon,gring_crs,gring_latmin,gring_latmax,gring_lonmin,gring_lonmax;
3396 for (
int s = 0;
s <
dp;
s++) {
3397 onelat=to_string(latarr[
s]);
3398 onelon=to_string(lonarr[
s]);
3401 onecoor=
"POLYGON(("+onelat+
" "+onelon+
",";
3402 firstcoor=onelat+
" "+onelon;
3404 else onecoor=onelat+
" "+onelon+
",";
3406 gring_polygon+=onecoor;
3411 gring_polygon+=firstcoor+
"))";
3413 float latpmin=999,latpmax=-999,lonpmin=999,lonpmax=-999;
3414 for(
int row=NY1;row<NY2+1;row++)
3416 for(
int col=0;col<nbinx;col++)
3419 if(lat_gd[row][col]<latpmin && lat_gd[row][col]!=
BAD_FLT) latpmin=lat_gd[row][col];
3420 if(lat_gd[row][col]>latpmax && lat_gd[row][col]!=
BAD_FLT) latpmax=lat_gd[row][col];
3421 if(lon_gd[row][col]<lonpmin && lon_gd[row][col]!=
BAD_FLT) lonpmin=lon_gd[row][col];
3422 if(lon_gd[row][col]>lonpmax && lon_gd[row][col]!=
BAD_FLT) lonpmax=lon_gd[row][col];
3425 gring_crs=
"EPSG:4326";
3426 nc_output->putAtt(
"geospatial_bounds", gring_polygon);
3427 nc_output->putAtt(
"geospatial_bounds_crs", gring_crs);
3430 nc_output->putAtt(
"geospatial_lat_min", ncFloat, latpmin);
3431 nc_output->putAtt(
"geospatial_lat_max", ncFloat, latpmax);
3432 nc_output->putAtt(
"geospatial_lon_min", ncFloat, lonpmin);
3433 nc_output->putAtt(
"geospatial_lon_max", ncFloat, lonpmax);
3438 cout <<
"ERROR EXTRACTING GRING coordinates!!-----" << endl;
3444 if (lat_out !=
nullptr)
3446 if (lon_out !=
nullptr)
3448 if (alt_out !=
nullptr)
3450 if (time_nad_out !=
nullptr)
3451 free (time_nad_out);
3457 if (gdtime !=
nullptr)
3461 if (gdindex !=
nullptr)
3465 if (granid !=
nullptr)
3482 nfiles = l1cinput->
files.size();
3484 for (
int j = 0;
j < nfiles;
j++) {
3492 for (
int j = 0;
j < 10;
j++) {
3513 cout <<
"ok transfering filehandle to l1c_filehandle info.." << endl;