8 #include <gsl/gsl_math.h>
9 #include <gsl/gsl_interp2d.h>
10 #include <gsl/gsl_spline2d.h>
11 #include <gsl/gsl_multifit.h>
15 static gsl_spline2d *spline_misr;
16 static gsl_interp_accel *xacc, *yacc;
17 static double xa[32], ya[2];
19 static int32_t geoFileId;
20 static int32_t lat_id;
21 static int32_t lon_id;
31 static int single_ifile=0;
35 int interp_values(
double *grid_values,
double interpolated_values[16][512]);
37 double interpolated_values[16][512]);
44 int32_t
start[3]={0,0,0};
45 int32_t
count[3]={180,8,32};
48 {
"DF",
"CF",
"BF",
"AF",
"AN",
"AA",
"BA",
"CA",
"DA"};
50 {
"Df",
"Cf",
"Bf",
"Af",
"An",
"Aa",
"Ba",
"Ca",
"Da"};
54 misr_t *private_data =
file->private_data;
61 if ( private_data->multipleInput == 1) {
68 strcat(namebuf, camera_type[
i]);
70 sd_id[
i] = SDstart(namebuf, DFACC_RDONLY);
71 if (sd_id[
i] ==
FAIL) {
72 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
73 __FILE__, __LINE__, namebuf, DFACC_RDONLY);
82 private_data->fileID[
i] = Hopen(namebuf, DFACC_RDONLY, 0);
83 Vstart ( private_data->fileID[
i]);
84 refn = VSfind( private_data->fileID[
i],
"PerBlockMetadataTime");
85 private_data->blockTimeID[
i] =
86 VSattach( private_data->fileID[
i], refn,
"r");
94 if ( strncmp(
basename(
file->name)+39, camera_type[
i], 2) == 0) {
98 sd_id[icamera] = SDstart(
file->name, DFACC_RDONLY);
99 if (sd_id[icamera] ==
FAIL) {
100 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
101 __FILE__, __LINE__,
file->name, DFACC_RDONLY);
108 private_data->fileID[icamera] = Hopen(
file->name, DFACC_RDONLY, 0);
109 Vstart ( private_data->fileID[icamera]);
110 refn = VSfind( private_data->fileID[icamera],
"PerBlockMetadataTime");
111 private_data->blockTimeID[icamera] =
112 VSattach( private_data->fileID[icamera], refn,
"r");
120 if (sd_id[
i] == -1)
continue;
122 SDselect(sd_id[
i],SDnametoindex(sd_id[
i],
"Red Radiance/RDQI"));
124 SDselect(sd_id[
i], SDnametoindex(sd_id[
i],
"Green Radiance/RDQI"));
126 SDselect(sd_id[
i], SDnametoindex(sd_id[
i],
"Blue Radiance/RDQI"));
128 SDselect(sd_id[
i], SDnametoindex(sd_id[
i],
"NIR Radiance/RDQI"));
144 geoFileId = SDstart(
file->geofile, DFACC_RDONLY);
145 if (geoFileId ==
FAIL) {
146 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
147 __FILE__, __LINE__,
file->geofile, DFACC_RDONLY);
151 lat_id = SDselect(geoFileId, SDnametoindex(geoFileId,
"GeoLatitude"));
152 lon_id = SDselect(geoFileId, SDnametoindex(geoFileId,
"GeoLongitude"));
168 gmp_id = SDstart(
file->gmpfile, DFACC_RDONLY);
169 if (gmp_id ==
FAIL) {
170 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
171 __FILE__, __LINE__,
file->gmpfile, DFACC_RDONLY);
176 sds_id = SDselect(gmp_id, SDnametoindex(gmp_id,
"SolarAzimuth"));
178 (VOIDP) &private_data->SolAzimuth);
180 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
181 __LINE__,
"SolAzimuth",
file->gmpfile);
187 sds_id = SDselect(gmp_id, SDnametoindex(gmp_id,
"SolarZenith"));
189 (VOIDP) &private_data->SolZenith);
191 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
192 __LINE__,
"SolZenith",
file->gmpfile);
199 if (sd_id[
i] == -1)
continue;
201 strcpy(namebuf, camera_type_mc[
i]);
202 strcat(namebuf,
"Azimuth");
203 sds_id = SDselect(gmp_id, SDnametoindex(gmp_id, namebuf));
205 (VOIDP) &private_data->SenAzimuth[
i]);
207 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
208 __LINE__, namebuf,
file->gmpfile);
213 strcpy(namebuf, camera_type_mc[
i]);
214 strcat(namebuf,
"Zenith");
215 sds_id = SDselect(gmp_id, SDnametoindex(gmp_id, namebuf));
217 (VOIDP) &private_data->SenZenith[
i]);
219 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
220 __LINE__, namebuf,
file->gmpfile);
230 SDreadattr(sd_id[icamera],
231 SDfindattr(sd_id[icamera],
"Start_block"),
232 (VOIDP) &private_data->startBlock);
233 SDreadattr(sd_id[icamera],
234 SDfindattr(sd_id[icamera],
"End block"),
235 (VOIDP) &private_data->endBlock);
239 file->nscan = 128*(private_data->endBlock);
244 SDreadattr(sd_id[icamera],
245 SDfindattr(sd_id[icamera],
"Ocean_blocks.numbers"),
246 (VOIDP) private_data->ocean_block_numbers);
247 memset(&private_data->isOceanBlock, 0, 180);
248 for (
i=0;
i<180;
i++) {
249 int j = private_data->ocean_block_numbers[
i];
250 if (
j != 0) private_data->isOceanBlock[
j-1] = 1;
254 memset(&private_data->offset, 0, 180);
255 for (
i=0;
i<179;
i++) {
256 double p1 = private_data->SolZenith[8*
i+6][15];
257 double p2 = private_data->SolZenith[8*
i+7][15];
258 double f1 = private_data->SolZenith[8*(
i+1)+0][15];
260 double f1_l = private_data->SolZenith[8*(
i+1)+0][14];
261 double f1_r = private_data->SolZenith[8*(
i+1)+0][16];
262 double diff1a =
fabs((p2-
p1)-(
f1-p2));
263 double diff1b =
fabs((p2-
p1)-(f1_l-p2));
264 double diff1c =
fabs((p2-
p1)-(f1_r-p2));
265 if (diff1a < diff1b && diff1a < diff1c)
266 private_data->offset[
i] = 0;
267 if (diff1b < diff1a && diff1b < diff1c)
268 private_data->offset[
i] = -1;
269 if (diff1c < diff1a && diff1c < diff1b)
270 private_data->offset[
i] = +1;
278 const gsl_interp2d_type *T = gsl_interp2d_bilinear;
279 spline_misr = gsl_spline2d_alloc(T, 32, 2);
280 xacc = gsl_interp_accel_alloc();
281 yacc = gsl_interp_accel_alloc();
283 for (
size_t i=0;
i<32;
i++) xa[
i] = 7.5 + 16*
i;
294 int32_t file_id, vg_band_ref, refn, vg_id, vd_id;
295 int32_t nObj, tag,
ref;
297 char *grpTags[4]={
"BlueBand",
"GreenBand",
"RedBand",
"NIRBand"};
299 file_id = Hopen(
file, DFACC_RDONLY, 0);
303 for (
i=0;
i<4;
i++) {
306 vg_band_ref = Vfind(file_id, grpTags[
i]);
309 refn = Vgetid(file_id, refn);
310 vg_id = Vattach(file_id, refn,
"r");
311 Vgetname(vg_id,
name);
312 if (strcmp(
name,
"Grid Attributes") == 0)
break;
315 nObj = Vntagrefs(vg_id);
318 for (
j=0;
j<nObj;
j++) {
319 Vgettagref(vg_id,
j, &tag, &
ref);
320 vd_id = VSattach(file_id,
ref,
"r");
321 VSgetname(vd_id,
name);
322 if (strcmp(
name,
"Scale factor") == 0) {
323 VSread(vd_id, (uint8 *) &rad_scl_factors[
i], 1, NO_INTERLACE);
329 rad_scl_factors[
i] /= 10;
343 int32_t
start[3]={0,0,0};
344 int32_t
count[3]={1,1,512};
347 static int32_t last_recnum_gp=-1;
350 int32_t
recnum, recnum_red, recnum_gp, block;
352 ushort rad_data[4][4][2048];
354 double dbl_data[2*32];
362 static double sla_interp_data[16][512];
363 static double slz_interp_data[16][512];
364 static double sna_interp_data[
N_CAMERAS][16][512];
365 static double snz_interp_data[
N_CAMERAS][16][512];
367 static double xy_interp_data[2][16][512];
368 static int32_t gp_index;
373 misr_t *private_data =
l1file->private_data;
377 for (
i=0;
i<16;
i++) {
378 for (
j=0;
j<512;
j++) {
379 sla_interp_data[
i][
j] = -32767;
380 slz_interp_data[
i][
j] = -32767;
385 for (
i=0;
i<16;
i++) {
386 for (
j=0;
j<512;
j++) {
390 sna_interp_data[
k][
i][
j] = -555;
391 snz_interp_data[
k][
i][
j] = -555;
414 if (single_ifile) jcamera = icamera;
else jcamera =
l1rec->iscan %
N_CAMERAS;
422 VSseek(private_data->blockTimeID[jcamera], block);
423 VSread(private_data->blockTimeID[jcamera], (uint8 *) timestring, 1,
444 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
445 __LINE__,
"GeoLatitude",
l1file->geofile);
451 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
452 __LINE__,
"GeoLongitude",
l1file->geofile);
460 recnum_gp = (
recnum - 8) / 16;
461 if (recnum_gp != last_recnum_gp &&
recnum >= 8) {
479 for (
i=0;
i<32;
i++) {
480 dbl_data[
i] = private_data->SolAzimuth[recnum_gp+0][
i];
481 if (dbl_data[
i] >= 0 && dbl_data[
i] < 180)
482 dbl_data[
i] = dbl_data[
i] + 360;
483 dbl_data[
i+32] = private_data->SolAzimuth[recnum_gp+1][
i];
484 if (dbl_data[
i+32] >= 0 && dbl_data[
i+32] < 180)
485 dbl_data[
i+32] = dbl_data[
i+32] + 360;
492 for (
i=0;
i<32;
i++) {
493 dbl_data[
i] = private_data->SolZenith[recnum_gp+0][
i];
494 dbl_data[
i+32] = private_data->SolZenith[recnum_gp+1][
i];
506 if (sd_id[
j] == -1)
continue;
508 for (
i=0;
i<32;
i++) {
510 if ( private_data->SenAzimuth[
j][recnum_gp+0][
i] > 0)
511 dbl_xy[
i] = cos(private_data->SenAzimuth[
j][recnum_gp+0][
i]*
D2R);
513 if ( private_data->SenAzimuth[
j][recnum_gp+1][
i] > 0)
514 dbl_xy[
i+32] = cos(private_data->SenAzimuth[
j][recnum_gp+1][
i]*
D2R);
518 for (
i=0;
i<32;
i++) {
520 if ( private_data->SenAzimuth[
j][recnum_gp+0][
i] > 0)
521 dbl_xy[
i] = sin(private_data->SenAzimuth[
j][recnum_gp+0][
i]*
D2R);
523 if ( private_data->SenAzimuth[
j][recnum_gp+1][
i] > 0)
524 dbl_xy[
i+32] = sin(private_data->SenAzimuth[
j][recnum_gp+1][
i]*
D2R);
528 for (
i=0;
i<16;
i++) {
529 for (
k=0;
k<512;
k++) {
530 if ( xy_interp_data[1][
i][
k] != -555 &&
531 xy_interp_data[0][
i][
k] != -555)
532 sna_interp_data[
j][
i][
k] = atan2(xy_interp_data[1][
i][
k],
533 xy_interp_data[0][
i][
k]) /
D2R;
535 sna_interp_data[
j][
i][
k] = -555;
545 if (sd_id[
j] == -1)
continue;
546 for (
i=0;
i<32;
i++) {
547 dbl_data[
i] = private_data->SenZenith[
j][recnum_gp+0][
i];
548 dbl_data[
i+32] = private_data->SenZenith[
j][recnum_gp+1][
i];
553 last_recnum_gp = recnum_gp;
562 start[0] = recnum_red / 512;
572 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
573 __LINE__,
"Red Radiance/RDQI",
l1file->name);
576 usptr = &rad_data[2][0][0];
581 if ((jcamera+1) != 5) {
591 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
592 __LINE__,
"Blue Radiance/RDQI",
l1file->name);
595 usptr = &rad_data[0][0][0];
597 if ((jcamera+1) == 5)
reduce_res(rad_data[0]);
603 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
604 __LINE__,
"Green Radiance/RDQI",
l1file->name);
607 usptr = &rad_data[1][0][0];
609 if ((jcamera+1) == 5)
reduce_res(rad_data[1]);
614 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
615 __LINE__,
"NIR Radiance/RDQI",
l1file->name);
618 usptr = &rad_data[3][0][0];
620 if ((jcamera+1) == 5)
reduce_res(rad_data[3]);
624 for (
size_t ip=8; ip<504; ++ip) {
625 if (rad_data[0][0][ip] < 16378)
626 l1rec->Lt[4*ip+0] = rad_data[0][0][ip]*private_data->radScaleFactors[0];
627 if (rad_data[1][0][ip] < 16378)
628 l1rec->Lt[4*ip+1] = rad_data[1][0][ip]*private_data->radScaleFactors[1];
629 if (rad_data[2][0][ip] < 16378)
630 l1rec->Lt[4*ip+2] = rad_data[2][0][ip]*private_data->radScaleFactors[2];
631 if (rad_data[3][0][ip] < 16378)
632 l1rec->Lt[4*ip+3] = rad_data[3][0][ip]*private_data->radScaleFactors[3];
636 for (
size_t ip=8; ip<504; ++ip) {
637 if (sla_interp_data[gp_index][ip] != -555) {
638 l1rec->sola[ip] = sla_interp_data[gp_index][ip];
643 if (slz_interp_data[gp_index][ip] != -555) {
644 l1rec->solz[ip] = slz_interp_data[gp_index][ip];
648 if (sna_interp_data[jcamera][gp_index][ip] != -555) {
649 l1rec->sena[ip] = sna_interp_data[jcamera][gp_index][ip];
654 if (snz_interp_data[jcamera][gp_index][ip] != -555) {
655 l1rec->senz[ip] = snz_interp_data[jcamera][gp_index][ip];
659 if (sla_interp_data[gp_index][ip] != -555 &&
660 sna_interp_data[jcamera][gp_index][ip] != -555) {
663 if (
l1rec->delphi[ip] < -180.)
664 l1rec->delphi[ip] += 360.0;
665 else if (
l1rec->delphi[ip] > 180.0)
666 l1rec->delphi[ip] -= 360.0;
678 int interp_values(
double *grid_values,
double interpolated_values[16][512]) {
680 const gsl_interp2d_type *T = gsl_interp2d_bilinear;
681 static gsl_spline2d *
spline;
682 static gsl_interp_accel *xacc, *yacc;
683 static double xa[32], ya[2];
685 double dbl_data[2*32];
694 spline = gsl_spline2d_alloc(T, 32, 2);
695 xacc = gsl_interp_accel_alloc();
696 yacc = gsl_interp_accel_alloc();
698 for (
size_t i=0;
i<32;
i++) xa[
i] = 7.5 + 16*
i;
705 for (
size_t i=0;
i<32;
i++) {
706 gsl_spline2d_set(
spline, dbl_data,
i, 0, grid_values[
i]);
707 gsl_spline2d_set(
spline, dbl_data,
i, 1, grid_values[
i+32]);
710 gsl_spline2d_init(
spline, xa, ya, dbl_data, 32, 2);
719 for (
size_t j=0;
j<16; ++
j) {
721 for (
size_t i=8;
i<504; ++
i) {
724 if (grid_values[(
i-8)/16] == -111 || grid_values[(
i-8)/16] == -222 ||
725 grid_values[(
i-8)/16] == -333 || grid_values[(
i-8)/16] == -444 ||
726 grid_values[(
i-8)/16] == -555 || grid_values[(
i-8)/16] == -999 ||
728 grid_values[(
i-8)/16+1] == -111 || grid_values[(
i-8)/16+1] == -222 ||
729 grid_values[(
i-8)/16+1] == -333 || grid_values[(
i-8)/16+1] == -444 ||
730 grid_values[(
i-8)/16+1] == -555 || grid_values[(
i-8)/16+1] == -999 ||
732 grid_values[(
i-8)/16+32] == -111 || grid_values[(
i-8)/16+32] == -222 ||
733 grid_values[(
i-8)/16+32] == -333 || grid_values[(
i-8)/16+32] == -444 ||
734 grid_values[(
i-8)/16+32] == -555 || grid_values[(
i-8)/16+32] == -999 ||
736 grid_values[(
i-8)/16+32+1] == -111 || grid_values[(
i-8)/16+32+1] == -222 ||
737 grid_values[(
i-8)/16+32+1] == -333 || grid_values[(
i-8)/16+32+1] == -444 ||
738 grid_values[(
i-8)/16+32+1] == -555 || grid_values[(
i-8)/16+32+1] == -999)
740 interpolated_values[
j][
i] = -555;
742 interpolated_values[
j][
i] =
743 gsl_spline2d_eval(
spline, xi, yi, xacc, yacc);
754 double interpolated_values[16][512]) {
756 double dbl_data[2*32];
758 if (diff_offset == 0) {
759 for (
size_t i=0;
i<32;
i++) {
760 gsl_spline2d_set(spline_misr, dbl_data,
i, 0, (
double) grid_values[
i]);
761 gsl_spline2d_set(spline_misr, dbl_data,
i, 1, (
double) grid_values[
i+32]);
764 gsl_spline2d_init(spline_misr, xa, ya, dbl_data, 32, 2);
766 for (
size_t j=0;
j<16; ++
j) {
768 for (
size_t i=8;
i<504; ++
i) {
771 interpolated_values[
j][
i] =
772 gsl_spline2d_eval(spline_misr, xi, yi, xacc, yacc);
775 }
else if (diff_offset == -1) {
777 for (
size_t i=0;
i<32;
i++)
778 gsl_spline2d_set(spline_misr, dbl_data,
i, 0, (
double) grid_values[
i]);
779 for (
size_t i=0;
i<31;
i++)
780 gsl_spline2d_set(spline_misr, dbl_data,
i+1, 1,
781 (
double) grid_values[
i+32]);
783 for (
size_t j=0;
j<8; ++
j) {
785 for (
size_t i=8;
i<504; ++
i) {
788 interpolated_values[
j][
i] =
789 gsl_spline2d_eval(spline_misr, xi, yi, xacc, yacc);
793 for (
size_t i=0;
i<32;
i++)
794 gsl_spline2d_set(spline_misr, dbl_data,
i, 0, (
double) grid_values[
i]);
795 for (
size_t i=0;
i<32;
i++)
796 gsl_spline2d_set(spline_misr, dbl_data,
i, 1,
797 (
double) grid_values[
i+32]);
800 for (
size_t i=1;
i<32;
i++)
801 gsl_spline2d_set(spline_misr, dbl_data,
i-1, 1,
802 (
double) grid_values[
i]);
804 for (
size_t j=0;
j<16; ++
j) {
806 for (
size_t i=8;
i<504; ++
i) {
809 interpolated_values[
j][
i] =
810 gsl_spline2d_eval(spline_misr, xi, yi, xacc, yacc);
823 static gsl_matrix *X, *cov;
824 static gsl_vector *
y, *w, *
c;
826 static gsl_multifit_linear_workspace *work;
832 X = gsl_matrix_alloc (16, 3);
833 y = gsl_vector_alloc (16);
834 w = gsl_vector_alloc (16);
836 c = gsl_vector_alloc (3);
837 cov = gsl_matrix_alloc (3, 3);
839 work = gsl_multifit_linear_alloc (16, 3);
841 for (
size_t i=0;
i<16;
i++) {
842 gsl_matrix_set (X,
i, 0, 1.0);
848 double x_val = col - 1.5;
849 double y_val = 1.5 - row;
851 gsl_matrix_set (X,
i, 1, x_val);
852 gsl_matrix_set (X,
i, 2, y_val);
858 for (
size_t ip=0; ip<512; ip++) {
860 for (
size_t irow=0; irow<4; irow++) {
861 for (
size_t icol=0; icol<4; icol++) {
862 int index = irow*4+icol;
863 double d_val = (
double) rad_data[irow][4*ip+icol];
864 gsl_vector_set (
y,
index, d_val);
865 if (rad_data[irow][4*ip+icol] >= 16378) {
866 gsl_vector_set (w,
index, 0.0);
868 gsl_vector_set (w,
index, 1.0);
889 gsl_multifit_wlinear (X, w,
y,
c, cov, &chisq, work);
890 double fit_val = gsl_vector_get(
c,0);
891 rad_data[0][ip] = (
ushort) ( fit_val + 0.5);
893 rad_data[0][ip] = 16378;
909 if (sd_id[
i] == -1)
continue;
910 SDendaccess(blu_id[
i]);
911 SDendaccess(grn_id[
i]);
912 SDendaccess(red_id[
i]);
913 SDendaccess(nir_id[
i]);