NASA Logo
Ocean Color Science Software

ocssw V2022
l1_oli.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <stdio.h>
3 
4 #include "l1.h"
5 #include "l1_oli.h"
6 
7 #include <tiffio.h>
8 #include <geotiff.h>
9 #include <xtiffio.h>
10 #include <geo_normalize.h>
11 #include <filetype.h>
12 #include <libnav.h>
13 #include <libgen.h>
14 #include "xcal.h"
15 
16 static const int itemSize = 500;
17 static const int maxReflBands = 8;
18 static float *Fobar;
19 // following added by Sudipta for FPM based correction
20 static double *xcal_factor = NULL; /* xcal factors for each FPM and band */
21 static int tile_exist;
22 static uint32_t tileLength = 0;
23 static uint32_t tileWidth = 0;
24 static uint32_t imageWidth = 0;
25 
26 typedef struct oli_struct {
27  int32_t year, doy, msec;
29  double *lat, *lon;
30  double *scale, *offset;
33  TIFF** tif; // file handle for each band
34  GTIF* gtif; // geotiff handle for the first file
35  GTIFDefn* defn; // geotiff definition structure for first file
36  uint16_t* buf_tile_row; // buffer used to read a row of tile * 9 bands from TIFF file
37  uint16_t* buf; // buffer used to read one scan line from TIFF file
38 } oli_t;
39 
40 oli_t* createPrivateData(int numBands) {
41  int i;
42 
43  oli_t* data = (oli_t*) calloc(1, sizeof (oli_t));
44  if (data == NULL) {
45  fprintf(stderr, "-E- %s line %d: unable to allocate private data for OLI\n",
46  __FILE__, __LINE__);
47  exit(1);
48  }
49 
50  data->scale = (double *) malloc(numBands * sizeof (double));
51  data->offset = (double *) malloc(numBands * sizeof (double));
52  if (data->scale == NULL || data->offset == NULL) {
53  fprintf(stderr, "-E- %s line %d: unable to allocate scale/offset data for OLI\n",
54  __FILE__, __LINE__);
55  exit(1);
56  }
57 
58  data->refl_scale = (double *) malloc(numBands * sizeof (double));
59  data->refl_offset = (double *) malloc(numBands * sizeof (double));
60  if (data->refl_scale == NULL || data->refl_offset == NULL) {
61  fprintf(stderr, "-E- %s line %d: unable to allocate reflectance scale/offset data for OLI\n",
62  __FILE__, __LINE__);
63  exit(1);
64  }
65 
66  for (i = 0; i < numBands; i++) {
67  data->scale[i] = BAD_FLT;
68  data->offset[i] = BAD_FLT;
69  data->refl_scale[i] = BAD_FLT;
70  data->refl_offset[i] = BAD_FLT;
71  }
72 
73  data->tif = (TIFF**) calloc(numBands, sizeof (TIFF*));
74  if (data->tif == NULL) {
75  fprintf(stderr, "-E- %s line %d: unable to allocate TIFF pointers for OLI\n",
76  __FILE__, __LINE__);
77  exit(1);
78  }
79 
80  data->defn = (GTIFDefn*) malloc(sizeof (GTIFDefn));
81  if (data->defn == NULL) {
82  fprintf(stderr, "-E- %s line %d: unable to allocate GEOTIFF definition structure for OLI\n",
83  __FILE__, __LINE__);
84  exit(1);
85  }
86 
87  data->line_num_cached = -1; //
88 
89  return data;
90 }
91 
92 void freePrivateData(oli_t* data) {
93  free(data->scale);
94  free(data->offset);
95  free(data->refl_scale);
96  free(data->refl_offset);
97  free(data->tif);
98  free(data->defn);
99  free(data);
100 }
101 
102 int readNextLine(FILE* fp, char* tag, int* i, char* val) {
103  char* result;
104  char line[itemSize];
105  int count;
106 
107  result = fgets(line, itemSize, fp);
108  if (result == NULL) {
109  return 0;
110  }
111  trimBlanks(line);
112 
113  count = sscanf(line, "%s = %s", tag, val);
114  if (count != 2) {
115  // not found so return blank line
116  tag[0] = 0;
117  *i = 0;
118  val[0] = 0;
119  return 1;
120  }
121 
122  // grab index if it exists
123  result = strrchr(tag, '_');
124  if (result) {
125  result++;
126  *i = atoi(result);
127  } else {
128  *i = 0;
129  }
130 
131  // get rid of the quotes from val
132  if (val[0] == '"')
133  val[0] = ' ';
134  count = strlen(val) - 1;
135  if (val[count] == '"')
136  val[count] = 0;
137  trimBlanks(val);
138  return 1;
139 }
140 
141 int openl1_oli(filehandle *file) {
142  int i;
143  FILE *fp;
144  char tag[itemSize];
145  char val[itemSize];
146  char dateStr[32];
147  char timeStr[32];
148  char fileName[FILENAME_MAX];
149 
150  oli_t* data = file->private_data = createPrivateData(maxReflBands);
151 
152  if (want_verbose)
153  printf("OLI Level-1B %s\n", file->name);
154 
155  /* Open file */
156  if ((fp = fopen(file->name, "r")) == NULL) {
157  fprintf(stderr, "-E- %s line %d: unable open %s\n",
158  __FILE__, __LINE__, file->name);
159  exit(1);
160  }
161 
162  int collectionNumber = 0;
163  int dateFound = 0;
164  int timeFound = 0;
165  int numLinesFound = 0;
166  int numSamplesFound = 0;
167  int sunAzimuthFound = 0;
168  int sunElevationFound = 0;
169  int angleFileFound = 0;
170 
171  // loop metadata
172  while (readNextLine(fp, tag, &i, val)) {
173 
174  // skip blank lines
175  if (tag[0] == 0)
176  continue;
177 
178  // get collection number
179  if (!strcmp(tag, "COLLECTION_NUMBER")) {
180  collectionNumber = atoi(val);
181  if (want_verbose)
182  printf("OLI Level-1B Collection %d\n", collectionNumber);
183 
184  // get date
185  } else if (!strcmp(tag, "DATE_ACQUIRED")) {
186  dateFound = 1;
187  strcpy(dateStr, val);
188 
189  // get time
190  } else if (!strcmp(tag, "SCENE_CENTER_TIME")) {
191  timeFound = 1;
192  strcpy(timeStr, val);
193 
194  // get num lines
195  } else if (!strcmp(tag, "REFLECTIVE_LINES")) {
196  numLinesFound = 1;
197  file->nscan = atoi(val);
198 
199  // get num samples
200  } else if (!strcmp(tag, "REFLECTIVE_SAMPLES")) {
201  numSamplesFound = 1;
202  file->npix = atoi(val);
203 
204  // get band file names
205  } else if (!strncmp(tag, "FILE_NAME_BAND_", 15)) {
206  i--;
207  if ((i >= 0 && i < file->nbands) || i == 8) {
208  // dirname might destroy input, so we pass it a copy
209  char dir[FILENAME_MAX];
210  strcpy(dir, file->name);
211  strcpy(fileName, dirname(dir));
212  strcat(fileName, "/");
213  strcat(fileName, val);
214  if (want_verbose)
215  printf("OLI Level-1B Band[%d]:%s\n", i, fileName);
216  if (i != 8) {
217  data->tif[i] = XTIFFOpen(fileName, "r");
218  if (!data->tif[i]) {
219  fprintf(stderr, "-E- %s line %d: unable open TIFF file %s\n",
220  __FILE__, __LINE__, fileName);
221  exit(1);
222  }
223  }
224  else {
225  data->tif[i - 1] = XTIFFOpen(fileName, "r"); // open Band 9
226  if (!data->tif[i -1 ]) {
227  fprintf(stderr, "-E- %s line %d: unable open TIFF file %s\n",
228  __FILE__, __LINE__, fileName);
229  exit(1);
230  }
231  }
232  }
233 
234  // get geofile name
235  } else if (!strcmp(tag, "ANGLE_COEFFICIENT_FILE_NAME") || !strcmp(tag, "FILE_NAME_ANGLE_COEFFICIENT")) {
236  angleFileFound = 1;
237  if ((file->geofile == NULL) || (file->geofile[0] == 0)) {
238  // dirname might destroy input, so we pass it a copy
239  char dir[FILENAME_MAX];
240  strcpy(dir, file->name);
241  strcpy(fileName, dirname(dir));
242  strcat(fileName, "/");
243  strcat(fileName, val);
244  file->geofile = strdup(fileName);
245  if (want_verbose)
246  printf("OLI Level-1B Angle File:%s\n", fileName);
247  }
248 
249  // get sun azimuth
250  } else if (!strcmp(tag, "SUN_AZIMUTH")) {
251  sunAzimuthFound = 1;
252  data->sunAzimuth = atof(val);
253 
254  // get sun elevation
255  } else if (!strcmp(tag, "SUN_ELEVATION")) {
256  sunElevationFound = 1;
257  data->sunElevation = atof(val);
258 
259  // get refl_scale
260  } else if (!strncmp(tag, "REFLECTANCE_MULT_BAND_", 22)) {
261  i--;
262  if (i >= 0 && i < maxReflBands) {
263  data->refl_scale[i] = atof(val);
264  }
265 
266  // get refl_offset
267  } else if (!strncmp(tag, "REFLECTANCE_ADD_BAND_", 21)) {
268  i--;
269  if (i >= 0 && i < maxReflBands) {
270  data->refl_offset[i] = atof(val);
271  }
272 
273  } else if (!strncmp(tag, "RADIANCE_MULT_BAND_", 19)) {
274  i--;
275  if (i >= 0 && i < maxReflBands) {
276  data->scale[i] = atof(val);
277  }
278 
279  // get offset
280  } else if (!strncmp(tag, "RADIANCE_ADD_BAND_", 18)) {
281  i--;
282  if (i >= 0 && i < maxReflBands) {
283  data->offset[i] = atof(val);
284  }
285  }
286 
287  } // while
288 
289  fclose(fp);
290 
291  if (!dateFound) {
292  fprintf(stderr, "-E- %s line %d: Did not find DATE_ACQUIRED in %s\n",
293  __FILE__, __LINE__, file->name);
294  exit(EXIT_FAILURE);
295  }
296  if (!timeFound) {
297  fprintf(stderr, "-E- %s line %d: Did not find SCENE_CENTER_TIME in %s\n",
298  __FILE__, __LINE__, file->name);
299  exit(EXIT_FAILURE);
300  }
301  if (!numLinesFound) {
302  fprintf(stderr, "-E- %s line %d: Did not find REFLECTIVE_LINES in %s\n",
303  __FILE__, __LINE__, file->name);
304  exit(EXIT_FAILURE);
305  }
306  if (!numSamplesFound) {
307  fprintf(stderr, "-E- %s line %d: Did not find REFLECTIVE_SAMPLES in %s\n",
308  __FILE__, __LINE__, file->name);
309  exit(EXIT_FAILURE);
310  }
311  if (!sunAzimuthFound) {
312  fprintf(stderr, "-E- %s line %d: Did not find SUN_AZIMUTH in %s\n",
313  __FILE__, __LINE__, file->name);
314  exit(EXIT_FAILURE);
315  }
316  if (!sunElevationFound) {
317  fprintf(stderr, "-E- %s line %d: Did not find SUN_ELEVATION in %s\n",
318  __FILE__, __LINE__, file->name);
319  exit(EXIT_FAILURE);
320  }
321  if (collectionNumber > 0) {
322  if (!angleFileFound) {
323  fprintf(stderr, "-E- %s line %d: Did not find ANGLE_COEFFICIENT_FILE_NAME in %s\n",
324  __FILE__, __LINE__, file->name);
325  exit(EXIT_FAILURE);
326  }
327  }
328  for (i = 0; i < maxReflBands; i++) {
329  if (data->tif[i] == NULL) {
330  fprintf(stderr, "-E- %s line %d: Did not find FILE_NAME_BAND_%d in %s\n",
331  __FILE__, __LINE__, i + 1, file->name);
332  exit(EXIT_FAILURE);
333  }
334  if (data->scale[i] == BAD_FLT) {
335  fprintf(stderr, "-E- %s line %d: Did not find RADIANCE_MULT_BAND_%d in %s\n",
336  __FILE__, __LINE__, i + 1, file->name);
337  exit(EXIT_FAILURE);
338  }
339  if (data->offset[i] == BAD_FLT) {
340  fprintf(stderr, "-E- %s line %d: Did not find RADIANCE_ADD_BAND_%d in %s\n",
341  __FILE__, __LINE__, i + 1, file->name);
342  exit(EXIT_FAILURE);
343  }
344  if (data->refl_scale[i] == BAD_FLT) {
345  fprintf(stderr, "-E- %s line %d: Did not find REFLECTANCE_MULT_BAND_%d in %s\n",
346  __FILE__, __LINE__, i + 1, file->name);
347  exit(EXIT_FAILURE);
348  }
349  if (data->refl_offset[i] == BAD_FLT) {
350  fprintf(stderr, "-E- %s line %d: Did not find REFLECTANCE_ADD_BAND_%d in %s\n",
351  __FILE__, __LINE__, i + 1, file->name);
352  exit(EXIT_FAILURE);
353  }
354  }
355 
356  // allocate lat and lon storage
357  data->lat = (double *) malloc(file->npix * sizeof (double));
358  data->lon = (double *) malloc(file->npix * sizeof (double));
359  if (data->lat == NULL || data->lon == NULL) {
360  fprintf(stderr, "-E- %s line %d: unable to allocate lat/lon data for OLI\n",
361  __FILE__, __LINE__);
362  exit(1);
363  }
364 
365  // only need the GEO TIFF info from one file
366  data->gtif = GTIFNew(data->tif[0]);
367  if (!data->gtif) {
368  fprintf(stderr, "-E- %s line %d: unable open GEOTIFF file %s\n",
369  __FILE__, __LINE__, fileName);
370  exit(1);
371  }
372 
373  if (!GTIFGetDefn(data->gtif, data->defn)) {
374  fprintf(stderr, "-E- %s line %d: unable populate GEOTIFF defn structure for %s\n",
375  __FILE__, __LINE__, fileName);
376  exit(1);
377  }
378 
379  // allocate buffer to hold one scan line
380  int size = TIFFScanlineSize(data->tif[0]);
381  if (size != file->npix * 2) {
382  fprintf(stderr, "-E- %s line %d: unexpected pixel data size in %s\n",
383  __FILE__, __LINE__, fileName);
384  exit(1);
385  }
386  data->buf = (uint16_t*) malloc(size);
387 
388 
389  tile_exist = TIFFGetField(data->tif[0], TIFFTAG_TILELENGTH, &tileLength);
390 
391  if (tile_exist != 0) {
392  TIFFGetField(data->tif[0], TIFFTAG_TILEWIDTH, &tileWidth);
393  TIFFGetField(data->tif[0], TIFFTAG_IMAGEWIDTH, &imageWidth);
394  // allocate buffer to hold a row of tile * 8 bands
395  int size_tile_row = maxReflBands * tileLength * size;
396  data->buf_tile_row = (uint16_t*) malloc(size_tile_row);
397  }
398 
399  // get date "2013-07-19"
400  int year, month, day;
401  sscanf(dateStr, "%d-%d-%d", &year, &month, &day);
402 
403  // get time "10:41:59.9930740Z"
404  int hour, minute;
405  double sec;
406  sscanf(timeStr, "%d:%d:%lf", &hour, &minute, &sec);
407 
408  int isec = (int) sec;
409  ymdhms2ydmsec(year, month, day, hour, minute, isec,
410  &data->year, &data->doy, &data->msec);
411  sec -= isec;
412  data->msec += sec * 1000;
413 
414  if (want_verbose) {
415  printf("OLI Start Time: %4d-%02d-%02d %03d %02d:%02d:%f\n",
416  year, month, day, data->doy, hour, minute, sec + isec);
417 
418  printf("OLI file has %d bands, %d samples, %d lines\n",
419  file->nbands, file->npix, file->nscan);
420  }
421  strcpy(file->spatialResolution, "30 m");
422  file->terrain_corrected = 1;
423  /*
424  * get the Fobar here to set up Fo
425  */
426  rdsensorinfo(file->sensorID, l1_input->evalmask, "Fobar", (void **) &Fobar);
427 
428  return 0;
429 }
430 
431 int readl1_oli(filehandle *file, int recnum, l1str *l1rec, int lonlat) {
432  int ip, ib, ipb;
433  oli_t* data = (oli_t*) file->private_data;
434 
435  /* Sudipta new addition for OLI to extract SCA and Det numbers */
436  static short *sca_num; /* SCA number */
437  static short *det_num; /* Detector number */
438  int isb, iw;
439  static int firstCall = 1;
440  /* End Sudipta new addition for OLI */
441 
442  // set information about data
443  l1rec->npix = file->npix;
444  l1rec->scantime = yds2unix((int16_t) data->year, (int16_t) data->doy,
445  (double) (data->msec / 1000.0));
446 
447  double esdist = esdist_(&data->year, &data->doy, &data->msec);
448  double fsol = pow(1.0 / esdist, 2);
449 
450  // get lat-lon
451  for (ip = 0; ip < file->npix; ip++) {
452  data->lon[ip] = ip;
453  data->lat[ip] = recnum;
454  GTIFImageToPCS(data->gtif, data->lon + ip, data->lat + ip);
455  }
456 
457  if (!GTIFProj4ToLatLong(data->defn, file->npix, data->lon, data->lat)) {
458  fprintf(stderr, "-E- %s line %d: unable reproject points for scan %d\n",
459  __FILE__, __LINE__, recnum);
460  exit(1);
461  }
462 
463  for (ip = 0; ip < file->npix; ip++) {
464 
465  l1rec->pixnum[ip] = ip;
466 
467  if (isnan(data->lat[ip]))
468  data->lat[ip] = -999.0;
469  if (isnan(data->lon[ip]))
470  data->lon[ip] = -999.0;
471  l1rec->lat[ip] = data->lat[ip];
472  l1rec->lon[ip] = data->lon[ip];
473 
474  if (l1rec->lon[ip] < -181.0 || l1rec->lon[ip] > 181.0 ||
475  l1rec->lat[ip] < -91.0 || l1rec->lat[ip] > 91.0)
476  l1rec->navfail[ip] = 1;
477 
478  }
479 
480  // read path angles if user supplied, else use best guess
481 
482  // new addition for OLI
483  /*
484  * if required for that record, set up the geom_per_band storage
485  */
486  if ((l1_input->geom_per_band == 1) && (l1rec->geom_per_band == NULL)) {
488  // gm_p_b = l1rec->geom_per_band; // store this address so that it can be later destroyed in close()
489  }
490 
491  if (firstCall) {
492  firstCall = 0;
493  // Sudipta - new addition to read the FPM xcal file and ingest the values
494  for (iw = 0; iw < l1_input->xcal_nwave; iw++)
495  if ((l1_input->xcal_opt[iw] & XCALOLI) != 0) {
496  xcal_factor = get_fpm_xcal(l1_input->xcal_file);
497  break;
498  }
499  /* printf("geom_per_band = %d\n",l1_input->geom_per_band);
500  printf("xcal_opt = %d\n", l1_input->xcal_opt[0]);
501  printf("xcal_factor = %lf\n", xcal_factor[0]);
502  exit(0)*/;
503 
504  // allocate arrays for the sca and detector number arrays for all bands and pixels
505  /* Sudipta new addition for OLI to extract SCA and Det numbers */
506  if ((sca_num = (short *) calloc(file->npix * file->nbands, sizeof (short))) == NULL) {
507  fprintf(stderr,
508  "-E- %s line %d: Unable to allocate SCA number array.\n",
509  __FILE__, __LINE__);
510  exit(1);
511  }
512 
513  if ((det_num = (short *) calloc(file->npix * file->nbands, sizeof (short))) == NULL) {
514  free(sca_num);
515  fprintf(stderr,
516  "-E- %s line %d: Unable to allocate detector number array.\n",
517  __FILE__, __LINE__);
518  exit(1);
519  }
520  /* End Sudipta new addition for OLI */
521 
522  }
523 
524  if (file->geofile == NULL || file->geofile[0] == 0) {
525  if (get_oli_nom_angles(file->name, file->npix, file->nscan, recnum,
526  l1rec->solz, l1rec->sola, l1rec->senz, l1rec->sena, sca_num,
527  det_num, 0) == -1) {
528  fprintf(stderr, "-E- %s line %d: Unable to compute geometries\n",
529  __FILE__, __LINE__);
530  exit(1);
531  }
532  // Sudipta added sca_num and det_num to get_oli_nom_angles
533  // also added provision for band based geometry
534  // band based geometry requested
535  if (l1_input->geom_per_band) {
536  if (get_oli_nom_angles(file->name, file->npix, file->nscan, recnum,
537  l1rec->geom_per_band->solz, l1rec->geom_per_band->sola,
538  l1rec->geom_per_band->senz, l1rec->geom_per_band->sena,
539  sca_num, det_num, l1_input->geom_per_band) == -1) {
540  fprintf(stderr, "-E- %s line %d: Unable to compute geometries\n",
541  __FILE__, __LINE__);
542  exit(1);
543  }
544  }
545  } else {
546  if (chk_oli_geo(file->geofile).type != FT_OLIL1B) {
547  printf("Exit get_oli_angles with error\n");
548  fprintf(stderr, "-E- %s line %d: geofile specified must be an Enhanced Meta-Data file (EMD format)\n",
549  __FILE__, __LINE__);
550  exit(1);
551  }
552  // nominal angles
553  if (get_oli_angles(file->geofile, file->npix, file->nscan, recnum,
554  l1rec->solz, l1rec->sola, l1rec->senz, l1rec->sena, 0) == -1) {
555  printf("Exit get_oli_angles with error\n");
556  fprintf(stderr, "-E- %s line %d: Unable to compute geometries\n",
557  __FILE__, __LINE__);
558  exit(1);
559  }
560  // band based geometry requested
561  if (l1_input->geom_per_band) {
562  if (get_oli_angles(file->geofile, file->npix, file->nscan, recnum,
563  l1rec->geom_per_band->solz, l1rec->geom_per_band->sola,
564  l1rec->geom_per_band->senz, l1rec->geom_per_band->sena,
565  l1_input->geom_per_band) == -1) {
566  printf("Exit get_oli_angles with error\n");
567  fprintf(stderr, "-E- %s line %d: Unable to compute geometries\n",
568  __FILE__, __LINE__);
569  exit(1);
570  }
571  }
572  }
573 
574  if (lonlat)
575  return (LIFE_IS_GOOD);
576 
577  // int y = 0;
578  int y_in_tile = 0;
579 
580  if (tile_exist != 0) {
581  // y = recnum / tileLength;
582  y_in_tile = recnum % tileLength;
583  if (data->line_num_cached == -1 || recnum < data->line_num_cached || recnum >= (data->line_num_cached + tileLength)) {
584  int y = recnum / tileLength;
585  data->line_num_cached = y * tileLength;
586  for (ib = 0; ib < maxReflBands; ib++) { // read Bands 1-7 && 9
587  for (int x = 0; x < imageWidth; x += tileWidth) {
588  if (TIFFReadTile(data->tif[ib], (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength), x, y * tileLength, 0, 0) == -1) {
589  fprintf(stderr, "-E- %s line %d: Failed to read Lt, band %d, recnum %d\n",
590  __FILE__, __LINE__, ib, recnum);
591  exit(1);
592  }
593  }
594  }
595  }
596  }
597 
598  for (ib = 0; ib < file->nbands; ib++) {
599 
600  if (tile_exist == 0) {
601  if (TIFFReadScanline(data->tif[ib], (void*) data->buf, recnum, 0) == -1) {
602  fprintf(stderr, "-E- %s line %d: Failed to read Lt, band %d, recnum %d\n",
603  __FILE__, __LINE__, ib, recnum);
604  exit(1);
605  }
606  } else {
607  for (int x = 0; x < imageWidth; x += tileWidth) {
608  if ((imageWidth - x) >= tileWidth) {
609  _TIFFmemcpy((void*) (data->buf + x), (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength + y_in_tile * tileWidth), tileWidth * 2);
610  }
611  else
612  _TIFFmemcpy((void*) (data->buf + x), (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength + y_in_tile * tileWidth), (imageWidth - x) * 2);
613  }
614  }
615 
616  l1rec->Fo[ib] = Fobar[ib] * fsol;
617 
618  for (ip = 0; ip < file->npix; ip++) {
619  ipb = ip * file->nbands + ib;
620  if (data->buf[ip] == 0) {
621  l1rec->Lt[ipb] = BAD_FLT; // I assume this is outside the projected tile
622  l1rec->navwarn[ip] = 1; // so set navigation failure
623  } else {
624  l1rec->Lt[ipb] = (data->buf[ip] * data->refl_scale[ib] + data->refl_offset[ib]) * l1rec->Fo[ib] / PI;
625  // New addition by Sudipta to scale by band specific FPM gain factor
626  for (iw = 0; iw < l1_input->xcal_nwave; iw++) {
627  if ((bindex_get(l1_input->xcal_wave[iw]) == ib) &&
628  ((l1_input->xcal_opt[iw] & XCALOLI) != 0)) {
629  isb = (sca_num[ipb] - 1) * file->nbands + ib;
630  l1rec->Lt[ipb] *= xcal_factor[isb];
631  break;
632  }
633  }
634  // end Sudipta addition
635  }
636  }
637  }
638 
639  // read Cirrus Band 9
640 
641  ib = 7;
642 
643  if (tile_exist == 0) {
644  if (TIFFReadScanline(data->tif[ib], (void*) data->buf, recnum, 0) == -1) {
645  fprintf(stderr, "-E- %s line %d: Failed to read Lt, band %d, recnum %d\n",
646  __FILE__, __LINE__, ib, recnum);
647  exit(1);
648  }
649  } else {
650  for (int x = 0; x < imageWidth; x += tileWidth) {
651  if ((imageWidth - x) >= tileWidth) {
652  _TIFFmemcpy((void*) (data->buf + x), (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength + y_in_tile * tileWidth), tileWidth * 2);
653  }
654  else
655  _TIFFmemcpy((void*) (data->buf + x), (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength + y_in_tile * tileWidth), (imageWidth - x) * 2);
656  }
657  }
658 
659  for (ip = 0; ip < file->npix; ip++) {
660  if (data->buf[ip] == 0)
661  l1rec->rho_cirrus[ip] = BAD_FLT;
662  else
663  l1rec->rho_cirrus[ip] = (data->buf[ip] * data->refl_scale[ib] + data->refl_offset[ib])
664  / cos(l1rec->solz[ip] / RADEG);
665 
666  }
667  return 0;
668 }
669 
670 int closel1_oli(filehandle *file) {
671  int ib;
672  oli_t* data = (oli_t*) file->private_data;
673 
674  // undo what open allocated
675  free(data->lat);
676  free(data->lon);
677  data->lat = data->lon = NULL;
678 
679  free(data->buf);
680  data->buf = NULL;
681 
682  if (tile_exist != 0) {
683  free(data->buf_tile_row);
684  data->buf_tile_row = NULL;
685  }
686 
687  GTIFFree(data->gtif);
688  data->gtif = NULL;
689 
690  for (ib = 0; ib < file->nbands; ib++) {
691  XTIFFClose(data->tif[ib]);
692  }
694  file->private_data = NULL;
695 
696  if (xcal_factor) free(xcal_factor);
697 
698  return 0;
699 }
700 
int init_geom_per_band(l1str *l1rec)
Definition: geom_per_band.c:7
int get_oli_angles(char *emeta_filename, int32_t npix, int32_t nscan, int32_t iscan, float *solz, float *sola, float *senz, float *sena, int32_t isGeomPerBand)
Definition: get_l8_angles.c:14
double * offset
Definition: l1_oli.c:30
int32_t day
double yds2unix(int16_t year, int16_t day, double secs)
Definition: yds2unix.c:7
int32_t year
Definition: l1_oli.c:27
int openl1_oli(filehandle *file)
Definition: l1_oli.c:141
#define NULL
Definition: decode_rs.h:63
double * scale
Definition: l1_oli.c:30
int get_oli_nom_angles(char *meta_filename, int32_t npix, int32_t nscan, int32_t iscan, float *solz, float *sola, float *senz, float *sena, short *sca_num, short *det_num, int32_t isGeomPerBand)
read l1rec
void trimBlanks(char *str)
Definition: trimBlanks.c:10
double sunElevation
Definition: l1_oli.c:28
double * refl_offset
Definition: l1_oli.c:31
double esdist_(int32_t *year, int32_t *day, int32_t *msec)
file_type type
Definition: filetype.h:70
#define XCALOLI
Definition: l1.h:88
GTIF * gtif
Definition: l1_oli.c:34
int32_t msec
Definition: l1_oli.c:27
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed file
Definition: HISTORY.txt:413
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
#define PI
Definition: l3_get_org.c:6
int bindex_get(int32_t wave)
Definition: windex.c:45
double * get_fpm_xcal(char *fpm_file)
Definition: xcal.c:334
read recnum
subroutine lonlat(alon, alat, xlon, ylat)
Definition: lonlat.f:2
double * lat
Definition: l1_oli.c:29
oli_t * createPrivateData(int numBands)
Definition: l1_oli.c:40
char * strdup(const char *)
void freePrivateData(oli_t *data)
Definition: l1_oli.c:92
int32_t doy
Definition: l1_oli.c:27
int line_num_cached
Definition: l1_oli.c:32
l1_input_t * l1_input
Definition: l1_options.c:9
uint16_t * buf
Definition: l1_oli.c:37
int want_verbose
#define RADEG
Definition: czcs_ctl_pt.c:5
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
int readl1_oli(filehandle *file, int recnum, l1str *l1rec, int lonlat)
Definition: l1_oli.c:431
#define BAD_FLT
Definition: jplaeriallib.h:19
void ymdhms2ydmsec(int yy, int mm, int dd, int hh, int mn, int sc, int32_t *year, int32_t *day, int32_t *msec)
Definition: ydhms2ydmsec.c:3
TIFF ** tif
Definition: l1_oli.c:33
int32_t nbands
uint16_t * buf_tile_row
Definition: l1_oli.c:36
file_format chk_oli_geo(char *filename)
Definition: filetype.c:1053
real *8 function esdist(iyr, iday, msec)
Definition: esdist.f:3
int imageWidth
Definition: l3mapgen.cpp:91
double * refl_scale
Definition: l1_oli.c:31
int32_t rdsensorinfo(int32_t, int32_t, const char *, void **)
Definition: rdsensorinfo.c:69
for(i=0;i< NROOTS;i++) s[i]
Definition: decode_rs.h:85
int closel1_oli(filehandle *file)
Definition: l1_oli.c:670
int readNextLine(FILE *fp, char *tag, int *i, char *val)
Definition: l1_oli.c:102
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
@ FT_OLIL1B
Definition: filetype.h:41
GTIFDefn * defn
Definition: l1_oli.c:35
double * lon
Definition: l1_oli.c:29
double sunAzimuth
Definition: l1_oli.c:28
int count
Definition: decode_rs.h:79