NASA Logo
Ocean Color Science Software

ocssw V2022
main_l2mapgen.c
Go to the documentation of this file.
1 /*
2 Inputs:
3  see usage...
4 Output:
5  Eight-bit PGM data stream.
6 
7 Code draws heavily on swplatecar, smigen, and l2bin
8 
9 Original Development:
10  Sean Bailey -- 30 June 2006
11 
12 Modifications:
13  SWB, 17 Jul 2008, fixed the threshold parameter - long/float discrepancy
14 
15  */
16 
17 #include <stdlib.h>
18 #include <math.h>
19 #include <string.h>
20 #include <stdint.h>
21 
22 #include <netcdf.h>
23 #include <png.h>
24 #include "miscstruct.h"
25 #include "miscanfill.h"
26 #include "mipoly.h"
27 #include "mfhdf.h"
28 #include <clo.h>
29 #include "l2mapgen.h"
30 #include "l2mapgen_input.h"
31 #include <genutils.h>
32 #include <readL2scan.h>
33 
34 #include <stdio.h>
35 #include <X11/X.h>
36 #include <X11/Xlib.h>
37 #include <unistd.h>
38 
39 #include <geotiffio.h>
40 #include <geo_normalize.h>
41 #include <geo_tiffp.h>
42 #include <geo_keyp.h>
43 #include <xtiffio.h>
44 #include <geokeys.h>
45 
46 
47 #define ROOT2 1.4142135623730950488016887242096981
48 #define PI 3.14159265358979323846
49 #define BINBELOWTHRESH 110
50 
51 #define CALLOC(ptr,typ,num) { \
52  (ptr) = (typ *)calloc((num) , sizeof(typ)); \
53  if((ptr) == NULL){ \
54  fprintf(stderr,"-E- %s line %d: Memory allocation failure.\n", \
55  __FILE__,__LINE__); \
56  exit(EXIT_FAILURE); \
57  } \
58 }
59 
60 /* function prototypes */
61 int scan_convert(XPoint *ptsIn);
62 int collect_bins(int number_of_initial_points, XPoint *initial_point,
63  int *span_width);
64 int miCreateETandAET();
65 int miInsertionSort();
66 
67 static int *binsoverlain = NULL;
68 static int binsperpixel = 0;
69 static int numoverlain;
70 static int width, height;
71 static double scale;
72 
73 int32_t l3m_params = 0;
76 char **unit_list;
77 char **scaling_list;
78 float *maximum_list;
79 float *minimum_list;
80 char **palette_list;
82 
83 int main(int argc, char *argv[]) {
84 
85  static instr input;
86  static l2_prod l2_str[MAXNFILES];
87  static meta_l2Type meta_l2;
88  static char buf[65535];
89  char qual[9];
90 
91  int32_t npix, nscans;
92  int32_t nfiles;
93  int status;
94  int32_t l2_flags;
95  byte quality;
96  byte goodpix;
97  int prodidx = -1;
98  int qualidx = -1;
99  double latmax = -90.0;
100  double latmin = 90.0;
101  double lonmin = 180.0;
102  double lonmax = -180.0;
103 
104  double *sum;
105  unsigned char *mean;
106  unsigned char *mask;
107  int *count;
108 
109  uint32_t numbins, numoutpix;
110  XPoint corners[8]; /* actually, 4 pixel corners + 4 side midpoints */
111  float64 threshold;
112  float nrad, srad, wrad, erad;
113  int i, j, k, m, n, ii;
114  int progress;
115  uint32_t mask_252, mask_253, all_masks;
116  uint32_t mask_glint = 0;
117  uint32_t required_mask;
118 
119  char scale_type[50];
120  uint8_t default_palfile = 0;
121  char *cptr;
122 
123  static uint16_t maxval = 250;
124  float val;
125  float slope = 1.0;
126  float intercept = 0.0;
127  int32_t prod_num = -1;
128  byte *rgb;
129  short *r, *g, *b;
130 
131  FILE *fp = NULL;
132  FILE *outfp = NULL;
133 
134 
135  /* hold all of the command line options */
137 
138  if (argc == 1 || strcmp(argv[1], "-version") == 0 || strcmp(argv[1], "--version") == 0) {
139  want_verbose = 0;
143  exit(EXIT_FAILURE);
144  }
145 
146  if (l2mapgen_input(argc, argv, list, &input) != 0) {
148  exit(EXIT_FAILURE);
149  }
150 
151  if (strcasecmp(input.palfile, "default") == 0) {
152  default_palfile = 1;
153  }
154 
155  /* Read product table */
156  fp = fopen(input.product_table, "r");
157  if (fp == 0x0) {
158  fprintf(stderr, "SMIGEN product table \"%s\" not found.\n", input.product_table);
159  exit(EXIT_FAILURE);
160  }
161 
162  l3m_params = 0;
163  while (fgets(buf, 128, fp) != NULL) {
164  if ((buf[0] >= 0x41) && (buf[0] <= 0x5a)) l3m_params++;
165  }
166  fseek(fp, 0, SEEK_SET);
167 
168  parmname_list = (char**) calloc(l3m_params, sizeof (char *));
169  parmname_short = (char**) calloc(l3m_params, sizeof (char *));
170  unit_list = (char**) calloc(l3m_params, sizeof (char *));
171  scaling_list = (char**) calloc(l3m_params, sizeof (char *));
172  palette_list = (char**) calloc(l3m_params, sizeof (char *));
173  maximum_list = (float *) calloc(l3m_params, sizeof (float));
174  minimum_list = (float *) calloc(l3m_params, sizeof (float));
175  precision_list = (char **) calloc(l3m_params, sizeof (char *));
176 
177  i = 0;
178  while (fgets(buf, 128, fp) != NULL) {
179  if ((buf[0] >= 0x41) && (buf[0] <= 0x5a)) {
180 
181  cptr = strtok(buf, ":");
182  parmname_list[i] = (char*) malloc(strlen(cptr) + 1);
183  strcpy(parmname_list[i], cptr);
184 
185  cptr = strtok(NULL, ":");
186  parmname_short[i] = (char*) malloc(strlen(cptr) + 1);
187  strcpy(parmname_short[i], cptr);
188 
189  cptr = strtok(NULL, ":");
190  unit_list[i] = (char*) malloc(strlen(cptr) + 1);
191  strcpy(unit_list[i], cptr);
192 
193  cptr = strtok(NULL, ":");
194  scaling_list[i] = (char*) malloc(strlen(cptr) + 1);
195  strcpy(scaling_list[i], cptr);
196 
197  cptr = strtok(NULL, ":");
198  minimum_list[i] = (float) atof(cptr);
199 
200  cptr = strtok(NULL, ":");
201  maximum_list[i] = (float) atof(cptr);
202 
203  cptr = strtok(NULL, ":");
204  precision_list[i] = (char*) malloc(strlen(cptr) + 1);
205  strcpy(precision_list[i], cptr);
206 
207  cptr = strtok(NULL, "\n");
208  palette_list[i] = (char*) malloc(strlen(cptr) + 1);
209  strcpy(palette_list[i], cptr);
210 
211  i++;
212  }
213  }
214  fclose(fp);
215 
216 
217  for (i = 0; i < l3m_params; i++) {
218 
219  if (strcmp(parmname_short[i], input.prod) == 0) {
220 
221  prod_num = i;
222 
223  /* define scaling */
224  strcpy(scale_type, scaling_list[i]);
225  if (input.stype == 1) strcpy(scale_type, "linear");
226  if (input.stype == 2) strcpy(scale_type, "logarithmic");
227 
228  if (input.datamin == 0.0) input.datamin = minimum_list[i];
229  if (input.datamax == 0.0) input.datamax = maximum_list[i];
230 
231 
232  if (strcmp(scale_type, "linear") == 0) {
233 
234  strcpy(scale_type, "LINEAR");
235  intercept = input.datamin;
236  slope = (input.datamax - intercept) / maxval;
237  } else if (strcmp(scale_type, "logarithmic") == 0) {
238 
239  strcpy(scale_type, "LOG");
240 
241  intercept = log10(input.datamin);
242  slope = (log10(input.datamax) - intercept) / maxval;
243  }
244 
245  /* Read palette file */
246  if (default_palfile) {
247  strcpy(input.palfile, input.palette_dir);
248  strcat(input.palfile, "/");
249  strcat(input.palfile, palette_list[i]);
250  strcat(input.palfile, ".pal");
251  }
252 
253  if (!(r = (short *) calloc(256, sizeof (short)))) {
254  fprintf(stderr, "smigen: Error allocating space for red.\n");
255  return -1;
256  };
257  if (!(g = (short *) calloc(256, sizeof (short)))) {
258  fprintf(stderr, "smigen: Error allocating space for green.\n");
259  return -1;
260  };
261  if (!(b = (short *) calloc(256, sizeof (short)))) {
262  fprintf(stderr, "smigen: Error allocating space for blue.\n");
263  return -1;
264  };
265 
266  if (getlut_file(input.palfile, r, g, b)) {
267  fprintf(stderr, "Error reading palette file %s\n", input.palfile);
268  free(r);
269  free(g);
270  free(b);
271  return -1;
272  }
273  if (input.mask) {
274  r[252] = 128;
275  g[252] = 128;
276  b[252] = 128;
277  r[253] = 160;
278  g[253] = 82;
279  b[253] = 45;
280  r[254] = 255;
281  g[254] = 255;
282  b[254] = 255;
283  r[255] = 0;
284  g[255] = 0;
285  b[255] = 0;
286  }
287  for (i = 0; i < 256; i++) {
288  input.palette[i * 3] = r[i];
289  input.palette[i * 3 + 1] = g[i];
290  input.palette[i * 3 + 2] = b[i];
291  }
292 
293  break;
294  } // if prod matches
295  } // for i
296 
297  if (prod_num == -1) {
298  /* define scaling */
299  strcpy(scale_type, "LINEAR");
300  if (input.stype == 1) strcpy(scale_type, "linear");
301  if (input.stype == 2) strcpy(scale_type, "logarithmic");
302 
303  if (input.datamin == 0.0) input.datamin = 0.001;
304  if (input.datamax == 0.0) input.datamax = 1.0;
305 
306 
307  if (strcmp(scale_type, "linear") == 0) {
308 
309  strcpy(scale_type, "LINEAR");
310  intercept = input.datamin;
311  slope = (input.datamax - intercept) / maxval;
312  }
313 
314  if (strcmp(scale_type, "logarithmic") == 0) {
315 
316  strcpy(scale_type, "LOG");
317 
318  intercept = log10(input.datamin);
319  slope = (log10(input.datamax) - intercept) / maxval;
320  }
321 
322  /* Read default.pal palette file */
323  strcpy(input.palfile, input.palette_dir);
324  strcat(input.palfile, "/default.pal");
325 
326  if (!(r = (short *) calloc(256, sizeof (short)))) {
327  fprintf(stderr, "smigen: Error allocating space for red.\n");
328  return -1;
329  };
330  if (!(g = (short *) calloc(256, sizeof (short)))) {
331  fprintf(stderr, "smigen: Error allocating space for green.\n");
332  return -1;
333  };
334  if (!(b = (short *) calloc(256, sizeof (short)))) {
335  fprintf(stderr, "smigen: Error allocating space for blue.\n");
336  return -1;
337  };
338 
339  if (getlut_file(input.palfile, r, g, b)) {
340  fprintf(stderr, "Error reading palette file %s\n", input.palfile);
341  free(r);
342  free(g);
343  free(b);
344  return -1;
345  }
346  if (input.mask) {
347  r[252] = 128;
348  g[252] = 128;
349  b[252] = 128;
350  r[253] = 160;
351  g[253] = 82;
352  b[253] = 45;
353  r[254] = 255;
354  g[254] = 255;
355  b[254] = 255;
356  r[255] = 0;
357  g[255] = 0;
358  b[255] = 0;
359  }
360  for (i = 0; i < 256; i++) {
361  input.palette[i * 3] = r[i];
362  input.palette[i * 3 + 1] = g[i];
363  input.palette[i * 3 + 2] = b[i];
364  }
365  }
366 
367  /* Single HDF input */
368  /* ---------------- */
369  int singleInputFile = 0;
370  if (Hishdf(input.ifile) == TRUE) {
371  singleInputFile = 1;
372  } else {
373  int fid;
374  status = nc_open(input.ifile, NC_NOWRITE, &fid);
375  if (status == NC_NOERR) {
376  singleInputFile = 1;
377  nc_close(fid);
378  }
379  }
380  if (singleInputFile) {
381  nfiles = 1;
382  status = openL2(input.ifile, 0x0, &l2_str[0]);
383 
384  status = readL2meta(&meta_l2, 0);
385  if (meta_l2.northlat >= latmax) latmax = meta_l2.northlat;
386  if (meta_l2.southlat <= latmin) latmin = meta_l2.southlat;
387  if (meta_l2.westlon <= lonmin) lonmin = meta_l2.westlon;
388  if (meta_l2.eastlon >= lonmax) lonmax = meta_l2.eastlon;
389 
390  closeL2(&l2_str[0], 0);
391  fprintf(stderr, "Single HDF input\n");
392  } else {
393 
394  /* Filelist input - Determine number of input files */
395  /* ------------------------------------------------ */
396  nfiles = 0;
397  fp = fopen(input.ifile, "r");
398  if (fp == NULL) {
399  fprintf(stderr, "Input listing file: \"%s\" not found.\n", input.ifile);
400  return -1;
401  }
402  while (fgets(buf, 256, fp) != NULL) nfiles++;
403  fclose(fp);
404  fprintf(stderr, "%d input files\n", nfiles);
405 
406 
407  /* Open L2 input files */
408  /* ------------------- */
409  fp = fopen(input.ifile, "r");
410  for (i = 0; i < nfiles; i++) {
411  fgets(buf, 256, fp);
412  buf[strlen(buf) - 1] = 0;
413  status = openL2(buf, 0x0, &l2_str[i]);
414 
415  status = readL2meta(&meta_l2, i);
416  if (meta_l2.northlat >= latmax) latmax = meta_l2.northlat;
417  if (meta_l2.southlat <= latmin) latmin = meta_l2.southlat;
418  if (meta_l2.westlon <= lonmin) lonmin = meta_l2.westlon;
419  if (meta_l2.eastlon >= lonmax) lonmax = meta_l2.eastlon;
420 
421  closeL2(&l2_str[i], i);
422 
423 
424  } /* ifile loop */
425  fclose(fp);
426  }
427  /* Setup flag masking */
428  /* --------------- */
429  if (input.flaguse[0] == 0) {
430  strcpy(input.flaguse, DEF_FLAG);
431  } else {
432  input.mask = 1;
433  }
434  strcpy(buf, l2_str[0].flagnames);
435  setupflags(buf, "HIGLINT", &mask_252, &required_mask, &status,l2_str[0].l2_bits);
436  setupflags(buf, "LAND", &mask_253, &required_mask, &status,l2_str[0].l2_bits);
437  setupflags(buf, input.flaguse, &all_masks, &required_mask, &status,l2_str[0].l2_bits);
438 
439  if ((all_masks & mask_252) != 0)
440  mask_glint = 1;
441 
442  /* Make sure L2 product exists for every input L2 file */
443  /* ---------------------------------------------------------------- */
444  status = 0;
445  for (j = 0; j < nfiles; j++) {
446  for (i = 0; i < l2_str[j].nprod; i++) {
447  if (strcmp(l2_str[j].prodname[i], input.prod) == 0) {
448  status++;
449  }
450  }
451  }
452 
453  if (status != nfiles) {
454  fprintf(stderr, "Product %s not found in all L2 file(s)\n", input.prod);
455  exit(EXIT_FAILURE);
456  }
457 
458  /* Get the box boundaries. */
459  if (input.north == input.south && input.west == input.east) {
460  input.north = latmax;
461  input.south = latmin;
462  input.west = lonmin;
463  input.east = lonmax;
464  }
465 
466  nrad = input.north * PI / 180;
467  srad = input.south * PI / 180;
468  wrad = input.west * PI / 180;
469  erad = input.east * PI / 180;
470 
471  fprintf(stderr, "Mapping data to:\n N: %8.5f\n S: %8.5f\n W: %8.5f\n E: %8.5f\n",
472  input.north, input.south, input.west, input.east);
473 
474  fprintf(stderr, "Scale Type : %s\n", scale_type);
475  fprintf(stderr, "Data Min (abs) : %8.4f\n", input.datamin);
476  fprintf(stderr, "Data Max (abs) : %8.4f\n", input.datamax);
477  fprintf(stderr, "Scale Slope : %8.4f\n", slope);
478  fprintf(stderr, "Scale Intercept : %8.4f\n", intercept);
479  if (input.apply_pal >= 1 || default_palfile == 0)
480  fprintf(stderr, "Applying palette: %s\n", input.palfile);
481  if (input.mask)
482  fprintf(stderr, "Applying masking to flagged pixels\n");
483 
484  if (nrad <= srad) {
485  fprintf(stderr, "The northernmost boundary must be greater than the ");
486  fprintf(stderr, "southernmost boundary.\n");
487  exit(EXIT_FAILURE);
488  }
489 
490  /* Get the size of the output image. */
491  width = input.width;
492  if (width < 32) {
493  fprintf(stderr, "Width (%d) is too small to produce a useful image.\n",
494  input.width);
495  exit(EXIT_FAILURE);
496  }
497  if (wrad < erad)
498  height = rint((nrad - srad) * width / (erad - wrad));
499  else
500  height = rint((nrad - srad) * width / (erad - wrad + 2 * PI));
501 
502  numbins = width * height;
503  scale = height / (nrad - srad);
504 
505  /* Allocate memory for the output data. */
506  CALLOC(sum, double, numbins);
507  CALLOC(count, int, numbins);
508  CALLOC(mean, unsigned char, numbins);
509  CALLOC(mask, unsigned char, numbins);
510  CALLOC(rgb, byte, numbins * 3);
511  /* Get the threshold percentage. */
512  threshold = (double) input.threshold;
513 
514  /* For each input image... */
515  for (k = 0; k < nfiles; k++) {
516  fprintf(stderr, "Opening HDF file, %s ...\n", l2_str[k].filename);
517  status = reopenL2(k, &l2_str[k]);
518 
519  nscans = l2_str[k].nrec;
520  npix = l2_str[k].nsamp;
521  fprintf(stderr, "pix: %d scan: %d\n", npix, nscans);
522 
523  if (strcmp(input.prod, "sst") == 0 || strcmp(input.prod, "sst4") == 0) {
524  strcpy(qual, "qual_");
525  strcat(qual, input.prod);
526  for (i = 0; i < l2_str[k].nprod; i++) {
527  if (strcmp(qual, l2_str[k].prodname[i]) == 0) {
528  qualidx = i;
529  break;
530  }
531  }
532  }
533  for (i = 0; i < l2_str[k].nprod; i++)
534  if (strcmp(input.prod, l2_str[k].prodname[i]) == 0) {
535  prodidx = i;
536  break;
537  }
538 
539  if (npix <= 0 || nscans <= 0) {
540  fprintf(stderr,
541  "-E- %s line %d: Bad scene dimension: npix=%d nscans=%d in file, %s.\n",
542  __FILE__, __LINE__, npix, nscans, l2_str[k].filename);
543  exit(EXIT_FAILURE);
544  }
545 
546  /* Use the following variable to show this program's progress. */
547  progress = (int) ceil(((double) nscans / 78));
548 
549 
550  /* For each scan line ... */
551  fprintf(stderr, "Mapping swath pixels to Plate Carree projection...\n");
552  for (i = 0; i < nscans; i++) {
553 
554  /* Read swath record from L2 */
555  /* ------------------------- */
556  status = readL2(&l2_str[k], k, i, -1, NULL);
557 
558  /* For each pixel ... */
559  for (j = 0; j < npix; j++) {
560 
561  double plat, plon; /* pixel center */
562  double sinplat, cosplat;
563  double c[2]; /* edge/corner distance */
564  double sinc[2], cosc[2];
565  double sinaz[8], cosaz[8];
566  int out = 0; /* Number of pixel "corners" */
567  /* that fall outside the image */
568 
569  plat = l2_str[k].latitude[j] * PI / 180.0;
570  plon = l2_str[k].longitude[j] * PI / 180.0;
571 
572  sinplat = sin(plat);
573  cosplat = cos(plat);
574 
575  if (j < npix - 1) {
576 
577  double nlat, nlon; /* next pixel center */
578  double dlat, dlon; /* delta lat and lon */
579  double sindlat2, sindlon2, cosnlat;
580  double az; /* azimuth to next pixel */
581  double phw; /* pixel half width */
582 
583 
584  nlat = l2_str[k].latitude[j + 1] * PI / 180.0;
585  nlon = l2_str[k].longitude[j + 1] * PI / 180.0;
586 
587  cosnlat = cos(nlat);
588 
589  dlat = nlat - plat;
590  dlon = nlon - plon;
591 
592  sindlat2 = sin(dlat / 2);
593  sindlon2 = sin(dlon / 2);
594 
595  phw = asin(sqrt(sindlat2 * sindlat2 + /* Page 30, */
596  sindlon2 * sindlon2 * /* Equation */
597  cosplat * cosnlat)); /* 5-3a */
598 
599  /*
600  Make the pixel's coverage slightly broader to avoid
601  black pin holes in the output image where the estimated
602  pixel boundaries do not quite line up. Don't increase
603  the size too much, however, because that will cause
604  unwanted image blurring.
605  */
606  phw *= 1.3;
607 
608  c[0] = phw; /* center-to-edge distance */
609  c[1] = phw * ROOT2; /* center-to-corner distance */
610 
611  sinc[0] = sin(c[0]);
612  sinc[1] = sin(c[1]);
613  cosc[0] = cos(c[0]);
614  cosc[1] = cos(c[1]);
615 
616  az = /* Page 30, Equation 5-4b */
617  atan2(
618  cosnlat * sin(dlon),
619  cosplat * sin(nlat) - sinplat * cosnlat * cos(dlon)
620  );
621 
622  sinaz[0] = sin(az);
623  cosaz[0] = cos(az);
624  for (ii = 1; ii < 8; ii++) {
625  az += PI / 4;
626  sinaz[ii] = sin(az);
627  cosaz[ii] = cos(az);
628  }
629  }
630 
631  for (ii = 0; ii < 8; ii++) {
632  double lat, lon;
633  int ec; /* edge = 0, corner = 1 */
634 
635  ec = ii & 1;
636 
637  /* Page 31, Equation 5-5 */
638  lat = asin(sinplat * cosc[ec]
639  + cosplat * sinc[ec] * cosaz[ii]);
640 
641  lon = plon /* Page 31, Equation 5-6 */
642  + atan2(sinc[ec] * sinaz[ii],
643  cosplat * cosc[ec]
644  - sinplat * sinc[ec] * cosaz[ii]);
645 
646  if (wrad > erad) { /* 180-degree meridian included */
647  if (lon >= wrad && lon > erad) {
648  corners[ii].x = (lon - wrad) * scale;
649  } else if (lon < wrad && lon <= erad) {
650  corners[ii].x = (lon - wrad + 2 * PI) * scale;
651  } else if (lon - erad < wrad - lon) {
652  corners[ii].x = (lon - wrad + 2 * PI) * scale;
653  } else {
654  corners[ii].x = (lon - wrad) * scale;
655  }
656  } else { /* 180-degree meridian not included */
657  corners[ii].x = (lon - wrad) * scale;
658  }
659  corners[ii].y = (nrad - lat) * scale;
660 
661  if (corners[ii].x < 0 || corners[ii].x >= width
662  || corners[ii].y < 0 || corners[ii].y >= height) out++;
663  }
664 
665  /*
666  If out == 8, then the entire pixel is outside the
667  image area, so I skip to the next one.
668  */
669  if (out == 8) continue;
670 
671  l2_flags = l2_str[k].l2_flags[j];
672  if (qualidx >= 0) {
673  quality = l2_str[k].l2_data[qualidx][j];
674  }
675 
676 
677  /* Use scan conversion to determine
678  * which bins are overlain by this pixel. */
679  numoverlain = 0;
680  scan_convert(corners);
681 
682  for (m = 0; m < numoverlain; m++) {
683  n = binsoverlain[m];
684 
685  /*
686  Keep track of the masks if so requested.
687  I am basing the mask logic on the code in put_l2brs.c
688  which is part of the level-2 browse file generator (l2brsgen).
689  At the time I write this, pixel values 251 and 255 are unused
690  in the SeaWiFS level-2 browse files. Norman Kuring 10-Jul-2001
691  */
692 
693  if (input.mask && qualidx < 0) {
694  if (l2_flags & mask_252 && mask_glint &&
695  strcmp(input.prod, "sst") != 0 &&
696  strcmp(input.prod, "sst4") != 0) {
697  mask[n] = 252;
698  } else if (l2_flags & mask_253) {
699  if (mask[n] != 252) mask[n] = 253;
700  } else if (l2_flags & all_masks) {
701  if (mask[n] != 252 && mask[n] != 253) mask[n] = 254;
702  }
703  } else if (input.mask && qualidx >= 0) {
704  if (l2_flags & mask_253) {
705  mask[n] = 253;
706  } else if (quality > input.quality) {
707  if (mask[n] != 253) mask[n] = 254;
708  }
709  }
710 
711  /* Accumulate the sums for each bin. Only count unmasked pixels. */
712  goodpix = 1;
713  if (qualidx >= 0 && quality > input.quality) goodpix = 0;
714  else if (qualidx < 0 && (l2_flags & all_masks) != 0) goodpix = 0;
715 
716  if (goodpix) {
717  val = l2_str[k].l2_data[prodidx][j];
718  if (val > input.datamax) val = input.datamax;
719  if (val < input.datamin) val = input.datamin;
720  sum[n] += val;
721  count[n]++;
722  }
723  }
724  }
725  if (i != 0 && i % progress == 0) fprintf(stderr, ".");
726  }
727  fprintf(stderr, "\n");
728  }
729  fprintf(stderr, "Finished Plate Carree projection mapping\n");
730 
731 
732  /* Calculate the means for each bin. */
733  fprintf(stderr, "Computing means...\n");
734  numoutpix = 0;
735  for (n = 0; n < numbins; n++) {
736  if (count[n] == 0) {
737  if (input.mask) {
738  if (mask[n] > 0) {
739  mean[n] = mask[n];
740  numoutpix++;
741  } else {
742  mean[n] = 255;
743  }
744  }
745  } else {
746  if (strcmp(scale_type, "LINEAR") == 0) {
747  mean[n] = (sum[n] / count[n] - intercept) / slope;
748  } else if (strcmp(scale_type, "LOG") == 0) {
749  mean[n] = (log10(sum[n] / count[n]) - intercept) / slope;
750  }
751  numoutpix++;
752  }
753  }
754 
755  if ((double) 100 * numoutpix / numbins < threshold) {
756  fprintf(stderr, "Number of output pixels (%u of a possible %u) ",
757  numoutpix, numbins);
758  fprintf(stderr, "< threshold (%.2f%%). Output image not generated.\n",
759  threshold);
760  exit(BINBELOWTHRESH);
761  }
762 
763  if (input.outmode == 1) { // ppm
764 
765  // setup output file pointer
766  if (strlen(input.ofile) > 0) {
767  fprintf(stderr, "Writing out file: %s ...\n", input.ofile);
768  outfp = fopen(input.ofile, "wb");
769  } else {
770  fprintf(stderr, "Writing out data to STDOUT...\n");
771  outfp = stdout;
772  }
773 
774  if (input.apply_pal == 0 && default_palfile == 1) {
775  fprintf(outfp, "P5\n%d %d\n255\n", width, height);
776  for (n = 0; n < numbins; n++) {
777  fputc((int) mean[n], outfp);
778  }
779  } else {
780  /*
781  * Convert from greyscale and palette to rgb array
782  */
783  for (i = 0; i < numbins; i++) {
784  rgb[3 * i] = r[mean[i]];
785  rgb[3 * i + 1] = g[mean[i]];
786  rgb[3 * i + 2] = b[mean[i]];
787  }
788 
789  fprintf(outfp, "P6\n%d %d\n255\n", width, height);
790  fwrite(&rgb[0], 1, width * height * 3, outfp);
791  }
792 
793  // close file if not using stdout
794  if (stdout != outfp)
795  fclose(outfp);
796 
797  // end ppm
798 
799  } else if (input.outmode == 2) { // png
800 
801  // setup output file pointer
802  if (strlen(input.ofile) > 0) {
803  fprintf(stderr, "Writing out file: %s ...\n", input.ofile);
804  outfp = fopen(input.ofile, "wb");
805  } else {
806  fprintf(stderr, "Writing out data to STDOUT...\n");
807  outfp = stdout;
808  }
809 
810  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
811  NULL, NULL, NULL);
812  if (!png_ptr) {
813  fprintf(stderr, "l2mapgen: Error: Unable to create PNG write structure.\n");
814  exit(EXIT_FAILURE);
815  }
816 
817  png_infop info_ptr = png_create_info_struct(png_ptr);
818  if (!info_ptr) {
819  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
820  fprintf(stderr, "l2mapgen: Error: Unable to create PNG info structure.\n");
821  exit(EXIT_FAILURE);
822  }
823  if (setjmp(png_jmpbuf(png_ptr))) {
824  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
825  fprintf(stderr, "l2mapgen: Error: Unable to call PNG setjmp().\n");
826  exit(EXIT_FAILURE);
827  }
828  png_init_io(png_ptr, outfp);
829 
830  uint8_t * row_pointers[height];
831  for (i = 0; i < height; i++)
832  row_pointers[i] = mean + (i * width);
833  png_set_rows(png_ptr, info_ptr, row_pointers);
834 
835  if (input.apply_pal == 0 && default_palfile == 1) {
836 
837  // Grayscale
838  png_set_IHDR(png_ptr, info_ptr, width, height,
839  8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
840  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
841  } else {
842 
843  // color palette
844  png_set_IHDR(png_ptr, info_ptr, width, height,
845  8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
846  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
847  png_set_PLTE(png_ptr, info_ptr, (png_const_colorp) input.palette, 256);
848  }
849 
850  png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
851 
852  /* clean up after the write, and free any memory allocated */
853  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
854 
855  // close file if not using stdout
856  if (stdout != outfp)
857  fclose(outfp);
858 
859  // end png
860 
861  } else if (input.outmode == 3) { // geotiff
862  uint16_t *rr, *gg, *bb;
863  TIFF *tiff;
864  GTIF *gtif;
865  float *fmean;
866 
867  if (strlen(input.ofile) == 0) {
868  fprintf(stderr, "Can not write TIFF file to stdout.\n");
869  exit(EXIT_FAILURE);
870  }
871 
872  tiff = XTIFFOpen(input.ofile, "w");
873  if (tiff == NULL) {
874  fprintf(stderr, "Could not open outgoing image\n");
875  exit(EXIT_FAILURE);
876  }
877  gtif = GTIFNew(tiff);
878  if (gtif == NULL) {
879  fprintf(stderr, "Could not create geoTIFF structure\n");
880  exit(EXIT_FAILURE);
881  }
882 
883  // calc geo TIFF tags
884  double tiepoints[6] = {0, 0, 0, 0, 0, 0};
885  double pixscale[3] = {0, 0, 0};
886 
887  // pixel width
888  pixscale[0] = (input.east - input.west) / width;
889 
890  // pixel height
891  pixscale[1] = (input.north - input.south) / height;
892 
893  // set top left corner pixel lat, lon
894  tiepoints[3] = input.west;
895  tiepoints[4] = input.north;
896 
897  TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width);
898  TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height);
899  TIFFSetField(tiff, GTIFF_PIXELSCALE, 3, pixscale);
900  TIFFSetField(tiff, GTIFF_TIEPOINTS, 6, tiepoints);
901 
902  if (input.apply_pal == 0 && default_palfile == 1) {
903  // Grayscale
904 
905  TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
906  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
907  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32);
908  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
909  TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
910 
911  // write geo TIFF keys
912  GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
913  GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
914  GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
915 
916  GTIFWriteKeys(gtif);
917 
918  fmean = (float*) malloc(numbins * sizeof (float));
919  if (fmean == NULL) {
920  fprintf(stderr, "Could not allocate memory for TIFF grayscale mean\n");
921  exit(EXIT_FAILURE);
922  }
923 
924  // calc the mean as a float
925  for (i = 0; i < numbins; i++) {
926  if (count[i] > 0) {
927  fmean[i] = sum[i] / count[i];
928  } else {
929  fmean[i] = -32767.0;
930  }
931  }
932 
933  // Actually write the image
934  if (TIFFWriteEncodedStrip(tiff, 0, fmean, numbins * sizeof (float)) == 0) {
935  fprintf(stderr, "Could not write TIFF image\n");
936  exit(EXIT_FAILURE);
937  }
938 
939  free(fmean);
940 
941  } else {
942  // Colormap
943  rr = (uint16_t*) malloc(256 * sizeof (uint16_t));
944  gg = (uint16_t*) malloc(256 * sizeof (uint16_t));
945  bb = (uint16_t*) malloc(256 * sizeof (uint16_t));
946  if (rr == NULL || gg == NULL || bb == NULL) {
947  fprintf(stderr, "Could not allocate memory for TIFF color map\n");
948  exit(EXIT_FAILURE);
949  }
950 
951  // need a colormap of shorts not bytes
952  for (i = 0; i < 256; i++) {
953  rr[i] = r[i] << 8;
954  gg[i] = g[i] << 8;
955  bb[i] = b[i] << 8;
956  }
957 
958  TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
959  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
960  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
961  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
962  TIFFSetField(tiff, TIFFTAG_COLORMAP, rr, gg, bb);
963 
964  // write geo TIFF keys
965  GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
966  GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
967  GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
968 
969  GTIFWriteKeys(gtif);
970 
971  // Actually write the image
972  if (TIFFWriteEncodedStrip(tiff, 0, mean, width * height) == 0) {
973  fprintf(stderr, "Could not write TIFF image\n");
974  exit(EXIT_FAILURE);
975  }
976 
977  free(rr);
978  free(gg);
979  free(bb);
980 
981  } // color map
982 
983  GTIFFree(gtif);
984  XTIFFClose(tiff);
985 
986  // end geotiff
987 
988  } else {
989 
990  fprintf(stderr, "l2mapgen: Error: invalid value for outmode - %d.\n", input.outmode);
991  exit(EXIT_FAILURE);
992  }
993 
994  for (i = 0; i < l3m_params; i++) {
995  free(parmname_list[i]);
996  free(parmname_short[i]);
997  free(unit_list[i]);
998  free(scaling_list[i]);
999  free(palette_list[i]);
1000  free(precision_list[i]);
1001  }
1002  free(parmname_list);
1003  free(parmname_short);
1004  free(unit_list);
1005  free(scaling_list);
1006  free(palette_list);
1007  free(maximum_list);
1008  free(minimum_list);
1009  free(precision_list);
1010 
1011  free(sum);
1012  free(count);
1013  free(mean);
1014  free(mask);
1015  free(rgb);
1016  free(r);
1017  free(g);
1018  free(b);
1019  fprintf(stderr, "Done.\n");
1020 
1021  return (EXIT_SUCCESS);
1022 
1023 }
1024 
1025 
1026 
1027 /*------------------------------------------------------------------------------
1028 
1029  Function: scan_convert
1030 
1031  Returns type: int
1032 
1033  Description: This function is derived from the scan-conversion
1034  code used by an X-server for filling in polygons.
1035 
1036  Parameters: (in calling order)
1037  Type Name I/O Description
1038  ---- ---- --- -----------
1039  struct _DDXPoint* ptsIn In vertex specifications
1040 
1041  Modification history:
1042  Programmer Date Description of change
1043  ---------- ---- ---------------------
1044  Norman Kuring 15-Sep-1992 Adaptation from X-server code
1045  for my own nefarious purposes.
1046 
1047 ------------------------------------------------------------------------------*/
1048 
1049 /***********************************************************
1050 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
1051 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
1052 
1053  All Rights Reserved
1054 
1055 Permission to use, copy, modify, and distribute this software and its
1056 documentation for any purpose and without fee is hereby granted,
1057 provided that the above copyright notice appear in all copies and that
1058 both that copyright notice and this permission notice appear in
1059 supporting documentation, and that the names of Digital or MIT not be
1060 used in advertising or publicity pertaining to distribution of the
1061 software without specific, written prior permission.
1062 
1063 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
1064 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
1065 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
1066 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1067 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1068 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
1069 SOFTWARE.
1070 
1071  ******************************************************************/
1072 /* $XConsortium: mipolygen.c,v 5.0 89/06/09 15:08:35 keith Exp $ */
1073 
1074 extern void miloadAET(), micomputeWAET(), miFreeStorage();
1075 
1076 /*
1077  *
1078  * Written by Brian Kelleher; Oct. 1985
1079  *
1080  * Routine to fill a polygon. Two fill rules are
1081  * supported: frWINDING and frEVENODD.
1082  *
1083  * See fillpoly.h for a complete description of the algorithm.
1084  *
1085  * Modified by Norman Kuring to fill a bin-number array instead of
1086  * filling shapes on the server.
1087  */
1088 
1089 int scan_convert(XPoint *ptsIn) {
1090  int count = 8;
1091  register EdgeTableEntry *pAET; /* the Active Edge Table */
1092  register int y; /* the current scanline */
1093  register int nPts = 0; /* number of pts in buffer */
1094  register EdgeTableEntry *pWETE; /* Winding Edge Table */
1095  register ScanLineList *pSLL; /* Current ScanLineList */
1096  register XPoint *ptsOut; /* ptr to output buffers */
1097  int *wdth;
1098  XPoint FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
1099  int FirstWidth[NUMPTSTOBUFFER];
1100  EdgeTableEntry *pPrevAET; /* previous AET entry */
1101  EdgeTable ET; /* Edge Table header node */
1102  EdgeTableEntry AET; /* Active ET header node */
1103  EdgeTableEntry *pETEs; /* Edge Table Entries buff */
1104  ScanLineListBlock SLLBlock; /* header for ScanLineList */
1105  int fixWAET = 0;
1106 
1107  if (!(pETEs = (EdgeTableEntry *) malloc(sizeof (EdgeTableEntry) * count))) {
1108  return (0);
1109  }
1110  ptsOut = FirstPoint;
1111  wdth = FirstWidth;
1112  if (!miCreateETandAET(count, ptsIn, &ET, &AET, pETEs, &SLLBlock)) {
1113  free(pETEs);
1114  return (0);
1115  }
1116  pSLL = ET.scanlines.next;
1117 
1118  /*
1119  * for each scanline
1120  */
1121  for (y = ET.ymin; y < ET.ymax; y++) {
1122  /*
1123  * Add a new edge to the active edge table when we
1124  * get to the next edge.
1125  */
1126  if (pSLL && y == pSLL->scanline) {
1127  miloadAET(&AET, pSLL->edgelist);
1128  micomputeWAET(&AET);
1129  pSLL = pSLL->next;
1130  }
1131  pPrevAET = &AET;
1132  pAET = AET.next;
1133  pWETE = pAET;
1134 
1135  /*
1136  * for each active edge
1137  */
1138  while (pAET) {
1139  /*
1140  * if the next edge in the active edge table is
1141  * also the next edge in the winding active edge
1142  * table.
1143  */
1144  if (pWETE == pAET) {
1145  ptsOut->x = pAET->bres.minor;
1146  ptsOut++->y = y;
1147  *wdth++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
1148  nPts++;
1149 
1150  /*
1151  * send out the buffer
1152  */
1153  if (nPts == NUMPTSTOBUFFER) {
1154  collect_bins(nPts, FirstPoint, FirstWidth);
1155  ptsOut = FirstPoint;
1156  wdth = FirstWidth;
1157  nPts = 0;
1158  }
1159 
1160  pWETE = pWETE->nextWETE;
1161  while (pWETE != pAET)
1162  EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
1163  pWETE = pWETE->nextWETE;
1164  }
1165  EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
1166  }
1167 
1168  /*
1169  * reevaluate the Winding active edge table if we
1170  * just had to resort it or if we just exited an edge.
1171  */
1172  if (miInsertionSort(&AET) || fixWAET) {
1173  micomputeWAET(&AET);
1174  fixWAET = 0;
1175  }
1176  }
1177 
1178  /*
1179  * Get any spans that we missed by buffering
1180  */
1181  collect_bins(nPts, FirstPoint, FirstWidth);
1182  free(pETEs);
1183  miFreeStorage(SLLBlock.next);
1184  return (1);
1185 }
1186 
1188  int number_of_initial_points,
1189  XPoint *initial_point,
1190  int *span_width
1191  ) {
1192 
1193  int i;
1194  short x, y;
1195  int end;
1196 
1197  /* The variables, width, height, binsoverlain, and numoverlain, are
1198  * static global varibles. */
1199 
1200  for (i = 0; i < number_of_initial_points; i++) {
1201 
1202  y = initial_point[i].y;
1203  if (y >= height || y < 0) continue;
1204 
1205  for (
1206  x = initial_point[i].x,
1207  end = initial_point[i].x + span_width[i];
1208  x < end;
1209  x++
1210  ) {
1211  if (x >= width || x < 0) continue;
1212  if (numoverlain >= binsperpixel) {
1213  binsperpixel += 1024;
1214  binsoverlain = (int *) realloc(binsoverlain, binsperpixel * sizeof (int));
1215  if (binsoverlain == NULL) {
1216  fprintf(stderr, "-E- %s line %d: ", __FILE__, __LINE__);
1217  fprintf(stderr,
1218  "Memory allocation error (numoverlain=%d binsperpixel=%d\n",
1219  numoverlain, binsperpixel);
1220  exit(EXIT_FAILURE);
1221  }
1222  return (0);
1223  }
1224  binsoverlain[numoverlain++] = y * width + x;
1225  }
1226  }
1227  return (1);
1228 }
void setupflags(char *flagdef, char *flaguse, uint32_t *flagusemask, uint32_t *required, int *status, int32_t *BITS)
Definition: setupflags.c:7
float * minimum_list
Definition: main_l2mapgen.c:79
int r
Definition: decode_rs.h:73
int32_t reopenL2(int32_t fileindex, l2_prod *l2_str)
Definition: readL2scan.c:1050
#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
Definition: mipoly.h:114
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
int j
Definition: decode_rs.h:73
int32_t l3m_params
Definition: main_l2mapgen.c:73
int status
Definition: l1_czcs_hdf.c:32
int ymin
Definition: mipoly.h:77
#define DEF_FLAG
Definition: l1c_input.h:14
float mean(float *xs, int sample_size)
Definition: numerical.c:81
#define PI
Definition: main_l2mapgen.c:48
int16_t * qual
Definition: l2bin.cpp:80
#define NULL
Definition: decode_rs.h:63
int32_t readL2meta(meta_l2Type *meta_l2, int32_t ifile)
Definition: readL2scan.c:2151
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 as required for compatibility with version of the SDP toolkit Corrected test output file names to end in out
Definition: HISTORY.txt:422
void miFreeStorage()
void miloadAET()
int miCreateETandAET()
#define TRUE
Definition: rice.h:165
int32_t readL2(l2_prod *l2_str, int32_t ifile, int32_t recnum, int32_t iprod, unsigned char *scan_in_rowgroup)
Definition: readL2scan.c:1336
int32_t closeL2(l2_prod *l2_str, int32_t ifile)
Definition: readL2scan.c:1995
int collect_bins(int number_of_initial_points, XPoint *initial_point, int *span_width)
instr * input
char ** unit_list
Definition: main_l2mapgen.c:76
void micomputeWAET()
#define BINBELOWTHRESH
Definition: main_l2mapgen.c:49
#define ROOT2
Definition: main_l2mapgen.c:47
clo_optionList_t * clo_createList()
Definition: clo.c:532
int main(int argc, char *argv[])
Definition: main_l2mapgen.c:83
list(APPEND LIBS ${NETCDF_LIBRARIES}) find_package(GSL REQUIRED) include_directories($
Definition: CMakeLists.txt:8
int32_t openL2(const char *fname, const char *plist, l2_prod *l2_str)
Definition: readL2scan.c:316
int ymax
Definition: mipoly.h:76
void clo_printUsage(clo_optionList_t *list)
Definition: clo.c:1988
float32 slope[]
Definition: l2lists.h:30
int scan_convert(XPoint *ptsIn)
int miInsertionSort()
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
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
float32 intercept[]
Definition: l2lists.h:44
integer, parameter double
float * maximum_list
Definition: main_l2mapgen.c:78
#define MAXNFILES
Definition: l3bin.cpp:20
char ** parmname_list
Definition: main_l2mapgen.c:74
int l2mapgen_input(int argc, char **argv, clo_optionList_t *list, instr *input)
data_t b[NROOTS+1]
Definition: decode_rs.h:77
int getlut_file(char *lut_file, short *rlut, short *glut, short *blut)
Definition: getlut_file.c:8
#define CALLOC(ptr, typ, num)
Definition: main_l2mapgen.c:51
char ** scaling_list
Definition: main_l2mapgen.c:77
#define NUMPTSTOBUFFER
Definition: mipoly.h:98
for(i=0;i< NROOTS;i++) s[i]
Definition: decode_rs.h:85
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 as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
int i
Definition: decode_rs.h:71
double rint(double)
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
char ** precision_list
Definition: main_l2mapgen.c:81
char ** parmname_short
Definition: main_l2mapgen.c:75
char ** palette_list
Definition: main_l2mapgen.c:80
int k
Definition: decode_rs.h:73
int npix
Definition: get_cmp.c:28
int l2mapgen_read_options(clo_optionList_t *list, int argc, char *argv[])
ScanLineList scanlines
Definition: mipoly.h:78
int l2mapgen_init_options(clo_optionList_t *list)
int count
Definition: decode_rs.h:79