OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l1_aviris_nc.c
Go to the documentation of this file.
1 /* ============================================================================ */
2 /* module l1_aviris_nc.c - functions to read AVIRIS netcdf (coastal color) for MSL12 */
3 /* Written By: Rick Healy GSFC SAIC, September, 2016. */
4 /* */
5 /* ============================================================================ */
6 
7 // #include <stdbool.h>
8 #include "l1_aviris.h"
9 
10 #include <netcdf.h>
11 #include "l1.h"
12 
13 static int16_t nline, npix;
14 
15 static int32_t spix = 0;
16 static double starttime;
17 static double *scan_start_tai, *scan_stop_tai;
18 static double time_interval;
19 static short *alt;
20 
21 int openl1_aviris_nc(filehandle * file) {
22 
23  size_t source_w, source_h, source_b;
24  int32_t nscan;
25  int i;
26  int fileID, xid, yid, band_id, retval, grp_id, sds_id;
27  double stoptime;
28  size_t start[3], count[3];
29  aviris_t* data = file->private_data = createPrivateData_aviris(AV_MAXBANDS);
30  data->isnetcdf = 1;
31 
32  // Open the netcdf4 input file
33  retval = nc_open(file->name, NC_NOWRITE, &fileID);
34  if (retval != NC_NOERR) {
35  fprintf(stderr, "-E- %s line %d: nc_open(%s) failed.\n",
36  __FILE__, __LINE__, file->name);
37  return (1);
38  }
39 
40  // Get pixel and scan dimensions
41  retval = nc_inq_dimid(fileID, "number_of_lines", &yid);
42  retval = nc_inq_dimid(fileID, "pixels_per_line", &xid);
43  retval = nc_inq_dimid(fileID, "number_of_bands", &band_id);
44  retval = nc_inq_dimlen(fileID, xid, &source_w);
45  retval = nc_inq_dimlen(fileID, yid, &source_h);
46  retval = nc_inq_dimlen(fileID, band_id, &source_b);
47 
48  if (want_verbose) {
49  printf("AVIRIS L1B Npix :%d Nscans:%d\n", (int) source_w,
50  (int) source_h);
51  } // want_verbose
52  npix = (int32_t) source_w;
53  nscan = (int32_t) source_h;
54  nline = nscan;
55 
56  file->sd_id = fileID;
57  file->npix = npix;
58  file->nscan = nscan;
59  file->nbands = source_b;
60  strcpy(file->spatialResolution, "750 m");
61 
62  scan_start_tai = (double *) calloc(nscan, sizeof (double));
63  scan_stop_tai = (double *) calloc(nscan, sizeof (double));
64  alt = (short *) calloc(nscan, sizeof (short));
65 
66  start[0] = 0;
67  start[1] = 0;
68  start[2] = 0;
69  count[0] = nscan;
70  count[1] = 0;
71  count[2] = 0;
72 
73  nc_inq_ncid(file->sd_id, "scan_line_attributes", &grp_id);
74 
75  retval = nc_inq_varid(grp_id, "altitude", &sds_id);
76  retval = nc_get_vara_short(grp_id, sds_id, start, count, alt);
77  if (retval != NC_NOERR) {
78  fprintf(stderr,
79  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
80  __FILE__, __LINE__, file->name, "altitude");
81  return (1);
82  }
83 
84  retval = nc_inq_varid(grp_id, "scan_start_time", &sds_id);
85  retval = nc_get_vara_double(grp_id, sds_id, start, count, scan_start_tai);
86  if (retval != NC_NOERR) {
87  fprintf(stderr,
88  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
89  __FILE__, __LINE__, file->name, "scan_start_time");
90  return (1);
91  }
92 
93  /*
94  * Temporary fix for scan_start and stop
95  */
96 
97  // for (i=0; i<nscan; i++) {
98  // scan_start_tai[i] = yds2unix(year, day, secs+i);
99  // }
100 
101  int iscan = 0, i1, i2;
102  starttime = 9999;
103  while (iscan < nscan) {
104  if (scan_start_tai[iscan] > 0) {
105  if (starttime > scan_start_tai[iscan])starttime = scan_start_tai[iscan];
106  }
107  iscan++;
108  }
109  i1 = iscan;
110 
111  //starttime = scan_start_tai[0];
112 
113  // nc_inq_varid(grp_id,"scan_end_time",&sds_id);
114  // nc_get_vara_double(grp_id, sds_id, start, count, scan_stop_tai);
115  iscan = nscan - 1;
116  stoptime = -9999;
117  while (iscan > 0) {
118  if (scan_start_tai[iscan] > 0) {
119  if (stoptime < scan_start_tai[iscan])stoptime = scan_start_tai[iscan];
120  }
121  iscan--;
122  }
123  i2 = iscan;
124  //stoptime = scan_start_tai[nscan];
125 
126  time_interval = (stoptime - starttime) / ((i2 - i1) + 1); /* in sec */
127 
128  /*
129  retval = navigation_meris(fileID);
130  */
131  start[0] = 0;
132  count[0] = source_b;
133 
134  file->fwhm = (float *) calloc(source_b, sizeof (float));
135  float *fwhm = (float *) calloc(source_b, sizeof (float));
136 
137  retval = nc_inq_ncid(file->sd_id, "sensor_band_parameters", &grp_id);
138  if (retval != NC_NOERR) {
139  fprintf(stderr,
140  "-E- %s line %d: nc_inq failed for file, %s group does not exist: %s.\n",
141  __FILE__, __LINE__, file->name, "sensor_band_parameters");
142  return (1);
143  }
144 
145  retval = nc_inq_varid(grp_id, "fwhm", &sds_id);
146  if (retval != NC_NOERR) {
147  fprintf(stderr,
148  "-E- %s line %d: nc_inq failed for file, %s field, variable %s does not exist.\n",
149  __FILE__, __LINE__, file->name, "fwhm");
150  return (1);
151  }
152  retval = nc_get_vara_float(grp_id, sds_id, start, count, fwhm);
153 
154 
155  for (i = 0; i < source_b; i++)
156  file->fwhm[i] = fwhm[i] / 1000.; //convert to microns from nm
157 
158  return (LIFE_IS_GOOD);
159 }
160 
161 int readl1_aviris_nc(filehandle *file, int32_t scan, l1str *l1rec) {
162  static int firstCall = 1;
163  int retval;
164  float *lon, *lat, *senz, *sena, *solz, *sola;
165 
166  int32_t ip, ib, ipb, Ibp;
167  int32_t nbands = l1rec->l1file->nbands;
168  size_t start[3], count[3];
169  int band_id, grp_id;
170  float *rad_data;
171 
172  if (firstCall) {
173  if (want_verbose)
174  printf("file->nbands = %d, l1rec->nbands = %d\n",
175  (int) file->nbands, (int) l1rec->l1file->nbands);
176  firstCall = 0;
177 
178  for (ip = 0; ip < npix; ip++) {
179  l1rec->pixnum[ip] = ip;
180  l1rec->flags[ip] = 0;
181  }
182 
183  }
184 
185 
186  // set time for this scan - if scan_start_time value not properly set, estimate from scene start time.
187  // printf("RJH: scan_start_tai=%f\n",scan_start_tai[scan]);
188  // if (scan_start_tai[scan] > 0){
189  // lastvalidtime = scan_start_tai[scan]+tai2unixoffset;
190  // lastvalidscan = scan;
191  // unix2yds(lastvalidtime, &scan_year, &scan_day, &msec);
192  // } else {
193  // unix2yds(lastvalidtime+(time_interval * (scan-lastvalidscan)),&scan_year,&scan_day, &msec);
194  // }
195  // msec -= leapseconds_since_1993(lastvalidtime-tai2unixoffset)*1000;
196  // l1rec->scantime = yds2unix(scan_year, scan_day, (double) (msec / 1.e3));
197  l1rec->scantime = scan_start_tai[scan];
198 
199  retval = nc_inq_ncid(file->sd_id, "navigation_data", &grp_id);
200  if (retval != NC_NOERR) {
201  fprintf(stderr,
202  "-E- %s line %d: nc_inq_ncid failed for file, %s group, %s.\n",
203  __FILE__, __LINE__, file->name, "navigation_data");
204  return (1);
205  }
206 
207  start[0] = scan;
208  start[1] = 0;
209  start[2] = 0;
210  count[0] = 1;
211  count[1] = npix;
212  count[2] = 0;
213 
214  lon = (float *) calloc(npix, sizeof (float));
215  lat = (float *) calloc(npix, sizeof (float));
216  senz = (float *) calloc(npix, sizeof (float));
217  sena = (float *) calloc(npix, sizeof (float));
218  solz = (float *) calloc(npix, sizeof (float));
219  sola = (float *) calloc(npix, sizeof (float));
220 
221  retval = nc_inq_varid(grp_id, "lon", &band_id);
222  if (retval != NC_NOERR) {
223  fprintf(stderr,
224  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
225  __FILE__, __LINE__, file->name, "lon");
226  return (1);
227  }
228  retval = nc_get_vara_float(grp_id, band_id, start, count, lon);
229  if (retval != NC_NOERR) {
230  fprintf(stderr,
231  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
232  __FILE__, __LINE__, file->name, "lon");
233  return (1);
234  }
235  retval = nc_inq_varid(grp_id, "lat", &band_id);
236  if (retval != NC_NOERR) {
237  fprintf(stderr,
238  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
239  __FILE__, __LINE__, file->name, "lon");
240  return (1);
241  }
242  retval = nc_get_vara_float(grp_id, band_id, start, count, lat);
243  if (retval != NC_NOERR) {
244  fprintf(stderr,
245  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
246  __FILE__, __LINE__, file->name, "lat");
247  return (1);
248  }
249  //until geolocation is read, set fill values -
250  for (ip = spix; ip < npix; ip++) {
251  l1rec->lon[ip] = lon[ip];
252  l1rec->lat[ip] = lat[ip];
253  l1rec->solz[ip] = -999; //solz[scan * npix + ip];
254  l1rec->sola[ip] = -999; //sola[scan * npix + ip];
255  l1rec->senz[ip] = -999; //senz[scan * npix + ip];
256  l1rec->sena[ip] = -999; //sena[scan * npix + ip];
257  }
258 
259  retval = nc_inq_varid(grp_id, "sena", &band_id);
260  retval = nc_get_vara_float(grp_id, band_id, start, count, sena);
261  if (retval != NC_NOERR) {
262  fprintf(stderr,
263  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
264  __FILE__, __LINE__, file->name, "sena");
265  return (1);
266  }
267  retval = nc_inq_varid(grp_id, "senz", &band_id);
268  retval = nc_get_vara_float(grp_id, band_id, start, count, senz);
269  if (retval != NC_NOERR) {
270  fprintf(stderr,
271  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
272  __FILE__, __LINE__, file->name, "senz");
273  return (1);
274  }
275  retval = nc_inq_varid(grp_id, "sola", &band_id);
276  retval = nc_get_vara_float(grp_id, band_id, start, count, sola);
277  if (retval != NC_NOERR) {
278  fprintf(stderr,
279  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
280  __FILE__, __LINE__, file->name, "sola");
281  return (1);
282  }
283  retval = nc_inq_varid(grp_id, "solz", &band_id);
284  retval = nc_get_vara_float(grp_id, band_id, start, count, solz);
285  if (retval != NC_NOERR) {
286  fprintf(stderr,
287  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
288  __FILE__, __LINE__, file->name, "solz");
289  return (1);
290  }
291 
292  for (ip = spix; ip < npix; ip++) {
293  l1rec->lon[ip] = lon[ip];
294  l1rec->lat[ip] = lat[ip];
295  l1rec->solz[ip] = solz[ip];
296  l1rec->sola[ip] = sola[ip];
297  l1rec->senz[ip] = senz[ip];
298  l1rec->sena[ip] = sena[ip];
299  //printf("RJH: ip=%d lon=%lf lat=%lf solz=%lf sola=%lf senz=%lf sena=%lf\n",ip,lon[ip],lat[ip], solz[ip],sola[ip],senz[ip],sena[ip] );
300  }
301 
302  // read in radiance data
303  rad_data = (float *) calloc(npix*nbands, sizeof (float));
304 
305  start[0] = 0;
306  start[1] = scan;
307  start[2] = 0;
308  count[0] = nbands;
309  count[1] = 1;
310  count[2] = npix;
311 
312  nc_inq_ncid(file->sd_id, "observation_data", &grp_id);
313 
314  retval = nc_inq_varid(grp_id, "Lt", &band_id);
315  retval = nc_get_vara_float(grp_id, band_id, start, count, rad_data);
316  if (retval != NC_NOERR) {
317  fprintf(stderr,
318  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
319  __FILE__, __LINE__, file->name, "Lt_visnir");
320  return (1);
321  }
322 
323  for (ib = 0; ib < nbands; ib++) {
324 
325  // copy to Lt record.
326  for (ip = spix; ip < npix; ip++) {
327  ipb = ip * nbands + ib;
328  Ibp = ib * npix + ip;
329  l1rec->Lt[ipb] = rad_data[Ibp];
330 
331  // mark negative input data as HILT
332  // navfail commented out for Lt < 0 - too limiting for hyperspectral - RJH
333  if (l1rec->Lt[ipb] < 0.0) {
334  l1rec->Lt[ipb] = 0.0001;
335  // l1rec->navfail[ip] = 1;
336  } else if (l1rec->Lt[ipb] > 0) {
337  // printf("scan=%d ip=%d Lt>0 %f \n",scan,ip,l1rec->Lt[ipb]);
338  }
339  }
340  } // for ib
341 
342  l1rec->alt = alt[scan] / 1000.; //convert to km
343 
344  free(rad_data);
345  free(lat);
346  free(lon);
347  free(solz);
348  free(sola);
349  free(senz);
350  free(sena);
351 
352  l1rec->l1file->sensorID = file->sensorID;
353  l1rec->npix = file->npix;
354 
355  return (LIFE_IS_GOOD);
356 }
357 
358 int closel1_aviris_nc(filehandle *file) {
359  int retval;
360  aviris_t *data = file->private_data;
361 
362  retval = nc_close(file->sd_id);
363  if (retval != NC_NOERR) {
364  fprintf(stderr, "-E- %s line %d: nc_close failed for file, %s.\n",
365  __FILE__, __LINE__, file->name);
366  return (1);
367  }
368  free(scan_start_tai);
370  free(file->private_data);
371 
372  return (LIFE_IS_GOOD);
373 }
374 
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
float * lat
int32 nscan
Definition: l1_czcs_hdf.c:19
float fwhm[NBANDS]
Definition: atrem_corl1.h:144
#define AV_MAXBANDS
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 readl1_aviris_nc(filehandle *file, int32_t scan, l1str *l1rec)
Definition: l1_aviris_nc.c:161
int want_verbose
int openl1_aviris_nc(filehandle *file)
Definition: l1_aviris_nc.c:21
int closel1_aviris_nc(filehandle *file)
Definition: l1_aviris_nc.c:358
aviris_t * createPrivateData_aviris(int numBands)
Definition: l1_aviris.c:30
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
int32_t nbands
int32_t iscan
float * lon
void freePrivateData_aviris(aviris_t *data)
Definition: l1_aviris.c:53
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")
int npix
Definition: get_cmp.c:27
int count
Definition: decode_rs.h:79