OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l1_mos_hdf.c
Go to the documentation of this file.
1 /* ====================================================== */
2 /* Module l1_mos_hdf.c */
3 /* */
4 /* Functions to open and read a MOS HDF l1b file. */
5 /* */
6 /* Written By: */
7 /* JT */
8 /* NASA/SIMBIOS Project */
9 /* 11/98 */
10 /* */
11 /* ====================================================== */
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include "l1.h"
18 #include "filehdr_struc.h"
19 #include <hdf4utils.h>
20 #include "l1_mos_hdf.h"
21 
22 #include <hdf.h>
23 #include <mfhdf.h>
24 
25 #define NP 384 /* # pixels for MOS files */
26 #define NS 384 /* # scans for MOS files */
27 #define NB 13 /* Number of channels */
28 #define MAXLEN 200 /* length of file description array */
29 #define PSIZE 2 /* Array size for the tabulated values */
30 #define SPACE 32 /* ASCII Blank */
31 #define NUM 63 /* # elements in id[] and desc[] arrays */
32 #define NBANDS_MOS 8
33 
34 static float gscan[NBANDS_MOS][4];
35 
36 
37 
38 /* Function prototypes */
39 /* ------------------- */
40 int rd_gscan(void);
41 int ReadSDS(filehandle *l1file);
42 int32_t GetTime(char arr[MAXLEN]);
43 int32_t TimeToSec(int32_t yr, int32_t mo, int32_t dm, int32_t hr, int32_t mn, int32_t sec);
44 int GetYearDayMsec(double dtime[NS]);
45 int LeapChk(int32_t yr);
46 int RemoveWhitespace(char arr[MAXLEN]);
47 int bilinear(float p[PSIZE][PSIZE], float x[NS][NP], float y[NS][NP], float z[NS][NP]);
48 
49 /* Static globals */
50 /* -------------- */
51 static char *desc_buffer = NULL; /* buffer for the file description */
52 
53 typedef uint16_t array_data_t[NS];
54 static array_data_t* array_data;
55 //static uint16_t array_data[NP*14][NS]; /* full image data array */
56 
57 typedef float data_2d_t[NP];
58 static data_2d_t *lon;
59 static data_2d_t *lat;
60 static data_2d_t *solz;
61 static data_2d_t *sola;
62 static data_2d_t *senz;
63 static data_2d_t *sena;
64 //static float lon [NS][NP];
65 //static float lat [NS][NP];
66 //static float solz [NS][NP];
67 //static float sola [NS][NP];
68 //static float senz [NS][NP];
69 //static float sena [NS][NP];
70 
71 typedef float image_t[NP][NBANDS_MOS];
72 static image_t* image;
73 //static float image [NS][NP][NBANDS_MOS];
74 
75 static int32_t* yeararr;
76 static int32_t* dayarr;
77 static int32_t* msecarr;
78 //static int32_t yeararr [NS];
79 //static int32_t dayarr [NS];
80 //static int32_t msecarr [NS];
81 
82 static int32_t begdm;
83 static int32_t enddm;
84 static int32_t begmo;
85 static int32_t endmo;
86 static int32_t begyr;
87 static int32_t endyr;
88 
89 static int bands[NBANDS_MOS] = {0, 1, 2, 3, 4, 7, 8, 10};
90 static float acal[NB];
91 
92 
93 /* ------------------------------------------------------ */
94 /* openl1_read_mos_hdf() - opens a MOS HDF level-1 file */
95 /* for reading, if not already opened. */
96 /* Stores the file data for lon, lat, */
97 /* etc. in 384 x 384 arrays. */
98 /* */
99 
100 /* ------------------------------------------------------ */
101 int openl1_read_mos_hdf(filehandle *l1file) {
102  data_2d_t *x;
103  data_2d_t *y;
104  //float x[NS][NP];
105  //float y[NS][NP];
106 
107  float ul[4], ur[4], ll[4], lr[4];
108  float p[PSIZE][PSIZE];
109  int i, j, k, m, n, len;
110  int status;
111  char desc[MAXLEN], id[40], calstr[20];
112  char *loc1, *loc2, *idend, *cal1, *cal2;
113  int32_t hr, mn, sec;
114  int32_t begMsec, endMsec, endTime, begTime;
115  double eTime, bTime, dtime[NS];
116 
117  // allocate global data
118  array_data = (array_data_t*) malloc((NP * 14) * sizeof (array_data_t));
119  lon = (data_2d_t*) malloc(NS * sizeof (data_2d_t));
120  lat = (data_2d_t*) malloc(NS * sizeof (data_2d_t));
121  solz = (data_2d_t*) malloc(NS * sizeof (data_2d_t));
122  sola = (data_2d_t*) malloc(NS * sizeof (data_2d_t));
123  senz = (data_2d_t*) malloc(NS * sizeof (data_2d_t));
124  sena = (data_2d_t*) malloc(NS * sizeof (data_2d_t));
125  image = (image_t*) malloc(NS * sizeof (image_t));
126  yeararr = (int32_t*) malloc(NS * sizeof (int32_t));
127  dayarr = (int32_t*) malloc(NS * sizeof (int32_t));
128  msecarr = (int32_t*) malloc(NS * sizeof (int32_t));
129 
130  // local data
131  x = (data_2d_t*) malloc(NS * sizeof (data_2d_t));
132  y = (data_2d_t*) malloc(NS * sizeof (data_2d_t));
133 
134  /* Get relative cal gains */
135  if (rd_gscan() != 0)
136  return (1);
137 
138  /* Set header info */
139  l1file->npix = NP;
140  l1file->nscan = NS;
141 
142  /* Get file description from the HDF file */
143  if ((desc_buffer = GetFileDesc(l1file->name)) == NULL)
144  return (1);
145 
146  /* Load the id[] and desc[] arrays */
147  loc1 = desc_buffer;
148  for (i = 0; i < NUM; i++) {
149  loc2 = strchr(loc1, ';');
150  if (loc2 == NULL) break;
151  len = loc2 - loc1;
152  desc[0] = '\0';
153  strncat(desc, loc1, len);
154 
155  /* Remove whitespace characters */
156  status = RemoveWhitespace(desc);
157 
158  /* Break into id[] and desc[] arrays */
159  idend = strchr(desc, '=');
160  len = idend - desc;
161  id[0] = '\0';
162  strncat(id, desc, len);
163  for (j = 0; j < MAXLEN; j++) {
164  desc[j] = desc[j + len];
165  }
166 
167  /* Remove whitespace characters */
168  status = RemoveWhitespace(desc);
169 
170  loc1 = loc2 + 1;
171 
172  /* Convert header information to usable format */
173  for (k = 0; k < 1; k++) {
174  if (strcmp(id, "LONG_UL") == 0) {
175  ul[0] = atof(desc);
176  break;
177  }
178  if (strcmp(id, "LATI_UL") == 0) {
179  ul[1] = atof(desc);
180  break;
181  }
182  if (strcmp(id, "SUNZ_UL") == 0) {
183  ul[2] = atof(desc);
184  break;
185  }
186  if (strcmp(id, "SUNA_UL") == 0) {
187  ul[3] = atof(desc);
188  break;
189  }
190  if (strcmp(id, "LONG_UR") == 0) {
191  ur[0] = atof(desc);
192  break;
193  }
194  if (strcmp(id, "LATI_UR") == 0) {
195  ur[1] = atof(desc);
196  break;
197  }
198  if (strcmp(id, "SUNZ_UR") == 0) {
199  ur[2] = atof(desc);
200  break;
201  }
202  if (strcmp(id, "SUNA_UR") == 0) {
203  ur[3] = atof(desc);
204  break;
205  }
206  if (strcmp(id, "LONG_LL") == 0) {
207  ll[0] = atof(desc);
208  break;
209  }
210  if (strcmp(id, "LATI_LL") == 0) {
211  ll[1] = atof(desc);
212  break;
213  }
214  if (strcmp(id, "SUNZ_LL") == 0) {
215  ll[2] = atof(desc);
216  break;
217  }
218  if (strcmp(id, "SUNA_LL") == 0) {
219  ll[3] = atof(desc);
220  break;
221  }
222  if (strcmp(id, "LONG_LR") == 0) {
223  lr[0] = atof(desc);
224  break;
225  }
226  if (strcmp(id, "LATI_LR") == 0) {
227  lr[1] = atof(desc);
228  break;
229  }
230  if (strcmp(id, "SUNZ_LR") == 0) {
231  lr[2] = atof(desc);
232  break;
233  }
234  if (strcmp(id, "SUNA_LR") == 0) {
235  lr[3] = atof(desc);
236  break;
237  }
238  if (strcmp(id, "BCAL_VAL") == 0) {
239  len = 0;
240  for (m = 0; m < NB; m++) {
241  for (n = 0; n < MAXLEN; n++) {
242  desc[n] = desc[n + len];
243  }
244  status = RemoveWhitespace(desc);
245  cal1 = desc;
246  cal2 = strchr(cal1, SPACE);
247  len = cal2 - cal1;
248  calstr[0] = '\0';
249  strncat(calstr, cal1, len);
250  acal[m] = atof(calstr);
251  cal1 = cal2 + 1;
252  }
253  break;
254  }
255  if (strcmp(id, "OP_BEG_DATE") == 0) {
256  begdm = GetTime(desc);
257  begmo = GetTime(desc);
258  begyr = GetTime(desc);
259  if (begyr > 50) {
260  begyr = begyr + 1900;
261  } else {
262  begyr = begyr + 2000;
263  }
264  hr = GetTime(desc);
265  mn = GetTime(desc);
266  sec = GetTime(desc);
267  begTime = TimeToSec(begyr, begmo, begdm, hr, mn, sec);
268  break;
269  }
270  if (strcmp(id, "OP_END_DATE") == 0) {
271  enddm = GetTime(desc);
272  endmo = GetTime(desc);
273  endyr = GetTime(desc);
274  if (endyr > 50) {
275  endyr = endyr + 1900;
276  } else {
277  endyr = endyr + 2000;
278  }
279  hr = GetTime(desc);
280  mn = GetTime(desc);
281  sec = GetTime(desc);
282  endTime = TimeToSec(endyr, endmo, enddm, hr, mn, sec);
283  break;
284  }
285  if (strcmp(id, "OP_BEG_MS") == 0) {
286  begMsec = atol(desc);
287  break;
288  }
289  if (strcmp(id, "OP_END_MS") == 0) {
290  endMsec = atol(desc);
291  break;
292  }
293  // if (strcmp(id,"CLOUD_PERC") == 0) {
294  // l1file->percent_cloud = atoi(desc);
295  // break;
296  // }
297  // if (strcmp(id,"LAND_PERC") == 0) {
298  // l1file->percent_land = atoi(desc);
299  // break;
300  // }
301  // if (strcmp(id,"WATER_PERC") == 0) {
302  // l1file->percent_water = atoi(desc);
303  // break;
304  // }
305  } /* k loop */
306  } /* i loop */
307 
308  bTime = (double) begTime + begMsec / 1000.0;
309  eTime = (double) endTime + endMsec / 1000.0;
310 
311  /* set yeararr, dayarr & msecarr arrays */
312  for (i = 0; i < NS; i++) {
313  dtime[i] = bTime + (eTime - bTime) / (NS - 1) * i;
314  }
315  status = GetYearDayMsec(dtime);
316 
317  /* set x and y matrices, using i for rows, j for columns */
318  for (i = 0; i < NS; i++) {
319  for (j = 0; j < NP; j++) {
320  x[i][j] = (1.0 * j) / (NP - 1);
321  y[i][j] = (1.0 * i) / (NS - 1);
322  }
323  }
324 
325  p[0][0] = ul[0];
326  p[0][1] = ur[0];
327  p[1][0] = ll[0];
328  p[1][1] = lr[0];
329  status = bilinear(p, x, y, lon);
330  p[0][0] = ul[1];
331  p[0][1] = ur[1];
332  p[1][0] = ll[1];
333  p[1][1] = lr[1];
334  status = bilinear(p, x, y, lat);
335  p[0][0] = ul[2];
336  p[0][1] = ur[2];
337  p[1][0] = ll[2];
338  p[1][1] = lr[2];
339  status = bilinear(p, x, y, solz);
340  p[0][0] = ul[3];
341  p[0][1] = ur[3];
342  p[1][0] = ll[3];
343  p[1][1] = lr[3];
344  status = bilinear(p, x, y, sola);
345 
346  /* keep the longitude in the -180 to 180 range */
347  for (i = 0; i < NS; i++) {
348  for (j = 0; j < NP; j++) {
349  if (lon[i][j] > 180) {
350  lon[i][j] = lon[i][j] - 360;
351  } else {
352  if (lon[i][j] < -180)
353  lon[i][j] = lon[i][j] + 360;
354  }
355  }
356  }
357 
358 
359  /* No sensor geometry is available. Assume zenith is zero */
360  /* at center, 7-deg at edge. Azimuth is 90-deg relative to */
361  /* solar azimuth */
362  for (i = 0; i < NS; i++) {
363  for (j = 0; j < NP; j++) {
364  senz[i][j] = fabs(-7.0 + x[i][j] * 14.0);
365  sena[i][j] = sola[i][j] + 270;
366  if (sena[i][j] > 360.0) sena[i][j] -= 360.0;
367  }
368  }
369 
370  printf("\nMOS Scan-Dependent Calibration Coefficients (Band C0 C1 C2 C3)\n");
371  for (i = 0; i < NBANDS_MOS; i++) {
372  printf(" %d: %e, %e, %e, %e\n", i + 1,
373  gscan[i][0], gscan[i][1], gscan[i][2], gscan[i][3]);
374  }
375 
376  free(x);
377  free(y);
378 
379  return (status);
380 }
381 
382 
383 /* ------------------------------------------------------ */
384 /* readl1_mos_hdf() - reads a MOS HDF level-1 record. */
385 /* */
386 
387 /* ------------------------------------------------------ */
388 int readl1_mos_hdf(filehandle *l1file, int32_t recnum, l1str *l1rec) {
389  int i, j, k;
390  static char current_file[FILENAME_MAX] = "";
391  int ibnd;
392  float gain, x;
393  float Lt7;
394 
395  int32_t ip, ib, iw;
396  int32_t nwave = l1rec->l1file->nbands;
397  int32_t *bindx = l1rec->l1file->bindx;
398 
399  /* check current recnum */
400  if (recnum >= NS) {
401  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
402  fprintf(stderr, "readl1_mos_hdf() called with record number (%d) ", recnum);
403  fprintf(stderr, "that is inappropriate to the number of scanlines (%d) ", NS);
404  fprintf(stderr, "in the current HDF file, %s . Call ignored.\n", l1file->name);
405  return (1);
406  }
407 
408 
409  /* On first access, load entire image array into memory */
410  if (strcmp(current_file, l1file->name) != 0) {
411 
412  printf("Reading image data block.\n");
413 
414  strcpy(current_file, l1file->name);
415 
416  /* read in the image data */
417  if (ReadSDS(l1file) != 0)
418  return (1);
419 
420  /* create the image array */
421  for (i = 0; i < NBANDS_MOS; i++) {
422  for (j = 0; j < NS; j++) {
423  ibnd = j * 14 + bands[i];
424  for (k = 0; k < NP; k++) {
425  x = k + 1;
426  gain = gscan[i][0] + x * (gscan[i][1] + x * (gscan[i][2] + x * gscan[i][3]));
427  image[j][k][i] = array_data[ibnd][k] * acal[bands[i]] * gain;
428  }
429  }
430  }
431  }
432  l1rec->scantime = yds2unix((int16_t) yeararr[recnum], (int16_t) dayarr[recnum],
433  (double) (msecarr[recnum] / 1000.0));
434 
435  /* copy the scan arrays */
436  memcpy(l1rec->lon, &lon [recnum][0], sizeof (float)*NP);
437  memcpy(l1rec->lat, &lat [recnum][0], sizeof (float)*NP);
438  memcpy(l1rec->solz, &solz[recnum][0], sizeof (float)*NP);
439  memcpy(l1rec->sola, &sola[recnum][0], sizeof (float)*NP);
440  memcpy(l1rec->senz, &senz[recnum][0], sizeof (float)*NP);
441  memcpy(l1rec->sena, &sena[recnum][0], sizeof (float)*NP);
442 
443  /* copy the image data for this line */
444  /* The input files do not contain the view angles per band, so we
445  must replicate them here from the nominal view angles */
446  for (ip = 0; ip < NP; ip++) {
447  for (iw = 0; iw < nwave; iw++) {
448  ib = bindx[iw];
449  l1rec->Lt[ip * nwave + ib] = image[recnum][ip][iw];
450  }
451  }
452 
453  /* Correction for 750 channel non-linearity in MOS */
454  for (j = 0; j < l1file->npix; j++) {
455  Lt7 = l1rec->Lt[j * nwave + bindx[6]];
456  if (Lt7 > 0.0)
457  l1rec->Lt[j * nwave + bindx[6]] = (Lt7 * Lt7 + 0.04) / Lt7;
458  }
459 
460  return (0);
461 }
462 
463 
464 /* ------------------------------------------------------ */
465 /* closel1_mos_hdf() - closes the level 1 HDF file */
466 /* */
467 
468 /* ------------------------------------------------------ */
469 int closel1_mos_hdf(filehandle *l1file) {
470  free(array_data);
471  free(lon);
472  free(lat);
473  free(solz);
474  free(sola);
475  free(senz);
476  free(sena);
477  free(image);
478  free(yeararr);
479  free(dayarr);
480  free(msecarr);
481 
482  return (0);
483 }
484 
485 
486 /* ------------------------------------------------------ */
487 /* ReadSDS() - reads "Data-Set-4". If it is empty, reads */
488 /* "Data-Set-6". */
489 /* */
490 
491 /* ------------------------------------------------------ */
492 int ReadSDS(filehandle *l1file) {
493  int32_t sd_id, sds_id, status;
494  int32_t sds_index, rank, nt, dims[HDF4_UTILS_MAX_DIM], nattrs;
495  int32_t start[2], edges[2];
497 
498  /* Open the file and initiate the SD interface */
499  sd_id = SDstart(l1file->name, DFACC_RDONLY);
500 
501  /* Get the "Data-Set-4" SDS index */
502  sds_index = SDnametoindex(sd_id, "Data-Set-4");
503 
504  /* Check that the "Data-Set-4" SDS exists; if not,
505  open the "Data-Set-6" SDS */
506  if (sds_index == -1) {
507  sds_index = SDnametoindex(sd_id, "Data-Set-6");
508  if (sds_index == -1) {
509  printf("-E- %s: Error seeking SDS\n", __FILE__);
510  return (1);
511  }
512  }
513 
514  /* Select the SDS */
515  sds_id = SDselect(sd_id, sds_index);
516 
517  /* Verify the characteristics of the array */
518  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
519 
520  /* Define the location, pattern and size of the data to read */
521  start[0] = start[1] = 0;
522  edges[0] = dims[0];
523  edges[1] = dims[1];
524 
525  /* Read the array */
526  status = SDreaddata(sds_id, start, NULL, edges, (VOIDP) array_data);
527 
528  /* Terminate access to the array */
529  status = SDendaccess(sds_id);
530 
531  /* Terminate access to the SD interface and close the file */
532  status = SDend(sd_id);
533 
534  return (status);
535 }
536 
537 /* ------------------------------------------------------ */
538 /* GetTime - gets the time from a string in the file */
539 /* description */
540 /* */
541 
542 /* ------------------------------------------------------ */
543 int32_t GetTime(char arr[MAXLEN]) {
544  int i;
545  int length, ch;
546  int32_t itime;
547  char tstr[5];
548 
549  RemoveWhitespace(arr);
550 
551  length = 0;
552  ch = arr[length];
553  while (isalnum(ch)) {
554  length = length + 1;
555  ch = arr[length];
556  }
557  tstr[0] = '\0';
558  strncat(tstr, arr, length);
559  itime = atol(tstr);
560  for (i = 0; i < MAXLEN - length - 2; i++) {
561  arr[i] = arr[i + length + 1];
562  }
563  arr[i] = '\0';
564  return (itime);
565 }
566 
567 /* ------------------------------------------------------ */
568 /* TimeToSec - calculates number of seconds since */
569 /* Jan 1,1968 */
570 /* */
571 
572 /* ------------------------------------------------------ */
573 int32_t TimeToSec(int32_t yr, int32_t mo, int32_t dm, int32_t hr, int32_t mn, int32_t sec) {
574  int i;
575  int32_t totalSec = 0;
576  int mdays[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243,
577  273, 304, 334};
578 
579  /* get T68 seconds to 1st day of year */
580  /* loop thru years from 1968 */
581  for (i = 1968; i < yr; i++) {
582  if (LeapChk(i) == -1) {
583  totalSec = totalSec + 3600 * 24 * 366; /* leap year */
584  } else {
585  totalSec = totalSec + 3600 * 24 * 365; /* non-leap year */
586  }
587  }
588 
589  /* add additional seconds */
590  totalSec = totalSec + mdays[mo - 1]*86400 +
591  (dm - 1)*86400 + hr * 3600 + mn * 60 + sec;
592 
593  /* adjust for leap years */
594  if ((LeapChk(yr) == -1) && (mo > 2)) {
595  totalSec = totalSec + 86400;
596  }
597  return (totalSec);
598 }
599 
600 /* ------------------------------------------------------ */
601 /* GetYearDayMsec() - sets the yeararr, dayarr */
602 /* msecarr arrays */
603 /* */
604 
605 /* ------------------------------------------------------ */
606 int GetYearDayMsec(double dtime[NS]) {
607  int i;
608  int32_t yr, sec;
609  int mdays[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243,
610  273, 304, 334};
611 
612  /* if the year doesn't change, set all yeararr elements the same */
613  if ((endyr - begyr) == 0) {
614  for (i = 0; i < NS; i++) {
615  yeararr[i] = begyr;
616  }
617  } else {
618  /* loop through years from 1968 */
619  for (i = 0; i < NS; i++) {
620  yr = 1968;
621  while (TimeToSec(yr, 1, 0, 0, 0, 0) < (int) dtime[i]) {
622  yr++;
623  }
624  yeararr[i] = yr - 1;
625  }
626  }
627 
628  /* if the day doesn't change, set all dayarr elements the same */
629  if (((endmo - begmo) == 0) && ((enddm - begdm) == 0)) {
630  for (i = 0; i < NS; i++) {
631  dayarr[i] = mdays[begmo - 1] + begdm;
632  }
633  } else {
634  /* get seconds up to this year */
635  for (i = 0; i < NS; i++) {
636  sec = TimeToSec(yeararr[i], 1, 0, 0, 0, 0);
637  /* seconds to convert into day is the difference dtime[i] - sec */
638  dayarr[i] = (int32_t) (dtime[i] - sec) / (86400);
639  }
640  }
641 
642  /* set msecarr */
643  for (i = 0; i < NS; i++) {
644  /* find seconds to beginning of the day */
645  sec = TimeToSec(yeararr[i], 1, dayarr[i], 0, 0, 0);
646  msecarr[i] = ((int) dtime[i] - sec)*1000 +
647  (dtime[i] - (double) ((int) dtime[i]))* 1000;
648  }
649  return (0);
650 }
651 
652 /* ------------------------------------------------------ */
653 /* LeapChk() - checks if the year is a leap year: */
654 /* returns -1 if leap year */
655 /* returns 0 if non-leap year */
656 /* */
657 
658 /* ------------------------------------------------------ */
659 int LeapChk(int32_t yr) {
660  int year, leap;
661 
662  year = yr;
663  leap = 0;
664  if ((year % 4) == 0) {
665  leap = -1;
666  }
667  if ((year % 100) == 0) {
668  leap = 0;
669  }
670  if ((year % 400) == 0) {
671  leap = -1;
672  }
673  return (leap);
674 }
675 
676 /* ------------------------------------------------------ */
677 /* RemoveWhitespace() - removes leading whitespace */
678 /* characters from an array */
679 /* */
680 
681 /* ------------------------------------------------------ */
682 int RemoveWhitespace(char arr[MAXLEN]) {
683  int i, j, ch, length;
684 
685  i = 0;
686  ch = (int) arr[0];
687  while (!isalnum(ch) && i++ < MAXLEN) {
688  ch = (int) arr[i];
689  }
690  length = MAXLEN - i;
691  for (j = 0; j < length; j++) {
692  arr[j] = arr[j + i];
693  }
694 
695  return (0);
696 }
697 
698 
699 /* ------------------------------------------------------ */
700 /* bilinear - bilinearly interpolates a set of reference */
701 /* points. */
702 /* */
703 /* NAME I/O DESCRIPTION */
704 /* ---- --- ----------- */
705 /* p I 2 x 2 array holding the 4 tabulated values */
706 /* x I x coordinates to interpolate at */
707 /* y I y coordinates to interpolate at */
708 /* z O array of interpolated values */
709 /* */
710 
711 /* ------------------------------------------------------ */
712 int bilinear(float p[PSIZE][PSIZE], float x[NS][NP],
713  float y[NS][NP], float z[NS][NP]) {
714  /* Cleanup and fix bilinear routine JMG 06/08/01 */
715 
716  float dx1[NS][NP], dy1[NS][NP];
717 
718  int i, j, a, b, c, d;
719 
720  /* create the arrays with elements 1 - (element from dx)
721  or 1- (element from dy) */
722  for (i = 0; i < NS; i++) {
723  for (j = 0; j < NP; j++) {
724  dx1[i][j] = 1. - x[i][j];
725  dy1[i][j] = 1. - y[i][j];
726  }
727  }
728 
729  /* calculate interpolated values */
730  for (i = 0; i < NS; i++) {
731  for (j = 0; j < NP; j++) {
732 
733  a = 0;
734  b = 0;
735  c = 1;
736  d = 1;
737 
738  z[j][i] = p[a][b] * dx1[i][j] * dy1[i][j] +
739  p[a][c] * dx1[i][j] * y[i][j] +
740  p[d][b] * x[i][j] * dy1[i][j] +
741  p[d][c] * x[i][j] * y[i][j];
742  }
743  }
744  return (0);
745 }
746 
747 int rd_gscan(void) {
748  FILE *fp;
749  char line[255];
750  int iband = 0;
751  char *tmp_str;
752  char file[1024];
753  int n;
754 
755  if ((tmp_str = getenv("OCDATAROOT")) == NULL) {
756  printf("OCDATAROOT environment variable is not defined.\n");
757  return (1);
758  }
759  strcpy(file, tmp_str);
760  strcat(file, "/mos/cal/relgain");
761  if ((fp = fopen(file, "r")) == NULL) {
762  printf("Error on opening the MOS relative cal file - %s\n", file);
763  return (1);
764  }
765 
766  while ((fgets(line, 255, fp) != NULL) && (iband < 8)) {
767 
768  /* skip the comment or blank line */
769  if (line[0] == '#' || line[0] == ' ' || line[0] == '\0' || line[0] == '\n')
770  continue;
771 
772  n = sscanf(line, "%f, %f, %f, %f",
773  &gscan[iband][0], &gscan[iband][1],
774  &gscan[iband][2], &gscan[iband][3]);
775 
776  if (n != 4) {
777  printf("Error in format of %s\n", file);
778  return (1);
779  }
780 
781  iband++;
782 
783  }
784 
785  return (0);
786 }
int32 l1file(int32 sdfid, int32 *nsamp, int32 *nscans, int16 *dtynum)
Definition: l1stat_chk.c:586
const int bindx[3]
Definition: DbLutNetcdf.cpp:28
char * GetFileDesc(const char *filename)
Definition: hdf_utils.c:752
float data_2d_t[NP]
Definition: l1_mos_hdf.c:57
int j
Definition: decode_rs.h:73
#define SPACE
Definition: l1_mos_hdf.c:30
int status
Definition: l1_czcs_hdf.c:32
double yds2unix(int16_t year, int16_t day, double secs)
Definition: yds2unix.c:7
int16 * gain
Definition: l1_czcs_hdf.c:33
int closel1_mos_hdf(filehandle *l1file)
Definition: l1_mos_hdf.c:469
int32_t TimeToSec(int32_t yr, int32_t mo, int32_t dm, int32_t hr, int32_t mn, int32_t sec)
Definition: l1_mos_hdf.c:573
#define NULL
Definition: decode_rs.h:63
read l1rec
int ReadSDS(filehandle *l1file)
Definition: l1_mos_hdf.c:492
float * lat
#define PSIZE
Definition: l1_mos_hdf.c:29
int LeapChk(int32_t yr)
Definition: l1_mos_hdf.c:659
#define MAXLEN
Definition: l1_mos_hdf.c:28
#define NP
Definition: l1_mos_hdf.c:25
float image_t[NP][NBANDS_MOS]
Definition: l1_mos_hdf.c:71
#define NUM
Definition: l1_mos_hdf.c:31
int rd_gscan(void)
Definition: l1_mos_hdf.c:747
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
int32_t GetTime(char arr[MAXLEN])
Definition: l1_mos_hdf.c:543
#define NBANDS_MOS
Definition: l1_mos_hdf.c:32
int GetYearDayMsec(double dtime[NS])
Definition: l1_mos_hdf.c:606
#define NB
Definition: l1_mos_hdf.c:27
read recnum
make_L3 README txt Compiling set environment variables for HDBLIB and HDFINC to the appropriate HDF4 lib and include directories make_L3_v1 c o make_L3 LIB lib a I LIB I $HDFINC L $HDFLIB lmfhdf ldf lz ljpeg lm lmalloc Running make_L3 takes input from standard so the SeaWIFS level files should be piped to the program via the command line as in to be allocated by the program to buffer the compositing The the better Ideally it should be to fit the entire global image(with all the layers) at once. Otherwise the process will be buffered on disk. -bufstep
uint16_t array_data_t[NS]
Definition: l1_mos_hdf.c:53
integer, parameter double
int openl1_read_mos_hdf(filehandle *l1file)
Definition: l1_mos_hdf.c:101
data_t b[NROOTS+1]
Definition: decode_rs.h:77
#define HDF4_UTILS_MAX_DIM
Definition: hdf4utils.h:12
int bilinear(float p[PSIZE][PSIZE], float x[NS][NP], float y[NS][NP], float z[NS][NP])
Definition: l1_mos_hdf.c:712
#define fabs(a)
Definition: misc.h:93
Extra metadata that will be written to the HDF4 file l2prod rank
int RemoveWhitespace(char arr[MAXLEN])
Definition: l1_mos_hdf.c:682
float * lon
#define NS
Definition: l1_mos_hdf.c:26
#define HDF4_UTILS_MAX_NAME
Definition: hdf4utils.h:11
logical function leap(YEAR)
Definition: leap.f:10
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
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to a
Definition: HISTORY.txt:424
int readl1_mos_hdf(filehandle *l1file, int32_t recnum, l1str *l1rec)
Definition: l1_mos_hdf.c:388
int k
Definition: decode_rs.h:73
float p[MODELMAX]
Definition: atrem_corl1.h:131