20 #define RADIUS 6378.137
21 #define FL 1.0/298.257
27 #define MAXOCARR 10000
32 using namespace netCDF;
33 using namespace netCDF::exceptions;
35 static int32_t msec_start;
38 static int16_t year,
day, nline,
npix, sline;
40 static int16_t maxday;
41 static float solz1, sola1, senz1, sena1;
42 static float *lon, *lat, *senz, *sena, *solz, *sola;
44 static int32_t scansPerScene;
45 static int32_t linesPerScan;
46 static int16_t *tilt_flag;
48 static float *inst_temp;
49 static int16_t *miss_qual;
50 static int16_t num_tab;
51 static int32_t extr_line_offset = 0;
52 static int16_t *start_scan;
53 static int16_t last_table = 0;
54 static int16_t sample_table[3][8][2][400][2];
80 static int CalcViewAngle_nc(
float lon1,
float lat1,
float pos[3],
84 float up[3], upxy, ea[3], no[3];
86 float gvec[3], scvec[3], senl[3], sunl[3];
89 rlon = lon1 *
PI / 180.0;
90 rlat = lat1 *
PI / 180.0;
96 up[0] = cos(rlat) * cos(rlon);
97 up[1] = cos(rlat) * sin(rlon);
99 upxy = sqrt(up[0] * up[0 ] + up[1] * up[1]);
100 ea[0] = -up[1] / upxy;
101 ea[1] = up[0] / upxy;
104 no[0] = up[1] * ea[2] - ea[1] * up[2];
105 no[1] = up[2] * ea[0] - ea[2] * up[0];
106 no[2] = up[0] * ea[1] - ea[0] * up[1];
113 phi = atan(tan(rlat)*(1 -
FL)*(1 -
FL));
115 R =
RADIUS * (1 -
FL) / sqrt(1 - (2 -
FL) *
FL * (cos(phi) * cos(phi)));
116 gvec[0] =
R * cos(phi) * cos(rlon);
117 gvec[1] =
R * cos(phi) * sin(rlon);
118 gvec[2] =
R * sin(phi);
119 for (
i = 0;
i < 3;
i++) {
120 scvec[
i] =
pos[
i] - gvec[
i];
125 for (
i = 0;
i < 3;
i++) {
130 for (
i = 0;
i < 3;
i++) {
133 for (
j = 0;
j < 3;
j++) {
134 senl[
i] = senl[
i] + rmat[
i][
j] * scvec[
j];
135 sunl[
i] = sunl[
i] + rmat[
i][
j] * usun[
j];
140 solz1 =
RADEG * atan(sqrt(sunl[0] * sunl[0] + sunl[1] * sunl[1]) / sunl[2]);
141 if (solz1 < 0.0) solz1 += 180.0;
144 sola1 =
RADEG * (atan2(sunl[0], sunl[1]));
149 sola1 = sola1 + 360.0;
153 senz1 =
RADEG * atan(sqrt(senl[0] * senl[0] + senl[1] * senl[1]) / senl[2]);
154 if (senz1 < 0.0) senz1 += 180.0;
156 sena1 =
RADEG * (atan2(senl[0], senl[1]));
161 sena1 = sena1 + 360.0;
180 float *inlon, *inlat;
181 float *insolz, *insola;
182 float *insenz, *insena;
189 float iusun[3], ipos[3];
192 int32_t
eline, nlon, nlat;
197 float *x_ctl_ll, *y_ctl_ll, *z_ctl_ll;
198 float *x_ctl_sol, *y_ctl_sol, *z_ctl_sol;
199 float *x_ctl_sen, *y_ctl_sen, *z_ctl_sen;
200 float * in_ptr[3][3], *out_ptr[3][2];
202 inlon = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
203 inlat = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
204 insolz = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
205 insola = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
206 insenz = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
207 insena = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
208 usun = (
float *) calloc(3 * scansPerScene,
sizeof (
float));
209 pos = (
float *) calloc(3 * scansPerScene,
sizeof (
float));
210 row = (int32_t *) calloc(scansPerScene,
sizeof (
int));
211 pxl = (int16_t *) calloc(ncol,
sizeof (int16_t));
212 xctl = (
float *) calloc(ncol,
sizeof (
float));
213 indx = (int32_t *) calloc(scansPerScene,
sizeof (
int));
214 yctl = (
float *) calloc(scansPerScene,
sizeof (
float));
215 in1 = (
float *) calloc(scansPerScene,
sizeof (
float));
216 in2 = (
float *) calloc(scansPerScene,
sizeof (
float));
219 NcVar tempVar = dataFile.getVar(
"det");
220 tempVar.getVar(&det);
221 tempVar = dataFile.getVar(
"pxl");
223 tempVar = dataFile.getVar(
"lon");
224 tempVar.getVar(inlon);
225 tempVar = dataFile.getVar(
"lat");
226 tempVar.getVar(inlat);
227 tempVar = dataFile.getVar(
"sun_ref");
228 tempVar.getVar(usun);
229 tempVar = dataFile.getVar(
"orb_vec");
233 for (
i = 0;
i < ncol;
i++) {
238 for (
i = 0;
i < scansPerScene;
i++) {
240 for (
j = 0;
j < 3;
j++) {
241 usun_sum = usun_sum + usun[3 *
i +
j] * usun[3 *
i +
j];
243 for (
j = 0;
j < 3;
j++) {
244 usun[3 *
i +
j] = usun[3 *
i +
j] / sqrt(usun_sum);
250 printf(
"scansPerScene,ncol = %d %d \n", scansPerScene, ncol);
251 for (
i = 0;
i < ncol;
i++) {
254 for (
i = 0;
i < scansPerScene;
i++) {
255 row[
i] =
i * linesPerScan + det;
259 eline = sline + nline - 1;
261 if (nline < linesPerScan * scansPerScene) {
263 }
else nlat = linesPerScan*scansPerScene;
265 for (
i = 0;
i < nlon;
i++) {
268 for (
i = 0;
i < nlat;
i++) {
274 for (
i = 0;
i < nlat;
i++) {
275 for (
j = 0;
j < scansPerScene;
j++) {
276 if (ilat[
i] == row[
j]) {
283 for (
i = 0;
i < nlat / linesPerScan;
i++) {
291 printf(
"Computing view angles at input control points\n");
292 for (
i = 0;
i < scansPerScene;
i++) {
293 for (
j = 0;
j < ncol;
j++) {
294 for (
k = 0;
k < 3;
k++) {
296 iusun[
k] = usun[3 *
i +
k];
298 CalcViewAngle_nc(inlon[
i * ncol +
j], inlat[
i * ncol +
j], ipos, iusun);
299 insolz[
i * ncol +
j] = solz1;
300 insola[
i * ncol +
j] = sola1;
301 insenz[
i * ncol +
j] = senz1;
302 insena[
i * ncol +
j] = sena1;
308 x_ctl_ll = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
309 y_ctl_ll = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
310 z_ctl_ll = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
312 x_ctl_sol = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
313 y_ctl_sol = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
314 z_ctl_sol = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
316 x_ctl_sen = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
317 y_ctl_sen = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
318 z_ctl_sen = (
float *) calloc(ncol*scansPerScene,
sizeof (
float));
321 for (
i = 0;
i < scansPerScene;
i++) {
322 for (
j = 0;
j < ncol;
j++) {
323 inlon[
i * ncol +
j] = inlon[
i * ncol +
j] /
RADEG;
324 inlat[
i * ncol +
j] = inlat[
i * ncol +
j] /
RADEG;
326 x_ctl_ll[
i * ncol +
j] = cos(inlat[
i * ncol +
j]) * cos(inlon[
i * ncol +
j]);
327 y_ctl_ll[
i * ncol +
j] = cos(inlat[
i * ncol +
j]) * sin(inlon[
i * ncol +
j]);
328 z_ctl_ll[
i * ncol +
j] = sin(inlat[
i * ncol +
j]);
331 insola[
i * ncol +
j] = insola[
i * ncol +
j] /
RADEG;
332 insolz[
i * ncol +
j] = insolz[
i * ncol +
j] /
RADEG;
334 x_ctl_sol[
i * ncol +
j] = cos(insolz[
i * ncol +
j]) * cos(insola[
i * ncol +
j]);
335 y_ctl_sol[
i * ncol +
j] = cos(insolz[
i * ncol +
j]) * sin(insola[
i * ncol +
j]);
336 z_ctl_sol[
i * ncol +
j] = sin(insolz[
i * ncol +
j]);
339 insena[
i * ncol +
j] = insena[
i * ncol +
j] /
RADEG;
340 insenz[
i * ncol +
j] = insenz[
i * ncol +
j] /
RADEG;
342 x_ctl_sen[
i * ncol +
j] = cos(insenz[
i * ncol +
j]) * cos(insena[
i * ncol +
j]);
343 y_ctl_sen[
i * ncol +
j] = cos(insenz[
i * ncol +
j]) * sin(insena[
i * ncol +
j]);
344 z_ctl_sen[
i * ncol +
j] = sin(insenz[
i * ncol +
j]);
348 in_ptr[0][0] = x_ctl_ll;
349 in_ptr[0][1] = y_ctl_ll;
350 in_ptr[0][2] = z_ctl_ll;
351 in_ptr[1][0] = x_ctl_sol;
352 in_ptr[1][1] = y_ctl_sol;
353 in_ptr[1][2] = z_ctl_sol;
354 in_ptr[2][0] = x_ctl_sen;
355 in_ptr[2][1] = y_ctl_sen;
356 in_ptr[2][2] = z_ctl_sen;
360 out_ptr[1][0] = sola;
361 out_ptr[1][1] = solz;
362 out_ptr[2][0] = sena;
363 out_ptr[2][1] = senz;
370 printf(
"Interpolating rows for longitude/azimuth\n");
371 spl_aux = (
float *) calloc(ncol,
sizeof (
float));
373 for (
i = 0;
i < scansPerScene;
i++) {
374 jout = row[
i] - sline;
375 if ((row[
i] >= sline) && (row[
i] <=
eline)) {
376 for (l = 0; l < 3; l++) {
377 spline(xctl, in_ptr[l][0] +
i*ncol, ncol, 1e30, 1e30, spl_aux);
378 for (
j = 0;
j < nlon;
j++)
379 splint(xctl, in_ptr[l][0] +
i * ncol, spl_aux, ncol,
380 (
float) ilon[
j], out_ptr[l][0] + jout *
npix +
j);
382 spline(xctl, in_ptr[l][1] +
i*ncol, ncol, 1e30, 1e30, spl_aux);
383 for (
j = 0;
j < nlon;
j++)
384 splint(xctl, in_ptr[l][1] +
i * ncol, spl_aux, ncol,
385 (
float) ilon[
j], out_ptr[l][1] + jout *
npix +
j);
394 printf(
"Interpolating columns for longitude/azimuth\n");
395 spl_aux = (
float *) calloc(nlat / linesPerScan,
sizeof (
float));
397 for (
i = 0;
i < nlon;
i++) {
398 for (l = 0; l < 3; l++) {
399 for (
k = 0;
k < nlat / linesPerScan;
k++) {
400 in1[
k] = *(out_ptr[l][0] + indx[
k] *
npix +
i);
401 in2[
k] = *(out_ptr[l][1] + indx[
k] *
npix +
i);
403 spline(yctl, in1, nlat / linesPerScan, 1e30, 1e30, spl_aux);
404 for (
j = 0;
j < nlat;
j++)
405 splint(yctl, in1, spl_aux, nlat / linesPerScan, (
float)
j, (
float *) &out1[
j]);
407 spline(yctl, in2, nlat / linesPerScan, 1e30, 1e30, spl_aux);
408 for (
j = 0;
j < nlat;
j++)
409 splint(yctl, in2, spl_aux, nlat / linesPerScan, (
float)
j, (
float *) &out2[
j]);
411 for (
j = 0;
j < nlat;
j++) {
412 *(out_ptr[l][0] +
j *
npix +
i) = atan2(out2[
j], out1[
j]) *
RADEG;
413 if (l >= 1 && *(out_ptr[l][0] +
j *
npix +
i) < 0) {
414 *(out_ptr[l][0] +
j *
npix +
i) += 360;
423 printf(
"Interpolating rows for latitude/zenith\n");
424 spl_aux = (
float *) calloc(ncol,
sizeof (
float));
426 for (
i = 0;
i < scansPerScene;
i++) {
427 jout = row[
i] - sline;
428 if ((row[
i] >= sline) && (row[
i] <=
eline)) {
429 for (l = 0; l < 3; l++) {
430 spline(xctl, in_ptr[l][2] +
i*ncol, ncol, 1e30, 1e30, spl_aux);
431 for (
j = 0;
j < nlon;
j++)
432 splint(xctl, in_ptr[l][2] +
i * ncol, spl_aux, ncol,
433 (
float) ilon[
j], out_ptr[l][1] + jout *
npix +
j);
442 printf(
"Interpolating columns for latitude/zenith\n");
443 spl_aux = (
float *) calloc(nlat / linesPerScan,
sizeof (
float));
445 for (
i = 0;
i < nlon;
i++) {
446 for (l = 0; l < 3; l++) {
447 for (
k = 0;
k < nlat / linesPerScan;
k++) {
448 in1[
k] = *(out_ptr[l][1] + indx[
k] *
npix +
i);
450 spline(yctl, in1, nlat / linesPerScan, 1e30, 1e30, spl_aux);
451 for (
j = 0;
j < nlat;
j++)
452 splint(yctl, in1, spl_aux, nlat / linesPerScan, (
float)
j, (
float *) &out1[
j]);
454 for (
j = 0;
j < nlat;
j++) {
455 *(out_ptr[l][1] +
j *
npix +
i) = asin(out1[
j]) *
RADEG;
506 int32_t linesPerScene;
512 NcFile dataFile(
l1file->name, NcFile::read);
513 char tempTimeCoverage[27];
516 dataFile.getAtt(
"time_coverage_start").getValues((
void*) &tempTimeCoverage);
519 int32_t tempDay, tempYear;
520 isodate2ydmsec(tempTimeCoverage, &tempYear, &tempDay, &msec_start);
525 pixPerScan = dataFile.getDim(
"nsamp").getSize();
526 scansPerScene = dataFile.getDim(
"rec").getSize();
527 ncol = dataFile.getDim(
"pxls").getSize();
529 dataFile.getAtt(
"orbit_node_longitude").getValues((
void*) &
l1file->orbit_node_lon);
530 dataFile.getAtt(
"orbit_number").getValues((
void*) &
l1file->orbit_number);
531 dataFile.getAtt(
"node_crossing_time").getValues((
char*) &buf);
535 linesPerScene = scansPerScene * linesPerScan;
538 if (!dataFile.getAtt(
"extract_pixel_start").isNull()) {
539 dataFile.getAtt(
"extract_pixel_start").getValues((
void*) &
spix);
540 dataFile.getAtt(
"extract_line_start").getValues((
void*) &extr_line_offset);
541 printf(
"File is Level-1A extract starting on line %d.\n", extr_line_offset + 1);
543 extr_line_offset = 0;
547 nline = linesPerScene;
553 printf(
"-E- %s: Number of scene lines: %d, greater than array allocation: %d.\n",
562 printf(
"-E- %s: Number of scan pixels: %d, greater than array allocation: %d.\n",
569 lon = (
float *) calloc(
npix*nline,
sizeof (
float));
570 lat = (
float *) calloc(
npix*nline,
sizeof (
float));
571 senz = (
float *) calloc(
npix*nline,
sizeof (
float));
572 sena = (
float *) calloc(
npix*nline,
sizeof (
float));
573 solz = (
float *) calloc(
npix*nline,
sizeof (
float));
574 sola = (
float *) calloc(
npix*nline,
sizeof (
float));
586 NcVar tempVar = dataFile.getVar(
"msec");
587 tempVar.getVar(msec_temp1);
589 for (
i = 0;
i < scansPerScene;
i++) {
590 for (
j = 0;
j < linesPerScan;
j++) {
591 msec_temp2[
i * linesPerScan +
j] = msec_temp1[
i];
594 msec_start = msec_temp2[0];
596 for (
i = sline;
i < (sline + nline);
i++) {
601 tempVar = dataFile.getVar(
"tilt");
602 tempVar.getVar(
tilt);
607 tilt_flag = (int16_t *) calloc(scansPerScene,
sizeof (int16_t));
608 tempVar = dataFile.getVar(
"tilt_flag");
609 tempVar.getVar(tilt_flag);
610 inst_temp = (
float *) calloc(4 * scansPerScene,
sizeof (
float));
611 tempVar = dataFile.getVar(
"inst_temp");
612 tempVar.getVar(inst_temp);
613 gain = (int16_t *) calloc(8 * scansPerScene,
sizeof (int16_t));
614 tempVar = dataFile.getVar(
"gain");
615 tempVar.getVar(
gain);
616 miss_qual = (int16_t *) calloc(scansPerScene,
sizeof (int16_t));
617 tempVar = dataFile.getVar(
"miss_qual");
618 tempVar.getVar(miss_qual);
621 tempVar = dataFile.getVar(
"num_tables");
622 tempVar.getVar(&num_tab);
623 start_scan = (int16_t *) calloc(num_tab,
sizeof (int16_t));
624 tempVar = dataFile.getVar(
"start_line");
625 tempVar.getVar(start_scan);
627 for (
i = 0;
i < num_tab;
i++) {
628 if ((extr_line_offset + sline) / linesPerScan < start_scan[
i]) {
635 tempVar = dataFile.getVar(
"samp_table");
637 vector<size_t> samp_start(tempVar.getDimCount());
638 vector<size_t> samp_edges(tempVar.getDimCount());
640 samp_start[0] = last_table;
653 tempVar.getVar(samp_start, samp_edges, &sample_table);
658 catch (NcException& e) {
659 cout <<
"-E- Error in reading input NetCDF: " << e.what() << endl;
676 int32_t nwave =
l1rec->l1file->nbands;
679 static int32_t FirstCall = 1;
680 int32_t current_scan =
recnum / linesPerScan;
686 static int32_t dayIncrimented = 0;
688 if(!dayIncrimented) {
699 if(!dayIncrimented) {
720 NcFile dataFile(
l1file->name, NcFile::read);
722 NcVar l1aDataVar = dataFile.getVar(
"l1a_data");
724 vector<size_t>
start(l1aDataVar.getDimCount());
725 vector<size_t>
edges(l1aDataVar.getDimCount());
740 scan = (
recnum + extr_line_offset) / linesPerScan;
745 if (tilt_flag[current_scan] == 1) tilt_deg = +20;
746 if (tilt_flag[current_scan] == 2) tilt_deg = 0;
747 if (tilt_flag[current_scan] == 4) tilt_deg = -20;
750 if (FirstCall == 1 &&
recnum > 0) {
751 for (
i = 0;
i < num_tab;
i++) {
752 if (
scan / linesPerScan < start_scan[
i]) {
759 NcVar samp_tableVar = dataFile.getVar(
"samp_table");
761 vector<size_t> samp_start(samp_tableVar.getDimCount());
762 vector<size_t> samp_edges(samp_tableVar.getDimCount());
764 samp_start[0] = last_table;
777 if (
scan >= start_scan[last_table + 1]) {
779 samp_start[0] = last_table;
781 samp_tableVar.getVar(samp_start, samp_edges, &sample_table);
785 catch (NcException& e) {
786 cout <<
"-E- Error in reading in readl1a_octs_netcdf: " << e.what() << endl;
792 gain, inst_temp, sample_table, scansPerScene,
797 "-E- %s line %d: Error applying calibration table \"%s\".\n",
798 __FILE__, __LINE__, cal_path);
803 for (ip = 0; ip <
npix; ip++) {
806 if (isnan(
l1rec->solz[ip]))
807 l1rec->navfail[ip] = 1;
809 for (iw = 0; iw < nwave; iw++) {
811 l1rec->Lt [ip * nwave + ib] = scanarr[ip][iw];
814 if (
gain[iw * scansPerScene + current_scan] > 0)
815 l1rec->navwarn[ip] = 1;
816 if (miss_qual[current_scan] > 0)
817 l1rec->navwarn[ip] = 1;
818 if (dataarr[iw][ip] > 1022)
820 if (scanarr[ip][iw] <= 0.0)
821 l1rec->navfail[ip] = 1;