OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
createNCDF_viirs.cpp
Go to the documentation of this file.
1 /*
2  * createNCDF_viirs.c
3  *
4  * Created on: Sep 2, 2016
5  * Author: rhealy
6  */
7 #include <string>
8 #include "netcdf.h"
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <stdint.h>
12 #include "nc4utils.h"
13 #include <sstream>
14 #include <iomanip>
15 #include "l1agen_viirs.h"
16 
17 int createNCDF_viirs( int ncid, const char *sname, const char *lname,
18  const char *standard_name, const char *units,
19  void *fill_value,
20  const char *flag_values, const char *flag_meanings,
21  double low, double high, int nt,
22  int rank, int *dimids) {
23 
24  int32_t varid;
25  int i;
26  int status;
27  size_t dimlength;
28  size_t newchunk;
29  size_t chunksize[3];
30 
31  /* Create the NCDF dataset */
32  status = nc_def_var(ncid, sname, nt, rank, dimids, &varid);
33  if( status != NC_NOERR) {
34  printf("-E- %s %d: %s for %s\n",
35  __FILE__, __LINE__, nc_strerror(status), sname);
36  exit(1);
37  }
38 
39  // Set fill value
40  double fill_value_dbl;
41  memcpy( &fill_value_dbl, fill_value, sizeof(double));
42 
43  int8_t i8;
44  uint8_t ui8;
45  int16_t i16;
46  int32_t i32;
47  float f32;
48 
49  // if ( (low < high) && (low != fill_value_dbl)) {
50  if ( low != fill_value_dbl) {
51  if ( nt == NC_BYTE) {
52  i8 = fill_value_dbl;
53  status = nc_def_var_fill( ncid, varid, 0, (void *) &i8);
54  } else if ( nt == NC_UBYTE) {
55  ui8 = fill_value_dbl;
56  status = nc_def_var_fill( ncid, varid, 0, (void *) &ui8);
57  } else if ( nt == NC_SHORT) {
58  i16 = fill_value_dbl;
59  status = nc_def_var_fill( ncid, varid, 0, (void *) &i16);
60  } else if ( nt == NC_INT) {
61  i32 = fill_value_dbl;
62  status = nc_def_var_fill( ncid, varid, 0, (void *) &i32);
63  } else if ( nt == NC_FLOAT) {
64  f32 = fill_value_dbl;
65  status = nc_def_var_fill( ncid, varid, 0, (void *) &f32);
66  } else {
67  status = nc_def_var_fill( ncid, varid, 0, (void *) &fill_value_dbl);
68  }
69  check_err(status,__LINE__,__FILE__);
70  }
71 
72  /* vary chunck size based on dimensions */
73  int do_deflate = 0;
74  if ( rank == 3) {
75  status = nc_inq_dimlen(ncid, dimids[2], &dimlength);
76  if ( dimlength >= 3200) {
77  chunksize[0] = 1;
78  chunksize[1] = 16;
79  chunksize[2] = 320;
80  do_deflate = 1;
81  }
82  }
83 
84  /* Set compression */
85  if ( do_deflate) {
86  /* First set chunking */
87  status = nc_def_var_chunking(ncid, varid, NC_CHUNKED, chunksize);
88  if (status != NC_NOERR) {
89  printf("-E- %s %d: %s for %s\n", __FILE__, __LINE__,
90  nc_strerror(status), sname);
91  exit(1);
92  }
93 
94  /* Now we can set compression */
95  // status = nc_def_var_deflate(ncid, varid, NC_NOSHUFFLE, 1, 5);
96  status = nc_def_var_deflate(ncid, varid, NC_SHUFFLE, 1, 5);
97  if (status != NC_NOERR) {
98  printf("-E- %s %d: %s for %s\n", __FILE__, __LINE__,
99  nc_strerror(status), sname);
100  exit(1);
101  }
102  }
103 
104 
105  /* Add a "long_name" attribute */
106  status = nc_put_att_text(ncid, varid, "long_name", strlen(lname), lname);
107  if( status != NC_NOERR) {
108  printf("-E- %s %d: %s for %s\n",
109  __FILE__, __LINE__, nc_strerror(status), "long_name");
110  exit(1);
111  }
112 
113  /* Add a "flag_values" attribute if specified*/
114  // Parse string and save as signed bytes
115  if ( strcmp( flag_values, "") != 0) {
116 
117  size_t curPos=0;
118 
119  string fv;
120  fv.assign( flag_values);
121  size_t pos = fv.find("=", curPos);
122  fv = fv.substr(pos+1);
123 
124  size_t semicln = fv.find(";");
125  pos = 0;
126 
127  int8_t vec[1024];
128  int n = 0;
129  while(pos != semicln) {
130  pos = fv.find(",", curPos);
131  if ( pos == string::npos)
132  pos = semicln;
133 
134  string flag_value;
135  istringstream iss(fv.substr(curPos, pos-curPos));
136  iss >> skipws >> flag_value;
137  vec[n++] = atoi( flag_value.c_str());
138  curPos = pos + 1;
139  }
140 
141  status = nc_put_att_schar(ncid, varid, "flag_values", NC_BYTE, n, vec);
142  if( status != NC_NOERR) {
143  printf("-E- %s %d: %s for %s\n",
144  __FILE__, __LINE__, nc_strerror(status), "flag_values");
145  exit(1);
146  }
147  }
148 
149  /* Add a "flag_meanings" attribute if specified*/
150  if ( strcmp( flag_meanings, "") != 0) {
151  status = nc_put_att_text(ncid, varid, "flag_meanings",
152  strlen(flag_meanings), flag_meanings);
153  if( status != NC_NOERR) {
154  printf("-E- %s %d: %s for %s\n",
155  __FILE__, __LINE__, nc_strerror(status), "flag_meanings");
156  exit(1);
157  }
158  }
159 
160  /* Add "valid_min/max" attributes if specified */
161  if (low < high) {
162  switch(nt) { /* Use the appropriate number type */
163  case NC_BYTE:
164  {
165  uint8_t vr[2];
166  vr[0] = (uint8_t)low;
167  vr[1] = (uint8_t)high;
168  status = nc_put_att_uchar(ncid, varid,"valid_min",NC_BYTE,1,&vr[0]);
169  if( status != NC_NOERR) {
170  printf("-E- %s %d: %s for %s\n",
171  __FILE__, __LINE__, nc_strerror(status), "valid_min");
172  exit(1);
173  }
174  status = nc_put_att_uchar(ncid, varid,"valid_max",NC_BYTE,1,&vr[1]);
175  if( status != NC_NOERR) {
176  printf("-E- %s %d: %s for %s\n",
177  __FILE__, __LINE__, nc_strerror(status), "valid_max");
178  exit(1);
179  }
180  }
181  break;
182  case NC_UBYTE:
183  {
184  uint8_t vr[2];
185  vr[0] = (uint8_t)low;
186  vr[1] = (uint8_t)high;
187  status = nc_put_att_uchar(ncid, varid,"valid_min",NC_UBYTE,1,&vr[0]);
188  if( status != NC_NOERR) {
189  printf("-E- %s %d: %s for %s\n",
190  __FILE__, __LINE__, nc_strerror(status), "valid_min");
191  exit(1);
192  }
193  status = nc_put_att_uchar(ncid, varid,"valid_max",NC_UBYTE,1,&vr[1]);
194  if( status != NC_NOERR) {
195  printf("-E- %s %d: %s for %s\n",
196  __FILE__, __LINE__, nc_strerror(status), "valid_max");
197  exit(1);
198  }
199  }
200  break;
201  case NC_SHORT:
202  {
203  int16_t vr[2];
204  vr[0] = (int16_t)low;
205  vr[1] = (int16_t)high;
206  status = nc_put_att_short(ncid, varid,"valid_min",NC_SHORT,1,&vr[0]);
207  if( status != NC_NOERR) {
208  printf("-E- %s %d: %s for %s\n",
209  __FILE__, __LINE__, nc_strerror(status), "valid_min");
210  exit(1);
211  }
212  status = nc_put_att_short(ncid, varid,"valid_max",NC_SHORT,1,&vr[1]);
213  if( status != NC_NOERR) {
214  printf("-E- %s %d: %s for %s\n",
215  __FILE__, __LINE__, nc_strerror(status), "valid_max");
216  exit(1);
217  }
218  }
219  break;
220  case NC_USHORT:
221  {
222  uint16_t vr[2];
223  vr[0] = (uint16_t)low;
224  vr[1] = (uint16_t)high;
225  status = nc_put_att_ushort(ncid, varid,"valid_min",NC_USHORT,1,&vr[0]);
226  if( status != NC_NOERR) {
227  printf("-E- %s %d: %s for %s\n",
228  __FILE__, __LINE__, nc_strerror(status), "valid_min");
229  exit(1);
230  }
231  status = nc_put_att_ushort(ncid, varid,"valid_max",NC_USHORT,1,&vr[1]);
232  if( status != NC_NOERR) {
233  printf("-E- %s %d: %s for %s\n",
234  __FILE__, __LINE__, nc_strerror(status), "valid_max");
235  exit(1);
236  }
237  }
238  break;
239  case NC_INT:
240  {
241  int32_t vr[2];
242  vr[0] = (int32_t)low;
243  vr[1] = (int32_t)high;
244  status = nc_put_att_int(ncid, varid,"valid_min",NC_INT,1,&vr[0]);
245  if( status != NC_NOERR) {
246  printf("-E- %s %d: %s for %s\n",
247  __FILE__, __LINE__, nc_strerror(status), "valid_min");
248  exit(1);
249  }
250  status = nc_put_att_int(ncid, varid,"valid_max",NC_INT,1,&vr[1]);
251  if( status != NC_NOERR) {
252  printf("-E- %s %d: %s for %s\n",
253  __FILE__, __LINE__, nc_strerror(status), "valid_max");
254  exit(1);
255  }
256  }
257  break;
258  case NC_FLOAT:
259  {
260  float vr[2];
261  vr[0] = (float)low;
262  vr[1] = (float)high;
263  status = nc_put_att_float(ncid, varid,"valid_min",NC_FLOAT,1,&vr[0]);
264  if( status != NC_NOERR) {
265  printf("-E- %s %d: %s for %s\n",
266  __FILE__, __LINE__, nc_strerror(status), "valid_min");
267  exit(1);
268  }
269  status = nc_put_att_float(ncid, varid,"valid_max",NC_FLOAT,1,&vr[1]);
270  if( status != NC_NOERR) {
271  printf("-E- %s %d: %s for %s\n",
272  __FILE__, __LINE__, nc_strerror(status), "valid_max");
273  exit(1);
274  }
275  }
276  break;
277  case NC_DOUBLE:
278  {
279  double vr[2];
280  vr[0] = low;
281  vr[1] = high;
282  status = nc_put_att_double(ncid, varid,"valid_min",NC_DOUBLE,1,&vr[0]);
283  if( status != NC_NOERR) {
284  printf("-E- %s %d: %s for %s\n",
285  __FILE__, __LINE__, nc_strerror(status), "valid_min");
286  exit(1);
287  }
288  status = nc_put_att_double(ncid, varid,"valid_max",NC_DOUBLE,1,&vr[1]);
289  if( status != NC_NOERR) {
290  printf("-E- %s %d: %s for %s\n",
291  __FILE__, __LINE__, nc_strerror(status), "valid_max");
292  exit(1);
293  }
294  }
295  break;
296  default:
297  fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
298  fprintf(stderr,"Got unsupported number type (%d) ",nt);
299  fprintf(stderr,"while trying to create NCDF variable, \"%s\", ",sname);
300  return(EXIT_FAILURE);
301  }
302  }
303 
304  /* Add a "units" attribute if one is specified */
305  if(units != NULL && *units != 0) {
306  status = nc_put_att_text(ncid, varid, "units", strlen(units), units);
307  if( status != NC_NOERR) {
308  printf("-E- %s %d: %s for %s\n",
309  __FILE__, __LINE__, nc_strerror(status), "units");
310  exit(1);
311  }
312  }
313 
314  /* Add a "standard_name" attribute if one is specified */
315  if(standard_name != NULL && *standard_name != 0) {
316  status = nc_put_att_text(ncid, varid, "standard_name",
317  strlen(standard_name), standard_name);
318  if( status != NC_NOERR) {
319  printf("-E- %s %d: %s for %s\n",
320  __FILE__, __LINE__, nc_strerror(status), "standard_name");
321  exit(1);
322  }
323  }
324 
325  return 0;
326 }
327 
328 
int status
Definition: l1_czcs_hdf.c:32
void check_err(const int stat, const int line, const char *file)
Definition: nc4utils.c:35
#define NULL
Definition: decode_rs.h:63
float32 * pos
Definition: l1_czcs_hdf.c:35
Extra metadata that will be written to the HDF4 file l2prod rank
int createNCDF_viirs(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, int nt, int rank, int *dimids)
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
float32 f32
Definition: l2bin.cpp:104