25 #define SATURATION_BIT 1
28 static int extract_pixel_start = 0;
29 static int use_rhot = 0;
31 static int bad_num_bands = 0;
33 static short *tmpShort;
36 static size_t expected_num_blue_bands = 119;
37 static size_t expected_num_red_bands = 163;
38 static size_t expected_num_SWIR_bands = 9;
40 static size_t num_scans, num_pixels;
41 static size_t num_blue_bands, num_red_bands, num_SWIR_bands;
42 static size_t tot_num_bands = 286;
46 static double *scan_time;
47 static double file_start_day;
49 static unsigned char *scanQual;
50 static uint8_t *hamside;
53 static int geolocationGrp;
54 static int lonId, latId, heightId, senzId, senaId, solzId, solaId;
55 static float latFillValue =
BAD_FLT;
56 static float lonFillValue =
BAD_FLT;
57 static short heightFillValue =
BAD_FLT;
58 static short senzFillValue =
BAD_FLT;
59 static float senzScale = 0.01;
60 static float senzOffset = 0.0;
61 static short senaFillValue =
BAD_FLT;
62 static float senaScale = 0.01;
63 static float senaOffset = 0.0;
64 static short solzFillValue =
BAD_FLT;
65 static float solzScale = 0.01;
66 static float solzOffset = 0.0;
67 static short solaFillValue =
BAD_FLT;
68 static float solaScale = 0.01;
69 static float solaOffset = 0.0;
72 static int observationGrp,navigationGrp;
73 static int Lt_blueId, Lt_redId, Lt_SWIRId, tiltId, qual_SWIRId;
74 static float **Lt_blue;
75 static float **Lt_red;
76 static float **Lt_SWIR;
77 static float Lt_blueFillValue =
BAD_FLT;
78 static float Lt_redFillValue =
BAD_FLT;
79 static float Lt_SWIRFillValue =
BAD_FLT;
80 static float tiltFillValue =
BAD_FLT;
81 static uint8_t **qual_SWIR;
82 static float *blue_solar_irradiance;
83 static float *red_solar_irradiance;
84 static float *SWIR_solar_irradiance;
85 static double earth_sun_distance_correction;
103 printf(
"Opening OCI L1B file\n");
104 status = nc_open(
file->name, NC_NOWRITE, &ncid_L1B);
106 fprintf(
stderr,
"-E- %s line %d: nc_open(%s) failed.\n",
107 __FILE__, __LINE__,
file->name);
112 status = nc_inq_dimid(ncid_L1B,
"scans", &dimid);
115 if (nc_inq_dimid(ncid_L1B,
"number_of_scans", &dimid) != NC_NOERR) {
116 fprintf(
stderr,
"-E- Error reading scan dimension.\n");
120 nc_inq_dimlen(ncid_L1B, dimid, &num_scans);
123 status = nc_inq_dimid(ncid_L1B,
"pixels", &dimid);
126 if (nc_inq_dimid(ncid_L1B,
"ccd_pixels", &dimid)) {
127 fprintf(
stderr,
"-E- Error reading num_pixels.\n");
131 nc_inq_dimlen(ncid_L1B, dimid, &num_pixels);
134 status = nc_inq_dimid(ncid_L1B,
"blue_bands", &dimid);
136 fprintf(
stderr,
"-E- Error reading num_blue_bands.\n");
139 nc_inq_dimlen(ncid_L1B, dimid, &num_blue_bands);
140 if(num_blue_bands < expected_num_blue_bands) {
141 fprintf(
stderr,
"-W- Not enough blue bands, expecting %d, found %d.\n",
142 (
int)expected_num_blue_bands, (
int)num_blue_bands);
147 status = nc_inq_dimid(ncid_L1B,
"red_bands", &dimid);
149 fprintf(
stderr,
"-E- Error reading num_red_bands.\n");
152 nc_inq_dimlen(ncid_L1B, dimid, &num_red_bands);
153 if(num_red_bands < expected_num_red_bands) {
154 fprintf(
stderr,
"-W- Not enough red bands, expecting %d, found %d.\n",
155 (
int)expected_num_red_bands, (
int)num_red_bands);
160 status = nc_inq_dimid(ncid_L1B,
"SWIR_bands", &dimid);
162 fprintf(
stderr,
"-E- Error reading num_SWIR_bands.\n");
165 nc_inq_dimlen(ncid_L1B, dimid, &num_SWIR_bands);
166 if(num_SWIR_bands < expected_num_SWIR_bands) {
167 fprintf(
stderr,
"-E- Not enough SWIR bands, expecting %d, found %d.\n",
168 (
int)expected_num_SWIR_bands, (
int)num_SWIR_bands);
173 printf(
"OCI L1B Npix :%d Nlines:%d\n", (
int)num_pixels, (
int)num_scans);
177 tmpShort = (
short*) malloc(num_pixels *
sizeof(
short));
178 scan_time = (
double*) malloc(num_scans *
sizeof(
double));
183 tilt = (
float*) malloc(num_scans *
sizeof(
float));
184 hamside = (uint8_t *) malloc(num_scans *
sizeof(uint8_t));
185 scanQual = (
unsigned char *) malloc(num_scans *
sizeof(
unsigned char));
190 if ((nc_inq_grp_ncid(ncid_L1B,
"scan_line_attributes", &scanLineGrp)) == NC_NOERR) {
192 fprintf(
stderr,
"-E- Error finding scan_line_attributes.\n");
196 double scan_timeFillValue =
BAD_FLT;
197 status = nc_inq_varid(scanLineGrp,
"time", &varId);
199 status = nc_inq_var_fill(scanLineGrp, varId,
NULL, &scan_timeFillValue);
201 status = nc_get_var_double(scanLineGrp, varId, scan_time);
204 status = nc_inq_varid(scanLineGrp,
"ev_mid_time", &varId);
206 status = nc_inq_var_fill(scanLineGrp, varId,
NULL, &scan_timeFillValue);
208 status = nc_get_var_double(scanLineGrp, varId, scan_time);
213 status = nc_inq_varid(scanLineGrp,
"HAM_side", &varId);
214 if( (
status = nc_inq_varid(scanLineGrp,
"HAM_side", &varId) ) == NC_NOERR) {
215 status = nc_get_var_ubyte(scanLineGrp, varId, hamside);
218 fprintf(
stderr,
"-E- Error reading the HAM side data.\n");
223 status = nc_inq_varid(scanLineGrp,
"scan_quality_flags", &varId);
224 if( (
status = nc_inq_varid(scanLineGrp,
"scan_quality_flags", &varId) ) == NC_NOERR) {
225 status = nc_get_var_uchar(scanLineGrp, varId, scanQual);
228 fprintf(
stderr,
"-E- Error reading the scan quality flags.\n");
234 status = nc_inq_attlen(ncid_L1B, NC_GLOBAL,
"time_coverage_start", &att_len);
238 char*
time_str = (
char *) malloc(att_len + 1);
241 status = nc_get_att_text(ncid_L1B, NC_GLOBAL,
"time_coverage_start",
time_str);
253 for(
int i=0;
i<num_scans;
i++) {
254 if(scan_time[
i] == scan_timeFillValue)
259 status = nc_inq_grp_ncid(ncid_L1B,
"geolocation_data", &geolocationGrp);
261 status = nc_inq_varid(geolocationGrp,
"longitude", &lonId);
263 status = nc_inq_var_fill(geolocationGrp, lonId,
NULL, &lonFillValue);
265 status = nc_inq_varid(geolocationGrp,
"latitude", &latId);
267 status = nc_inq_var_fill(geolocationGrp, latId,
NULL, &latFillValue);
269 status = nc_inq_varid(geolocationGrp,
"height", &heightId);
271 status = nc_inq_var_fill(geolocationGrp, heightId,
NULL, &heightFillValue);
274 status = nc_inq_varid(geolocationGrp,
"sensor_zenith", &senzId);
276 status = nc_inq_var_fill(geolocationGrp, senzId,
NULL, &senzFillValue);
278 status = nc_get_att_float(geolocationGrp, senzId,
"scale_factor", &senzScale);
281 status = nc_get_att_float(geolocationGrp, senzId,
"add_offset", &senzOffset);
285 status = nc_inq_varid(geolocationGrp,
"sensor_azimuth", &senaId);
287 status = nc_inq_var_fill(geolocationGrp, senaId,
NULL, &senaFillValue);
289 status = nc_get_att_float(geolocationGrp, senaId,
"scale_factor", &senaScale);
292 status = nc_get_att_float(geolocationGrp, senaId,
"add_offset", &senaOffset);
296 status = nc_inq_varid(geolocationGrp,
"solar_zenith", &solzId);
298 status = nc_inq_var_fill(geolocationGrp, solzId,
NULL, &solzFillValue);
300 status = nc_get_att_float(geolocationGrp, solzId,
"scale_factor", &solzScale);
303 status = nc_get_att_float(geolocationGrp, solzId,
"add_offset", &solzOffset);
307 status = nc_inq_varid(geolocationGrp,
"solar_azimuth", &solaId);
309 status = nc_inq_var_fill(geolocationGrp, solaId,
NULL, &solaFillValue);
311 status = nc_get_att_float(geolocationGrp, solaId,
"scale_factor", &solaScale);
314 status = nc_get_att_float(geolocationGrp, solaId,
"add_offset", &solaOffset);
320 status = nc_inq_grp_ncid(ncid_L1B,
"observation_data", &observationGrp);
324 status = nc_inq_varid(observationGrp,
"Lt_blue", &Lt_blueId);
328 status = nc_inq_var_fill(observationGrp, Lt_blueId,
NULL, &Lt_blueFillValue);
331 status = nc_inq_varid(observationGrp,
"Lt_red", &Lt_redId);
333 status = nc_inq_var_fill(observationGrp, Lt_redId,
NULL, &Lt_redFillValue);
336 status = nc_inq_varid(observationGrp,
"Lt_SWIR", &Lt_SWIRId);
338 status = nc_inq_var_fill(observationGrp, Lt_SWIRId,
NULL, &Lt_SWIRFillValue);
343 status = nc_inq_varid(observationGrp,
"rhot_blue", &Lt_blueId);
345 status = nc_inq_var_fill(observationGrp, Lt_blueId,
NULL, &Lt_blueFillValue);
348 status = nc_inq_varid(observationGrp,
"rhot_red", &Lt_redId);
350 status = nc_inq_var_fill(observationGrp, Lt_redId,
NULL, &Lt_redFillValue);
353 status = nc_inq_varid(observationGrp,
"rhot_SWIR", &Lt_SWIRId);
355 status = nc_inq_var_fill(observationGrp, Lt_SWIRId,
NULL, &Lt_SWIRFillValue);
359 status = nc_inq_grp_ncid(ncid_L1B,
"navigation_data", &navigationGrp);
361 status = nc_inq_varid(navigationGrp,
"tilt_angle", &tiltId);
363 status = nc_inq_varid(navigationGrp,
"tilt", &tiltId);
367 status = nc_inq_var_fill(navigationGrp, tiltId,
NULL, &tiltFillValue);
369 status = nc_get_var_float(navigationGrp,tiltId,
tilt);
372 status = nc_inq_varid(observationGrp,
"qual_SWIR", &qual_SWIRId);
378 status = nc_get_att_double(ncid_L1B, NC_GLOBAL,
"earth_sun_distance_correction", &earth_sun_distance_correction);
383 blue_solar_irradiance = malloc(num_blue_bands *
sizeof(
float));
384 red_solar_irradiance = malloc(num_red_bands *
sizeof(
float));
385 SWIR_solar_irradiance = malloc(num_SWIR_bands *
sizeof(
float));
386 status = nc_inq_grp_ncid(ncid_L1B,
"sensor_band_parameters", &sensorBandGrp);
389 status = nc_inq_varid(sensorBandGrp,
"blue_solar_irradiance", &tmpId);
391 status = nc_get_var_float(sensorBandGrp, tmpId, blue_solar_irradiance);
394 status = nc_inq_varid(sensorBandGrp,
"red_solar_irradiance", &tmpId);
396 status = nc_get_var_float(sensorBandGrp, tmpId, red_solar_irradiance);
399 status = nc_inq_varid(sensorBandGrp,
"SWIR_solar_irradiance", &tmpId);
401 status = nc_get_var_float(sensorBandGrp, tmpId, SWIR_solar_irradiance);
405 file->sd_id = ncid_L1B;
406 file->nbands = tot_num_bands;
407 file->npix = num_pixels;
408 file->nscan = num_scans;
410 file->terrain_corrected = 1;
414 printf(
"file->nbands = %d\n", (
int)
file->nbands);
437 size_t start[] = { 0, 0, 0 };
438 size_t count[] = { 1, 1, 1 };
440 for (
int ip = 0; ip < num_pixels; ip++) {
441 l1rec->pixnum[ip] = ip + extract_pixel_start;
448 l1rec->scantime = file_start_day + scan_time[
line];
459 int32_t
msec = (int32_t) (secs * 1000.0);
468 count[1] = num_pixels;
481 for(
int i=0;
i<num_pixels;
i++) {
482 if(
l1rec->lat[
i] == latFillValue)
484 if(
l1rec->lon[
i] == lonFillValue)
488 if(scanQual[
line] & 1) {
489 for(
int i=0;
i<num_pixels;
i++)
495 for(
int i=0;
i<num_pixels;
i++) {
496 if(tmpShort[
i] == solzFillValue)
499 l1rec->solz[
i] = tmpShort[
i] * solzScale + solzOffset;
508 fprintf(
stderr,
"-E- Bad number of bands\n");
514 for(
int i=0;
i<num_pixels;
i++) {
515 if(tmpShort[
i] == senaFillValue)
518 l1rec->sena[
i] = tmpShort[
i] * senaScale + senaOffset;
523 for(
int i=0;
i<num_pixels;
i++) {
524 if(tmpShort[
i] == senzFillValue)
527 l1rec->senz[
i] = tmpShort[
i] * senzScale + senzOffset;
532 for(
int i=0;
i<num_pixels;
i++) {
533 if(tmpShort[
i] == solaFillValue)
536 l1rec->sola[
i] = tmpShort[
i] * solaScale + solaOffset;
543 count[0] = expected_num_blue_bands;
545 count[2] = num_pixels;
546 status = nc_get_vara_float(observationGrp, Lt_blueId,
start,
count, Lt_blue[0]);
549 count[0] = expected_num_red_bands;
550 status = nc_get_vara_float(observationGrp, Lt_redId,
start,
count, Lt_red[0]);
553 count[0] = expected_num_SWIR_bands;
554 status = nc_get_vara_float(observationGrp, Lt_SWIRId,
start,
count, Lt_SWIR[0]);
557 status = nc_get_vara_ubyte(observationGrp, qual_SWIRId,
start,
count, qual_SWIR[0]);
560 for(
int ip=0; ip<num_pixels; ip++) {
563 int ipb = ip * tot_num_bands;
567 if(Lt_blue[
band][ip] == Lt_blueFillValue) {
573 l1rec->Lt[ipb] *= blue_solar_irradiance[
band] * cos(
l1rec->solz[ip]/
RADEG) / earth_sun_distance_correction /
M_PI / 10.0;
575 l1rec->Lt[ipb] /= 10.;
584 if(Lt_red[
band][ip] == Lt_redFillValue) {
590 l1rec->Lt[ipb] *= red_solar_irradiance[
band] * cos(
l1rec->solz[ip]/
RADEG) / earth_sun_distance_correction /
M_PI / 10.0;
592 l1rec->Lt[ipb] /= 10.;
613 if((
band==2 ||
band==5) && !saturated)
615 else if((
band==3 ||
band==6) && saturated)
618 if(Lt_SWIR[
band][ip] == Lt_SWIRFillValue) {
624 l1rec->Lt[ipb] *= SWIR_solar_irradiance[
band] * cos(
l1rec->solz[ip]/
RADEG) / earth_sun_distance_correction /
M_PI / 10.0;
626 l1rec->Lt[ipb] /= 10.;
646 printf(
"Closing oci l1b file\n");
652 if (tmpShort) free(tmpShort);
653 if (scan_time) free(scan_time);
654 if (hamside) free(hamside);
656 if (scanQual) free(scanQual);
661 if (blue_solar_irradiance) free(blue_solar_irradiance);
662 if (red_solar_irradiance) free(red_solar_irradiance);
663 if (SWIR_solar_irradiance) free(SWIR_solar_irradiance);