17 #include <gsl/gsl_matrix_float.h>
18 #include <gsl/gsl_blas.h>
21 const double PI = 3.14159265358979323846;
25 using namespace netCDF;
26 using namespace netCDF::exceptions;
38 int accum( uint32_t totlines, uint32_t npixels,
39 uint32_t nalong, uint32_t nacross,
40 short *brow,
short *bcol,
41 float **cldprod, int8_t **cld_phase,
42 float **binval_ic,
short **nobs_ic,
43 float **binval_wc,
short **nobs_wc) {
46 for (
size_t i=0;
i<nalong;
i++) {
47 for (
size_t j=0;
j<nacross;
j++) {
48 binval_ic[
i][
j] = 0.0;
49 binval_wc[
i][
j] = 0.0;
58 for (
size_t i=0;
i<totlines;
i++) {
59 for (
size_t j=0;
j<npixels;
j++) {
62 if (cldprod[
i][
j] == -32767) {
68 if (cld_phase[
i][
j] == 1) {
69 binval_ic[*brptr][*bcptr] += cldprod[
i][
j];
70 nobs_ic[*brptr][*bcptr]++;
72 binval_wc[*brptr][*bcptr] += cldprod[
i][
j];
73 nobs_wc[*brptr][*bcptr]++;
86 uint32_t nalong, uint32_t nacross,
87 short *brow,
short *bcol,
88 float **cldprod, int8_t **cld_phase,
89 float **binval_ic,
short **nobs_ic,
90 float **binval_wc,
short **nobs_wc) {
93 for (
size_t i=0;
i<nalong;
i++) {
94 for (
size_t j=0;
j<nacross;
j++) {
95 binval_ic[
i][
j] = 0.0;
96 binval_wc[
i][
j] = 0.0;
105 for (
size_t i=0;
i<totlines;
i++) {
106 for (
size_t j=0;
j<npixels;
j++) {
109 if(cldprod[
i][
j] != -32767) {
111 nobs_ic[*brptr][*bcptr]++;
112 nobs_wc[*brptr][*bcptr]++;
114 if (cldprod[
i][
j] == 1) {
115 if (cld_phase[
i][
j] == 1) {
116 binval_ic[*brptr][*bcptr]++;
118 binval_wc[*brptr][*bcptr]++;
133 int accum_wm( uint32_t nwm,
short *brow,
short *bcol,
float *wlval,
134 float **binval,
short **
nobs) {
139 for (
size_t i=0;
i<nwm;
i++) {
142 if (wlval[
i] == -32767) {
148 binval[*brptr][*bcptr] += wlval[
i];
149 nobs[*brptr][*bcptr]++;
159 int lonlat2rowcol( uint32_t nalong, uint32_t nacross, uint32_t ncm,
160 float gridres,
float *lonL1C,
float *latL1C,
161 float *lonCM,
float *latCM,
short *brow,
short *bcol);
163 int copyVarAtts( NcVar *varin, NcVar *varout,
string override[],
164 string overridetype[]);
169 int readCLD( NcGroup ncGrp[],
const char *fldname, T *array,
170 uint32_t npixels, uint32_t nlines[]) {
175 uint32_t nlines0 = 0;
178 if ( !ncGrp[0].isNull()) {
179 if(nlines[0] < 250) {
186 start.push_back(nlines[0]-nlines0);
190 count.push_back(nlines0);
191 count.push_back(npixels);
193 var = ncGrp[0].getVar( fldname);
198 var = ncGrp[1].getVar( fldname);
199 var.getVar( &array[nlines0*npixels]);
202 if ( !ncGrp[2].isNull()) {
209 count.push_back(nlines[2]);
211 count.push_back(250);
212 count.push_back(npixels);
214 var = ncGrp[2].getVar( fldname);
215 var.getVar(
start,
count, &array[(nlines0+nlines[1])*npixels]);
223 if ( (*sValue).find_first_of(
"$" ) == std::string::npos)
return 0;
224 std::string::size_type posEndIdx = (*sValue).find_first_of(
"/" );
225 if ( posEndIdx == std::string::npos)
return 0;
226 const std::string envVar = sValue->substr (1, posEndIdx - 1);
227 char *envVar_str = getenv(envVar.c_str());
228 if (envVar_str == 0x0) {
229 printf(
"Environment variable: %s not defined.\n", sValue->c_str());
232 *sValue = envVar_str + (*sValue).substr( posEndIdx);
240 NcVar var, varin, varout;
246 char targetfilename[FILENAME_MAX];
247 char chlfilename[FILENAME_MAX];
248 char profilename[FILENAME_MAX];
249 char metfilename[FILENAME_MAX];
250 char aerfilename[FILENAME_MAX];
251 char geoscffilename[FILENAME_MAX];
252 char cldmask1[FILENAME_MAX];
253 char cldmask2[FILENAME_MAX];
254 char cldmask3[FILENAME_MAX];
255 char cldprod1[FILENAME_MAX];
256 char cldprod2[FILENAME_MAX];
257 char cldprod3[FILENAME_MAX];
258 char albedofilename[FILENAME_MAX];
259 char camsch4filename[FILENAME_MAX];
260 char camsco2filename[FILENAME_MAX];
261 char camsn2ofilename[FILENAME_MAX];
262 char gebcofilename[FILENAME_MAX];
263 char ancoutfilename[FILENAME_MAX];
268 "Input target file");
270 "Output ancillary file");
272 "Input MERRA2 profile ancillary file");
274 "Input MERRA2 MET ancillary file");
276 "Input MERRA2 AER ancillary file (optional)");
278 "Input GEOS CF ancillary file");
281 "Input trailing cloud mask L2 file");
283 "Input current cloud mask L2 file");
285 "Input following cloud mask L2 file");
288 "Input trailing cloud product L2 file");
290 "Input current cloud product L2 file");
292 "Input following cloud product L2 file");
296 "Input albedo ancillary file");
298 "Input chlor_a L3 map file (optional)");
300 "Input CAMS CH4 ancillary file");
302 "Input CAMS CO2 ancillary file");
304 "Input CAMS N2O ancillary file");
307 "Input GEBCO landmask file");
319 strcpy(targetfilename, strVal);
322 strcpy(ancoutfilename, strVal);
325 strcpy(profilename, strVal);
328 strcpy(metfilename, strVal);
331 strcpy(geoscffilename, strVal);
340 strcpy(albedofilename, strVal);
343 strcpy(camsch4filename, strVal);
346 strcpy(camsco2filename, strVal);
349 strcpy(camsn2ofilename, strVal);
351 int numOptions, optionId;
354 for (optionId = 0; optionId < numOptions; optionId++) {
359 if (strcmp(keyword,
"chlfile") == 0) {
365 }
else if (strcmp(keyword,
"merraaerfile") == 0) {
371 }
else if (strcmp(keyword,
"cldmask1") == 0) {
377 }
else if (strcmp(keyword,
"cldmask2") == 0) {
383 }
else if (strcmp(keyword,
"cldmask3") == 0) {
389 }
else if (strcmp(keyword,
"cldprod1") == 0) {
395 }
else if (strcmp(keyword,
"cldprod2") == 0) {
401 }
else if (strcmp(keyword,
"cldprod3") == 0) {
406 }
else if (strcmp(keyword,
"gebcofile") == 0) {
410 strcpy(gebcofilename,
"$OCDATAROOT/common/gebco_ocssw_v2020.nc");
420 cout << endl <<
"Opening L1C file" << endl;
421 NcFile *L1Cfile =
new NcFile( targetfilename, NcFile::read);
423 NcGroupAtt
att = L1Cfile->getAtt(
"time_coverage_start");
425 cout <<
"Error - Could not find time_coverage_start global attribute.\n";
428 string time_coverage_start;
429 att.getValues(time_coverage_start);
432 att = L1Cfile->getAtt(
"time_coverage_end");
434 cout <<
"Error - Could not find time_coverage_end global attribute.\n";
437 string time_coverage_end;
438 att.getValues(time_coverage_end);
441 att = L1Cfile->getAtt(
"instrument");
443 cout <<
"Error - Could not find instrument global attribute.\n";
449 NcDim across_dim = L1Cfile->getDim(
"bins_across_track");
450 uint32_t nacross = across_dim.getSize();
451 NcDim along_dim = L1Cfile->getDim(
"bins_along_track");
452 uint32_t nalong = along_dim.getSize();
459 int bins_along_track = nalong;
460 int bins_across_track = nacross;
462 size_t nl1c = bins_along_track * bins_across_track;
473 cout <<
"Creating ancillary file" << endl;
475 nc_output =
new NcFile( ancoutfilename, NcFile::replace);
481 nc_output->putAtt(
"date_created", date_created);
482 nc_output->putAtt(
"time_coverage_start", time_coverage_start);
483 nc_output->putAtt(
"time_coverage_end", time_coverage_end);
484 nc_output->putAtt(
"title",
instrument +
" L1C ancillary file");
485 nc_output->putAtt(
"product_name",
basename(ancoutfilename));
486 nc_output->putAtt(
"creator_name",
"NASA/GSFC/OBPG");
487 nc_output->putAtt(
"creator_url",
"http://oceandata.sci.gsfc.nasa.gov");
488 nc_output->putAtt(
"creator_email",
"data@oceancolor.gsfc.nasa.gov");
489 nc_output->putAtt(
"project",
490 "Ocean Biology Processing Group (NASA/GSFC/OBPG)");
491 nc_output->putAtt(
"publisher_name",
"NASA/GSFC/OBPG");
492 nc_output->putAtt(
"publisher_url",
"http://oceandata.sci.gsfc.nasa.gov");
493 nc_output->putAtt(
"publisher_email",
"data@oceancolor.gsfc.nasa.gov");
497 NcDim rows = nc_output->addDim(
"bins_along_track", bins_along_track);
498 NcDim cols = nc_output->addDim(
"bins_across_track", bins_across_track);
501 dims.push_back(rows);
502 dims.push_back(cols);
505 NcGroup gidGEO = L1Cfile->getGroup(
"geolocation_data");
509 var = gidGEO.getVar(
"latitude");
510 var.getVar( &latL1C[0][0]);
511 varout = nc_output->addVar(
"latitude", ncFloat, dims);
513 string override_ll[] = {
"-32767",
"=",
"=",
"=",
"="};
514 string overridetype_ll[] = {
"F",
"=",
"=",
"=",
"="};
515 copyVarAtts( &var, &varout, override_ll, overridetype_ll);
518 fptr = &latL1C[0][0];
519 for (
size_t i=0;
i<nl1c;
i++) {
520 if (*fptr < -900) *fptr = -32767;
523 varout.putVar( &latL1C[0][0]);
525 var = gidGEO.getVar(
"longitude");
526 var.getVar( &lonL1C[0][0]);
527 varout = nc_output->addVar(
"longitude", ncFloat, dims);
529 copyVarAtts( &var, &varout, override_ll, overridetype_ll);
532 fptr = &lonL1C[0][0];
533 for (
size_t i=0;
i<nl1c;
i++) {
534 if (*fptr < -900) *fptr = -32767;
537 varout.putVar( &lonL1C[0][0]);
541 float lonmax=-180, lonmin=+180;
542 fptr = &lonL1C[0][0];
543 for (
size_t i=0;
i< (size_t) nl1c;
i++) {
544 if (*fptr < lonmin) lonmin = *fptr;
545 if (*fptr > lonmax) lonmax = *fptr;
549 float latmax=-90, latmin=+90;
550 fptr = &latL1C[0][0];
551 for (
size_t i=0;
i< (size_t) nl1c;
i++) {
552 if (*fptr < latmin) latmin = *fptr;
553 if (*fptr > latmax) latmax = *fptr;
558 vector<ptrdiff_t> stride;
563 size_t albedo_npix = 43200;
564 size_t albedo_nlines = 21600;
565 size_t albedo_nfields = 5;
566 float albedo_pixel_size = 0.00833333;
568 cout << endl <<
"Opening ALBEDO file" << endl;
569 NcFile *albedofile =
new NcFile( albedofilename, NcFile::read);
571 uint8_t **albedorow =
new uint8_t*[albedo_nlines];
573 std::vector<string> ALBEDOfields
574 = {
"Albedo_Map_0.659",
"Albedo_Map_0.858",
575 "Albedo_Map_1.24",
"Albedo_Map_1.64",
582 int32_t period_8day =
sday / 8;
584 start.push_back(period_8day);
591 count.push_back(albedo_npix);
594 for (
size_t k=0;
k<albedo_nfields;
k++) {
595 var = albedofile->getVar( ALBEDOfields[
k].c_str());
597 for (
size_t i=0;
i<albedo_nlines;
i++)
601 for (
size_t i=0;
i<nalong;
i++) {
602 for (
size_t j=0;
j<nacross;
j++) {
604 int latrow = (latL1C[
i][
j] + 90) / albedo_pixel_size;
606 if (albedorow[latrow] ==
NULL) {
609 size_t cache_boundary = ((size_t)(latrow /
NCACHE)) *
NCACHE;
610 if (first == -1) first = cache_boundary;
611 albedorow[cache_boundary] =
new uint8_t[albedo_npix*
NCACHE];
613 albedorow[cache_boundary+
k]
614 = albedorow[cache_boundary] +
k*albedo_npix;
616 start[1] = cache_boundary;
619 var.getVar(
start,
count, albedorow[cache_boundary]);
621 int loncol = (lonL1C[
i][
j] + 180) / albedo_pixel_size;
623 uint8_t albedo = albedorow[latrow][loncol];
625 out_l1c_2d[
i][
j] = -32767;
627 out_l1c_2d[
i][
j] = albedo * 0.004;
631 cout <<
"Writing " << ALBEDOfields[
k].c_str() << endl;
632 varout = nc_output->addVar(ALBEDOfields[
k].c_str(), ncFloat, dims);
634 string override[] = {
"-32767",
"",
"=",
"-32767",
"",
"=",
"="};
635 string overridetype[] = {
"F",
"",
"=",
"F",
"",
"=",
"="};
636 copyVarAtts( &var, &varout,
override, overridetype);
638 varout.putVar(&out_l1c_2d[0][0]);
640 for (
size_t i=first;
i<albedo_nlines;
i+=
NCACHE)
641 if (albedorow[
i] !=
NULL)
delete [] albedorow[
i];
652 bool datelinecross=
false;
653 if (lonmax - lonmin > 180) {
654 cout << endl <<
"Correcting longitude for dataline crossing" << endl;
655 datelinecross =
true;
656 lonmax=0; lonmin=360;
657 fptr = &lonL1C[0][0];
658 for (
size_t i=0;
i< (size_t) nl1c;
i++) {
659 if (*fptr < 0) *fptr += 360;
660 if (*fptr < lonmin) lonmin = *fptr;
661 if (*fptr > lonmax) lonmax = *fptr;
675 cout << endl <<
"Opening MERRA2 file" << endl;
676 NcFile *MERRAfile =
new NcFile( profilename, NcFile::read);
682 for (
size_t i=0;
i<361;
i++) {
683 for (
size_t j=0;
j<576;
j++) {
684 lat_merra[
i][
j] =
i*0.50 - 90;
685 lon_merra[
i][
j] =
j*0.625 - 180;
687 if (datelinecross && lon_merra[
i][
j] < 0) lon_merra[
i][
j] += 360;
690 int nmerra = nlon*nlat;
696 fptr = &latL1C[0][0];
697 short *slatptr = &latbinL1C[0][0];
698 for (
size_t i=0;
i< (size_t) nl1c;
i++) {
699 *slatptr = (short) ((*fptr + 90) / 0.50);
704 fptr = &lonL1C[0][0];
705 short *slonptr = &lonbinL1C[0][0];
706 for (
size_t i=0;
i< (size_t) nl1c;
i++) {
707 *slonptr = (short) ((*fptr + 180) / 0.625);
712 cout <<
"Computing MERRA to L1C interpolation mapping" << endl;
713 int nnc_tag_merra =
cgal_nnc( nmerra, &lat_merra[0][0], &lon_merra[0][0],
714 nl1c, &latL1C[0][0], &lonL1C[0][0]);
718 NcDim levs = nc_output->addDim(
"levels", nlev);
721 dims.push_back(levs);
722 dims.push_back(rows);
723 dims.push_back(cols);
734 string MERRAfields[5]={
"H",
"T",
"RH",
"QV",
"O3"};
737 for (
size_t k=0;
k<5;
k++) {
739 varin = MERRAfile->getVar( MERRAfields[
k].c_str());
740 varin.getVar(&merra_data[0][0][0]);
743 float *fptr = &merra_data[0][0][0];
744 for (
size_t i=0;
i<42*361*576;
i++) {
745 if (*fptr > 1e14) *fptr = -1e14;
750 for (
size_t i=0;
i<nlev;
i++) {
752 &lat_merra[0][0], &lon_merra[0][0], &merra_data[
i][0][0],
753 nl1c, &out_l1c_3d[
i][0][0], nnc_tag_merra);
756 fptr = &out_l1c_3d[0][0][0];
757 for (
size_t i=0;
i<nlev*nalong*nacross;
i++) {
758 if (*fptr < 0) *fptr = -32767;
763 fptr = &out_l1c_3d[
i][0][0];
764 slatptr = &latbinL1C[0][0];
765 slonptr = &lonbinL1C[0][0];
767 for (
size_t j=0;
j< (size_t) nl1c;
j++) {
769 *fptr = merra_data[
i][*slatptr][*slonptr];
777 cout <<
"Writing " << MERRAfields[
k] << endl;
779 varout = nc_output->addVar(MERRAfields[
k].c_str(), ncFloat, dims);
781 string override[] = {
"-32767",
"=",
"-32767",
"=",
"="};
782 string overridetype[] = {
"F",
"=",
"F",
"=",
"="};
783 copyVarAtts( &varin, &varout,
override, overridetype);
785 varout.putVar(&out_l1c_3d[0][0][0]);
796 cout << endl <<
"Opening MERRA2 MET file" << endl;
797 MERRAfile =
new NcFile( metfilename, NcFile::read);
801 dims.push_back(rows);
802 dims.push_back(cols);
804 string MERRA_MET_fields[10]={
"PS",
"QV10M",
"SLP",
"T10M",
"TO3",
805 "TQV",
"U10M",
"V10M",
"FRSNO",
"FRSEAICE"};
807 for (
size_t k=0;
k<10;
k++) {
809 varin = MERRAfile->getVar( MERRA_MET_fields[
k].c_str());
810 varin.getVar(&merra_data[0][0][0]);
813 float *fptr = &merra_data[0][0][0];
814 for (
size_t i=0;
i<361*576;
i++) {
815 if (*fptr > 1e14) *fptr = -1e14;
820 &lat_merra[0][0], &lon_merra[0][0], &merra_data[0][0][0],
821 nl1c, &out_l1c_3d[0][0][0], nnc_tag_merra);
824 fptr = &out_l1c_3d[0][0][0];
825 for (
size_t i=0;
i<nalong*nacross;
i++) {
826 if (*fptr < 0) *fptr = -32767;
832 fptr = &out_l1c_3d[0][0][0];
833 slatptr = &latbinL1C[0][0];
834 slonptr = &lonbinL1C[0][0];
836 for (
size_t j=0;
j< (size_t) nl1c;
j++) {
838 *fptr = merra_data[0][*slatptr][*slonptr];
845 cout <<
"Writing " << MERRA_MET_fields[
k] << endl;
847 varout = nc_output->addVar(MERRA_MET_fields[
k].c_str(), ncFloat, dims);
849 string override[] = {
"-32767",
"=",
"-32767",
"=",
"="};
850 string overridetype[] = {
"F",
"=",
"F",
"=",
"="};
851 copyVarAtts( &varin, &varout,
override, overridetype);
852 varout.putVar(&out_l1c_3d[0][0][0]);
861 if (strcmp(aerfilename,
"") != 0) {
862 cout << endl <<
"Opening MERRA2 AER_file" << endl;
863 MERRAfile =
new NcFile( aerfilename, NcFile::read);
867 dims.push_back(rows);
868 dims.push_back(cols);
870 string MERRA_AER_fields[13]={
"BCEXTTAU",
"BCSCATAU",
"DUEXTTAU",
871 "DUSCATAU",
"SSEXTTAU",
"SSSCATAU",
872 "SUEXTTAU",
"SUSCATAU",
"OCEXTTAU",
873 "OCSCATAU",
"TOTEXTTAU",
"TOTSCATAU",
876 for (
size_t k=0;
k<13;
k++) {
878 varin = MERRAfile->getVar( MERRA_AER_fields[
k].c_str());
879 varin.getVar(&merra_data[0][0][0]);
882 float *fptr = &merra_data[0][0][0];
883 for (
size_t i=0;
i<361*576;
i++) {
884 if (*fptr > 1e14) *fptr = -1e14;
889 &lat_merra[0][0], &lon_merra[0][0], &merra_data[0][0][0],
890 nl1c, &out_l1c_3d[0][0][0], nnc_tag_merra);
893 fptr = &out_l1c_3d[0][0][0];
894 for (
size_t i=0;
i<nalong*nacross;
i++) {
895 if (*fptr < 0) *fptr = -32767;
901 fptr = &out_l1c_3d[0][0][0];
902 slatptr = &latbinL1C[0][0];
903 slonptr = &lonbinL1C[0][0];
905 for (
size_t j=0;
j< (size_t) nl1c;
j++) {
907 *fptr = merra_data[0][*slatptr][*slonptr];
914 cout <<
"Writing " << MERRA_AER_fields[
k] << endl;
916 varout = nc_output->addVar(MERRA_AER_fields[
k].c_str(), ncFloat, dims);
918 string override[] = {
"-32767",
"=",
"-32767",
"=",
"="};
919 string overridetype[] = {
"F",
"=",
"F",
"=",
"="};
920 copyVarAtts( &varin, &varout,
override, overridetype);
921 varout.putVar(&out_l1c_3d[0][0][0]);
938 NcFile *CAMSfile =
new NcFile( camsch4filename, NcFile::read);
940 NcDim camslat_dim = CAMSfile->getDim(
"latitude_bins");
941 uint32_t camslat = camslat_dim.getSize();
943 NcDim camslon_dim = CAMSfile->getDim(
"longitude_bins");
944 uint32_t camslon = camslon_dim.getSize();
949 for (
size_t i=0;
i<camslat;
i++) {
950 for (
size_t j=0;
j<camslon;
j++) {
951 lat_cams[
i][
j] =
i*2 - 89.0;
952 lon_cams[
i][
j] =
j*3 - 178.5;
954 if (datelinecross && lon_cams[
i][
j] < 0) lon_cams[
i][
j] += 360;
957 int ncams = camslon*camslat;
959 cout << endl <<
"Computing CAMS SATELLITE to L1C interpolation mapping"
961 int nnc_tag_cams =
cgal_nnc( ncams, &lat_cams[0][0], &lon_cams[0][0],
962 nl1c, &latL1C[0][0], &lonL1C[0][0]);
965 dims.push_back(levs);
966 dims.push_back(rows);
967 dims.push_back(cols);
971 int month = atoi(time_coverage_start.substr(5,2).c_str());
973 string s = to_string(month);
974 unsigned int number_of_zeros = 2 -
s.length();
975 s.insert(0, number_of_zeros,
'0');
978 varin = CAMSfile->getVar(
s.c_str());
979 varin.getVar(&cams_data[0][0][0]);
982 fptr = &cams_data[0][0][0];
983 for (
size_t i=0;
i<nlev*camslat*camslon;
i++) {
984 if (*fptr == -999) *fptr = -32767;
988 for (
size_t l=0; l<42; l++) {
990 &lat_cams[0][0], &lon_cams[0][0], &cams_data[l][0][0],
991 nl1c, &out_l1c_3d[l][0][0], nnc_tag_cams);
995 fptr = &out_l1c_3d[0][0][0];
996 for (
size_t i=0;
i<nlev*nalong*nacross;
i++) {
997 if (*fptr < 0) *fptr = -32767;
1002 cout <<
"Writing " <<
s << endl;
1004 varout = nc_output->addVar(
s.c_str(), ncFloat, dims);
1006 string override[] = {
"-32767",
"=",
"=",
"=",
"=",
"=",
"=",
"="};
1007 string overridetype[] = {
"F",
"=",
"=",
"=",
"=",
"=",
"=",
"="};
1008 copyVarAtts( &varin, &varout,
override, overridetype);
1010 varout.putVar(&out_l1c_3d[0][0][0]);
1025 CAMSfile =
new NcFile( camsco2filename, NcFile::read);
1027 camslat_dim = CAMSfile->getDim(
"latitude_bins");
1028 camslat = camslat_dim.getSize();
1030 camslon_dim = CAMSfile->getDim(
"longitude_bins");
1031 camslon = camslon_dim.getSize();
1036 for (
size_t i=0;
i<camslat;
i++) {
1037 for (
size_t j=0;
j<camslon;
j++) {
1038 lat_cams[
i][
j] =
i*1.8947368421 - 90.0;
1039 lon_cams[
i][
j] =
j*3.75 - 180.0;
1041 if (datelinecross && lon_cams[
i][
j] < 0) lon_cams[
i][
j] += 360;
1044 ncams = camslon*camslat;
1046 cout << endl <<
"Computing CAMS INST to L1C interpolation mapping"
1048 nnc_tag_cams =
cgal_nnc( ncams, &lat_cams[0][0], &lon_cams[0][0],
1049 nl1c, &latL1C[0][0], &lonL1C[0][0]);
1053 s = to_string(month);
1054 number_of_zeros = 2 -
s.length();
1055 s.insert(0, number_of_zeros,
'0');
1056 s.insert(0,
"CO2_");
1058 varin = CAMSfile->getVar(
s.c_str());
1059 varin.getVar(&cams_data[0][0][0]);
1062 fptr = &cams_data[0][0][0];
1063 for (
size_t i=0;
i<nlev*camslat*camslon;
i++) {
1064 if (*fptr == -999) *fptr = -32767;
1068 for (
size_t l=0; l<42; l++) {
1070 &lat_cams[0][0], &lon_cams[0][0], &cams_data[l][0][0],
1071 nl1c, &out_l1c_3d[l][0][0], nnc_tag_cams);
1075 fptr = &out_l1c_3d[0][0][0];
1076 for (
size_t i=0;
i<nlev*nalong*nacross;
i++) {
1077 if (*fptr < 0) *fptr = -32767;
1082 cout <<
"Writing " <<
s << endl;
1084 varout = nc_output->addVar(
s.c_str(), ncFloat, dims);
1085 copyVarAtts( &varin, &varout,
override, overridetype);
1087 varout.putVar(&out_l1c_3d[0][0][0]);
1091 CAMSfile =
new NcFile( camsn2ofilename, NcFile::read);
1093 s = to_string(month);
1094 number_of_zeros = 2 -
s.length();
1095 s.insert(0, number_of_zeros,
'0');
1096 s.insert(0,
"N2O_");
1098 varin = CAMSfile->getVar(
s.c_str());
1099 varin.getVar(&cams_data[0][0][0]);
1102 fptr = &cams_data[0][0][0];
1103 for (
size_t i=0;
i<nlev*camslat*camslon;
i++) {
1104 if (*fptr == -999) *fptr = -32767;
1108 for (
size_t l=0; l<42; l++) {
1110 &lat_cams[0][0], &lon_cams[0][0], &cams_data[l][0][0],
1111 nl1c, &out_l1c_3d[l][0][0], nnc_tag_cams);
1115 fptr = &out_l1c_3d[0][0][0];
1116 for (
size_t i=0;
i<nlev*nalong*nacross;
i++) {
1117 if (*fptr < 0) *fptr = -32767;
1122 cout <<
"Writing " <<
s << endl;
1124 varout = nc_output->addVar(
s.c_str(), ncFloat, dims);
1125 copyVarAtts( &varin, &varout,
override, overridetype);
1127 varout.putVar(&out_l1c_3d[0][0][0]);
1144 cout << endl <<
"Opening GEOS-CF file" << endl;
1145 NcFile *GEOSfile =
new NcFile( geoscffilename, NcFile::read);
1150 int ngeos = nlon*nlat;
1156 for (
size_t i=0;
i<721;
i++) {
1157 for (
size_t j=0;
j<1440;
j++) {
1158 lat_geos[
i][
j] =
i*0.25 - 90;
1159 lon_geos[
i][
j] =
j*0.25 - 180;
1161 if (datelinecross && lon_geos[
i][
j] < 0) lon_geos[
i][
j] += 360;
1167 dims.push_back(levs);
1168 varout = nc_output->addVar(
"levels", ncFloat, dims);
1171 varin = GEOSfile->getVar(
"lev");
1178 cout <<
"Computing GEOS to L1C interpolation mapping" << endl;
1179 int nnc_tag_geos =
cgal_nnc( ngeos, &lat_geos[0][0], &lon_geos[0][0],
1180 nl1c, &latL1C[0][0], &lonL1C[0][0]);
1182 string GEOSfields[5]={
"NO2",
"SO2",
1183 "TOTCOL_NO2",
"STRATCOL_NO2",
"TROPCOL_NO2"};
1185 for (
size_t k=0;
k<5;
k++) {
1187 varin = GEOSfile->getVar( GEOSfields[
k].c_str());
1188 varin.getVar(&geos_data[0][0][0]);
1190 if (GEOSfields[
k].compare(
"NO2") == 0 ||
1191 GEOSfields[
k].compare(
"SO2") == 0)
1192 nlev = 42;
else nlev = 1;
1195 float *fptr = &geos_data[0][0][0];
1196 for (
size_t i=0;
i<nlev*721*1440;
i++) {
1197 if (*fptr > 1e14) *fptr = -1e14;
1201 for (
size_t i=0;
i<nlev;
i++) {
1203 &lat_geos[0][0], &lon_geos[0][0], &geos_data[
i][0][0],
1204 nl1c, &out_l1c_3d[
i][0][0], nnc_tag_geos);
1208 fptr = &out_l1c_3d[0][0][0];
1209 for (
size_t i=0;
i<nlev*nalong*nacross;
i++) {
1210 if (*fptr < 0) *fptr = -32767;
1215 if (GEOSfields[
k].compare(
"NO2") == 0 ||
1216 GEOSfields[
k].compare(
"SO2") == 0) {
1217 dims.push_back(levs);
1218 dims.push_back(rows);
1219 dims.push_back(cols);
1221 dims.push_back(rows);
1222 dims.push_back(cols);
1225 cout <<
"Writing " << GEOSfields[
k].c_str() << endl;
1227 varout = nc_output->addVar(GEOSfields[
k].c_str(), ncFloat, dims);
1229 string overrideGEOS[] = {
"-32767",
"=",
"-32767",
"=",
"="};
1230 string overridetypeGEOS[] = {
"F",
"=",
"F",
"=",
"="};
1231 copyVarAtts( &varin, &varout, overrideGEOS, overridetypeGEOS);
1233 varout.putVar(&out_l1c_3d[0][0][0]);
1247 if ( strcmp(cldmask2,
"") != 0 &&
1248 strcmp(cldprod2,
"") != 0) {
1250 cout << endl <<
"Opening CLDMSK files" << endl;
1254 uint32_t nlines[3]={0,0,0};
1259 uint32_t nlines0 = 0;
1262 if ( strcmp(cldmask1,
"") != 0) {
1263 CLDMSKfile[0] =
new NcFile( cldmask1, NcFile::read);
1264 lines_dim = CLDMSKfile[0]->getDim(
"number_of_lines");
1265 nlines[0] = lines_dim.getSize();
1268 if ( strcmp(cldmask3,
"") != 0) {
1269 CLDMSKfile[2] =
new NcFile( cldmask3, NcFile::read);
1270 lines_dim = CLDMSKfile[2]->getDim(
"number_of_lines");
1271 nlines[2] = lines_dim.getSize();
1275 CLDMSKfile[1] =
new NcFile( cldmask2, NcFile::read);
1276 lines_dim = CLDMSKfile[1]->getDim(
"number_of_lines");
1277 nlines[1] = lines_dim.getSize();
1279 pixel_dim = CLDMSKfile[1]->getDim(
"pixels_per_line");
1280 npixels = pixel_dim.getSize();
1283 uint32_t totlines = nlines[1];
1284 if (nlines[0] != 0) {
1285 if (nlines[0] < 250)
1286 totlines += nlines[0];
1291 if (nlines[2] != 0) {
1292 if (nlines[2] < 250)
1293 totlines += nlines[2];
1302 for (
size_t i=0;
i<totlines;
i++) {
1303 for (
size_t j=0;
j<npixels;
j++) {
1312 if ( CLDMSKfile[0] !=
NULL) {
1313 if(nlines[0] < 250) {
1314 nlines0 = nlines[0];
1318 start[0] = nlines[0] - 250;
1324 ncGroup = CLDMSKfile[0]->getGroup(
"navigation_data");
1325 if(ncGroup.isNull()) {
1326 var = CLDMSKfile[0]->getVar(
"latitude");
1329 var = CLDMSKfile[0]->getVar(
"longitude");
1332 var = CLDMSKfile[0]->getVar(
"ADJ_MASK");
1335 var = ncGroup.getVar(
"latitude");
1338 var = ncGroup.getVar(
"longitude");
1341 ncGroup = CLDMSKfile[0]->getGroup(
"geophysical_data");
1342 var = ncGroup.getVar(
"cloud_flag");
1347 ncGroup = CLDMSKfile[1]->getGroup(
"navigation_data");
1348 if(ncGroup.isNull()) {
1349 var = CLDMSKfile[1]->getVar(
"latitude");
1350 var.getVar( &latCM[nlines0][0]);
1352 var = CLDMSKfile[1]->getVar(
"longitude");
1353 var.getVar( &lonCM[nlines0][0]);
1355 var = CLDMSKfile[1]->getVar(
"ADJ_MASK");
1356 var.getVar( &adj_mask[nlines0][0]);
1358 var = ncGroup.getVar(
"latitude");
1359 var.getVar( &latCM[nlines0][0]);
1361 var = ncGroup.getVar(
"longitude");
1362 var.getVar( &lonCM[nlines0][0]);
1364 ncGroup = CLDMSKfile[1]->getGroup(
"geophysical_data");
1365 var = ncGroup.getVar(
"cloud_flag");
1366 var.getVar( &adj_mask[nlines0][0]);
1370 if ( CLDMSKfile[2] !=
NULL) {
1372 if(nlines[2] < 250) {
1373 count[0] = nlines[2];
1380 ncGroup = CLDMSKfile[2]->getGroup(
"navigation_data");
1381 if(ncGroup.isNull()) {
1382 var = CLDMSKfile[2]->getVar(
"latitude");
1383 var.getVar(
start,
count, &latCM[nlines0+nlines[1]][0]);
1385 var = CLDMSKfile[2]->getVar(
"longitude");
1386 var.getVar(
start,
count, &lonCM[nlines0+nlines[1]][0]);
1388 var = CLDMSKfile[2]->getVar(
"ADJ_MASK");
1389 var.getVar(
start,
count, &adj_mask[nlines0+nlines[1]][0]);
1391 var = ncGroup.getVar(
"latitude");
1392 var.getVar(
start,
count, &latCM[nlines0+nlines[1]][0]);
1394 var = ncGroup.getVar(
"longitude");
1395 var.getVar(
start,
count, &lonCM[nlines0+nlines[1]][0]);
1397 ncGroup = CLDMSKfile[2]->getGroup(
"geophysical_data");
1398 var = ncGroup.getVar(
"cloud_flag");
1399 var.getVar(
start,
count, &adj_mask[nlines0+nlines[1]][0]);
1403 uint32_t ncm = totlines*npixels;
1409 short *brow =
new short[ncm];
1410 short *bcol =
new short[ncm];
1411 lonlat2rowcol( nalong, nacross, ncm, gridres, &lonL1C[0][0], &latL1C[0][0],
1412 &lonCM[0][0], &latCM[0][0], brow, bcol);
1429 if ( strcmp(cldprod1,
"") != 0) {
1430 CLDfile[0] =
new NcFile( cldprod1, NcFile::read);
1431 ncGrp[0] = CLDfile[0]->getGroup(
"geophysical_data");
1434 if ( strcmp(cldprod3,
"") != 0) {
1435 CLDfile[2] =
new NcFile( cldprod3, NcFile::read);
1436 ncGrp[2] = CLDfile[2]->getGroup(
"geophysical_data");
1439 CLDfile[1] =
new NcFile( cldprod2, NcFile::read);
1440 ncGrp[1] = CLDfile[1]->getGroup(
"geophysical_data");
1445 readCLD<int8_t>( ncGrp,
"cld_phase_21", &cld_phase[0][0], npixels, nlines);
1448 for (
size_t i=0;
i<totlines;
i++)
1449 for (
size_t j=0;
j<npixels;
j++)
1450 if (cld_phase[
i][
j] == 3)
1451 cld_phase[
i][
j] = 1;
1453 cld_phase[
i][
j] = 0;
1466 for (
size_t i=0;
i<totlines;
i++)
1467 for (
size_t j=0;
j<npixels;
j++)
1468 if(adj_mask[
i][
j] == -128)
1469 cldprod[
i][
j] = -32767;
1479 accum_frac( totlines, npixels, nalong, nacross, brow, bcol, cldprod, cld_phase,
1480 binval_ic, nobs_ic, binval_wc, nobs_wc);
1483 for (
size_t i=0;
i<nalong;
i++) {
1484 for (
size_t j=0;
j<nacross;
j++) {
1485 if (nobs_ic[
i][
j] != 0)
1486 out_l1c_2d[
i][
j] = binval_ic[
i][
j] / nobs_ic[
i][
j];
1488 out_l1c_2d[
i][
j] = -32767;
1493 dims.push_back(rows);
1494 dims.push_back(cols);
1496 cout <<
"Writing ice cloud fraction" << endl;
1497 varout = nc_output->addVar(
"ice_cloud_fraction", ncFloat, dims);
1499 string override_icf[] =
1500 {
"-32767",
"",
"",
"",
"",
"Ice cloud fraction",
"",
"1.0",
"0.0"};
1501 string overridetype_icf[] = {
"F",
"",
"",
"",
"",
"=",
"",
"F",
"F"};
1502 copyVarAtts( &var, &varout, override_icf, overridetype_icf);
1504 varout.putVar(&out_l1c_2d[0][0]);
1507 for (
size_t i=0;
i<nalong;
i++) {
1508 for (
size_t j=0;
j<nacross;
j++) {
1509 if (nobs_wc[
i][
j] != 0)
1510 out_l1c_2d[
i][
j] = binval_wc[
i][
j] / nobs_wc[
i][
j];
1512 out_l1c_2d[
i][
j] = -32767;
1516 cout <<
"Writing water cloud fraction" << endl;
1517 varout = nc_output->addVar(
"water_cloud_fraction", ncFloat, dims);
1519 string override_wcf[] =
1520 {
"-32767",
"",
"",
"",
"",
"Water cloud fraction",
"",
"1.0",
"0.0"};
1521 string overridetype_wcf[] = {
"F",
"",
"",
"",
"",
"=",
"",
"F",
"F"};
1522 copyVarAtts( &var, &varout, override_wcf, overridetype_wcf);
1524 varout.putVar(&out_l1c_2d[0][0]);
1533 string CLDfields[5]={
"ctp",
"ctt",
"cth",
"cer_21",
"cot_21"};
1535 for (
size_t k=0;
k<5;
k++) {
1536 cout <<
"Writing " << CLDfields[
k].c_str() << endl;
1538 var = ncGrp[1].getVar( CLDfields[
k].c_str());
1540 for (
size_t i=0;
i<totlines;
i++)
1541 for (
size_t j=0;
j<npixels;
j++) cldprod[
i][
j] = 0.0;
1543 readCLD<float>( ncGrp, CLDfields[
k].c_str(), &cldprod[0][0],
1546 accum( totlines, npixels, nalong, nacross, brow, bcol, cldprod, cld_phase,
1547 binval_ic, nobs_ic, binval_wc, nobs_wc);
1550 for (
size_t i=0;
i<nalong;
i++) {
1551 for (
size_t j=0;
j<nacross;
j++) {
1552 if (nobs_ic[
i][
j] != 0)
1553 out_l1c_2d[
i][
j] = binval_ic[
i][
j] / nobs_ic[
i][
j];
1555 out_l1c_2d[
i][
j] = -32767;
1561 outname.assign(CLDfields[
k]);
1562 outname.append(
"_ice_cloud");
1564 varout = nc_output->addVar(outname.c_str(), ncFloat, dims);
1566 varout.putVar(&out_l1c_2d[0][0]);
1569 for (
size_t i=0;
i<nalong;
i++) {
1570 for (
size_t j=0;
j<nacross;
j++) {
1571 if (nobs_wc[
i][
j] != 0)
1572 out_l1c_2d[
i][
j] = binval_wc[
i][
j] / nobs_wc[
i][
j];
1574 out_l1c_2d[
i][
j] = -32767;
1578 outname.assign(CLDfields[
k]);
1579 outname.append(
"_water_cloud");
1581 varout = nc_output->addVar(outname.c_str(), ncFloat, dims);
1583 varout.putVar(&out_l1c_2d[0][0]);
1604 float wm_pixel_size = 360.0 / 86400;
1605 int wm_latrow = (latmin + 90) / wm_pixel_size;
1606 int wm_loncol = (lonmin + 180) / wm_pixel_size;
1612 start.push_back(wm_latrow);
1613 start.push_back(wm_loncol);
1615 size_t n_wm_latrow = ((latmax + 90) / wm_pixel_size - wm_latrow + 1)/4;
1616 size_t n_wm_loncol = ((lonmax + 180) / wm_pixel_size - wm_loncol + 1)/4;
1619 count.push_back(n_wm_latrow);
1620 count.push_back(n_wm_loncol);
1623 stride.push_back(4);
1624 stride.push_back(4);
1626 float *lon_wm =
new float[n_wm_latrow*n_wm_loncol];
1627 float *lat_wm =
new float[n_wm_latrow*n_wm_loncol];
1632 for (
size_t i=0;
i<(size_t) n_wm_latrow;
i++) {
1633 for (
size_t j=0;
j<(size_t) n_wm_loncol;
j++) {
1634 lat_wm[
k] = (4*
i+wm_latrow)*wm_pixel_size - 90;
1635 lon_wm[
k] = (4*
j+wm_loncol)*wm_pixel_size - 180;
1637 if (datelinecross && lon_wm[
k] < 0) lon_wm[
k] += 360;
1642 uint32_t nwm = n_wm_latrow * n_wm_loncol;
1645 string gebcofilestring = gebcofilename;
1648 NcFile *WMfile =
new NcFile( gebcofilestring.c_str(), NcFile::read);
1650 float *wm =
new float[n_wm_latrow*n_wm_loncol];
1651 uint8_t *wmbyte =
new uint8_t[n_wm_latrow*n_wm_loncol];
1652 var = WMfile->getVar(
"watermask");
1653 if (datelinecross) {
1654 uint8_t *wm0 =
new uint8_t[n_wm_latrow*n_wm_loncol];
1655 count[1] = (86400 - wm_loncol) / 4;
1657 for (
size_t i=0;
i<(size_t) n_wm_latrow;
i++)
1658 memcpy(&wmbyte[
i*n_wm_loncol], &wm0[
i*
count[1]],
1659 count[1]*
sizeof(uint8_t));
1665 for (
size_t i=0;
i<(size_t) n_wm_latrow;
i++)
1666 memcpy(&wmbyte[
i*n_wm_loncol+(86400-wm_loncol)/4],
1670 var.getVar(
start,
count, stride, &wmbyte[0]);
1675 for (
size_t i=0;
i<(size_t) n_wm_latrow;
i++) {
1676 for (
size_t j=0;
j<(size_t) n_wm_loncol;
j++) {
1685 short *brow =
new short[nwm];
1686 short *bcol =
new short[nwm];
1692 for (
size_t i=0;
i<nalong;
i++) {
1693 for (
size_t j=0;
j<nacross;
j++) {
1694 binval_wm[
i][
j] = 0.0;
1699 size_t N = 2147483648 / (n_wm_loncol*nalong);
1700 size_t M = n_wm_latrow/
N;
1701 if (n_wm_latrow %
N != 0)
M++;
1702 for (
size_t i=0;
i<
M;
i++) {
1705 if (n_wm_latrow -
i*
N <
N)
L = n_wm_latrow -
i*
N;
1708 &lonL1C[0][0], &latL1C[0][0],
1709 &lon_wm[
i*
N*n_wm_loncol], &lat_wm[
i*
N*n_wm_loncol],
1712 accum_wm(
L*n_wm_loncol, brow, bcol, &wm[
i*
N*n_wm_loncol],
1713 binval_wm, nobs_wm);
1716 for (
size_t i=0;
i<nalong;
i++) {
1717 for (
size_t j=0;
j<nacross;
j++) {
1719 if (nobs_wm[
i][
j] != 0)
1720 out_l1c_2d[
i][
j] = binval_wm[
i][
j] / nobs_wm[
i][
j];
1722 out_l1c_2d[
i][
j] = -32767;
1726 cout <<
"Writing waterfraction" << endl;
1727 varout = nc_output->addVar(
"waterfraction", ncFloat, dims);
1729 string override_wf[] =
1730 {
"-32767",
"=",
"Water fraction",
"waterfraction",
"1.0",
"0.0"};
1731 string overridetype_wf[] = {
"F",
"",
"",
"=",
"F",
"F"};
1732 copyVarAtts( &var, &varout, override_wf, overridetype_wf);
1733 varout.putVar(&out_l1c_2d[0][0]);
1752 if (strcmp(chlfilename,
"") != 0) {
1753 float chl_pixel_size = 360.0 / 8640;
1754 int chl_latrow = (90 - latmax) / chl_pixel_size;
1755 int chl_loncol = (lonmin + 180) / chl_pixel_size;
1757 cout << latmin <<
" " << latmax <<
" " << lonmin <<
" " << lonmax << endl;
1758 cout << chl_latrow <<
" " << chl_loncol << endl;
1761 start.push_back(chl_latrow);
1762 start.push_back(chl_loncol);
1764 int n_chl_latrow = (90 - latmin) / chl_pixel_size - chl_latrow + 1;
1765 int n_chl_loncol = (lonmax + 180) / chl_pixel_size - chl_loncol + 1;
1768 count.push_back(n_chl_latrow);
1769 count.push_back(n_chl_loncol);
1771 float *lon_chl =
new float[n_chl_latrow*n_chl_loncol];
1772 float *lat_chl =
new float[n_chl_latrow*n_chl_loncol];
1774 cout << n_chl_latrow <<
" " << n_chl_loncol << endl;
1777 for (
size_t i=0;
i<(size_t) n_chl_latrow;
i++) {
1778 for (
size_t j=0;
j<(size_t) n_chl_loncol;
j++) {
1779 lat_chl[
k] = 90 - (
i+chl_latrow)*chl_pixel_size;
1780 lon_chl[
k] = (
j+chl_loncol)*chl_pixel_size - 180;
1782 if (datelinecross && lon_chl[
k] < 0) lon_chl[
k] += 360;
1787 int nchl = n_chl_latrow * n_chl_loncol;
1789 cout <<
"Computing CHLOR_A map to L1C interpolation mapping" << endl;
1790 int nnc_tag_chl =
cgal_nnc( nchl, &lat_chl[0], &lon_chl[0],
1791 nl1c, &latL1C[0][0], &lonL1C[0][0]);
1794 NcFile *CHLfile =
new NcFile( chlfilename, NcFile::read);
1796 float *chl =
new float[n_chl_latrow*n_chl_loncol];
1797 var = CHLfile->getVar(
"chlor_a");
1799 if (datelinecross) {
1800 float *chl0 =
new float[n_chl_latrow*n_chl_loncol];
1801 count[1] = 8640 - chl_loncol;
1803 for (
size_t i=0;
i<(size_t) n_chl_latrow;
i++)
1804 memcpy(&chl[
i*n_chl_loncol], &chl0[
i*
count[1]],
count[1]*
sizeof(
float));
1807 count[1] = n_chl_loncol + chl_loncol - 8640;
1808 cout <<
count[1] << endl;
1810 for (
size_t i=0;
i<(size_t) n_chl_latrow;
i++)
1811 memcpy(&chl[
i*n_chl_loncol+(8640-chl_loncol)],
1819 nl1c, &out_l1c_2d[0][0], nnc_tag_chl);
1822 fptr = &out_l1c_2d[0][0];
1823 for (
size_t i=0;
i<nalong*nacross;
i++) {
1824 if (*fptr < 0) *fptr = -32767;
1828 cout <<
"Writing chlor_a" << endl;
1829 varout = nc_output->addVar(
"chlor_a", ncFloat, dims);
1831 varout.putVar(&out_l1c_2d[0][0]);
1847 float gridres,
float *lonL1C,
float *latL1C,
1848 float *lonCM,
float *latCM,
short *brow,
short *bcol) {
1855 float *fptrlon, *fptrlat;
1861 for (
size_t i=0;
i<nalong;
i++) {
1862 for (
size_t j=0;
j<nacross;
j++) {
1863 gvec[
i][
j][0] = cos(*fptrlon/
RADEG) * cos(*fptrlat/
RADEG);
1864 gvec[
i][
j][1] = sin(*fptrlon/
RADEG) * cos(*fptrlat/
RADEG);
1865 gvec[
i][
j][2] = sin(*fptrlat/
RADEG);
1876 for (
size_t i=0;
i<ncm;
i++) {
1877 bvec[
i][0] = cos(*fptrlon/
RADEG)*cos(*fptrlat/
RADEG);
1878 bvec[
i][1] = sin(*fptrlon/
RADEG)*cos(*fptrlat/
RADEG);
1879 bvec[
i][2] = sin(*fptrlat/
RADEG);
1893 float *gnvm =
new float[nalong];
1895 for (
size_t i=0;
i<nalong;
i++) {
1897 gvec[
i][nacross-1][1]*gvec[
i][0][2] -
1898 gvec[
i][nacross-1][2]*gvec[
i][0][1];
1901 gvec[
i][nacross-1][2]*gvec[
i][0][0] -
1902 gvec[
i][nacross-1][0]*gvec[
i][0][2];
1905 gvec[
i][nacross-1][0]*gvec[
i][0][1] -
1906 gvec[
i][nacross-1][1]*gvec[
i][0][0];
1908 vecm[0] = gnvec[
i][0];
1909 vecm[1] = gnvec[
i][1];
1910 vecm[2] = gnvec[
i][2];
1912 gnvm[
i] = sqrt(vecm[0]*vecm[0] + vecm[1]*vecm[1] + vecm[2]*vecm[2]);
1914 for (
size_t i=0;
i<nalong;
i++) {
1915 gnvec[
i][0] /= gnvm[
i];
1916 gnvec[
i][1] /= gnvm[
i];
1917 gnvec[
i][2] /= gnvm[
i];
1927 gsl_matrix_float_view G =
1928 gsl_matrix_float_view_array(&gnvec[0][0], nalong, 3);
1929 gsl_matrix_float_view
B =
1930 gsl_matrix_float_view_array(&bvec[0][0], ncm, 3);
1933 gsl_matrix_float_view bdotgn_mat =
1934 gsl_matrix_float_view_array(&bdotgn[0][0], ncm, nalong);
1937 gsl_blas_sgemm(CblasNoTrans, CblasTrans, 1.0, &
B.matrix, &G.matrix,
1938 0.0, &bdotgn_mat.matrix);
1947 uint32_t ic = nacross / 2;
1949 for (
size_t i=0;
i<nalong;
i++) {
1950 cnvec[
i][0] = gvec[
i][ic][1]*gnvec[
i][2] - gvec[
i][ic][2]*gnvec[
i][1];
1951 cnvec[
i][1] = gvec[
i][ic][2]*gnvec[
i][0] - gvec[
i][ic][0]*gnvec[
i][2];
1952 cnvec[
i][2] = gvec[
i][ic][0]*gnvec[
i][1] - gvec[
i][ic][1]*gnvec[
i][0];
1956 float *dcm =
new float[nalong];
1957 for (
size_t i=0;
i<nalong;
i++) {
1958 vecm[0] = gvec[
i][ic+1][0] - gvec[
i][ic][0];
1959 vecm[1] = gvec[
i][ic+1][1] - gvec[
i][ic][1];
1960 vecm[2] = gvec[
i][ic+1][2] - gvec[
i][ic][2];
1962 dcm[
i] = sqrt(vecm[0]*vecm[0] + vecm[1]*vecm[1] + vecm[2]*vecm[2]);
1966 float db = gridres/6311/2;
1970 for (
size_t i=0;
i<ncm;
i++) {
1971 if (bdotgn[
i][0] >
db || bdotgn[
i][nalong-1] < -
db) {
1980 for (
size_t j=0;
j<nalong;
j++) {
1981 if (bdotgn[
i][
j] > -
db && bdotgn[
i][
j] <=
db) {
1985 for (
size_t k=0;
k<3;
k++)
1986 bdotcn += (bvec[
i][
k] * cnvec[
j][
k]);
1988 bcol[
i] = (short) round(ic + bdotcn/dcm[
j]);
1990 if (bcol[
i] < 0 || bcol[
i] >= (
short) nacross) {