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