OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
cdl_utils.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <string.h>
5 #include <libgen.h>
6 
7 #include <sstream>
8 #include <iomanip>
9 #include "nc4utils.h"
10 #include "cdl_utils.h"
11 #include "netcdf.h"
12 #include "timeutils.h"
13 
15  ncid = -1;
16 }
17 
19 
20 }
21 
22 /*----------------------------------------------------------------- */
23 /* Create a netcdf4 level1 file from cdl file */
24 
25 /* ---------------------------------------------------------------- */
26 int ncdfFile::cdlCreate(char* l1_filename, char* cdl_filename,
27  int32_t numScans) {
28 
29  int status, i;
30  // idDS ds_id;
31  status = nc_create(l1_filename, NC_NETCDF4, &ncid);
32  check_err(status, __LINE__, __FILE__);
33 
34  ifstream cdl_data_structure;
35  string line;
36  string dataStructureFile(cdl_filename);
37 
38  expandEnvVar(&dataStructureFile);
39 
40  cdl_data_structure.open(dataStructureFile.c_str(), ifstream::in);
41  if (cdl_data_structure.fail() == true) {
42  cout << "\"" << dataStructureFile.c_str() << "\" not found" << endl;
43  exit(1);
44  }
45 
46  // Find "dimensions" section of CDL file
47  while (1) {
48  getline(cdl_data_structure, line);
49 
50  size_t firstNonBlank = line.find_first_not_of(" ");
51  if (firstNonBlank != string::npos)
52  if (line.compare(firstNonBlank, 2, "//") == 0) continue;
53 
54  size_t pos = line.find("dimensions:");
55  if (pos == 0) break;
56  }
57 
58  // Define dimensions from "dimensions" section of CDL file
59  ndims = 0;
60  while (1) {
61  getline(cdl_data_structure, line);
62 
63  size_t firstNonBlank = line.find_first_not_of(" ");
64  if (firstNonBlank != string::npos)
65  if (line.compare(firstNonBlank, 2, "//") == 0) continue;
66 
67  size_t pos = line.find(" = ");
68  if (pos == string::npos) break;
69 
70  uint32_t dimSize;
71  istringstream iss(line.substr(pos + 2, string::npos));
72  iss >> dimSize;
73 
74  iss.clear();
75  iss.str(line);
76  iss >> skipws >> line;
77 
78  cout << "Dimension Name: " << line.c_str() << " Dimension Size: "
79  << dimSize << endl;
80 
81  status = nc_def_dim(ncid, line.c_str(), dimSize, &dimid[ndims++]);
82  check_err(status, __LINE__, __FILE__);
83  } // while loop
84 
85  ngrps = 0;
86  // Loop through groups
87  while (1) {
88  getline(cdl_data_structure, line);
89 
90  size_t firstNonBlank = line.find_first_not_of(" ");
91  if (firstNonBlank != string::npos)
92  if (line.compare(firstNonBlank, 2, "//") == 0) continue;
93 
94  // Check if end of CDL file
95  // If so then close CDL file and return
96  if (line.substr(0, 1).compare("}") == 0) {
97  cdl_data_structure.close();
98  return 0;
99  }
100 
101  // Check for beginning of new group
102  size_t pos = line.find("group:");
103 
104  // If found then create new group and variables
105  if (pos == 0) {
106 
107  // Parse group name
108  istringstream iss(line.substr(6, string::npos));
109  iss >> skipws >> line;
110  cout << "Group: " << line.c_str() << endl;
111 
112  // Create NCDF4 group
113  status = nc_def_grp(ncid, line.c_str(), &this->gid[ngrps]);
114  check_err(status, __LINE__, __FILE__);
115 
116  ngrps++;
117 
118  int numDims = 0;
119  int varDims[NC_MAX_DIMS];
120  size_t dimSize[NC_MAX_DIMS];
121  char dimName[NC_MAX_NAME + 1];
122  string sname;
123  string lname;
124  string standard_name;
125  string units;
126  string flag_values;
127  string flag_meanings;
128  double valid_min = 0.0;
129  double valid_max = 0.0;
130  double fill_value = 0.0;
131  size_t *chunksize;
132 
133  int ntype = 0;
134 
135  // Loop through datasets in group
136  // Skip until "variables:" found
137  while (1) {
138  getline(cdl_data_structure, line);
139  if (line.find("variables:") != string::npos) break;
140  }
141 
142  while (1) {
143  getline(cdl_data_structure, line);
144 
145  if (line.length() == 0) continue;
146  if (line.substr(0, 1).compare("\r") == 0) continue;
147  if (line.substr(0, 1).compare("\n") == 0) continue;
148 
149  size_t firstNonBlank = line.find_first_not_of(" ");
150  if (firstNonBlank != string::npos)
151  if (line.compare(firstNonBlank, 2, "//") == 0) continue;
152 
153  size_t pos = line.find(":");
154 
155  // No ":" found, new dataset or empty line or end-of-group
156  if (pos == string::npos) {
157 
158  if (numDims > 0) {
159  // Create previous dataset
160  createNCDF(gid[ngrps - 1],
161  sname.c_str(), lname.c_str(),
162  standard_name.c_str(), units.c_str(),
163  (void *) &fill_value,
164  flag_values.c_str(), flag_meanings.c_str(),
165  valid_min, valid_max, ntype, numDims, varDims, chunksize);
166 
167  flag_values.assign("");
168  flag_meanings.assign("");
169  free(chunksize);
170  }
171 
172  valid_min = 0.0;
173  valid_max = 0.0;
174  fill_value = 0.0;
175 
176  if (line.substr(0, 10).compare("} // group") == 0) break;
177 
178  // Parse variable type
179  string varType;
180  istringstream iss(line);
181  iss >> skipws >> varType;
182 
183  // Get corresponding NC variable type
184  if (varType.compare("char") == 0) ntype = NC_CHAR;
185  else if (varType.compare("byte") == 0) ntype = NC_BYTE;
186  else if (varType.compare("short") == 0) ntype = NC_SHORT;
187  else if (varType.compare("int") == 0) ntype = NC_INT;
188  else if (varType.compare("long") == 0) ntype = NC_INT;
189  else if (varType.compare("float") == 0) ntype = NC_FLOAT;
190  else if (varType.compare("real") == 0) ntype = NC_FLOAT;
191  else if (varType.compare("double") == 0) ntype = NC_DOUBLE;
192  else if (varType.compare("ubyte") == 0) ntype = NC_UBYTE;
193  else if (varType.compare("ushort") == 0) ntype = NC_USHORT;
194  else if (varType.compare("uint") == 0) ntype = NC_UINT;
195  else if (varType.compare("int64") == 0) ntype = NC_INT64;
196  else if (varType.compare("uint64") == 0) ntype = NC_UINT64;
197 
198  // Parse short name (sname)
199  pos = line.find("(");
200  size_t posSname = line.substr(0, pos).rfind(" ");
201  sname.assign(line.substr(posSname + 1, pos - posSname - 1));
202  cout << "sname: " << sname.c_str() << endl;
203 
204  // Parse variable dimension info
205  this->parseDims(line.substr(pos + 1, string::npos),
206  &numDims, varDims);
207  for (int i = 0; i < numDims; i++) {
208  nc_inq_dim(ncid, varDims[i], dimName, &dimSize[i]);
209  cout << line.c_str() << " " << i << " " << dimName
210  << " " << dimSize[i] << endl;
211  }
212 
213  chunksize = (size_t *) calloc(numDims, sizeof (size_t));
214 
215  } else {
216  // Parse variable attributes
217  size_t posEql = line.find("=");
218  size_t pos1qte = line.find("\"");
219  size_t pos2qte = line.substr(pos1qte + 1, string::npos).find("\"");
220  // cout << line.substr(pos+1, posEql-pos-2).c_str() << endl;
221 
222  string attrName = line.substr(pos + 1, posEql - pos - 2);
223 
224  // Get long_name
225  if (attrName.compare("long_name") == 0) {
226  lname.assign(line.substr(pos1qte + 1, pos2qte));
227  // cout << "lname: " << lname.c_str() << endl;
228  }
229  // Get units
230  else if (attrName.compare("units") == 0) {
231  units.assign(line.substr(pos1qte + 1, pos2qte));
232  // cout << "units: " << units.c_str() << endl;
233  }
234  // Get _FillValue
235  else if (attrName.compare("_FillValue") == 0) {
236  iss.clear();
237  iss.str(line.substr(posEql + 1, string::npos));
238  iss >> fill_value;
239  // cout << "_FillValue: " << fill_value << endl;
240  }
241  // Get flag_values
242  else if (attrName.compare("flag_values") == 0) {
243  flag_values.assign(line.substr(pos1qte + 1, pos2qte));
244  }
245  // Get flag_meanings
246  else if (attrName.compare("flag_meanings") == 0) {
247  flag_meanings.assign(line.substr(pos1qte + 1, pos2qte));
248  }
249  // Get valid_min
250  else if (attrName.compare("valid_min") == 0) {
251  iss.clear();
252  iss.str(line.substr(posEql + 1, string::npos));
253  iss >> valid_min;
254  // cout << "valid_min: " << valid_min << endl;
255  }
256  // Get valid_max
257  else if (attrName.compare("valid_max") == 0) {
258  iss.clear();
259  iss.str(line.substr(posEql + 1, string::npos));
260  iss >> valid_max;
261  // cout << "valid_max: " << valid_max << endl;
262  } // Get Chunk sizes
263  else if (attrName.compare("_ChunkSizes") == 0) {
264  size_t posComma = line.find(",");
265  status = posEql + 1;
266 
267  for (i = 0; i < numDims; i++) {
268  iss.clear();
269  if (i == numDims - 1) {
270  iss.str(line.substr(status, string::npos));
271  } else {
272  iss.str(line.substr(status, posComma));
273  status = posComma + 1;
274  posComma += line.substr(posComma + 1, string::npos).find(",") + 1;
275  }
276  iss >> chunksize[i];
277  }
278  // cout << "_FillValue: " << fill_value << endl;
279  }
280 
281  } // if ( pos == string::npos)
282  } // datasets in group loop
283  } // New Group loop
284  } // Main Group loop
285 
286 
287  return 0;
288 }
289 
290 /*----------------------------------------------------------------- */
291 /* Create an Generic NETCDF4 level1 file */
292 
293 /* ---------------------------------------------------------------- */
294 int ncdfFile::cdlCreateDim(char* l1_filename, char* cdl_filename, const char** dim_names, size_t* dim_size, size_t n_dims,
295  size_t numScans) {
296 
297  // Let user define the dimensions and sizes
298  int status, i;
299  // idDS ds_id;
300  status = nc_create(l1_filename, NC_NETCDF4, &ncid);
301  check_err(status, __LINE__, __FILE__);
302 
303  ifstream cdl_data_structure;
304  string line;
305  string dataStructureFile(cdl_filename);
306 
307  expandEnvVar(&dataStructureFile);
308 
309  cdl_data_structure.open(dataStructureFile.c_str(), ifstream::in);
310  if (cdl_data_structure.fail() == true) {
311  cout << "\"" << dataStructureFile.c_str() << "\" not found" << endl;
312  exit(1);
313  }
314 
315 
316  // Define dimensions from "dimensions" section of CDL file
317  ndims = 0;
318 
319  for (size_t i = 0; i < n_dims; i++) {
320 
321  cout << "Dimension Name: " << dim_names[i] << " Dimension Size: "
322  << dim_size[i] << endl;
323 
324  status = nc_def_dim(ncid, dim_names[i], dim_size[i], &dimid[ndims++]);
325  check_err(status, __LINE__, __FILE__);
326  } // for loop
327 
328  // Find "dimensions" section of CDL file
329  while (1) {
330  getline(cdl_data_structure, line);
331 
332  size_t firstNonBlank = line.find_first_not_of(" ");
333  if (firstNonBlank != string::npos)
334  if (line.compare(firstNonBlank, 2, "//") == 0) continue;
335 
336  size_t pos = line.find("dimensions:");
337  if (pos == 0) break;
338  }
339 
340  // Then skip over the dimensions section
341  while (1) {
342  getline(cdl_data_structure, line);
343 
344  size_t firstNonBlank = line.find_first_not_of(" ");
345  if (firstNonBlank != string::npos)
346  if (line.compare(firstNonBlank, 2, "//") == 0) continue;
347 
348  size_t pos = line.find(" = ");
349  if (pos == string::npos) break;
350 
351  uint32_t dimSize;
352  istringstream iss(line.substr(pos + 2, string::npos));
353  iss >> dimSize;
354 
355  iss.clear();
356  iss.str(line);
357  iss >> skipws >> line;
358 
359  // cout << "Dimension Name: " << line.c_str() << " Dimension Size: "
360  // << dimSize << endl;
361 
362  } // while loop
363 
364  // Loop through global attributes
365  string attVal;
366  char history[256];
367 
368  while (1) {
369  getline(cdl_data_structure, line);
370  size_t pos = line.find("group:");
371  // If found then break from loop and process groups and variables
372  if (pos == 0) {
373  break;
374  }
375 
376  if (line.length() == 0) continue;
377  if (line.substr(0, 1).compare("\r") == 0) continue;
378  if (line.substr(0, 1).compare("\n") == 0) continue;
379 
380  size_t firstNonBlank = line.find_first_not_of(" ");
381  if (firstNonBlank != string::npos)
382  if (line.compare(firstNonBlank, 2, "//") == 0) continue;
383 
384  pos = line.find(":");
385 
386  // ":" found, new global attribute to create
387  if (pos != string::npos) {
388  size_t posEql = line.find("=");
389  size_t pos1qte = line.find("\"");
390  size_t pos2qte = line.substr(pos1qte + 1, string::npos).find("\"");
391  cout << line.substr(pos + 1, posEql - pos - 2).c_str() << endl;
392 
393  string attrName = line.substr(pos + 1, posEql - pos - 2);
394  // Get long_name
395  attVal.assign(line.substr(pos1qte + 1, pos2qte));
396  if (attrName.compare("product_name") == 0) {
397  // cout << "lname: " << lname.c_str() << endl;
398  status = nc_put_att_text(ncid, NC_GLOBAL, attrName.c_str(), strlen(l1_filename) + 1, l1_filename);
399  if (status != NC_NOERR) {
400  printf("-E- %s %d: %s for %s\n",
401  __FILE__, __LINE__, nc_strerror(status), attrName.c_str());
402  exit(1);
403  }
404  } else if (attrName.compare("date_created") == 0) {
405  status = nc_put_att_text(ncid, NC_GLOBAL, attrName.c_str(), strlen(ydhmsf(now(), 'G')) + 1, ydhmsf(now(), 'G'));
406  if (status != NC_NOERR) {
407  printf("-E- %s %d: %s for %s\n",
408  __FILE__, __LINE__, nc_strerror(status), attrName.c_str());
409  exit(1);
410  }
411  } else if (attrName.compare("history") == 0) {
412  sprintf(history, "Generated by avirisbil2oci; cdlfile=%s", cdl_filename);
413  status = nc_put_att_text(ncid, NC_GLOBAL, attrName.c_str(), strlen(history) + 1, history);
414  if (status != NC_NOERR) {
415  printf("-E- %s %d: %s for %s\n",
416  __FILE__, __LINE__, nc_strerror(status), attrName.c_str());
417  exit(1);
418  }
419  } else if (attrName.compare("orbit_number") == 0) {
420  int32_t vr[1];
421  vr[0] = 0;
422  status = nc_put_att_int(ncid, NC_GLOBAL, attrName.c_str(), NC_INT, 1, &vr[0]);
423  if (status != NC_NOERR) {
424  printf("-E- %s %d: %s for %s\n",
425  __FILE__, __LINE__, nc_strerror(status), attrName.c_str());
426  exit(1);
427  }
428  } else if (attrName.compare("license") == 0) {
429  printf("length of name=%ld\n", attrName.length());
430  status = nc_put_att_text(ncid, NC_GLOBAL, "license",
431  strlen(line.substr(pos1qte + 1, pos2qte).c_str()) + 1,
432  line.substr(pos1qte + 1, pos2qte).c_str());
433  if (status != NC_NOERR) {
434  printf("-E- %s %d: %s for %s\n",
435  __FILE__, __LINE__, nc_strerror(status), history);
436  exit(1);
437  }
438  } else if (attrName.compare("creator_name") == 0) {
439  printf("length of name=%ld\n", attrName.length());
440  status = nc_put_att_text(ncid, NC_GLOBAL, "creator_name",
441  strlen(attVal.c_str()) + 1,
442  attVal.c_str());
443  if (status != NC_NOERR) {
444  printf("-E- %s %d: %s for %s\n",
445  __FILE__, __LINE__, nc_strerror(status), history);
446  exit(1);
447  }
448 
449  } else if (attrName.compare("creator_url") == 0) {
450  printf("length of name=%ld\n", attrName.length());
451  status = nc_put_att_text(ncid, NC_GLOBAL, "creator_url",
452  strlen(attVal.c_str()) + 1,
453  attVal.c_str());
454  if (status != NC_NOERR) {
455  printf("-E- %s %d: %s for %s\n",
456  __FILE__, __LINE__, nc_strerror(status), history);
457  exit(1);
458  }
459  } else if (attrName.compare("publisher_name") == 0) {
460  printf("length of name=%ld\n", attrName.length());
461  status = nc_put_att_text(ncid, NC_GLOBAL, "publisher_name",
462  strlen(attVal.c_str()) + 1,
463  attVal.c_str());
464  if (status != NC_NOERR) {
465  printf("-E- %s %d: %s for %s\n",
466  __FILE__, __LINE__, nc_strerror(status), history);
467  exit(1);
468  }
469 
470  } else if (attrName.compare("publisher_url") == 0) {
471  printf("length of name=%ld\n", attrName.length());
472  status = nc_put_att_text(ncid, NC_GLOBAL, "publisher_url",
473  strlen(attVal.c_str()) + 1,
474  attVal.c_str());
475  if (status != NC_NOERR) {
476  printf("-E- %s %d: %s for %s\n",
477  __FILE__, __LINE__, nc_strerror(status), history);
478  exit(1);
479  }
480 
481 
482 
483  } else {
484  printf("value = %s\n", line.substr(pos1qte + 1, pos2qte).c_str());
485  status = nc_put_att_text(ncid, NC_GLOBAL, attrName.c_str(),
486  strlen(attVal.c_str()) + 1,
487  attVal.c_str());
488  if (status != NC_NOERR) {
489  printf("-E- %s %d: %s for %s\n",
490  __FILE__, __LINE__, nc_strerror(status), attrName.c_str());
491  exit(1);
492  }
493 
494  }
495  }
496  }
497  ngrps = 0;
498  // Loop through groups
499  while (1) {
500 
501  size_t firstNonBlank = line.find_first_not_of(" ");
502  if (firstNonBlank != string::npos)
503  if (line.compare(firstNonBlank, 2, "//") == 0) {
504  getline(cdl_data_structure, line);
505  continue;
506  }
507  // Check if end of CDL file
508  // If so then close CDL file and return
509  if (line.substr(0, 1).compare("}") == 0) {
510  cdl_data_structure.close();
511  return 0;
512  }
513 
514  // Check for beginning of new group
515  size_t pos = line.find("group:");
516 
517  // If found then create new group and variables
518  if (pos == 0) {
519 
520  // Parse group name
521  istringstream iss(line.substr(6, string::npos));
522  iss >> skipws >> line;
523  cout << "Group: " << line.c_str() << endl;
524 
525  // Create NCDF4 group
526  status = nc_def_grp(ncid, line.c_str(), &this->gid[ngrps]);
527  check_err(status, __LINE__, __FILE__);
528 
529  ngrps++;
530 
531  int numDims = 0;
532  int varDims[NC_MAX_DIMS];
533  size_t dimSize[NC_MAX_DIMS];
534  char dimName[NC_MAX_NAME + 1];
535  string sname;
536  string lname;
537  string standard_name;
538  string units;
539  string flag_values;
540  string flag_meanings;
541  double valid_min = 0.0;
542  double valid_max = 0.0;
543  double fill_value = 0.0;
544  size_t *chunksize;
545 
546  int ntype = 0;
547 
548  // Loop through datasets in group
549  // Skip until "variables:" found
550  while (1) {
551  getline(cdl_data_structure, line);
552  if (line.find("variables:") != string::npos) break;
553  }
554 
555  while (1) {
556  getline(cdl_data_structure, line);
557 
558  if (line.length() == 0) continue;
559  if (line.substr(0, 1).compare("\r") == 0) continue;
560  if (line.substr(0, 1).compare("\n") == 0) continue;
561 
562  size_t firstNonBlank = line.find_first_not_of(" ");
563  if (firstNonBlank != string::npos)
564  if (line.compare(firstNonBlank, 2, "//") == 0) continue;
565 
566  size_t pos = line.find(":");
567 
568  // No ":" found, new dataset or empty line or end-of-group
569  if (pos == string::npos) {
570 
571  if (numDims > 0) {
572  // Create previous dataset
573  createNCDF(gid[ngrps - 1],
574  sname.c_str(), lname.c_str(),
575  standard_name.c_str(), units.c_str(),
576  (void *) &fill_value,
577  flag_values.c_str(), flag_meanings.c_str(),
578  valid_min, valid_max, ntype, numDims, varDims, chunksize);
579 
580  flag_values.assign("");
581  flag_meanings.assign("");
582  free(chunksize);
583  }
584 
585  valid_min = 0.0;
586  valid_max = 0.0;
587  fill_value = 0.0;
588 
589  if (line.substr(0, 10).compare("} // group") == 0) break;
590 
591  // Parse variable type
592  string varType;
593  istringstream iss(line);
594  iss >> skipws >> varType;
595 
596  // Get corresponding NC variable type
597  if (varType.compare("char") == 0) ntype = NC_CHAR;
598  else if (varType.compare("byte") == 0) ntype = NC_BYTE;
599  else if (varType.compare("short") == 0) ntype = NC_SHORT;
600  else if (varType.compare("int") == 0) ntype = NC_INT;
601  else if (varType.compare("long") == 0) ntype = NC_INT;
602  else if (varType.compare("float") == 0) ntype = NC_FLOAT;
603  else if (varType.compare("real") == 0) ntype = NC_FLOAT;
604  else if (varType.compare("double") == 0) ntype = NC_DOUBLE;
605  else if (varType.compare("ubyte") == 0) ntype = NC_UBYTE;
606  else if (varType.compare("ushort") == 0) ntype = NC_USHORT;
607  else if (varType.compare("uint") == 0) ntype = NC_UINT;
608  else if (varType.compare("int64") == 0) ntype = NC_INT64;
609  else if (varType.compare("uint64") == 0) ntype = NC_UINT64;
610 
611  // Parse short name (sname)
612  pos = line.find("(");
613  size_t posSname = line.substr(0, pos).rfind(" ");
614  sname.assign(line.substr(posSname + 1, pos - posSname - 1));
615  cout << "sname: " << sname.c_str() << endl;
616 
617  // Parse variable dimension info
618  this->parseDims(line.substr(pos + 1, string::npos),
619  &numDims, varDims);
620  for (int i = 0; i < numDims; i++) {
621  nc_inq_dim(ncid, varDims[i], dimName, &dimSize[i]);
622  cout << line.c_str() << " " << i << " " << dimName
623  << " " << dimSize[i] << endl;
624  }
625  chunksize = (size_t *) calloc(numDims, sizeof (size_t));
626 
627  } else {
628  // Parse variable attributes
629  size_t posEql = line.find("=");
630  size_t pos1qte = line.find("\"");
631  size_t pos2qte = line.substr(pos1qte + 1, string::npos).find("\"");
632  // cout << line.substr(pos+1, posEql-pos-2).c_str() << endl;
633 
634  string attrName = line.substr(pos + 1, posEql - pos - 2);
635 
636  // Get long_name
637  if (attrName.compare("long_name") == 0) {
638  lname.assign(line.substr(pos1qte + 1, pos2qte));
639  // cout << "lname: " << lname.c_str() << endl;
640  }
641  // Get units
642  else if (attrName.compare("units") == 0) {
643  units.assign(line.substr(pos1qte + 1, pos2qte));
644  // cout << "units: " << units.c_str() << endl;
645  }
646  // Get _FillValue
647  else if (attrName.compare("_FillValue") == 0) {
648  iss.clear();
649  iss.str(line.substr(posEql + 1, string::npos));
650  iss >> fill_value;
651  // cout << "_FillValue: " << fill_value << endl;
652  }
653  // Get flag_values
654  else if (attrName.compare("flag_values") == 0) {
655  flag_values.assign(line.substr(pos1qte + 1, pos2qte));
656  }
657  // Get flag_meanings
658  else if (attrName.compare("flag_meanings") == 0) {
659  flag_meanings.assign(line.substr(pos1qte + 1, pos2qte));
660  }
661  // Get valid_min
662  else if (attrName.compare("valid_min") == 0) {
663  iss.clear();
664  iss.str(line.substr(posEql + 1, string::npos));
665  iss >> valid_min;
666  // cout << "valid_min: " << valid_min << endl;
667  }
668  // Get valid_max
669  else if (attrName.compare("valid_max") == 0) {
670  iss.clear();
671  iss.str(line.substr(posEql + 1, string::npos));
672  iss >> valid_max;
673  // cout << "valid_max: " << valid_max << endl;
674  } // Get Chunk sizes
675  else if (attrName.compare("_ChunkSizes") == 0) {
676  size_t posComma = line.find(",");
677  status = posEql + 1;
678 
679  for (i = 0; i < numDims; i++) {
680  iss.clear();
681  if (i == numDims - 1) {
682  // printf("iss=%s\n",line.substr(status, string::npos).c_str());
683  iss.str(line.substr(status, string::npos));
684  } else {
685  iss.str(line.substr(status, posComma));
686  // printf("iss=%s\n",line.substr(status, posComma).c_str());
687  status = posComma + 1;
688  posComma += line.substr(posComma + 1, string::npos).find(",") + 1;
689  }
690  iss >> chunksize[i];
691  }
692  // cout << "_FillValue: " << fill_value << endl;
693  }
694 
695  } // if ( pos == string::npos)
696  } // datasets in group loop
697  } // New Group loop
698  getline(cdl_data_structure, line);
699  } // Main Group loop
700 
701 
702  return 0;
703 }
704 
705 int ncdfFile::parseDims(string dimString, int *numDims, int *varDims) {
706 
707  size_t dimSize, curPos = 0;
708  char dimName[NC_MAX_NAME + 1];
709 
710  *numDims = 0;
711 
712  while (1) {
713  size_t pos = dimString.find(",", curPos);
714  if (pos == string::npos)
715  pos = dimString.find(")");
716 
717  string varDimName;
718  istringstream iss(dimString.substr(curPos, pos - curPos));
719  iss >> skipws >> varDimName;
720 
721  for (int i = 0; i < ndims; i++) {
722  nc_inq_dim(ncid, dimid[i], dimName, &dimSize);
723  if (varDimName.compare(dimName) == 0) {
724  varDims[(*numDims)++] = dimid[i];
725  break;
726  }
727  }
728  if (dimString.substr(pos, 1).compare(")") == 0) break;
729 
730  curPos = pos + 1;
731  }
732 
733  return 0;
734 }
735 
736 int ncdfFile::getGid(const char *grpName) {
737 
738  int status;
739  int grpID;
740  status = nc_inq_grp_ncid(ncid, grpName, &grpID);
741  check_err(status, __LINE__, __FILE__);
742 
743  return grpID;
744 }
745 
747 
748  return ncid;
749 }
750 
752 
753  nc_close(ncid);
754 
755  return 0;
756 }
757 
char * ydhmsf(double dtime, char zone)
Definition: ydhmsf.c:12
int status
Definition: l1_czcs_hdf.c:32
int getNcid()
Definition: cdl_utils.cpp:746
void check_err(const int stat, const int line, const char *file)
Definition: nc4utils.c:35
float32 * pos
Definition: l1_czcs_hdf.c:35
int cdlCreate(char *l1_filename, char *cdl_filename, int32_t numScans)
Definition: cdl_utils.cpp:26
int close()
Definition: cdl_utils.cpp:751
int getGid(const char *grpName)
Definition: cdl_utils.cpp:736
int expandEnvVar(string *sValue)
Definition: hawkeyeUtil.h:41
string history
Definition: ncattredit.py:30
int parseDims(string dimString, int *numDims, int *varDims)
Definition: cdl_utils.cpp:705
int createNCDF(int ncid, const char *sname, const char *lname, const char *standard_name, const char *units, void *fill_value, const char *flag_values, const char *flag_meanings, double low, double high, float scale_factor, float add_offset, int nt, int rank, int *dimids)
u5 which has been done in the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT production Changes from v6 which may affect scientific the sector rotation may actually occur during one of the scans earlier than the one where it is first reported As a the b1 values are about the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT to fill pixels affected by dead subframes with a special value Output the metadata of noisy and dead subframe Dead Subframe EV and Detector Quality Flag2 Removed the function call of Fill_Dead_Detector_SI to stop interpolating SI values for dead but also for all downstream products for science test only Changes from v5 which will affect scientific to conform to MODIS requirements Removed the Mixed option from the ScanType in the code because the L1A Scan Type is never Mixed Changed for ANSI C compliance and comments to better document the fact that when the HDF_EOS metadata is stricly the and products are off by and in the track respectively Corrected some misspelling of RCS swir_oob_sending_detector to the Reflective LUTs to enable the SWIR OOB correction detector so that if any of the sending detectors becomes noisy or non near by good detectors from the same sending band can be specified as the substitute in the new look up table Code change for adding an additional dimension of mirror side to the Band_21_b1 LUT to separate the coefficient of the two mirror sides for just like other thermal emissive so that the L1B code can calibrate Band scan to scan with mirror side dependency which leads better calibration result Changes which do not affect scientific when the EV data are not provided in this Crosstalk Correction will not be performed to the Band calibration data Changes which do not affect scientific and BB_500m in L1A Logic was added to turn off the or to spatial aggregation processes and the EV_250m_Aggr1km_RefSB and EV_500m_Aggr1km_RefSB fields were set to fill values when SDSs EV_250m and EV_500m are absent in L1A file Logic was added to skip the processing and turn off the output of the L1B QKM and HKM EV data when EV_250m and EV_500m are absent from L1A In this the new process avoids accessing and reading the and L1A EV skips and writing to the L1B and EV omits reading and subsampling SDSs from geolocation file and writing them to the L1B and omits writing metadata to L1B and EV and skips closing the L1A and L1B EV and SDSs Logic was added to turn off the L1B OBC output when the high resolution OBC SDSs are absent from L1A This is accomplished by skipping the openning the writing of metadata and the closing of the L1B OBC hdf which is Bit in the scan by scan bit QA has been changed Until now
Definition: HISTORY.txt:361
int cdlCreateDim(char *l1_filename, char *cdl_filename, const char **dim_names, size_t *dim_size, size_t n_dims, size_t numScans)
Definition: cdl_utils.cpp:294
These two strings are used for the product XML output If product_id is not set then prefix is used If the last char of the name_prefix is _ then it is removed If algorithm_id is not set then name_suffix is used If the first char is _ then it is removed l2prod standard_name[0]
int i
Definition: decode_rs.h:71