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;
38 int32_t
start[3]={0,0,0};
39 int32_t
count[3]={180,8,32};
42 {
"DF",
"CF",
"BF",
"AF",
"AN",
"AA",
"BA",
"CA",
"DA"};
44 {
"Df",
"Cf",
"Bf",
"Af",
"An",
"Aa",
"Ba",
"Ca",
"Da"};
48 misr_t *private_data =
file->private_data;
55 if ( private_data->multipleInput == 1) {
62 strcat(namebuf, camera_type[
i]);
64 sd_id[
i] = SDstart(namebuf, DFACC_RDONLY);
65 if (sd_id[
i] ==
FAIL) {
66 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
67 __FILE__, __LINE__, namebuf, DFACC_RDONLY);
76 private_data->fileID[
i] = Hopen(namebuf, DFACC_RDONLY, 0);
77 Vstart ( private_data->fileID[
i]);
78 refn = VSfind( private_data->fileID[
i],
"PerBlockMetadataTime");
79 private_data->blockTimeID[
i] =
80 VSattach( private_data->fileID[
i], refn,
"r");
88 if ( strncmp(
basename(
file->name)+39, camera_type[
i], 2) == 0) {
92 sd_id[icamera] = SDstart(
file->name, DFACC_RDONLY);
93 if (sd_id[icamera] ==
FAIL) {
94 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
95 __FILE__, __LINE__,
file->name, DFACC_RDONLY);
102 private_data->fileID[icamera] = Hopen(
file->name, DFACC_RDONLY, 0);
103 Vstart ( private_data->fileID[icamera]);
104 refn = VSfind( private_data->fileID[icamera],
"PerBlockMetadataTime");
105 private_data->blockTimeID[icamera] =
106 VSattach( private_data->fileID[icamera], refn,
"r");
114 if (sd_id[
i] == -1)
continue;
116 SDselect(sd_id[
i],SDnametoindex(sd_id[
i],
"Red Radiance/RDQI"));
118 SDselect(sd_id[
i], SDnametoindex(sd_id[
i],
"Green Radiance/RDQI"));
120 SDselect(sd_id[
i], SDnametoindex(sd_id[
i],
"Blue Radiance/RDQI"));
122 SDselect(sd_id[
i], SDnametoindex(sd_id[
i],
"NIR Radiance/RDQI"));
138 geoFileId = SDstart(
file->geofile, DFACC_RDONLY);
139 if (geoFileId ==
FAIL) {
140 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
141 __FILE__, __LINE__,
file->geofile, DFACC_RDONLY);
145 lat_id = SDselect(geoFileId, SDnametoindex(geoFileId,
"GeoLatitude"));
146 lon_id = SDselect(geoFileId, SDnametoindex(geoFileId,
"GeoLongitude"));
162 gmp_id = SDstart(
file->gmpfile, DFACC_RDONLY);
163 if (gmp_id ==
FAIL) {
164 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
165 __FILE__, __LINE__,
file->gmpfile, DFACC_RDONLY);
170 sds_id = SDselect(gmp_id, SDnametoindex(gmp_id,
"SolarAzimuth"));
172 (VOIDP) &private_data->SolAzimuth);
174 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
175 __LINE__,
"SolAzimuth",
file->gmpfile);
181 sds_id = SDselect(gmp_id, SDnametoindex(gmp_id,
"SolarZenith"));
183 (VOIDP) &private_data->SolZenith);
185 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
186 __LINE__,
"SolZenith",
file->gmpfile);
193 if (sd_id[
i] == -1)
continue;
195 strcpy(namebuf, camera_type_mc[
i]);
196 strcat(namebuf,
"Azimuth");
197 sds_id = SDselect(gmp_id, SDnametoindex(gmp_id, namebuf));
199 (VOIDP) &private_data->SenAzimuth[
i]);
201 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
202 __LINE__, namebuf,
file->gmpfile);
207 strcpy(namebuf, camera_type_mc[
i]);
208 strcat(namebuf,
"Zenith");
209 sds_id = SDselect(gmp_id, SDnametoindex(gmp_id, namebuf));
211 (VOIDP) &private_data->SenZenith[
i]);
213 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
214 __LINE__, namebuf,
file->gmpfile);
224 SDreadattr(sd_id[icamera],
225 SDfindattr(sd_id[icamera],
"Start_block"),
226 (VOIDP) &private_data->startBlock);
227 SDreadattr(sd_id[icamera],
228 SDfindattr(sd_id[icamera],
"End block"),
229 (VOIDP) &private_data->endBlock);
233 file->nscan = 128*(private_data->endBlock);
238 SDreadattr(sd_id[icamera],
239 SDfindattr(sd_id[icamera],
"Ocean_blocks.numbers"),
240 (VOIDP) private_data->ocean_block_numbers);
241 memset(&private_data->isOceanBlock, 0, 180);
242 for (
i=0;
i<180;
i++) {
243 int j = private_data->ocean_block_numbers[
i];
244 if (
j != 0) private_data->isOceanBlock[
j-1] = 1;
248 memset(&private_data->offset, 0, 180);
249 for (
i=0;
i<179;
i++) {
250 double p1 = private_data->SolZenith[8*
i+6][15];
251 double p2 = private_data->SolZenith[8*
i+7][15];
252 double f1 = private_data->SolZenith[8*(
i+1)+0][15];
254 double f1_l = private_data->SolZenith[8*(
i+1)+0][14];
255 double f1_r = private_data->SolZenith[8*(
i+1)+0][16];
256 double diff1a =
fabs((p2-
p1)-(
f1-p2));
257 double diff1b =
fabs((p2-
p1)-(f1_l-p2));
258 double diff1c =
fabs((p2-
p1)-(f1_r-p2));
259 if (diff1a < diff1b && diff1a < diff1c)
260 private_data->offset[
i] = 0;
261 if (diff1b < diff1a && diff1b < diff1c)
262 private_data->offset[
i] = -1;
263 if (diff1c < diff1a && diff1c < diff1b)
264 private_data->offset[
i] = +1;
272 const gsl_interp2d_type *T = gsl_interp2d_bilinear;
273 spline_misr = gsl_spline2d_alloc(T, 32, 2);
274 xacc = gsl_interp_accel_alloc();
275 yacc = gsl_interp_accel_alloc();
277 for (
size_t i=0;
i<32;
i++) xa[
i] = 7.5 + 16*
i;
288 int32_t file_id, vg_band_ref, refn, vg_id, vd_id;
289 int32_t nObj, tag,
ref;
291 char *grpTags[4]={
"BlueBand",
"GreenBand",
"RedBand",
"NIRBand"};
293 file_id = Hopen(
file, DFACC_RDONLY, 0);
297 for (
i=0;
i<4;
i++) {
300 vg_band_ref = Vfind(file_id, grpTags[
i]);
303 refn = Vgetid(file_id, refn);
304 vg_id = Vattach(file_id, refn,
"r");
305 Vgetname(vg_id,
name);
306 if (strcmp(
name,
"Grid Attributes") == 0)
break;
309 nObj = Vntagrefs(vg_id);
312 for (
j=0;
j<nObj;
j++) {
313 Vgettagref(vg_id,
j, &tag, &
ref);
314 vd_id = VSattach(file_id,
ref,
"r");
315 VSgetname(vd_id,
name);
316 if (strcmp(
name,
"Scale factor") == 0) {
317 VSread(vd_id, (uint8 *) &rad_scl_factors[
i], 1, NO_INTERLACE);
323 rad_scl_factors[
i] /= 10;
337 int32_t
start[3]={0,0,0};
338 int32_t
count[3]={1,1,512};
341 static int32_t last_recnum_gp=-1;
344 int32_t
recnum, recnum_red, recnum_gp, block;
346 ushort rad_data[4][4][2048];
348 double dbl_data[2*32];
356 static double sla_interp_data[16][512];
357 static double slz_interp_data[16][512];
358 static double sna_interp_data[
N_CAMERAS][16][512];
359 static double snz_interp_data[
N_CAMERAS][16][512];
361 static double xy_interp_data[2][16][512];
362 static int32_t gp_index;
367 misr_t *private_data =
l1file->private_data;
371 for (
i=0;
i<16;
i++) {
372 for (
j=0;
j<512;
j++) {
373 sla_interp_data[
i][
j] = -32767;
374 slz_interp_data[
i][
j] = -32767;
379 for (
i=0;
i<16;
i++) {
380 for (
j=0;
j<512;
j++) {
384 sna_interp_data[
k][
i][
j] = -555;
385 snz_interp_data[
k][
i][
j] = -555;
408 if (single_ifile) jcamera = icamera;
else jcamera =
l1rec->iscan %
N_CAMERAS;
416 VSseek(private_data->blockTimeID[jcamera], block);
417 VSread(private_data->blockTimeID[jcamera], (uint8 *) timestring, 1,
438 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
439 __LINE__,
"GeoLatitude",
l1file->geofile);
445 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
446 __LINE__,
"GeoLongitude",
l1file->geofile);
454 recnum_gp = (
recnum - 8) / 16;
455 if (recnum_gp != last_recnum_gp &&
recnum >= 8) {
473 for (
i=0;
i<32;
i++) {
474 dbl_data[
i] = private_data->SolAzimuth[recnum_gp+0][
i];
475 if (dbl_data[
i] >= 0 && dbl_data[
i] < 180)
476 dbl_data[
i] = dbl_data[
i] + 360;
477 dbl_data[
i+32] = private_data->SolAzimuth[recnum_gp+1][
i];
478 if (dbl_data[
i+32] >= 0 && dbl_data[
i+32] < 180)
479 dbl_data[
i+32] = dbl_data[
i+32] + 360;
486 for (
i=0;
i<32;
i++) {
487 dbl_data[
i] = private_data->SolZenith[recnum_gp+0][
i];
488 dbl_data[
i+32] = private_data->SolZenith[recnum_gp+1][
i];
500 if (sd_id[
j] == -1)
continue;
502 for (
i=0;
i<32;
i++) {
504 if ( private_data->SenAzimuth[
j][recnum_gp+0][
i] > 0)
505 dbl_xy[
i] = cos(private_data->SenAzimuth[
j][recnum_gp+0][
i]*
D2R);
507 if ( private_data->SenAzimuth[
j][recnum_gp+1][
i] > 0)
508 dbl_xy[
i+32] = cos(private_data->SenAzimuth[
j][recnum_gp+1][
i]*
D2R);
512 for (
i=0;
i<32;
i++) {
514 if ( private_data->SenAzimuth[
j][recnum_gp+0][
i] > 0)
515 dbl_xy[
i] = sin(private_data->SenAzimuth[
j][recnum_gp+0][
i]*
D2R);
517 if ( private_data->SenAzimuth[
j][recnum_gp+1][
i] > 0)
518 dbl_xy[
i+32] = sin(private_data->SenAzimuth[
j][recnum_gp+1][
i]*
D2R);
522 for (
i=0;
i<16;
i++) {
523 for (
k=0;
k<512;
k++) {
524 if ( xy_interp_data[1][
i][
k] != -555 &&
525 xy_interp_data[0][
i][
k] != -555)
526 sna_interp_data[
j][
i][
k] = atan2(xy_interp_data[1][
i][
k],
527 xy_interp_data[0][
i][
k]) /
D2R;
529 sna_interp_data[
j][
i][
k] = -555;
539 if (sd_id[
j] == -1)
continue;
540 for (
i=0;
i<32;
i++) {
541 dbl_data[
i] = private_data->SenZenith[
j][recnum_gp+0][
i];
542 dbl_data[
i+32] = private_data->SenZenith[
j][recnum_gp+1][
i];
547 last_recnum_gp = recnum_gp;
556 start[0] = recnum_red / 512;
566 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
567 __LINE__,
"Red Radiance/RDQI",
l1file->name);
570 usptr = &rad_data[2][0][0];
575 if ((jcamera+1) != 5) {
585 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
586 __LINE__,
"Blue Radiance/RDQI",
l1file->name);
589 usptr = &rad_data[0][0][0];
591 if ((jcamera+1) == 5)
reduce_res(rad_data[0]);
597 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
598 __LINE__,
"Green Radiance/RDQI",
l1file->name);
601 usptr = &rad_data[1][0][0];
603 if ((jcamera+1) == 5)
reduce_res(rad_data[1]);
608 printf(
"-E- %s line %d: Error reading SDS %s from %s.\n", __FILE__,
609 __LINE__,
"NIR Radiance/RDQI",
l1file->name);
612 usptr = &rad_data[3][0][0];
614 if ((jcamera+1) == 5)
reduce_res(rad_data[3]);
618 for (
size_t ip=8; ip<504; ++ip) {
619 if (rad_data[0][0][ip] < 16378)
620 l1rec->Lt[4*ip+0] = rad_data[0][0][ip]*private_data->radScaleFactors[0];
621 if (rad_data[1][0][ip] < 16378)
622 l1rec->Lt[4*ip+1] = rad_data[1][0][ip]*private_data->radScaleFactors[1];
623 if (rad_data[2][0][ip] < 16378)
624 l1rec->Lt[4*ip+2] = rad_data[2][0][ip]*private_data->radScaleFactors[2];
625 if (rad_data[3][0][ip] < 16378)
626 l1rec->Lt[4*ip+3] = rad_data[3][0][ip]*private_data->radScaleFactors[3];
630 for (
size_t ip=8; ip<504; ++ip) {
631 if (sla_interp_data[gp_index][ip] != -555) {
632 l1rec->sola[ip] = sla_interp_data[gp_index][ip];
637 if (slz_interp_data[gp_index][ip] != -555) {
638 l1rec->solz[ip] = slz_interp_data[gp_index][ip];
642 if (sna_interp_data[jcamera][gp_index][ip] != -555) {
643 l1rec->sena[ip] = sna_interp_data[jcamera][gp_index][ip];
648 if (snz_interp_data[jcamera][gp_index][ip] != -555) {
649 l1rec->senz[ip] = snz_interp_data[jcamera][gp_index][ip];
653 if (sla_interp_data[gp_index][ip] != -555 &&
654 sna_interp_data[jcamera][gp_index][ip] != -555) {
657 if (
l1rec->delphi[ip] < -180.)
658 l1rec->delphi[ip] += 360.0;
659 else if (
l1rec->delphi[ip] > 180.0)
660 l1rec->delphi[ip] -= 360.0;
672 int interp_values(
double *grid_values,
double interpolated_values[16][512]) {
674 const gsl_interp2d_type *T = gsl_interp2d_bilinear;
675 static gsl_spline2d *
spline;
676 static gsl_interp_accel *xacc, *yacc;
677 static double xa[32], ya[2];
679 double dbl_data[2*32];
688 spline = gsl_spline2d_alloc(T, 32, 2);
689 xacc = gsl_interp_accel_alloc();
690 yacc = gsl_interp_accel_alloc();
692 for (
size_t i=0;
i<32;
i++) xa[
i] = 7.5 + 16*
i;
699 for (
size_t i=0;
i<32;
i++) {
700 gsl_spline2d_set(
spline, dbl_data,
i, 0, grid_values[
i]);
701 gsl_spline2d_set(
spline, dbl_data,
i, 1, grid_values[
i+32]);
704 gsl_spline2d_init(
spline, xa, ya, dbl_data, 32, 2);
713 for (
size_t j=0;
j<16; ++
j) {
715 for (
size_t i=8;
i<504; ++
i) {
718 if (grid_values[(
i-8)/16] == -111 || grid_values[(
i-8)/16] == -222 ||
719 grid_values[(
i-8)/16] == -333 || grid_values[(
i-8)/16] == -444 ||
720 grid_values[(
i-8)/16] == -555 || grid_values[(
i-8)/16] == -999 ||
722 grid_values[(
i-8)/16+1] == -111 || grid_values[(
i-8)/16+1] == -222 ||
723 grid_values[(
i-8)/16+1] == -333 || grid_values[(
i-8)/16+1] == -444 ||
724 grid_values[(
i-8)/16+1] == -555 || grid_values[(
i-8)/16+1] == -999 ||
726 grid_values[(
i-8)/16+32] == -111 || grid_values[(
i-8)/16+32] == -222 ||
727 grid_values[(
i-8)/16+32] == -333 || grid_values[(
i-8)/16+32] == -444 ||
728 grid_values[(
i-8)/16+32] == -555 || grid_values[(
i-8)/16+32] == -999 ||
730 grid_values[(
i-8)/16+32+1] == -111 || grid_values[(
i-8)/16+32+1] == -222 ||
731 grid_values[(
i-8)/16+32+1] == -333 || grid_values[(
i-8)/16+32+1] == -444 ||
732 grid_values[(
i-8)/16+32+1] == -555 || grid_values[(
i-8)/16+32+1] == -999)
734 interpolated_values[
j][
i] = -555;
736 interpolated_values[
j][
i] =
737 gsl_spline2d_eval(
spline, xi, yi, xacc, yacc);
748 double interpolated_values[16][512]) {
750 double dbl_data[2*32];
752 if (diff_offset == 0) {
753 for (
size_t i=0;
i<32;
i++) {
754 gsl_spline2d_set(spline_misr, dbl_data,
i, 0, (
double) grid_values[
i]);
755 gsl_spline2d_set(spline_misr, dbl_data,
i, 1, (
double) grid_values[
i+32]);
758 gsl_spline2d_init(spline_misr, xa, ya, dbl_data, 32, 2);
760 for (
size_t j=0;
j<16; ++
j) {
762 for (
size_t i=8;
i<504; ++
i) {
765 interpolated_values[
j][
i] =
766 gsl_spline2d_eval(spline_misr, xi, yi, xacc, yacc);
769 }
else if (diff_offset == -1) {
771 for (
size_t i=0;
i<32;
i++)
772 gsl_spline2d_set(spline_misr, dbl_data,
i, 0, (
double) grid_values[
i]);
773 for (
size_t i=0;
i<31;
i++)
774 gsl_spline2d_set(spline_misr, dbl_data,
i+1, 1,
775 (
double) grid_values[
i+32]);
777 for (
size_t j=0;
j<8; ++
j) {
779 for (
size_t i=8;
i<504; ++
i) {
782 interpolated_values[
j][
i] =
783 gsl_spline2d_eval(spline_misr, xi, yi, xacc, yacc);
787 for (
size_t i=0;
i<32;
i++)
788 gsl_spline2d_set(spline_misr, dbl_data,
i, 0, (
double) grid_values[
i]);
789 for (
size_t i=0;
i<32;
i++)
790 gsl_spline2d_set(spline_misr, dbl_data,
i, 1,
791 (
double) grid_values[
i+32]);
794 for (
size_t i=1;
i<32;
i++)
795 gsl_spline2d_set(spline_misr, dbl_data,
i-1, 1,
796 (
double) grid_values[
i]);
798 for (
size_t j=0;
j<16; ++
j) {
800 for (
size_t i=8;
i<504; ++
i) {
803 interpolated_values[
j][
i] =
804 gsl_spline2d_eval(spline_misr, xi, yi, xacc, yacc);
817 static gsl_matrix *X, *cov;
818 static gsl_vector *
y, *w, *
c;
820 static gsl_multifit_linear_workspace *work;
826 X = gsl_matrix_alloc (16, 3);
827 y = gsl_vector_alloc (16);
828 w = gsl_vector_alloc (16);
830 c = gsl_vector_alloc (3);
831 cov = gsl_matrix_alloc (3, 3);
833 work = gsl_multifit_linear_alloc (16, 3);
835 for (
size_t i=0;
i<16;
i++) {
836 gsl_matrix_set (X,
i, 0, 1.0);
842 double x_val = col - 1.5;
843 double y_val = 1.5 - row;
845 gsl_matrix_set (X,
i, 1, x_val);
846 gsl_matrix_set (X,
i, 2, y_val);
852 for (
size_t ip=0; ip<512; ip++) {
854 for (
size_t irow=0; irow<4; irow++) {
855 for (
size_t icol=0; icol<4; icol++) {
856 int index = irow*4+icol;
857 double d_val = (
double) rad_data[irow][4*ip+icol];
858 gsl_vector_set (
y,
index, d_val);
859 if (rad_data[irow][4*ip+icol] >= 16378) {
860 gsl_vector_set (w,
index, 0.0);
862 gsl_vector_set (w,
index, 1.0);
883 gsl_multifit_wlinear (X, w,
y,
c, cov, &chisq, work);
884 double fit_val = gsl_vector_get(
c,0);
885 rad_data[0][ip] = (
ushort) ( fit_val + 0.5);
887 rad_data[0][ip] = 16378;
903 if (sd_id[
i] == -1)
continue;
904 SDendaccess(blu_id[
i]);
905 SDendaccess(grn_id[
i]);
906 SDendaccess(red_id[
i]);
907 SDendaccess(nir_id[
i]);