OB.DAAC Logo
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;
141  l2mapgen_read_options(list, argc, argv);
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 
381  if (singleInputFile) {
382  nfiles = 1;
383  status = openL2(input.ifile, 0x0, &l2_str[0]);
384 
385  status = readL2meta(&meta_l2, 0);
386  if (meta_l2.northlat >= latmax) latmax = meta_l2.northlat;
387  if (meta_l2.southlat <= latmin) latmin = meta_l2.southlat;
388  if (meta_l2.westlon <= lonmin) lonmin = meta_l2.westlon;
389  if (meta_l2.eastlon >= lonmax) lonmax = meta_l2.eastlon;
390 
391  closeL2(&l2_str[0], 0);
392  fprintf(stderr, "Single HDF input\n");
393  } else {
394 
395  /* Filelist input - Determine number of input files */
396  /* ------------------------------------------------ */
397  nfiles = 0;
398  fp = fopen(input.ifile, "r");
399  if (fp == NULL) {
400  fprintf(stderr, "Input listing file: \"%s\" not found.\n", input.ifile);
401  return -1;
402  }
403  while (fgets(buf, 256, fp) != NULL) nfiles++;
404  fclose(fp);
405  fprintf(stderr, "%d input files\n", nfiles);
406 
407 
408  /* Open L2 input files */
409  /* ------------------- */
410  fp = fopen(input.ifile, "r");
411  for (i = 0; i < nfiles; i++) {
412  fgets(buf, 256, fp);
413  buf[strlen(buf) - 1] = 0;
414  status = openL2(buf, 0x0, &l2_str[i]);
415 
416  status = readL2meta(&meta_l2, i);
417  if (meta_l2.northlat >= latmax) latmax = meta_l2.northlat;
418  if (meta_l2.southlat <= latmin) latmin = meta_l2.southlat;
419  if (meta_l2.westlon <= lonmin) lonmin = meta_l2.westlon;
420  if (meta_l2.eastlon >= lonmax) lonmax = meta_l2.eastlon;
421 
422  closeL2(&l2_str[i], i);
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);
436  setupflags(buf, "LAND", &mask_253, &required_mask, &status);
437  setupflags(buf, input.flaguse, &all_masks, &required_mask, &status);
438  if ((all_masks & mask_252) != 0)
439  mask_glint = 1;
440 
441  /* Make sure L2 product exists for every input L2 file */
442  /* ---------------------------------------------------------------- */
443  status = 0;
444  for (j = 0; j < nfiles; j++) {
445  for (i = 0; i < l2_str[j].nprod; i++) {
446  if (strcmp(l2_str[j].prodname[i], input.prod) == 0) {
447  status++;
448  }
449  }
450  }
451 
452  if (status != nfiles) {
453  fprintf(stderr, "Product %s not found in all L2 file(s)\n", input.prod);
454  exit(EXIT_FAILURE);
455  }
456 
457  /* Get the box boundaries. */
458  if (input.north == input.south && input.west == input.east) {
459  input.north = latmax;
460  input.south = latmin;
461  input.west = lonmin;
462  input.east = lonmax;
463  }
464 
465  nrad = input.north * PI / 180;
466  srad = input.south * PI / 180;
467  wrad = input.west * PI / 180;
468  erad = input.east * PI / 180;
469 
470  fprintf(stderr, "Mapping data to:\n N: %8.5f\n S: %8.5f\n W: %8.5f\n E: %8.5f\n",
471  input.north, input.south, input.west, input.east);
472 
473  fprintf(stderr, "Scale Type : %s\n", scale_type);
474  fprintf(stderr, "Data Min (abs) : %8.4f\n", input.datamin);
475  fprintf(stderr, "Data Max (abs) : %8.4f\n", input.datamax);
476  fprintf(stderr, "Scale Slope : %8.4f\n", slope);
477  fprintf(stderr, "Scale Intercept : %8.4f\n", intercept);
478  if (input.apply_pal >= 1 || default_palfile == 0)
479  fprintf(stderr, "Applying palette: %s\n", input.palfile);
480  if (input.mask)
481  fprintf(stderr, "Applying masking to flagged pixels\n");
482 
483  if (nrad <= srad) {
484  fprintf(stderr, "The northernmost boundary must be greater than the ");
485  fprintf(stderr, "southernmost boundary.\n");
486  exit(EXIT_FAILURE);
487  }
488 
489  /* Get the size of the output image. */
490  width = input.width;
491  if (width < 32) {
492  fprintf(stderr, "Width (%d) is too small to produce a useful image.\n",
493  input.width);
494  exit(EXIT_FAILURE);
495  }
496  if (wrad < erad)
497  height = rint((nrad - srad) * width / (erad - wrad));
498  else
499  height = rint((nrad - srad) * width / (erad - wrad + 2 * PI));
500 
501  numbins = width * height;
502  scale = height / (nrad - srad);
503 
504  /* Allocate memory for the output data. */
505  CALLOC(sum, double, numbins);
506  CALLOC(count, int, numbins);
507  CALLOC(mean, unsigned char, numbins);
508  CALLOC(mask, unsigned char, numbins);
509  CALLOC(rgb, byte, numbins * 3);
510  /* Get the threshold percentage. */
511  threshold = (double) input.threshold;
512 
513  /* For each input image... */
514  for (k = 0; k < nfiles; k++) {
515  fprintf(stderr, "Opening HDF file, %s ...\n", l2_str[k].filename);
516  status = reopenL2(k, &l2_str[k]);
517 
518  nscans = l2_str[k].nrec;
519  npix = l2_str[k].nsamp;
520  fprintf(stderr, "pix: %d scan: %d\n", npix, nscans);
521 
522  if (strcmp(input.prod, "sst") == 0 || strcmp(input.prod, "sst4") == 0) {
523  strcpy(qual, "qual_");
524  strcat(qual, input.prod);
525  for (i = 0; i < l2_str[k].nprod; i++) {
526  if (strcmp(qual, l2_str[k].prodname[i]) == 0) {
527  qualidx = i;
528  break;
529  }
530  }
531  }
532  for (i = 0; i < l2_str[k].nprod; i++)
533  if (strcmp(input.prod, l2_str[k].prodname[i]) == 0) {
534  prodidx = i;
535  break;
536  }
537 
538  if (npix <= 0 || nscans <= 0) {
539  fprintf(stderr,
540  "-E- %s line %d: Bad scene dimension: npix=%d nscans=%d in file, %s.\n",
541  __FILE__, __LINE__, npix, nscans, l2_str[k].filename);
542  exit(EXIT_FAILURE);
543  }
544 
545  /* Use the following variable to show this program's progress. */
546  progress = (int) ceil(((double) nscans / 78));
547 
548 
549  /* For each scan line ... */
550  fprintf(stderr, "Mapping swath pixels to Plate Carree projection...\n");
551  for (i = 0; i < nscans; i++) {
552 
553  /* Read swath record from L2 */
554  /* ------------------------- */
555  status = readL2(&l2_str[k], k, i, -1, NULL);
556 
557  /* For each pixel ... */
558  for (j = 0; j < npix; j++) {
559 
560  double plat, plon; /* pixel center */
561  double sinplat, cosplat;
562  double c[2]; /* edge/corner distance */
563  double sinc[2], cosc[2];
564  double sinaz[8], cosaz[8];
565  int out = 0; /* Number of pixel "corners" */
566  /* that fall outside the image */
567 
568  plat = l2_str[k].latitude[j] * PI / 180.0;
569  plon = l2_str[k].longitude[j] * PI / 180.0;
570 
571  sinplat = sin(plat);
572  cosplat = cos(plat);
573 
574  if (j < npix - 1) {
575 
576  double nlat, nlon; /* next pixel center */
577  double dlat, dlon; /* delta lat and lon */
578  double sindlat2, sindlon2, cosnlat;
579  double az; /* azimuth to next pixel */
580  double phw; /* pixel half width */
581 
582 
583  nlat = l2_str[k].latitude[j + 1] * PI / 180.0;
584  nlon = l2_str[k].longitude[j + 1] * PI / 180.0;
585 
586  cosnlat = cos(nlat);
587 
588  dlat = nlat - plat;
589  dlon = nlon - plon;
590 
591  sindlat2 = sin(dlat / 2);
592  sindlon2 = sin(dlon / 2);
593 
594  phw = asin(sqrt(sindlat2 * sindlat2 + /* Page 30, */
595  sindlon2 * sindlon2 * /* Equation */
596  cosplat * cosnlat)); /* 5-3a */
597 
598  /*
599  Make the pixel's coverage slightly broader to avoid
600  black pin holes in the output image where the estimated
601  pixel boundaries do not quite line up. Don't increase
602  the size too much, however, because that will cause
603  unwanted image blurring.
604  */
605  phw *= 1.3;
606 
607  c[0] = phw; /* center-to-edge distance */
608  c[1] = phw * ROOT2; /* center-to-corner distance */
609 
610  sinc[0] = sin(c[0]);
611  sinc[1] = sin(c[1]);
612  cosc[0] = cos(c[0]);
613  cosc[1] = cos(c[1]);
614 
615  az = /* Page 30, Equation 5-4b */
616  atan2(
617  cosnlat * sin(dlon),
618  cosplat * sin(nlat) - sinplat * cosnlat * cos(dlon)
619  );
620 
621  sinaz[0] = sin(az);
622  cosaz[0] = cos(az);
623  for (ii = 1; ii < 8; ii++) {
624  az += PI / 4;
625  sinaz[ii] = sin(az);
626  cosaz[ii] = cos(az);
627  }
628  }
629 
630  for (ii = 0; ii < 8; ii++) {
631  double lat, lon;
632  int ec; /* edge = 0, corner = 1 */
633 
634  ec = ii & 1;
635 
636  /* Page 31, Equation 5-5 */
637  lat = asin(sinplat * cosc[ec]
638  + cosplat * sinc[ec] * cosaz[ii]);
639 
640  lon = plon /* Page 31, Equation 5-6 */
641  + atan2(sinc[ec] * sinaz[ii],
642  cosplat * cosc[ec]
643  - sinplat * sinc[ec] * cosaz[ii]);
644 
645  if (wrad > erad) { /* 180-degree meridian included */
646  if (lon >= wrad && lon > erad) {
647  corners[ii].x = (lon - wrad) * scale;
648  } else if (lon < wrad && lon <= erad) {
649  corners[ii].x = (lon - wrad + 2 * PI) * scale;
650  } else if (lon - erad < wrad - lon) {
651  corners[ii].x = (lon - wrad + 2 * PI) * scale;
652  } else {
653  corners[ii].x = (lon - wrad) * scale;
654  }
655  } else { /* 180-degree meridian not included */
656  corners[ii].x = (lon - wrad) * scale;
657  }
658  corners[ii].y = (nrad - lat) * scale;
659 
660  if (corners[ii].x < 0 || corners[ii].x >= width
661  || corners[ii].y < 0 || corners[ii].y >= height) out++;
662  }
663 
664  /*
665  If out == 8, then the entire pixel is outside the
666  image area, so I skip to the next one.
667  */
668  if (out == 8) continue;
669 
670  l2_flags = l2_str[k].l2_flags[j];
671  if (qualidx >= 0) {
672  quality = l2_str[k].l2_data[qualidx][j];
673  }
674 
675 
676  /* Use scan conversion to determine
677  * which bins are overlain by this pixel. */
678  numoverlain = 0;
679  scan_convert(corners);
680 
681  for (m = 0; m < numoverlain; m++) {
682  n = binsoverlain[m];
683 
684  /*
685  Keep track of the masks if so requested.
686  I am basing the mask logic on the code in put_l2brs.c
687  which is part of the level-2 browse file generator (l2brsgen).
688  At the time I write this, pixel values 251 and 255 are unused
689  in the SeaWiFS level-2 browse files. Norman Kuring 10-Jul-2001
690  */
691 
692  if (input.mask && qualidx < 0) {
693  if (l2_flags & mask_252 && mask_glint &&
694  strcmp(input.prod, "sst") != 0 &&
695  strcmp(input.prod, "sst4") != 0) {
696  mask[n] = 252;
697  } else if (l2_flags & mask_253) {
698  if (mask[n] != 252) mask[n] = 253;
699  } else if (l2_flags & all_masks) {
700  if (mask[n] != 252 && mask[n] != 253) mask[n] = 254;
701  }
702  } else if (input.mask && qualidx >= 0) {
703  if (l2_flags & mask_253) {
704  mask[n] = 253;
705  } else if (quality > input.quality) {
706  if (mask[n] != 253) mask[n] = 254;
707  }
708  }
709 
710  /* Accumulate the sums for each bin. Only count unmasked pixels. */
711  goodpix = 1;
712  if (qualidx >= 0 && quality > input.quality) goodpix = 0;
713  else if (qualidx < 0 && (l2_flags & all_masks) != 0) goodpix = 0;
714 
715  if (goodpix) {
716  val = l2_str[k].l2_data[prodidx][j];
717  if (val > input.datamax) val = input.datamax;
718  if (val < input.datamin) val = input.datamin;
719  sum[n] += val;
720  count[n]++;
721  }
722  }
723  }
724  if (i != 0 && i % progress == 0) fprintf(stderr, ".");
725  }
726  fprintf(stderr, "\n");
727  }
728  fprintf(stderr, "Finished Plate Carree projection mapping\n");
729 
730 
731  /* Calculate the means for each bin. */
732  fprintf(stderr, "Computing means...\n");
733  numoutpix = 0;
734  for (n = 0; n < numbins; n++) {
735  if (count[n] == 0) {
736  if (input.mask) {
737  if (mask[n] > 0) {
738  mean[n] = mask[n];
739  numoutpix++;
740  } else {
741  mean[n] = 255;
742  }
743  }
744  } else {
745  if (strcmp(scale_type, "LINEAR") == 0) {
746  mean[n] = (sum[n] / count[n] - intercept) / slope;
747  } else if (strcmp(scale_type, "LOG") == 0) {
748  mean[n] = (log10(sum[n] / count[n]) - intercept) / slope;
749  }
750  numoutpix++;
751  }
752  }
753 
754  if ((double) 100 * numoutpix / numbins < threshold) {
755  fprintf(stderr, "Number of output pixels (%u of a possible %u) ",
756  numoutpix, numbins);
757  fprintf(stderr, "< threshold (%.2f%%). Output image not generated.\n",
758  threshold);
759  exit(BINBELOWTHRESH);
760  }
761 
762  if (input.outmode == 1) { // ppm
763 
764  // setup output file pointer
765  if (strlen(input.ofile) > 0) {
766  fprintf(stderr, "Writing out file: %s ...\n", input.ofile);
767  outfp = fopen(input.ofile, "wb");
768  } else {
769  fprintf(stderr, "Writing out data to STDOUT...\n");
770  outfp = stdout;
771  }
772 
773  if (input.apply_pal == 0 && default_palfile == 1) {
774  fprintf(outfp, "P5\n%d %d\n255\n", width, height);
775  for (n = 0; n < numbins; n++) {
776  fputc((int) mean[n], outfp);
777  }
778  } else {
779  /*
780  * Convert from greyscale and palette to rgb array
781  */
782  for (i = 0; i < numbins; i++) {
783  rgb[3 * i] = r[mean[i]];
784  rgb[3 * i + 1] = g[mean[i]];
785  rgb[3 * i + 2] = b[mean[i]];
786  }
787 
788  fprintf(outfp, "P6\n%d %d\n255\n", width, height);
789  fwrite(&rgb[0], 1, width * height * 3, outfp);
790  }
791 
792  // close file if not using stdout
793  if (stdout != outfp)
794  fclose(outfp);
795 
796  // end ppm
797 
798  } else if (input.outmode == 2) { // png
799 
800  // setup output file pointer
801  if (strlen(input.ofile) > 0) {
802  fprintf(stderr, "Writing out file: %s ...\n", input.ofile);
803  outfp = fopen(input.ofile, "wb");
804  } else {
805  fprintf(stderr, "Writing out data to STDOUT...\n");
806  outfp = stdout;
807  }
808 
809  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
810  NULL, NULL, NULL);
811  if (!png_ptr) {
812  fprintf(stderr, "l2mapgen: Error: Unable to create PNG write structure.\n");
813  exit(EXIT_FAILURE);
814  }
815 
816  png_infop info_ptr = png_create_info_struct(png_ptr);
817  if (!info_ptr) {
818  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
819  fprintf(stderr, "l2mapgen: Error: Unable to create PNG info structure.\n");
820  exit(EXIT_FAILURE);
821  }
822  if (setjmp(png_jmpbuf(png_ptr))) {
823  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
824  fprintf(stderr, "l2mapgen: Error: Unable to call PNG setjmp().\n");
825  exit(EXIT_FAILURE);
826  }
827  png_init_io(png_ptr, outfp);
828 
829  uint8_t * row_pointers[height];
830  for (i = 0; i < height; i++)
831  row_pointers[i] = mean + (i * width);
832  png_set_rows(png_ptr, info_ptr, row_pointers);
833 
834  if (input.apply_pal == 0 && default_palfile == 1) {
835 
836  // Grayscale
837  png_set_IHDR(png_ptr, info_ptr, width, height,
838  8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
839  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
840  } else {
841 
842  // color palette
843  png_set_IHDR(png_ptr, info_ptr, width, height,
844  8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
845  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
846  png_set_PLTE(png_ptr, info_ptr, (png_const_colorp) input.palette, 256);
847  }
848 
849  png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
850 
851  /* clean up after the write, and free any memory allocated */
852  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
853 
854  // close file if not using stdout
855  if (stdout != outfp)
856  fclose(outfp);
857 
858  // end png
859 
860  } else if (input.outmode == 3) { // geotiff
861  uint16_t *rr, *gg, *bb;
862  TIFF *tiff;
863  GTIF *gtif;
864  float *fmean;
865 
866  if (strlen(input.ofile) == 0) {
867  fprintf(stderr, "Can not write TIFF file to stdout.\n");
868  exit(EXIT_FAILURE);
869  }
870 
871  tiff = XTIFFOpen(input.ofile, "w");
872  if (tiff == NULL) {
873  fprintf(stderr, "Could not open outgoing image\n");
874  exit(EXIT_FAILURE);
875  }
876  gtif = GTIFNew(tiff);
877  if (gtif == NULL) {
878  fprintf(stderr, "Could not create geoTIFF structure\n");
879  exit(EXIT_FAILURE);
880  }
881 
882  // calc geo TIFF tags
883  double tiepoints[6] = {0, 0, 0, 0, 0, 0};
884  double pixscale[3] = {0, 0, 0};
885 
886  // pixel width
887  pixscale[0] = (input.east - input.west) / width;
888 
889  // pixel height
890  pixscale[1] = (input.north - input.south) / height;
891 
892  // set top left corner pixel lat, lon
893  tiepoints[3] = input.west;
894  tiepoints[4] = input.north;
895 
896  TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width);
897  TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height);
898  TIFFSetField(tiff, GTIFF_PIXELSCALE, 3, pixscale);
899  TIFFSetField(tiff, GTIFF_TIEPOINTS, 6, tiepoints);
900 
901  if (input.apply_pal == 0 && default_palfile == 1) {
902  // Grayscale
903 
904  TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
905  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
906  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32);
907  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
908  TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
909 
910  // write geo TIFF keys
911  GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
912  GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
913  GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
914 
915  GTIFWriteKeys(gtif);
916 
917  fmean = (float*) malloc(numbins * sizeof (float));
918  if (fmean == NULL) {
919  fprintf(stderr, "Could not allocate memory for TIFF grayscale mean\n");
920  exit(EXIT_FAILURE);
921  }
922 
923  // calc the mean as a float
924  for (i = 0; i < numbins; i++) {
925  if (count[i] > 0) {
926  fmean[i] = sum[i] / count[i];
927  } else {
928  fmean[i] = -32767.0;
929  }
930  }
931 
932  // Actually write the image
933  if (TIFFWriteEncodedStrip(tiff, 0, fmean, numbins * sizeof (float)) == 0) {
934  fprintf(stderr, "Could not write TIFF image\n");
935  exit(EXIT_FAILURE);
936  }
937 
938  free(fmean);
939 
940  } else {
941  // Colormap
942  rr = (uint16_t*) malloc(256 * sizeof (uint16_t));
943  gg = (uint16_t*) malloc(256 * sizeof (uint16_t));
944  bb = (uint16_t*) malloc(256 * sizeof (uint16_t));
945  if (rr == NULL || gg == NULL || bb == NULL) {
946  fprintf(stderr, "Could not allocate memory for TIFF color map\n");
947  exit(EXIT_FAILURE);
948  }
949 
950  // need a colormap of shorts not bytes
951  for (i = 0; i < 256; i++) {
952  rr[i] = r[i] << 8;
953  gg[i] = g[i] << 8;
954  bb[i] = b[i] << 8;
955  }
956 
957  TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
958  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
959  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
960  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
961  TIFFSetField(tiff, TIFFTAG_COLORMAP, rr, gg, bb);
962 
963  // write geo TIFF keys
964  GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
965  GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
966  GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
967 
968  GTIFWriteKeys(gtif);
969 
970  // Actually write the image
971  if (TIFFWriteEncodedStrip(tiff, 0, mean, width * height) == 0) {
972  fprintf(stderr, "Could not write TIFF image\n");
973  exit(EXIT_FAILURE);
974  }
975 
976  free(rr);
977  free(gg);
978  free(bb);
979 
980  } // color map
981 
982  GTIFFree(gtif);
983  XTIFFClose(tiff);
984 
985  // end geotiff
986 
987  } else {
988 
989  fprintf(stderr, "l2mapgen: Error: invalid value for outmode - %d.\n", input.outmode);
990  exit(EXIT_FAILURE);
991  }
992 
993  for (i = 0; i < l3m_params; i++) {
994  free(parmname_list[i]);
995  free(parmname_short[i]);
996  free(unit_list[i]);
997  free(scaling_list[i]);
998  free(palette_list[i]);
999  free(precision_list[i]);
1000  }
1001  free(parmname_list);
1002  free(parmname_short);
1003  free(unit_list);
1004  free(scaling_list);
1005  free(palette_list);
1006  free(maximum_list);
1007  free(minimum_list);
1008  free(precision_list);
1009 
1010  free(sum);
1011  free(count);
1012  free(mean);
1013  free(mask);
1014  free(rgb);
1015  free(r);
1016  free(g);
1017  free(b);
1018  fprintf(stderr, "Done.\n");
1019 
1020  return (EXIT_SUCCESS);
1021 
1022 }
1023 
1024 
1025 
1026 /*------------------------------------------------------------------------------
1027 
1028  Function: scan_convert
1029 
1030  Returns type: int
1031 
1032  Description: This function is derived from the scan-conversion
1033  code used by an X-server for filling in polygons.
1034 
1035  Parameters: (in calling order)
1036  Type Name I/O Description
1037  ---- ---- --- -----------
1038  struct _DDXPoint* ptsIn In vertex specifications
1039 
1040  Modification history:
1041  Programmer Date Description of change
1042  ---------- ---- ---------------------
1043  Norman Kuring 15-Sep-1992 Adaptation from X-server code
1044  for my own nefarious purposes.
1045 
1046 ------------------------------------------------------------------------------*/
1047 
1048 /***********************************************************
1049 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
1050 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
1051 
1052  All Rights Reserved
1053 
1054 Permission to use, copy, modify, and distribute this software and its
1055 documentation for any purpose and without fee is hereby granted,
1056 provided that the above copyright notice appear in all copies and that
1057 both that copyright notice and this permission notice appear in
1058 supporting documentation, and that the names of Digital or MIT not be
1059 used in advertising or publicity pertaining to distribution of the
1060 software without specific, written prior permission.
1061 
1062 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
1063 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
1064 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
1065 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1066 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1067 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
1068 SOFTWARE.
1069 
1070  ******************************************************************/
1071 /* $XConsortium: mipolygen.c,v 5.0 89/06/09 15:08:35 keith Exp $ */
1072 
1073 extern void miloadAET(), micomputeWAET(), miFreeStorage();
1074 
1075 /*
1076  *
1077  * Written by Brian Kelleher; Oct. 1985
1078  *
1079  * Routine to fill a polygon. Two fill rules are
1080  * supported: frWINDING and frEVENODD.
1081  *
1082  * See fillpoly.h for a complete description of the algorithm.
1083  *
1084  * Modified by Norman Kuring to fill a bin-number array instead of
1085  * filling shapes on the server.
1086  */
1087 
1088 int scan_convert(XPoint *ptsIn) {
1089  int count = 8;
1090  register EdgeTableEntry *pAET; /* the Active Edge Table */
1091  register int y; /* the current scanline */
1092  register int nPts = 0; /* number of pts in buffer */
1093  register EdgeTableEntry *pWETE; /* Winding Edge Table */
1094  register ScanLineList *pSLL; /* Current ScanLineList */
1095  register XPoint *ptsOut; /* ptr to output buffers */
1096  int *wdth;
1097  XPoint FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
1098  int FirstWidth[NUMPTSTOBUFFER];
1099  EdgeTableEntry *pPrevAET; /* previous AET entry */
1100  EdgeTable ET; /* Edge Table header node */
1101  EdgeTableEntry AET; /* Active ET header node */
1102  EdgeTableEntry *pETEs; /* Edge Table Entries buff */
1103  ScanLineListBlock SLLBlock; /* header for ScanLineList */
1104  int fixWAET = 0;
1105 
1106  if (!(pETEs = (EdgeTableEntry *) malloc(sizeof (EdgeTableEntry) * count))) {
1107  return (0);
1108  }
1109  ptsOut = FirstPoint;
1110  wdth = FirstWidth;
1111  if (!miCreateETandAET(count, ptsIn, &ET, &AET, pETEs, &SLLBlock)) {
1112  free(pETEs);
1113  return (0);
1114  }
1115  pSLL = ET.scanlines.next;
1116 
1117  /*
1118  * for each scanline
1119  */
1120  for (y = ET.ymin; y < ET.ymax; y++) {
1121  /*
1122  * Add a new edge to the active edge table when we
1123  * get to the next edge.
1124  */
1125  if (pSLL && y == pSLL->scanline) {
1126  miloadAET(&AET, pSLL->edgelist);
1127  micomputeWAET(&AET);
1128  pSLL = pSLL->next;
1129  }
1130  pPrevAET = &AET;
1131  pAET = AET.next;
1132  pWETE = pAET;
1133 
1134  /*
1135  * for each active edge
1136  */
1137  while (pAET) {
1138  /*
1139  * if the next edge in the active edge table is
1140  * also the next edge in the winding active edge
1141  * table.
1142  */
1143  if (pWETE == pAET) {
1144  ptsOut->x = pAET->bres.minor;
1145  ptsOut++->y = y;
1146  *wdth++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
1147  nPts++;
1148 
1149  /*
1150  * send out the buffer
1151  */
1152  if (nPts == NUMPTSTOBUFFER) {
1153  collect_bins(nPts, FirstPoint, FirstWidth);
1154  ptsOut = FirstPoint;
1155  wdth = FirstWidth;
1156  nPts = 0;
1157  }
1158 
1159  pWETE = pWETE->nextWETE;
1160  while (pWETE != pAET)
1161  EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
1162  pWETE = pWETE->nextWETE;
1163  }
1164  EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
1165  }
1166 
1167  /*
1168  * reevaluate the Winding active edge table if we
1169  * just had to resort it or if we just exited an edge.
1170  */
1171  if (miInsertionSort(&AET) || fixWAET) {
1172  micomputeWAET(&AET);
1173  fixWAET = 0;
1174  }
1175  }
1176 
1177  /*
1178  * Get any spans that we missed by buffering
1179  */
1180  collect_bins(nPts, FirstPoint, FirstWidth);
1181  free(pETEs);
1182  miFreeStorage(SLLBlock.next);
1183  return (1);
1184 }
1185 
1187  int number_of_initial_points,
1188  XPoint *initial_point,
1189  int *span_width
1190  ) {
1191 
1192  int i;
1193  short x, y;
1194  int end;
1195 
1196  /* The variables, width, height, binsoverlain, and numoverlain, are
1197  * static global varibles. */
1198 
1199  for (i = 0; i < number_of_initial_points; i++) {
1200 
1201  y = initial_point[i].y;
1202  if (y >= height || y < 0) continue;
1203 
1204  for (
1205  x = initial_point[i].x,
1206  end = initial_point[i].x + span_width[i];
1207  x < end;
1208  x++
1209  ) {
1210  if (x >= width || x < 0) continue;
1211  if (numoverlain >= binsperpixel) {
1212  binsperpixel += 1024;
1213  binsoverlain = (int *) realloc(binsoverlain, binsperpixel * sizeof (int));
1214  if (binsoverlain == NULL) {
1215  fprintf(stderr, "-E- %s line %d: ", __FILE__, __LINE__);
1216  fprintf(stderr,
1217  "Memory allocation error (numoverlain=%d binsperpixel=%d\n",
1218  numoverlain, binsperpixel);
1219  exit(EXIT_FAILURE);
1220  }
1221  return (0);
1222  }
1223  binsoverlain[numoverlain++] = y * width + x;
1224  }
1225  }
1226  return (1);
1227 }
int32_t openL2(const char *fname, char *plist, l2_prod *l2_str)
Definition: readL2scan.c:296
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:975
#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
list(APPEND LIBS ${PGSTK_LIBRARIES}) add_executable(atteph_info_modis atteph_info_modis.c) target_link_libraries(atteph_info_modis $
Definition: CMakeLists.txt:7
#define DEF_FLAG
Definition: l1c_input.h:17
float mean(float *xs, int sample_size)
Definition: numerical.c:81
#define PI
Definition: main_l2mapgen.c:48
int16_t * qual
Definition: l2bin.cpp:86
#define NULL
Definition: decode_rs.h:63
int32_t readL2meta(meta_l2Type *meta_l2, int32_t ifile)
Definition: readL2scan.c:2081
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
float * lat
int32_t readL2(l2_prod *l2_str, int32_t ifile, int32_t recnum, int32_t iprod, unsigned char *scan_in_rowgroup)
Definition: readL2scan.c:1250
int32_t closeL2(l2_prod *l2_str, int32_t ifile)
Definition: readL2scan.c:1936
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
void setupflags(char *flagdef, char *flaguse, uint32_t *flagusemask, uint32_t *required, int *status)
Definition: setupflags.c:5
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
float * lon
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)
msiBandIdx val
Definition: l1c_msi.cpp:34
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
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:27
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