ocssw V2020
productInfo.cpp
Go to the documentation of this file.
1 #include <productInfo.h>
2 
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include <pugixml.hpp>
7 #include <genutils.h>
8 #include <sensorInfo.h>
9 
10 #define XML_STRING_SIZE 512
11 
12 using namespace pugi;
13 
14 /*
15  * global variables
16  */
17 static bool productInitialized = false;
18 static char productXMLFileName[FILENAME_MAX];
19 static xml_document rootNode;
20 static xml_node productsNode;
21 static xml_node productNode;
22 static xml_node algorithmNode;
23 
24 static productInfo_t* productInfo = NULL;
25 static productInfo_t* algorithmInfo = NULL;
26 
27 /*
28  * dup string if src is not NULL.
29  */
30 static char* duplicateString(const char* src) {
31  if (src == NULL)
32  return NULL;
33  else
34  return strdup(src);
35 }
36 
42 extern "C" void clearProductInfo(productInfo_t* info) {
43  if (info->description)
44  free(info->description);
45  info->description = duplicateString(PRODUCT_DEFAULT_description);
46  if (info->units)
47  free(info->units);
48  info->units = duplicateString(PRODUCT_DEFAULT_units);
49  if (info->palette)
50  free(info->palette);
51  info->palette = duplicateString(PRODUCT_DEFAULT_palette);
52  if (info->paramDesignator)
53  free(info->paramDesignator);
54  info->paramDesignator = duplicateString(PRODUCT_DEFAULT_paramDesignator);
55  info->paramWaveMin = PRODUCT_DEFAULT_paramWaveMin;
56  info->paramWaveMax = PRODUCT_DEFAULT_paramWaveMax;
57  if (info->standardName)
58  free(info->standardName);
59  info->standardName = duplicateString(PRODUCT_DEFAULT_standardName);
60  if (info->category)
61  free(info->category);
62  info->category = duplicateString(PRODUCT_DEFAULT_category);
63  if (info->dataType)
64  free(info->dataType);
65  info->dataType = duplicateString(PRODUCT_DEFAULT_dataType);
66  if (info->prefix)
67  free(info->prefix);
68  info->prefix = duplicateString(PRODUCT_DEFAULT_prefix);
69  if (info->suffix)
70  free(info->suffix);
71  info->suffix = duplicateString(PRODUCT_DEFAULT_suffix);
72  if (info->algorithmName)
73  free(info->algorithmName);
74  info->algorithmName = duplicateString(PRODUCT_DEFAULT_algorithmName);
75  if (info->productName)
76  free(info->productName);
77  info->productName = duplicateString(PRODUCT_DEFAULT_productName);
78  info->cat_ix = PRODUCT_DEFAULT_cat_ix;
79  info->prod_ix = PRODUCT_DEFAULT_prod_ix;
80  info->rank = PRODUCT_DEFAULT_rank;
81  info->fillValue = PRODUCT_DEFAULT_fillValue;
82  info->validMin = PRODUCT_DEFAULT_validMin;
83  info->validMax = PRODUCT_DEFAULT_validMax;
84  if (info->displayScale)
85  free(info->displayScale);
86  info->displayScale = duplicateString(PRODUCT_DEFAULT_displayScale);
87  info->displayMin = PRODUCT_DEFAULT_displayMin;
88  info->displayMax = PRODUCT_DEFAULT_displayMax;
89  info->scaleFactor = PRODUCT_DEFAULT_scaleFactor;
90  info->addOffset = PRODUCT_DEFAULT_addOffset;
91  if (info->reference)
92  free(info->reference);
93  info->reference = duplicateString(PRODUCT_DEFAULT_reference);
94  if (info->comment)
95  free(info->comment);
96  info->comment = duplicateString(PRODUCT_DEFAULT_comment);
97  if (info->titleFormat)
98  free(info->titleFormat);
99  info->titleFormat = duplicateString(PRODUCT_DEFAULT_titleFormat);
100 }
101 
107 extern "C" void initProductInfo(productInfo_t* info) {
108  bzero(info, sizeof (productInfo_t));
109  clearProductInfo(info);
110 }
111 
118 extern "C" productInfo_t* allocateProductInfo() {
119  productInfo_t* info = (productInfo_t*) allocateMemory(sizeof (productInfo_t),
120  "productInfo");
121  clearProductInfo(info);
122  return info;
123 }
124 
130 extern "C" void freeProductInfo(productInfo_t* info) {
131  if (info->description)
132  free(info->description);
133  if (info->units)
134  free(info->units);
135  if (info->palette)
136  free(info->palette);
137  if (info->paramDesignator)
138  free(info->paramDesignator);
139  if (info->standardName)
140  free(info->standardName);
141  if (info->category)
142  free(info->category);
143  if (info->dataType)
144  free(info->dataType);
145  if (info->prefix)
146  free(info->prefix);
147  if (info->suffix)
148  free(info->suffix);
149  if (info->algorithmName)
150  free(info->algorithmName);
151  if (info->productName)
152  free(info->productName);
153  if (info->displayScale)
154  free(info->displayScale);
155  if (info->reference)
156  free(info->reference);
157  if (info->comment)
158  free(info->comment);
159  if (info->titleFormat)
160  free(info->titleFormat);
161  free(info);
162 }
163 
170 void copyProductInfoHeader(productInfo_t* dest, const productInfo_t* src) {
171  if (dest->productName)
172  free(dest->productName);
173  dest->productName = duplicateString(src->productName);
174  if (dest->paramDesignator)
175  free(dest->paramDesignator);
176  dest->paramDesignator = duplicateString(src->paramDesignator);
177  dest->paramWaveMin = src->paramWaveMin;
178  dest->paramWaveMax = src->paramWaveMax;
179 }
180 
187 extern "C" void copyProductInfo(productInfo_t* dest, const productInfo_t* src) {
188  if (dest->description && strlen(dest->description) > 0)
189  free(dest->description);
190  dest->description = duplicateString(src->description);
191  if (dest->units)
192  free(dest->units);
193  dest->units = duplicateString(src->units);
194  if (dest->palette)
195  free(dest->palette);
196  dest->palette = duplicateString(src->palette);
197  if (dest->paramDesignator)
198  free(dest->paramDesignator);
199  dest->paramDesignator = duplicateString(src->paramDesignator);
200  dest->paramWaveMin = src->paramWaveMin;
201  dest->paramWaveMax = src->paramWaveMax;
202  if (dest->standardName)
203  free(dest->standardName);
204  dest->standardName = duplicateString(src->standardName);
205  if (dest->category)
206  free(dest->category);
207  dest->category = duplicateString(src->category);
208  if (dest->dataType)
209  free(dest->dataType);
210  dest->dataType = duplicateString(src->dataType);
211  if (dest->prefix)
212  free(dest->prefix);
213  dest->prefix = duplicateString(src->prefix);
214  if (dest->suffix)
215  free(dest->suffix);
216  dest->suffix = duplicateString(src->suffix);
217  if (dest->algorithmName)
218  free(dest->algorithmName);
219  dest->algorithmName = duplicateString(src->algorithmName);
220  if (dest->productName)
221  free(dest->productName);
222  dest->productName = duplicateString(src->productName);
223  dest->cat_ix = src->cat_ix;
224  dest->prod_ix = src->prod_ix;
225  dest->rank = src->rank;
226  dest->fillValue = src->fillValue;
227  dest->validMin = src->validMin;
228  dest->validMax = src->validMax;
229  if (dest->displayScale)
230  free(dest->displayScale);
231  dest->displayScale = duplicateString(src->displayScale);
232  dest->displayMin = src->displayMin;
233  dest->displayMax = src->displayMax;
234  dest->scaleFactor = src->scaleFactor;
235  dest->addOffset = src->addOffset;
236  if (dest->reference)
237  free(dest->reference);
238  dest->reference = duplicateString(src->reference);
239  if (dest->comment)
240  free(dest->comment);
241  dest->comment = duplicateString(src->comment);
242  if (dest->titleFormat)
243  free(dest->titleFormat);
244  dest->titleFormat = duplicateString(src->titleFormat);
245 }
246 
250 void initXmlFile() {
251 
252  // bail if root node is already set
253  if (productInitialized)
254  return;
255  productInitialized = true;
256 
257  char *dataRoot;
258  if ((dataRoot = getenv("OCDATAROOT")) == NULL) {
259  printf("OCDATAROOT environment variable is not defined.\n");
260  exit(1);
261  }
262  strcpy(productXMLFileName, dataRoot);
263  strcat(productXMLFileName, "/common/product.xml");
264 
265  xml_parse_result result = rootNode.load_file(productXMLFileName);
266  if (!result) {
267  printf("%s Line %d: could not open product XML file = %s\n",
268  __FILE__, __LINE__, productXMLFileName);
269  printf(" %s", result.description());
270  exit(1);
271  }
272  productsNode = rootNode.child("products");
273  if (!productsNode) {
274  printf("%s Line %d: could not find products tag in XML file = %s\n",
275  __FILE__, __LINE__, productXMLFileName);
276  exit(1);
277  }
278 
279  productInfo = allocateProductInfo();
280  algorithmInfo = allocateProductInfo();
281 
282 }
283 
288  const char *tmpStr;
289 
290  tmpStr = productNode.name();
291  if (strcmp(tmpStr, "product") != 0) {
292  printf("%s Line %d: \"product\" node expected, found \"%s\" in file %s\n",
293  __FILE__, __LINE__, tmpStr, productXMLFileName);
294  exit(1);
295  }
296 }
297 
302  const char *tmpStr;
303 
304  tmpStr = algorithmNode.name();
305  if (strcmp(tmpStr, "algorithm") != 0) {
306  printf("%s Line %d: \"algorithm\" node expected, found \"%s\" in file %s\n",
307  __FILE__, __LINE__, tmpStr, productXMLFileName);
308  exit(1);
309  }
310 }
311 
315 void readParamDesignator(productInfo_t* info, xml_node node) {
316  char *tmpStr;
317  const char *tmpStr1;
318  xml_node tmpNode;
319 
320  tmpNode = node.child("paramDesignator");
321 
322  // reset the param designator to none if there is one
323  if (tmpNode) {
324  free(info->paramDesignator);
325  info->paramDesignator = strdup(PRODUCT_DEFAULT_paramDesignator);
326  info->paramWaveMin = PRODUCT_DEFAULT_paramWaveMin;
327  info->paramWaveMax = PRODUCT_DEFAULT_paramWaveMax;
328  }
329 
330  while (tmpNode) {
331 
332  // grab the text
333 
334  tmpStr1 = tmpNode.child_value();
335  tmpStr = trimBlanksDup(tmpStr1);
336 
337  if (strcmp(tmpStr, "none") == 0 ||
338  strcmp(tmpStr, "band") == 0 ||
339  strcmp(tmpStr, "int") == 0) {
340  free(info->paramDesignator);
341  info->paramDesignator = tmpStr;
342  info->paramWaveMin = PRODUCT_DEFAULT_paramWaveMin;
343  info->paramWaveMax = PRODUCT_DEFAULT_paramWaveMax;
344  return;
345  } else if (strcmp(tmpStr, "uv") == 0) {
346  if (strcmp(info->paramDesignator, "wave") != 0) {
347  free(info->paramDesignator);
348  info->paramDesignator = strdup("wave");
349  }
350  if (info->paramWaveMin == PRODUCT_DEFAULT_paramWaveMin ||
351  info->paramWaveMin > 100)
352  info->paramWaveMin = 100;
353  if (info->paramWaveMax == PRODUCT_DEFAULT_paramWaveMax ||
354  info->paramWaveMax < 400)
355  info->paramWaveMax = 400;
356  } else if (strcmp(tmpStr, "visible") == 0) {
357  if (strcmp(info->paramDesignator, "wave") != 0) {
358  free(info->paramDesignator);
359  info->paramDesignator = strdup("wave");
360  }
361  if (info->paramWaveMin == PRODUCT_DEFAULT_paramWaveMin ||
362  info->paramWaveMin > 400)
363  info->paramWaveMin = 400;
364  if (info->paramWaveMax == PRODUCT_DEFAULT_paramWaveMax ||
365  info->paramWaveMax < 725)
366  info->paramWaveMax = 725;
367  } else if (strcmp(tmpStr, "nir") == 0) {
368  if (strcmp(info->paramDesignator, "wave") != 0) {
369  free(info->paramDesignator);
370  info->paramDesignator = strdup("wave");
371  }
372  if (info->paramWaveMin == PRODUCT_DEFAULT_paramWaveMin ||
373  info->paramWaveMin > 725)
374  info->paramWaveMin = 725;
375  if (info->paramWaveMax == PRODUCT_DEFAULT_paramWaveMax ||
376  info->paramWaveMax < 1400)
377  info->paramWaveMax = 1400;
378  } else if (strcmp(tmpStr, "swir") == 0) {
379  if (strcmp(info->paramDesignator, "wave") != 0) {
380  free(info->paramDesignator);
381  info->paramDesignator = strdup("wave");
382  }
383  if (info->paramWaveMin == PRODUCT_DEFAULT_paramWaveMin ||
384  info->paramWaveMin > 1400)
385  info->paramWaveMin = 1400;
386  if (info->paramWaveMax == PRODUCT_DEFAULT_paramWaveMax ||
387  info->paramWaveMax < 3000)
388  info->paramWaveMax = 3000;
389  } else if (strcmp(tmpStr, "emissive") == 0) {
390  if (strcmp(info->paramDesignator, "wave") != 0) {
391  free(info->paramDesignator);
392  info->paramDesignator = strdup("wave");
393  }
394  if (info->paramWaveMin == PRODUCT_DEFAULT_paramWaveMin ||
395  info->paramWaveMin > 3000)
396  info->paramWaveMin = 3000;
397  if (info->paramWaveMax == PRODUCT_DEFAULT_paramWaveMax ||
398  info->paramWaveMax < 15000)
399  info->paramWaveMax = 15000;
400  } else {
401  printf("%s Line %d: \"paramDesignator\" node has illegal value \"%s\" in file %s\n",
402  __FILE__, __LINE__, tmpStr, productXMLFileName);
403  exit(1);
404  }
405 
406  free(tmpStr);
407 
408  // grab next node
409  tmpNode = tmpNode.next_sibling("paramDesignator");
410  }
411 }
412 
419 void readSingleRange(productInfo_t* productInfo, xml_node rangeNode) {
420  xml_node node;
421  if ((node = rangeNode.child("validMin")))
422  productInfo->validMin = atof(node.child_value());
423  if ((node = rangeNode.child("validMax")))
424  productInfo->validMax = atof(node.child_value());
425  if ((node = rangeNode.child("displayMin")))
426  productInfo->displayMin = atof(node.child_value());
427  if ((node = rangeNode.child("displayMax")))
428  productInfo->displayMax = atof(node.child_value());
429  if ((node = rangeNode.child("scaleFactor")))
430  productInfo->scaleFactor = atof(node.child_value());
431  if ((node = rangeNode.child("addOffset")))
432  productInfo->addOffset = atof(node.child_value());
433 }
434 
442 void readRange(productInfo_t* productInfo, xml_node productNode, int paramVal) {
443  int min, max;
444  xml_node rangeNode;
445  xml_attribute attr;
446 
447  // set the default
448  rangeNode = productNode.child("range");
449  do {
450 
451  // make sure min and max are not defined
452  if (rangeNode.attribute("min"))
453  continue;
454  if (rangeNode.attribute("max"))
455  continue;
456 
457  readSingleRange(productInfo, rangeNode);
458 
459  } while ((rangeNode = rangeNode.next_sibling("range")));
460 
461  // now search for the matching range
462  rangeNode = productNode.child("range");
463  do {
464  // make sure min and max are defined
465  if ((attr = rangeNode.attribute("min"))) {
466  min = attr.as_int();
467  if ((attr = rangeNode.attribute("max"))) {
468  max = attr.as_int();
469  if (min <= paramVal && paramVal <= max) {
470  readSingleRange(productInfo, rangeNode);
471  break;
472  }
473  }
474  }
475  } while ((rangeNode = rangeNode.next_sibling("range")));
476 
477 }
478 
483 
484  // clear and set productName
485  if (productInfo->productName)
486  free(productInfo->productName);
487  productInfo->productName = trimBlanksDup(productNode.attribute("name").value());
488 
489  // clear and set paramDesignator
490  if (productInfo->paramDesignator)
491  free(productInfo->paramDesignator);
492  productInfo->paramDesignator = duplicateString(PRODUCT_DEFAULT_paramDesignator);
493  readParamDesignator(productInfo, productNode);
494 }
495 
499 void readProduct(int paramVal) {
500  xml_node node;
501 
502  // clear product structure to defaults
503  clearProductInfo(productInfo);
504 
505  if (productInfo->productName)
506  free(productInfo->productName);
507  productInfo->productName = trimBlanksDup(productNode.attribute("name").value());
508 
509  if ((node = productNode.child("standardName"))) {
510  if (productInfo->standardName)
511  free(productInfo->standardName);
512  productInfo->standardName = trimBlanksDup(node.child_value());
513  }
514 
515  node = productNode.child("units");
516  if (!node) {
517  printf("-E- Need to define \"units\" in product \"%s\" in product.xml\n",
518  productInfo->productName);
519  exit(EXIT_FAILURE);
520  }
521  if (productInfo->units)
522  free(productInfo->units);
523  productInfo->units = trimBlanksDup(node.child_value());
524 
525 
526  if ((node = productNode.child("palette"))) {
527  if (productInfo->palette)
528  free(productInfo->palette);
529  productInfo->palette = trimBlanksDup(node.child_value());
530  }
531 
532  node = productNode.child("category");
533  if (!node) {
534  printf("-E- Need to define \"category\" in product \"%s\" in product.xml\n",
535  productInfo->productName);
536  exit(EXIT_FAILURE);
537  }
538  if (productInfo->category)
539  free(productInfo->category);
540  productInfo->category = trimBlanksDup(node.child_value());
541 
542  if ((node = productNode.child("displayScale"))) {
543  if (productInfo->displayScale)
544  free(productInfo->displayScale);
545  productInfo->displayScale = trimBlanksDup(node.child_value());
546  }
547 
548  if ((node = productNode.child("type"))) {
549  if (productInfo->dataType)
550  free(productInfo->dataType);
551  productInfo->dataType = trimBlanksDup(node.child_value());
552  }
553 
554  if ((node = productNode.child("reference"))) {
555  if (productInfo->reference)
556  free(productInfo->reference);
557  productInfo->reference = trimBlanksDup(node.child_value());
558  }
559 
560  if ((node = productNode.child("comment"))) {
561  if (productInfo->comment)
562  free(productInfo->comment);
563  productInfo->comment = trimBlanksDup(node.child_value());
564  }
565 
566  readParamDesignator(productInfo, productNode);
567  if (strcmp(productInfo->paramDesignator, "none") != 0) {
568  productInfo->prod_ix = paramVal;
569  }
570 
571  readRange(productInfo, productNode, paramVal);
572 }
573 
579 
580  xml_attribute attr;
581  xml_node node;
582 
583  // copy header info from the productInfo
584  copyProductInfoHeader(algorithmInfo, productInfo);
585 
586  // clear algorithm header
587  if (algorithmInfo->algorithmName) {
588  free(algorithmInfo->algorithmName);
589  algorithmInfo->algorithmName = NULL;
590  }
591  if (algorithmInfo->prefix) {
592  free(algorithmInfo->prefix);
593  algorithmInfo->prefix = NULL;
594  }
595  if (algorithmInfo->suffix) {
596  free(algorithmInfo->suffix);
597  algorithmInfo->suffix = NULL;
598  }
599 
600  // populate the fields
601  if ((attr = algorithmNode.attribute("name"))) {
602  algorithmInfo->algorithmName = trimBlanksDup(attr.value());
603  } else {
604  algorithmInfo->algorithmName = strdup("");
605  }
606 
607  readParamDesignator(algorithmInfo, algorithmNode);
608 
609  char defaultPrefix[XML_STRING_SIZE];
610  if (strcmp(algorithmInfo->paramDesignator, "none") == 0) {
611  strcpy(defaultPrefix, algorithmInfo->productName);
612  } else {
613  strcpy(defaultPrefix, algorithmInfo->productName);
614  strcat(defaultPrefix, "_");
615  }
616 
617  if ((node = algorithmNode.child("prefix"))) {
618  algorithmInfo->prefix = trimBlanksDup(node.child_value());
619  } else {
620  algorithmInfo->prefix = strdup(defaultPrefix);
621  }
622  if ((node = algorithmNode.child("suffix"))) {
623  algorithmInfo->suffix = trimBlanksDup(node.child_value());
624  } else {
625  if (strlen(algorithmInfo->algorithmName) > 0) {
626  algorithmInfo->suffix = (char*) malloc(strlen(algorithmInfo->algorithmName) + 2);
627  strcpy(algorithmInfo->suffix, "_");
628  strcat(algorithmInfo->suffix, algorithmInfo->algorithmName);
629  } else {
630  algorithmInfo->suffix = strdup("");
631  }
632  }
633 }
634 
638 void readAlgorithm(int paramVal) {
639  char tmpStr[XML_STRING_SIZE];
640  xml_node node;
641 
642  // start with the productInfo as default values
643  copyProductInfo(algorithmInfo, productInfo);
645 
646  algorithmInfo->cat_ix = atoi(algorithmNode.child_value("cat_ix"));
647  if ((node = algorithmNode.child("rank")))
648  algorithmInfo->rank = atoi(node.child_value());
649 
650 
651  if ((node = algorithmNode.child("units"))) {
652  if (algorithmInfo->units)
653  free(algorithmInfo->units);
654  algorithmInfo->units = trimBlanksDup(node.child_value());
655  }
656 
657  if ((node = algorithmNode.child("fillValue")))
658  algorithmInfo->fillValue = atof(node.child_value());
659 
660  node = algorithmNode.child("description");
661  if (!node) {
662  printf("-E- Need to define \"description\" in product \"%s_%s\" in product.xml\n",
663  productInfo->productName, productInfo->algorithmName);
664  exit(EXIT_FAILURE);
665 
666  }
667  strcpy(tmpStr, node.child_value());
668  trimBlanks(tmpStr);
669 
670  if (algorithmInfo->titleFormat)
671  free(algorithmInfo->titleFormat);
672  algorithmInfo->titleFormat = strdup(tmpStr);
673  if (algorithmInfo->description)
674  free(algorithmInfo->description);
675  if (strcmp(algorithmInfo->paramDesignator, "none") == 0) {
676  if ((node = algorithmNode.child("prod_ix")))
677  algorithmInfo->prod_ix = atoi(node.child_value());
678  algorithmInfo->description = trimBlanksDup(tmpStr);
679  } else {
680  algorithmInfo->description = (char*) malloc(strlen(tmpStr) + 64);
681  algorithmInfo->prod_ix = paramVal;
682  sprintf(algorithmInfo->description, tmpStr, algorithmInfo->prod_ix);
683  }
684 
685  if ((node = algorithmNode.child("reference"))) {
686  if (algorithmInfo->reference)
687  free(algorithmInfo->reference);
688  algorithmInfo->reference = trimBlanksDup(node.child_value());
689  }
690 
691  if ((node = algorithmNode.child("comment"))) {
692  if (algorithmInfo->comment)
693  free(algorithmInfo->comment);
694  algorithmInfo->comment = trimBlanksDup(node.child_value());
695  }
696 
697  if ((node = algorithmNode.child("type"))) {
698  if (algorithmInfo->dataType)
699  free(algorithmInfo->dataType);
700  algorithmInfo->dataType = trimBlanksDup(node.child_value());
701  }
702 
703  readRange(algorithmInfo, algorithmNode, paramVal);
704 }
705 
710  productNode = productsNode.child("product");
711  if (!productNode) {
712  printf("%s Line %d: could not find first product tag in XML file = %s\n",
713  __FILE__, __LINE__, productXMLFileName);
714  exit(1);
715  }
718 
719  algorithmNode = productNode.child("algorithm");
720  if (!algorithmNode) {
721  printf("%s Line %d: could not find first algorithm tag for product=%s in XML file = %s\n",
722  __FILE__, __LINE__, productInfo->productName, productXMLFileName);
723  exit(1);
724  }
727 }
728 
735  algorithmNode = algorithmNode.next_sibling("algorithm");
736  if (!algorithmNode) {
737 
738  // try next product
739  productNode = productNode.next_sibling("product");
740  if (!productNode)
741  return 0;
744 
745  algorithmNode = productNode.child("algorithm");
746  if (!algorithmNode) {
747  printf("%s Line %d: could not find first algorithm tag for product=%s in XML file = %s\n",
748  __FILE__, __LINE__, productInfo->productName, productXMLFileName);
749  exit(1);
750  }
751  }
754  return 1;
755 }
756 
765 int compareAlgorithmHeader(const char* productFullName, int sensorId, int* paramVal) {
766 
767  // see if prefix matches
768  if (strncmp(productFullName, algorithmInfo->prefix, strlen(algorithmInfo->prefix)))
769  return 0;
770 
771  char tmpStr[XML_STRING_SIZE];
772  if (strcmp(algorithmInfo->paramDesignator, "none") == 0) {
773  strcpy(tmpStr, algorithmInfo->prefix);
774  strcat(tmpStr, algorithmInfo->suffix);
775  if (strcmp(tmpStr, productFullName) == 0) {
776  *paramVal = PRODUCT_DEFAULT_prod_ix;
777  return 1;
778  } else {
779  return 0;
780  }
781  } else {
782  int nameLen = strlen(productFullName);
783  int prefixLen = strlen(algorithmInfo->prefix);
784  int suffixLen = strlen(algorithmInfo->suffix);
785  int paramLen = nameLen - prefixLen - suffixLen;
786 
787  // need at least one char to be a valid param
788  if (paramLen < 1)
789  return 0;
790 
791  // check the suffix
792  if (strcmp(algorithmInfo->suffix, productFullName + nameLen - suffixLen) != 0)
793  return 0;
794 
795  // get the param value
796  char paramStr[XML_STRING_SIZE];
797  if (paramLen > XML_STRING_SIZE - 1) // just in case
798  paramLen = XML_STRING_SIZE - 1;
799  paramStr[0] = 0;
800  strncat(paramStr, productFullName + prefixLen, paramLen);
801 
802  if (!isValidInt(paramStr))
803  return 0;
804 
805  int i = atoi(paramStr);
806  if (strcmp(algorithmInfo->paramDesignator, "wave") == 0) {
807  if (algorithmInfo->paramWaveMin <= i && i <= algorithmInfo->paramWaveMax) {
808  int32_t numBands;
809  int32_t *iwave;
810  int waveIndex;
811  int old_verbose = want_verbose;
812  want_verbose = 0;
813  numBands = rdsensorinfo(sensorId, 0, "iwave", (void**) &iwave);
814  numBands += rdsensorinfo(sensorId, 0, "NbandsIR", NULL);
815  want_verbose = old_verbose;
816  if (numBands != -1) {
817  for (waveIndex = 0; waveIndex < numBands; waveIndex++) {
818  if (i == iwave[waveIndex]) {
819  *paramVal = i;
820  return 1;
821  }
822  }
823  }
824 
825  }
826  } else {
827  *paramVal = i;
828  return 1;
829  }
830  }
831  return 0;
832 }
833 
839 extern "C" void getFirstProductInfo(productInfo_t* info) {
840  initXmlFile();
842  readProduct(-1);
843  readAlgorithm(-1);
844  copyProductInfo(info, algorithmInfo);
845 }
846 
853 extern "C" int getNextProductInfo(productInfo_t* info) {
854  if (findNextAlgorithmHeader()) {
855  readProduct(-1);
856  readAlgorithm(-1);
857  copyProductInfo(info, algorithmInfo);
858  return 1;
859  }
860  return 0;
861 }
862 
871 extern "C" int findProductInfo(const char* productName, int sensorId, productInfo_t* info) {
872  int paramVal;
873  const char* tmpProductName = productName;
874 
875 
876  if (strcmp(productName, "chl_ocx") == 0) {
877  switch (sensorId) {
878  case OCTS:
879  case SEAWIFS:
880  case OCM1:
881  case OCM2:
882  case MOS:
883  case MERIS:
884  case HICO:
885  case OCIA:
886  case OCI:
887  case HAWKEYE:
888  case AVIRIS:
889  case PRISM:
890  case OLCIS3A:
891  case OLCIS3B:
892  tmpProductName = "chl_oc4";
893  break;
894  case MODIST:
895  case MODISA:
896  case CZCS:
897  case OSMI:
898  case VIIRSN:
899  case VIIRSJ1:
900  case OCRVC:
901  case GOCI:
902  case SGLI:
903  case OLI:
904  tmpProductName = "chl_oc3";
905  break;
906  case L5TM:
907  case L7ETMP:
908  case MISR:
909  tmpProductName = "chl_oc2";
910  break;
911  default:
912  printf("%s Line %d: need a default chlorophyll algorithm for this sensor\n",
913  __FILE__, __LINE__);
914  exit(1);
915  break;
916 
917  }
918  }
919 
920  initXmlFile();
922  do {
923  if (compareAlgorithmHeader(tmpProductName, sensorId, &paramVal)) {
924  readProduct(paramVal);
925  readAlgorithm(paramVal);
926  copyProductInfo(info, algorithmInfo);
927  if (strcmp(productName, "chl_ocx") == 0) {
928  free(info->suffix);
929  info->suffix = strdup("_ocx");
930  }
931  return 1;
932  }
933  } while (findNextAlgorithmHeader());
934 
935  return 0;
936 }
937 
943 extern "C" char* getProductNameFull(productInfo_t* info) {
944  static char name[XML_STRING_SIZE];
945 
946  if (strcmp(info->paramDesignator, "none") == 0) {
947  strcpy(name, info->prefix);
948  strcat(name, info->suffix);
949  } else {
950  sprintf(name, "%s%d%s", info->prefix, info->prod_ix, info->suffix);
951  }
952  return name;
953 }
954 
961 extern "C" void printProductInfo(const char* productFullName, const productInfo_t* info) {
962  printf("fullProductName=%s\n", productFullName);
963  printf("description=%s\n", info->description);
964  printf("units=%s\n", info->units);
965  printf("palette=%s\n", info->palette);
966  printf("paramDesignator=%s\n", info->paramDesignator);
967  printf("paramWaveMin=%d\n", info->paramWaveMin);
968  printf("paramWaveMax=%d\n", info->paramWaveMax);
969  printf("standardName=%s\n", info->standardName);
970  printf("category=%s\n", info->category);
971  printf("dataType=%s\n", info->dataType);
972  printf("prefix=%s\n", info->prefix);
973  printf("suffix=%s\n", info->suffix);
974  printf("algorithmName=%s\n", info->algorithmName);
975  printf("productName=%s\n", info->productName);
976  printf("cat_ix=%d\n", info->cat_ix);
977  printf("prod_ix=%d\n", info->prod_ix);
978  printf("rank=%d\n", info->rank);
979  printf("fillValue=%g\n", info->fillValue);
980  printf("validMin=%g\n", info->validMin);
981  printf("validMax=%g\n", info->validMax);
982  printf("displayScale=%s\n", info->displayScale);
983  printf("displayMin=%g\n", info->displayMin);
984  printf("displayMax=%g\n", info->displayMax);
985  printf("scaleFactor=%g\n", info->scaleFactor);
986  printf("addOffset=%g\n", info->addOffset);
987  printf("reference=%s\n", info->reference);
988  printf("comment=%s\n", info->comment);
989  printf("titleFormat=%s\n", info->titleFormat);
990 }
#define OLCIS3A
Definition: sensorDefs.h:32
void trimBlanks(char *str)
Definition: trimBlanks.c:10
void checkAlgorithmNode()
void freeProductInfo(productInfo_t *info)
#define PRODUCT_DEFAULT_standardName
Definition: productInfo.h:18
#define SGLI
Definition: sensorDefs.h:33
void readParamDesignator(productInfo_t *info, xml_node node)
#define OCI
Definition: sensorDefs.h:42
These are used to scale the SD before writing it to the HDF4 file The default is and which means the product is not scaled at all Since the product is usually stored as a float inside of this is a way to write the float out as a integer l2prod min
void initProductInfo(productInfo_t *info)
void getFirstProductInfo(productInfo_t *info)
#define PRODUCT_DEFAULT_validMax
Definition: productInfo.h:30
#define PRODUCT_DEFAULT_addOffset
Definition: productInfo.h:35
#define PRODUCT_DEFAULT_paramWaveMin
Definition: productInfo.h:16
void * allocateMemory(size_t numBytes, const char *name)
Definition: allocateMemory.c:7
void printProductInfo(const char *productFullName, const productInfo_t *info)
#define OSMI
Definition: sensorDefs.h:16
#define NULL
Definition: decode_rs.h:63
#define PRODUCT_DEFAULT_suffix
Definition: productInfo.h:22
#define PRODUCT_DEFAULT_prod_ix
Definition: productInfo.h:26
#define VIIRSN
Definition: sensorDefs.h:23
#define L5TM
Definition: sensorDefs.h:35
#define PRODUCT_DEFAULT_algorithmName
Definition: productInfo.h:23
int isValidInt(const char *str)
Definition: isValidInt.c:9
#define MERIS
Definition: sensorDefs.h:22
#define PRODUCT_DEFAULT_category
Definition: productInfo.h:19
#define PRODUCT_DEFAULT_comment
Definition: productInfo.h:37
#define MODIST
Definition: sensorDefs.h:18
#define PRODUCT_DEFAULT_scaleFactor
Definition: productInfo.h:34
#define PRODUCT_DEFAULT_description
Definition: productInfo.h:12
#define OCIA
Definition: sensorDefs.h:29
void bzero()
void clearProductInfo(productInfo_t *info)
Definition: productInfo.cpp:42
#define PRODUCT_DEFAULT_fillValue
Definition: productInfo.h:28
#define PRODUCT_DEFAULT_paramDesignator
Definition: productInfo.h:15
void readRange(productInfo_t *productInfo, xml_node productNode, int paramVal)
void readSingleRange(productInfo_t *productInfo, xml_node rangeNode)
#define XML_STRING_SIZE
Definition: productInfo.cpp:10
int findNextAlgorithmHeader()
#define PRODUCT_DEFAULT_reference
Definition: productInfo.h:36
productInfo_t * allocateProductInfo()
char * strdup(const char *)
int32_t rdsensorinfo(int32_t sensorID, int32_t evalmask, const char *pname, void **pval)
Definition: rdsensorinfo.c:69
#define PRODUCT_DEFAULT_palette
Definition: productInfo.h:14
#define PRODUCT_DEFAULT_paramWaveMax
Definition: productInfo.h:17
#define PRODUCT_DEFAULT_displayMin
Definition: productInfo.h:32
#define PRODUCT_DEFAULT_units
Definition: productInfo.h:13
#define HAWKEYE
Definition: sensorDefs.h:39
#define PRODUCT_DEFAULT_displayMax
Definition: productInfo.h:33
#define PRODUCT_DEFAULT_titleFormat
Definition: productInfo.h:38
void readAlgorithm(int paramVal)
#define PRODUCT_DEFAULT_prefix
Definition: productInfo.h:21
#define PRODUCT_DEFAULT_rank
Definition: productInfo.h:27
#define PRISM
Definition: sensorDefs.h:31
int want_verbose
#define PRODUCT_DEFAULT_dataType
Definition: productInfo.h:20
void initXmlFile()
#define AVIRIS
Definition: sensorDefs.h:30
void readAlgorithmHeader()
void readProductHeader()
#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
#define OCTS
Definition: sensorDefs.h:14
char * getProductNameFull(productInfo_t *info)
#define OCM1
Definition: sensorDefs.h:20
void checkProductNode()
#define PRODUCT_DEFAULT_displayScale
Definition: productInfo.h:31
char * name
Definition: Granule.c:1234
void copyProductInfo(productInfo_t *dest, const productInfo_t *src)
#define PRODUCT_DEFAULT_validMin
Definition: productInfo.h:29
#define CZCS
Definition: sensorDefs.h:17
char * trimBlanksDup(const char *str)
Definition: trimBlanks.c:58
void findFirstAlgorithmHeader()
#define OLCIS3B
Definition: sensorDefs.h:41
void readProduct(int paramVal)
#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
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define MODISA
Definition: sensorDefs.h:19
#define PRODUCT_DEFAULT_productName
Definition: productInfo.h:24
#define VIIRSJ1
Definition: sensorDefs.h:37
#define PRODUCT_DEFAULT_cat_ix
Definition: productInfo.h:25
void copyProductInfoHeader(productInfo_t *dest, const productInfo_t *src)
@ OLI
Definition: smeta.h:53
#define OCM2
Definition: sensorDefs.h:21
int getNextProductInfo(productInfo_t *info)
int compareAlgorithmHeader(const char *productFullName, int sensorId, int *paramVal)
l2prod max
#define GOCI
Definition: sensorDefs.h:26