OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
aviris2orca.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 "dfutils.h"
16 #include "nc_gridutils.h"
17 
18 #include <gsl/gsl_errno.h>
19 #include <gsl/gsl_spline.h>
20 #include <gsl/gsl_sort_double.h>
21 
22 
23 extern "C" void handle_error(int status);
24 
25 using namespace std;
26 
27 
28 #define VERSION "0.10"
29 
30 // Modification history:
31 // Programmer Organization Date Ver Description of change
32 // ---------- ------------ ---- --- ---------------------
33 // Joel Gales FutureTech 12/18/14 0.01 Original development
34 // Joel Gales FutureTech 01/12/15 0.10 Add support for writing
35 // interpolated ORCA Lt values
36 // and navigation
37 
38 int main(int argc, char* argv[]) {
39  int status;
40 
41  cout << "aviris2orca " << VERSION << " ("
42  << __DATE__ << " " << __TIME__ << ")" << endl;
43 
44  if (argc == 1) {
45  cout << endl <<
46  "aviris2orca input_AVIRIS_file output_ORCA_file ORCA_CDL_structure_file"
47  << endl;
48  return 0;
49  }
50 
51  // Open AVIRIS file
52  idDS aviris_id = openDS(argv[1]);
53 
54  size_t nscans, npixels;
55  int dimid;
56  int grpID;
57 
58  // Get number of pixels (per scan) in AVIRIS file
59  status = nc_inq_dimid(aviris_id.fid, "x", &dimid);
60  if (status != NC_NOERR) {
61  cout << "Can't find 'x' dimension in: " << argv[1] << endl;
62  exit(1);
63  }
64  status = nc_inq_dimlen(aviris_id.fid, dimid, &npixels);
65 
66  // Get number of scans in AVIRIS file
67  status = nc_inq_dimid(aviris_id.fid, "y", &dimid);
68  if (status != NC_NOERR) {
69  cout << "Can't find 'y' dimension in: " << argv[1] << endl;
70  exit(1);
71  }
72  status = nc_inq_dimlen(aviris_id.fid, dimid, &nscans);
73 
74  // Create ORCA output file
75  static ncdfFile orcafile;
76  orcafile.cdlCreate(argv[2], argv[3], nscans);
77 
78  //
79  // Copy AVIRIS nav fields to ORCA
80  //
81  char *navfieldsAVIRIS[] = {"to-sensor_azimuth", "to-sensor_zenith",
82  "to-sun_azimuth", "to-sun_zenith",
83  "lat", "lon"};
84  char *navfieldsORCA[] = {"sena", "senz", "sola", "solz", "lat", "lon"};
85 
86  float *navbuffer = (float *) calloc(nscans*npixels, sizeof (float));
87  grpID = orcafile.getGid("navigation_data");
88  int varID;
89 
90  int startAVIRIS[2] = {0, 0};
91  int countAVIRIS[2] = {nscans, npixels};
92  size_t startORCA[2] = {0, 0};
93  size_t countORCA[2] = {nscans, npixels};
94 
95  for (size_t i = 0; i < 6; i++) {
96  cout << "Copying " << navfieldsAVIRIS[i] << " to " <<
97  navfieldsORCA[i] << endl;
98 
99  PTB(readDS(aviris_id, navfieldsAVIRIS[i],
100  startAVIRIS, NULL, countAVIRIS, navbuffer));
101 
102  status = nc_inq_varid(grpID, navfieldsORCA[i], &varID);
103  check_err(status, __LINE__, __FILE__);
104 
105  status = nc_put_vara_float(grpID, varID, startORCA, countORCA, navbuffer);
106  check_err(status, __LINE__, __FILE__);
107  }
108 
109  // Compute attitude from path_length and cos(sensor zenith angle)
110  float *plbuffer = (float *) calloc(nscans*npixels, sizeof (float));
111  PTB(readDS(aviris_id, "path_length",
112  startAVIRIS, NULL, countAVIRIS, plbuffer));
113  PTB(readDS(aviris_id, "to-sensor_zenith",
114  startAVIRIS, NULL, countAVIRIS, navbuffer));
115  float deg2rad = 3.1415927 / 180;
116  for (size_t j = 0; j < nscans * npixels; j++) {
117  if (navbuffer[j] == -9999)
118  plbuffer[j] = -9999;
119  else
120  plbuffer[j] *= cos(deg2rad * navbuffer[j]);
121  }
122  status = nc_inq_varid(grpID, "altitude", &varID);
123  check_err(status, __LINE__, __FILE__);
124 
125  status = nc_put_vara_float(grpID, varID, startORCA, countORCA, plbuffer);
126  check_err(status, __LINE__, __FILE__);
127 
128 
129  // Get number of datasets in AVIRIS file
130  int n_datasets;
131  status = nc_inq(aviris_id.fid, NULL, &n_datasets, NULL, NULL);
132 
133  // Allocate space for AVIRIS Lt dataset IDs, wavelengths, and scale factors
134  int *varLtid = (int *) calloc(n_datasets, sizeof (int));
135  float *avirisWavelength = (float *) calloc(n_datasets, sizeof (float));
136  double *scale_factor = (double *) calloc(n_datasets, sizeof (double));
137 
138  size_t n = 0;
139  istringstream istr;
140  string str;
141  int att_type;
142  size_t typeSize;
143  char nambuf[NC_MAX_NAME];
144 
145  for (size_t i = 0; i < n_datasets; i++) {
146  nc_inq_varname(aviris_id.fid, i, nambuf);
147 
148  // If Lt dataset ...
149  if (strncmp(nambuf, "Lt_", 3) == 0) {
150 
151  // Store dataset ID
152  varLtid[n] = i;
153 
154  printf("Nambuf=%s %d\n", nambuf, varLtid[n]);
155  // Store AVIRIS wavelength
156  str.assign(nambuf);
157  str.replace(str.find_first_of('_', 3), 1, ".");
158  istr.clear();
159  istr.str(str.substr(3, string::npos));
160  istr >> avirisWavelength[n];
161 
162  // status = nc_inq_atttype( aviris_id.fid, i, "scale_factor", &att_type);
163  //status = nc_inq_type( aviris_id.fid, att_type, nambuf, &typeSize);
164 
165  // Store scale factors
166  status = nc_get_att_double(aviris_id.fid, i, "scale_factor",
167  &scale_factor[n]);
168  n++;
169  }
170  }
171  int n_Lt_datasets = n;
172 
173  // Allocate space for AVIRIS Lt (short) values
174  int start[2] = {0, 0};
175  int count[2] = {1, npixels};
176  int16_t *sval = (int16_t *) calloc(npixels*n_Lt_datasets, sizeof (int16_t));
177 
178  gsl_interp_accel *acc = gsl_interp_accel_alloc();
179 
180  size_t n_refl_bands = 91; // Wavelength <= 800nm
181  size_t n_ir_bands = 6; // Wavelength >= 940nm
182 
183  int orcaWavelength[] ={350, 355, 360, 365, 370, 375, 380, 385, 390, 395, 400, 405, 410, 415,
184  420, 425, 430, 435, 440, 445, 450, 455, 460, 465, 470, 475, 480, 485,
185  490, 495, 500, 505, 510, 515, 520, 525, 530, 535, 540, 545, 550, 555,
186  560, 565, 570, 575, 580, 585, 590, 595, 600, 605, 610, 615, 620, 625,
187  630, 635, 640, 645, 650, 655, 660, 665, 670, 675, 680, 685, 690, 695,
188  700, 705, 710, 715, 720, 725, 730, 735, 740, 745, 750, 755, 760, 765,
189  770, 775, 780, 785, 790, 795, 800, 940, 1240, 1378, 1640, 2130, 2250, 0};
190 
191  float *visnir = (float *) calloc(npixels*n_refl_bands, sizeof (float));
192  float *ir = (float *) calloc(npixels*n_ir_bands, sizeof (float));
193 
194  grpID = orcafile.getGid("earth_view_data");
195 
196  for (size_t iscan = 0; iscan < nscans; iscan++) {
197 
198  if ((iscan % 100) == 0)
199  cout << "Processing scan: " << iscan << " out of " << nscans << endl;
200 
201  for (size_t j = 0; j < npixels * n_refl_bands; j++) visnir[j] = -999.0;
202 
203  // Read AVIRIS Lt datasets for this scan
204  start[0] = iscan;
205  for (size_t j = 0; j < n_Lt_datasets; j++) {
206  printf("max=%d j=%d varid=%d\n", n_Lt_datasets, j, varLtid[j]);
207  nc_inq_varname(aviris_id.fid, varLtid[j], nambuf);
208  PTB(readDS(aviris_id, nambuf, start, NULL, count, &sval[j * npixels]));
209  }
210 
211  // For each pixel in scan ...
212  for (size_t k = 0; k < npixels; k++) {
213 
214  // Get number of good AVIRIS wavelengths for each pixel
215  n = 0;
216  for (size_t j = 0; j < n_Lt_datasets; j++) {
217  if (sval[j * npixels + k] > 0) n++;
218  }
219 
220  // Bail if no good AVIRIS Lt values
221  if (n == 0) continue;
222 
223  // Allocate space for spline
224  gsl_spline *spline = gsl_spline_alloc(gsl_interp_cspline, n);
225  double *x = (double *) calloc(n, sizeof (double));
226  double *y = (double *) calloc(n, sizeof (double));
227 
228  // Generate x & y arrays for spline
229  // x - AVIRIS wavelengths
230  // y - AVIRIS Lt values
231  n = 0;
232  for (size_t j = 0; j < n_Lt_datasets; j++) {
233  if (sval[j * npixels + k] > 0) {
234  x[n] = avirisWavelength[j];
235  y[n] = sval[j * npixels + k] * scale_factor[j];
236  n++;
237  }
238  }
239 
240  // Sort wavelenghts and corresponding Lt values
241  gsl_sort2(x, 1, y, 1, n);
242 
243  // Initiate spline
244  gsl_spline_init(spline, x, y, n);
245 
246  // Generate interpolated values
247  size_t iwave = 0;
248  while (orcaWavelength[iwave] != 0) {
249  if (orcaWavelength[iwave] > x[0] &&
250  orcaWavelength[iwave] < x[n - 1]) {
251  double yi = gsl_spline_eval(spline, orcaWavelength[iwave], acc);
252  if (orcaWavelength[iwave] <= 800)
253  visnir[iwave * npixels + k] = yi;
254  else
255  ir[(iwave - n_refl_bands) * npixels + k] = yi;
256  // cout << setw(6);
257  //cout << orcaWavelength[iwave] << " ";
258  //cout << setw(10) << setprecision(5) << fixed << yi << endl;
259  }
260  iwave++;
261  }
262 
263  free(x);
264  free(y);
265  gsl_spline_free(spline);
266 
267  } // pixel loop
268 
269  // Write vis & nir bands to Lt_visnir
270  for (size_t iwave = 0; iwave < n_refl_bands; iwave++) {
271  int varID;
272  status = nc_inq_varid(grpID, "Lt_visnir", &varID);
273  check_err(status, __LINE__, __FILE__);
274 
275  size_t start[3] = {iwave, iscan, 0};
276  size_t count[3] = {1, 1, npixels};
277  status = nc_put_vara_float(grpID, varID, start, count,
278  &visnir[iwave * npixels]);
279  check_err(status, __LINE__, __FILE__);
280  }
281 
282  // Write irbands to Lt_xxxx (xxxx=940,1240,1378,1640,2130,2250)
283  char *irLt[] = {"Lt_940", "Lt_1240", "Lt_1378",
284  "Lt_1640", "Lt_2130", "Lt_2250"};
285 
286  for (size_t iwave = 0; iwave < n_ir_bands; iwave++) {
287  int varID;
288  status = nc_inq_varid(grpID, irLt[iwave], &varID);
289  check_err(status, __LINE__, __FILE__);
290 
291  size_t start[2] = {iscan, 0};
292  size_t count[2] = {1, npixels};
293  status = nc_put_vara_float(grpID, varID, start, count,
294  &ir[iwave * npixels]);
295  check_err(status, __LINE__, __FILE__);
296  }
297 
298  } // scan loop
299 
300  gsl_interp_accel_free(acc);
301 
302  // outfile.close();
303 
304  status = endDS(aviris_id);
305 
306  free(visnir);
307  free(ir);
308 
309  free(varLtid);
310  free(avirisWavelength);
311  free(scale_factor);
312  free(sval);
313 
314  return 0;
315 }
int main(int argc, char *argv[])
Definition: aviris2orca.cpp:38
int j
Definition: decode_rs.h:73
int status
Definition: l1_czcs_hdf.c:32
void check_err(const int stat, const int line, const char *file)
Definition: nc4utils.c:35
idDS openDS(const char *filename)
Definition: wrapper.c:616
void handle_error(int status)
Definition: nccmp.c:219
#define NULL
Definition: decode_rs.h:63
const double deg2rad
subroutine spline(s, x, y, n, in, t, il, iu, vl, vu, e, u)
Definition: phs.f:1348
int cdlCreate(char *l1_filename, char *cdl_filename, int32_t numScans)
Definition: cdl_utils.cpp:26
int getGid(const char *grpName)
Definition: cdl_utils.cpp:736
#define VERSION
Definition: aviris2orca.cpp:28
#define PTB(function)
Definition: passthebuck.h:16
int readDS(idDS ds_id, const char *name, int32_t *start, int32_t *stride, int32_t *count, void *data)
const char * str
Definition: l1c_msi.cpp:35
int32_t iscan
int32_t fid
Definition: dfutils.h:29
Definition: dfutils.h:28
int endDS(idDS ds_id)
Definition: wrapper.c:634
int i
Definition: decode_rs.h:71
int k
Definition: decode_rs.h:73
int count
Definition: decode_rs.h:79