OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
get_l2prod_index.c
Go to the documentation of this file.
1 /* -------------------------------------------------------------------------- */
2 /* Module get_l2prod_index - maintains a list of all possible L2 products and */
3 /* returns attributes on request. */
4 /* */
5 /* B. A. Franz, SAIC GSC, NASA/SIMBIOS Project, April 1999 */
6 /* -------------------------------------------------------------------------- */
7 
8 #include <stdio.h>
9 #include <strings.h>
10 #include "l12_proto.h"
11 #include "l2prod.h"
12 
13 #include <productInfo.h>
14 
15 
16 #define ARRAY_CHUNK_SIZE 20
17 
18 static l2prodstr **l2prod_array = NULL; // array of pointers to all the products
19 static int l2prod_num = 0; // number of products in the array
20 static int l2prod_storage = 0; // size of the array holding the pointers
21 
22 /* init a product structure */
23 void initProduct(l2prodstr* l2prod) {
24  l2prod->param_type = PARAM_TYPE_NONE;
25  l2prod->name_prefix[0] = '\0';
26  l2prod->name_suffix[0] = '\0';
27  l2prod->cat_ix = -1;
28  l2prod->prod_ix = -1;
29  l2prod->datatype = DFNT_FLOAT32;
30  l2prod->slope = 1.0;
31  l2prod->offset = 0.0;
32  l2prod->min = 0;
33  l2prod->max = 0;
34  l2prod->rank = 2;
35  strcpy(l2prod->title_format, "no title format yet (%d)");
36  strcpy(l2prod->title, "no title yet");
37  strcpy(l2prod->units, "undefined units");
38  l2prod->badData = BAD_FLT;
39  l2prod->product_id[0] = '\0';
40  l2prod->algorithm_id[0] = '\0';
41  l2prod->standard_name[0] = '\0';
42 }
43 
44 /* create a new product structure, init it, add it to the global array
45  * and return the pointer.
46  */
47 l2prodstr* createNewProduct() {
48 
49  // allocate the structure
50  l2prodstr* l2prod = (l2prodstr*) malloc(sizeof (l2prodstr));
51 
52  initProduct(l2prod);
53 
54  // add the product structure to the global array
55  l2prod_num++;
56  if (l2prod_num > l2prod_storage) {
57  l2prod_storage += ARRAY_CHUNK_SIZE;
58  l2prod_array = (l2prodstr**) realloc(l2prod_array, l2prod_storage * sizeof (l2prodstr*));
59  }
60  l2prod_array[l2prod_num - 1] = l2prod;
61 
62  return l2prod;
63 }
64 
65 /* -------------------------------------------------------------------------- */
66 int convertDataType(char* str) {
67  if (strcmp(str, "byte") == 0)
68  return DFNT_INT8;
69  if (strcmp(str, "ubyte") == 0)
70  return DFNT_UINT8;
71  if (strcmp(str, "short") == 0)
72  return DFNT_INT16;
73  if (strcmp(str, "ushort") == 0)
74  return DFNT_UINT16;
75  if (strcmp(str, "int") == 0)
76  return DFNT_INT32;
77  if (strcmp(str, "uint") == 0)
78  return DFNT_UINT32;
79  if (strcmp(str, "float") == 0)
80  return DFNT_FLOAT32;
81  if (strcmp(str, "double") == 0)
82  return DFNT_FLOAT64;
83  return DFNT_FLOAT32;
84 }
85 
86 /* -------------------------------------------------------------------------- */
87 int convertParamType(char* str) {
88  if (strcmp(str, "none") == 0)
89  return PARAM_TYPE_NONE;
90  if (strcmp(str, "wave") == 0)
91  return PARAM_TYPE_ALL_WAVE;
92  if (strcmp(str, "uv") == 0)
93  return PARAM_TYPE_ALL_WAVE;
94  if (strcmp(str, "visible") == 0)
95  return PARAM_TYPE_VIS_WAVE;
96  if (strcmp(str, "nir") == 0)
97  return PARAM_TYPE_ALL_WAVE;
98  if (strcmp(str, "swir") == 0)
99  return PARAM_TYPE_ALL_WAVE;
100  if (strcmp(str, "emissive") == 0)
101  return PARAM_TYPE_ALL_WAVE;
102  if (strcmp(str, "band") == 0)
103  return PARAM_TYPE_BAND;
104  if (strcmp(str, "int") == 0)
105  return PARAM_TYPE_INT;
106  return PARAM_TYPE_NONE;
107 }
108 
109 int compareProd(l2prodstr *prod1, l2prodstr *prod2) {
110 
111  /*
112  printf("param_type %d=%d\n", prod1->param_type, prod2->param_type);
113  printf("name_prefix %s=%s\n", prod1->name_prefix, prod2->name_prefix);
114  printf("name_suffix %s=%s\n", prod1->name_suffix, prod2->name_suffix);
115  printf("cat_ix %d=%d\n", prod1->cat_ix, prod2->cat_ix);
116  printf("prod_ix %d=%d\n", prod1->prod_ix, prod2->prod_ix);
117  printf("datatype %d=%d\n", prod1->datatype, prod2->datatype);
118  printf("slope %f=%f\n", prod1->slope, prod2->slope);
119  printf("offset %f=%f\n", prod1->offset, prod2->offset);
120  printf("min %f=%f\n", prod1->min, prod2->min);
121  printf("max %f=%f\n", prod1->max, prod2->max);
122  printf("rank %d=%d\n", prod1->rank, prod2->rank);
123  //prod->dim
124  //prod->dimname
125  printf("title_format %s=%s\n", prod1->title_format, prod2->title_format);
126  printf("title %s=%s\n", prod1->title, prod2->title);
127  printf("units %s=%s\n", prod1->units, prod2->units);
128  printf("badData %f=%f\n", prod1->badData, prod2->badData);
129  printf("product_id %s=%s\n", prod1->product_id, prod2->product_id);
130  printf("algorithm_id %s=%s\n", prod1->algorithm_id, prod2->algorithm_id);
131  printf("standard_name %s=%s\n", prod1->standard_name, prod2->standard_name);
132 
133  */
134 
135 
136 
137 
138 
139 
140 
141  int result = 1;
142 
143  if (prod1->param_type != prod2->param_type) {
144  result = 0;
145  printf("param_type %d=%d\n", prod1->param_type, prod2->param_type);
146  }
147  if (strcmp(prod1->name_prefix, prod2->name_prefix)) {
148  result = 0;
149  printf("name_prefix %s=%s\n", prod1->name_prefix, prod2->name_prefix);
150  }
151  if (strcmp(prod1->name_suffix, prod2->name_suffix)) {
152  result = 0;
153  printf("name_suffix %s=%s\n", prod1->name_suffix, prod2->name_suffix);
154  }
155  if (prod1->cat_ix != prod2->cat_ix) {
156  result = 0;
157  printf("cat_ix %d=%d\n", prod1->cat_ix, prod2->cat_ix);
158  }
159  if (prod1->prod_ix != prod2->prod_ix) {
160  result = 0;
161  printf("prod_ix %d=%d\n", prod1->prod_ix, prod2->prod_ix);
162  }
163  if (prod1->datatype != prod2->datatype) {
164  result = 0;
165  printf("datatype %d=%d\n", prod1->datatype, prod2->datatype);
166  }
167  if (prod1->slope != prod2->slope) {
168  result = 0;
169  printf("slope %f=%f\n", prod1->slope, prod2->slope);
170  }
171  if (prod1->offset != prod2->offset) {
172  result = 0;
173  printf("offset %f=%f\n", prod1->offset, prod2->offset);
174  }
175  if (prod1->min != prod2->min) {
176  result = 0;
177  printf("min %f=%f\n", prod1->min, prod2->min);
178  }
179  if (prod1->max != prod2->max) {
180  result = 0;
181  printf("max %f=%f\n", prod1->max, prod2->max);
182  }
183  if (prod1->rank != prod2->rank) {
184  result = 0;
185  printf("rank %d=%d\n", prod1->rank, prod2->rank);
186  //prod->dim
187  //prod->dimname
188  }
189  if (strcmp(prod1->title_format, prod2->title_format)) {
190  result = 0;
191  printf("title_format %s=%s\n", prod1->title_format, prod2->title_format);
192  }
193  if (strcmp(prod1->title, prod2->title)) {
194  result = 0;
195  printf("title %s=%s\n", prod1->title, prod2->title);
196  }
197  if (strcmp(prod1->units, prod2->units)) {
198  result = 0;
199  printf("units %s=%s\n", prod1->units, prod2->units);
200  }
201  if (prod1->badData != prod2->badData) {
202  result = 0;
203  printf("badData %f=%f\n", prod1->badData, prod2->badData);
204  }
205  if (strcmp(prod1->product_id, prod2->product_id)) {
206  result = 0;
207  printf("product_id %s=%s\n", prod1->product_id, prod2->product_id);
208  }
209  if (strcmp(prod1->algorithm_id, prod2->algorithm_id)) {
210  result = 0;
211  printf("algorithm_id %s=%s\n", prod1->algorithm_id, prod2->algorithm_id);
212  }
213  if (strcmp(prod1->standard_name, prod2->standard_name)) {
214  result = 0;
215  printf("standard_name %s=%s\n", prod1->standard_name, prod2->standard_name);
216  }
217 
218  return result;
219 }
220 
221 /* -------------------------------------------------------------------------- */
222 void init_l2prod() {
223  l2prodstr *l2prod;
224 
225  productInfo_t *productInfo = allocateProductInfo();
226  getFirstProductInfo(productInfo);
227 
228  do {
229  l2prod = createNewProduct();
230  l2prod->param_type = convertParamType(productInfo->paramDesignator);
231  if (l2prod->param_type == PARAM_TYPE_ALL_WAVE
232  && productInfo->paramWaveMin == 400
233  && productInfo->paramWaveMax == 725) {
234  l2prod->param_type = PARAM_TYPE_VIS_WAVE;
235  }
236  strcpy(l2prod->name_prefix, productInfo->prefix);
237  strcpy(l2prod->name_suffix, productInfo->suffix);
238  l2prod->cat_ix = productInfo->cat_ix;
239  l2prod->prod_ix = productInfo->prod_ix;
240  l2prod->datatype = convertDataType(productInfo->dataType);
241  l2prod->slope = productInfo->scaleFactor;
242  l2prod->offset = productInfo->addOffset;
243  l2prod->min = productInfo->validMin;
244  l2prod->max = productInfo->validMax;
245  l2prod->rank = productInfo->rank;
246  //l2prod->dim
247  //l2prod->dimname
248  strcpy(l2prod->title_format, productInfo->titleFormat);
249  if (l2prod->param_type == PARAM_TYPE_NONE)
250  strcpy(l2prod->title, l2prod->title_format);
251  strcpy(l2prod->units, productInfo->units);
252  l2prod->badData = productInfo->fillValue;
253  strcpy(l2prod->product_id, productInfo->productName);
254  strcpy(l2prod->algorithm_id, productInfo->algorithmName);
255  if (productInfo->standardName)
256  strcpy(l2prod->standard_name, productInfo->standardName);
257 
258  } while (getNextProductInfo(productInfo));
259  freeProductInfo(productInfo);
260 }
261 
262 /* read the product structure and copy the product name into name */
263 void getProductName(char* name, l2prodstr* product) {
264  if (product->product_id[0] != '\0') {
265  strcpy(name, product->product_id);
266  } else {
267  strcpy(name, product->name_prefix);
268 
269  // remove trailing underscore
270  if (name[strlen(name) - 1] == '_') {
271  name[strlen(name) - 1] = '\0';
272  }
273  }
274 }
275 
276 /* read the product structure and copy the prefix into name */
277 void getPrefix(char* name, l2prodstr* product) {
278  char productName[UNITLEN];
279  getProductName(productName, product);
280  strcat(productName, "_");
281  if (strcmp(productName, product->name_prefix) == 0)
282  name[0] = 0;
283  else
284  strcpy(name, product->name_prefix);
285  return;
286 }
287 
288 /* read the product structure and copy the algorithm name into name */
289 void getAlgorithmName(char* name, l2prodstr* product) {
290  int i;
291  int length;
292 
293  if (product->algorithm_id[0] != '\0') {
294  strcpy(name, product->algorithm_id);
295  } else {
296  strcpy(name, product->name_suffix);
297 
298  // remove leading underscore
299  if (name[0] == '_') {
300  length = strlen(name);
301  for (i = 1; i <= length; i++) {
302  name[i - 1] = name[i];
303  }
304  }
305  }
306 }
307 
308 /* read the product structure and copy the suffix into name */
309 void getSuffix(char* name, l2prodstr* product) {
310  char algorithmName[UNITLEN];
311  algorithmName[0] = '_';
312  getAlgorithmName(algorithmName + 1, product);
313  if (strcmp(algorithmName, product->name_suffix) == 0)
314  name[0] = 0;
315  else
316  strcpy(name, product->name_suffix);
317  return;
318 }
319 
320 /* read the product structure and copy the product param type into name */
321 void getParamType(char* name, l2prodstr* product) {
322  switch (product->param_type) {
323  case PARAM_TYPE_NONE:
324  strcpy(name, "None");
325  break;
326  case PARAM_TYPE_VIS_WAVE:
327  strcpy(name, "Visible");
328  break;
329  case PARAM_TYPE_ALL_WAVE:
330  strcpy(name, "All");
331  break;
332  case PARAM_TYPE_BAND:
333  strcpy(name, "Bands");
334  break;
335  case PARAM_TYPE_INT:
336  strcpy(name, "Integer");
337  break;
338  default:
339  strcpy(name, "Unknown");
340  break;
341  }
342 }
343 
344 /* read the product structure and copy the product data type into name */
345 void getDataType(char* name, l2prodstr* product) {
346  switch (product->datatype) {
347  case DFNT_INT8:
348  strcpy(name, "INT8");
349  break;
350  case DFNT_UINT8:
351  strcpy(name, "UINT8");
352  break;
353  case DFNT_INT16:
354  strcpy(name, "INT16");
355  break;
356  case DFNT_INT32:
357  strcpy(name, "INT32");
358  break;
359  case DFNT_FLOAT32:
360  strcpy(name, "FLOAT32");
361  break;
362  case DFNT_FLOAT64:
363  strcpy(name, "FLOAT64");
364  break;
365  default:
366  strcpy(name, "Unknown");
367  break;
368  }
369 }
370 
371 void setTitleString(l2prodstr* product) {
372  switch (product->param_type) {
373  case PARAM_TYPE_NONE:
374  break;
375  case PARAM_TYPE_VIS_WAVE:
376  case PARAM_TYPE_ALL_WAVE:
377  case PARAM_TYPE_BAND:
378  case PARAM_TYPE_INT:
379  sprintf(product->title, product->title_format, 0);
380  break;
381  }
382 }
383 
384 void getFullProductName(char* name, l2prodstr* prod) {
385  if (prod->param_type == PARAM_TYPE_NONE) {
386  strcpy(name, prod->name_prefix);
387  strcat(name, prod->name_suffix);
388  } else {
389  strcpy(name, prod->name_prefix);
390  strcat(name, "nnn");
391  strcat(name, prod->name_suffix);
392  }
393 }
394 
395 /* dump the product list to a file */
396 void dumpProductStructure(l2prodstr **list, char* filename) {
397  l2prodstr* product;
398  int productIndex;
399  char fullProductName[UNITLEN];
400  char productName[UNITLEN];
401  char algorithmName[UNITLEN];
402  char paramType[UNITLEN];
403  char* description;
404  FILE* fout;
405 
406  fout = fopen(filename, "w");
407 
408  for (productIndex = 0; productIndex < l2prod_num; productIndex++) {
409  product = list[productIndex];
410  getProductName(productName, product);
411  getAlgorithmName(algorithmName, product);
412  getParamType(paramType, product);
413  getFullProductName(fullProductName, product);
414  if (product->param_type == PARAM_TYPE_NONE) {
415  description = product->title;
416  } else {
417  description = product->title_format;
418  }
419 
420  fprintf(fout, "%s, %s, %s, %s, %d, %d, %d, %g, %g, %g, %g, %g, %d, %s, %s, %s\n",
421  fullProductName,
422  paramType,
423  productName,
424  algorithmName,
425  product->cat_ix,
426  product->prod_ix,
427  product->datatype,
428  product->slope,
429  product->offset,
430  product->min,
431  product->max,
432  product->badData,
433  product->rank,
434  product->units,
435  description,
436  product->standard_name);
437  }
438 
439  fclose(fout);
440 }
441 
442 char* xmlEncapsulateText(char* str) {
443  static int strLength = 0;
444  static char* buffer = NULL;
445 
446  if (strpbrk(str, "<>&")) {
447  // make buffer big enough
448  int length = strlen(str) + 15;
449  if (strLength < length) {
450  if (buffer)
451  free(buffer);
452  strLength = length;
453  buffer = (char*) malloc(strLength);
454  }
455 
456  sprintf(buffer, "<![CDATA[%s]]>", str);
457  return buffer;
458  }
459  return str;
460 }
461 
462 void XML_file_header(FILE* fout) {
463  fprintf(fout, "<productList>\n");
464 }
465 
466 void XML_file_footer(FILE* fout) {
467  fprintf(fout, "</productList>\n");
468 }
469 
470 void XML_product_header(FILE* fout, l2prodstr* product) {
471  char name[UNITLEN];
472 
474  fprintf(fout, " <product name=\"%s\">\n", name);
475 }
476 
477 void XML_product_footer(FILE* fout) {
478  fprintf(fout, " </product>\n");
479 }
480 
481 void XML_algorithm(FILE* fout, l2prodstr* product) {
482  char name[UNITLEN];
483  char param[UNITLEN];
484  char data[UNITLEN];
485 
487  getParamType(param, product);
490 
491  if (strlen(name) > 0) {
492  fprintf(fout, " <algorithm name=\"%s\">\n", name);
493  } else {
494  fprintf(fout, " <algorithm>\n");
495  }
496  clo_writeXmlTag(fout, 3, "prefix", product->name_prefix);
497  clo_writeXmlTag(fout, 3, "suffix", product->name_suffix);
498  clo_writeXmlTag(fout, 3, "parameterType", param);
499  clo_writeXmlTag(fout, 3, "dataType", data);
500  clo_writeXmlTag(fout, 3, "units", product->units);
501  clo_writeXmlTag(fout, 3, "description", product->title);
502  fprintf(fout, " </algorithm>\n");
503 }
504 
506  l2prodstr **tmpList = NULL; // array of pointers to all the products
507  l2prodstr **sortedList = NULL; // array of pointers to all the products
508  int sortedIndex = 0; // number of products in the array
509  l2prodstr* product;
510  l2prodstr* product2;
511  static l2prodstr *chlProd;
512  char productName[UNITLEN];
513  char productName2[UNITLEN];
514  int productIndex;
515  int productIndex2;
516  FILE* fout;
517 
518  if (filename == NULL || filename[0] == 0) {
519  printf("%s Line %d: NULL filename for XML file.\n",
520  __FILE__, __LINE__);
521  exit(1);
522  }
523 
524  if (chlProd == NULL) {
525  // allocate the structure
526  chlProd = (l2prodstr*) malloc(sizeof (l2prodstr));
527  initProduct(chlProd);
528 
529  chlProd->cat_ix = CAT_chl_oc2;
530  strncpy(chlProd->name_prefix, "chlor_a", UNITLEN);
531  strncpy(chlProd->product_id, "chlor_a", UNITLEN);
532  strncpy(chlProd->algorithm_id, "chlor_a", UNITLEN);
533  strncpy(chlProd->units, "mg m^-3", UNITLEN);
534  strncpy(chlProd->title, "Chlorophyll Concentration, Default Sensor Algorithm", TITLELEN);
535  strncpy(chlProd->standard_name, "chlorophyll_concentration_in_sea_water", TITLELEN);
536  }
537 
538  // allocate lists
539  tmpList = (l2prodstr**) malloc((l2prod_num + 1) * sizeof (l2prodstr*));
540  sortedList = (l2prodstr**) malloc((l2prod_num + 1) * sizeof (l2prodstr*));
541 
542  // copy list
543  for (productIndex = 0; productIndex < l2prod_num; productIndex++) {
544  tmpList[productIndex] = l2prod_array[productIndex];
545  }
546 
547  // add default chl
548  tmpList[productIndex] = chlProd;
549 
550  // sort list by product name
551  for (productIndex = 0; productIndex < l2prod_num + 1; productIndex++) {
552  product = tmpList[productIndex];
553  if (product) {
554  getProductName(productName, product);
555  sortedList[sortedIndex++] = product; // add to sorted
556  tmpList[productIndex] = NULL; // remove from tmp
557 
558  // search for matching product entries
559  for (productIndex2 = productIndex + 1; productIndex2 < l2prod_num + 1; productIndex2++) {
560  product2 = tmpList[productIndex2];
561  if (product2) {
562  getProductName(productName2, product2);
563  if (strcasecmp(productName, productName2) == 0) {
564  sortedList[sortedIndex++] = product2; // add to sorted
565  tmpList[productIndex2] = NULL; // remove from tmp
566  } // name matches
567  } // product2 exists
568  } // for product2
569  } // product exists
570  } // for product
571 
572  // open XML file
573  fout = fopen(filename, "w");
574 
575  // loop sorted list to print XML
576  XML_file_header(fout);
577  getProductName(productName2, sortedList[0]);
578  XML_product_header(fout, sortedList[0]);
579 
580  for (productIndex = 0; productIndex < l2prod_num + 1; productIndex++) {
581  product = sortedList[productIndex];
582  getProductName(productName, product);
583 
584  // if changed product
585  if (strcasecmp(productName, productName2) != 0) {
586  strcpy(productName2, productName);
587  XML_product_footer(fout);
589  }
590  XML_algorithm(fout, product);
591  }
592 
593  XML_product_footer(fout);
594  XML_file_footer(fout);
595 
596  // close XML file
597  fclose(fout);
598 
599  // free lists
600  free(tmpList);
601  free(sortedList);
602 }
603 
604 /* -------------------------------------------------------------------------- */
605 l2prodstr *get_l2prod_index(char *prod_name, /* Input SDS name */
606  int32 sensorID, /* Sensor ID */
607  int32 numBands, /* Number of Wavelengths */
608  int32 numPixels, /* Number of Pixels per Scan */
609  int32 numScans, /* Number of Scans in File */
610  int32_t wave[]) /* Wavelength Array (numBands) */ {
611  int i;
612  int prodIndex;
613  char tmp_pname[32];
614  l2prodstr *p = NULL;
615  int status;
616 
617  static int first = 1;
618  static int lastNumPixels = 0;
619  static int default_iprod_chl = -1;
620  static l2prodstr* default_prod_chl = NULL;
621  static productInfo_t* info;
622 
623 
624  if (first) {
625  first = 0;
626  lastNumPixels = numPixels;
627  info = allocateProductInfo();
628  init_l2prod();
629 
630  // loop through the products and set some default info
631  for (i = 0; i < l2prod_num; i++) {
632  l2prodstr *l2prod = l2prod_array[i];
633  if (l2prod->rank == 3) {
634  l2prod->dim[0] = numScans;
635  l2prod->dim[1] = numPixels;
636  l2prod->dim[2] = numBands;
637  strncpy(l2prod->dimname[0], "Number of Scan Lines", DIMNAMELEN);
638  strncpy(l2prod->dimname[1], "Pixels per Scan Line", DIMNAMELEN);
639  strncpy(l2prod->dimname[2], "Bands per Pixel", DIMNAMELEN);
640  } else if (l2prod->rank == 2) {
641  l2prod->dim[0] = numScans;
642  l2prod->dim[1] = numPixels;
643  l2prod->dim[2] = 1;
644  strncpy(l2prod->dimname[0], "Number of Scan Lines", DIMNAMELEN);
645  strncpy(l2prod->dimname[1], "Pixels per Scan Line", DIMNAMELEN);
646  strncpy(l2prod->dimname[2], "", DIMNAMELEN);
647  } else if (l2prod->rank == 1) {
648  l2prod->dim[0] = numScans;
649  l2prod->dim[1] = 1;
650  l2prod->dim[2] = 1;
651  strncpy(l2prod->dimname[0], "Number of Scan Lines", DIMNAMELEN);
652  strncpy(l2prod->dimname[1], "", DIMNAMELEN);
653  strncpy(l2prod->dimname[2], "", DIMNAMELEN);
654  }
655  }
656  // the following needs to be consistent with libl2/productInfo.c:findProductInfo
657  switch (sensorID) {
658  case OCTS:
659  case SEAWIFS:
660  case OCM1:
661  case OCM2:
662  case MOS:
663  case MERIS:
664  case HICO:
665  case OCIA:
666  case OCI:
667  case OCIS:
668  case HAWKEYE:
669  case AVIRIS:
670  case PRISM:
671  case OLCIS3A:
672  case OLCIS3B:
673  default_iprod_chl = CAT_chl_oc4;
674  break;
675  case MODIST:
676  case MODISA:
677  case CZCS:
678  case OSMI:
679  case VIIRSN:
680  case VIIRSJ1:
681  case VIIRSJ2:
682  case OCRVC:
683  case GOCI:
684  case SGLI:
685  case OLIL8:
686  case OLIL9:
687  case MSIS2A:
688  case MSIS2B:
689  default_iprod_chl = CAT_chl_oc3;
690  break;
691  case L5TM:
692  case L7ETMP:
693  case MISR:
694  default_iprod_chl = CAT_chl_oc2;
695  break;
696  case AVHRR:
697  break;
698  default:
699  printf("%s Line %d: need a default chlorophyll algorithm for this sensor\n",
700  __FILE__, __LINE__);
701  exit(1);
702  break;
703  } // switch
704 
705  for (prodIndex = 0; prodIndex < l2prod_num; prodIndex++) {
706  p = l2prod_array[prodIndex];
707  if (p->cat_ix == default_iprod_chl) {
708  default_prod_chl = p;
709  break;
710  }
711  }
712  if (default_prod_chl == NULL && sensorID != AVHRR) {
713  printf("%s Line %d: could not find the default chlorophyll algorithm for this sensor\n",
714  __FILE__, __LINE__);
715  exit(1);
716  }
717 
718  // fix the title of the CDOM-corrected CHL model
719  for (prodIndex = 0; prodIndex < l2prod_num; prodIndex++) {
720  p = l2prod_array[prodIndex];
721  if (p->cat_ix == CAT_chl_cdomcorr_morel) {
722  sprintf(p->title, "%s, CDOM-corrected via Morel",
723  default_prod_chl->title);
724  break;
725  }
726  }
727 
728  } // if first
729 
730  if (numPixels != lastNumPixels) {
731  lastNumPixels = numPixels;
732  for (i = 0; i < l2prod_num; i++) {
733  l2prodstr *l2prod = l2prod_array[i];
734  if (l2prod->rank == 2 ) {
735  l2prod->dim[1] = numPixels;
736  }
737  if (l2prod->rank == 3) {
738  l2prod->dim[1] = numPixels;
739  l2prod->dim[2] = numBands;
740  }
741  }
742  }
743 
744  if (strcmp(prod_name, "chl_ocx") == 0) { /* Sensor default chlorophyll-a */
745  return default_prod_chl;
746  }
747 
748  // loop through products until we find a match
749  for (prodIndex = 0; prodIndex < l2prod_num; prodIndex++) {
750  p = l2prod_array[prodIndex];
751  switch (p->param_type) {
752  case PARAM_TYPE_NONE:
753  sprintf(tmp_pname, "%s%s", p->name_prefix, p->name_suffix);
754  if (strcmp(prod_name, tmp_pname) == 0)
755  return p;
756  break;
757 
758  case PARAM_TYPE_VIS_WAVE:
759  case PARAM_TYPE_ALL_WAVE:
760  if (strncmp(prod_name, p->name_prefix, strlen(p->name_prefix)) == 0) {
761  for (i = 0; i < numBands; i++) {
762  sprintf(tmp_pname, "%s%d%s", p->name_prefix, wave[i], p->name_suffix);
763  if (strcmp(prod_name, tmp_pname) == 0) {
764  p->prod_ix = i;
765  sprintf(p->title, p->title_format, wave[i]);
766 
767  // fix the values that change due to range
768  status = findProductInfo(prod_name, sensorID, info);
769  if (status) {
770  p->slope = info->scaleFactor;
771  p->offset = info->addOffset;
772  p->max = info->validMax;
773  p->min = info->validMin;
774  }
775  return p;
776  }
777  } // for bands
778  } // if prefix matches
779  break;
780 
781  case PARAM_TYPE_BAND:
782  for (i = 0; i < numBands; i++) {
783  sprintf(tmp_pname, "%s%d%s", p->name_prefix, i + 1, p->name_suffix);
784  if (strcmp(prod_name, tmp_pname) == 0) {
785  p->prod_ix = i;
786  sprintf(p->title, p->title_format, i);
787 
788  // fix the values that change due to range
789  status = findProductInfo(prod_name, sensorID, info);
790  if (status) {
791  p->slope = info->scaleFactor;
792  p->offset = info->addOffset;
793  p->max = info->validMax;
794  p->min = info->validMin;
795  }
796  return p;
797  }
798  }
799  break;
800 
801  case PARAM_TYPE_INT:
802  if (p->name_suffix[0] == 0) {
803  if (strncmp(prod_name, p->name_prefix, strlen(p->name_prefix)) == 0) {
804  p->prod_ix = atoi(&prod_name[strlen(p->name_prefix)]);
805  sprintf(p->title, p->title_format, p->prod_ix);
806  // fix the values that change due to range
807  status = findProductInfo(prod_name, sensorID, info);
808  if (status) {
809  p->slope = info->scaleFactor;
810  p->offset = info->addOffset;
811  p->max = info->validMax;
812  p->min = info->validMin;
813  }
814  return p;
815  }
816  } else {
817  if ((strncmp(prod_name, p->name_prefix, strlen(p->name_prefix)) == 0) &&
818  (strcmp(prod_name + strlen(prod_name) - strlen(p->name_suffix), p->name_suffix) == 0)) {
819  p->prod_ix = atoi(&prod_name[strlen(p->name_prefix)]);
820  sprintf(p->title, p->title_format, p->prod_ix);
821  // fix the values that change due to range
822  status = findProductInfo(prod_name, sensorID, info);
823  if (status) {
824  p->slope = info->scaleFactor;
825  p->offset = info->addOffset;
826  p->max = info->validMax;
827  p->min = info->validMin;
828  }
829  return p;
830  }
831  } // prefix and suffix
832  break;
833 
834  } // switch
835 
836  } // for product list
837 
838  fprintf(stderr, "\n%s - Invalid product name : %s\n", __FILE__, prod_name);
839  exit(1);
840 }
841 
void getAlgorithmName(char *name, l2prodstr *product)
#define OLCIS3A
Definition: sensorDefs.h:32
void dumpProductStructure(l2prodstr **list, char *filename)
void freeProductInfo(productInfo_t *info)
void getFullProductName(char *name, l2prodstr *prod)
void XML_file_header(FILE *fout)
int status
Definition: l1_czcs_hdf.c:32
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 SGLI
Definition: sensorDefs.h:33
#define AVHRR
Definition: sensorDefs.h:15
#define OCI
Definition: sensorDefs.h:42
void getFirstProductInfo(productInfo_t *info)
#define UNITLEN
Definition: l2prod_struc.h:8
#define MSIS2B
Definition: sensorDefs.h:38
#define OSMI
Definition: sensorDefs.h:16
#define NULL
Definition: decode_rs.h:63
#define OLIL9
Definition: sensorDefs.h:45
#define VIIRSN
Definition: sensorDefs.h:23
#define L5TM
Definition: sensorDefs.h:35
void XML_product_footer(FILE *fout)
#define MERIS
Definition: sensorDefs.h:22
l2prodstr * createNewProduct()
#define MODIST
Definition: sensorDefs.h:18
#define CAT_chl_oc2
Definition: l2prod.h:32
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
void clo_writeXmlTag(FILE *fout, int level, const char *tag, const char *value)
Definition: clo.c:2410
#define OCIA
Definition: sensorDefs.h:29
int convertDataType(char *str)
#define PARAM_TYPE_ALL_WAVE
Definition: l2prod_struc.h:14
#define OLIL8
Definition: sensorDefs.h:27
int convertParamType(char *str)
void setTitleString(l2prodstr *product)
#define PARAM_TYPE_BAND
Definition: l2prod_struc.h:15
#define DIMNAMELEN
Definition: l2prod_struc.h:7
#define CAT_chl_cdomcorr_morel
Definition: l2prod.h:249
productInfo_t * allocateProductInfo()
float32 slope
l2prodstr * get_l2prod_index(char *prod_name, int32 sensorID, int32 numBands, int32 numPixels, int32 numScans, int32_t wave[])
void getPrefix(char *name, l2prodstr *product)
#define HAWKEYE
Definition: sensorDefs.h:39
#define CAT_chl_oc4
Definition: l2prod.h:49
#define OCIS
Definition: sensorDefs.h:43
#define PRISM
Definition: sensorDefs.h:31
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
#define CAT_chl_oc3
Definition: l2prod.h:72
#define AVIRIS
Definition: sensorDefs.h:30
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
void getProductName(char *name, l2prodstr *product)
#define PARAM_TYPE_INT
Definition: l2prod_struc.h:16
description
Definition: setup.py:16
void init_l2prod()
#define MOS
Definition: sensorDefs.h:13
#define MISR
Definition: sensorDefs.h:40
int findProductInfo(const char *productName, int sensorId, productInfo_t *info)
#define L7ETMP
Definition: sensorDefs.h:36
void write_product_XML_file(char *filename)
const char * str
Definition: l1c_msi.cpp:35
#define BAD_FLT
Definition: jplaeriallib.h:19
#define OCTS
Definition: sensorDefs.h:14
#define MSIS2A
Definition: sensorDefs.h:34
#define OCM1
Definition: sensorDefs.h:20
void initProduct(l2prodstr *l2prod)
#define CZCS
Definition: sensorDefs.h:17
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 and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
void XML_product_header(FILE *fout, l2prodstr *product)
void getSuffix(char *name, l2prodstr *product)
#define VIIRSJ2
Definition: sensorDefs.h:44
int compareProd(l2prodstr *prod1, l2prodstr *prod2)
char * xmlEncapsulateText(char *str)
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
void getParamType(char *name, l2prodstr *product)
#define OLCIS3B
Definition: sensorDefs.h:41
#define HICO
Definition: sensorDefs.h:25
#define OCRVC
Definition: sensorDefs.h:24
#define SEAWIFS
Definition: sensorDefs.h:12
int i
Definition: decode_rs.h:71
void XML_file_footer(FILE *fout)
#define PARAM_TYPE_NONE
Definition: l2prod_struc.h:11
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 sensorID[MAXNFILES]
Definition: l2bin.cpp:97
HISTORY txt for MOD_PR01(step one of PGE01) History follows the following convention needed due to new Aqua ReprocessingActual and the expected LUT revision number from PCF Changed to use PGE version for ProductionHistory Added Archive including ProcessingEnvironment Corrected handling of bad to resovle GSFcd02514 Changed to check staged LUT revision number versus the expected LUT revision number from thereby resolving defect report MODxl02056 This change also avoids the memory access violation reported in MODur00039 Changed the way output arrays were initialized with fill to be more but placed into the L1A output product and thought of as valid packets These packets had an invalid frame count in them and since only the last valid packet of any specific type gets it frame count data written to the output product
Definition: HISTORY.txt:176
#define MODISA
Definition: sensorDefs.h:19
#define VIIRSJ1
Definition: sensorDefs.h:37
#define ARRAY_CHUNK_SIZE
#define TITLELEN
Definition: l2prod_struc.h:9
#define OCM2
Definition: sensorDefs.h:21
int getNextProductInfo(productInfo_t *info)
float p[MODELMAX]
Definition: atrem_corl1.h:131
void getDataType(char *name, l2prodstr *product)
void XML_algorithm(FILE *fout, l2prodstr *product)
#define PARAM_TYPE_VIS_WAVE
Definition: l2prod_struc.h:12
#define GOCI
Definition: sensorDefs.h:26