Due to the lapse in federal government funding, NASA is not updating this website. We sincerely regret this inconvenience.
NASA Logo
Ocean Color Science Software

ocssw V2022
avirisbil2oci.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 <unistd.h>
6 
7 #include <sstream>
8 #include <iomanip>
9 #include <stdint.h>
10 #include <iostream>
11 #include <fstream>
12 
13 #include "cdl_utils.h"
14 #include "netcdf.h"
15 #include "nc4utils.h"
16 #include "nc_gridutils.h"
17 #include "aviris.h"
18 #include <timeutils.h>
19 #include <gsl/gsl_errno.h>
20 #include <gsl/gsl_spline.h>
21 #include <gsl/gsl_sort_double.h>
22 
23 #define SENSOR "ocia"
24 #define CDLFILE "OCI_Level-1B_Data_Structure.cdl"
25 #define NBANDS 61 // number of OCI bands
26 #define FILL -32767
27 
28 extern "C" void handle_error(int status);
29 
30 using namespace std;
31 
32 
33 #define VERSION "1.00"
34 
35 size_t interpLt(size_t startJ, size_t npixels, size_t k, size_t nbMax,
36  float ociaWavelength, size_t iwave, aviris4ocia_t* data,
37  gsl_interp_accel* acc, float* Lt) {
38  size_t j, n;
39  size_t i0 = startJ, i1 = startJ + 5;
40  float minWave, maxWave;
41 
42  double* x = (double*) (calloc(nbMax, sizeof (double)));
43  double* y = (double*) (calloc(nbMax, sizeof (double)));
44  size_t iter = 0;
45  while (i0 >= 0 && i1 < nbMax) {
46  n = 0;
47  minWave = 99999;
48  maxWave = -1;
49  for (j = i0; j < i1; j++) {
50  if (data->Lt[j * npixels + k] > 0) {
51  x[n] = data->wave[j];
52  y[n] = data->Lt[j * npixels + k];
53  n++;
54  if (minWave > data->wave[j]) minWave = data->wave[j];
55  if (maxWave < data->wave[j]) maxWave = data->wave[j];
56  }
57  }
58 
59  if (n > 2 && minWave <= ociaWavelength && maxWave >= ociaWavelength) break;
60  if (minWave > ociaWavelength || n < 3)
61  i0--;
62  if (maxWave < ociaWavelength || n < 3)
63  i1++;
64  iter++;
65  }
66  if (n > 2) {
67  // Allocate space for spline
68  gsl_spline* spline = gsl_spline_alloc(gsl_interp_cspline, n);
69  gsl_sort2(x, 1, y, 1, n);
70  if (ociaWavelength > x[0]) {
71  // Sort wavelengths and corresponding Lt values
72  gsl_sort2(x, 1, y, 1, n);
73  // Initiate spline
74  gsl_spline_init(spline, x, y, n);
75  // Generate interpolated values
76  double yi = gsl_spline_eval(spline, ociaWavelength, acc);
77  Lt[iwave * npixels + k] = yi;
78  } else {
79  Lt[iwave * npixels + k] = FILL;
80  }
81  iwave++;
82  gsl_spline_free(spline);
83  }
84  free(x);
85  free(y);
86  return iwave;
87 }
88 
89 // Modification history:
90 // Programmer Organization Date Ver Description of change
91 // ---------- ------------ ---- --- ---------------------
92 // Joel Gales FutureTech 12/18/14 0.01 Original development
93 // Joel Gales FutureTech 01/12/15 0.10 Add support for writing
94 // interpolated ORCA Lt values
95 // and navigation
96 // Rick Healy SAIC 06/06/16 1.00 Integrated L2gen L1 reader for Aviris
97 
98 int main(int argc, char* argv[]) {
99  int status;
100  size_t sline = 0, eline = 0;
101  char filename[FILENAME_MAX], hdrfile[FILENAME_MAX], imgfile[FILENAME_MAX],
102  navfile[FILENAME_MAX], gainfile[FILENAME_MAX];
103  ;
104  char *filedir;
105  double scantime_first, scantime_last;
106  static int first_good_scantime = 0;
107  cout << "avirisbil2oci " << VERSION << " ("
108  << __DATE__ << " " << __TIME__ << ")" << endl;
109 
110  if (argc < 3) {
111  cout << endl <<
112  "avirisbil2oci input_AVIRIS_file output_OCIA_file <sline (default=0)> <eline (default=last row) <img file(optional)> <nav file(optional)> <gain file(optional)>>"
113  << endl;
114  return 0;
115  }
116 
117  if (argc >= 4) {
118  sscanf(argv[3], "%ld", &sline);
119  if (sline < 0) sline = 0;
120  }
121 
122  if (argc >= 5) {
123  sscanf(argv[4], "%ld", &eline);
124  if (eline < 0) eline = 0;
125  }
126  if (argc >= 6) {
127  sscanf(argv[5], "%s", imgfile);
128  if (eline < 0) eline = 0;
129  }
130  if (argc >= 7) {
131  sscanf(argv[6], "%s", navfile);
132  if (eline < 0) eline = 0;
133  }
134  if (argc >= 8) {
135  sscanf(argv[7], "%s", gainfile);
136  if (eline < 0) eline = 0;
137  }
138  // aviris4orca_t *&data;
139 
140  if ((filedir = getenv("OCDATAROOT")) == NULL) {
141  printf("-E- %s: OCDATAROOT env variable undefined.\n", __FILE__);
142  return (-1);
143  }
144  strcpy(filename, filedir);
145 
146  strcat(filename, "/");
147  strcat(filename, SENSOR);
148  strcat(filename, "/");
149 
150  strcat(filename, CDLFILE);
151 
152  if (!checkAvProcessFile(argv[1], hdrfile, imgfile, navfile, gainfile, FILENAME_MAX))
153  strncpy(hdrfile, argv[1], FILENAME_MAX);
154 
155  aviris4ocia_t **data, *temp;
156  float fwhm[NBANDS];
157  data = (aviris4ocia_t **) malloc(sizeof (aviris4ocia_t *));
158  temp = open_aviris(hdrfile, imgfile, navfile, gainfile, data);
159  size_t nscans, ip, npixels = temp->npix;
160 
161  if (eline <= 0) eline = temp->nscans;
162 
163  if (eline == sline && sline > 0) sline--;
164  nscans = eline - sline;
165 
166  int ncid, grpID;
167  //char** dim_names, uint32_t* dim_size, size_t n_dims
168  const char *dimNames[] = {"number_of_scans", "number_of_pixels", "number_of_bands"};
169  size_t dimSize[] = {nscans, npixels, NBANDS};
170  size_t n_dims = 3;
171 
172  // Create ORCA output file
173  static ncdfFile ociafile;
174  ociafile.cdlCreateDim(argv[2], filename, dimNames, dimSize, n_dims, nscans);
175 
176  // nc_def_dim(orcafile.ncid, "number_of_lines", nscans, &dimid[0]);
177  // nc_def_dim(orcafile.ncid, "pixels_per_line", nscans, &dimid[1]);
178  //
179  // Copy AVIRIS nav fields to ORCA
180  //
181  ncid = ociafile.getNcid();
182 
183  size_t nbands_av = temp->numBands;
184  size_t nbands_ocia = NBANDS;
185 
186  size_t n = 0, iwave = 0;
187  istringstream istr;
188  string str;
189  char isodatetime_first[30], isodatetime_last[30];
190 
191  // Allocate space for AVIRIS Lt (short) values
192  // size_t start[3] = {0,0,0};
193  // size_t count[3] = {1,npixels,0};
194 
195  gsl_interp_accel *acc = gsl_interp_accel_alloc();
196 
197  float *Lt = (float *) calloc(npixels*nbands_ocia, sizeof (float));
198  float *ociaWavelength = (float *) calloc(nbands_ocia, sizeof (float));
199  double* utc = (double*) (calloc(nscans, sizeof (double)));
200  float* alt = (float*) (calloc(nscans, sizeof (float)));
201  size_t j;
202 
203  grpID = ociafile.getGid("observation_data");
204 
205  for (size_t iscan = sline; iscan < eline; iscan++) {
206 
207 
208  // Read AVIRIS Lt's for this scan
209  if (read_aviris(temp, iscan)) {
210 
211  cout << "Can't read file " << argv[1] << endl;
212  exit(1);
213 
214  }
215  for (ip = 0; ip < npixels; ip++) for (iwave = 0; iwave < nbands_ocia; iwave++) Lt[iwave * npixels + ip] = FILL;
216 
217  if ((iscan % 100) == 0) {
218  cout << "Processing scan: " << iscan << " out of " << nscans << endl;
219  //printf("year=%d doy=%d msec=%d month=%d day=%d hour=%d min=%d sec=%f\n ",temp->year, temp->doy, temp->msec,temp->month,temp->day,temp->hour,temp->min,temp->sec);
220  }
221  // For each pixel in scan ...
222  for (size_t k = 0; k < npixels; k++) {
223 
224  // Get number of good AVIRIS wavelengths for each pixel
225  n = 0;
226  j = 0;
227  for (j = 0; j < nbands_av; j++) {
228  if (temp->Lt[j * npixels + k] > 0) n++;
229  }
230 
231  // Bail if no good AVIRIS Lt values
232  if (n == 0) continue;
233 
234 
235  // Generate x & y arrays for spline
236  // x - AVIRIS wavelengths
237  // y - AVIRIS Lt values
238  iwave = 0;
239  for (j = 0; j < 31; j++) {
240  if (temp->Lt[j * npixels + k] > 0) {
241  ociaWavelength[iwave] = temp->wave[j];
242  Lt[iwave * npixels + k] = temp->Lt[j * npixels + k];
243  fwhm[iwave] = temp->fwhm[j];
244  }
245  iwave++;
246  }
247  for (j = 33; j < 57; j++) {
248  if (temp->Lt[j * npixels + k] > 0) {
249  ociaWavelength[iwave] = temp->wave[j];
250  Lt[iwave * npixels + k] = temp->Lt[j * npixels + k];
251  fwhm[iwave] = temp->fwhm[j];
252  }
253  iwave++;
254  }
255 
256  ociaWavelength[iwave] = 936.646;
257  fwhm[iwave] = 32.4702967;
258  Lt[iwave * npixels + k] = (11.9269624 * temp->Lt[60 * npixels + k] +
259  10.78153 * temp->Lt[61 * npixels + k] +
260  9.76180425 * temp->Lt[62 * npixels + k]) / fwhm[iwave];
261  iwave++;
262 
263  ociaWavelength[iwave] = 1238.750;
264  fwhm[iwave] = 20.3179033;
265  Lt[iwave * npixels + k] = (10.1448143 * temp->Lt[92 * npixels + k] +
266  10.173089 * temp->Lt[93 * npixels + k]) / fwhm[iwave];
267  iwave++;
268 
269  Lt[iwave * npixels + k] = temp->Lt[109 * npixels + k];
270  fwhm[iwave] = temp->fwhm[109];
271  ociaWavelength[iwave] = temp->wave[109];
272  iwave++;
273 
274  ociaWavelength[iwave] = 1641.530;
275  fwhm[iwave] = 53.6097915;
276  Lt[iwave * npixels + k] = (10.7227049 * temp->Lt[133 * npixels + k] +
277  10.7221941 * temp->Lt[134 * npixels + k] +
278  10.7218208 * temp->Lt[135 * npixels + k] +
279  10.721585 * temp->Lt[136 * npixels + k] +
280  10.7214867 * temp->Lt[137 * npixels + k]) / fwhm[iwave];
281  iwave++;
282  //iwave = interpLt(133, npixels, k, nbands_av, orcaWavelength[iwave], iwave, temp, acc,Lt);
283  ociaWavelength[iwave] = 2126.795;
284  fwhm[iwave] = 54.1850639;
285  Lt[iwave * npixels + k] = (10.8702638 * temp->Lt[184 * npixels + k] +
286  10.8539551 * temp->Lt[185 * npixels + k] +
287  10.8373296 * temp->Lt[186 * npixels + k] +
288  10.8203873 * temp->Lt[187 * npixels + k] +
289  10.8031281 * temp->Lt[188 * npixels + k]) / fwhm[iwave];
290  iwave++;
291  //iwave = interpLt(184, npixels, k, nbands_av, orcaWavelength[iwave], iwave, temp, acc,Lt);
292  ociaWavelength[iwave] = 2246.658;
293  fwhm[iwave] = 53.0639591;
294  Lt[iwave * npixels + k] = (10.6536474 * temp->Lt[196 * npixels + k] +
295  10.6335365 * temp->Lt[197 * npixels + k] +
296  10.6131087 * temp->Lt[198 * npixels + k] +
297  10.592364 * temp->Lt[199 * npixels + k] +
298  10.5713025 * temp->Lt[200 * npixels + k]) / fwhm[iwave];
299  iwave++;
300  //iwave = interpLt(196, npixels, k, nbands_av, orcaWavelength[iwave], iwave, temp, acc,Lt);
301 
302 
303  } // pixel loop
304 
305  if (NBANDS != iwave) {
306  printf("Oops, something's wrong iwave (%d) != nbands (%d) \n", (int) iwave, NBANDS);
307  exit(-1);
308  }
309  // Write Lt's
310  // for (size_t iwave=0; iwave<nbands_ocia; iwave++ ) {
311  int varID;
312 
313  // printf("Lambda(%d) = %d\n",iwave+1,(int)(orcaWavelength[iwave]+.5));
314  status = nc_inq_varid(grpID, "Lt", &varID);
315  check_err(status, __LINE__, __FILE__);
316 
317  size_t start[3] = {0, iscan, 0};
318  size_t count[3] = {nbands_ocia, 1, npixels};
319  status = nc_put_vara_float(grpID, varID, start, count,
320  &Lt[0]);
321  // &Lt[iwave*npixels]);
322  check_err(status, __LINE__, __FILE__);
323  // }
324  alt[iscan] = temp->alt[iscan];
325  utc[iscan] = temp->scantime;
326  if (temp->scantime > 0) {
327  scantime_last = temp->scantime;
328  if (!first_good_scantime) {
329  first_good_scantime = 1;
330  scantime_first = temp->scantime;
331  // printf("utc=%f\n",utc[iscan]);
332  // strncpy(isodatetime_first,unix2isodate(scantime_first, 'G'),30);
333  // printf("%s\n",isodatetime_first);
334  }
335  // strncpy(isodatetime_last,unix2isodate(scantime_last, 'G'),30);
336  // printf("Last=%s\n",isodatetime_last);
337  }
338 
339 
340  } // scan loop
341  int varID;
342 
343  if (scantime_first < scantime_last) {
344  strncpy(isodatetime_first, unix2isodate(scantime_first, 'G'), 30);
345  strncpy(isodatetime_last, unix2isodate(scantime_last, 'G'), 30);
346  } else {
347  strncpy(isodatetime_last, unix2isodate(scantime_first, 'G'), 30);
348  strncpy(isodatetime_first, unix2isodate(scantime_last, 'G'), 30);
349  }
350  status = nc_put_att_text(ncid, NC_GLOBAL, "time_coverage_start", strlen(isodatetime_first) + 1, isodatetime_first);
351  if (status != NC_NOERR) {
352  printf("-E- %s %d: %s for %s\n",
353  __FILE__, __LINE__, nc_strerror(status), "time_coverage_start");
354  exit(1);
355  }
356  status = nc_put_att_text(ncid, NC_GLOBAL, "time_coverage_end", strlen(isodatetime_last) + 1, isodatetime_last);
357  if (status != NC_NOERR) {
358  printf("-E- %s %d: %s for %s\n",
359  __FILE__, __LINE__, nc_strerror(status), "time_coverage_end");
360  exit(1);
361  }
362 
363  const char *navfieldsAVIRIS[] = {"to-sensor_azimuth", "to-sensor_zenith", "to-sun_azimuth", "to-sun_zenith", "lat", "lon"};
364  const char *navfieldsOCIA[] = {"sensor_azimuth", "sensor_zenith", "solar_azimuth", "solar_zenith", "latitude", "longitude"};
365 
366  grpID = ociafile.getGid("geolocation_data");
367 
368  size_t startOCIA[2] = {0, 0};
369  size_t countOCIA[2] = {nscans, npixels};
370  size_t i;
371 
372  for (i = 0; i < 6; i++) {
373  cout << "Copying " << navfieldsAVIRIS[i] << " to " <<
374  navfieldsOCIA[i] << endl;
375 
376  status = nc_inq_varid(grpID, navfieldsOCIA[i], &varID);
377  check_err(status, __LINE__, __FILE__);
378 
379  switch (i) {
380  case 0:
381  status = nc_put_vara_float(grpID, varID, startOCIA, countOCIA, &temp->sena[sline * npixels]);
382  check_err(status, __LINE__, __FILE__);
383  break;
384  case 1:
385  status = nc_put_vara_float(grpID, varID, startOCIA, countOCIA, &temp->senz[sline * npixels]);
386  check_err(status, __LINE__, __FILE__);
387  break;
388  case 2:
389  status = nc_put_vara_float(grpID, varID, startOCIA, countOCIA, &temp->sola[sline * npixels]);
390  check_err(status, __LINE__, __FILE__);
391  break;
392  case 3:
393  status = nc_put_vara_float(grpID, varID, startOCIA, countOCIA, &temp->solz[sline * npixels]);
394  check_err(status, __LINE__, __FILE__);
395  break;
396  case 4:
397  status = nc_put_vara_double(grpID, varID, startOCIA, countOCIA, &temp->lat[sline * npixels]);
398  check_err(status, __LINE__, __FILE__);
399  break;
400  case 5:
401  status = nc_put_vara_double(grpID, varID, startOCIA, countOCIA, &temp->lon[sline * npixels]);
402  check_err(status, __LINE__, __FILE__);
403  break;
404  default:
405  break;
406  }
407  }
408 
409  gsl_interp_accel_free(acc);
410 
411  size_t startw[2] = {0, 0};
412  size_t countw[2] = {nbands_ocia, 0};
413 
414  grpID = ociafile.getGid("sensor_band_parameters");
415 
416  status = nc_inq_varid(grpID, "wavelength", &varID);
417 
418  status = nc_put_vara_float(grpID, varID, startw, countw, ociaWavelength);
419  check_err(status, __LINE__, __FILE__);
420 
421  status = nc_inq_varid(grpID, "fwhm", &varID);
422 
423  status = nc_put_vara_float(grpID, varID, startw, countw, fwhm);
424  check_err(status, __LINE__, __FILE__);
425 
426  size_t starts[2] = {0, 0};
427  size_t counts[2] = {nscans, 0};
428 
429  const char *nscanfieldsAVIRIS[] = {"utc", "alt"};
430  const char *nscanfieldsOCIA[] = {"scan_start_time","altitude"};
431 
432  for (i = 0; i < nscans; i++) {
433  //utc[i] = temp->scantime;
434  //alt[i] = temp->alt[sline + i]*1000;
435  }
436  grpID = ociafile.getGid("scan_line_attributes");
437  countOCIA[1] = 0;
438  for (i = 0; i < 2; i++) {
439  cout << "Copying " << nscanfieldsAVIRIS[i] << " to " <<
440  nscanfieldsOCIA[i] << endl;
441 
442  status = nc_inq_varid(grpID, nscanfieldsOCIA[i], &varID);
443  check_err(status, __LINE__, __FILE__);
444 
445  switch (i) {
446  case 0:
447  status = nc_put_vara_double(grpID, varID, starts, counts, utc);
448  check_err(status, __LINE__, __FILE__);
449  break;
450  case 1:
451  status = nc_put_vara_float(grpID, varID, starts, counts, alt);
452  check_err(status, __LINE__, __FILE__);
453  break;
454  default:
455  break;
456  }
457  }
458 
459  // outfile.close();
460 
461  status = close_aviris(temp);
462 
463  return 0;
464 }
#define VERSION
int j
Definition: decode_rs.h:73
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
int close_aviris(aviris4ocia_t *data)
Definition: read_aviris.c:822
int main(int argc, char *argv[])
#define NULL
Definition: decode_rs.h:63
size_t interpLt(size_t startJ, size_t npixels, size_t k, size_t nbMax, float ociaWavelength, size_t iwave, aviris4ocia_t *data, gsl_interp_accel *acc, float *Lt)
subroutine spline(s, x, y, n, in, t, il, iu, vl, vu, e, u)
Definition: phs.f:1348
uint8 * counts
Definition: l1_czcs_hdf.c:30
aviris4ocia_t * open_aviris(char *filename, char *imgfile, char *navfile, char *gainfile, aviris4ocia_t **data)
Definition: read_aviris.c:175
int checkAvProcessFile(char *filename, char *hdrfile, char *imgfile, char *navfile, char *gainfile, int itemsize)
Definition: read_aviris.c:831
float fwhm[NBANDS]
Definition: atrem_corl1.h:144
int getGid(const char *grpName)
Definition: cdl_utils.cpp:736
int read_aviris(aviris4ocia_t *data, int32_t recnum)
Definition: read_aviris.c:710
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
SENSOR
Definition: DDProcess.h:81
#define CDLFILE
int32_t iscan
char * unix2isodate(double dtime, char zone)
Definition: unix2isodate.c:10
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
#define NBANDS
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
#define FILL
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 k
Definition: decode_rs.h:73
void handle_error(int status)
Definition: nccmp.c:219
#define str(s)
int count
Definition: decode_rs.h:79