OB.DAAC Logo
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
const char * str
Definition: l1c_msi.cpp:35
#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
int count
Definition: decode_rs.h:79