OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
read_aviris.c
Go to the documentation of this file.
1 /*
2  * l1_aviris.c
3  *
4  * Created on: May 18, 2015
5  * Author: Rick Healy SAIC
6  * NASA-GSFC OBPG
7  */
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <proj.h>
12 #include "timeutils.h"
13 #include "aviris.h"
14 #include "jplaeriallib.h"
15 #include <math.h>
16 #include <genutils.h>
17 #include <libnav.h>
18 
19 
20 #define SKIP -9999
21 
22 
23 static const int maxBands = 224;
24 
25 void freePrivateData_ocia(aviris4ocia_t* data) {
26  free(data->wave);
27  free(data->fwhm);
28  free(data->gain);
29  free(data->sena);
30  free(data->senz);
31  free(data->sola);
32  free(data->solz);
33  free(data->utc);
34  gsl_interp_accel_free(data->spl_acc);
35 
36 }
37 
38 float getValidAngleB(float *ang, int32_t npix, int32_t skip, float *fillangle) {
39  int32_t i;
40  float angle = *fillangle;
41 
42  for (i = 0; i < npix && ang[i] <= skip; i++)
43  angle = ang[i];
44 
45  *fillangle = angle;
46  return (angle);
47 
48 }
49 
50 void aviris4ocia_proj4_convert(aviris4ocia_t *data, int32_t numPoints, double *x, double *y) {
51  int i;
52  PJ_COORD c, c_out;
53 
54  // set default z and t
55  c.xyzt.z = 0.0;
56  c.xyzt.t = HUGE_VAL;
57 
58  for (i = 0; i < numPoints; i++) {
59  c.xy.x = x[i];
60  c.xy.y = y[i];
61  c_out = proj_trans(data->pj, PJ_FWD, c);
62  x[i] = c_out.xy.x;
63  y[i] = c_out.xy.y;
64  }
65 }
66 
67 void get_nav_data(char* navfile, int32_t nscans, int32_t npix, aviris4ocia_t* data) {
68 
69  FILE* ptr;
70  double sec;
71  char line[itemSize];
72  float sunpos[3];
73  float latitude, longitude;
74  double secondOfDay;
75  float sunDist;
76  int i, k, ip;
77  int16_t year, hour, minute, doy;
78  char* result;
79  int32_t iyear, idoy;
80  double *range, *lon, *lat;
81  double c0, c1, d0, d1, cov00, cov01, cov11, chisq, dth = 0.00087, th;
82  float xlon, xlat, vel[3], pos[3], pview[3], att[3] = {0, 0, 0}, coef[10],
83  *smat[3];
84  float sena, senz, sola, solz;
85 
86  if (nscans < 2) {
87  fprintf(stderr,
88  "-E- %s line %d: Navigation needs at least 2 scan lines\n",
89  __FILE__, __LINE__);
90  exit(-1);
91  }
92  if ((ptr = fopen(navfile, "r")) == NULL) {
93  fprintf(stderr, "-E- %s line %d: unable to open %s\n", __FILE__,
94  __LINE__, navfile);
95  exit(-1);
96  }
97 
98 
99  range = (double*) malloc(nscans * sizeof (double));
100  lon = (double*) malloc(nscans * sizeof (double));
101  lat = (double*) malloc(nscans * sizeof (double));
102  for (i = 0; i < 3; i++)
103  smat[i] = (float*) malloc(3 * sizeof (float));
104  i = 0;
105  while ((result = fgets(line, itemSize, ptr)) && i < nscans) {
106  if (result == NULL) {
107  fprintf(stderr,
108  "-E- %s line %d: unable to read all of the navigation data from AVIRIS nav file\n",
109  __FILE__, __LINE__);
110  exit(1);
111  }
112  trimBlanks(line);
113  sscanf(line, "%f %f %lf %lf ", &data->utc[i], &data->alt[i], &lat[i],
114  &lon[i]);
115  range[i] = i;
116  i++;
117  }
118  // smooth the digitized lon/lat's
119  gsl_fit_linear(range, 1, lon, 1, nscans, &c0, &c1, &cov00, &cov01, &cov11,
120  &chisq);
121  gsl_fit_linear(range, 1, lat, 1, nscans, &d0, &d1, &cov00, &cov01, &cov11,
122  &chisq);
123  //Get the velocity vector
124  nav_get_vel(d0, d1, c0, c1, vel);
125  for (i = 0; i < nscans; i++) {
126  longitude = c0 + c1 * i;
127  latitude = d0 + d1 * i;
128  hour = (int) (data->utc[i]);
129  minute = (data->utc[i] - hour) * 60;
130  sec = ((data->utc[i] - hour) * 60 - minute) * 60;
131  data->scantime = ymds2unix(data->year, data->month, data->day,
132  (hour * 3600. + minute * 60. + sec));
133  data->hour = hour;
134  data->min = minute;
135  data->sec = sec;
136  //printf("Date:utc=%f sec=%f minute=%d (utc-hour)x60=%d \n",data->utc[i],data->sec,data->min,data->hour );
137  //getPosVecR(latitude,longitude, data->alt[i], pos); // get position vector of sensor
138  unix2yds(data->scantime, &year, &doy, &secondOfDay);
140  nav_gd_orient(pos, vel, att, smat, coef);
141  iyear = (int32_t) year;
142  idoy = (int32_t) doy;
143  l_sun_(&iyear, &idoy, &secondOfDay, sunpos, &sunDist); // get position vector for the sun
144  for (k = 0; k < 3; k++) {
145  sunpos[k] *= 1.496e8; //convert to km for call to get_zenaz
146  //epos[k] = pos[k];
147  }
148  //get_zenaz (epos, longitude, latitude, &data->senz[i*npix], &data->sena[i*npix]);
149  //get_zenaz(sunpos, longitude, latitude, &data->solz[i*npix], &data->sola[i*npix]);
150  for (ip = 0; ip < npix; ip++) {
151  th = (ip - (npix - 1) / 2) * dth;
152  pview[0] = 0;
153  pview[1] = -sin(th);
154  pview[2] = cos(th);
155  nav_get_geonav(sunpos, pos, pview, coef, smat, &xlon, &xlat, &solz,
156  &sola, &senz, &sena);
157  data->lon[i * npix + ip] = xlon;
158  data->lat[i * npix + ip] = xlat;
159  data->senz[i * npix + ip] = senz;
160  data->sena[i * npix + ip] = sena;
161  data->solz[i * npix + ip] = solz;
162  data->sola[i * npix + ip] = sola;
163  // if (ip == 0 || ip == npix/2 || ip == npix-1)
164  // printf("RJH: %d %d %f senz=%f sena=%f solz=%f sola=%f\n", i, ip,
165  // th, data->senz[i * npix + ip],
166  // data->sena[i * npix + ip], data->solz[i * npix + ip],
167  // data->sola[i * npix + ip]);
168  }
169  //if (i % 100 == 0) printf("Calculated Geometry for scan = %d of %d\n",i,nscans);
170  }
171  data->have_nav = 1;
172  return;
173 }
174 
175 aviris4ocia_t *open_aviris(char *filename, char *imgfile, char *navfile, char *gainfile, aviris4ocia_t **data) {
176 
177  FILE *ptr;
178  char tag[itemSize];
179  char *val0;
180  char val[itemSize];
181  char *inbasename, *infile;
182  int i, j, k, status, pos;
183  double *indata, *elev;
184  float *indataf;
185  float rotation;
186  int numBands, num;
187  char* result;
188  char line[itemSize];
189  int16_t year, month, day, hour, minute;
190  int32_t npix, nscans;
191  aviris4ocia_t *temp;
192  int isec = 0;
193  double sec;
194  float valf;
195 
196  char projStr[1024];
197 
198  cdata_(); // initialize global FORTRAN common block data for l_sun call
199 
200  // *data = createPrivateData_av(maxBands);
201  *data = (aviris4ocia_t*) malloc(sizeof (aviris4ocia_t));
202  if (*data == NULL) {
203  fprintf(stderr, "-E- %s line %d: unable to allocate private data for aviris\n",
204  __FILE__, __LINE__);
205  exit(1);
206  }
207 
208  (*data)->wave = (float *) malloc(maxBands * sizeof (float));
209  (*data)->fwhm = (float *) malloc(maxBands * sizeof (float));
210  (*data)->gain = (double *) malloc(maxBands * sizeof (double));
211  if ((*data)->wave == NULL || (*data)->fwhm == NULL) {
212  fprintf(stderr, "-E- %s line %d: unable to allocate scale/offset data for aviris\n",
213  __FILE__, __LINE__);
214  exit(1);
215  }
216 
217  temp = *data;
218  inbasename = getinbasename_av(filename);
219  pos = strlen(inbasename);
220  if (pos <= 0) {
221  fprintf(stderr, "-E- %s line %d: Not a avalid AVIRIS file %s\n",
222  __FILE__, __LINE__, filename);
223  exit(-1);
224  }
225 
226  sscanf(inbasename, "f%2hd%2hd%2hd", &year, &month, &day);
227 
228  if (year >= 92) year += 1900;
229  else year += 2000;
230 
231  sec = 0;
232  hour = 0;
233  minute = 0;
234  isec = (int) sec;
235 
236  temp->month = month;
237  temp->day = day;
238  temp->hour = hour;
239  temp->min = minute;
240  temp->sec = isec;
241  temp->have_nav = 0;
242  temp->have_gain = 0;
243 
244  ymdhms2ydmsec(year, month, day, hour, minute, isec,
245  &temp->year, &temp->doy, &temp->msec);
246 
247  sec -= isec;
248  temp->msec += sec * 1000;
249 
250  printf("Date of AVIRIS flight: Y-%d M-%d D-%d\n", year, month, day);
251 
252  if ((ptr = fopen(filename, "r")) == NULL) {
253  fprintf(stderr, "-E- %s line %d: unable to open %s\n",
254  __FILE__, __LINE__, filename);
255  exit(-1);
256  }
257 
258 
259  int numLinesNeeded = 1;
260  int numSamplesNeeded = 1;
261  int bandsNeeded = 1;
262  int waveLengthNeeded = 1;
263  int fwhmNeeded = 1;
264  int utmZoneNeeded = 1;
265  int eastingNeeded = 1;
266  int northingNeeded = 1;
267  int pixelSizeNeeded = 1;
268  int interleaveNeeded = 1;
269  int rotationAngNeeded = 1;
270 
271  // loop metadata
272  result = fgets(line, itemSize, ptr); // Skip ENVI line and set result
273  while ((numLinesNeeded ||
274  numSamplesNeeded ||
275  bandsNeeded ||
276  fwhmNeeded ||
277  pixelSizeNeeded ||
278  utmZoneNeeded ||
279  eastingNeeded ||
280  northingNeeded ||
281  waveLengthNeeded ||
282  rotationAngNeeded ||
283  interleaveNeeded) && result) {
284 
285  result = fgets(line, itemSize, ptr);
286  if (!result) continue;
287  // if(result == NULL) {
288  // fprintf(stderr,"-E- %s line %d: unable to read all of the required metadata from AVIRIS file\n",
289  // __FILE__,__LINE__);
290  // exit(1);
291  // }
292  trimBlanks(line);
293 
294  if ((val0 = checkTagLine(line, "lines"))) {
295  numLinesNeeded = 0;
296  //nscans = (int)atoi(val0);
297  sscanf(val0, "%d", &nscans);
298  temp->nscans = nscans;
299  }
300  if ((val0 = checkTagLine(line, "samples"))) {
301  numSamplesNeeded = 0;
302  sscanf(val0, "%d", &npix);
303  //npix = (int)atoi(val0);
304  temp->npix = npix;
305  }
306  if ((val0 = checkTagLine(line, "bands"))) {
307  bandsNeeded = 0;
308  //numBands = (int)atoi(val0);
309  sscanf(val0, "%d", &numBands);
310  temp->numBands = numBands;
311  if (numBands > maxBands) {
312  fprintf(stderr, "-E- %s line %d: number of bands (%d) from AVIRIS file > maxBands (%d)\n",
313  __FILE__, __LINE__, numBands, maxBands);
314  exit(1);
315  }
316  }
317  if ((val0 = checkTagLine(line, "interleave"))) {
318  interleaveNeeded = 0;
319  if (strstr(val0, "bip")) {
320  temp->interleave = BIP;
321  } else if (strstr(val0, "bil")) {
322  temp->interleave = BIL;
323  } else {
324  fprintf(stderr, "Interleave = %s is not supported\n", val0);
325  exit(1);
326  }
327  }
328 
329  if ((val0 = checkTagLine(line, "rotation angle"))) {
330  rotationAngNeeded = 0;
331  //rotation = atof(val0);
332  rotation = checkTagLine_f(line, "rotation angle");
333  temp->rotation = rotation;
334  if (rotation > 45)
335  temp->eastbyscan = -1;
336  else //(rotation < -45)
337  temp->eastbyscan = 1;
338  // else
339  // temp->eastbyscan = 0;
340  }
341 
342  if ((val0 = checkTagLine(line, "pixel size"))) {
343  pixelSizeNeeded = 0;
344  valf = checkTagLine_f(line, "pixel size");
345  temp->pixelSize = valf;
346  }
347  if ((val0 = checkTagLine(line, "Northing"))) {
348  northingNeeded = 0;
349  temp->northing = checkTagLine_f(line, "Northing");
350 
351  }
352  if ((val0 = checkTagLine(line, "Easting"))) {
353  eastingNeeded = 0;
354  temp->easting = checkTagLine_f(line, "Easting");
355  // temp->easting = atof(val0);
356  }
357  if ((val0 = checkTagLine(line, "UTM zone"))) {
358  utmZoneNeeded = 0;
359  //temp->utmZone = (int)atof(val0);
360  sscanf(val0, "%d", &temp->utmZone);
361  }
362 
363  if ((val0 = checkTagLine(line, "wavelength"))) {
364  waveLengthNeeded = 0;
365  i = 0;
366  readWavInfo_jpl(ptr, tag, val);
367  while (i < maxBands && strcmp(tag, "}")) {
368  temp->wave[i] = atof(val);
369  readWavInfo_jpl(ptr, tag, val);
370  i++;
371  }
372 
373  if (!strcmp(tag, "}") && i <= maxBands) {
374  temp->wave[i] = atof(val);
375  i++;
376  } else { // if (i> maxBands) {
377 
378  fprintf(stderr, "-E- %s line %d: number of bands (%d) from AVIRIS file > maxBands (%d)\n",
379  __FILE__, __LINE__, numBands, maxBands);
380  exit(1);
381  }
382  numBands = i - 1;
383  }
384 
385  if ((val0 = checkTagLine(line, "data gain values"))) {
386  i = 0;
387  readWavInfo_jpl(ptr, tag, val);
388  while (i < maxBands && strcmp(tag, "}")) {
389  temp->gain[i] = atof(val);
390  readWavInfo_jpl(ptr, tag, val);
391  i++;
392  }
393 
394  if (!strcmp(tag, "}") && i <= maxBands) {
395  temp->gain[i] = atof(val);
396  i++;
397  } else { // if (i> AV_MAXBANDS) {
398 
399  fprintf(stderr, "-E- %s line %d: number of bands (%d) from AVIRIS file > AV_MAXBANDS (%d)\n",
400  __FILE__, __LINE__, numBands, maxBands);
401  exit(1);
402  }
403  numBands = i - 1;
404  temp->have_gain = 1;
405  }
406 
407  if ((val0 = checkTagLine(line, "fwhm"))) {
408  fwhmNeeded = 0;
409  i = 0;
410  readWavInfo_jpl(ptr, tag, val);
411  while (i < maxBands && strcmp(tag, "}")) {
412  temp->fwhm[i] = atof(val);
413  readWavInfo_jpl(ptr, tag, val);
414  i++;
415  }
416  if (!strcmp(tag, "}") && i < maxBands) {
417  temp->fwhm[i] = atof(val);
418  i++;
419  } else {
420  fprintf(stderr, "-E- %s line %d: number of bands (%d) from AVIRIS file > maxBands (%d)\n",
421  __FILE__, __LINE__, numBands, maxBands);
422  exit(1);
423  }
424  }
425  }
426 
427  fclose(ptr);
428  if ((numLinesNeeded ||
429  numSamplesNeeded ||
430  bandsNeeded ||
431  fwhmNeeded ||
432  waveLengthNeeded)) {
433 
434  fprintf(stderr, "-E- %s line %d: unable to read all of the required metadata from AVIRIS file\n",
435  __FILE__, __LINE__);
436  exit(1);
437  }
438 
439  temp->sena = (float *) malloc(nscans * npix * sizeof (float));
440  temp->senz = (float *) malloc(nscans * npix * sizeof (float));
441  temp->solz = (float *) malloc(nscans * npix * sizeof (float));
442  temp->sola = (float *) malloc(nscans * npix * sizeof (float));
443  temp->utc = (float *) malloc(nscans * npix * sizeof (float));
444  temp->Lt = (float *) malloc(temp->numBands * npix * sizeof (float));
445  temp->lon = (double *) malloc(nscans * npix * sizeof (double));
446  temp->lat = (double *) malloc(nscans * npix * sizeof (double));
447  temp->alt = (float *) malloc(nscans * sizeof (float));
448 
449  if (temp->sena == NULL || temp->senz == NULL || temp->sola == NULL || temp->solz == NULL) {
450  fprintf(stderr, "-E- %s line %d: unable to allocate sensor and solar angle data for AVIRIS\n",
451  __FILE__, __LINE__);
452  exit(1);
453  }
454 
455  if (navfile[0] != '\0') get_nav_data(navfile, nscans, npix, temp);
456 
457  if (gainfile[0] != '\0') {
458  if ((ptr = fopen(gainfile, "r")) == NULL) {
459  fprintf(stderr, "-E- %s line %d: unable to open %s\n",
460  __FILE__, __LINE__, gainfile);
461  exit(-1);
462 
463  }
464  i = 0;
465  while ((result = fgets(line, itemSize, ptr)) && i < numBands) {
466 
467  if (result == NULL) {
468  fprintf(stderr, "-E- %s line %d: unable to read all of the gain data from AVIRIS gain file\n",
469  __FILE__, __LINE__);
470  exit(1);
471  }
472  trimBlanks(line);
473 
474  sscanf(line, "%lf", &temp->gain[i]);
475  i++;
476  }
477  temp->have_gain = 1;
478  }
479 
480  if (navfile[0] == '\0') {
481  // Get info about the WGS84 data
482  // Get the lat/lon/elev
483  numLinesNeeded = 1;
484  numSamplesNeeded = 1;
485 
486  infile = malloc((pos + strlen("_obs.hdr")) * sizeof (char));
487  strcpy(infile, inbasename);
488  strcat(infile, "_obs.hdr");
489 
490  if ((ptr = fopen(infile, "r")) == NULL) {
491  fprintf(stderr, "-E- %s line %d: unable to open %s\n",
492  __FILE__, __LINE__, infile);
493  exit(-1);
494 
495  }
496  // loop metadata
497  while (numLinesNeeded ||
498  numSamplesNeeded) {
499 
500  readNextLine_jpl(ptr, tag, val);
501  // skip blank lines
502  if (tag[0] == 0)
503  continue;
504 
505  // get date
506  if (!strcmp(tag, "lines")) {
507  numLinesNeeded = 0;
508  temp->wgs_nscan = (int) atof(val);
509  }
510  if (!strcmp(tag, "samples")) {
511  numSamplesNeeded = 0;
512  temp->wgs_npix = (int) atof(val);
513  }
514  }
515 
516  fclose(ptr);
517 
518 
519  //Get the lat/lon/elev
520 
521  infile = malloc((pos + strlen("_lonlat_eph")) * sizeof (char));
522  strcpy(infile, inbasename);
523  strcat(infile, "_lonlat_eph");
524 
525  printf("Reading lon/lat/elev information from file %s\n", infile);
526 
527  // allocate lat and lon storage
528  num = 6;
529  // data->lat = (double *) malloc(data->wgs_nscan*sizeof(double) );
530  // data->lon = (double *) malloc(data->wgs_nscan*sizeof(double) );
531  elev = (double *) malloc(temp->wgs_nscan * sizeof (double));
532  indata = (double *) malloc(temp->wgs_nscan * num * sizeof (double));
533 
534  // if(temp->lat==NULL || temp->lon==NULL || temp->elev==NULL || indata==NULL) {
535  if (elev == NULL || indata == NULL) {
536  fprintf(stderr, "-E- %s line %d: unable to allocate lat/lon data for aviris\n",
537  __FILE__, __LINE__);
538  exit(1);
539  }
540 
541  if ((ptr = fopen(infile, "rb")) == NULL) {
542  fprintf(stderr, "-E- %s line %d: unable to open %s\n",
543  __FILE__, __LINE__, infile);
544  exit(-1);
545 
546  }
547  status = fread(indata, sizeof (double), temp->wgs_nscan*num, ptr);
548  if (status != temp->wgs_nscan * num) {
549  printf("Wrong data read size: want %d got %d in file %s\n", temp->wgs_nscan*num, status, infile);
550  exit(1);
551  }
552 
553  i = 0;
554 
555  gsl_spline *spline = gsl_spline_alloc(gsl_interp_cspline, temp->wgs_nscan);
556 
557  double *dist = (double *) calloc(temp->wgs_nscan, sizeof (double));
558  double *xlon = (double *) calloc(temp->wgs_nscan, sizeof (double));
559  double *xlat = (double *) calloc(temp->wgs_nscan, sizeof (double));
560 
561  temp->spl_acc = gsl_interp_accel_alloc();
562  temp->lon0 = indata[0];
563  temp->lat0 = indata[1];
564  temp->distmin = 999;
565  temp->distmax = -999;
566  while (i < temp->wgs_nscan * num) {
567  j = i / num;
568  xlon[j] = indata[i];
569  xlat[j] = indata[i + 1];
570  elev[j] = indata[i + 2];
571  //dist[j] = pow((xlon[j]-temp->lon0),2.0) + pow((xlat[j]-temp->lat0),2.0) ;
572  dist[j] = (double) angular_distance((double) xlat[j], (double) xlon[j], (double) temp->lat0, (double) temp->lon0);
573  //printf("RJH: elev[%d]=%lf dist=%lf lat=%f lon=%f lat0=%lf lon0=%lf\n",j,elev[j],dist[j],xlat[j],xlon[j], temp->lat0, temp->lon0);
574  i += num;
575  }
576  // Sort distances and corresponding elevation values
577  gsl_sort2(dist, 1, elev, 1, temp->wgs_nscan);
578  temp->distmin = dist[0];
579  temp->distmax = dist[temp->wgs_nscan - 2];
580  // for (j=0;j<temp->wgs_nscan;j++)
581  // printf("sort:RJH: elev[%d]=%lf dist=%lf lat=%f lon=%f lat0=%lf lon0=%lf\n",j,elev[j],dist[j],xlat[j],xlon[j], temp->lat0, temp->lon0);
582 
583  // Initiate spline
584  gsl_spline_init(spline, dist, elev, temp->wgs_nscan);
585 
586  temp->spline = spline;
587 
588  free(indata);
589  fclose(ptr);
590 
591  // Get the sensor and solar data
592 
593  num = 10;
594  indataf = (float *) malloc(npix * sizeof (float)*num);
595 
596  infile = malloc((pos + strlen("_obs_ort")) * sizeof (char));
597  strcpy(infile, inbasename);
598  strcat(infile, "_obs_ort");
599 
600  printf("Reading sensor and solar angles information from file %s\n", infile);
601 
602  if ((ptr = fopen(infile, "rb")) == NULL) {
603  fprintf(stderr, "-E- %s line %d: unable to open %s\n",
604  __FILE__, __LINE__, infile);
605  exit(-1);
606 
607  }
608  for (j = 0; j < nscans; j++) {
609  // for (j=nscans-1;j>=nscans;j--) {
610  status = fread(indataf, sizeof (float), num*npix, ptr);
611  if (status != num * npix) {
612  fprintf(stderr, "-E- %s line %d: AVIRIS Wrong sensor and solar data read size: want %d got %d\n",
613  __FILE__, __LINE__, npix*num, status);
614  exit(1);
615  }
616 
617  for (k = 0; k < npix; k++) {
618  temp->sena[j * npix + k] = indataf[1 * npix + k];
619  temp->senz[j * npix + k] = indataf[2 * npix + k];
620  temp->sola[j * npix + k] = indataf[3 * npix + k];
621  temp->solz[j * npix + k] = indataf[4 * npix + k];
622  temp->utc [j * npix + k] = indataf[9 * npix + k];
623  // if (temp->utc [j*npix+k] > 0) printf("i=%f %f\n",indataf[8*npix+k],temp->utc [j*npix+k]);
624  }
625  }
626 
627  free(indataf);
628  fclose(ptr);
629 
630 
631  PJ *pj;
632  // init the proj4 projections
633  sprintf(projStr, "+proj=utm +zone=%d +ellps=WGS84 +datum=WGS84 +units=m +no_defs ",
634  temp->utmZone);
635  pj = proj_create_crs_to_crs(PJ_DEFAULT_CTX,
636  projStr,
637  "+proj=longlat +ellps=WGS84 +datum=WGS84",
638  NULL);
639  if(pj == NULL) {
640  printf("Error - AVIRIS first PROJ projection failed to init\n");
641  exit(1);
642  }
643  temp->pj = proj_normalize_for_visualization(PJ_DEFAULT_CTX, pj);
644  if(temp->pj == NULL) {
645  printf("Error - AVIRIS visualization PROJ projection failed to init\n");
646  exit(1);
647  }
648  proj_destroy(pj);
649 
650  // Get the gain data
651  free(infile);
652  }
653 
654  if (!temp->have_gain) {
655  infile = malloc((pos + strlen(".gain")) * sizeof (char));
656  strcpy(infile, inbasename);
657  strcat(infile, ".gain");
658 
659  printf("Reading gain information from file %s\n", infile);
660 
661  if ((ptr = fopen(infile, "r")) == NULL) {
662  fprintf(stderr, "-E- %s line %d: unable to open %s\n Will assume gains.\n",
663  __FILE__, __LINE__, infile);
664  for (k = 0; k < numBands; k++) {
665  if (k < 110) temp->gain[i] = 300;
666  else if (k < 160) temp->gain[i] = 600;
667  else temp->gain[i] = 1200;
668 
669  }
670  temp->have_gain = 1;
671 
672  } else {
673 
674  temp->scale_factor = (float *) malloc(numBands * sizeof (float));
675  if (temp->gain == NULL) {
676  fprintf(stderr, "-E- %s line %d: unable to allocate gain data for AVIRIS\n",
677  __FILE__, __LINE__);
678  exit(1);
679  }
680  for (i = 0; i < numBands && fscanf(ptr, "%lf %d", &temp->gain[i], &k); i++) {
681  temp->scale_factor[i] = 1 / (temp->gain[i]);
682  printf("gain: %lf %d\n", *(temp->gain + i), k);
683  }
684 
685  temp->have_gain = 1;
686  fclose(ptr);
687  }
688  free(infile);
689  }
690  infile = malloc(FILENAME_MAX * sizeof (char));
691  if (imgfile[0] == '\0') {
692  strcpy(infile, inbasename);
693  strcat(infile, "_sc01_ort_img");
694  } else {
695  strcpy(infile, imgfile);
696  }
697  printf("Opening AVIRIS image file %s\n", infile);
698 
699  if ((temp->av_fp = fopen(infile, "rb")) == NULL) {
700  fprintf(stderr, "-E- %s line %d: unable to open %s\n",
701  __FILE__, __LINE__, infile);
702  exit(-1);
703 
704  }
705 
706  return temp;
707 
708 }
709 
710 int read_aviris(aviris4ocia_t* data, int32_t recnum)
711 /*
712  * fill standard record with L1B line of data
713  */ {
714  int status;
715 
716  static double last_good_hour = 18;
717  static int firstCall = 1;
718  static float validSenz, validSena, validSolz, validSola;
719  double sec;
720  int hour, minute;
721  double dist;
722  int isec;
723  int32_t npix = data->npix, ip;
724  static int swap;
725  int32_t skip = SKIP;
726 
727 
728  if (firstCall) {
729  firstCall = 0;
730 
731 
732  if (endianess() == 1)
733  swap = 1;
734  else
735  swap = 0;
736 
737  }
738 
739 
740  if (!data->have_nav) {
741  int k = 0;
742  // while ((hour = (int)(data->utc[recnum][k])) <0 && k<npix) k++;
743  while ((hour = (int) (data->utc[recnum * npix + k])) < 0 && k < npix) k++;
744 
745  if (hour < 0) hour = last_good_hour;
746 
747  last_good_hour = hour;
748 
749  // minute = (data->utc[recnum][k] - hour)*60;
750  // sec = ((data->utc[recnum][k] - hour)*60 - minute)*60;
751  minute = (data->utc[recnum * npix + k] - hour)*60;
752  sec = ((data->utc[recnum * npix + k] - hour)*60 - minute)*60;
753  // printf("Date:utc=%f sec=%f minute=%d (utc-hour)*60=%f ",data->utc[recnum][k],sec,minute,(data->utc[recnum][k] - hour)*60 );
754  isec = (int) sec;
755 
756  data->hour = hour;
757  data->min = minute;
758  data->sec = sec;
759 
760  ymdhms2ydmsec(data->year, data->month, data->day, hour, minute, isec,
761  &data->year, &data->doy, &data->msec);
762 
763  //data->msec = sec * 1000;
764 
765  //data->scantime = yds2unix(data->year, data->doy, (double) (data->msec / 1.e3));
766  data->scantime = ymds2unix(data->year, data->month, data->day, (hour * 3600 + minute * 60 + sec));
767  // printf("Date=%4d %d %d\n",*(l1rec->year),*(l1rec->day),*(l1rec->msec));
768 
769  for (ip = 0; ip < npix; ip++) {
770 
771  // Rotate the image
772  data->lon[recnum * npix + ip] = data->easting + ip * cos(deg2rad(data->rotation)) * data->pixelSize - recnum * sin(deg2rad(data->rotation)) * data->pixelSize; // starts in upper left corner
773  data->lat[recnum * npix + ip] = data->northing - ip * sin(deg2rad(data->rotation)) * data->pixelSize - recnum * cos(deg2rad(data->rotation)) * data->pixelSize;
774 
775  if (isnan(data->lat[recnum * npix + ip])) data->lat[recnum * npix + ip] = -999.0;
776  if (isnan(data->lon[recnum * npix + ip])) data->lon[recnum * npix + ip] = -999.0;
777 
778  if (data->senz[recnum * npix + ip] <= skip) data->senz[recnum * npix + ip] = getValidAngleB(&data->senz[recnum * npix], npix, skip, &validSenz);
779  if (data->sena[recnum * npix + ip] <= skip) data->sena[recnum * npix + ip] = getValidAngleB(&data->sena[recnum * npix], npix, skip, &validSena);
780  if (data->solz[recnum * npix + ip] <= skip) data->solz[recnum * npix + ip] = getValidAngleB(&data->solz[recnum * npix], npix, skip, &validSolz);
781  if (data->sola[recnum * npix + ip] <= skip) data->sola[recnum * npix + ip] = getValidAngleB(&data->sola[recnum * npix], npix, skip, &validSola);
782  }
783 
785 
786 
787  // find interpolated elevation from wgs-84 lat/lon
788  ip = npix / 2;
789  // dist = (data->lon[recnum*npix+ip]-data->lon0)*(data->lon[recnum*npix+ip]-data->lon0) +
790  // (data->lat[recnum*npix+ip]-data->lat0)*(data->lat[recnum*npix+ip]-data->lat0);
791  dist = (float) angular_distance((double) data->lat[recnum * npix + ip], (double) data->lon[recnum * npix + ip], (double) data->lat0, (double) data->lon0);
792  if (dist > data->distmax) {
793  printf("lat/lon > range of wgs coordinates - using altitude of nearest neighbor\n");
794  dist = data->distmax;
795  } else if (dist < data->distmin) {
796  printf("lat/lon < range of wgs coordinates - using altitude of nearest neighbor\n");
797  dist = data->distmin;
798  }
799  data->alt[recnum] = (float) gsl_spline_eval(data->spline, dist, data->spl_acc);
800 
801  } else {
802  hour = (int) (data->utc[recnum]);
803  minute = (data->utc[recnum] - hour) * 60;
804  sec = ((data->utc[recnum] - hour) * 60 - minute) * 60;
805  data->scantime = ymds2unix(data->year, data->month, data->day,
806  (hour * 3600. + minute * 60. + sec));
807  data->hour = hour;
808  data->min = minute;
809  data->sec = sec;
810 
811  }
812 
813  status = readBinScanLine4ocia_int2(data->Lt, recnum, data->npix, data->gain, data->numBands, data->numBands, data->interleave, swap, data->av_fp);
814 
815  if (status == data->npix * data->numBands)
816  return (0);
817  else
818  return (1);
819 
820 }
821 
822 int close_aviris(aviris4ocia_t *data) {
823 
824  // undo what open allocated
825 
827  fclose(data->av_fp);
828  return 0;
829 }
830 
831 int checkAvProcessFile(char *filename, char *hdrfile, char *imgfile, char *navfile, char *gainfile, int itemsize) {
832  FILE *fh;
833  char *result;
834  int status = 0;
835  char line[itemsize];
836  char desc[itemsize];
837  char fobj[itemsize];
838 
839  if ((fh = fopen(filename, "r")) == NULL) {
840  fprintf(stderr, "-E- %s line %d: unable to open %s\n",
841  __FILE__, __LINE__, filename);
842  exit(-1);
843  }
844  imgfile[0] = '\0';
845  navfile[0] = '\0';
846  gainfile[0] = '\0';
847  if (fgets(line, itemsize, fh)) {
848  sscanf(line, "%s", desc);
849  if (strstr(desc, "AVIRIS_PREPROC_HDR")) {
850  while ((result = fgets(line, itemsize, fh))) {
851 
852  if (result == NULL) {
853  fprintf(stderr, "-E- %s line %d: unable to read all of the gain data from AVIRIS gain file\n",
854  __FILE__, __LINE__);
855  exit(1);
856  }
857  trimBlanks(line);
858 
859  sscanf(line, "%s = %s", desc, fobj);
860  if (strstr(desc, "hdrfile"))
861  strncpy(hdrfile, fobj, itemsize);
862  if (strstr(desc, "navfile"))
863  strncpy(navfile, fobj, itemsize);
864  if (strstr(desc, "gainfile"))
865  strncpy(gainfile, fobj, itemsize);
866  if (strstr(desc, "imgfile"))
867  strncpy(imgfile, fobj, itemsize);
868  }
869  status = 1;
870  }
871  }
872  fclose(fh);
873  return status;
874 }
875 
876 
877 
int j
Definition: decode_rs.h:73
int read_aviris(aviris4ocia_t *data, int32_t recnum)
Definition: read_aviris.c:710
int32_t day
int status
Definition: l1_czcs_hdf.c:32
real(single), dimension(:,:), allocatable longitude
void nav_gd_orient(float *pos, float *vel, float *att, float *smat[], float *coef)
Definition: get_zenaz.c:160
#define NULL
Definition: decode_rs.h:63
#define SKIP
Definition: read_aviris.c:20
void nav_get_geonav(float *sunr, float *pos, float *pview, float *coef, float *smat[], float *xlon, float *xlat, float *solz, float *sola, float *senz, float *sena)
Definition: get_zenaz.c:310
aviris4ocia_t * open_aviris(char *filename, char *imgfile, char *navfile, char *gainfile, aviris4ocia_t **data)
Definition: read_aviris.c:175
const double deg2rad
void trimBlanks(char *str)
Definition: trimBlanks.c:10
real(single), dimension(:,:), allocatable latitude
subroutine spline(s, x, y, n, in, t, il, iu, vl, vu, e, u)
Definition: phs.f:1348
void readNextLine_jpl(FILE *fp, char *tag, char *val)
Definition: jplaeriallib.c:90
float32 * pos
Definition: l1_czcs_hdf.c:35
float * lat
void freePrivateData_ocia(aviris4ocia_t *data)
Definition: read_aviris.c:25
int endianess(void)
determine endianess
Definition: endianess.c:10
char * getinbasename_av(char *file)
Definition: jplaeriallib.c:17
int readBinScanLine4ocia_int2(float *Lt, int32_t recnum, int32_t npix, double *gain, int nbands, int numBands, int interleave, int swap, FILE *ptr)
Definition: jplaeriallib.c:125
#define BIL
read recnum
#define BIP
void cdata_()
void unix2yds(double usec, short *year, short *day, double *secs)
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
float getValidAngleB(float *ang, int32_t npix, int32_t skip, float *fillangle)
Definition: read_aviris.c:38
integer, parameter double
instead the metadata field ProcessingEnvinronment is filled in from the output of a call to the POSIX compliant function uname from within the L1B code A small bug in L1B_Tables an incorrect comparison of RVS coefficients for TEBs to RVS coefficients for RSBs was being made This was replaced with a comparison between TEB coefficients This error never resulted in an incorrect RVS correction but did lead to recalculating the coefficients for each detector in a thermal band even if the coefficients were the same for all detectors To reduce to overall size of the reflective LUT HDF fill values were eliminated from all LUTs previously dimensioned where and where NUM_TIMES is the number of time dependent table pieces In Preprocess a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed This counter is internal only and is not yet used for any chiefly to casting of were added to make it LINUX compatible Output of code run on LINUX machines displays differences of at most scaled sector rotation
Definition: HISTORY.txt:575
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
int checkAvProcessFile(char *filename, char *hdrfile, char *imgfile, char *navfile, char *gainfile, int itemsize)
Definition: read_aviris.c:831
float xlon[LAC_PIXEL_NUM]
Definition: l1a_seawifs.c:93
void ymdhms2ydmsec(int yy, int mm, int dd, int hh, int mn, int sc, int32_t *year, int32_t *day, int32_t *msec)
Definition: ydhms2ydmsec.c:3
char * checkTagLine(char *line, char *tag)
Definition: jplaeriallib.c:433
double angular_distance(double lat1, double lon1, double lat2, double lon2)
Definition: read_prism.c:537
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)
float * lon
float checkTagLine_f(char *linein, char *tag)
Definition: jplaeriallib.c:457
void aviris4ocia_proj4_convert(aviris4ocia_t *data, int32_t numPoints, double *x, double *y)
Definition: read_aviris.c:50
double ymds2unix(short year, short month, short day, double secs)
int close_aviris(aviris4ocia_t *data)
Definition: read_aviris.c:822
void nav_get_pos(float lat, float lon, float alt, float *p)
Definition: get_zenaz.c:134
void get_nav_data(char *navfile, int32_t nscans, int32_t npix, aviris4ocia_t *data)
Definition: read_aviris.c:67
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 as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
int i
Definition: decode_rs.h:71
msiBandIdx val
Definition: l1c_msi.cpp:34
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define maxBands
int sunpos(double tjd, double r[3], char **errstr)
int k
Definition: decode_rs.h:73
void nav_get_vel(float ilat, float mlat, float ilon, float mlon, float *vel)
Definition: get_zenaz.c:105
int npix
Definition: get_cmp.c:27
void l_sun_(int *iyr, int *iday, double *sec, float *sunr, float *rs)
void readWavInfo_jpl(FILE *fp, char *tag, char *val)
Definition: jplaeriallib.c:65