OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l1_nc_generic_read.c
Go to the documentation of this file.
1 #include "l1_nc_generic_read.h"
2 
3 #include "l1.h"
4 #include <genutils.h>
5 #include <timeutils.h>
6 #include <libnav.h>
7 
8 #include <netcdf.h>
9 #include <stdlib.h>
10 
11 static int16_t nline, npix;
12 static int32_t spix = 0;
13 
14 static void scaleFloat(float *buf, int num, float scale, float offset) {
15  int i;
16  if (scale != 1.0 || offset != 0.0) {
17  for (i = 0; i < num; i++) {
18  if (buf[i] != -32767.0) {
19  buf[i] = buf[i] * scale + offset;
20  }
21  }
22  }
23 }
24 
25 int openl1_nc_generic(filehandle *file) {
26  size_t source_w, source_h;
27  int32_t nscan;
28  int fileID, xid, yid, retval;
29 
30  // Open the netcdf4 input file
31  retval = nc_open(file->name, NC_NOWRITE, &fileID);
32  if (retval != NC_NOERR) {
33  fprintf(stderr, "-E- %s line %d: nc_open(%s) failed.\n",
34  __FILE__, __LINE__, file->name);
35  return (1);
36  }
37  // Get pixel and scan dimensions
38  retval = nc_inq_dimid(fileID, "number_of_lines", &yid);
39  retval = nc_inq_dimid(fileID, "pixels_per_line", &xid);
40  retval = nc_inq_dimlen(fileID, xid, &source_w);
41  retval = nc_inq_dimlen(fileID, yid, &source_h);
42 
43  if (want_verbose) {
44  printf("L1B Npix :%d Nscans:%d\n", (int) source_w,
45  (int) source_h);
46  } // want_verbose
47  npix = (int32_t) source_w;
48  nscan = (int32_t) source_h;
49  nline = nscan;
50 
51  file->sd_id = fileID;
52  file->npix = npix;
53  file->nscan = nscan;
54  file->terrain_corrected = 1; //assumed
55  return (LIFE_IS_GOOD);
56 }
57 
58 int readl1_nc_generic(filehandle *file, int32_t scan, l1str *l1rec) {
59  static int firstCall = 1;
60 
61  static int scanGrp = -1;
62  static int dataGrp = -1;
63  static int navigationGrp = -1;
64  static int ancillaryGrp = -1;
65 
66  static int scantimeVar = -1;
67  static int yearVar = -1;
68  static int dayVar = -1;
69  static int msecVar = -1;
70  static int lonVar = -1;
71  static int latVar = -1;
72  static int senaVar = -1;
73  static int senzVar = -1;
74  static int solaVar = -1;
75  static int solzVar = -1;
76  static int wsVar = -1;
77  static int wdVar = -1;
78  static int prVar = -1;
79  static int ozVar = -1;
80  static int rhVar = -1;
81  static int wvVar = -1;
82  static int *ltVar;
83 
84  static float senaScale = 1.0;
85  static float senaOffset = 0.0;
86  static float senzScale = 1.0;
87  static float senzOffset = 0.0;
88  static float solaScale = 1.0;
89  static float solaOffset = 0.0;
90  static float solzScale = 1.0;
91  static float solzOffset = 0.0;
92 
93  static int *pixnum;
94  static float *rad_data;
95 
96  int retval;
97 
98  int32_t ip, ib, ipb;
99  int32_t nbands = l1rec->l1file->nbands;
100  size_t start[3], count[3];
101  int i;
102  int msec;
103  int scan_year, scan_day;
104 
105  if (firstCall) {
106  if (want_verbose)
107  printf("file->nbands = %d\n", (int) file->nbands);
108  firstCall = 0;
109 
110  int sensorGrp;
111  int pixnumVar;
112  retval = nc_inq_ncid(file->sd_id, "sensor_band_parameters", &sensorGrp);
113  if (retval == NC_NOERR) {
114  retval = nc_inq_varid(sensorGrp, "pixnum", &pixnumVar);
115  if (retval == NC_NOERR) {
116  pixnum = (int*) malloc(npix * sizeof (int));
117  start[0] = 0;
118  count[0] = npix;
119  retval = nc_get_vara_int(sensorGrp, pixnumVar, start, count, pixnum);
120  if (retval != NC_NOERR) {
121  fprintf(stderr,
122  "-E- %s line %d: nc_get_vara_int failed for file, %s group, %s var, %s.\n",
123  __FILE__, __LINE__, file->name, "sensor_band_parameters", "pixnum");
124  exit(EXIT_FAILURE);
125  }
126  }
127  }
128 
129  // find all of the group IDs
130  retval = nc_inq_ncid(file->sd_id, "scan_line_attributes", &scanGrp);
131  if (retval != NC_NOERR) {
132  fprintf(stderr,
133  "-E- %s line %d: nc_inq_ncid failed for file, %s group, %s.\n",
134  __FILE__, __LINE__, file->name, "scan_line_attributes");
135  exit(EXIT_FAILURE);
136  }
137 
138  retval = nc_inq_ncid(file->sd_id, "geophysical_data", &dataGrp);
139  if (retval != NC_NOERR) {
140  fprintf(stderr,
141  "-E- %s line %d: nc_inq_ncid failed for file, %s group, %s.\n",
142  __FILE__, __LINE__, file->name, "geophysical_data");
143  exit(EXIT_FAILURE);
144  }
145 
146  retval = nc_inq_ncid(file->sd_id, "navigation_data", &navigationGrp);
147  if (retval != NC_NOERR) {
148  fprintf(stderr,
149  "-E- %s line %d: nc_inq_ncid failed for file, %s group, %s.\n",
150  __FILE__, __LINE__, file->name, "navigation_data");
151  exit(EXIT_FAILURE);
152  }
153 
154  retval = nc_inq_ncid(file->sd_id, "ancillary_data", &ancillaryGrp);
155  if (retval != NC_NOERR)
156  ancillaryGrp = -1;
157 
158 
159  // setup all of the variable IDs
160  retval = nc_inq_varid(scanGrp, "scantime", &scantimeVar);
161  if (retval != NC_NOERR) {
162  scantimeVar = -1;
163  retval = nc_inq_varid(scanGrp, "year", &yearVar);
164  if (retval != NC_NOERR) {
165  fprintf(stderr,
166  "-E- %s line %d: variable \"scantime\" or \"year,day,msec\" required in group \"%s\"\n",
167  __FILE__, __LINE__, "scan_line_attributes");
168  exit(EXIT_FAILURE);
169  }
170  retval = nc_inq_varid(scanGrp, "day", &dayVar);
171  if (retval != NC_NOERR) {
172  fprintf(stderr,
173  "-E- %s line %d: variable \"scantime\" or \"year,day,msec\" required in group \"%s\"\n",
174  __FILE__, __LINE__, "scan_line_attributes");
175  exit(EXIT_FAILURE);
176  }
177  retval = nc_inq_varid(scanGrp, "msec", &msecVar);
178  if (retval != NC_NOERR) {
179  fprintf(stderr,
180  "-E- %s line %d: variable \"scantime\" or \"year,day,msec\" required in group \"%s\"\n",
181  __FILE__, __LINE__, "scan_line_attributes");
182  exit(EXIT_FAILURE);
183  }
184  } // scantime not found
185 
186  retval = nc_inq_varid(navigationGrp, "longitude", &lonVar);
187  if (retval != NC_NOERR) {
188  fprintf(stderr,
189  "-E- %s line %d: nc_inq_varid failed for file, %s field, %s.\n",
190  __FILE__, __LINE__, file->name, "longitude");
191  exit(EXIT_FAILURE);
192  }
193  retval = nc_inq_varid(navigationGrp, "latitude", &latVar);
194  if (retval != NC_NOERR) {
195  fprintf(stderr,
196  "-E- %s line %d: nc_inq_varid failed for file, %s field, %s.\n",
197  __FILE__, __LINE__, file->name, "latitude");
198  exit(EXIT_FAILURE);
199  }
200  retval = nc_inq_varid(navigationGrp, "sena", &senaVar);
201  if (retval != NC_NOERR) {
202  fprintf(stderr,
203  "-E- %s line %d: nc_inq_varid failed for file, %s field, %s.\n",
204  __FILE__, __LINE__, file->name, "sena");
205  exit(EXIT_FAILURE);
206  }
207  retval = nc_inq_varid(navigationGrp, "senz", &senzVar);
208  if (retval != NC_NOERR) {
209  fprintf(stderr,
210  "-E- %s line %d: nc_inq_varid failed for file, %s field, %s.\n",
211  __FILE__, __LINE__, file->name, "senz");
212  exit(EXIT_FAILURE);
213  }
214  retval = nc_inq_varid(navigationGrp, "sola", &solaVar);
215  if (retval != NC_NOERR)
216  solaVar = -1;
217  retval = nc_inq_varid(navigationGrp, "solz", &solzVar);
218  if (retval != NC_NOERR) {
219  if (solaVar == -1) {
220  solzVar = -1;
221  } else {
222  fprintf(stderr,
223  "-E- %s line %d: nc_inq_varid failed for file, %s field, %s.\n",
224  __FILE__, __LINE__, file->name, "solz");
225  fprintf(stderr, " solz must exist if sola is defined.\n");
226  exit(EXIT_FAILURE);
227  }
228  } else {
229  if (solaVar == -1) {
230  fprintf(stderr,
231  "-E- %s line %d: nc_inq_varid failed for file, %s field, %s.\n",
232  __FILE__, __LINE__, file->name, "sola");
233  fprintf(stderr, " sola must exist if solz is defined.\n");
234  exit(EXIT_FAILURE);
235  }
236  }
237 
238  if (ancillaryGrp != -1) {
239  retval = nc_inq_varid(ancillaryGrp, "windspeed", &wsVar);
240  if (retval != NC_NOERR) {
241  wsVar = -1;
242  }
243  retval = nc_inq_varid(ancillaryGrp, "windangle", &wdVar);
244  if (retval != NC_NOERR) {
245  wdVar = -1;
246  }
247  retval = nc_inq_varid(ancillaryGrp, "pressure", &prVar);
248  if (retval != NC_NOERR) {
249  prVar = -1;
250  }
251  retval = nc_inq_varid(ancillaryGrp, "ozone", &ozVar);
252  if (retval != NC_NOERR) {
253  ozVar = -1;
254  }
255  retval = nc_inq_varid(ancillaryGrp, "relhumid", &rhVar);
256  if (retval != NC_NOERR) {
257  rhVar = -1;
258  }
259  retval = nc_inq_varid(ancillaryGrp, "watervapor", &wvVar);
260  if (retval != NC_NOERR) {
261  wvVar = -1;
262  }
263  } // ancillary group exists
264 
265  char bandName[512];
266  ltVar = (int*) malloc((nbands + file->nbandsir) * sizeof (int));
267  rad_data = (float *) malloc(npix * sizeof (float));
268  for (i = 0; i < nbands; i++) {
269  sprintf(bandName, "Lt_%d", file->iwave[i]);
270  retval = nc_inq_varid(dataGrp, bandName, ltVar + i);
271  if (retval != NC_NOERR) {
272  fprintf(stderr,
273  "-E- %s line %d: could not find \"%s\" variable in file, %s\n",
274  __FILE__, __LINE__, bandName, file->name);
275  exit(EXIT_FAILURE);
276  }
277  }
278  for (i = nbands; i < (nbands + file->nbandsir); i++) {
279  sprintf(bandName, "Lt_%d", file->iwave[i]);
280  retval = nc_inq_varid(dataGrp, bandName, ltVar + i);
281  if (retval != NC_NOERR) {
282  ltVar[i] = -1;
283  }
284  }
285 
286  // read scale factors since sol and sen angles can be scaled shorts
287  nc_get_att_float(navigationGrp, senaVar, "scale_factor", &senaScale);
288  nc_get_att_float(navigationGrp, senaVar, "add_offset", &senaOffset);
289 
290  nc_get_att_float(navigationGrp, senzVar, "scale_factor", &senzScale);
291  nc_get_att_float(navigationGrp, senzVar, "add_offset", &senzOffset);
292 
293  if (solaVar != -1) {
294  nc_get_att_float(navigationGrp, solaVar, "scale_factor", &solaScale);
295  nc_get_att_float(navigationGrp, solaVar, "add_offset", &solaOffset);
296  }
297 
298  if (solzVar != -1) {
299  nc_get_att_float(navigationGrp, solzVar, "scale_factor", &solzScale);
300  nc_get_att_float(navigationGrp, solzVar, "add_offset", &solzOffset);
301  }
302 
303  } // first call
304 
305 
306  if (pixnum) {
307  for (ip = 0; ip < npix; ip++)
308  l1rec->pixnum[ip] = pixnum[ip];
309  }
310 
311  start[0] = scan;
312  count[0] = 1;
313 
314  if (scantimeVar != -1) {
315  nc_get_vara_double(scanGrp, scantimeVar, start, count, &l1rec->scantime);
316  } else {
317  retval = nc_get_vara_int(scanGrp, yearVar, start, count, &scan_year);
318  if (retval != NC_NOERR) {
319  fprintf(stderr,
320  "-E- %s line %d: nc_get_vara_int failed for file, %s field, %s.\n",
321  __FILE__, __LINE__, file->name, "year");
322  exit(EXIT_FAILURE);
323  }
324  retval = nc_get_vara_int(scanGrp, dayVar, start, count, &scan_day);
325  if (retval != NC_NOERR) {
326  fprintf(stderr,
327  "-E- %s line %d: nc_get_vara_int failed for file, %s field, %s.\n",
328  __FILE__, __LINE__, file->name, "day");
329  exit(EXIT_FAILURE);
330  }
331  retval = nc_get_vara_int(scanGrp, msecVar, start, count, &msec);
332  if (retval != NC_NOERR) {
333  fprintf(stderr,
334  "-E- %s line %d: nc_get_vara_int failed for file, %s field, %s.\n",
335  __FILE__, __LINE__, file->name, "msec");
336  exit(EXIT_FAILURE);
337  }
338 
339  l1rec->scantime = yds2unix((int16_t) scan_year, (int16_t) scan_day, (double) (msec / 1.e3));
340  }
341 
342  start[0] = scan;
343  start[1] = 0;
344  start[2] = 0;
345  count[0] = 1;
346  count[1] = npix;
347  count[2] = 1;
348 
349  retval = nc_get_vara_float(navigationGrp, lonVar, start, count, l1rec->lon);
350  if (retval != NC_NOERR) {
351  fprintf(stderr,
352  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
353  __FILE__, __LINE__, file->name, "longitude");
354  exit(EXIT_FAILURE);
355  }
356  retval = nc_get_vara_float(navigationGrp, latVar, start, count, l1rec->lat);
357  if (retval != NC_NOERR) {
358  fprintf(stderr,
359  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
360  __FILE__, __LINE__, file->name, "latitude");
361  exit(EXIT_FAILURE);
362  }
363  retval = nc_get_vara_float(navigationGrp, senaVar, start, count, l1rec->sena);
364  if (retval != NC_NOERR) {
365  fprintf(stderr,
366  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
367  __FILE__, __LINE__, file->name, "sena");
368  exit(EXIT_FAILURE);
369  }
370  scaleFloat(l1rec->sena, npix, senaScale, senaOffset);
371  retval = nc_get_vara_float(navigationGrp, senzVar, start, count, l1rec->senz);
372  if (retval != NC_NOERR) {
373  fprintf(stderr,
374  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
375  __FILE__, __LINE__, file->name, "senz");
376  exit(EXIT_FAILURE);
377  }
378  scaleFloat(l1rec->senz, npix, senzScale, senzOffset);
379  if (solaVar != -1) {
380  retval = nc_get_vara_float(navigationGrp, solaVar, start, count, l1rec->sola);
381  if (retval != NC_NOERR) {
382  fprintf(stderr,
383  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
384  __FILE__, __LINE__, file->name, "sola");
385  exit(EXIT_FAILURE);
386  }
387  scaleFloat(l1rec->sola, npix, solaScale, solaOffset);
388  retval = nc_get_vara_float(navigationGrp, solzVar, start, count, l1rec->solz);
389  if (retval != NC_NOERR) {
390  fprintf(stderr,
391  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
392  __FILE__, __LINE__, file->name, "solz");
393  exit(EXIT_FAILURE);
394  }
395  scaleFloat(l1rec->solz, npix, solzScale, solzOffset);
396  } else {
397  int iyear, iday;
398  float gmt;
399  int16_t syear, sday;
400  double secs;
401  int i;
402 
403  unix2yds(l1rec->scantime, &syear, &sday, &secs);
404  iyear = syear;
405  iday = sday;
406  gmt = secs / 3600.0;
407  for (i = 0; i < npix; i++) {
408  sunangs_(&iyear, &iday, &gmt, l1rec->lon + i, l1rec->lat + i, l1rec->solz + i, l1rec->sola + i);
409  }
410  }
411 
412  // read in ancillary data
413  if (ancillaryGrp) {
414 
415  if (wsVar != -1) {
416  retval = nc_get_vara_float(ancillaryGrp, wsVar, start, count, l1rec->ws);
417  if (retval != NC_NOERR) {
418  fprintf(stderr,
419  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
420  __FILE__, __LINE__, file->name, "windspeed");
421  exit(EXIT_FAILURE);
422  }
423  }
424 
425  if (wdVar != -1) {
426  retval = nc_get_vara_float(ancillaryGrp, wdVar, start, count, l1rec->wd);
427  if (retval != NC_NOERR) {
428  fprintf(stderr,
429  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
430  __FILE__, __LINE__, file->name, "windangle");
431  exit(EXIT_FAILURE);
432  }
433  }
434 
435  if (prVar != -1) {
436  retval = nc_get_vara_float(ancillaryGrp, prVar, start, count, l1rec->pr);
437  if (retval != NC_NOERR) {
438  fprintf(stderr,
439  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
440  __FILE__, __LINE__, file->name, "pressure");
441  exit(EXIT_FAILURE);
442  }
443  }
444 
445  if (ozVar != -1) {
446  retval = nc_get_vara_float(ancillaryGrp, ozVar, start, count, l1rec->oz);
447  if (retval != NC_NOERR) {
448  fprintf(stderr,
449  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
450  __FILE__, __LINE__, file->name, "ozone");
451  exit(EXIT_FAILURE);
452  }
453  }
454 
455  if (rhVar != -1) {
456  retval = nc_get_vara_float(ancillaryGrp, rhVar, start, count, l1rec->rh);
457  if (retval != NC_NOERR) {
458  fprintf(stderr,
459  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
460  __FILE__, __LINE__, file->name, "relhumid");
461  exit(EXIT_FAILURE);
462  }
463  }
464 
465  if (wvVar != -1) {
466  retval = nc_get_vara_float(ancillaryGrp, wvVar, start, count, l1rec->wv);
467  if (retval != NC_NOERR) {
468  fprintf(stderr,
469  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
470  __FILE__, __LINE__, file->name, "watervapor");
471  exit(EXIT_FAILURE);
472  }
473  }
474  } // found ancillary group
475 
476 
477  // read in radiance data
478  for (ib = 0; ib < nbands; ib++) {
479 
480  retval = nc_get_vara_float(dataGrp, ltVar[ib], start, count, rad_data);
481  if (retval != NC_NOERR) {
482  fprintf(stderr,
483  "-E- %s line %d: nc_get_vara_float failed for file, %s Lt %d nm.\n",
484  __FILE__, __LINE__, file->name, file->iwave[ib]);
485  exit(EXIT_FAILURE);
486  }
487 
488  // copy to Lt record.
489  for (ip = spix; ip < npix; ip++) {
490  ipb = ip * nbands + ib;
491  l1rec->Lt[ipb] = rad_data[ip] / 10.0;
492 
493  if (l1rec->Lt[ipb] <= 0.0)
494  l1rec->Lt[ipb] = 0.0001;
495  }
496  } // for ib
497 
498  // now for IR bands
499  for (ib = nbands; ib < (nbands + file->nbandsir); ib++) {
500  if (ltVar[ib] != -1) {
501  retval = nc_get_vara_float(dataGrp, ltVar[ib], start, count, rad_data);
502  if (retval == NC_NOERR) {
503  // copy to Lt record.
504  for (ip = spix; ip < npix; ip++) {
505  ipb = ip * file->nbandsir + ib - nbands;
506  l1rec->Ltir[ipb] = rad_data[ip] / 10.0;
507 
508  if (l1rec->Ltir[ipb] <= 0.0)
509  l1rec->Ltir[ipb] = 0.0001;
510  }
511  }
512  }
513 
514  } // for ib
515 
516  l1rec->npix = file->npix;
517 
518  return (LIFE_IS_GOOD);
519 }
520 
521 int closel1_nc_generic(filehandle *file) {
522  int retval;
523 
524  retval = nc_close(file->sd_id);
525  if (retval != NC_NOERR) {
526  fprintf(stderr, "-E- %s line %d: nc_close failed for file, %s.\n",
527  __FILE__, __LINE__, file->name);
528  return (1);
529  }
530 
531  return (LIFE_IS_GOOD);
532 }
533 
double yds2unix(int16_t year, int16_t day, double secs)
Definition: yds2unix.c:7
int16_t fileID
MOD_PR01 Production producing one five minute granule of output data in each run It can be configured to produce as many as three five minute granules per run Each execution with one construction record and one date file for each dataset In normal these are created by which splits them out of the hour datasets For LANCE they are created by which merges all session MODIS L0 datasets overlapping the requested time and extracts from the merged data those packets which fall within that time period Each scan of data is stored in the L1A granule that covers the start time of that scan
Definition: MOD_PR01_pr.txt:19
read l1rec
int32 * msec
Definition: l1_czcs_hdf.c:31
int syear
Definition: l1_czcs_hdf.c:15
int32 nscan
Definition: l1_czcs_hdf.c:19
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed file
Definition: HISTORY.txt:413
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
int sday
Definition: l1_czcs_hdf.c:15
int closel1_nc_generic(filehandle *file)
void sunangs_(int *, int *, float *, float *, float *, float *, float *)
int openl1_nc_generic(filehandle *file)
int want_verbose
void unix2yds(double usec, short *year, short *day, double *secs)
int32_t nbands
int32 spix
Definition: l1_czcs_hdf.c:21
int readl1_nc_generic(filehandle *file, int32_t scan, l1str *l1rec)
l2prod offset
int i
Definition: decode_rs.h:71
int npix
Definition: get_cmp.c:27
int count
Definition: decode_rs.h:79