NASA Logo
Ocean Color Science Software

ocssw V2022
main_l1det2det.c
Go to the documentation of this file.
1 /* =====================================================================*/
2 /* */
3 /* Program: l1det2det - multi-sensor detector-to-detector calibration */
4 /* */
5 /* */
6 /* Written By: */
7 /* */
8 /* Ewa J. Kwiatkowska */
9 /* SAIC */
10 /* NASA/Ocean Color Project */
11 /* June 2007 */
12 /* */
13 /* Programmer Organization Date Description of change*/
14 /* -------------- ------------ -------- ---------------------*/
15 /* Joel Gales Futuretech 08/01/13 Add support for */
16 /* NETCDF4 */
17 /* B. Franz NASA 09/10/13 Remove references to */
18 /* resolution and 1640 */
19 /* and 500m MODIS code */
20 /* Sean Bailey Futuretech 04/15/13 Entirely reworked to */
21 /* handle any mission, */
22 /* work with existing */
23 /* product definitions */
24 /* and require complete */
25 /* scans */
26 /* =====================================================================*/
27 
28 #include <stdio.h>
29 #include <sys/stat.h>
30 #include <stdlib.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <libgen.h>
36 #include <setupflags.h>
37 #include "l12_proto.h"
38 #include "calfile_utils.h"
39 #include <hdf5.h>
40 #include <readL2scan.h>
41 
42 int read9km_mask(char *file, char *mask);
43 int is_masked(int32_t bin, char *mask, int32_t nrows);
44 int16_t fileID = 0;
45 
46 float ***aots, ***nlws; //arrays to contain the values needed to avg over for inversion
47 
48 /* -------------------------------------------------------------------- */
49 /* main */
50 
51 /* -------------------------------------------------------------------- */
52 int main(int argc, char* argv[]) {
53 
54  static int32_t nrows = 2160;
55  long iscan = 0; /* input scan number */
56  long npix = 0; /* input number pixels per scan */
57  long spix = 0; /* start pixel for subscene process */
58  long epix = -1; /* end pixel for subscene process */
59  long sscan = 0; /* start scan for subscene process */
60  long escan = -1; /* end scan for subscene process */
61  long nscan;
62  long nbands;
63  int32_t ndets;
64  long nruns; /* number of output detector runs */
65  long ipix;
66  long jscan; /* loop variables */
67  int band;
68  long scanidx;
69  long runidx;
70  int initial_mirror_side;
71  int goodscan;
72  idDS ds_id;
73 
74  l1str l1rec; /* generic level-1b scan structure */
75  l2str l2rec; /* generic level-2 scan structure */
76  tgstr tgrec; /* structure to store target values */
77  aestr aerec; /* structure to store aerosol values */
78  calstr** detrecArray; /* detrec for each pixel in a scan */
79 
80  filehandle l1file; /* input l1 file handle */
81 
82  double start_time;
83  long i, j, ib, runCounter, nir_l, nprods;
84  int32 *numbin, *basebin;
85  int32_t bin, ibin, bin_row, bin_col;
86  long **valid_pixel_array; //Valid pixel array 0=invalid, 1=pixel valid
87  int numContiguousDetectorRuns; // number of scans for detector runs
88  int status;
89 
90  char buf[5000], *mask, *maskfile, maskname[1000];
91  float lat, lon, latbin;
92  int32_t flagusemask;
93  uint32 required;
94 
95  if (argc == 1) {
96  l2gen_usage("l1det2det");
97  return 0;
98  }
99 
100  want_verbose = 1;
101 
102  setvbuf(stdout, NULL, _IOLBF, 0);
103  setvbuf(stderr, NULL, _IOLBF, 0);
104 
105  /* Initialize file handles */
106  //cdata_();
109 
110  /* Parse input parameters */
111  if (msl12_input(argc, argv, "l1det2det", &l1file) != 0) {
112  printf("-E- %s: Error parsing input parameters.\n", argv[0]);
113  exit(FATAL_ERROR);
114  }
115 
116  if (access(input->ifile[0], F_OK) || access(input->ifile[0], R_OK)) {
117  printf("-E- %s: Input file '%s' does not exist or cannot open.\n",
118  argv[0], input->ifile[0]);
119  exit(FATAL_ERROR);
120  }
121 
122  /* */
123  /* Open input file and get sensor */
124  /* and scan information from handle */
125  /* */
126  strcpy(l1file.name, input->ifile[0]);
127  l1file.geofile = input->geofile;
128 
129  if (openl1(&l1file) != 0) {
130  printf("-E- %s: Error opening %s for reading.\n",
131  argv[0], l1file.name);
132  exit(FATAL_ERROR);
133  }
134 
135  /*
136  * Check output file for matching sensorID
137  */
138  int existingSensorID;
139 
140  /* Save old HDF5 error handler */
141  H5E_auto_t old_func;
142  void *old_client_data;
143  H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data);
144 
145  /* Turn off error handling */
146  H5Eset_auto(H5E_DEFAULT, NULL, NULL);
147 
148  if (Hishdf(input->ofile[0]) == TRUE || H5Fis_hdf5(input->ofile[0]) == TRUE) {
149  ds_id = openDS(input->ofile[0]);
150  status = readAttr(ds_id, "sensorID", &existingSensorID);
151  if (status) {
152  printf("-E- %s: Problem reading output file: %s\n", argv[0], input->ofile[0]);
153  exit(EXIT_FAILURE);
154  }
155  endDS(ds_id);
156  if (l1file.sensorID != existingSensorID) {
157  printf("-E- %s: Mixing L2 data from different sensors, %s and %s.\n",
158  argv[0], sensorId2SensorName(l1file.sensorID), sensorId2SensorName(existingSensorID));
159  exit(EXIT_FAILURE);
160  }
161 
162  }
163  /* Restore previous HDF5 error handler */
164  H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
165 
166  npix = l1file.npix;
167  numContiguousDetectorRuns = input->ybox;
168  if (numContiguousDetectorRuns < 1)
169  numContiguousDetectorRuns = 1;
170 
171  if (numContiguousDetectorRuns > 2) {
172  printf("ybox > 2, sorry, only letting you use 2 - talk to management if you want more...\n");
173  numContiguousDetectorRuns = 2;
174  }
175  /* */
176  /* Allocate memory for L1 and L2 scan data */
177  /* */
178  if (alloc_l1(&l1file, &l1rec) == 0) {
179  printf("-E- %s: Unable to allocate L1 record.\n", argv[0]);
180  exit(FATAL_ERROR);
181  }
182  if (alloc_l2(&l1rec, &l2rec) == 0) {
183  printf("-E- %s: Unable to allocate L2 record.\n", argv[0]);
184  exit(FATAL_ERROR);
185  }
186 
187  /* Set the end pixel if it was not set by command argument */
188  if (l1_input->epixl == -1 || l1_input->epixl > l1file.npix)
189  l1_input->epixl = l1file.npix;
190  if (l1_input->eline == -1 || l1_input->eline > l1file.nscan)
191  l1_input->eline = l1file.nscan;
192  if (l1_input->spixl < 1)
193  l1_input->spixl = 1;
194  if (l1_input->sline < 1)
195  l1_input->sline = 1;
196 
197  spix = MAX(l1_input->spixl - 1, 0);
198  epix = MIN(l1_input->epixl - 1, l1file.npix - 1);
199  sscan = MAX(l1_input->sline - 1, 0);
200  escan = MIN(l1_input->eline - 1, l1file.nscan - 1);
201 
202  ndets = l1file.ndets;
203  // ensure there are full scans
204  if (sscan > 0) {
205  while (sscan % ndets)
206  sscan++;
207  }
208  int numContiguousDets = ndets * numContiguousDetectorRuns;
209  escan = ((escan + 1) / numContiguousDets) * numContiguousDets - 1;
210  //escan = ((escan + 1) / ndets) * ndets - 1;
211 
212  if (sscan > escan || spix > epix) {
213  printf("-E- %s: scan and pixel limits make no sense.\n", argv[0]);
214  printf(" start scan = %ld\n", sscan + 1);
215  printf(" end scan = %ld\n", escan + 1);
216  printf(" start pixel = %ld\n", spix + 1);
217  printf(" end pixel = %ld\n", epix + 1);
218  exit(FATAL_ERROR);
219  }
220 
221  /* Note: for the L1 file, npix is still the native scan pixel count */
222  l1file.spix = spix;
223  l1file.epix = epix;
224 
225  nscan = (escan - sscan) + 1;
226  npix = (epix - spix) + 1;
227  nbands = l1file.nbands;
228 
229  /* */
230  /* Transfer any additional header info to the L2 record headers */
231  /* */
232  l2rec.bindx = l1file.bindx;
233 
234  /* */
235  /* Set up parameters for strict ocean color forward processing */
236  /* */
237  input->proc_ocean = 1;
238  input->proc_land = 0;
239  input->proc_sst = 0;
240  input->atmocor = 1;
241  input->aer_opt = AERWANG;
242  l1_input->outband_opt = 0;
243  input->mode = FORWARD;
244  char outprod[L1_MAXPROD][32];
245  int nvars1d = 2;
246  char vars1Dnames[nvars1d][32]; // floating point one dimensional data to include in output - lon, lat
247  nprods = prodlist(l1file.sensorID, 0, (const char *) &(input->l2prod), (const char *) &(input->def_l2prod), outprod);
248 
249  /*
250  * Allocating memory for the multidimentional arrays of pixel index, nLw and aot
251  */
252  if ((valid_pixel_array = (long **) malloc(nscan * sizeof (long *))) == NULL) {
253  printf("-E- %s: Error allocating memory to the pixel index.\n", argv[0]);
254  exit(FATAL_ERROR);
255  }
256 
257  if ((aots = (float ***) malloc(nscan * sizeof (float *))) == NULL) {
258  printf("-E- : Error allocating memory to in situ inputs\n");
259  exit(FATAL_ERROR);
260  }
261  if ((nlws = (float ***) malloc(nscan * sizeof (float *))) == NULL) {
262  printf("-E- : Error allocating memory to in situ inputs\n");
263  exit(FATAL_ERROR);
264  }
265 
266  for (i = 0; i < nscan; i++) {
267  if ((valid_pixel_array[i] = (long *) calloc(npix, sizeof (long))) == NULL) {
268  printf("-E- %s: Error allocating memory to the pixel index.\n", argv[0]);
269  exit(FATAL_ERROR);
270  }
271 
272  if ((aots[i] = (float **) malloc(npix * sizeof (float *))) == NULL) {
273  printf("-E- %s: Error allocating memory to the AOT data.\n", argv[0]);
274  exit(FATAL_ERROR);
275  }
276  if ((nlws[i] = (float **) malloc(npix * sizeof (float *))) == NULL) {
277  printf("-E- %s: Error allocating memory to the nLw data.\n", argv[0]);
278  exit(FATAL_ERROR);
279  }
280  for (j = 0; j < npix; j++) {
281  if ((aots[i][j] = (float *) calloc(nbands, sizeof (float))) == NULL) {
282  printf("-E- %s: Error allocating memory to the aot data.\n", argv[0]);
283  exit(FATAL_ERROR);
284  }
285  if ((nlws[i][j] = (float *) calloc(nbands, sizeof (float))) == NULL) {
286  printf("-E- %s: Error allocating memory to the nLw data.\n", argv[0]);
287  exit(FATAL_ERROR);
288  }
289  }
290  }
291 
292  // Allocate memory for and set up deepwater mask
293  if ((mask = (char *) malloc(5940424 * sizeof (char))) == NULL) {
294  printf("-E- %s: Error allocating memory to the mask data\n", argv[0]);
295  exit(FATAL_ERROR);
296  }
297  if ((maskfile = getenv("OCDATAROOT")) == NULL) {
298  printf("-E- %s: OCDATAROOT directory undefined.\n", argv[0]);
299  exit(FATAL_ERROR);
300  }
301  strcpy(maskname, maskfile);
302  strcat(maskname, "/common/deep_water_mask_9km.dat\x0");
303 
304  if (read9km_mask(maskname, mask) > 0) {
305  printf("-E- %s: Failed reading the deep water mask file\n", argv[0]);
306  exit(FATAL_ERROR);
307  }
308 
309  /* ----------------- */
310  /* Set up bin arrays */
311  /* ----------------- */
312  if ((numbin = (int32 *) calloc(nrows, sizeof (int32))) == NULL) {
313  printf("-E- %s: Error allocating memory to numbin\n", argv[0]);
314  exit(FATAL_ERROR);
315  }
316  if ((basebin = (int32 *) calloc(nrows + 1, sizeof (int32))) == NULL) {
317  printf("-E- %s: Error allocating memory to basebin\n", argv[0]);
318  exit(FATAL_ERROR);
319  }
320 
321  bin = 0;
322  for (i = 0; i < nrows; i++) {
323  latbin = (i + 0.5) * (180.0 / nrows) - 90.0;
324  numbin[i] = (int32) (cos(latbin * PI / 180.0) * (2.0 * nrows) + 0.5);
325  bin += numbin[i];
326  }
327  basebin[0] = 1;
328  for (i = 1; i <= nrows; i++) {
329  basebin[i] = basebin[i - 1] + numbin[i - 1];
330  }
331 
336  l2_prod l2_str;
337  {
338  if (openL2(input->ifile[0], 0x0, &l2_str)) {
339  printf("-E- %s: Error reading L2 data %s.\n", argv[0], input->ifile[0]);
340  exit(EXIT_FAILURE);
341  }
342  }
343 
344 
345  strcpy(buf, l2_str.flagnames);
346 
347  strcpy(buf, "\x0");
348  setupflags(buf, input->flaguse, (uint32 *) & flagusemask, &required, &status,l2_str.l2_bits);
349  if (status < 0) {
350  printf("-E- %s: Error reading L2 flags %s.\n", argv[0], input->ifile[0]);
351  exit(FATAL_ERROR);
352  }
353 
354 
355  // freeing memory
356  {
357  closeL2(&l2_str,0);
358  freeL2(&l2_str);
359  }
360 
361  strcpy(vars1Dnames[0], "lon");
362  strcpy(vars1Dnames[1], "lat");
363 
364  nir_l = bindex_get(input->aer_wave_long);
365 
366  printf("\n\nBegin %s Processing\n", "l1det2det\x0");
367  printf("\nSensor is %s\n", sensorId2SensorName(l1file.sensorID));
368  printf("Sensor ID is %d\n", l1file.sensorID);
369  printf("Sensor has %d reflective bands\n", l1file.nbands);
370  printf("Sensor has %d emissive bands\n", l1file.nbandsir);
371  printf("Sensor resolution %d m\n", l1_input->resolution);
372  printf("Number of along-track detectors per band is %d\n", ndets);
373  printf("Number of input pixels per scan is %d\n", l1file.npix);
374  printf("Processing pixels %ld to %ld\n", spix + 1, epix + 1);
375  printf("Processing scans %ld to %ld\n", sscan + 1, escan + 1);
376 
377  start_time = now();
378  printf("\nBegin l1det2det processing at %s\n\n", ydhmsf(start_time, 'L'));
379 
380  /*
381  * Read file scan by scan, convert to L2
382  * determine valid detector "runs" and
383  * populate the nLw and tau arrays needed
384  * for averaging to insert into inverse
385  * processing.
386  */
387  for (iscan = sscan; iscan <= escan; iscan++) {
388 
389  scanidx = iscan - sscan;
390 
391  if (getl1rec(iscan, 1, &l1rec) != 0) {
392  exit(FATAL_ERROR);
393  }
394  // First Line!
395  if (iscan == sscan) {
396  initial_mirror_side = l1rec.mside;
397  }
398 
399  if ((iscan % 50) == 0)
400  printf("Processing scan #%6ld (%ld of %ld) after %6.0f seconds\n",
401  iscan, iscan - sscan + 1, escan - sscan + 1, now() - start_time);
402 
403  /* */
404  /* Convert the L1B radiances to L2 */
405  /* */
406  convl12(&l1rec, &l2rec, 0, l1rec.npix - 1, NULL);
407 
408  /* */
409  /* Loop through each pixel and check exclusion criteria */
410  /* on pixel flags and values */
411  /* */
412  for (ipix = 0; ipix < l1rec.npix; ipix++) {
413  ibin = 1;
414 
415  lat = l1rec.lat[ipix];
416  lon = l1rec.lon[ipix];
417  bin_row = (int32_t) ((90.0 + lat) * ((float64) nrows / (float64) 180.0));
418  bin_col = (int32_t) ((float64) numbin[bin_row] * (lon + 180.0) / (float64) 360.0);
419  bin = basebin[bin_row] + bin_col;
420  ibin = (int32_t) is_masked(bin, mask, nrows);
421 
422  if (((l1rec.flags[ipix] & flagusemask) == 0) &&
423  l2rec.chl[ipix] > 0.0 &&
424  l2rec.chl[ipix] <= input->chlthreshold &&
425  l2rec.taua[ipix * nbands + nir_l] > 0.0 &&
426  l2rec.taua[ipix * nbands + nir_l] <= input->aotthreshold && ibin > 0) {
427 
428  valid_pixel_array[scanidx][ipix] = 1;
429  for (ib = 0; ib < nbands; ib++) {
430  nlws[scanidx][ipix][ib] = l2rec.nLw [ipix * nbands + ib];
431  aots[scanidx][ipix][ib] = l2rec.taua[ipix * nbands + ib];
432  }
433  }
434  /*
435  * Once a detector run is complete,
436  * check the all lines in the scan to ensure all detectors are valid
437  */
438  if (l1rec.detnum == ndets - 1) {
439  if (numContiguousDetectorRuns == 1 || l1rec.mside != initial_mirror_side) {
440  for (i = 0; i < ndets * numContiguousDetectorRuns; i++) {
441  if (!valid_pixel_array[scanidx - i][ipix]) {
442  for (j = 0; j < ndets * numContiguousDetectorRuns; j++) {
443  valid_pixel_array[scanidx - j][ipix] = 0;
444  }
445  break;
446  }
447  }
448 
449  }
450  }
451  }
452  }
453 
454  printf("\nEnd of line-by-line processing at %s\n", ydhmsf(now(), 'L'));
455  printf("Processing Rate = %f scans/sec\n", nscan / (now() - start_time));
456 
457  // Free memory associated with deepwater mask
458  free(mask);
459  free(numbin);
460  free(basebin);
461 
462  /*
463  * Count the number of valid detector runs (i.e. scans with all detectors valid)
464  */
465  nruns = 0;
466  for (iscan = sscan; iscan <= escan; iscan += ndets) {
467  scanidx = iscan - sscan;
468  for (ipix = 0; ipix < l1rec.npix; ipix++) {
469  if (valid_pixel_array[scanidx][ipix])
470  nruns++;
471  }
472  }
473 
474  if (!nruns) {
475  printf("-W- %s: No analysis pixel data found in the L2 file %s\n", argv[0], input->ifile[0]);
476  } else {
477 
478  printf("\n\nNow extracting valid pixel runs\n");
479  printf("Along-track pixel runs of %d found: %ld\n", numContiguousDets, nruns);
480 
481  start_time = now();
482 
483  /*
484  * Allocate detrec, aer and tgt structures
485  */
486  if ((detrecArray = (calstr **) malloc(l1rec.npix * sizeof (calstr *))) == NULL) {
487  printf("-E- : Error allocating memory for detector record structures\n");
488  exit(EXIT_FAILURE);
489  }
490  for (i = 0; i < l1rec.npix; i++) {
491  detrecArray[i] = alloc_calrec(ndets, nbands, nprods, nvars1d);
492  }
493 
494 
495  alloc_aer(l1rec.npix, nbands, &aerec);
496  alloc_target(l1rec.npix, nbands, &tgrec);
497  /*
498  * set up the bits for inversion
499  */
500  input->aer_opt = FIXAOT;
501  input->mode = INVERSE_NLW;
502  aerec.mode = ON;
503  tgrec.mode = ON;
504  l2rec.tgrec = &tgrec;
505 
506  /*
507  * Open the output file. It will be created if necessary
508  */
509 
510  runCounter = 0;
511  ds_id = calfile_open(input->ofile[0], l1file.sensorID, nruns, ndets, nprods, nvars1d, outprod, vars1Dnames, &runCounter, DET2DET);
512 
513  /*
514  * Fill up detrec with detector info and grab avg aot/nlws
515  * for use in inversion to fill in vLt array in detrec
516  * along with the other
517  * detector values...
518  */
519 
520  runCounter--; //nruns index
521  int runNum = 0; //just for nice printing on output...
522 
523  for (iscan = sscan; iscan <= escan; iscan += ndets * numContiguousDetectorRuns) {
524  goodscan = 0;
525  runidx = iscan - sscan;
526  for (ipix = 0; ipix < l1rec.npix; ipix++) {
527  if (valid_pixel_array[runidx][ipix]) {
528  goodscan = 1;
529  break;
530  }
531  }
532  if (goodscan) {
533  // For "good scans", loop through detectors for the valid runs and get the pixel info for detrec
534  for (jscan = iscan; jscan < iscan + ndets * numContiguousDetectorRuns; jscan++) {
535  scanidx = jscan - sscan;
536  int detidx = jscan - iscan;
537  if (detidx >= ndets)
538  detidx -= ndets;
539 
540  if (getl1rec(jscan, 1, &l1rec) != 0) {
541  exit(EXIT_FAILURE);
542  }
543  // For the first line in the scan, fill up the per run values in detrec
544  if (detidx == 0) {
545  int16_t year, day;
546  double sec;
547  unix2yds(l1rec.scantime, &year, &day, &sec);
548 
549  for (ipix = 0; ipix < l1rec.npix; ipix++) {
550  if (valid_pixel_array[scanidx][ipix]) {
551  detrecArray[ipix]->sensorID = l1rec.l1file->sensorID;
552  detrecArray[ipix]->year = (int32_t) year;
553  detrecArray[ipix]->day = (int32_t) day;
554  detrecArray[ipix]->msec = (int32_t) (sec * 1.e3);
555  detrecArray[ipix]->mside = l1rec.mside;
556  detrecArray[ipix]->iscan = (int16_t) jscan;
557  detrecArray[ipix]->pixnum = l1rec.pixnum[ipix];
558  detrecArray[ipix]->vars1D[0] = l1rec.lon[ipix];
559  detrecArray[ipix]->vars1D[1] = l1rec.lat[ipix];
560  // average the nLws and aots over the pixels in ndets*numContiguousDetectorRuns
561  // and fills in the aerec and tgrec arrays needed for the inversion step
562  inversion_init(ndets*numContiguousDetectorRuns, runidx, nbands, ipix, &aerec, &tgrec);
563  }
564  }
565  }
566  // The Lt array is filled and the avg nLw and taua needed for the inversion
567  // are set up in this loop
568  for (ipix = 0; ipix < l1rec.npix; ipix++) {
569  if (valid_pixel_array[scanidx][ipix]) {
570  // average the nLws and aots over the pixels in ndets*numContiguousDetectorRuns
571  // and fills in the aerec and tgrec arrays needed for the inversion step
572  // inversion_init(ndets*numContiguousDetectorRuns, runidx, l1rec.nbands, ipix, &aerec, &tgrec);
573  for (band = 0; band < nbands; band++) {
574  ib = ipix * nbands + band;
575  detrecArray[ipix]->Lt[band][detidx] = (float) l1rec.Lt[ib];
576  }
577  }
578  }
579  /* */
580  /* Convert the L1B radiances to L2 */
581  /* */
582  convl12(&l1rec, &l2rec, 0, l1rec.npix - 1, &aerec);
583  /* */
584  /* Convert back to L1B to get vLts */
585  /* */
586  convl21(&l2rec, &tgrec, 0, l1rec.npix - 1, l1rec.Lt, NULL);
587 
588  // set detrec data and vLts obtained via inversion step
589  for (ipix = 0; ipix < l1rec.npix; ipix++) {
590  if (valid_pixel_array[scanidx][ipix]) {
591  // The vLts are filled here
592  for (band = 0; band < nbands; band++) {
593  ib = ipix * nbands + band;
594  detrecArray[ipix]->vLt[band][detidx] = (float) l1rec.Lt[ib];
595  }
596  // The detrec entries for the other request products are populated here
597  for (i = 0; i < nprods; i++) {
598  if (strcmp(outprod[i], "pixnum") != 0 &&
599  strcmp(outprod[i], "mside") != 0 &&
600  strncmp(outprod[i], "Lt", 2) != 0 &&
601  strncmp(outprod[i], "vLt", 3) != 0 &&
602  strcmp(outprod[i], "detnum") != 0 &&
603  strcmp(outprod[i], "l2_flags") != 0) {
604  // get the product index record
605  l2prodstr *p;
606 
607  if ((p = get_l2prod_index(outprod[i], l1rec.l1file->sensorID,
608  nbands + l1file.nbandsir, l1rec.npix, l1rec.l1file->nscan, l1rec.l1file->iwave)) == NULL) {
609  fprintf(stderr,
610  "-E- %s line %d: product index failure.\n",
611  __FILE__, __LINE__);
612  return (1);
613  };
614 
615  // extract the product
616  float *pbuf;
617  pbuf = prodgen(p, &l2rec);
618 
619  // fill up detrec data
620  detrecArray[ipix]->data[i][detidx] = pbuf[ipix];
621  }
622  }
623  }
624  }
625 
626  // Write out the valid runs for this scan
627  if (detidx == ndets - 1) {
628  for (ipix = 0; ipix < l1rec.npix; ipix++) {
629  if (valid_pixel_array[scanidx][ipix]) {
630  runCounter++;
631  runNum++;
632  if ((runNum % 500) == 0)
633  printf("Writing run %d of %ld\n", runNum, nruns);
634  calfile_write(ds_id, detrecArray[ipix], runCounter, nruns, ndets, nprods, nbands, nvars1d, outprod, vars1Dnames, DET2DET);
635  }
636  }
637  }
638  }
639  }
640  }
641  printf("\nEnd pixel-run extraction at %s, pixel-run number found: %ld\n\n\n", ydhmsf(now(), 'L'), nruns);
642  if (calfile_close(ds_id) != 0) {
643  printf("Trouble closing file %s\n", input->ofile[0]);
644  exit(EXIT_FAILURE);
645  }
646  // Free up some memory
647  for (i = 0; i < l1rec.npix; i++) {
648  free_calrec(detrecArray[i], nbands, nprods);
649  }
650 
651  }
652 
653  for (ib = 0; ib < nbands; ib++) {
654  free(aots[ib]);
655  free(nlws[ib]);
656  }
657  free(aots);
658  free(nlws);
659 
660  /* */
661  /* Close all files */
662  /* */
663  closel1(&l1file);
664 
665  if (nruns > 0) return (EXIT_SUCCESS);
666  else return (NOMATCH_ERROR);
667 }
char * ydhmsf(double dtime, char zone)
Definition: ydhmsf.c:12
#define L1_MAXPROD
Definition: filehandle.h:20
void setupflags(char *flagdef, char *flaguse, uint32_t *flagusemask, uint32_t *required, int *status, int32_t *BITS)
Definition: setupflags.c:7
int32 l1file(int32 sdfid, int32 *nsamp, int32 *nscans, int16 *dtynum)
Definition: l1stat_chk.c:586
#define MAX(A, B)
Definition: swl0_utils.h:25
#define MIN(x, y)
Definition: rice.h:169
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
int j
Definition: decode_rs.h:73
#define INVERSE_NLW
Definition: filehandle.h:13
int32_t day
int msl12_input(int argc, char *argv[], const char *progName, filehandle *l1file)
Definition: msl12_input.c:4359
int status
Definition: l1_czcs_hdf.c:32
float *** nlws
idDS openDS(const char *filename)
Definition: wrapper.c:606
int calfile_write(idDS ds_id, calstr *calrec, int recnum, int ydim, int xdim, int nprods, int nbands, int nvars1d, char l2prods[L1_MAXPROD][32], char vars1Dnames[L1_MAXPROD][32], caltype ctype)
int alloc_aer(int32_t npix, int32_t nbands, aestr *rec)
Definition: alloc_aer.c:12
#define NOMATCH_ERROR
Definition: l12_parms.h:82
#define NULL
Definition: decode_rs.h:63
void filehandle_init(filehandle *file)
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
int32 nrows
#define TRUE
Definition: rice.h:165
#define ON
Definition: l1.h:44
void msl12_input_init()
Definition: msl12_input.c:495
This should be set to the NetCDF standard name if exists for this product Create a function that computes your product edit get_myprod c add prototype to l12_proto h add get_myprod c to L2GEN_PRODUCT_FILES in CMakeLists txt Add an entry to the output routine to call your function edit prodgen c edit function prodgen() case CAT_myprod pbuf
int32 nscan
Definition: l1_czcs_hdf.c:19
int32_t closeL2(l2_prod *l2_str, int32_t ifile)
Definition: readL2scan.c:1995
int l2gen_usage(const char *prog)
Definition: msl12_input.c:4414
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
instr * input
#define FORWARD
Definition: regen_attr.h:12
int readAttr(idDS ds_id, const char *nam, void *data)
#define PI
Definition: l3_get_org.c:6
int alloc_target(int32_t npix, int32_t nbands, tgstr *rec)
Definition: alloc_target.c:12
int32_t prodlist(int32_t sensorID, int32_t evalmask, const char *inprod, const char *defprod, char outprod[L1_MAXPROD][32])
int alloc_l2(l1str *l1rec, l2str *l2rec)
Definition: alloc_l2.c:17
int bindex_get(int32_t wave)
Definition: windex.c:45
#define AERWANG
Definition: l12_parms.h:23
int32_t openL2(const char *fname, const char *plist, l2_prod *l2_str)
Definition: readL2scan.c:316
int convl12(l1str *l1rec, l2str *l2rec, int32_t spix, int32_t epix, aestr *aerec)
Definition: convl12.c:16
void free_calrec(calstr *calrec, int nbands, int nprods)
l1_input_t * l1_input
Definition: l1_options.c:9
#define FATAL_ERROR
Definition: swl0_parms.h:5
INT32 getl1rec(INT16 sceneFrameNum, swl0scene *scene, swl0ctl *l0ctl, input_sType navinp[], navblk_sType navblk[], tilt_states_sType *tiltblk, swl1rec l1rec[])
Definition: getl1rec.c:45
int16_t fileID
int want_verbose
a context in which it is NOT documented to do so subscript which cannot be easily calculated when extracting TONS attitude data from the Terra L0 files Corrected several defects in extraction of entrained ephemeris and and as HDF file for both the L1A and Geolocation enabling retrieval of South Polar DEM data Resolved Bug by changing to opent the geolocation file only after a successful read of the L1A and also by checking for fatal errors from not restoring C5 and to report how many of those high resolution values were water in the new WaterPresent SDS Added valid_range attribute to Land SeaMask Changed to bilinearly interpolate the geoid_height to remove artifacts at one degree lines Made corrections to const qualification of pointers allowed by new version of M API library Removed casts that are no longer for same not the geoid Corrected off by one error in calculation of high resolution offsets Corrected parsing of maneuver list configuration parameter Corrected to set Height SDS to fill values when geolocation when for elevation and land water mask
Definition: HISTORY.txt:114
void unix2yds(double usec, short *year, short *day, double *secs)
@ DET2DET
Definition: calfile_utils.h:21
void closel1(filehandle *l1file)
Definition: l1_io.c:73
int main(int argc, char *argv[])
calstr * alloc_calrec(int ydim, int nbands, int nprods, int nvar1d)
void inversion_init(long ndets, long iscan, int nbands, long ipix, aestr *aerec, tgstr *tgrec)
int32_t nbands
const char * sensorId2SensorName(int sensorId)
Definition: sensorInfo.c:273
int32 spix
Definition: l1_czcs_hdf.c:21
int32_t iscan
void * prodgen(l2prodstr *p, l2str *l2rec)
Definition: prodgen.c:101
u5 which has been done in the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT production Changes from v6 which may affect scientific the sector rotation may actually occur during one of the scans earlier than the one where it is first reported As a the b1 values are about the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT to fill pixels affected by dead subframes with a special value Output the metadata of noisy and dead subframe Dead Subframe EV and Detector Quality Flag2 Removed the function call of Fill_Dead_Detector_SI to stop interpolating SI values for dead but also for all downstream products for science test only Changes from v5 which will affect scientific to conform to MODIS requirements Removed the Mixed option from the ScanType in the code because the L1A Scan Type is never Mixed Changed for ANSI C compliance and comments to better document the fact that when the HDF_EOS metadata is stricly the and products are off by and in the track respectively Corrected some misspelling of RCS swir_oob_sending_detector to the Reflective LUTs to enable the SWIR OOB correction detector so that if any of the sending detectors becomes noisy or non near by good detectors from the same sending band can be specified as the substitute in the new look up table Code change for adding an additional dimension of mirror side to the Band_21_b1 LUT to separate the coefficient of the two mirror sides for just like other thermal emissive so that the L1B code can calibrate Band scan to scan with mirror side dependency which leads better calibration result Changes which do not affect scientific when the EV data are not provided in this Crosstalk Correction will not be performed to the Band calibration data Changes which do not affect scientific and BB_500m in L1A Logic was added to turn off the or to spatial aggregation processes and the EV_250m_Aggr1km_RefSB and EV_500m_Aggr1km_RefSB fields were set to fill values when SDSs EV_250m and EV_500m are absent in L1A file Logic was added to skip the processing and turn off the output of the L1B QKM and HKM EV data when EV_250m and EV_500m are absent from L1A In this the new process avoids accessing and reading the and L1A EV skips and writing to the L1B and EV omits reading and subsampling SDSs from geolocation file and writing them to the L1B and omits writing metadata to L1B and EV and skips closing the L1A and L1B EV and SDSs Logic was added to turn off the L1B OBC output when the high resolution OBC SDSs are absent from L1A This is accomplished by skipping the openning the writing of metadata and the closing of the L1B OBC hdf which is Bit in the scan by scan bit QA has been changed Until now
Definition: HISTORY.txt:361
Definition: dfutils.h:28
int read9km_mask(char *file, char *mask)
Definition: read9km_mask.c:25
int convl21(l2str *l2rec, tgstr *tgrec, int32_t spix, int32_t epix, float *vLt, vcstr *vrec)
Definition: convl21.c:15
int32 epix
Definition: l1_czcs_hdf.c:23
int32_t alloc_l1(filehandle *l1file, l1str *l1rec)
Definition: alloc_l1.c:18
int calfile_close(idDS ds_id)
int endDS(idDS ds_id)
Definition: wrapper.c:624
idDS calfile_open(char *ofile, int sensorID, int ydim, int xdim, int nprods, int nvars1d, char l2prods[L1_MAXPROD][32], char vars1Dnames[L1_MAXPROD][32], long *numExistingRecords, caltype ctype)
Definition: calfile_utils.c:48
float *** aots
int i
Definition: decode_rs.h:71
int openl1(filehandle *l1file)
Definition: l1_io.c:230
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int32_t freeL2(l2_prod *l2_str)
Definition: readL2scan.c:2083
#define FIXAOT
Definition: l12_parms.h:30
int npix
Definition: get_cmp.c:28
int is_masked(int32_t bin, char *mask, int32_t nrows)
Definition: read9km_mask.c:65
float p[MODELMAX]
Definition: atrem_corl1.h:131
int32_t get_l2prod_index(const l2_prod &l2, const char *prodname)
Definition: l2bin.cpp:109