OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
HDFroutines.c
Go to the documentation of this file.
1 /*-----------------------------------------------------------------------------
2  File: HDFroutines.c
3 
4  Contents:
5  openHDF - Opens the given HDF file
6  rdlatlon - Reads the geometry vdata and writes lat/lons
7  get_clim_data - Reads climatology file for the req month
8  get_NRT_data - Reads NRT data from the given file
9  get_refs - Traverses thro' the NRT file vgroup and outputs
10  the SDS ref number to access the requested data
11  closeHDF - Closes the HDF file
12 
13  Other relevant files:
14  anc.h - various #defined constants for ancillary data, also
15  includes hdf.h
16  ancproto.h - prototypes for ancillary data input routines
17  getanc.c - a higher layer of ancillary data input functions
18  dataintp.f - interpolation routine
19 
20  Modification history:
21  Programmer Organization Date Description of change
22  -------------- ------------ -------- ---------------------
23  Lakshmi Kumar Hughes STX 04/02/93 Original development
24  Lakshmi Kumar Hughes STX 12/07/93 Modified to incorporate
25  HDF3.3r1 changes
26  Lakshmi Kumar Hughes STX 08/11/95 Fixed couple of Unitializ-
27  ed memory read problems
28  Lakshmi Kumar Hughes STX 08/02/96 corrected the order of
29  arguments passed in the
30  function 'get_clim_data'
31  non-prototype defn.
32  MAX has been redefined as
33  MAXVAL to avoid compile
34  time warnings, also
35  removed unused variables
36  Lakshmi Kumar Hughes STX 01/15/97 Reversed the order of
37  longitudes in lon_buf
38  Lakshmi Kumar Hughes STX 03/31/97 changed to return the
39  datatype of the attribute
40  read. Remove non-proto
41  function declarations.
42 -----------------------------------------------------------------------------*/
43 
44 #include "netcdf.h"
45 #include <mfhdf.h>
46 #include "anc.h"
47 #include "ancproto.h"
48 
49 /*-----------------------------------------------------------------------------
50  Function: openHDF
51 
52  Returns: int32 (status)
53  The return code is a negative value if any error occurs.
54 
55  Description:
56  The function openHDF opens the requested HDF file
57 
58  Parameters: (in calling order)
59  Type Name I/O Description
60  ---- ---- --- -----------
61  char * infile I input HDF file name
62  int32 * sdfid O ID req to access HDF SDS interface
63  int32 * fid O file ID
64 
65  Modification history:
66  Programmer Organization Date Description of change
67  -------------- ------------ -------- ---------------------
68  Lakshmi Kumar Hughes STX 12/09/93 Original development
69 
70 ----------------------------------------------------------------------------*/
71 int openHDF(char *infile, int32_t *sdfid, int32_t *fid) {
72  int32 lsdfid, lfid;
73  char *FUNC = "openHDF";
74 
75  if ((lsdfid = SDstart(infile, DFACC_RDONLY)) < 0) {
76  sprintf(ERR_MSG, "%s: Cannot open file -- SDstart failed on %s",
77  FUNC, infile);
78  return FAIL;
79  }
80 
81  if ((lfid = Hopen(infile, 0, DFACC_RDONLY)) < 0) {
82  sprintf(ERR_MSG, "%s: Cannot open file -- Hopen failed on %s",
83  FUNC, infile);
84  return FAIL;
85  }
86 
87  Vstart(lfid);
88 
89  *sdfid = lsdfid;
90  *fid = lfid;
91 
92  return SUCCEED;
93 
94 } /* startHDF */
95 
96 /*-----------------------------------------------------------------------------
97  Function: rdancattr
98 
99  Returns: int32 (status)
100  The return code is a negative value if any error occurs, otherwise,
101  returns the data type of the attribute read.
102 
103  Description:
104  The function rdancattr reads the requested global attribute
105 
106  Parameters: (in calling order)
107  Type Name I/O Description
108  ---- ---- --- -----------
109  int32 sdfid I ID req to access HDF SDS interface
110  char * attr_name I attribute name
111  void * buf I/O pointer to data buffer
112 
113  Modification history:
114  Programmer Organization Date Description of change
115  -------------- ------------ -------- ---------------------
116  Lakshmi Kumar Hughes STX 11/07/94 Original development
117  Lakshmi Kumar Hughes STX 03/31/97 changed to return the datatype of
118  the attribute read
119 ----------------------------------------------------------------------------*/
120 
121 int32_t rdancattr(int32_t sdfid, char *attr_name, void *buf) {
122  int32 attrnum, nt, count;
123  char name[255];
124  char *FUNC = "rdancattr";
125 
126  if ((attrnum = SDfindattr(sdfid, attr_name)) < 0) {
127  sprintf(ERR_MSG, "%s: SDfindattr failed for %s", FUNC, attr_name);
128  return FAIL;
129  }
130 
131  if ((SDattrinfo(sdfid, attrnum, name, &nt, &count)) < 0) {
132  sprintf(ERR_MSG, "%s: SDattrinfo failed for %s", FUNC, attr_name);
133  return FAIL;
134  }
135 
136  if ((SDreadattr(sdfid, attrnum, buf)) < 0) {
137  sprintf(ERR_MSG, "%s: SDreadattr failed for %s", FUNC, attr_name);
138  return FAIL;
139  }
140 
141  return nt;
142 }
143 
144 /*-----------------------------------------------------------------------------
145  Function: rdlatlon
146 
147  Returns: int32 (status)
148  The return code is a negative value if any error occurs.
149 
150  Description:
151  The function rdlatlon reads an appropriate geometry vdata for the
152  stepsize and corner coordinates. Using the stepsize (vsize, hsize)
153  and corner coordinates writes latitudes and longitudes in to the
154  lat/lon buffers.
155 
156  Parameters: (in calling order)
157  Type Name I/O Description
158  ---- ---- --- -----------
159  int32 fid I File ID
160  int32 * dims I dimensions of the data
161  float32 * lat_buf O latitude buffer
162  float32 * lon_buf O longitude buffer
163 
164  Modification history:
165  Programmer Organization Date Description of change
166  -------------- ------------ -------- ---------------------
167  Lakshmi Kumar Hughes STX 12/09/93 Original development
168  Lakshmi Kumar Hughes STX 08/11/95 Removed VSdetach call
169  Lakshmi Kumar Hughes STX 01/15/97 Reversed the order of longitudes
170 ----------------------------------------------------------------------------*/
171 int rdlatlon(int32_t sdfid, int32_t *dims, float *lat_buf, float *lon_buf) {
172  int32 i;
173  float32 vsize, hsize, sw_lat, sw_lon;
174 
175  /**** read global attribute "Latitude Step" */
176  if ((rdancattr(sdfid, VSIZE, (VOIDP *) & vsize)) < 0)
177  return FAIL;
178 
179  /**** read global attribute "Longitude Step" */
180  if ((rdancattr(sdfid, HSIZE, (VOIDP *) & hsize)) < 0)
181  return FAIL;
182 
183  /**** read global attribute "SW Point Latitude" */
184  if ((rdancattr(sdfid, SWPT_LAT, (VOIDP *) & sw_lat)) < 0)
185  return FAIL;
186 
187  /**** read global attribute "SW Point Longitude" */
188  if ((rdancattr(sdfid, SWPT_LON, (VOIDP *) & sw_lon)) < 0)
189  return FAIL;
190 
191  lat_buf[dims[0] - 1] = sw_lat;
192  for (i = dims[0] - 2; i >= 0; i--)
193  lat_buf[i] = (lat_buf[i + 1] + vsize);
194 
195  for (lon_buf[0] = sw_lon, i = 1; i < dims[1]; i++)
196  lon_buf[i] = (lon_buf[i - 1] + hsize);
197 
198  return SUCCEED;
199 }
200 
201 /*-----------------------------------------------------------------------------
202  Function: closeHDF
203 
204  Returns: none
205 
206  Description:
207  The function closeHDF closes the given HDF file.
208 
209  Parameters: (in calling order)
210  Type Name I/O Description
211  ---- ---- --- -----------
212  int32 sdfid I ID req to access SDS interface
213  int32 fid I File ID
214 
215  Modification history:
216  Programmer Organization Date Description of change
217  -------------- ------------ -------- ---------------------
218  Lakshmi Kumar Hughes STX 12/09/93 Original development
219 
220 ----------------------------------------------------------------------------*/
221 int closeHDF(int32_t sdfid, int32_t fid) {
222  int result;
223 
224  if ((result = Vend(fid)) < 0) perror("closing V file");
225  if ((result = SDend(sdfid)) < 0) perror("closing SDS");
226  if ((result = Hclose(fid)) < 0) perror("closing H file");
227 
228  return result;
229 }
230 
231 /*-----------------------------------------------------------------------------
232  Function: get_clim_data
233 
234  Returns: int32 (status)
235  The return code is a negative value if any error occurs.
236 
237  Description:
238  The function get_clim_data finds the right month vgroup,
239  obtains right parameter SDS reference number and reads data in
240  to the output buffer. Calls rd_latlon if required.
241 
242  Parameters: (in calling order)
243  Type Name I/O Description
244  ---- ---- --- -----------
245  int32 fid I File ID
246  int32 sdfid I ID req to access SDS interface
247  int16 parm_flag I flag indicating the parameter type
248  int16 month I requested data month
249  int32 * dims O dimensions of the data
250  float32 * lat_buf O latitude buffer
251  float32 * lon_buf O longitude buffer
252  void * parm_buf O data buffer
253 
254  Modification history:
255  Programmer Organization Date Description of change
256  -------------- ------------ -------- ---------------------
257  Lakshmi Kumar Hughes STX 12/09/93 Original development
258  Lakshmi Kumar Hughes STX 08/11/95 Passing proper (MAX) vlaue to
259  Vgettagrefs
260  Lakshmi Kumar Hughes STX 08/02/96 corrected the order of arguments
261  passed in the non-prototype defn.
262  W. Robinson, SAIC, 2 Dec 2013 remove the pr_dims and usage
263 ----------------------------------------------------------------------------*/
264 int get_clim_data(int32_t fid, int32_t sdfid, int16_t parm_flag,
265  int16_t month, int32_t *dims, float *lat_buf,
266  float *lon_buf, void *parm_buf) {
267  int32 i, done = 0;
268  int32 vref, vid, index, sdsid, nrefs;
269  int32 start[3] = {0, 0, 0}, taglist[MAXVAL], reflist[MAXVAL];
270  int32 rank, nattrs, numbertype;
271  char name[MAXVAL], *FUNC = "get_clim_data";
272 
273  if ((vref = Vfind(fid, clim_vgps[month - 1])) <= 0) {
274  sprintf(ERR_MSG, "%s: Vfind failed to find vgroup %s",
275  FUNC, clim_vgps[month - 1]);
276  return FAIL;
277  }
278 
279  if ((vid = Vattach(fid, vref, "r")) < 0) {
280  sprintf(ERR_MSG, "%s: Vattach failed for vgroup %s",
281  FUNC, clim_vgps[month - 1]);
282  return FAIL;
283  }
284 
285  if ((Vgettagrefs(vid, taglist, reflist, MAXVAL)) < 0) {
286  sprintf(ERR_MSG, "%s: Vgettagrefs failed for vgroup %s",
287  FUNC, clim_vgps[month - 1]);
288  return FAIL;
289  }
290 
291  if ((nrefs = Vntagrefs(vid)) < 0)
292  return FAIL;
293 
294  /*** get sdsid for the requested parameter sds */
295  for (i = 0; i < nrefs && !done; i++) {
296  if (taglist[i] == DFTAG_NDG) {
297  if ((index = SDreftoindex(sdfid, reflist[i])) < 0)
298  return FAIL;
299  if ((sdsid = SDselect(sdfid, index)) < 0)
300  return FAIL;
301  if ((SDgetinfo(sdsid, name, &rank, dims, &numbertype, &nattrs)) < 0)
302  return FAIL;
303  if (strcmp(name, clim_datasets[parm_flag]) == 0)
304  done = 1;
305  }
306  }
307 
308  if (!done) {
309  sprintf(ERR_MSG,
310  "%s: requested dataset %s not found", FUNC, clim_datasets[parm_flag]);
311  return FAIL;
312  }
313 
314  if ((rdlatlon(sdfid, dims, lat_buf, lon_buf)) < 0)
315  return FAIL;
316 
317  if ((SDreaddata(sdsid, start, NULL, dims, parm_buf)) < 0)
318  return FAIL;
319 
320  return SUCCEED;
321 }
322 
323 /*-----------------------------------------------------------------------------
324  Function: get_NRT_data
325 
326  Returns: int32 (status)
327  The return code is a negative value if any error occurs.
328 
329  Description:
330  The function get_NRT_data finds the right parameter vgroup and
331  calls get_refs to get the requested SDS reference number and
332  dimensions of the data. Calls rd_latlon if required.
333 
334 
335  Parameters: (in calling order)
336  Type Name I/O Description
337  ---- ---- --- -----------
338  int32 fid I File ID
339  int32 sdfid I ID req to access SDS interface
340  char * anc_cor_file I ancillary correction file, if NULL,
341  apply no correction t(to ozone)
342  int16 parm_flag I flag indicating the parameter type
343  int32 * dims O dimensions of the data
344  float32 * lat_buf O latitude buffer
345  float32 * lon_buf O longitude buffer
346  void * parm_buf O data buffer
347  int8 * qc_buf O qc data buffer
348 
349  Modification history:
350  Programmer Organization Date Description of change
351  -------------- ------------ -------- ---------------------
352  Lakshmi Kumar Hughes STX 12/09/93 Original development
353  Lakshmi Kumar HITC 05/25/95 Modified code to read the re-
354  structured data files (see product
355  specs 2.7)
356  W. Robinson, SAIC, 2 Dec 2013 remove the pr_dims and usage
357  W. Robinson, SAIC, 17 Jan 2014 add capability to read and apply the
358  correction to N7, EP TOMS and AURAOMI
359 ----------------------------------------------------------------------------*/
360 int get_NRT_data(int32_t fid, int32_t sdfid, char *anc_cor_file, int16_t parm_flag,
361  int32_t *dims, float *lat_buf, float *lon_buf,
362  void *parm_buf, int8_t *qc_buf) {
363 
364  int32 sdsid, index, numbertype;
365  int32 rank, start[3] = {0, 0, 0}, nattrs;
366  char name[132], *FUNC = "get_NRT_data", dsrc[100];
367  int32_t oz_typ;
368  int16 st_yr, st_day;
369  int corr_oz(char *, int16 *, char *, int32 *, int16, int16, int);
370 
371  /* read data SDS */
372  if ((index = SDnametoindex(sdfid, data_sdsnames[parm_flag])) < 0) {
373  sprintf(ERR_MSG, "%s: SDnametoindex failed for %s",
374  FUNC, data_sdsnames[parm_flag]);
375  return FAIL;
376  }
377 
378  if ((sdsid = SDselect(sdfid, index)) < 0) {
379  sprintf(ERR_MSG, "%s: SDselect failed for %s",
380  FUNC, data_sdsnames[parm_flag]);
381  return FAIL;
382  }
383 
384  if ((SDgetinfo(sdsid, name, &rank, dims, &numbertype, &nattrs)) < 0)
385  return FAIL;
386 
387  if ((SDreaddata(sdsid, start, NULL, dims, (VOIDP) parm_buf)) < 0) {
388  sprintf(ERR_MSG, "%s: SDreaddata faild for sds - %s", FUNC, name);
389  return FAIL;
390  }
391 
392  SDendaccess(sdsid);
393 
394 
395  /* read QC SDS */
396  if ((index = SDnametoindex(sdfid, QC_sdsnames[parm_flag])) < 0) {
397  sprintf(ERR_MSG, "%s: SDnametoindex failed for %s ",
398  FUNC, QC_sdsnames[parm_flag]);
399  return FAIL;
400  }
401 
402  if ((sdsid = SDselect(sdfid, index)) < 0)
403  return FAIL;
404 
405  if ((SDgetinfo(sdsid, name, &rank, dims, &numbertype, &nattrs)) < 0)
406  return FAIL;
407 
408  if ((SDreaddata(sdsid, start, NULL, dims, (VOIDP) qc_buf)) < 0)
409  return FAIL;
410 
411  SDendaccess(sdsid);
412 
413  if ((rdlatlon(sdfid, dims, lat_buf, lon_buf)) < 0)
414  return FAIL;
415 
416  /*
417  * for the ozone, if it has a source of the TOMS types, see about correcting
418  */
419  if (parm_flag == 4) {
420  if (rdancattr(sdfid, "Data Source", (void *) dsrc) != DFNT_CHAR) {
421  printf("%s, %d E: Could not read 'Data Source' from ozone file\n",
422  __FILE__, __LINE__);
423  return FAIL;
424  }
425  oz_typ = -1;
426  if (strcmp(dsrc, "N7TOMS") == 0)
427  oz_typ = 0;
428  else if (strcmp(dsrc, "EPTOMS") == 0)
429  oz_typ = 1;
430  else if (strcmp(dsrc, "AURAOMI") == 0)
431  oz_typ = 2;
432 
433  if (oz_typ != -1) {
434  /*
435  * for applicable ozones, see if the oz_corr_file is not null
436  * use clo_get... to get the oz_corr_file
437  * initially just set here
438  *
439  * at this time, we'd have to get the oz_corr_file into msl12_input.c and
440  * input structure and then ferry it from setanc - get_ancillary -
441  * read_NRT - get_NRT_data to use OR use clo_get_String if list was
442  * global, later, probably do the 1st option
443  * for now, just hard code it
444  */
445  if (strcmp(anc_cor_file, "") != 0) {
446  /*
447  * now, read the Start Year, Start Day and apply the correction
448  */
449  if ((rdancattr(sdfid, "Start Year", (void *) &st_yr) != DFNT_INT16)
450  || (rdancattr(sdfid, "Start Day", (void *) &st_day) != DFNT_INT16)) {
451  printf(
452  "%s, %d E: Could not read 'Start Year' or 'Start Day' from ozone file\n",
453  __FILE__, __LINE__);
454  return FAIL;
455  }
456  if (corr_oz(anc_cor_file, parm_buf, (char*) qc_buf, dims, st_yr,
457  st_day, oz_typ) != 0)
458  return FAIL;
459  }
460  }
461  }
462 
463  return SUCCEED;
464 }
465 
466 /*******************************************************************
467 
468  corr_oz
469 
470  purpose: read out the proper ozone correction to apply to the ozone
471  data array
472 
473  Returns type: int - 0 if all is OK
474 
475  Parameters: (in calling order)
476  Type Name I/O Description
477  ---- ---- --- -----------
478  char * oz_corr_file I name of ozone correction file
479  int16 * oz_dat I/O array of ozone data
480  char * qc_dat I array of qc data, 20 indicates
481  bad data
482  int32 * dims I array of x, y size of oz_dat
483  int16 yr, doy I year of the ozone array
484  int oz_typ I ozone type: 0 N7, 1 EP, 2 AURA
485 
486  Modification history:
487  Programmer Date Description of change
488  ---------- ---- ---------------------
489  W. Robinson, SAIC, 17 Jan 2014 original development
490 
491  *******************************************************************/
492 int corr_oz(char *oz_corr_file, int16 *oz_dat, char *qc_dat, int32 *dims,
493  int16 yr, int16 doy, int oz_typ) {
494  int ncid, gid, status, var_id;
495  char *oz_inst_grp[] = {"N7TOMS", "EPTOMS", "AURAOMI", "Extrap_AURAOMI"};
496  int16 corr_time_st[4], corr_time_en[4], mon, day;
497  int32_t yrs[2], mons[2], npix_oz, nlin_oz, ilin, ipix, ixmon, tot_mon;
498  int32_t ixlat;
499  float t_wt1, t_wt2, l_wt1, l_wt2, corr_arr[2 * 36], lat, slat, del_lat;
500  float pos, corr_fac;
501  size_t start[2], count[2];
502  /*
503  * open the oz_corr_file
504  */
505  if (nc_open(oz_corr_file, 0, &ncid) != NC_NOERR) {
506  printf("%s, %d E: Unable to open ozone correction file: %s\n",
507  __FILE__, __LINE__, oz_corr_file);
508  return -1;
509  }
510  /*
511  * go to the group of corrections for that instruent
512  */
513  if (nc_inq_grp_ncid(ncid, oz_inst_grp[oz_typ], &gid) != NC_NOERR) {
514  printf("%s, %d E: Unable to set group: %s for ozone correction file: %s\n",
515  __FILE__, __LINE__, oz_inst_grp[oz_typ], oz_corr_file);
516  return -1;
517  }
518  printf("%s, %d I: Correcting ozone using file:\n", __FILE__, __LINE__);
519  printf(" %s\n", oz_corr_file);
520  printf(" ozone inst: %s\n", oz_inst_grp[oz_typ]);
521  /*
522  * read the time array for the instrument
523  */
524  if ((status = nc_inq_varid(gid, "start_time", &var_id)) != NC_NOERR) {
525  printf("%s, %d E: Unable to read 'start_time' from correction file: %s\n",
526  __FILE__, __LINE__, oz_corr_file);
527  return -1;
528  }
529  if ((status = nc_get_var_short(gid, var_id, corr_time_st)) != NC_NOERR) {
530  printf("%s, %d E: Unable to read 'start_time' from correction file: %s\n",
531  __FILE__, __LINE__, oz_corr_file);
532  return -1;
533  }
534  ;
535  if ((status = nc_inq_varid(gid, "end_time", &var_id)) != NC_NOERR) {
536  printf("%s, %d E: Unable to read 'end_time' from correction file: %s\n",
537  __FILE__, __LINE__, oz_corr_file);
538  return -1;
539  }
540  if ((status = nc_get_var_short(gid, var_id, corr_time_en)) != NC_NOERR) {
541  printf("%s, %d E: Unable to read 'end_time' from correction file: %s\n",
542  __FILE__, __LINE__, oz_corr_file);
543  return -1;
544  }
545  /*
546  * determine which months to read for the ozone time
547  */
548  gregor(doy, yr, &mon, &day);
549  if (day <= 15) {
550  yrs[1] = yr;
551  mons[1] = mon;
552  if (mon == 1) {
553  yrs[0] = yr - 1;
554  mons[0] = 12;
555  } else {
556  yrs[0] = yr;
557  mons[0] = mon - 1;
558  }
559  t_wt1 = (15 - day) / 30.;
560  t_wt2 = (15 + day) / 30.;
561  } else {
562  yrs[0] = yr;
563  mons[0] = mon;
564  if (mon == 12) {
565  yrs[1] = yr + 1;
566  mons[1] = 1;
567  } else {
568  yrs[1] = yr;
569  mons[1] = mon + 1;
570  }
571  t_wt1 = (45 - day) / 30.;
572  t_wt2 = (day - 15) / 30.;
573  }
574  /*
575  * compute the position of the start of the 2 months to interpolate on
576  * and the total # months
577  */
578  ixmon = (yrs[0] - corr_time_st[0]) * 12 +
579  (mons[0] - corr_time_st[1]);
580  tot_mon = (corr_time_en[0] - corr_time_st[0]) * 12 +
581  (corr_time_en[1] - corr_time_st[1] + 1);
582  /*
583  * check for out of bounds and use the end time alone unless beyond the
584  * AURA end time - then, use the extrapolated month set
585  */
586  if (ixmon < 0) {
587  ixmon = 0;
588  t_wt1 = 1.;
589  t_wt2 = 0.;
590  } else if (ixmon >= (tot_mon - 1)) {
591  if (oz_typ == 2) /* it is AURA, we use extrapolation array */ {
592  /*
593  * the extrapolated AURA is set up to start in January and repeat
594  * January so that a pair of months will always be side-by-side.
595  * The time weights are still good from above, so we only need
596  * to set to the Extrapolated_AURA group , set the ixmon and the
597  * following code to read will work fine.
598  */
599  oz_typ = 3;
600  if (nc_inq_grp_ncid(ncid, oz_inst_grp[oz_typ], &gid) != NC_NOERR) {
601  printf(
602  "%s, %d E: Unable to set group: %s for ozone correction file: %s\n",
603  __FILE__, __LINE__, oz_inst_grp[oz_typ], oz_corr_file);
604  return -1;
605  }
606  printf("%s, %d I: Extrapolated ozone correction used, name: %s\n",
607  __FILE__, __LINE__, oz_inst_grp[oz_typ]);
608  ixmon = mons[0] - 1;
609  } else {
610  ixmon = tot_mon - 2;
611  t_wt1 = 0.;
612  t_wt2 = 1.;
613  }
614  }
615  /*
616  * read in the 2 month by 36 lat portion of the proper dataset
617  */
618  if ((status = nc_inq_varid(gid, "correction_array", &var_id))
619  != NC_NOERR) {
620  printf("%s, %d E: Unable to read 'correction_array' from correction file: %s\n",
621  __FILE__, __LINE__, oz_corr_file);
622  return -1;
623  }
624  start[0] = 0;
625  start[1] = ixmon;
626  count[0] = 36;
627  count[1] = 2;
628 
629  if ((status =
630  nc_get_vars_float(gid, var_id, start, count, NULL, corr_arr))
631  != NC_NOERR) {
632  printf("%s, %d E: Unable to read 'correction_array' from correction file: %s\n",
633  __FILE__, __LINE__, oz_corr_file);
634  return -1;
635  }
636  npix_oz = dims[1];
637  nlin_oz = dims[0];
638  /*
639  * close the correction file
640  */
641  nc_close(ncid);
642  /*
643  * NOTE!!! that the ozone array is stored so that the start line is at 89.5
644  * latitude, not -89.5 (SW Latitude in dataset). So, we need to consider
645  * that when applying the correction (which is not reversed in this silly way)
646  *
647  * The ozone grid is grid box centered and starts at 90 - box siz / 2
648  */
649  /* if storage started at -90...
650  del_lat = 180. / nlin_oz;
651  slat = -90. + del_lat / 2.;
652  */
653  del_lat = -180. / nlin_oz;
654  slat = 90. + del_lat / 2.;
655  /*
656  * loop through the lines and pixels of the ozone and correct all the non-bad
657  * values with the interpolated correction value
658  *
659  */
660  for (ilin = 0; ilin < nlin_oz; ilin++) {
661  lat = slat + ilin * del_lat;
662  pos = (lat + 87.5) / 5.; /* pos is in units of the correction grid */
663  ixlat = (int) (pos + 1) - 1;
664  if (ixlat < 0) {
665  ixlat = 0;
666  l_wt1 = 1.;
667  l_wt2 = 0.;
668  } else if (ixlat > 34) {
669  ixlat = 34;
670  l_wt1 = 0;
671  l_wt2 = 1.;
672  } else {
673  l_wt1 = (float) (ixlat + 1) - pos;
674  l_wt2 = pos - (float) ixlat;
675  }
676  /*
677  * get the correction factor for the time and latitude
678  */
679  corr_fac = t_wt1 * (l_wt1 * *(corr_arr + 2 * ixlat) +
680  l_wt2 * *(corr_arr + 2 * (ixlat + 1))) +
681  t_wt2 * (l_wt1 * *(corr_arr + 1 + 2 * ixlat) +
682  l_wt2 * *(corr_arr + 1 + 2 * (ixlat + 1)));
683  /*
684  * apply this to all the pixels, the 0.5 is to get closest correction
685  * to the integer values of ozone (I'd change this in re-write too)
686  */
687  for (ipix = 0; ipix < npix_oz; ipix++) {
688  if (*(qc_dat + ipix + npix_oz * ilin) != 20)
689  *(oz_dat + ipix + npix_oz * ilin) += (corr_fac + 0.5);
690  }
691  }
692  /* and end with ozone modified */
693  return 0;
694 }
695 
696 /*-----------------------------------------------------------------------------
697  Function: get_refs
698 
699  Returns: int32 (status)
700  The return code is a negative value if any error occurs.
701 
702  Description:
703  The function get_refs attaches the right parameter vgroup and
704  traverses through the vgroup to find the parameter SDS and the
705  QC SDS. Outputs the reference numbers of the parameter and the
706  QC SDSs.
707 
708  Parameters: (in calling order)
709  Type Name I/O Description
710  ---- ---- --- -----------
711  int32 fid I File ID
712  int32 sdfid I ID req to access SDS interface
713  int32 vid I Parameter Vgroup ID
714  char * parm_label I parameter SDS label
715  char * QC_label I QC SDS label
716  int32 * parm_sdsid O parameter SDS ID
717  int32 * QC_sdsid O QC SDS ID
718  int32 * dims O dimensions of the data
719 
720  Modification history:
721  Programmer Organization Date Description of change
722  -------------- ------------ -------- ---------------------
723  Lakshmi Kumar Hughes STX 12/09/93 Original development
724 
725 ----------------------------------------------------------------------------*/
726 int get_refs(int32_t fid, int32_t sdfid, int32_t vid, char *parm_label,
727  char *QC_label, int32_t *geom_id, int32_t *parm_sdsid, int32_t *QC_sdsid,
728  int32_t *dims) {
729  int32 i, j, ret = 0, vg, natts = MAXVAL, nrefs, tagarray[MAXVAL];
730  int32 refarray[MAXVAL];
731  int32 index, sdsid, rank, numbertype, nattrs, numSDSs;
732  int32 sdrefs[25];
733  char name[256];
734 
735  if ((vg = Vattach(fid, vid, "r")) < 0)
736  return FAIL;
737 
738  Vgettagrefs(vg, tagarray, refarray, natts);
739  nrefs = Vntagrefs(vg);
740  for (i = 0, j = 0; i < nrefs; i++) {
741  if (tagarray[i] == DFTAG_NDG || tagarray[i] == DFTAG_SD) {
742  sdrefs[j++] = refarray[i];
743  } else
744  if (tagarray[i] == DFTAG_VH || tagarray[i] == DFTAG_VS)
745  *geom_id = refarray[i];
746  }
747 
748  numSDSs = j;
749 
750  for (i = 0; i < numSDSs && ret >= 0; i++) {
751  index = SDreftoindex(sdfid, sdrefs[i]);
752  sdsid = SDselect(sdfid, index);
753  if ((SDgetinfo(sdsid, name, &rank, dims, &numbertype, &nattrs)) < 0)
754  return FAIL;
755  if (strcmp(name, parm_label) == 0) {
756  *parm_sdsid = sdsid;
757  } else
758  if (strcmp(name, QC_label) == 0)
759  *QC_sdsid = sdsid;
760  }
761 
762  Vdetach(vg);
763 
764  return SUCCEED;
765 }
int openHDF(char *infile, int32_t *sdfid, int32_t *fid)
Definition: HDFroutines.c:71
#define SWPT_LON
Definition: anc.h:66
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
char ERR_MSG[255]
Definition: extract_sub.c:119
integer, parameter int16
Definition: cubeio.f90:3
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
subroutine gregor(JULDAY, YEAR, MONTH, DAY)
Definition: gregor.f:2
int j
Definition: decode_rs.h:73
int32_t day
int status
Definition: l1_czcs_hdf.c:32
int corr_oz(char *oz_corr_file, int16 *oz_dat, char *qc_dat, int32 *dims, int16 yr, int16 doy, int oz_typ)
Definition: HDFroutines.c:492
#define FAIL
Definition: ObpgReadGrid.h:18
#define MAXVAL
Definition: l3stat.h:13
#define NULL
Definition: decode_rs.h:63
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
float32 * pos
Definition: l1_czcs_hdf.c:35
float * lat
int closeHDF(int32_t sdfid, int32_t fid)
Definition: HDFroutines.c:221
#define SWPT_LAT
Definition: anc.h:65
int get_refs(int32_t fid, int32_t sdfid, int32_t vid, char *parm_label, char *QC_label, int32_t *geom_id, int32_t *parm_sdsid, int32_t *QC_sdsid, int32_t *dims)
Definition: HDFroutines.c:726
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
int32_t rdancattr(int32_t sdfid, char *attr_name, void *buf)
Definition: HDFroutines.c:121
int rdlatlon(int32_t sdfid, int32_t *dims, float *lat_buf, float *lon_buf)
Definition: HDFroutines.c:171
#define VSIZE
Definition: anc_seaice.c:32
Extra metadata that will be written to the HDF4 file l2prod rank
#define HSIZE
Definition: anc_seaice.c:33
int i
Definition: decode_rs.h:71
int count
Definition: decode_rs.h:79