OB.DAAC Logo
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 = 9;
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 < maxReflBands) {
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  data->tif[i] = XTIFFOpen(fileName, "r");
217  if (!data->tif[i]) {
218  fprintf(stderr, "-E- %s line %d: unable open TIFF file %s\n",
219  __FILE__, __LINE__, fileName);
220  exit(1);
221  }
222  }
223 
224  // get geofile name
225  } else if (!strcmp(tag, "ANGLE_COEFFICIENT_FILE_NAME") || !strcmp(tag, "FILE_NAME_ANGLE_COEFFICIENT")) {
226  angleFileFound = 1;
227  if ((file->geofile == NULL) || (file->geofile[0] == 0)) {
228  // dirname might destroy input, so we pass it a copy
229  char dir[FILENAME_MAX];
230  strcpy(dir, file->name);
231  strcpy(fileName, dirname(dir));
232  strcat(fileName, "/");
233  strcat(fileName, val);
234  file->geofile = strdup(fileName);
235  if (want_verbose)
236  printf("OLI Level-1B Angle File:%s\n", fileName);
237  }
238 
239  // get sun azimuth
240  } else if (!strcmp(tag, "SUN_AZIMUTH")) {
241  sunAzimuthFound = 1;
242  data->sunAzimuth = atof(val);
243 
244  // get sun elevation
245  } else if (!strcmp(tag, "SUN_ELEVATION")) {
246  sunElevationFound = 1;
247  data->sunElevation = atof(val);
248 
249  // get refl_scale
250  } else if (!strncmp(tag, "REFLECTANCE_MULT_BAND_", 22)) {
251  i--;
252  if (i >= 0 && i < maxReflBands) {
253  data->refl_scale[i] = atof(val);
254  }
255 
256  // get refl_offset
257  } else if (!strncmp(tag, "REFLECTANCE_ADD_BAND_", 21)) {
258  i--;
259  if (i >= 0 && i < maxReflBands) {
260  data->refl_offset[i] = atof(val);
261  }
262 
263  } else if (!strncmp(tag, "RADIANCE_MULT_BAND_", 19)) {
264  i--;
265  if (i >= 0 && i < maxReflBands) {
266  data->scale[i] = atof(val);
267  }
268 
269  // get offset
270  } else if (!strncmp(tag, "RADIANCE_ADD_BAND_", 18)) {
271  i--;
272  if (i >= 0 && i < maxReflBands) {
273  data->offset[i] = atof(val);
274  }
275  }
276 
277  } // while
278 
279  fclose(fp);
280 
281  if (!dateFound) {
282  fprintf(stderr, "-E- %s line %d: Did not find DATE_ACQUIRED in %s\n",
283  __FILE__, __LINE__, file->name);
284  exit(EXIT_FAILURE);
285  }
286  if (!timeFound) {
287  fprintf(stderr, "-E- %s line %d: Did not find SCENE_CENTER_TIME in %s\n",
288  __FILE__, __LINE__, file->name);
289  exit(EXIT_FAILURE);
290  }
291  if (!numLinesFound) {
292  fprintf(stderr, "-E- %s line %d: Did not find REFLECTIVE_LINES in %s\n",
293  __FILE__, __LINE__, file->name);
294  exit(EXIT_FAILURE);
295  }
296  if (!numSamplesFound) {
297  fprintf(stderr, "-E- %s line %d: Did not find REFLECTIVE_SAMPLES in %s\n",
298  __FILE__, __LINE__, file->name);
299  exit(EXIT_FAILURE);
300  }
301  if (!sunAzimuthFound) {
302  fprintf(stderr, "-E- %s line %d: Did not find SUN_AZIMUTH in %s\n",
303  __FILE__, __LINE__, file->name);
304  exit(EXIT_FAILURE);
305  }
306  if (!sunElevationFound) {
307  fprintf(stderr, "-E- %s line %d: Did not find SUN_ELEVATION in %s\n",
308  __FILE__, __LINE__, file->name);
309  exit(EXIT_FAILURE);
310  }
311  if (collectionNumber > 0) {
312  if (!angleFileFound) {
313  fprintf(stderr, "-E- %s line %d: Did not find ANGLE_COEFFICIENT_FILE_NAME in %s\n",
314  __FILE__, __LINE__, file->name);
315  exit(EXIT_FAILURE);
316  }
317  }
318  for (i = 0; i < maxReflBands; i++) {
319  if (data->tif[i] == NULL) {
320  fprintf(stderr, "-E- %s line %d: Did not find FILE_NAME_BAND_%d in %s\n",
321  __FILE__, __LINE__, i + 1, file->name);
322  exit(EXIT_FAILURE);
323  }
324  if (data->scale[i] == BAD_FLT) {
325  fprintf(stderr, "-E- %s line %d: Did not find RADIANCE_MULT_BAND_%d in %s\n",
326  __FILE__, __LINE__, i + 1, file->name);
327  exit(EXIT_FAILURE);
328  }
329  if (data->offset[i] == BAD_FLT) {
330  fprintf(stderr, "-E- %s line %d: Did not find RADIANCE_ADD_BAND_%d in %s\n",
331  __FILE__, __LINE__, i + 1, file->name);
332  exit(EXIT_FAILURE);
333  }
334  if (data->refl_scale[i] == BAD_FLT) {
335  fprintf(stderr, "-E- %s line %d: Did not find REFLECTANCE_MULT_BAND_%d in %s\n",
336  __FILE__, __LINE__, i + 1, file->name);
337  exit(EXIT_FAILURE);
338  }
339  if (data->refl_offset[i] == BAD_FLT) {
340  fprintf(stderr, "-E- %s line %d: Did not find REFLECTANCE_ADD_BAND_%d in %s\n",
341  __FILE__, __LINE__, i + 1, file->name);
342  exit(EXIT_FAILURE);
343  }
344  }
345 
346  // allocate lat and lon storage
347  data->lat = (double *) malloc(file->npix * sizeof (double));
348  data->lon = (double *) malloc(file->npix * sizeof (double));
349  if (data->lat == NULL || data->lon == NULL) {
350  fprintf(stderr, "-E- %s line %d: unable to allocate lat/lon data for OLI\n",
351  __FILE__, __LINE__);
352  exit(1);
353  }
354 
355  // only need the GEO TIFF info from one file
356  data->gtif = GTIFNew(data->tif[0]);
357  if (!data->gtif) {
358  fprintf(stderr, "-E- %s line %d: unable open GEOTIFF file %s\n",
359  __FILE__, __LINE__, fileName);
360  exit(1);
361  }
362 
363  if (!GTIFGetDefn(data->gtif, data->defn)) {
364  fprintf(stderr, "-E- %s line %d: unable populate GEOTIFF defn structure for %s\n",
365  __FILE__, __LINE__, fileName);
366  exit(1);
367  }
368 
369  // allocate buffer to hold one scan line
370  int size = TIFFScanlineSize(data->tif[0]);
371  if (size != file->npix * 2) {
372  fprintf(stderr, "-E- %s line %d: unexpected pixel data size in %s\n",
373  __FILE__, __LINE__, fileName);
374  exit(1);
375  }
376  data->buf = (uint16_t*) malloc(size);
377 
378 
379  tile_exist = TIFFGetField(data->tif[0], TIFFTAG_TILELENGTH, &tileLength);
380 
381  if (tile_exist != 0) {
382  TIFFGetField(data->tif[0], TIFFTAG_TILEWIDTH, &tileWidth);
383  TIFFGetField(data->tif[0], TIFFTAG_IMAGEWIDTH, &imageWidth);
384  // allocate buffer to hold a row of tile * 9 bands
385  int size_tile_row = 9 * tileLength * size;
386  data->buf_tile_row = (uint16_t*) malloc(size_tile_row);
387  }
388 
389  // get date "2013-07-19"
390  int year, month, day;
391  sscanf(dateStr, "%d-%d-%d", &year, &month, &day);
392 
393  // get time "10:41:59.9930740Z"
394  int hour, minute;
395  double sec;
396  sscanf(timeStr, "%d:%d:%lf", &hour, &minute, &sec);
397 
398  int isec = (int) sec;
399  ymdhms2ydmsec(year, month, day, hour, minute, isec,
400  &data->year, &data->doy, &data->msec);
401  sec -= isec;
402  data->msec += sec * 1000;
403 
404  if (want_verbose) {
405  printf("OLI Start Time: %4d-%02d-%02d %03d %02d:%02d:%f\n",
406  year, month, day, data->doy, hour, minute, sec + isec);
407 
408  printf("OLI file has %d bands, %d samples, %d lines\n",
409  file->nbands, file->npix, file->nscan);
410  }
411  strcpy(file->spatialResolution, "30 m");
412  file->terrain_corrected = 1;
413  /*
414  * get the Fobar here to set up Fo
415  */
416  rdsensorinfo(file->sensorID, l1_input->evalmask, "Fobar", (void **) &Fobar);
417 
418  return 0;
419 }
420 
421 int readl1_oli(filehandle *file, int recnum, l1str *l1rec, int lonlat) {
422  int ip, ib, ipb;
423  oli_t* data = (oli_t*) file->private_data;
424 
425  /* Sudipta new addition for OLI to extract SCA and Det numbers */
426  static short *sca_num; /* SCA number */
427  static short *det_num; /* Detector number */
428  int isb, iw;
429  static int firstCall = 1;
430  /* End Sudipta new addition for OLI */
431 
432  // set information about data
433  l1rec->npix = file->npix;
434  l1rec->scantime = yds2unix((int16_t) data->year, (int16_t) data->doy,
435  (double) (data->msec / 1000.0));
436 
437  double esdist = esdist_(&data->year, &data->doy, &data->msec);
438  double fsol = pow(1.0 / esdist, 2);
439 
440  // get lat-lon
441  for (ip = 0; ip < file->npix; ip++) {
442  data->lon[ip] = ip;
443  data->lat[ip] = recnum;
444  GTIFImageToPCS(data->gtif, data->lon + ip, data->lat + ip);
445  }
446 
447  if (!GTIFProj4ToLatLong(data->defn, file->npix, data->lon, data->lat)) {
448  fprintf(stderr, "-E- %s line %d: unable reproject points for scan %d\n",
449  __FILE__, __LINE__, recnum);
450  exit(1);
451  }
452 
453  for (ip = 0; ip < file->npix; ip++) {
454 
455  l1rec->pixnum[ip] = ip;
456 
457  if (isnan(data->lat[ip]))
458  data->lat[ip] = -999.0;
459  if (isnan(data->lon[ip]))
460  data->lon[ip] = -999.0;
461  l1rec->lat[ip] = data->lat[ip];
462  l1rec->lon[ip] = data->lon[ip];
463 
464  if (l1rec->lon[ip] < -181.0 || l1rec->lon[ip] > 181.0 ||
465  l1rec->lat[ip] < -91.0 || l1rec->lat[ip] > 91.0)
466  l1rec->navfail[ip] = 1;
467 
468  }
469 
470  if (lonlat)
471  return (LIFE_IS_GOOD);
472 
473  // read path angles if user supplied, else use best guess
474 
475  // new addition for OLI
476  /*
477  * if required for that record, set up the geom_per_band storage
478  */
479  if ((l1_input->geom_per_band == 1) && (l1rec->geom_per_band == NULL)) {
481  // gm_p_b = l1rec->geom_per_band; // store this address so that it can be later destroyed in close()
482  }
483 
484  if (firstCall) {
485  firstCall = 0;
486  // Sudipta - new addition to read the FPM xcal file and ingest the values
487  for (iw = 0; iw < l1_input->xcal_nwave; iw++)
488  if ((l1_input->xcal_opt[iw] & XCALOLI) != 0) {
489  xcal_factor = get_fpm_xcal(l1_input->xcal_file);
490  break;
491  }
492  /* printf("geom_per_band = %d\n",l1_input->geom_per_band);
493  printf("xcal_opt = %d\n", l1_input->xcal_opt[0]);
494  printf("xcal_factor = %lf\n", xcal_factor[0]);
495  exit(0)*/;
496 
497  // allocate arrays for the sca and detector number arrays for all bands and pixels
498  /* Sudipta new addition for OLI to extract SCA and Det numbers */
499  if ((sca_num = (short *) calloc(file->npix * file->nbands, sizeof (short))) == NULL) {
500  fprintf(stderr,
501  "-E- %s line %d: Unable to allocate SCA number array.\n",
502  __FILE__, __LINE__);
503  exit(1);
504  }
505 
506  if ((det_num = (short *) calloc(file->npix * file->nbands, sizeof (short))) == NULL) {
507  free(sca_num);
508  fprintf(stderr,
509  "-E- %s line %d: Unable to allocate detector number array.\n",
510  __FILE__, __LINE__);
511  exit(1);
512  }
513  /* End Sudipta new addition for OLI */
514 
515  }
516 
517  if (file->geofile == NULL || file->geofile[0] == 0) {
518  if (get_oli_nom_angles(file->name, file->npix, file->nscan, recnum,
519  l1rec->solz, l1rec->sola, l1rec->senz, l1rec->sena, sca_num,
520  det_num, 0) == -1) {
521  fprintf(stderr, "-E- %s line %d: Unable to compute geometries\n",
522  __FILE__, __LINE__);
523  exit(1);
524  }
525  // Sudipta added sca_num and det_num to get_oli_nom_angles
526  // also added provision for band based geometry
527  // band based geometry requested
528  if (l1_input->geom_per_band) {
529  if (get_oli_nom_angles(file->name, file->npix, file->nscan, recnum,
530  l1rec->geom_per_band->solz, l1rec->geom_per_band->sola,
531  l1rec->geom_per_band->senz, l1rec->geom_per_band->sena,
532  sca_num, det_num, l1_input->geom_per_band) == -1) {
533  fprintf(stderr, "-E- %s line %d: Unable to compute geometries\n",
534  __FILE__, __LINE__);
535  exit(1);
536  }
537  }
538  } else {
539  if (chk_oli_geo(file->geofile).type != FT_OLIL1B) {
540  printf("Exit get_oli_angles with error\n");
541  fprintf(stderr, "-E- %s line %d: geofile specified must be an Enhanced Meta-Data file (EMD format)\n",
542  __FILE__, __LINE__);
543  exit(1);
544  }
545  // nominal angles
546  if (get_oli_angles(file->geofile, file->npix, file->nscan, recnum,
547  l1rec->solz, l1rec->sola, l1rec->senz, l1rec->sena, 0) == -1) {
548  printf("Exit get_oli_angles with error\n");
549  fprintf(stderr, "-E- %s line %d: Unable to compute geometries\n",
550  __FILE__, __LINE__);
551  exit(1);
552  }
553  // band based geometry requested
554  if (l1_input->geom_per_band) {
555  if (get_oli_angles(file->geofile, file->npix, file->nscan, recnum,
556  l1rec->geom_per_band->solz, l1rec->geom_per_band->sola,
557  l1rec->geom_per_band->senz, l1rec->geom_per_band->sena,
558  l1_input->geom_per_band) == -1) {
559  printf("Exit get_oli_angles with error\n");
560  fprintf(stderr, "-E- %s line %d: Unable to compute geometries\n",
561  __FILE__, __LINE__);
562  exit(1);
563  }
564  }
565  }
566 
567  // int y = 0;
568  int y_in_tile = 0;
569 
570  if (tile_exist != 0) {
571  // y = recnum / tileLength;
572  y_in_tile = recnum % tileLength;
573  if (data->line_num_cached == -1 || recnum < data->line_num_cached || recnum >= (data->line_num_cached + tileLength)) {
574  int y = recnum / tileLength;
575  data->line_num_cached = y * tileLength;
576  for (ib = 0; ib <= file->nbands; ib++) {
577  for (int x = 0; x < imageWidth; x += tileWidth) {
578  if (TIFFReadTile(data->tif[ib], (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength), x, y * tileLength, 0, 0) == -1) {
579  fprintf(stderr, "-E- %s line %d: Failed to read Lt, band %d, recnum %d\n",
580  __FILE__, __LINE__, ib, recnum);
581  exit(1);
582  }
583  }
584  }
585  }
586  }
587 
588  for (ib = 0; ib < file->nbands; ib++) {
589 
590  if (tile_exist == 0) {
591  if (TIFFReadScanline(data->tif[ib], (void*) data->buf, recnum, 0) == -1) {
592  fprintf(stderr, "-E- %s line %d: Failed to read Lt, band %d, recnum %d\n",
593  __FILE__, __LINE__, ib, recnum);
594  exit(1);
595  }
596  } else {
597  for (int x = 0; x < imageWidth; x += tileWidth) {
598  if ((imageWidth - x) >= tileWidth) {
599  _TIFFmemcpy((void*) (data->buf + x), (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength + y_in_tile * tileWidth), tileWidth * 2);
600  }
601  else
602  _TIFFmemcpy((void*) (data->buf + x), (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength + y_in_tile * tileWidth), (imageWidth - x) * 2);
603  }
604  }
605 
606  l1rec->Fo[ib] = Fobar[ib] * fsol;
607 
608  for (ip = 0; ip < file->npix; ip++) {
609  ipb = ip * file->nbands + ib;
610  if (data->buf[ip] == 0) {
611  l1rec->Lt[ipb] = BAD_FLT; // I assume this is outside the projected tile
612  l1rec->navwarn[ip] = 1; // so set navigation failure
613  } else {
614  l1rec->Lt[ipb] = (data->buf[ip] * data->refl_scale[ib] + data->refl_offset[ib]) * l1rec->Fo[ib] / PI;
615  // New addition by Sudipta to scale by band specific FPM gain factor
616  for (iw = 0; iw < l1_input->xcal_nwave; iw++) {
617  if ((bindex_get(l1_input->xcal_wave[iw]) == ib) &&
618  ((l1_input->xcal_opt[iw] & XCALOLI) != 0)) {
619  isb = (sca_num[ipb] - 1) * file->nbands + ib;
620  l1rec->Lt[ipb] *= xcal_factor[isb];
621  break;
622  }
623  }
624  // end Sudipta addition
625  }
626  }
627  }
628 
629  // read Cirrus Band 9
630 
631  ib = 8;
632 
633  if (tile_exist == 0) {
634  if (TIFFReadScanline(data->tif[ib], (void*) data->buf, recnum, 0) == -1) {
635  fprintf(stderr, "-E- %s line %d: Failed to read Lt, band %d, recnum %d\n",
636  __FILE__, __LINE__, ib, recnum);
637  exit(1);
638  }
639  } else {
640  for (int x = 0; x < imageWidth; x += tileWidth) {
641  if ((imageWidth - x) >= tileWidth) {
642  _TIFFmemcpy((void*) (data->buf + x), (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength + y_in_tile * tileWidth), tileWidth * 2);
643  }
644  else
645  _TIFFmemcpy((void*) (data->buf + x), (void*) (data->buf_tile_row + ib * imageWidth * tileLength + x * tileLength + y_in_tile * tileWidth), (imageWidth - x) * 2);
646  }
647  }
648 
649  for (ip = 0; ip < file->npix; ip++) {
650  if (data->buf[ip] == 0)
651  l1rec->rho_cirrus[ip] = BAD_FLT;
652  else
653  l1rec->rho_cirrus[ip] = (data->buf[ip] * data->refl_scale[ib] + data->refl_offset[ib])
654  / cos(l1rec->solz[ip] / RADEG);
655 
656  }
657  return 0;
658 }
659 
660 int closel1_oli(filehandle *file) {
661  int ib;
662  oli_t* data = (oli_t*) file->private_data;
663 
664  // undo what open allocated
665  free(data->lat);
666  free(data->lon);
667  data->lat = data->lon = NULL;
668 
669  free(data->buf);
670  data->buf = NULL;
671 
672  if (tile_exist != 0) {
673  free(data->buf_tile_row);
674  data->buf_tile_row = NULL;
675  }
676 
677  GTIFFree(data->gtif);
678  data->gtif = NULL;
679 
680  for (ib = 0; ib < file->nbands; ib++) {
681  XTIFFClose(data->tif[ib]);
682  }
684  file->private_data = NULL;
685 
686  if (xcal_factor) free(xcal_factor);
687 
688  return 0;
689 }
690 
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:67
#define XCALOLI
Definition: l1.h:87
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:421
#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
uint16_t * buf_tile_row
Definition: l1_oli.c:36
file_format chk_oli_geo(char *filename)
Definition: filetype.c:969
real *8 function esdist(iyr, iday, msec)
Definition: esdist.f:3
int imageWidth
Definition: l3mapgen.cpp:47
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:660
int readNextLine(FILE *fp, char *tag, int *i, char *val)
Definition: l1_oli.c:102
int i
Definition: decode_rs.h:71
msiBandIdx val
Definition: l1c_msi.cpp:34
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