OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
getanc.c
Go to the documentation of this file.
1 /*-----------------------------------------------------------------------------
2  File: getanc.c
3 
4  Contents:
5  get_ancillary - will open ancillary data product or climatology
6  files when required, retrieve the ancillary data,
7  perform the interpolations, and close any open
8  files.
9  set_files - sets file1 and file2 from input file names depend-
10  ing upon syear, sday and eday
11  set_file_dt - sets file1, file2 and dt1 and dt2 from input file
12  names depending upon the time of the current scane line
13  ck_files_in_buf - checks whether the requested data is already in
14  the buffers and if so, sets the rd_flag.
15  read_climatology - reads climatology data file
16  read_NRT - reads ancillary NRT data file/s
17  extract_data_pts - extracts 4 surrounding coords and corresponding
18  data for the given lat/lon
19  gregor - converts julian day into gregorian month/day
20  interpolate - initializes/sets parameters and calls dataintp rtn.
21  dataintp_ - returns interpolated value for the given surrounding
22 
23  Notes:
24 
25  Other relevant files:
26  anc.h - various #defined constants for ancillary data, also
27  includes hdf.h
28  ancproto.h - prototypes for ancillary data input routines
29  HDFroutines.c - a lower layer of ancillary data input functions
30  dataintp.f - interpolation routine
31 
32  Modification history:
33  Programmer Organization Date Description of change
34  -------------- ------------ -------- ---------------------
35  Lakshmi Kumar Hughes STX 04/02/93 Original development
36  Lakshmi Kumar Hughes STX 12/07/93 Modified to incorporate
37  HDF3.3r1 changes
38  Lakshmi Kumar Hughes STX 01/04/94 Corrected dims bug
39  Lakshmi Kumar Hughes STX 06/21/94 Incorporated I/O Specs
40  v3.0 and v3.2 changes
41  Lakshmi Kumar HITC 05/25/95 Modified to read data
42  from the new redesigned
43  ancillary data files
44  (Ref: I/O specs V4.3 &
45  product specs V2.7)
46  Lakshmi Kumar Hughes STX 08/10/95 Initialized DT1 & DT2 to
47  zero
48  Lakshmi Kumar Hughes STX 10/10/95 Removed PA_flag from
49  input arguments to rtn
50  "get_ancillary". Changed
51  time checking logic
52  (ref: V4.4 I/O specs)
53  Lakshmi Kumar Hughes STX 11/27/95 Changed the order of data
54  pts in data_list1 &
55  data_list2
56  Lakshmi Kumar Hughes STX 11/28/95 changed the logic of
57  choosing files based on
58  file's start and end times
59  rather than its mean time
60  Changed extract_data_pts
61  logic to send 4 diff pts
62  always to interp rtn
63  Lakshmi Kumar Hughes STX 03/08/96 changed ftime structure
64  and moved it from hfile
65  to this file to avoid
66  re inclusion warning msgs.
67  Lakshmi Kumar Hughes STX 04/18/96 Removed a redundant loop.
68  Lakshmi Kumar Hughes STX 08/02/96 Removed unused variables
69  & redefined MAX as MAXVAL
70  Lakshmi Kumar Hughes STX 10/24/96 when parm_flag = 3,
71  precipitable water is
72  accessed instead of
73  humidity (ref. V3.0
74  product specs.)
75  Lakshmi Kumar Hughes STX 01/17/97 made changes to use range
76  & def values of humidity
77  when PA_flag is set and
78  parm_flag = 3, as clima-
79  tology files at present
80  contain humidity not
81  precipitable water.
82  Lakshmi Kumar Hughes STX 02/25/97 Made changes to allow
83  access to both humidity
84  & precipitable water.
85  Accesses humidity when
86  param_flag = 5 and
87  precipitable water when
88  param_flag = 3. Removed
89  non-prototype declarations
90  Lakshmi Kumar Hughes STX 07/07/97 Added 'get_ancillary_' to
91  allow Fortran interface.
92  Lakshmi Kumar Hughes STX 08/25/97 Incorporated Miami's
93  binary search.
94  Ewa Kwiatkowska GSC 11/12/99 Time reference for TOMS data
95  added.
96  Don Shea SAIC 3/20/09 moved function BinarySearch
97  so prototype not necessary
98  in ancproto.h
99 
100 -----------------------------------------------------------------------------*/
101 
102 #include <mfhdf.h>
103 #include "anc.h"
104 #include "ancproto.h"
105 
106 #include <genutils.h>
107 
108 /* Private Global Variables */
111 char ERR_MSG[1024];
112 
113 #define FLIMIT 12
114 
115 #define BS_INCR 0 /* increasing order */
116 #define BS_DECR 1 /* decreasing order */
117 
118 static int BinarySearch(int dim, float *bufp, float val, int order,
119  int16 *lower, int16 *upper) {
120  int lo, hi, mid;
121  int n = 0;
122 
123  lo = 0;
124  hi = dim - 1;
125 
126  /* quick checks to see if value still bounded in last interval */
127  /* and some additional optimizations for (just) outside last interval */
128  if (*lower >= 0 && *upper >= 0) {
129  int Lo, Hi;
130 
131  Lo = *lower;
132  Hi = *upper;
133  if (order == BS_INCR) {
134  if (bufp[Lo] <= val && val <= bufp[Hi]) {
135  /* bounded in last interval */
136  return n;
137  }
138  if (val < bufp[Lo]) {
139  if (Lo > 0 && bufp[Lo - 1] <= val && val <= bufp[Lo]) {
140  /* slide one index lower */
141  *lower = Lo - 1;
142  *upper = Lo;
143  return n;
144  }
145  hi = Lo; /* bounded above */
146  } else {
147  if (Hi < dim - 1 && bufp[Hi] <= val && val <= bufp[Hi + 1]) {
148  /* slide one index higher */
149  *lower = Hi;
150  *upper = Hi + 1;
151  return n;
152  }
153  lo = Hi; /* bounded below */
154  }
155  } else {
156  if (bufp[Lo] >= val && val >= bufp[Hi]) {
157  /* bounded in last interval */
158  return n;
159  }
160  if (val > bufp[Lo]) {
161  if (Lo > 0 && bufp[Lo - 1] >= val && val >= bufp[Lo]) {
162  /* slide one index lower */
163  *lower = Lo - 1;
164  *upper = Lo;
165  return n;
166  }
167  hi = Lo; /* bounded above */
168  } else {
169  if (Hi < dim - 1 && bufp[Hi] >= val && val >= bufp[Hi + 1]) {
170  /* slide one index higher */
171  *lower = Hi;
172  *upper = Hi + 1;
173  return n;
174  }
175  lo = Hi; /* bounded below */
176  }
177  }
178  }
179 
180  /* perform standard binary search */
181  if (order == BS_INCR) {
182  /* ascending order list */
183  /* bufp[lower] < val < bufp[upper] */
184  /* or bufp[lower=upper] = val */
185  if (val < bufp[0] || val > bufp[dim - 1]) {
186  *lower = *upper = -1;
187  return n;
188  }
189  for (;;) {
190  mid = (hi + lo) / 2;
191  n++;
192  if (bufp[mid] > val)
193  hi = mid;
194  else
195  lo = mid;
196  if (lo == hi - 1) {
197  *lower = lo;
198  *upper = hi;
199  return n;
200  }
201  }
202  } else {
203  /* descending order list */
204  /* bufp[lower] > val > bufp[upper] */
205  /* or bufp[lower=upper] = val */
206  if (val > bufp[0] || val < bufp[dim - 1]) {
207  *lower = *upper = -1;
208  return n;
209  }
210  for (;;) {
211  mid = (hi + lo) / 2;
212  n++;
213  if (bufp[mid] < val)
214  hi = mid;
215  else
216  lo = mid;
217  if (lo == hi - 1) {
218  *lower = lo;
219  *upper = hi;
220  return n;
221  }
222  }
223  }
224 }
225 
226 /*-----------------------------------------------------------------------------
227  Function: get_ancillary
228 
229  Returns: int32 (status)
230  The return code is a negative value if any error occurs.
231 
232  Description:
233  The function get_ancillary calls appropiate functions to perform
234  the open, read, and closing of the required files and to perform
235  the interpolations for the given coordinates.
236  See "INTERFACE SPECIFICATIONS FOR SeaWiFS OPERATIONAL PRODUCT
237  INPUT AND OUTPUT SOFTWARE" (By F. Patt, J. Firestone and M. Darzi)
238  and SeaWiFS ANCILLARY DATA FORMAT (HDF) (By J. Firestone, M. Darzi)
239  for details.
240 
241  Parameters: (in calling order)
242  Type Name I/O Description
243  ---- ---- --- -----------
244  float32 lat I An array of latitudes
245  float32 lon I An array of longitudes
246  int16 nsamp I Count of pixels (no. of lats/lons)
247  int16 syear I year of data start time
248  int16 sday I day-of-year for data start time
249  int16 eday I day-of-year for data end time
250  int32 msec I time in milliseconds
251  char * filename1 I name of the ancillary data product for the
252  nearest time preceding the scan time or
253  the corresponding climatology
254  char * filename2 I name of the ancillary data product for the
255  nearest time following the scan time
256  if = NULL then read file1 for climatology
257  char * filename3 I name of the anc data product for the near-
258  est tm following the l-1A's last scan-
259  line's time
260  char * anc_cor_file I ancillary data correction file
261  int16 Parm_flag I Flag indicating the parameter whose data
262  are to be returned in interp:
263  0 - zonal wind component(meters/sec),
264  1 - meridional wind component,
265  2 - surface pressure (millibars)
266  3 - precipitable water(kg m^-2)
267  4 - total ozone (Dobson units).
268  5 - relative humidity (percent)
269  float * interp O Interpolated data points
270  float * anc_unc O ancillary data value uncertainty
271  int16 * qcflag O array corresponding to interp values,
272  containing flags indicating the integrity
273  of those values:
274  if = 0: all grid pts used in
275  interpolation were not suspect
276  if = 1: suspect grid points used in
277  interpolation
278 
279 
280  Modification history:
281  Programmer Organization Date Description of change
282  -------------- ------------ -------- ---------------------
283  Lakshmi Kumar Hughes STX 04/02/93 Original development
284  Lakshmi Kumar Hughes STX 12/09/93 Incorporated HDF3.3r1 changes and
285  updated comments.
286  Lakshmi Kumar Hughes STX 01/04/94 Corrected dimensions problem
287  Lakshmi Kumar Hughes STX 06/21/94 Incorporated I/O Specs v3.0 and
288  v3.2 changes
289  Lakshmi Kumar Hughes STX 10/10/05 Removed PA_flag as input argument
290  Lakshmi Kumar Hughes STX 10/24/96 when parm_flag = 3, precipitable
291  water is accessed instead of
292  humidity (ref. V3.0 product specs.)
293  Lakshmi Kumar Hughes STX 02/25/97 Added parm_flag = 5 for accessing
294  relative humidity
295 ----------------------------------------------------------------------------*/
296 
297 int get_ancillary(float *lat, float *lon, int16_t nsamp, int16_t syear,
298  int16_t sday, int16_t eday, int32_t msec, char *filename1,
299  char *filename2, char *filename3, char *anc_cor_file,
300  int16_t parm_flag, float *interp, float *anc_unc,
301  int16_t *qcflag) {
302 
303  int32 i, ret = 0;
304  int16 PA_flag = 0, read_flag, day, month=0;
305  intn toms; /* BOOLEAN value whether EP TOMS data are used */
306  typedef int8 qc_buf_t[NPARMS][LAT * LON];
307  static qc_buf_t *qc_buf; /* NPARMS = 6(uvppoh) */
308  typedef float32 uvpph_buf_t[NPARMS - 1][LAT * LON];
309  static uvpph_buf_t *uvpph_buf; /* oz has its own buf */
310  static float32 *c_uvpph_lat; /* buf for clim lats */
311  static float32 *c_uvpph_lon; /* buf for clim lons */
312  static float32 *nrt_uvpph_lat; /* buf for nrt lats */
313  static float32 *nrt_uvpph_lon; /* buf for nrt lons */
314  static float32 *oz_lat; /* buf for oz lats */
315  static float32 *oz_lon; /* buf for oz lons */
316  static float32 *lat_buf;
317  static float32 *lon_buf;
318  typedef int16 oz_buf_t[LAT * LON];
319  static oz_buf_t *oz_buf;
320  static int32 oz_dims[2] = {0, 0}; /* array to hold dimensions */
321  static int32 c_uvpph_dims[2] = {0, 0}; /*array to hold dimensions */
322  static int32 nrt_uvpph_dims[2] = {0, 0}; /* array to hold dimensions */
323  int32 *dims; /* array to hold dimensions */
324  static int16 error_flag = -1; /* flag indicating prev read error */
325  timech DT1, DT2; /* delta time1 and time 2 for the scan line */
326  float32 lat_list[4]; /* surrounding lats of -1 time step*/
327  float32 lon_list[4]; /* surrounding lons of -1 time step*/
328  char file1[MAXVAL], file2[MAXVAL]; /* local variable for input files */
329  char *FUNC = "get_ancillary";
330 
331  // allocate data
332  if (qc_buf == NULL) {
333  qc_buf = (qc_buf_t*) allocateMemory(NFILE * sizeof (qc_buf_t), "qc_buf");
334  uvpph_buf = (uvpph_buf_t*) allocateMemory(NFILE * sizeof (uvpph_buf_t), "uvpph_buf");
335  c_uvpph_lat = (float32*) allocateMemory(LAT * sizeof (float32), "c_uvpph_lat");
336  c_uvpph_lon = (float32*) allocateMemory(LON * sizeof (float32), "c_uvpph_lon");
337  nrt_uvpph_lat = (float32*) allocateMemory(LAT * sizeof (float32), "nrt_uvpph_lat");
338  nrt_uvpph_lon = (float32*) allocateMemory(LON * sizeof (float32), "nrt_uvpph_lon");
339  oz_lat = (float32*) allocateMemory(LAT * sizeof (float32), "oz_lat");
340  oz_lon = (float32*) allocateMemory(LON * sizeof (float32), "oz_lon");
341  oz_buf = (oz_buf_t*) allocateMemory(NFILE * sizeof (oz_buf_t), "oz_buf");
342  }
343 
344  /* need to init these, to avoid test of unititialized values when not TOMS */
345  toms = FAIL;
346  DT1.start = 0.0;
347  DT1.inc = 0.0;
348  DT2.start = 0.0;
349  DT2.inc = 0.0;
350 
351  /*** check filenames */
352  if (filename1 == NULL || filename1[0] == 0) {
353  printf("****ERROR: %s: File name error: filename1 equals NULL", FUNC);
354  return FAIL;
355  }
356 
357  if (filename2 == NULL || filename2[0] == 0)
358  PA_flag = 1;
359  else
360  if (filename3 == NULL || filename3[0] == 0) {
361  printf("****ERROR: %s: File name error: filename3 equals NULL ", FUNC);
362  return FAIL;
363  }
364 
365  for (i = 0; i < nsamp; i++)
366  qcflag[i] = -1;
367 
368  if (parm_flag < 0 || parm_flag > 5) {
369  printf("****ERROR: %s: Invalid parm_flag input ", FUNC);
370  return FAIL;
371  }
372 
373  if (parm_flag == OZONE) {
374  parm_buf1 = (void *) oz_buf[F1];
375  parm_buf2 = (void *) oz_buf[F2];
376  lat_buf = (float *) oz_lat;
377  lon_buf = (float *) oz_lon;
378  dims = oz_dims;
379  } else {
380  if (parm_flag == 5) { /* relative humidity */
381  parm_buf1 = (void *) uvpph_buf[F1][4];
382  parm_buf2 = (void *) uvpph_buf[F2][4];
383  } else {
384  parm_buf1 = (void *) uvpph_buf[F1][parm_flag];
385  parm_buf2 = (void *) uvpph_buf[F2][parm_flag];
386  }
387  if (PA_flag) {
388  lat_buf = (float *) c_uvpph_lat;
389  lon_buf = (float *) c_uvpph_lon;
390  dims = c_uvpph_dims;
391  } else {
392  lat_buf = (float *) nrt_uvpph_lat;
393  lon_buf = (float *) nrt_uvpph_lon;
394  dims = nrt_uvpph_dims;
395  }
396  }
397 
398  if (PA_flag) {
399  gregor(sday, syear, &month, &day); /* convert julian day to */
400  strcpy(file1, filename1); /* gregorian month and day */
401  } else
402  if ((set_files(parm_flag, syear, sday, eday, msec,
403  filename1, filename2, filename3, file1, file2, &DT1, &DT2, &toms)) < 0) {
404  printf("\n****ERROR: %s: %s\n", FUNC, ERR_MSG);
405  return FAIL;
406  }
407 
408  if ((ck_files_in_buf(PA_flag, parm_flag, file1, file2, month,
409  &error_flag, &read_flag)) < 0) {
410  printf("\n****ERROR: %s: %s\n", FUNC, ERR_MSG);
411  return FAIL;
412  }
413 
414  if (read_flag) {
415 
416  if (PA_flag == 1)
417  ret = read_climatology(file1, parm_flag, month,
418  dims, lat_buf, lon_buf, parm_buf1);
419  else
420  ret = read_NRT(file1, file2, anc_cor_file, parm_flag, read_flag, dims,
421  lat_buf, lon_buf, parm_buf1, parm_buf2,
422  qc_buf[F1][parm_flag], qc_buf[F2][parm_flag]);
423  }
424 
425 
426  if (ret >= 0)
427  extract_data_pts(PA_flag, parm_flag, DT1, DT2, nsamp, lat, lon, lat_buf,
428  lon_buf, dims, qc_buf[F1][parm_flag], qc_buf[F2][parm_flag],
429  parm_buf1, parm_buf2, toms, lat_list, lon_list, qcflag,
430  interp, anc_unc);
431 
432  else {
433  error_flag = parm_flag;
434  for (i = 0; i < nsamp; i++)
435  interp[i] = 0;
436  printf("\n****ERROR: %s: %s\n", FUNC, ERR_MSG);
437  return FAIL;
438  }
439 
440  return SUCCEED;
441 }
442 
443 intn get_ancillary_(float32 *lat, float32 *lon, int16 nsamp, int16 syear,
444  int16 sday, int16 eday, int32 msec, char *filename1,
445  char *filename2, char *filename3, char *anc_cor_file,
446  int16 parm_flag, float32 *interp, float32 *anc_unc,
447  int16 *qcflag) {
448  return get_ancillary(lat, lon, nsamp, syear, sday, eday, msec,
449  filename1, filename2, filename3, anc_cor_file,
450  parm_flag, interp, anc_unc, qcflag);
451 }
452 
453 /*----------------------------------------------------------------------------
454  Function: check_on_TOMS
455 
456  Returns: FAIL for applying the conventional approximation scheme;
457  SUCCEED for applying EP TOMS with nearest-time approximation scheme.
458 
459  Arguments: (in calling order)
460  Type Name I/O Description
461  ---- ---- --- -----------
462  int16 parm_flag I indicates wh parm it is being processed
463  char * filename1 I name of the ancillary data product for the
464  nearest time preceding the scan time or
465  the corresponding climatology
466  char * filename2 I name of the ancillary data product for the
467  nearest time following the scan time
468  if = NULL then read file1 for climatology
469  char * filename3 I name of the anc data product for the near-
470  est tm following the l-1A's last scan-
471  line's time
472  float32 * in_lonlist I input longitude array
473  int16 nsamp I number of scan line points
474  float64 s_jd1 I Julian time for the start of auxilliary filename1
475  float64 s_jd2 I Julian time for the start of auxilliary filename2
476  float64 s_jd3 I Julian time for the start of auxilliary filename3
477  float64 e_jd1 I Julian time for the end of auxilliary filename1
478  float64 e_jd2 I Julian time for the end of auxilliary filename2
479  float64 e_jd3 I Julian time for the end of auxilliary filename3
480  float64 d_jd I Julian time for the data scan line
481  timech * dt1 O Time diff bet actual time & time step 1
482  timech * dt2 O Time diff bet actual time & time step 2
483 
484  History:
485  Programmer Organization Date Description of change
486  -------------- ------------ -------- ---------------------
487  Ewa Kwiatkowska GSC 11/12/99 Function fully programmed
488  */
489 
490 int check_on_TOMS(int16_t parm_flag, char *file1, char *file2,
491  char *filename1, char *filename2, char *filename3, double s_jd1,
492  double s_jd2, double s_jd3, double e_jd1, double e_jd2,
493  double e_jd3, double d_jd, timech *dt1, timech *dt2) {
494 
495 
496  if (strcmp(file1, file2) == 0) {
497  //printf ("\n\n check_on_TOMS failed" );
498  return FAIL;
499  }
500  if (parm_flag != OZONE) {
501  //printf ("\n\n check_on_TOMS failed" );
502  return FAIL;
503  };
504 
505  //length = strlen( file1 );
506  //if (strcmp (((char *)(&(file1[length-10]))), "TOMS.OZONE" ) != 0) {
507 
508  if ((strstr(file1, "TOMS") == NULL) &&
509  (strstr(file1, "OMI") == NULL)) {
510  //printf ("\n\n check_on_TOMS detected non TOMS OZONE file" );
511  return FAIL;
512  };
513 
514  //length = strlen( file2 );
515  //if (strcmp (((char *)(&(file2[length-10]))), "TOMS.OZONE" ) != 0) {
516 
517  if ((strstr(file2, "TOMS") == NULL) &&
518  (strstr(file2, "OMI") == NULL)) {
519  //printf ("\n\n check_on_TOMS detected non TOMS OZONE file" );
520  return FAIL;
521  };
522 
523 
524  if ((strcmp(file1, filename1)) == 0) {
525 
526  dt1->start = d_jd - (e_jd1 + s_jd1) / 2.0;
527  dt1->inc = (e_jd1 - s_jd1) / 360.0; /*358.75;*/
528  } else
529  if ((strcmp(file1, filename2)) == 0) {
530 
531  dt1->start = d_jd - (e_jd2 + s_jd2) / 2.0;
532  dt1->inc = (e_jd2 - s_jd2) / 360.0; /*358.75;*/
533  } else
534  return FAIL;
535 
536  if ((strcmp(file2, filename2)) == 0) {
537 
538  dt2->start = d_jd - (e_jd2 + s_jd2) / 2.0;
539  dt2->inc = (e_jd2 - s_jd2) / 360.0; /*358.75;*/
540  } else
541  if ((strcmp(file2, filename3)) == 0) {
542 
543  dt2->start = d_jd - (e_jd3 + s_jd3) / 2.0;
544  dt2->inc = (e_jd3 - s_jd3) / 360.0; /*358.75;*/
545  } else
546  return FAIL;
547 
548 
549 
550  //printf ("\n\n Check on TOMS has been successful\n\n" ) ; exit(1);
551 
552  return SUCCEED;
553 
554 }
555 
556 /*----------------------------------------------------------------------------
557  Function: read_climatology
558 
559  Returns: int32 (Status)
560  The return code is FAIL (-1) if an error occurs. Otherwise, SUCCEED (0)
561 
562  Description:
563  The function read_climatology will be called if the climatology file
564  needs to be read. It opens the file and calls appropriate functions
565  to read the requested months data in to the given data buffer and
566  lat/lon to the latitude and longitude buffers.
567 
568  Arguments: (in calling order)
569  Type Name I/O Description
570  ---- ---- --- -----------
571  char * file1 I Climatology file name
572  int16 parm_flag I Parameter flag identifying the parameter
573  to be read
574  int16 month I data month
575  int32 * dims O dimensions of the data
576  float32 * lat_buf O buffer containing latitude data
577  float32 * lon_buf O buffer containing longitude data
578  float32 * parm_buf O buffer containing parameter data
579 
580  Modification history:
581  Programmer Organization Date Description of change
582  -------------- ------------ -------- ---------------------
583  Lakshmi Kumar Hughes STX 04/02/93 Original development
584  Lakshmi Kumar Hughes STX 12/09/93 Incorporated HDF3.3r1
585 -----------------------------------------------------------------------------*/
586 int read_climatology(char *file1, int16_t parm_flag, int16_t month,
587  int32_t *dims, float *lat_buf,
588  float *lon_buf, void *parm_buf) {
589  if ((openHDF(file1, &sdfid1, &fid1)) < 0)
590  return FAIL;
591 
592  if ((get_clim_data(fid1, sdfid1, parm_flag, month,
593  dims, lat_buf, lon_buf, parm_buf)) < 0)
594  return FAIL;
595 
596  if ((closeHDF(sdfid1, fid1)) < 0)
597  return FAIL;
598  return SUCCEED;
599 }
600 
601 /*-----------------------------------------------------------------------------
602  Function: read_NRT
603 
604  Returns: int32 (Status)
605  The return code is FAIL (-1) if an error occurs. Otherwise, SUCCEED (0)
606 
607  Description:
608  The function read_NRT will be called if the Near Real Time file/s
609  needs to be read. It opens the file and calls appropriate functions
610  to read the requested data in to the given data buffer and
611  lat/lon to the latitude and longitude buffers.
612 
613  Arguments: (in calling order)
614  Type Name I/O Description
615  ---- ---- --- -----------
616  char * file1 I NRT file with the nearest time preceding
617  the scan time
618  char * file2 I NRT file with the nearest time following
619  the scan time
620  char * anc_cor_file I ancillary data correction file
621  int16 parm_flag I Parameter flag identifying the parameter
622  to be read
623  int16 rd_flag I flag indicating wh file to read:
624  1 for file1, 2 for file2 and 3 for
625  file1 and file2
626  int32 * dims O dimensions of the data
627  float32 * lat_buf O buffer containing latitude data
628  float32 * lon_buf O buffer containing longitude data
629  float32 * parm_buf1 O buffer containing parameter data of file1
630  float32 * parm_buf2 O buffer containing parameter data of file2
631  int8 * qc_buf1 O buffer containing qc flags of the given
632  parameter from file1
633  int8 * qc_buf2 O buffer containing qc flags of the given
634  parameter from file2
635 
636  Modification history:
637  Lakshmi Kumar Hughes STX 04/02/93 Original development
638 
639  Lakshmi Kumar Hughes STX 12/09/93 Incorporated HDF3.3r1 changes
640  W. Robinson, SAIC 4 Dec 2013 added code to handle anc array size
641  mismatch for ozone (in lon dimension) but fail for
642  other products and lat # mismatch
643  also pass in name of ancillary correction file
644 ------------------------------------------------------------------------------*/
645 int read_NRT(char *file1, char *file2, char *anc_cor_file, int16_t parm_flag,
646  int16_t rd_flag, int32_t *dims, float *lat_buf,
647  float *lon_buf, void *parm_buf1, void *parm_buf2,
648  int8_t *qc_buf1, int8_t *qc_buf2) {
649  int32 i;
650  static float32 *lon_buf_p4;
651  static int32 lon_dim_p4;
652 
653  if (lon_buf_p4 == NULL) {
654  lon_buf_p4 = (float32*) allocateMemory(LON * sizeof (float32), "lon_buf_p4");
655  }
656 
657  if (rd_flag == 1 || rd_flag == 3) {
658  if ((openHDF(file1, &sdfid1, &fid1)) < 0)
659  return FAIL;
660  if ((get_NRT_data(fid1, sdfid1, anc_cor_file, parm_flag, dims,
661  lat_buf, lon_buf, parm_buf1, qc_buf1)) < 0)
662  return FAIL;
663  if ((closeHDF(sdfid1, fid1)) < 0)
664  return FAIL;
665  if (parm_flag == 4) {
666  lon_dim_p4 = dims[1];
667  for (i = 0; i < dims[1]; i++)
668  lon_buf_p4[i] = lon_buf[i];
669  }
670  }
671 
672 
673  if (rd_flag == 2 || rd_flag == 3) {
674  if ((openHDF(file2, &sdfid2, &fid2)) < 0)
675  return FAIL;
676  if ((get_NRT_data(fid2, sdfid2, anc_cor_file, parm_flag, dims,
677  lat_buf, lon_buf, parm_buf2, qc_buf2)) < 0)
678  return FAIL;
679  if ((closeHDF(sdfid2, fid2)) < 0)
680  return FAIL;
681  if ((parm_flag == 4) && (dims[1] != lon_dim_p4)) {
682  /*
683  * in rare case where the 2 ozone arrays are different in lon size
684  * as between EP and AURA , make the parm_buf1 the same size as parm_buf2
685  */
686  printf(
687  "%s, %d - I: Detect different longitude size in ancilary data\n",
688  __FILE__, __LINE__);
689  printf(" adapting file1\n");
690  printf(" file1: %s\n", file1);
691  printf(" file2: %s\n", file2);
692  /* resize array 1 to size of array 2 */
693  resiz_anc((int16 *) parm_buf1, qc_buf1, dims[0], lon_dim_p4, dims[1],
694  lon_buf_p4, lon_buf);
695  }
696  }
697  return SUCCEED;
698 }
699 
700 /*-----------------------------------------------------------------------------
701  Function: resiz_anc
702  Returns: None
703  Description:
704  resize a data and qc array in the longitude dimension to match that of
705  another array. Use simple lineas interpolation
706 
707  Type Name I/O Description
708  ---- ---- --- -----------
709  int16 * data I/O data array to resize (size change:
710  nlat, nlon1 -> nlat, nlon2)
711  int8 * qc I/O qc array
712  int32 nlat I # points in latitude
713  int32 nlon1 I # lon points in input array
714  int32 nlon2 I # lon points in final array
715  float32 * lons1 I input longitude array
716  float32 * lons2 I final longitude array
717 
718  W. Robinson, SAIC, 3 Dec 2013 Original development
719  Note that this oonly applies to the ozone, which comes in int16 size
720 
721 -----------------------------------------------------------------------------*/
722 void resiz_anc(int16_t *data, int8_t *qc, int32_t nlat, int32_t nlon1, int32_t nlon2,
723  float * lons1, float * lons2) {
724  int32 ix, ilon, ilat, intloc, ix1, ix2;
725  float st1, del1, lonwt, wt1, wt2, lon, floc;
726  int8 *cp_qc, q_fin, q1, q2;
727  int16 *cp_data, dat1, dat2, dat_fin;
728  /*
729  * we assume a ( -180 -> 180 ) system for both arrays
730  */
731  st1 = lons1[0];
732  del1 = lons1[1] - st1;
733  /*
734  * allocate a temporary storage for the data and qc and copy it to these
735  */
736  cp_data = (int16 *) malloc(nlat * nlon1 * sizeof ( int16));
737  cp_qc = (int8 *) malloc(nlat * nlon1 * sizeof ( int8));
738 
739  memcpy(cp_data, data, nlat * nlon1 * sizeof ( int16));
740  memcpy(cp_qc, qc, nlat * nlon1 * sizeof ( int8));
741  /*
742  * Note ix is the index of the values in data to interpolate (with ix + 1)
743  * when mapping to the final array. lonwt is weight to apply
744  */
745  for (ilon = 0; ilon < nlon2; ilon++) {
746  lon = lons2[ilon];
747  floc = (lon - st1) / del1;
748  intloc = (int) (floc + 1.) - 1; /* the '1' makes sure the lon is
749  always ahead of what is pointed to by iloc */
750  lonwt = floc - (float) intloc;
751  intloc = (intloc < 0) ? (nlon1 - 1) : intloc;
752  ix = intloc;
753  /*
754  * do the interpolation for the row of latitudes at this longitude
755  */
756  ix1 = ix;
757  ix2 = (ix1 == nlon1 - 1) ? 0 : ix + 1;
758  wt1 = 1. - lonwt;
759  wt2 = lonwt;
760  for (ilat = 0; ilat < nlat; ilat++) {
761  dat1 = *(cp_data + ix1 + nlon1 * ilat);
762  dat2 = *(cp_data + ix2 + nlon1 * ilat);
763  /*
764  * only the new qc of 20 will indicate bad qc
765  */
766  q1 = (*(cp_qc + ix1 + nlon1 * ilat) == 20) ? 1 : 0;
767  q2 = (*(cp_qc + ix2 + nlon1 * ilat) == 20) ? 1 : 0;
768 
769  if ((q1 == 1) && (q2 == 1)) {
770  dat_fin = dat1;
771  q_fin = 20;
772  } else if ((q1 == 0) && (q2 == 1)) {
773  dat_fin = dat1;
774  q_fin = 0;
775  } else if ((q1 == 1) && (q2 == 0)) {
776  dat_fin = dat2;
777  q_fin = 0;
778  } else {
779  dat_fin = dat1 * wt1 + dat2 * wt2;
780  q_fin = 0;
781  };
782 
783  *(data + ilon + nlon2 * ilat) = dat_fin;
784  *(qc + ilon + nlon2 * ilat) = q_fin;
785  }
786  }
787  /*
788  * at the end, release workspace
789  */
790  free(cp_data);
791  free(cp_qc);
792 }
793 
794 /*-----------------------------------------------------------------------------
795  Function: extract_data_pts
796 
797  Returns: None
798 
799  Description:
800  The function extract_data_pts extracts the four surrounding data
801  points and the latitude/longitude points for the given coordinates
802  and calls interpolation routine to interpolate the data points.
803 
804  Arguments: (in calling order)
805  Type Name I/O Description
806  ---- ---- --- -----------
807  int16 PA_flag I product type: if 1, climatology else NRT
808  int16 parm_flag I indicates wh parm it is being processed
809  timech * DT1 I Time diff bet actual time & time step 1
810  timech * DT2 I Time diff bet actual time & time step 2
811  int16 nsamp I number of scan line points
812  float32 * in_latlist I input latitude array
813  float32 * in_lonlist I input longitude array
814  float32 * lat_bufp I latitude buffer
815  float32 * lon_bufp I longitude buffer
816  int32 * dims I dimensions of the data
817  int8 * qc_buf1 I buffer containing QC flags from file1
818  int8 * qc_buf2 I buffer containing QC flags from file2
819  void * parm_buf1 I buffer containing data from file1
820  void * parm_buf2 I buffer containing data from file2
821  intn toms; I BOOLEAN value whether EP TOMS data are used
822  float32 * out_lat_list O surrounding latitude points
823  float32 * out_lon_list O surrounding longitude points
824  int16 * qcflag O array corresponding to interp values,
825  containing flags indicating the
826  integrity of those values.
827  float32 * interp O interpolated values of the data
828  float32 * anc_unc O uncertainty in the ancillary value
829 
830  Modification history:
831  Lakshmi Kumar Hughes STX 04/02/93 Original development
832 
833  Lakshmi Kumar Hughes STX 12/09/93 Modified to call this rtn only
834  once for the given list of
835  lat/lons to avoid function call
836  overhead
837  Lakshmi Kumar Hughes STX 11/27/95 Changed the order of data pts
838  in data_list1 and data_list2
839  Lakshmi Kumar Hughes STX 07/02/97 fixed code to extract correct
840  4 corner pts when input lat/lon
841  lies outside the lat/lon buffs
842  Ewa Kwiatkowska GSC 11/12/99 Added parts supporting TOMS
843  ancillary specification
844  W Robinson, SAIC 4 Aug 2016 Pass through the ancillary
845  uncertainty: anc_unc
846 -----------------------------------------------------------------------------*/
847 void extract_data_pts(int16_t PA_flag, int16_t parm_flag, timech DTime1, timech DTime2,
848  int16_t nsamp, float *in_latlist, float *in_lonlist, float *lat_bufp,
849  float *lon_bufp, int32_t *dims, int8_t *qc_buf1, int8_t *qc_buf2,
850  void *parm_buf1, void *parm_buf2, int toms, float *out_lat_list,
851  float *out_lon_list, int16_t *qcflag, float *interp, float *anc_unc) {
852 
853  int8 qc1_vals[4];
854  int8 qc2_vals[4];
855  int16 i, p, lat_index1 = -1, lat_index2 = -1;
856  int16 lon_index1 = -1, lon_index2 = -1, index;
857  int16 *OZ_list1, *OZ_list2, outside = 0;
858  int16 *oz_p1, *oz_p2, loop;
859  int32 int_qc;
860  float32 in_lat, in_lon, *wph_p1, *wph_p2, data_list1[4], data_list2[4];
861  float32 *WPH_list1, *WPH_list2, gridstep;
862  float64 DT1, DT2;
863 
864 
865  OZ_list1 = (int16 *) data_list1;
866  OZ_list2 = (int16 *) data_list2;
867  oz_p1 = (int16 *) parm_buf1;
868  oz_p2 = (int16 *) parm_buf2;
869 
870  WPH_list1 = (float32 *) data_list1;
871  WPH_list2 = (float32 *) data_list2;
872  wph_p1 = (float32 *) parm_buf1;
873  wph_p2 = (float32 *) parm_buf2;
874 
875  gridstep = lon_bufp[1] - lon_bufp[0];
876 
877 
878  for (loop = 0; loop < nsamp; loop++) {
879 
880  in_lat = in_latlist[loop];
881  in_lon = in_lonlist[loop];
882  for (i = 0; i < 4; i++)
883  qc1_vals[i] = qc2_vals[i] = -1;
884 
885  lat_index1 = lat_index2 = -1;
886 #if 1
887  BinarySearch(dims[0], lat_bufp, in_lat, BS_DECR, &lat_index1,
888  &lat_index2);
889 #else
890  for (done = 0, i = 0; i < dims[0] && done == 0; i++) {
891  if (in_lat == lat_bufp[i]) {
892  lat_index1 = i;
893  if (i + 1 == dims[0])
894  lat_index2 = i - 1;
895  else
896  lat_index2 = i + 1;
897  done = 1;
898  }
899  else {
900  if (in_lat > lat_bufp[i]) {
901  lat_index1 = i - 1;
902  lat_index2 = i;
903  done = 1;
904  }
905  }
906  }
907 
908 #endif
909  if (lat_index1 == -1 && lat_index2 == -1) {
910  if (in_lat > 0)
911  lat_index1 = lat_index2 = 0;
912  else
913  lat_index1 = lat_index2 = dims[0] - 1;
914 
915  /* lat_index2 = dims[0] - 2; */
916  } else
917  if (lat_index1 == -1)
918  lat_index1 = 0;
919 
920  lon_index1 = lon_index2 = -1;
921 
922 #if 1
923  BinarySearch(dims[1], lon_bufp, in_lon, BS_INCR, &lon_index1,
924  &lon_index2);
925 #else
926  for (done = 0, i = 0; i < dims[1] && done == 0; i++) {
927  if (in_lon == lon_bufp[i]) {
928  lon_index1 = i;
929  if (i + 1 == dims[1])
930  lon_index2 = i - 1;
931  else
932  lon_index2 = i + 1;
933  done = 1;
934  }
935  else {
936  if (in_lon < lon_bufp[i]) {
937  lon_index1 = i - 1;
938  lon_index2 = i;
939  done = 1;
940  }
941  }
942  }
943 
944 #endif
945  if (lon_index1 == -1 || lon_index2 == -1) { /* global */
946 
947  if (((lon_bufp[0] + 360 - gridstep) == lon_bufp[dims[1] - 1]) || (toms == SUCCEED)) {
948  lon_index1 = dims[1] - 1;
949  lon_index2 = 0;
950  outside = 1;
951  } else {
952  if (in_lon < lon_bufp[0]) { /* regional */
953  lon_index1 = 0;
954  lon_index2 = 1;
955  } else {
956  lon_index1 = dims[1] - 1;
957  lon_index2 = dims[1] - 2;
958  }
959  }
960  }
961 
962  out_lat_list[3] = lat_bufp[lat_index1];
963  out_lat_list[0] = lat_bufp[lat_index1];
964  out_lat_list[1] = lat_bufp[lat_index2];
965  out_lat_list[2] = lat_bufp[lat_index2];
966 
967  out_lon_list[3] = lon_bufp[lon_index1];
968  out_lon_list[0] = lon_bufp[lon_index2];
969  out_lon_list[1] = lon_bufp[lon_index2];
970  out_lon_list[2] = lon_bufp[lon_index1];
971 
972  if (parm_flag == OZONE) {
973 
974  if ((outside) && (toms == SUCCEED)) {
975 
976  if (in_lon < 0)
977  index = lon_index2;
978  else
979  index = lon_index1;
980 
981  OZ_list1[3] = oz_p1[lat_index1 * dims[1] + index];
982  OZ_list1[0] = oz_p1[lat_index1 * dims[1] + index];
983  OZ_list1[1] = oz_p1[lat_index2 * dims[1] + index];
984  OZ_list1[2] = oz_p1[lat_index2 * dims[1] + index];
985 
986  OZ_list2[3] = oz_p2[lat_index1 * dims[1] + index];
987  OZ_list2[0] = oz_p2[lat_index1 * dims[1] + index];
988  OZ_list2[1] = oz_p2[lat_index2 * dims[1] + index];
989  OZ_list2[2] = oz_p2[lat_index2 * dims[1] + index];
990  } else {
991 
992  OZ_list1[3] = oz_p1[lat_index1 * dims[1] + lon_index1];
993  OZ_list1[0] = oz_p1[lat_index1 * dims[1] + lon_index2];
994  OZ_list1[1] = oz_p1[lat_index2 * dims[1] + lon_index2];
995  OZ_list1[2] = oz_p1[lat_index2 * dims[1] + lon_index1];
996 
997  if (PA_flag == 1) {
998  for (i = 0; i < CORNERS; i++)
999  OZ_list2[i] = 0;
1000  } else {
1001  OZ_list2[3] = oz_p2[lat_index1 * dims[1] + lon_index1];
1002  OZ_list2[0] = oz_p2[lat_index1 * dims[1] + lon_index2];
1003  OZ_list2[1] = oz_p2[lat_index2 * dims[1] + lon_index2];
1004  OZ_list2[2] = oz_p2[lat_index2 * dims[1] + lon_index1];
1005  }
1006  }
1007  } else {
1008 
1009  WPH_list1[3] = wph_p1[lat_index1 * dims[1] + lon_index1];
1010  WPH_list1[0] = wph_p1[lat_index1 * dims[1] + lon_index2];
1011  WPH_list1[1] = wph_p1[lat_index2 * dims[1] + lon_index2];
1012  WPH_list1[2] = wph_p1[lat_index2 * dims[1] + lon_index1];
1013 
1014  if (PA_flag == 1) {
1015  for (i = 0; i < CORNERS; i++)
1016  WPH_list2[i] = 0;
1017  } else {
1018  WPH_list2[3] = wph_p2[lat_index1 * dims[1] + lon_index1];
1019  WPH_list2[0] = wph_p2[lat_index1 * dims[1] + lon_index2];
1020  WPH_list2[1] = wph_p2[lat_index2 * dims[1] + lon_index2];
1021  WPH_list2[2] = wph_p2[lat_index2 * dims[1] + lon_index1];
1022  }
1023  }
1024 
1025  if (PA_flag != 1) {
1026 
1027  if ((outside) && (toms == SUCCEED)) {
1028 
1029  qc1_vals[3] = qc_buf1[lat_index1 * dims[1] + index];
1030  qc1_vals[0] = qc_buf1[lat_index1 * dims[1] + index];
1031  qc1_vals[1] = qc_buf1[lat_index2 * dims[1] + index];
1032  qc1_vals[2] = qc_buf1[lat_index2 * dims[1] + index];
1033 
1034  qc2_vals[3] = qc_buf2[lat_index1 * dims[1] + index];
1035  qc2_vals[0] = qc_buf2[lat_index1 * dims[1] + index];
1036  qc2_vals[1] = qc_buf2[lat_index2 * dims[1] + index];
1037  qc2_vals[2] = qc_buf2[lat_index2 * dims[1] + index];
1038  } else {
1039 
1040  qc1_vals[3] = qc_buf1[lat_index1 * dims[1] + lon_index1];
1041  qc1_vals[0] = qc_buf1[lat_index1 * dims[1] + lon_index2];
1042  qc1_vals[1] = qc_buf1[lat_index2 * dims[1] + lon_index2];
1043  qc1_vals[2] = qc_buf1[lat_index2 * dims[1] + lon_index1];
1044 
1045  qc2_vals[3] = qc_buf2[lat_index1 * dims[1] + lon_index1];
1046  qc2_vals[0] = qc_buf2[lat_index1 * dims[1] + lon_index2];
1047  qc2_vals[1] = qc_buf2[lat_index2 * dims[1] + lon_index2];
1048  qc2_vals[2] = qc_buf2[lat_index2 * dims[1] + lon_index1];
1049  }
1050 
1051  // qc_check = 0;
1052  // for (i = 0; i < 4; i++) {
1053  // if(qc1_vals[i] != 0 || qc2_vals[i] != 0)
1054  // qc_check = 1;
1055  // }
1056  }
1057 
1058  /*
1059  if (PA_flag != 1 && qc_check == 1)
1060  qcflag[loop] = -1;
1061  else
1062  qcflag[loop] = 0;
1063  above code is replaced by the int_qc from interpolate below */
1064 
1065 
1066  if (outside) {
1067  if (in_lon < 0) {
1068  for (p = 0; p < 4; p++)
1069  if (out_lon_list[p] > 0)
1070  out_lon_list[p] -= 360;
1071  } else {
1072  for (p = 0; p < 4; p++)
1073  if (out_lon_list[p] < 0)
1074  out_lon_list[p] += 360;
1075  }
1076  }
1077 
1078 
1079  DT1 = DTime1.start + DTime1.inc*in_lon;
1080  if ((toms == SUCCEED)&&(DT1 < 0.0)) DT1 *= -1.0;
1081  DT2 = DTime2.start + DTime2.inc*in_lon;
1082  if ((toms == SUCCEED)&&(DT2 < 0.0)) DT2 *= -1.0;
1083 
1084 
1085  outside = 0;
1086 
1087  interpolate(PA_flag, parm_flag, DT1, DT2, in_lat, in_lon,
1088  out_lat_list, out_lon_list, data_list1, data_list2,
1089  qc1_vals, qc2_vals, &interp[loop], &anc_unc[loop],
1090  &int_qc);
1091  qcflag[loop] = int_qc;
1092 
1093  /*
1094  */
1095  }
1096 }
1097 
1098 /*-----------------------------------------------------------------------------
1099  Function: gregor
1100 
1101  Returns: none
1102 
1103  Description:
1104  Converts Julian day into Gregorian Month/Day.
1105 
1106  Parameters:
1107  Type Name I/O Description
1108  ---- ---- --- -----------
1109  int16 sday I Julian day of syear
1110  int16 syear I Year in which sday occurs
1111  int16 day O Day of Month in Year
1112  int16 month O Month in Year
1113 
1114 
1115  Modification history:
1116  Programmer Organization Date Description of change
1117  -------------- ------------ -------- ---------------------
1118  Michael Darzi GSC 10/89 Original development in FORTRAN
1119  Lakshmi Kumar Hughes STX 04/02/93 Converted to C
1120  Lakshmi Kumar Hughes STX 12/09/93 Modified the comments
1121 -----------------------------------------------------------------------------*/
1122 void gregor(int16_t sday, int16_t syear, int16_t *month, int16_t *day) {
1123  int32 sdays[2][12] = {
1124  {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
1125  {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
1126  };
1127  int16 row = 0, mth = 0, done = 0;
1128 
1129  if (syear % 4 == 0)
1130  row = 1;
1131 
1132  mth = 11;
1133  while (!done) {
1134  if (sday > sdays[row][mth]) {
1135  *day = sday - sdays[row][mth];
1136  done = 1;
1137  } else
1138  mth = mth - 1;
1139  }
1140  *month = mth + 1;
1141 }
1142 
1143 /*----------------------------------------------------------------------------
1144  Function: ck_files_in_buf
1145 
1146  Returns: Status
1147 
1148  Description:
1149  The function ck_files_in_buf checks whether the requested real time
1150  data or the climatology data are in the buffers or not. Sets the
1151  readflag to 1 if file1 needs to be read, 2 if file2 needs to be read
1152  and 3 if both file1 and file2 needs to be read.
1153 
1154  Arguments: (in calling order)
1155  Type Name I/O Description
1156  ---- ---- --- -----------
1157  int16 PA_flag I product type: 1 for climatology, else
1158  NRT
1159  int16 parm_flag I flag indicating the parameter
1160  char * f1 I file 1
1161  char * f2 I file 2
1162  int16 month I data month
1163  int16 * error_flag I/O error_flag indicating previous read
1164  errors
1165  int16 * read_flag O flag indicating read:
1166  0 - no read, 1 - read file1,
1167  2 - read file2, 3 -read file1 and file2
1168  Modification history:
1169  Programmer Organization Date Description of change
1170  -------------- ------------ -------- ---------------------
1171  Lakshmi Kumar Hughes STX 04/02/93 Original development
1172  Lakshmi Kumar Hughes STX 12/09/93 Moved the climatology data check
1173  for the given month from read-
1174  climatology fnc. to this fnc.
1175  Lakshmi Kumar Hughes STX 04/18/96 Fixed a potential array out of
1176  bounds problem (ref. to error_flag)
1177  Lakshmi Kumar Hughes STX 08/16/96 Changed const 5 to NPARMS in the
1178  if condn. below
1179 -----------------------------------------------------------------------------*/
1180 int32_t ck_files_in_buf(int16_t PA_flag, int16_t parm_flag, char *f1, char *f2,
1181  int16_t month, int16_t *error_flag, int16_t *read_flag) {
1182  int16 i;
1183  /* prev parameter files read for -t step */
1184  typedef char p_files_t[MAXVAL];
1185  static p_files_t *p_files1;
1186  /* prev parameter files read for +t step */
1187  static p_files_t *p_files2;
1188  static int16 *prev_mth, fst_call = 1;
1189  char *p_f1, *p_f2; /* pointers to prev file1 and file2 */
1190  void *temp_p;
1191 
1192  if (PA_flag == 1) {
1193  if (strlen(f1) <= 0)
1194  return FAIL;
1195  } else {
1196  if (strlen(f1) <= 0 || strlen(f2) <= 0)
1197  return FAIL;
1198  }
1199 
1200  if (fst_call) {
1201  p_files1 = (p_files_t*) allocateMemory(NPARMS * sizeof (p_files_t), "p_files1");
1202  p_files2 = (p_files_t*) allocateMemory(NPARMS * sizeof (p_files_t), "p_files2");
1203  prev_mth = (int16*) allocateMemory(NPARMS * sizeof (int16), "prev_mth");
1204  for (i = 0; i < NPARMS; i++)
1205  prev_mth[i] = -1;
1206  fst_call = 0;
1207  }
1208 
1209  if (*error_flag >= 0 && *error_flag < NPARMS) {
1210  strcpy(p_files1[*error_flag], "");
1211  strcpy(p_files2[*error_flag], "");
1212  *error_flag = -1;
1213  }
1214 
1215  p_f1 = p_files1[parm_flag];
1216  p_f2 = p_files2[parm_flag];
1217 
1218  *read_flag = 0;
1219 
1220  if (PA_flag == 1) {
1221  if ((strcmp(f1, p_f1)) != 0) {
1222  *read_flag = 1;
1223  strcpy(p_f1, f1);
1224  } else
1225  if (prev_mth[parm_flag] != month) { /* ck if data in buf is for*/
1226  *read_flag = 1; /* the requested month, if */
1227  }
1228  prev_mth[parm_flag] = month; /* not, set the read_flag */
1229  } else {
1230  if (((strcmp(f1, p_f1)) == 0) && (strcmp(f2, p_f2)) == 0)
1231  *read_flag = 0;
1232  else {
1233  /*
1234  * for the ozone, force a read of both files
1235  */
1236  if (parm_flag == 4) {
1237  *read_flag = 3;
1238  strcpy(p_f1, f1);
1239  strcpy(p_f2, f2);
1240  } else {
1241  if (strcmp(f1, p_f2) == 0) {
1242  *read_flag = 2;
1243  temp_p = parm_buf1; /* switch pointers */
1244  parm_buf1 = parm_buf2;
1245  parm_buf2 = temp_p;
1246  strcpy(p_f1, f2);
1247  } else {
1248  if (strcmp(f2, p_f1) == 0) {
1249  *read_flag = 1;
1250  temp_p = parm_buf1;
1251  parm_buf1 = parm_buf2;
1252  parm_buf2 = temp_p;
1253  strcpy(p_f2, f1);
1254  } else {
1255  if (strcmp(f2, p_f2) == 0)
1256  *read_flag = 1;
1257  else
1258  *read_flag = 3;
1259  strcpy(p_f1, f1);
1260  strcpy(p_f2, f2);
1261  }
1262  }
1263  }
1264  }
1265  }
1266 
1267  return SUCCEED;
1268 }
1269 
1270 /*----------------------------------------------------------------------------
1271  Function: interpolate
1272 
1273  Returns: None
1274 
1275  Description:
1276  Initializes and sets some input and output parameters and calls
1277  FORTRAN subroutine "dataintp" to do the interpolation.
1278 
1279  Parameters:
1280  Type Name I/O Description
1281  ---- ---- --- -----------
1282  int16 PA_flag I Flag set to 1 to read climatology else
1283  to read NRT data files
1284  int16 parm_flag I indicates for wh parmeter it is being
1285  processed
1286  float32 DT1 I Time diff bet file1 and file2
1287  float32 DT2 I Time diff bet file1 and file2
1288  float32 in_lat I input latitude
1289  float32 in_lon I input longitude
1290  float32 * lat_list I adjacent latitude pts of the given latitude
1291  float32 * lon_list I adjacent lon pts of the given longitude
1292  void * data_p1 I adjacent data pts of file 1
1293  void * data_p2 I adjacent data pts of file 2
1294  int8 * qc1, qc2 I the qc values for each data_p1, data_p2
1295  float32 * intpdata O interpolated data for given lat/lon
1296  float32 * anc_unc O ancillary data uncertainty
1297  int32 * int_qc O qc for interpolation 0 - good, 1 -
1298  insufficient good data values to interpolate
1299 
1300  Modification history:
1301  Programmer Organization Date Description of change
1302  -------------- ------------ -------- ---------------------
1303  Lakshmi Kumar Hughes STX 03/22/93 Original development
1304  Lakshmi Kumar Hughes STX 12/09/93 Modified comments
1305  Lakshmi Kumar Hughes STX 04/18/96 Removed a redundant for loop
1306  Lakshmi Kumar Hughes STX 03/28/97 Defined range for humidity if parm
1307  type is 5.
1308  W. Robinson, SAIC, 13 Dec 2013 include the qc values for the points
1309  W. Robinson, SAIC, 5 Jun 2014 expand valid RH range down to 0%
1310  and set change default to 80%
1311  instead of 90%
1312  W. Robinson, SAIC, 4 Aug 2016 pass through an uncertainty: anc_unc
1313 -----------------------------------------------------------------------------*/
1314 void interpolate(int16_t PA_flag, int16_t parm_flag, double DT1, double DT2,
1315  float in_lat, float in_lon, float *lat_list,
1316  float *lon_list, void *data_p1, void *data_p2,
1317  int8_t *qc1, int8_t *qc2, float *intpdata,
1318  float *anc_unc, int32_t *int_qc) {
1319 
1320  float32 in_latlon[2];
1321  float32 range[2];
1322  float32 def = 0.0;
1323  float32 dummy[4];
1324  float32 *WPH_p1, *WPH_p2;
1325  float32 data_list1[4], data_list2[4];
1326  float32 dataout = -1.343, unc = 0.;
1327  int32 ipt = 4;
1328  int32 nband = 1;
1329  int32 intporder;
1330  int32 row = 1, col = 1, i, int_bad;
1331  int16 *OZ_p1, *OZ_p2;
1332 
1333 
1334  in_latlon[0] = in_lat;
1335  in_latlon[1] = in_lon;
1336 
1337  range[0] = -98.00;
1338  range[1] = 9999.99;
1339 
1340  switch (parm_flag) {
1341  case 0: /* wind-u and wind-v */
1342  case 1:
1343  def = 6;
1344  range[0] = -40;
1345  range[1] = 40;
1346  break;
1347  case 2: /* pressure */
1348  def = 1013;
1349  range[0] = 850;
1350  range[1] = 1084;
1351  break;
1352  case 3: /* precipitable water */
1353  def = 50;
1354  range[0] = 0;
1355  range[1] = 200;
1356  break;
1357  case 4: /* ozone */
1358  def = 360;
1359  range[0] = 80;
1360  range[1] = 600;
1361  break;
1362  case 5: /* relative humidity */
1363  def = 80;
1364  range[0] = 0;
1365  range[1] = 100;
1366  break;
1367  default:
1368  break;
1369  }
1370 
1371  intporder = SPATIAL_TEMPORAL;
1372 
1373  if (PA_flag == 1) /* climatology requested */
1374  DT1 = DT2 = 0;
1375 
1376  if (DT1 == 0 && DT2 == 0) /* if climatology or same NRT files */
1377  intporder = SPATIAL;
1378  /*
1379  * we make sure that any data value that is qc flagged with 20 (= bad data)
1380  * will have a value outside the good data range
1381  */
1382  if (parm_flag == OZONE) {
1383  OZ_p1 = (int16 *) data_p1;
1384  OZ_p2 = (int16 *) data_p2;
1385  for (i = 0; i < 4; i++) {
1386  data_list1[i] = (qc1[i] == 20) ? range[0] - 1 : OZ_p1[i];
1387  data_list2[i] = (qc2[i] == 20) ? range[0] - 1 : OZ_p2[i];
1388  }
1389  } else {
1390  WPH_p1 = (float32 *) data_p1;
1391  WPH_p2 = (float32 *) data_p2;
1392  for (i = 0; i < 4; i++) {
1393  data_list1[i] = (qc1[i] == 20) ? range[0] - 1 : WPH_p1[i];
1394  data_list2[i] = (qc2[i] == 20) ? range[0] - 1 : WPH_p2[i];
1395  }
1396  }
1397 
1398  dataintp_(in_latlon, lat_list, lon_list, data_list1, &DT1, data_list2,
1399  &DT2, &ipt, &nband, &range, &def, &intporder, dummy,
1400  &dataout, &unc, &int_bad, &row, &col);
1401 
1402  *intpdata = dataout;
1403  *anc_unc = unc;
1404  *int_qc = int_bad;
1405 
1406 }
1407 
1408 /*----------------------------------------------------------------------------
1409  Function: set_files
1410 
1411  Returns: Status
1412 
1413  Description:
1414  Set_files sets file1 and file2 to input filename1 and filename2 to
1415  generate the interp values if the scan-line's date and time, as
1416  determined by syear, sday, eday, and msec, fall between the time range
1417  represented by these two files; if the scan's date and time fall
1418  outside their range, it will use filename2 and filname3 for generating
1419  interp; ignored if time fall within the range of filename1 and
1420  filename2
1421 
1422  Parameters:
1423  Type Name I/O Description
1424  ---- ---- --- -----------
1425  int16 syear I year of data start time
1426  int16 sday I day-of-year for data start time
1427  int16 eday I day-of-year for data end time
1428  int32 msec I milliseconds-of-day for data start time
1429  char * filename1 I input filename1
1430  char * filename2 I input filename2
1431  char * filename3 I input filename3
1432  char * file1 O file to be used for generating interp vals
1433  char * file2 O file to be used for generating interp vals
1434  timech * dtime1 O Time diff bet actual scan time & time step 1
1435  timech * dtime2 O Time diff bet actual scan time & time step 2
1436  intn * toms O Boolean value whether EP TOMS approximation is used
1437 
1438  Modification history:
1439  Programmer Organization Date Description of change
1440  -------------- ------------ -------- ---------------------
1441  Lakshmi Kumar Hughes STX 06/21/94 Original development
1442  Lakshmi Kumar HITC 05/25/95 Added code to return error messages
1443  Lakshmi Kumar Hughes STX 10/10/95 Changed time checking logic
1444  (Ref: V4.4 I/O Specs.)
1445  Lakshmi Kumar Hughes STX 03/08/96 changed get_time interface to
1446  return files start and end times
1447  in julian days. section of the
1448  code that was converting time to
1449  julian days is moved to get_time
1450  Ewa Kwiatkowska GSC 11/12/99 Added parts supporting TOMS
1451  ancillary specification
1452 -----------------------------------------------------------------------------*/
1453 
1454 int32_t set_files(int16_t parm_flag, int16_t syear, int16_t sday, int16_t eday,
1455  int32_t msec, char *filename1, char *filename2, char *filename3,
1456  char *file1, char *file2, timech *dtime1, timech *dtime2, int *toms) {
1457  int16 dday, dyear, month, day;
1458  int16 hh, mm;
1459  int32 ss;
1460  float64 d_jd, s_jd1, e_jd1, s_jd2, e_jd2, s_jd3, e_jd3;
1461  float64 dtin[2];
1462  div_t quot1, quot2;
1463  char *FUNC = "set_files";
1464  static int32 prev_msec = -1;
1465  float64 dt1, dt2;
1466 
1467  if (prev_msec == -1)
1468  prev_msec = msec;
1469  /*** get start and end times of all 3 files, calculate center point time */
1470 
1471  if ((anc_get_time(filename1, &s_jd1, &e_jd1)) < 0)
1472  return FAIL;
1473 
1474  if (strcmp(filename2, filename1) == 0) {
1475  s_jd2 = s_jd1;
1476  e_jd2 = e_jd1;
1477  } else {
1478  if ((anc_get_time(filename2, &s_jd2, &e_jd2)) < 0)
1479  return FAIL;
1480  }
1481 
1482  if (strcmp(filename3, filename2) == 0) {
1483  s_jd3 = s_jd2;
1484  e_jd3 = e_jd2;
1485  } else {
1486  if ((anc_get_time(filename3, &s_jd3, &e_jd3)) < 0)
1487  return FAIL;
1488  }
1489 
1490  /*** convert given scan time to julian day */
1491  dyear = syear;
1492  dday = sday;
1493  if (sday != eday && msec < 43200000)
1494  dday = eday;
1495  if (dday < sday)
1496  dyear += 1;
1497 
1498  /**** call gregor to calculate month and day from julian day */
1499  gregor(dday, dyear, &month, &day);
1500  dtin[0] = (syear * 100 + month)*100 + day;
1501 
1502  quot1 = div(msec, MSECHOUR);
1503  hh = quot1.quot;
1504  quot2 = div(quot1.rem, MSECMIN);
1505  mm = quot2.quot;
1506  ss = quot2.rem;
1507  dtin[1] = (hh * 100 + mm)*100 + (ss / 1000.0);
1508 
1509  julian_(dtin, &d_jd);
1510 
1511  /**** check if the given time is in error */
1512 
1513  /****set file1 and file2 depending upon the given input date and time */
1514 
1515  if (s_jd1 == s_jd2 && e_jd1 == e_jd2) {
1516  strcpy(file1, filename2);
1517  strcpy(file2, filename2);
1518  dt1 = (d_jd - s_jd2);
1519  dt2 = (d_jd - s_jd2);
1520  } else {
1521  if (d_jd < s_jd1) {
1522  sprintf(ERR_MSG, "%s: Input time error: \nthe given time %f "
1523  "(in jdays) is less than \n"
1524  "%s start time of %f", FUNC, d_jd, filename1, s_jd1);
1525  return FAIL;
1526  }
1527  if (d_jd <= e_jd2) { /* data time is bet file1 & file2 times */
1528  strcpy(file1, filename1);
1529  strcpy(file2, filename2);
1530  dt1 = (d_jd - s_jd1);
1531  dt2 = (d_jd - s_jd2);
1532  } else { /* if (d_jd > s_jd2) */
1533  strcpy(file1, filename2);
1534  dt1 = (d_jd - s_jd2);
1535  }
1536  }
1537 
1538  if (s_jd2 == s_jd3 && e_jd2 == e_jd3) {
1539  strcpy(file2, filename2);
1540  dt2 = (d_jd - s_jd2);
1541  } else {
1542  if (d_jd > e_jd3) { /* data time falls outside file 3 ? */
1543  sprintf(ERR_MSG, "%s: Input time error: \nthe given time %f "
1544  "(in jdays) is greater than %s \n"
1545  "end time of %f", FUNC, d_jd, filename3, e_jd3);
1546  return FAIL;
1547  }
1548  if (d_jd >= s_jd2) { /* data time is bet file2 and file3 times? */
1549  strcpy(file2, filename3);
1550  dt2 = (d_jd - s_jd3);
1551  }
1552  }
1553 
1554 
1555  *toms = check_on_TOMS(parm_flag, file1, file2, filename1, filename2,
1556  filename3, s_jd1, s_jd2, s_jd3, e_jd1, e_jd2, e_jd3, d_jd, dtime1, dtime2);
1557 
1558  if (*toms == FAIL) {
1559  dtime1->start = dt1;
1560  if (dtime1->start < 0) dtime1->start *= -1.0;
1561  dtime2->start = dt2;
1562  if (dtime2->start < 0) dtime2->start *= -1.0;
1563  dtime1->inc = 0.0;
1564  dtime2->inc = 0.0;
1565  }
1566 
1567  if ((strcmp(file1, file2)) == 0)
1568  dtime1->start = dtime2->start = dtime1->inc = dtime2->inc = 0;
1569 
1570 
1571  return SUCCEED;
1572 }
1573 
1574 /*----------------------------------------------------------------------------
1575  Function: get_time
1576 
1577  Returns: int32 status
1578  The return code is a negative value if any error occurs.
1579 
1580  Description:
1581  get_time checks ftime structure to see if the given input file
1582  name and times exists in that structure. If so, it reads the
1583  start and end times from that structure and returns the values.
1584  Otherwise, it opens the given HDF file, reads global attributes
1585  syear, sday, smsec, eyear, eday, and emsec. Calls julian_ to
1586  convert start and end times to julian days and sets these values
1587  in the ftime structure, and returns.
1588 
1589  Parameters:
1590  Type Name I/O Description
1591  ---- ---- --- -----------
1592  char * filename I file name
1593  float64 *s_jd O start time in julian days
1594  float64 *e_jd O end time in julian days
1595 
1596  Modification history:
1597  Programmer Organization Date Description of change
1598  -------------- ------------ -------- ---------------------
1599  Lakshmi Kumar Hughes STX 06/21/94 Original development
1600  Lakshmi Kumar HITC 05/22/95 Modified to access date and time
1601  from global attributes rather than
1602  reading it from the file name
1603  Lakshmi Kumar Hughes STX 10/10/95 Modified to read start and end
1604  date and time from the input file
1605  and return them in the format shown
1606  above.
1607  Lakshmi Kumar Hughes STX 03/08/96 interface has been changed and
1608  added code to convert file times
1609  to julian days.
1610 -----------------------------------------------------------------------------*/
1611 
1612 int32_t anc_get_time(char *filename, double *s_jd, double *e_jd) {
1613 
1614  typedef struct file_time {
1615  char *fn;
1616  float64 s_jd;
1617  float64 e_jd;
1618  } ftm;
1619  static ftm *ftime;
1620 
1621  int32 i, ret, done, fid, sdfid;
1622  int16 syear, eyear, sday, eday, month, day;
1623  int32 smsec, emsec;
1624  int32 hh, mm, ss;
1625  float64 sdate, stime, edate, etime;
1626  float64 stin[2], etin[2];
1627  div_t quot1, quot2;
1628  static int32 file_num = 0;
1629 
1630 
1631  if (ftime == NULL) {
1632  ftime = (ftm*) allocateMemory(FLIMIT * sizeof (ftm), "ftime");
1633  }
1634 
1635  done = 0;
1636  for (i = 0; !done && i < FLIMIT && ftime[i].fn != NULL; i++) {
1637  if ((strcmp(ftime[i].fn, filename)) == 0) {
1638  *s_jd = ftime[i].s_jd;
1639  *e_jd = ftime[i].e_jd;
1640  done = 1;
1641  }
1642  }
1643 
1644  if (done)
1645  return SUCCEED;
1646  else if (i >= FLIMIT) {
1647  i = file_num % FLIMIT;
1648  free(ftime[i].fn);
1649  }
1650 
1651  ftime[i].fn = (char *) malloc(sizeof (char) * (strlen(filename) + 1));
1652  strcpy(ftime[i].fn, filename);
1653 
1654  /**** Open the given data file */
1655  if ((openHDF(filename, &sdfid, &fid)) < 0) return FAIL;
1656  file_num++;
1657 
1658  /**** read global attribute "Start Year" */
1659  ret = rdancattr(sdfid, SYEAR, (VOIDP *) & syear);
1660  if (ret < 0)
1661  return FAIL;
1662  if (DFNT_INT16 != ret) {
1663  fprintf(stderr, "\nWARNING: Datatype of %s read from %s is not int16. Processing from this point is unpredictable", SYEAR, filename);
1664  }
1665 
1666  /**** read global attribute "Start Day" */
1667  if ((ret = rdancattr(sdfid, SDAY, (VOIDP *) & sday)) < 0)
1668  return FAIL;
1669  if (DFNT_INT16 != ret) {
1670  fprintf(stderr, "\nWARNING: Datatype of %s read from %s is not int16. Processing from this point is unpredictable", SDAY, filename);
1671  }
1672 
1673  /**** read global attribute "Start Millisec" */
1674  if ((ret = rdancattr(sdfid, SMSEC, (VOIDP *) & smsec)) < 0) return FAIL;
1675  if (ret != DFNT_INT32) {
1676  fprintf(stderr, "\nWARNING: Datatype of %s read from %s is not int32. Processing from this point is unpredictable", SMSEC, filename);
1677  }
1678 
1679  /**** read global attribute "End Year" */
1680  if ((ret = rdancattr(sdfid, EYEAR, (VOIDP *) & eyear)) < 0) return FAIL;
1681  if (ret != DFNT_INT16) {
1682  fprintf(stderr, "\nWARNING: Datatype of %s read from %s is not int16. Processing from this point is unpredictable", EYEAR, filename);
1683  }
1684 
1685  /**** read global attribute "End Day" */
1686  if ((ret = rdancattr(sdfid, EDAY, (VOIDP *) & eday)) < 0) return FAIL;
1687  if (ret != DFNT_INT16) {
1688  fprintf(stderr, "\nWARNING: Datatype of %s read from %s is not int16. Processing from this point is unpredictable", EDAY, filename);
1689  }
1690 
1691  /**** read global attribute "End Millisec" */
1692  if ((ret = rdancattr(sdfid, EMSEC, (VOIDP *) & emsec)) < 0) return FAIL;
1693  if (ret != DFNT_INT32) {
1694  fprintf(stderr, "\nWARNING: Datatype of %s read from %s is not int32. Processing from this point is unpredictable", EMSEC, filename);
1695  }
1696 
1697  /**** call gregor to calculate month and day from julian day */
1698  gregor(sday, syear, &month, &day);
1699  sdate = (syear * 100 + month)*100 + day;
1700 
1701  gregor(eday, eyear, &month, &day);
1702  edate = ((eyear * 100 + month)*100 + day);
1703 
1704 
1705  /**** extract hours from msec */
1706  quot1 = div(smsec, MSECHOUR);
1707  hh = quot1.quot;
1708  quot2 = div(quot1.rem, MSECMIN);
1709  mm = quot2.quot;
1710  ss = quot2.rem;
1711 
1712  stime = ((hh * 100 + mm)*100 + (ss / 1000.0));
1713 
1714  quot1 = div(emsec, MSECHOUR);
1715  hh = quot1.quot;
1716  quot2 = div(quot1.rem, MSECMIN);
1717  mm = quot2.quot;
1718  ss = quot2.rem;
1719 
1720  etime = ((hh * 100 + mm)*100 + (ss / 1000.0));
1721 
1722  stin[0] = sdate;
1723  stin[1] = stime;
1724  etin[0] = edate;
1725  etin[1] = etime;
1726  julian_(stin, s_jd);
1727  julian_(etin, e_jd);
1728 
1729  ftime[i].s_jd = *s_jd;
1730  ftime[i].e_jd = *e_jd;
1731 
1732  /**** close input file */
1733  closeHDF(sdfid, fid);
1734 
1735  return SUCCEED;
1736 }
1737 
an array had not been initialized Several spelling and grammar corrections were which is read from the appropriate MCF the above metadata values were hard coded A problem calculating the average background DN for SWIR bands when the moon is in the space view port was corrected The new algorithm used to calculate the average background DN for all reflective bands when the moon is in the space view port is now the same as the algorithm employed by the thermal bands For non SWIR changes in the averages are typically less than Also for non SWIR the black body DNs remain a backup in case the SV DNs are not available For SWIR the changes in computed averages were larger because the old which used the black body suffered from contamination by the micron leak As a consequence of the if SV DNs are not available for the SWIR the EV pixels will not be the granule time is used to identify the appropriate tables within the set given for one LUT the first two or last two tables respectively will be used for the interpolation If there is only one LUT in the set of it will be treated as a constant LUT The manner in which Earth View data is checked for saturation was changed Previously the raw Earth View DNs and Space View DNs were checked against the lookup table values contained in the table dn_sat The change made is to check the raw Earth and Space View DNs to be sure they are less than the maximum saturation value and to check the Space View subtracted Earth View dns against a set of values contained in the new lookup table dn_sat_ev The metadata configuration and ASSOCIATEDINSTRUMENTSHORTNAME from the MOD02HKM product The same metatdata with extensions and were removed from the MOD021KM and MOD02OBC products ASSOCIATEDSENSORSHORTNAME was set to MODIS in all products These changes are reflected in new File Specification which users may consult for exact the pow functions were eliminated in Emissive_Cal and Emissive bands replaced by more efficient code Other calculations throughout the code were also made more efficient Aside from a few round off there was no difference to the product The CPU time decreased by about for a day case and for a night case A minor bug in calculating the uncertainty index for emissive bands was corrected The frame index(0-based) was previously being used the frame number(1-based) should have been used. There were only a few minor changes to the uncertainty index(maximum of 1 digit). 3. Some inefficient arrays(Sigma_RVS_norm_sq) were eliminated and some code lines in Preprocess_L1A_Data were moved into Process_OBCEng_Emiss. There were no changes to the product. Required RAM was reduced by 20 MB. Now
void interp(double *ephemPtr, int startLoc, double *inTime, int numCoefs, int numCom, int numSets, int velFlag, double *posvel)
integer, parameter int16
Definition: cubeio.f90:3
int16 eday
Definition: l1_czcs_hdf.c:17
#define NFILE
Definition: anc.h:24
int32_t day
#define EYEAR
Definition: regen.h:37
#define F2
Definition: anc.h:26
PRIVATE int32 sdfid2
Definition: getanc.c:109
int read_climatology(char *file1, int16_t parm_flag, int16_t month, int32_t *dims, float *lat_buf, float *lon_buf, void *parm_buf)
Definition: getanc.c:586
float f1(float x)
int get_ancillary(float *lat, float *lon, int16_t nsamp, int16_t syear, int16_t sday, int16_t eday, int32_t msec, char *filename1, char *filename2, char *filename3, char *anc_cor_file, int16_t parm_flag, float *interp, float *anc_unc, int16_t *qcflag)
Definition: getanc.c:297
#define SYEAR
Definition: regen.h:34
#define FAIL
Definition: ObpgReadGrid.h:18
void * allocateMemory(size_t numBytes, const char *name)
Definition: allocateMemory.c:7
#define MAXVAL
Definition: l3stat.h:13
#define NULL
Definition: decode_rs.h:63
#define SDAY
Definition: regen.h:35
int check_on_TOMS(int16_t parm_flag, char *file1, char *file2, char *filename1, char *filename2, char *filename3, double s_jd1, double s_jd2, double s_jd3, double e_jd1, double e_jd2, double e_jd3, double d_jd, timech *dt1, timech *dt2)
Definition: getanc.c:490
#define MSECMIN
Definition: regen.h:13
float * lat
int32 * msec
Definition: l1_czcs_hdf.c:31
int16 eyear
Definition: l1_czcs_hdf.c:17
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
int syear
Definition: l1_czcs_hdf.c:15
void extract_data_pts(int16_t PA_flag, int16_t parm_flag, timech DTime1, timech DTime2, int16_t nsamp, float *in_latlist, float *in_lonlist, float *lat_bufp, float *lon_bufp, int32_t *dims, int8_t *qc_buf1, int8_t *qc_buf2, void *parm_buf1, void *parm_buf2, int toms, float *out_lat_list, float *out_lon_list, int16_t *qcflag, float *interp, float *anc_unc)
Definition: getanc.c:847
int32 smsec
Definition: l1_czcs_hdf.c:16
#define CORNERS
int get_NRT_data(int32_t fid, int32_t sdfid, char *anc_cor_file, int16_t parm_flag, int32_t *dims, float *lat_buf, float *lon_buf, void *parm_buf, int8_t *qc_buf)
Definition: HDFroutines.c:360
#define SPATIAL
Definition: anc.h:36
int sday
Definition: l1_czcs_hdf.c:15
#define BS_DECR
Definition: getanc.c:116
#define MSECHOUR
Definition: regen.h:12
float f2(float y)
PRIVATE int32 fid1
Definition: getanc.c:109
int openHDF(char *infile, int32_t *sdfid, int32_t *fid)
Definition: HDFroutines.c:71
#define EMSEC
Definition: regen.h:39
#define SPATIAL_TEMPORAL
Definition: anc.h:37
intn get_ancillary_(float32 *lat, float32 *lon, int16 nsamp, int16 syear, int16 sday, int16 eday, int32 msec, char *filename1, char *filename2, char *filename3, char *anc_cor_file, int16 parm_flag, float32 *interp, float32 *anc_unc, int16 *qcflag)
Definition: getanc.c:443
int get_clim_data(int32_t fid, int32_t sdfid, int16_t parm_flag, int16_t month, int32_t *dims, float *lat_buf, float *lon_buf, void *parm_buf)
Definition: HDFroutines.c:264
int32_t ck_files_in_buf(int16_t PA_flag, int16_t parm_flag, char *f1, char *f2, int16_t month, int16_t *error_flag, int16_t *read_flag)
Definition: getanc.c:1180
#define BS_INCR
Definition: getanc.c:115
void julian_(double *dtin, double *d_jd)
#define SMSEC
Definition: regen.h:36
PRIVATE void * parm_buf1
Definition: getanc.c:110
void resiz_anc(int16_t *data, int8_t *qc, int32_t nlat, int32_t nlon1, int32_t nlon2, float *lons1, float *lons2)
Definition: getanc.c:722
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
void dataintp_(float *in_latlon, float *lat_list, float *lon_list, float *data_list1, double *DT1, float *data_list2, double *DT2, int32_t *ipt, int32_t *nband, float(*)[2], float *def, int32_t *intporder, float *dummy, float *dataout, float *unc, int32_t *int_bad, int32_t *row, int32_t *col)
#define LAT
Definition: anc.h:10
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
float wt2
Definition: atrem_cor.h:114
char ERR_MSG[1024]
Definition: getanc.c:111
#define PRIVATE
Definition: usrmac.h:85
int32_t rdancattr(int32_t sdfid, char *attr_name, void *buf)
Definition: HDFroutines.c:121
#define NPARMS
Definition: anc.h:23
int32 emsec
Definition: l1_czcs_hdf.c:18
int32_t nband
#define EDAY
Definition: regen.h:38
#define FLIMIT
Definition: getanc.c:113
int32_t set_files(int16_t parm_flag, int16_t syear, int16_t sday, int16_t eday, int32_t msec, char *filename1, char *filename2, char *filename3, char *file1, char *file2, timech *dtime1, timech *dtime2, int *toms)
Definition: getanc.c:1454
int closeHDF(int32_t sdfid, int32_t fid)
Definition: HDFroutines.c:221
#define F1
Definition: anc.h:25
int32_t anc_get_time(char *filename, double *s_jd, double *e_jd)
Definition: getanc.c:1612
PRIVATE void * parm_buf2
Definition: getanc.c:110
float * lon
int read_NRT(char *file1, char *file2, char *anc_cor_file, int16_t parm_flag, int16_t rd_flag, int32_t *dims, float *lat_buf, float *lon_buf, void *parm_buf1, void *parm_buf2, int8_t *qc_buf1, int8_t *qc_buf2)
Definition: getanc.c:645
void gregor(int16_t sday, int16_t syear, int16_t *month, int16_t *day)
Definition: getanc.c:1122
PRIVATE int32 sdfid1
Definition: getanc.c:109
int i
Definition: decode_rs.h:71
msiBandIdx val
Definition: l1c_msi.cpp:34
PRIVATE int32 fid2
Definition: getanc.c:109
void interpolate(int16_t PA_flag, int16_t parm_flag, double DT1, double DT2, float in_lat, float in_lon, float *lat_list, float *lon_list, void *data_p1, void *data_p2, int8_t *qc1, int8_t *qc2, float *intpdata, float *anc_unc, int32_t *int_qc)
Definition: getanc.c:1314
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
float wt1
Definition: atrem_cor.h:114
#define OZONE
Definition: make_L3_v1.1.c:82
#define LON
Definition: anc.h:11
float p[MODELMAX]
Definition: atrem_corl1.h:131