OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l1b_ocis.c
Go to the documentation of this file.
1 /* ============================================================================ */
2 /* module l1b_ocis.c - functions to read OCI Similated L1B for l2gen */
3 /* Written By: Don Shea */
4 /* */
5 /* ============================================================================ */
6 
7 /* Issues:
8  -Assume num_pixels = ccd_pixels = SWIR_pixels
9 */
10 
11 #include <netcdf.h>
12 #include "l1b_ocis.h"
13 
14 #include "l1.h"
15 #include <nc4utils.h>
16 #include "libnav.h"
17 #include <stdio.h>
18 #include <math.h>
19 #include <allocate2d.h>
20 
21 
22 static float *Fobar; // reflectance to radiance conversion factors
23 static int extract_pixel_start = 0;
24 static int normalizedLt = 1;
25 static int use_rhot = 0;
26 
27 static short *tmpShort;
28 
29 // whole file stuff
30 static size_t expected_num_blue_bands = 120;
31 static size_t expected_num_red_bands = 120;
32 static size_t expected_num_SWIR_bands = 9;
33 
34 static size_t num_scans, num_pixels;
35 static size_t num_blue_bands, num_red_bands, num_SWIR_bands;
36 static size_t tot_num_bands = 239;
37 static int ncid_L1B;
38 
39 // scan line attributes
40 static double *scan_time; // seconds of day
41 static int32_t scan_time_year, scan_time_month, scan_time_day;
42 
43 //static uint_8 *scan_quality;
44 
45 // geolocation data
46 static int geolocationGrp;
47 static int lonId, latId, senzId, senaId, solzId, solaId;
48 static float latFillValue = -999.0;
49 static float lonFillValue = -999.0;
50 static short senzFillValue = -32768;
51 static float senzScale = 0.01;
52 static float senzOffset = 0.0;
53 static short senaFillValue = -32768;
54 static float senaScale = 0.01;
55 static float senaOffset = 0.0;
56 static short solzFillValue = -32768;
57 static float solzScale = 0.01;
58 static float solzOffset = 0.0;
59 static short solaFillValue = -32768;
60 static float solaScale = 0.01;
61 static float solaOffset = 0.0;
62 
63 // Observation data
64 static int observationGrp;
65 static int Lt_blueId, Lt_redId, Lt_SWIRId;
66 static float **Lt_blue; //[num_blue_bands][num_pixels], This scan
67 static float **Lt_red; //[num_red_bands][num_pixels], This scan
68 static float **Lt_SWIR; //[num_SWIR_bands][num_pixels], This scan
69 static float Lt_blueFillValue = -999.0;
70 static float Lt_redFillValue = -999.0;
71 static float Lt_SWIRFillValue = -999.0;
72 
85 int openl1b_ocis(filehandle * file) {
86  int dimid, status;
87 
88  // Open the netcdf4 input file
89  printf("Opening OCIS L1B file\n");
90  status = nc_open(file->name, NC_NOWRITE, &ncid_L1B);
91  if (status != NC_NOERR) {
92  fprintf(stderr, "-E- %s line %d: nc_open(%s) failed.\n",
93  __FILE__, __LINE__, file->name);
94  return (1);
95  }
96 
97  // num_scans
98  status = nc_inq_dimid(ncid_L1B, "number_of_scans", &dimid);
99  if (status != NC_NOERR) {
100  fprintf(stderr, "-E- Error reading number_of_scans.\n");
101  exit(EXIT_FAILURE);
102  }
103  nc_inq_dimlen(ncid_L1B, dimid, &num_scans);
104 
105  // num_pixels
106  status = nc_inq_dimid(ncid_L1B, "ccd_pixels", &dimid);
107  if (status != NC_NOERR) {
108  fprintf(stderr, "-E- Error reading num_pixels.\n");
109  exit(EXIT_FAILURE);
110  }
111  nc_inq_dimlen(ncid_L1B, dimid, &num_pixels);
112 
113  // num_blue_bands
114  status = nc_inq_dimid(ncid_L1B, "blue_bands", &dimid);
115  if (status != NC_NOERR) {
116  fprintf(stderr, "-E- Error reading num_blue_bands.\n");
117  exit(EXIT_FAILURE);
118  }
119  nc_inq_dimlen(ncid_L1B, dimid, &num_blue_bands);
120  if(num_blue_bands < expected_num_blue_bands) {
121  fprintf(stderr, "-E- Not enough blue bands, expecting %d, found %d.\n",
122  (int)expected_num_blue_bands, (int)num_blue_bands);
123  exit(EXIT_FAILURE);
124  }
125 
126  // num_red_bands
127  status = nc_inq_dimid(ncid_L1B, "red_bands", &dimid);
128  if (status != NC_NOERR) {
129  fprintf(stderr, "-E- Error reading num_red_bands.\n");
130  exit(EXIT_FAILURE);
131  };
132  nc_inq_dimlen(ncid_L1B, dimid, &num_red_bands);
133  if(num_red_bands < expected_num_red_bands) {
134  fprintf(stderr, "-E- Not enough red bands, expecting %d, found %d.\n",
135  (int)expected_num_red_bands, (int)num_red_bands);
136  exit(EXIT_FAILURE);
137  }
138 
139  // num_SWIR_bands
140  status = nc_inq_dimid(ncid_L1B, "SWIR_bands", &dimid);
141  if (status != NC_NOERR) {
142  fprintf(stderr, "-E- Error reading num_SWIR_bands.\n");
143  exit(EXIT_FAILURE);
144  };
145  nc_inq_dimlen(ncid_L1B, dimid, &num_SWIR_bands);
146  if(num_SWIR_bands < expected_num_SWIR_bands) {
147  fprintf(stderr, "-E- Not enough SWIR bands, expecting %d, found %d.\n",
148  (int)expected_num_SWIR_bands, (int)num_SWIR_bands);
149  exit(EXIT_FAILURE);
150  }
151 
152  if (want_verbose) {
153  printf("OCI L1B Npix :%d Nlines:%d\n", (int)num_pixels, (int)num_scans);
154  } // want_verbose
155 
156  // allocate all of the data
157  tmpShort = (short*) malloc(num_pixels * sizeof(short));
158  scan_time = (double*) malloc(num_scans * sizeof(double));
159 
160  Lt_blue = allocate2d_float(num_blue_bands, num_pixels);
161  Lt_red = allocate2d_float(num_red_bands, num_pixels);
162  Lt_SWIR = allocate2d_float(num_SWIR_bands, num_pixels);
163 
164  // Get group id from L1B file for GROUP scan_line_attributes.
165  int groupid;
166  if ((nc_inq_grp_ncid(ncid_L1B, "scan_line_attributes", &groupid)) == NC_NOERR) {
167  } else {
168  fprintf(stderr, "-E- Error finding scan_line_attributes.\n");
169  exit(EXIT_FAILURE);
170  }
171  int varid;
172  double scan_timeFillValue = -999.9;
173  status = nc_inq_varid(groupid, "time", &varid);
174  if(status == NC_NOERR) {
175  status = nc_inq_var_fill(groupid, varid, NULL, &scan_timeFillValue);
176  check_err(status, __LINE__, __FILE__);
177  status = nc_get_var_double(groupid, varid, scan_time);
178  check_err(status, __LINE__, __FILE__);
179  status = nc_get_att_int(groupid, varid, "year", &scan_time_year);
180  check_err(status, __LINE__, __FILE__);
181  status = nc_get_att_int(groupid, varid, "month", &scan_time_month);
182  check_err(status, __LINE__, __FILE__);
183  status = nc_get_att_int(groupid, varid, "day", &scan_time_day);
184  check_err(status, __LINE__, __FILE__);
185  } else {
186  status = nc_inq_varid(groupid, "ev_mid_time", &varid);
187  check_err(status, __LINE__, __FILE__);
188  status = nc_inq_var_fill(groupid, varid, NULL, &scan_timeFillValue);
189  check_err(status, __LINE__, __FILE__);
190  status = nc_get_var_double(groupid, varid, scan_time);
191  check_err(status, __LINE__, __FILE__);
192 
193  // get start time
194  size_t att_len;
195  status = nc_inq_attlen(ncid_L1B, NC_GLOBAL, "time_coverage_start", &att_len);
196  check_err(status, __LINE__, __FILE__);
197 
198  // allocate required space before retrieving values
199  char* time_str = (char *) malloc(att_len + 1); // + 1 for trailing null
200 
201  // get attribute values
202  status = nc_get_att_text(ncid_L1B, NC_GLOBAL, "time_coverage_start", time_str);
203  check_err(status, __LINE__, __FILE__);
204  time_str[att_len] = '\0';
205 
206  double start_time = isodate2unix(time_str);
207  int16_t syear, smon, sday;
208  double secs;
209  unix2ymds(start_time, &syear, &smon, &sday, &secs);
210  scan_time_year = syear;
211  scan_time_month = smon;
212  scan_time_day = sday;
213 
214  }
215 
216  for(int i=0; i<num_scans; i++) {
217  if(scan_time[i] == scan_timeFillValue)
218  scan_time[i] = BAD_FLT;
219  }
220 
221  // check if the normalizedLt attribute is set; GMAO output will be normalized Lt, and likley won't have
222  // this attribute set, so default to TRUE. If the file defines it, use it.
223  int normLt;
224  status = nc_get_att_int(ncid_L1B, NC_GLOBAL, "normalizedLt", &normLt);
225  if (!status) {
226  normalizedLt = normLt;
227  }
228 
229  // read the orbit#
230  int orbit_number;
231  status = nc_get_att_int(ncid_L1B, NC_GLOBAL, "orbit_number", &orbit_number);
232  check_err(status, __LINE__, __FILE__);
233 
234  // Setup geofile pointers
235  status = nc_inq_grp_ncid(ncid_L1B, "geolocation_data", &geolocationGrp);
236  check_err(status, __LINE__, __FILE__);
237  status = nc_inq_varid(geolocationGrp, "longitude", &lonId);
238  check_err(status, __LINE__, __FILE__);
239  status = nc_inq_var_fill(geolocationGrp, lonId, NULL, &lonFillValue);
240  check_err(status, __LINE__, __FILE__);
241  status = nc_inq_varid(geolocationGrp, "latitude", &latId);
242  check_err(status, __LINE__, __FILE__);
243  status = nc_inq_var_fill(geolocationGrp, latId, NULL, &latFillValue);
244  check_err(status, __LINE__, __FILE__);
245 
246  status = nc_inq_varid(geolocationGrp, "sensor_zenith", &senzId);
247  check_err(status, __LINE__, __FILE__);
248  status = nc_inq_var_fill(geolocationGrp, senzId, NULL, &senzFillValue);
249  check_err(status, __LINE__, __FILE__);
250  status = nc_get_att_float(geolocationGrp, senzId, "scale_factor", &senzScale);
251  check_err(status, __LINE__, __FILE__);
252  status = nc_get_att_float(geolocationGrp, senzId, "add_offset", &senzOffset);
253  check_err(status, __LINE__, __FILE__);
254 
255  status = nc_inq_varid(geolocationGrp, "sensor_azimuth", &senaId);
256  check_err(status, __LINE__, __FILE__);
257  status = nc_inq_var_fill(geolocationGrp, senaId, NULL, &senaFillValue);
258  check_err(status, __LINE__, __FILE__);
259  status = nc_get_att_float(geolocationGrp, senaId, "scale_factor", &senaScale);
260  check_err(status, __LINE__, __FILE__);
261  status = nc_get_att_float(geolocationGrp, senaId, "add_offset", &senaOffset);
262  check_err(status, __LINE__, __FILE__);
263 
264  status = nc_inq_varid(geolocationGrp, "solar_zenith", &solzId);
265  check_err(status, __LINE__, __FILE__);
266  status = nc_inq_var_fill(geolocationGrp, solzId, NULL, &solzFillValue);
267  check_err(status, __LINE__, __FILE__);
268  status = nc_get_att_float(geolocationGrp, solzId, "scale_factor", &solzScale);
269  check_err(status, __LINE__, __FILE__);
270  status = nc_get_att_float(geolocationGrp, solzId, "add_offset", &solzOffset);
271  check_err(status, __LINE__, __FILE__);
272 
273  status = nc_inq_varid(geolocationGrp, "solar_azimuth", &solaId);
274  check_err(status, __LINE__, __FILE__);
275  status = nc_inq_var_fill(geolocationGrp, solaId, NULL, &solaFillValue);
276  check_err(status, __LINE__, __FILE__);
277  status = nc_get_att_float(geolocationGrp, solaId, "scale_factor", &solaScale);
278  check_err(status, __LINE__, __FILE__);
279  status = nc_get_att_float(geolocationGrp, solaId, "add_offset", &solaOffset);
280  check_err(status, __LINE__, __FILE__);
281 
282 
283  // get IDs for the observations
284  status = nc_inq_grp_ncid(ncid_L1B, "observation_data", &observationGrp);
285  check_err(status, __LINE__, __FILE__);
286 
287  // Get varids for each of the Lt_*
288  use_rhot = 0;
289  status = nc_inq_varid(observationGrp, "Lt_blue", &Lt_blueId);
290  if(status == NC_NOERR) {
291  check_err(status, __LINE__, __FILE__);
292  status = nc_inq_var_fill(observationGrp, Lt_blueId, NULL, &Lt_blueFillValue);
293  check_err(status, __LINE__, __FILE__);
294 
295  status = nc_inq_varid(observationGrp, "Lt_red", &Lt_redId);
296  check_err(status, __LINE__, __FILE__);
297  status = nc_inq_var_fill(observationGrp, Lt_redId, NULL, &Lt_redFillValue);
298  check_err(status, __LINE__, __FILE__);
299 
300  status = nc_inq_varid(observationGrp, "Lt_SWIR", &Lt_SWIRId);
301  check_err(status, __LINE__, __FILE__);
302  status = nc_inq_var_fill(observationGrp, Lt_SWIRId, NULL, &Lt_SWIRFillValue);
303  check_err(status, __LINE__, __FILE__);
304  } else { // no Lt, so check for rhot
305  status = nc_inq_varid(observationGrp, "rhot_blue", &Lt_blueId);
306  check_err(status, __LINE__, __FILE__);
307  status = nc_inq_var_fill(observationGrp, Lt_blueId, NULL, &Lt_blueFillValue);
308  check_err(status, __LINE__, __FILE__);
309 
310  status = nc_inq_varid(observationGrp, "rhot_red", &Lt_redId);
311  check_err(status, __LINE__, __FILE__);
312  status = nc_inq_var_fill(observationGrp, Lt_redId, NULL, &Lt_redFillValue);
313  check_err(status, __LINE__, __FILE__);
314 
315  status = nc_inq_varid(observationGrp, "rhot_SWIR", &Lt_SWIRId);
316  check_err(status, __LINE__, __FILE__);
317  status = nc_inq_var_fill(observationGrp, Lt_SWIRId, NULL, &Lt_SWIRFillValue);
318  check_err(status, __LINE__, __FILE__);
319  use_rhot = 1;
320  }
321 
322 
323  file->sd_id = ncid_L1B;
324  file->nbands = tot_num_bands;
325  file->npix = num_pixels;
326  file->nscan = num_scans;
327  file->ndets = 1;
328  file->terrain_corrected = 1; // presumed.
329  file->orbit_number = orbit_number;
330  strcpy(file->spatialResolution, "1000 m");
331 
332  rdsensorinfo(file->sensorID, l1_input->evalmask,
333  "Fobar", (void **) &Fobar);
334 
335  if (want_verbose)
336  printf("file->nbands = %d\n", (int) file->nbands);
337 
338  return (LIFE_IS_GOOD);
339 }
340 
341 
354 int readl1b_ocis(filehandle *file, int32_t line, l1str *l1rec) {
355 
356  int status;
357  size_t start[] = { 0, 0, 0 };
358  size_t count[] = { 1, 1, 1 };
359 
360  //printf("reading oci l1b file\n");
361  for (int ip = 0; ip < num_pixels; ip++) {
362  l1rec->pixnum[ip] = ip + extract_pixel_start;
363  }
364 
365  l1rec->npix = file->npix;
366 
367  l1rec->scantime = ymds2unix((int16_t)scan_time_year, (int16_t)scan_time_month, (int16_t)scan_time_day, scan_time[line]);
368 
369  int16_t syear, sday;
370  double secs;
371  unix2yds(l1rec->scantime, &syear, &sday, &secs);
372 
373  int32_t yr = syear;
374  int32_t dy = sday;
375  int32_t msec = (int32_t) (secs * 1000.0);
376  double esdist = esdist_(&yr, &dy, &msec);
377 
378  l1rec->fsol = pow(1.0 / esdist, 2);
379 
380  start[0] = line;
381  start[1] = 0;
382  start[2] = 0;
383  count[0] = 1;
384  count[1] = num_pixels; // 1 line at a time
385  count[2] = 1;
386  status = nc_get_vara_float(geolocationGrp, latId, start, count, l1rec->lat);
387  check_err(status, __LINE__, __FILE__);
388  status = nc_get_vara_float(geolocationGrp, lonId, start, count, l1rec->lon);
389  check_err(status, __LINE__, __FILE__);
390 
391  for(int i=0; i<num_pixels; i++) {
392  if(l1rec->lat[i] == latFillValue)
393  l1rec->lat[i] = BAD_FLT;
394  if(l1rec->lon[i] == lonFillValue)
395  l1rec->lon[i] = BAD_FLT;
396  }
397 
398  status = nc_get_vara_short(geolocationGrp, senaId, start, count, tmpShort);
399  check_err(status, __LINE__, __FILE__);
400  for(int i=0; i<num_pixels; i++) {
401  if(tmpShort[i] == senaFillValue)
402  l1rec->sena[i] = BAD_FLT;
403  else
404  l1rec->sena[i] = tmpShort[i] * senaScale + senaOffset;
405  }
406 
407  status = nc_get_vara_short(geolocationGrp, senzId, start, count, tmpShort);
408  check_err(status, __LINE__, __FILE__);
409  for(int i=0; i<num_pixels; i++) {
410  if(tmpShort[i] == senzFillValue)
411  l1rec->senz[i] = BAD_FLT;
412  else
413  l1rec->senz[i] = tmpShort[i] * senzScale + senzOffset;
414  }
415 
416  status = nc_get_vara_short(geolocationGrp, solaId, start, count, tmpShort);
417  check_err(status, __LINE__, __FILE__);
418  for(int i=0; i<num_pixels; i++) {
419  if(tmpShort[i] == solaFillValue)
420  l1rec->sola[i] = BAD_FLT;
421  else
422  l1rec->sola[i] = tmpShort[i] * solaScale + solaOffset;
423  }
424 
425  status = nc_get_vara_short(geolocationGrp, solzId, start, count, tmpShort);
426  check_err(status, __LINE__, __FILE__);
427  for(int i=0; i<num_pixels; i++) {
428  if(tmpShort[i] == solzFillValue)
429  l1rec->solz[i] = BAD_FLT;
430  else
431  l1rec->solz[i] = tmpShort[i] * solzScale + solzOffset;
432  }
433 
434 
435  start[0] = 0;
436  start[1] = line;
437  start[2] = 0;
438  count[0] = num_blue_bands;
439  count[1] = 1; // 1 line at a time
440  count[2] = num_pixels;
441  status = nc_get_vara_float(observationGrp, Lt_blueId, start, count, Lt_blue[0]);
442  check_err(status, __LINE__, __FILE__);
443 
444  count[0] = num_red_bands;
445  status = nc_get_vara_float(observationGrp, Lt_redId, start, count, Lt_red[0]);
446  check_err(status, __LINE__, __FILE__);
447 
448  count[0] = num_SWIR_bands;
449  status = nc_get_vara_float(observationGrp, Lt_SWIRId, start, count, Lt_SWIR[0]);
450  check_err(status, __LINE__, __FILE__);
451 
452 
453  // old
454  //Lt = <file val> * <F0 from read_sensor_info> * <esdist()> * cos(solz)
455 
456  // this should be the correct equation
457  //Lt = <file val> * <F0 from read_sensor_info> * <esdist()>
458 
459 
460  for(int ip=0; ip<num_pixels; ip++) {
461  int band;
462  int ib = 0;
463  int ipb = ip * tot_num_bands;
464 
465  // load up the blue bands skip the last two
466  for(band=0; band<expected_num_blue_bands-2; band++) {
467  if(Lt_blue[band][ip] == Lt_blueFillValue) {
468  l1rec->Lt[ipb] = 0.001; // should be BAD_FLT, but that makes atmocor fail
469  } else {
470  l1rec->Lt[ipb] = Lt_blue[band][ip];
471  if (normalizedLt) {
472  l1rec->Lt[ipb] *= Fobar[ib] * l1rec->fsol;
473  } else if (use_rhot) {
474  l1rec->Lt[ipb] *= Fobar[ib] * l1rec->fsol * cos(l1rec->solz[ip]/RADEG) / M_PI;
475  } else {
476  l1rec->Lt[ipb] /= 10.; // the input is in W/m2 ...
477  }
478  }
479  ib++;
480  ipb++;
481  }
482 
483  // load up the red bands skipping the first two and the last 4
484  for(band=2; band<expected_num_red_bands-4; band++) {
485  if(Lt_red[band][ip] == Lt_redFillValue) {
486  l1rec->Lt[ipb] = 0.001; // should be BAD_FLT, but that makes atmocor fail
487  } else {
488  l1rec->Lt[ipb] = Lt_red[band][ip];
489  if (normalizedLt) {
490  l1rec->Lt[ipb] *= Fobar[ib] * l1rec->fsol;
491  } else if (use_rhot) {
492  l1rec->Lt[ipb] *= Fobar[ib] * l1rec->fsol * cos(l1rec->solz[ip]/RADEG) / M_PI;
493  } else {
494  l1rec->Lt[ipb] /= 10.; // the input is in W/m2 ...
495  }
496  }
497  ib++;
498  ipb++;
499  }
500 
501  // load up the SWIR bands, skip band 3 and 6, hi/low gain wavelengths
502  for(band=0; band<expected_num_SWIR_bands; band++) {
503  if(band == 3 || band == 6)
504  continue;
505  if(Lt_SWIR[band][ip] == Lt_SWIRFillValue) {
506  l1rec->Lt[ipb] = 0.001; // should be BAD_FLT, but that makes atmocor fail
507  } else {
508  l1rec->Lt[ipb] = Lt_SWIR[band][ip];
509  if (normalizedLt) {
510  l1rec->Lt[ipb] *= Fobar[ib] * l1rec->fsol;
511  } else if (use_rhot) {
512  l1rec->Lt[ipb] *= Fobar[ib] * l1rec->fsol * cos(l1rec->solz[ip]/RADEG) / M_PI;
513  } else {
514  l1rec->Lt[ipb] /= 10.; // the input is in W/m2 ...
515  }
516  }
517  ib++;
518  ipb++;
519  }
520  }
521 
522  return (LIFE_IS_GOOD);
523 }
524 
525 
531 int closel1b_ocis(filehandle *file) {
532  int status;
533 
534  printf("Closing ocis l1b file\n");
535  status = nc_close(file->sd_id);
536  check_err(status, __LINE__, __FILE__);
537 
538  // Free memory
539  // From openl1b_ocis
540  if (tmpShort) free(tmpShort);
541  if (scan_time) free(scan_time);
542  if (Lt_blue) free2d_float(Lt_blue);
543  if (Lt_red) free2d_float(Lt_red);
544  if (Lt_SWIR) free2d_float(Lt_SWIR);
545 
546  return (LIFE_IS_GOOD);
547 }
548 
549 
550 
551 
552 
int status
Definition: l1_czcs_hdf.c:32
void check_err(const int stat, const int line, const char *file)
Definition: nc4utils.c:35
int openl1b_ocis(filehandle *file)
Definition: l1b_ocis.c:85
#define NULL
Definition: decode_rs.h:63
read l1rec
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second band
void unix2ymds(double usec, int16_t *year, int16_t *mon, int16_t *day, double *secs)
Definition: unix2ymds.c:8
int32 * msec
Definition: l1_czcs_hdf.c:31
double esdist_(int32_t *year, int32_t *day, int32_t *msec)
int syear
Definition: l1_czcs_hdf.c:15
int closel1b_ocis(filehandle *file)
Definition: l1b_ocis.c:531
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
int sday
Definition: l1_czcs_hdf.c:15
int time_str(short, short, int, char *)
Definition: time_str.c:3
void free2d_float(float **p)
Free a two-dimensional array created by allocate2d_float.
Definition: allocate2d.c:142
l1_input_t * l1_input
Definition: l1_options.c:9
#define M_PI
Definition: pml_iop.h:15
int want_verbose
void unix2yds(double usec, short *year, short *day, double *secs)
#define RADEG
Definition: czcs_ctl_pt.c:5
Utility functions for allocating and freeing two-dimensional arrays of various types.
#define BAD_FLT
Definition: jplaeriallib.h:19
real *8 function esdist(iyr, iday, msec)
Definition: esdist.f:3
int32_t rdsensorinfo(int32_t, int32_t, const char *, void **)
Definition: rdsensorinfo.c:69
float ** allocate2d_float(size_t h, size_t w)
Allocate a two-dimensional array of type float of a given size.
Definition: allocate2d.c:125
double ymds2unix(short year, short month, short day, double secs)
int i
Definition: decode_rs.h:71
int readl1b_ocis(filehandle *file, int32_t line, l1str *l1rec)
Definition: l1b_ocis.c:354
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
double isodate2unix(const char *isodate)
Definition: unix2isodate.c:61
int count
Definition: decode_rs.h:79