OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
ancnrt_aquarius.c
Go to the documentation of this file.
1 /*****************************************************************
2  * File: ancnrt_aquarius.c
3  *
4  * Purpose: create HDF ancillary real time datafile from
5  * NCEP (formerly NMC) (unpacked GRIB format) W, P, PW, H input
6  * or a TOVS ozone unpacked GRIB file from NMC.
7  *
8  * Description: this program will create a HDF with the components:
9  *
10  * Met data:
11  * HDF DAAC compliant Annotation object
12  * 1-D Latitude SDS
13  * 1-D Longitude SDS
14  * 2-D data parameter SDS (geohgt)
15  * 2-D data parameter SDS (tmp_sfc)
16  * 2-D data parameter SDS (press)
17  * 2-D data parameter SDS (c_water)
18  * 2-D data parameter SDS (soil_w)
19  *
20  *
21  * Input parms:
22  * char *annotfile - input of DAAC compliant annotations ("fillenv.met")
23  * char *ingeohgt - input to process ("geohgt.dat")
24  * char *intmp_sfc - input to process ("tmp_sfc.dat")
25  * char *inpress - input to process ("press.dat")
26  * char *inc_water - input to process ("c_water.dat")
27  * char *inc_soil - input to process ("soil_w.dat")
28  *
29  * char *outdir - output directory to write file
30  *
31  * Output parms:none
32  *
33  * output name is derived from GRIB converted file header.
34  * Example name: "Q199312300_NCEP.MET"
35  *
36  * Returns: run status
37  *
38  * Local vars: numerous variables for storing HDF annotations and SDSs.
39  *
40  * Subs called:
41  * wrtattr - write HDF annotation to file
42  * fill_annot - read HDF annotations from file
43  * wrtsds - write SDS from array to file
44  * pexit - print fatal errors
45  * check_usage- check command line args
46  * readgrib - FORTRAN routine to read binary
47  * (GRIB extracted) files
48  *
49  * History: none
50  *
51  * Note: This program is meant to generate SeaWiFS style HDF
52  * ancillary real-time datafiles.
53  *
54  * Author: Brian D. Schieber, GSC, 4/93
55  *
56  * Modification history:
57  * BDS, 4/19/93 - HDF missing flag removed after discussions
58  * with Jim F. and M.Darzi.
59  * - NCEP data in Pascals, divided by 100 => millibars.
60  * BDS, 4/30/93 - Modified GRIB read WPHLONSZ to remove "world wrapped"
61  * extra Lon. Will skip last longitude in HDF write.
62  * BDS, 10/4/93 - Modified for new HDF design and to produce and
63  * output file which holds all three met fields (WPH).
64  * BDS, 11/8/93 - Modified to create z/m wind SDS rather than windspeed.
65  * BDS, 11/28/93- Modified MAX_EAST to 177.5 (from 180.0).
66  * BDS, 12/6/93 - Assuming no missing values, 0.0's passed through.
67  * BDS, 5/19/95 - Support new SeaWiFS v 2.7 product specs.
68  * BDS, 8/21/96 - Renamed 'perror' to 'pexit' to avoid conflict with
69  * HDF4.0.
70  * BDS, 9/18/96 - Changed annot structure. Modify to support new 1x1
71  * GDAS1 files.
72  * BDS, 9/19/96 - Precipitable water has units kg/m^2
73  * W. Robinson, GSC, 4 Feb 97 put rh back in
74  * W. Robinson, GSC, 18 Jun 98 rename to ancnrt to include added
75  * role of processing the TOVS ozone data
76  * W. Robinson, GSC, 18 Dec 98 for the ozone output, write the
77  * start and end times to be compatible with o3nrt
78  * W. Robinson, SAIC, 23 Jan 2008 to add ability to read the binary
79  * files derived from the GRIB 2 format files (just a few
80  * differences, see readgrib2 in readgrib.c)
81  * W. Robinson, SAIC, modify for added argument to readgrib2
82  * W. Robinson, SAIC, 16 Feb 2010 modify readgrib2, readgrib2_3d
83  * call args npix, nlin
84  * W. Robinson, SAIC, 6 Apr 2015 new readgrib2 call and added grib2_t
85  * call - also name RH wit h2m AGL instead of entire atmosphere
86  *
87  *****************************************************************/
88 
89 #include "ancil.h"
90 #include <time.h>
91 #include <limits.h>
92 #include <unistd.h>
93 #include "ancnrt_proto.h"
94 
95 /*
96  * Met data specific settings
97  */
98 
99 #define VGROUPNAME "Geophysical Data"
100 
101 #define BIN_METH 2
102 #define REGISTRATION CENTER
103 #define VSIZE 1.0
104 #define HSIZE 1.0
105 #define MAX_NORTH 90.0
106 #define MAX_SOUTH -90.0
107 #define MAX_WEST -180.0
108 #define MAX_EAST 180.0
109 #define WPHLATSZ 181 /* latitude of GRIB files */
110 #define WPHLONSZ 360 /* long of MODIFIED GRIB files */
111 #define WPHLATSZ_GFS 361 /* latitude of GRIB GFS files */
112 #define WPHLONSZ_GFS 720 /* long of MODIFIED GRIB GFS files */
113 #define NPRFL 21
114 #define NPRFL_HGT 26
115 
116 #define GRIB_MODE_1 1 /* the GRIB modes, GRIB 1 old, GRIB 2 post jan 08 */
117 #define GRIB_MODE_2 2
118 
119 #define VERSION "1.10"
120 
121 /* #define VSIZE 2.5 */
122 /* #define HSIZE 2.5 */
123 /* #define MAX_EAST 177.5 */
124 /* #define WPHLATSZ 73 */ /* latitude of GRIB files */
125 /* #define WPHLONSZ 144 */ /* long of MODIFIED GRIB files */
126 
127 int main(int argc, char *argv[]) {
128  int i, j, k, l, anctyp;
129  int rank, rank_3d, SDSref = 0;
130  int result = 0;
131  int array_size = 0, array_size_gfs = 0;
132  int numannarr = 0;
133  int one = 1, rgmode = 0;
134  int year = 0, month = 0, day = 0, hour = 0, msec = 0,
135  julval = 0, pyear = 0;
136  int32 shape[2], shape_3d[3], shape_gfs[2];
137  int np, nl, fcst;
138  int npix = WPHLONSZ, nlin = WPHLATSZ;
139  int npix_gfs = WPHLONSZ_GFS, nlin_gfs = WPHLATSZ_GFS;
140 
141  float32 datarr1[WPHLATSZ][WPHLONSZ];
142  float32 datarr2[WPHLATSZ][WPHLONSZ];
143  float32 datarr3[WPHLATSZ][WPHLONSZ];
144  float32 datarr4[WPHLATSZ][WPHLONSZ];
145  float32 datarr5[WPHLATSZ][WPHLONSZ];
146  float32 datarr6[WPHLATSZ][WPHLONSZ];
147 
148  float32 latscl[WPHLATSZ], lonscl[WPHLONSZ],
149  dlat, dlon;
150  char message[MAXNAMELNG], ingeohgt[MAXNAMELNG], intmp_sfc[MAXNAMELNG];
151  char inpress[MAXNAMELNG], inp_water[MAXNAMELNG], inc_water[MAXNAMELNG];
152  char insoil_w[MAXNAMELNG], intmp_bgr[MAXNAMELNG];
153  ;
154  char inu_wind[MAXNAMELNG], inv_wind[MAXNAMELNG];
155  char inrh[MAXNAMELNG];
156  char ingeohgt_prl[MAXNAMELNG], intmp_prl[MAXNAMELNG];
157  char inrh_prl[MAXNAMELNG], inclwmr_prl[MAXNAMELNG];
158  char insnow_gfs[MAXNAMELNG];
159  char longname[MAXNAMELNG], *sdsname;
160  char *units, *dataattr, *longnamelabel, *longnamevalue;
161  char *unitslabel, *unitsvalue, *datafmt, outfile[MAXNAMELNG];
162  char outfilename[MAXNAMELNG], outdir[MAXNAMELNG];
163  char annotfile[MAXNAMELNG], source_name[100];
164  int n_opt_arg;
165  float latstep, lonstep; /* lat/lon incr. */
166  int latsz, lonsz; /* lat/lon size */
167  float nmostlat, smostlat, wmostlon, emostlon; /* lat/lon corners */
168  time_t t; /* processing time */
169  struct tm *localtm; /* processing time */
170  struct annotation *xannot;
171  int grib_mode;
172  char grib2_t_str[300];
173 
174  /*
175  * HDF datafile variables
176  */
177 
178  int32 sdfid, fid, gridid, dimid, sdsid, sdsref;
179  int32 datatype;
180 
181  /*
182  * data type array pointers
183  */
184 
185  float32 *float_SDSgeohgt, *float_SDStmp_sfc, *float_SDSpress;
186  float32 *float_SDSrh, *float_SDSp_water, *float_SDSc_water;
187  float32 *float_SDSsoil_w, *float_SDStmp_bgr;
188  float32 *float_SDSgeohgt_prl, *float_SDStmp_prl, *float_SDSrh_prl;
189  float32 *float_SDSclwmr_prl;
190  float32 *float_SDSu_wind, *float_SDSv_wind;
191  float32 *float_SDSsnow_gfs;
192  // int8 *int8_SDSdataQC;
193 
194  /*
195  * external functions used
196  */
197 
198  int readgrib(), julian_(), wrtattr(), startHDF();
199  int addAttr(), setSDSref();
200  int32 wrtsds();
201  void deattachHDFGrid(), pexit();
202  int8 check_usage();
203  struct annotation * fillenv_annot();
204 
205  /*
206  * ------- check command line arguments and set args ------------------
207  */
208 
209  if ((check_usage(argc, argv, &n_opt_arg, source_name,
210  &grib_mode, grib2_t_str)) != 0)
211  exit(-1);
212 
213  if (argc == 1) {
214  printf("%s %s (%s %s)\n\n", "ancnrt_aquarius", VERSION, __DATE__, __TIME__);
215  printf("ancnrt_aquarius junk geohgt_grib2.dat tmp_sfc_grib2.dat\n");
216  printf("press_grib2.dat rh_grib2.dat p_water_grib2.dat\n");
217  printf("c_water_grib2.dat soil_w_grib2.dat\n");
218  printf("u_wind_grib2.dat v_wind_grib2.dat\n");
219  printf("geohgt_prl_grib2.dat tmp_prl_grib2.dat rh_prl_grib2.dat\n");
220  printf("clwmr_prl_grib2.dat snow_gfs_grib2.dat tmp_bgr_grib2.dat -2 gtime\n");
221  exit(0);
222  }
223 
224  printf("%s %s (%s %s)\n\n", "ancnrt_aquarius", VERSION, __DATE__, __TIME__);
225 
226  strcpy(annotfile, argv[ n_opt_arg ]);
227 
228  strcpy(ingeohgt, argv[ 1 + n_opt_arg ]);
229  strcpy(intmp_sfc, argv[ 2 + n_opt_arg ]);
230  strcpy(inpress, argv[ 3 + n_opt_arg ]);
231  strcpy(inrh, argv[ 4 + n_opt_arg ]);
232  strcpy(inp_water, argv[ 5 + n_opt_arg ]);
233  strcpy(inc_water, argv[ 6 + n_opt_arg ]);
234  strcpy(insoil_w, argv[ 7 + n_opt_arg ]);
235  strcpy(inu_wind, argv[ 8 + n_opt_arg ]);
236  strcpy(inv_wind, argv[ 9 + n_opt_arg ]);
237 
238  strcpy(ingeohgt_prl, argv[10 + n_opt_arg ]);
239  strcpy(intmp_prl, argv[11 + n_opt_arg ]);
240  strcpy(inrh_prl, argv[12 + n_opt_arg ]);
241  strcpy(inclwmr_prl, argv[13 + n_opt_arg ]);
242 
243  strcpy(insnow_gfs, argv[14 + n_opt_arg ]);
244  strcpy(intmp_bgr, argv[15 + n_opt_arg ]);
245 
246  strcpy(outdir, argv[16 + n_opt_arg ]);
247 
248  /*
249  * ------- Read each binary file, extract data array and time ----------
250  */
251 
252  /*
253  * -------- Allocate space for 2D data arrays -----------------------
254  */
255 
256  rank = 2;
257 
258  shape[0] = WPHLATSZ; /* lat */
259  shape[1] = WPHLONSZ; /* lon */
260  array_size = shape[0] * shape[1];
261 
262  shape_gfs[0] = WPHLATSZ_GFS; /* lat */
263  shape_gfs[1] = WPHLONSZ_GFS; /* lon */
264  array_size_gfs = shape_gfs[0] * shape_gfs[1];
265 
266  if ((float_SDSgeohgt =
267  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
268  pexit("malloc float_SDSgeohgt");
269 
270  if ((float_SDStmp_sfc =
271  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
272  pexit("malloc float_SDStmp_sfc");
273 
274  if ((float_SDSpress =
275  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
276  pexit("malloc float_SDSpress");
277 
278  if ((float_SDSrh =
279  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
280  pexit("malloc float_SDSrh");
281 
282  if ((float_SDSp_water =
283  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
284  pexit("malloc float_SDSp_water");
285 
286  if ((float_SDSc_water =
287  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
288  pexit("malloc float_SDSc_water");
289 
290  if ((float_SDSsoil_w =
291  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
292  pexit("malloc float_SDSsoil_w");
293 
294  if ((float_SDSu_wind =
295  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
296  pexit("malloc float_SDSu_wind");
297 
298  if ((float_SDSv_wind =
299  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
300  pexit("malloc float_SDSv_wind");
301 
302  if (strcmp(insnow_gfs, "NONE") != 0) {
303  if ((float_SDSsnow_gfs =
304  (float32 *) malloc(sizeof (float32) * array_size_gfs)) == NULL)
305  pexit("malloc float_SDSsnow_gfs");
306  }
307 
308  if ((float_SDStmp_bgr =
309  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
310  pexit("malloc float_SDStmp_bgr");
311 
312  if (grib_mode == GRIB_MODE_2) {
313  result = readgrib2(ingeohgt, npix, nlin, rgmode, float_SDSgeohgt);
314  grib2_t(grib2_t_str, &year, &julval, &hour, &np, &nl, &fcst);
315  } else
316  result = readgrib(ingeohgt, npix, nlin, datarr1, &year, &month,
317  &day, &hour);
318 
319  if (result == 1) {
320  strcpy(message, "readgrib file: ");
321  strcat(message, ingeohgt);
322  pexit(message);
323  }
324 
325  result = readgrib2(intmp_sfc, npix, nlin, rgmode, float_SDStmp_sfc);
326 
327  if (result == 1) {
328  strcpy(message, "readgrib file: ");
329  strcat(message, intmp_sfc);
330  pexit(message);
331  }
332 
333  result = readgrib2(inpress, npix, nlin, rgmode, float_SDSpress);
334 
335  if (result == 1) {
336  strcpy(message, "readgrib file: ");
337  strcat(message, inpress);
338  pexit(message);
339  }
340 
341  result = readgrib2(inrh, npix, nlin, rgmode, float_SDSrh);
342 
343  if (result == 1) {
344  strcpy(message, "readgrib file: ");
345  strcat(message, inrh);
346  pexit(message);
347  }
348 
349  result = readgrib2(inp_water, npix, nlin, rgmode, float_SDSp_water);
350 
351  if (result == 1) {
352  strcpy(message, "readgrib file: ");
353  strcat(message, inp_water);
354  pexit(message);
355  }
356 
357  result = readgrib2(inc_water, npix, nlin, rgmode, float_SDSc_water);
358 
359  if (result == 1) {
360  strcpy(message, "readgrib file: ");
361  strcat(message, inc_water);
362  pexit(message);
363  }
364 
365  result = readgrib2(insoil_w, npix, nlin, rgmode, float_SDSsoil_w);
366 
367  if (result == 1) {
368  strcpy(message, "readgrib file: ");
369  strcat(message, insoil_w);
370  pexit(message);
371  }
372 
373  result = readgrib2(inu_wind, npix, nlin, rgmode, float_SDSu_wind);
374 
375  if (result == 1) {
376  strcpy(message, "readgrib file: ");
377  strcat(message, inu_wind);
378  pexit(message);
379  }
380 
381  result = readgrib2(inv_wind, npix, nlin, rgmode, float_SDSv_wind);
382 
383  if (result == 1) {
384  strcpy(message, "readgrib file: ");
385  strcat(message, inv_wind);
386  pexit(message);
387  }
388 
389  if (strcmp(insnow_gfs, "NONE") != 0) {
390  result = readgrib2(insnow_gfs, npix_gfs, nlin_gfs, rgmode,
391  float_SDSsnow_gfs);
392 
393  if (result == 1) {
394  strcpy(message, "readgrib file: ");
395  strcat(message, insnow_gfs);
396  pexit(message);
397  }
398  }
399 
400  result = readgrib2(intmp_bgr, npix, nlin, rgmode, float_SDStmp_bgr);
401 
402  if (result == 1) {
403  strcpy(message, "readgrib file: ");
404  strcat(message, intmp_bgr);
405  pexit(message);
406  }
407 
408  // Profile data
409 
410  rank_3d = 3;
411 
412  shape_3d[0] = NPRFL_HGT; /* prfl */
413  shape_3d[1] = WPHLATSZ; /* lat */
414  shape_3d[2] = WPHLONSZ; /* lon */
415  array_size = shape_3d[0] * shape_3d[1] * shape_3d[2];
416 
417  if ((float_SDSgeohgt_prl =
418  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
419  pexit("malloc float_SDSgeohgt_prl");
420 
421  if ((float_SDStmp_prl =
422  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
423  pexit("malloc float_SDStmp_prl");
424 
425  if (grib_mode == GRIB_MODE_2)
426  result = readgrib2_3d(ingeohgt_prl, grib2_t_str, npix, nlin,
427  float_SDSgeohgt_prl, NPRFL_HGT,
428  &year, &month, &day, &hour);
429 
430  if (result == 1) {
431  strcpy(message, "readgrib file: ");
432  strcat(message, ingeohgt_prl);
433  pexit(message);
434  }
435 
436 
437  if (grib_mode == GRIB_MODE_2)
438  result = readgrib2_3d(intmp_prl, grib2_t_str, npix, nlin,
439  float_SDStmp_prl, NPRFL_HGT,
440  &year, &month, &day, &hour);
441 
442  if (result == 1) {
443  strcpy(message, "readgrib file: ");
444  strcat(message, intmp_prl);
445  pexit(message);
446  }
447 
448 
449  shape_3d[0] = NPRFL; /* prfl */
450  shape_3d[1] = WPHLATSZ; /* lat */
451  shape_3d[2] = WPHLONSZ; /* lon */
452  array_size = shape_3d[0] * shape_3d[1] * shape_3d[2];
453 
454  if ((float_SDSrh_prl =
455  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
456  pexit("malloc float_SDSrh_prl");
457 
458  if ((float_SDSclwmr_prl =
459  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
460  pexit("malloc float_SDSclwmr_prl");
461 
462  if (grib_mode == GRIB_MODE_2)
463  result = readgrib2_3d(inrh_prl, grib2_t_str, npix, nlin, float_SDSrh_prl,
464  NPRFL,
465  &year, &month,
466  &day, &hour);
467 
468  if (result == 1) {
469  strcpy(message, "readgrib file: ");
470  strcat(message, inrh_prl);
471  pexit(message);
472  }
473 
474  if (grib_mode == GRIB_MODE_2)
475  result = readgrib2_3d(inclwmr_prl, grib2_t_str, npix, nlin,
476  float_SDSclwmr_prl, NPRFL,
477  &year, &month,
478  &day, &hour);
479 
480  if (result == 1) {
481  strcpy(message, "readgrib file: ");
482  strcat(message, inclwmr_prl);
483  pexit(message);
484  }
485 
486 
487  /*
488  * Create outfile name
489  * Note that for grib 2 files, whole year is available already
490  */
491  if (grib_mode == GRIB_MODE_1) {
492  if (year < 90) year = year + 2000; /* 2 digit 19xx or 20xx yrs to 4 */
493  else year = year + 1900;
494  }
495 
496  if (grib_mode == GRIB_MODE_1)
497  julval = julian_(&day, &month, &year);
498  // sprintf(outfile, "%s/Q%04d%03d%02d_%s.MET",
499  // outdir, year, julval, hour, source_name );
500 
501  //sprintf(outfilename, "Q%04d%03d%02d_%s.MET",
502  // year, julval, hour, source_name );
503 
504  sprintf(outfile, "%s/N%04d%03d%02d_QMET_NCEP_6h",
505  outdir, year, julval, hour);
506 
507  sprintf(outfilename, "N%04d%03d%02d_QMET_NCEP_6h",
508  year, julval, hour);
509  printf("%s\n", outfile);
510 
511 
512 
513  /*
514  * Write HDF annotations, lat and lon SDSs
515  */
516 
517  /**** check for existing HDF ***/
518  /*
519  // JMG
520  if (!access(outfile, F_OK)) pexit ("....output file exists");
521 
522  if ((numannarr = count_annot(annotfile)) == 0)
523  pexit ("no annotations found");
524 
525  if ((xannot = (struct annotation *)
526  malloc (sizeof(struct annotation) * numannarr))
527  == NULL) pexit ("malloc Annotation");
528 
529  xannot = fillenv_annot(annotfile);
530  */
531 
532  /*
533  * Determine processing time
534  */
535 
536  (void) time(&t);
537  localtm = localtime(&t);
538  pyear = localtm->tm_year;
539  if (pyear < 90) pyear = pyear + 2000; /* 2 digit 19xx or 20xx yrs to 4 */
540  else pyear = pyear + 1900;
541 
542  if (hour > 0) msec = hour * 60 * 60 * 1000;
543  else msec = 0;
544 
545  /*
546  * ------- assign metadata values to local descriptive variables ----
547  * ------- insert dates and other values to metadata array ---------
548  * ------- follow order of fillenv data file -----------------------
549  */
550 
551  for (i = 0; i < numannarr; i++) {
552 
553  /* Insert values to descr array element */
554 
555  if (!strcmp(xannot[i].label, "Product Name"))
556  sprintf(xannot[i].descr, "%s", outfilename);
557 
558  else if (!strcmp(xannot[i].label, "Processing Time"))
559  sprintf(xannot[i].descr, "%04d%03d%02d%02d%02d%03d",
560  pyear, (localtm->tm_yday + 1), localtm->tm_hour, localtm->tm_min,
561  localtm->tm_sec, 0);
562 
563  else if (!strcmp(xannot[i].label, "Input Files"))
564  sprintf(xannot[i].descr, "%s %s %s %s %s",
565  ingeohgt, intmp_sfc, inpress, inc_water, insoil_w);
566 
567  else if (!strcmp(xannot[i].label, "Processing Control"))
568  sprintf(xannot[i].descr, "%s %s %s %s %s %s %s %s",
569  argv[0], annotfile, ingeohgt, intmp_sfc, inpress,
570  inc_water, insoil_w, outdir);
571 
572  else if (!strcmp(xannot[i].label, "Start Time"))
573  sprintf(xannot[i].descr, "%04d%03d%02d0000000", year, julval, hour);
574 
575  else if (!strcmp(xannot[i].label, "End Time"))
576  sprintf(xannot[i].descr, "%04d%03d%02d0000000", year, julval, hour);
577 
578  else if (!strcmp(xannot[i].label, "Start Year"))
579  sprintf(xannot[i].descr, "%04d", year);
580 
581  else if (!strcmp(xannot[i].label, "Start Day"))
582  sprintf(xannot[i].descr, "%03d", julval);
583 
584  else if (!strcmp(xannot[i].label, "Start Millisec"))
585  sprintf(xannot[i].descr, "%08d", msec);
586 
587  else if (!strcmp(xannot[i].label, "End Year"))
588  sprintf(xannot[i].descr, "%04d", year);
589 
590  else if (!strcmp(xannot[i].label, "End Day"))
591  sprintf(xannot[i].descr, "%03d", julval);
592 
593  else if (!strcmp(xannot[i].label, "End Millisec"))
594  sprintf(xannot[i].descr, "%08d", msec);
595 
596  /* Extract values from descr array element for program use */
597 
598  else if (!strcmp(xannot[i].label, "Northernmost Latitude"))
599  sscanf(xannot[i].descr, "%f", &nmostlat);
600 
601  else if (!strcmp(xannot[i].label, "Southernmost Latitude"))
602  sscanf(xannot[i].descr, "%f", &smostlat);
603 
604  else if (!strcmp(xannot[i].label, "Westernmost Longitude"))
605  sscanf(xannot[i].descr, "%f", &wmostlon);
606 
607  else if (!strcmp(xannot[i].label, "Easternmost Longitude"))
608  sscanf(xannot[i].descr, "%f", &emostlon);
609 
610  else if (!strcmp(xannot[i].label, "Latitude Step"))
611  sscanf(xannot[i].descr, "%f", &latstep);
612 
613  /*
614  * WDR now a variable longitude step, # rows and columns
615  */
616  else if (!strcmp(xannot[i].label, "Longitude Step")) {
617  lonstep = 1.;
618  sprintf(xannot[i].descr, "%f", lonstep);
619  }
620  else if (!strcmp(xannot[i].label, "Number of Rows")) {
621  latsz = 181;
622  sprintf(xannot[i].descr, "%d", latsz);
623  }
624  else if (!strcmp(xannot[i].label, "Number of Columns")) {
625  lonsz = 360;
626  sprintf(xannot[i].descr, "%d", lonsz);
627  }
628  }
629 
630  /*
631  * Create HDF file
632  */
633 
634  if ((result = startHDF(outfile, &sdfid, &fid, DFACC_CREATE)) != 0)
635  pexit("Fatal error starting HDF file");
636 
637  /*
638  * Write attribute array to HDF file
639  */
640 
641  if ((result = wrtattr(sdfid, xannot, numannarr)) != 0) pexit("wrtattr");
642  // free(xannot);
643 
644 
645  /*
646  * ----------------- Create Vgroup ----------------------------
647  */
648 
649  gridid = setupGrid(fid, VGROUPNAME);
650 
651  /*
652  * ----------------- Write geohgt SDS ----------------------------
653  */
654  sdsname = "geohgt";
655  strcpy(longname, "Geopotential height, surface");
656  units = "gpm";
657  datafmt = "float32";
658  datatype = DFNT_FLOAT32;
659 
660  if ((SDSinFile(sdsname, longname, units, datafmt,
661  datatype, sdfid, rank, shape,
662  float_SDSgeohgt, gridid)) != 0)
663  pexit("SDSinFile geohgt");
664 
665  free(float_SDSgeohgt);
666 
667  /*
668  * ----------------- Write tmp_sfc SDS ----------------------------
669  */
670  sdsname = "tmp_sfc";
671  strcpy(longname, "Temperature at surface");
672  units = "degrees K";
673  datafmt = "float32";
674  datatype = DFNT_FLOAT32;
675 
676  if ((SDSinFile(sdsname, longname, units, datafmt,
677  datatype, sdfid, rank, shape,
678  float_SDStmp_sfc, gridid)) != 0)
679  pexit("SDSinFile tmp_sfc");
680 
681  free(float_SDStmp_sfc);
682 
683 
684  /*
685  * ----------------- Write pressure SDS ----------------------------
686  */
687  sdsname = "press";
688  strcpy(longname, "Atmospheric pressure at surface");
689  units = "Pascals";
690  datafmt = "float32";
691  datatype = DFNT_FLOAT32;
692 
693  if ((SDSinFile(sdsname, longname, units, datafmt,
694  datatype, sdfid, rank, shape,
695  float_SDSpress, gridid)) != 0)
696  pexit("SDSinFile press");
697 
698  free(float_SDSpress);
699 
700  /*
701  * ----------------- Write relative humidity 2 m AGL SDS ---------
702  */
703  sdsname = "rh";
704  strcpy(longname, "Relative Humidity, 2 m above ground level");
705  units = "percent";
706  datafmt = "float32";
707  datatype = DFNT_FLOAT32;
708 
709  if ((SDSinFile(sdsname, longname, units, datafmt,
710  datatype, sdfid, rank, shape,
711  float_SDSrh, gridid)) != 0)
712  pexit("SDSinFile rh");
713 
714  free(float_SDSrh);
715 
716 
717  /*
718  * ----------------- Write Precipitable water SDS -------------------------
719  */
720  sdsname = "p_water";
721  strcpy(longname, "Precipitable water");
722  units = "kg m^-2";
723  datafmt = "float32";
724  datatype = DFNT_FLOAT32;
725 
726  if ((SDSinFile(sdsname, longname, units, datafmt,
727  datatype, sdfid, rank, shape,
728  float_SDSp_water, gridid)) != 0)
729  pexit("SDSinFile p_water");
730 
731  free(float_SDSp_water);
732 
733 
734  /*
735  * ----------------- Write cloud water SDS ----------------------------
736  */
737  sdsname = "c_water";
738  strcpy(longname, "Cloud water");
739  units = "kg m^-2";
740  datafmt = "float32";
741  datatype = DFNT_FLOAT32;
742 
743  if ((SDSinFile(sdsname, longname, units, datafmt,
744  datatype, sdfid, rank, shape,
745  float_SDSc_water, gridid)) != 0)
746  pexit("SDSinFile c_water");
747 
748  free(float_SDSc_water);
749 
750 
751  /*
752  * ----------------- Write soil moisture SDS ----------------------------
753  */
754  sdsname = "soil_w";
755  strcpy(longname, "Soil moisture");
756  units = "";
757  datafmt = "float32";
758  datatype = DFNT_FLOAT32;
759 
760  if ((SDSinFile(sdsname, longname, units, datafmt,
761  datatype, sdfid, rank, shape,
762  float_SDSsoil_w, gridid)) != 0)
763  pexit("SDSinFile soil_w");
764 
765  free(float_SDSsoil_w);
766 
767 
768  /*
769  * ----------------- Write u wind SDS ----------------------------
770  */
771  sdsname = "u_wind";
772  strcpy(longname, "u wind 10 m");
773  units = "m sec^-1";
774  datafmt = "float32";
775  datatype = DFNT_FLOAT32;
776 
777  if ((SDSinFile(sdsname, longname, units, datafmt,
778  datatype, sdfid, rank, shape,
779  float_SDSu_wind, gridid)) != 0)
780  pexit("SDSinFile u_wind");
781 
782  free(float_SDSu_wind);
783 
784 
785  /*
786  * ----------------- Write v wind SDS ----------------------------
787  */
788  sdsname = "v_wind";
789  strcpy(longname, "v wind 10 m");
790  units = "m sec^-1";
791  datafmt = "float32";
792  datatype = DFNT_FLOAT32;
793 
794  if ((SDSinFile(sdsname, longname, units, datafmt,
795  datatype, sdfid, rank, shape,
796  float_SDSv_wind, gridid)) != 0)
797  pexit("SDSinFile v_wind");
798 
799  free(float_SDSv_wind);
800 
801 
802  /*
803  * ----------------- Write GFS snow SDS ----------------------------
804  */
805  sdsname = "snow_gfs";
806  strcpy(longname, "Snow (GFS)");
807  units = "kg/m^2";
808  datafmt = "float32";
809  datatype = DFNT_FLOAT32;
810 
811  if (strcmp(insnow_gfs, "NONE") != 0) {
812  if ((SDSinFile(sdsname, longname, units, datafmt,
813  datatype, sdfid, rank, shape_gfs,
814  float_SDSsnow_gfs, gridid)) != 0)
815  pexit("SDSinFile snow_gfs");
816 
817  free(float_SDSsnow_gfs);
818  }
819 
820 
821  /*
822  * ----------------- Write geohgt profile SDS -------------------------
823  */
824  sdsname = "geohgt_prfl";
825  strcpy(longname, "Geopotential height, profile");
826  units = "m sec^-1";
827  datafmt = "float32";
828  datatype = DFNT_FLOAT32;
829 
830  shape_3d[0] = NPRFL_HGT;
831 
832  if ((SDSinFile(sdsname, longname, units, datafmt,
833  datatype, sdfid, rank_3d, shape_3d,
834  float_SDSgeohgt_prl, gridid)) != 0)
835  pexit("SDSinFile geohgt");
836 
837  free(float_SDSgeohgt_prl);
838 
839  /*
840  * ----------------- Write tmp_bgr SDS ----------------------------
841  */
842  sdsname = "tmp_bgr";
843  strcpy(longname, "Temperature 0-0.1 m below ground");
844  units = "degrees K";
845  datafmt = "float32";
846  datatype = DFNT_FLOAT32;
847 
848  if ((SDSinFile(sdsname, longname, units, datafmt,
849  datatype, sdfid, rank, shape,
850  float_SDStmp_bgr, gridid)) != 0)
851  pexit("SDSinFile tmp_bgr");
852 
853  free(float_SDStmp_bgr);
854 
855 
856 
857  /*
858  * ----------------- Write tmp profile SDS -------------------------
859  */
860  sdsname = "tmp_prfl";
861  strcpy(longname, "Temperature, profile");
862  units = "degrees K";
863  datafmt = "float32";
864  datatype = DFNT_FLOAT32;
865 
866  if ((SDSinFile(sdsname, longname, units, datafmt,
867  datatype, sdfid, rank_3d, shape_3d,
868  float_SDStmp_prl, gridid)) != 0)
869  pexit("SDSinFile tmp");
870 
871  free(float_SDStmp_prl);
872 
873 
874  /*
875  * ----------------- Write relative humidity profile SDS -----------------
876  */
877  sdsname = "rh_prfl";
878  strcpy(longname, "Relative Humidity, profile");
879  units = "percent";
880  datafmt = "float32";
881  datatype = DFNT_FLOAT32;
882 
883  shape_3d[0] = NPRFL;
884 
885  if ((SDSinFile(sdsname, longname, units, datafmt,
886  datatype, sdfid, rank_3d, shape_3d,
887  float_SDSrh_prl, gridid)) != 0)
888  pexit("SDSinFile rh");
889 
890  free(float_SDSrh_prl);
891 
892 
893  /*
894  * ----------------- Write Cloud Mixing Ratio profile SDS -----------------
895  */
896  sdsname = "clwmr_prfl";
897  strcpy(longname, "Cloud Water Mixing Ratio, profile");
898  units = "";
899  datafmt = "float32";
900  datatype = DFNT_FLOAT32;
901 
902  if ((SDSinFile(sdsname, longname, units, datafmt,
903  datatype, sdfid, rank_3d, shape_3d,
904  float_SDSclwmr_prl, gridid)) != 0)
905  pexit("SDSinFile clwmr");
906 
907  free(float_SDSclwmr_prl);
908 
909 
910  /*
911  * deattach HDF grid (used for all products)
912  */
913 
914  deattachHDFgrid(gridid);
915 
916  /*
917  * close HDF structures
918  */
919 
920  if ((result = closeHDFstructs(sdfid, fid)) != 0) pexit("closeHDFstructs");
921 
922  return 0;
923 } /* main */
924 
925 int8 check_usage(int argc, char *argv[], int *n_opt_arg,
926  char *source_name, int *grib_mode, char *grib2_t_str)
927 /*****************************************************************
928  File: check_usage
929 
930  Purpose: check command line arguments
931 
932  Description: check command line arguements and report proper usage
933  on argument count error or no argumnts.
934 
935  Returns: success (0) or failure(-1)
936 
937  Parameters: (in calling order)
938  Type Name I/O Description
939  ---- ---- --- -----------
940  int argc I arg count
941  char *[] argv I input arg list
942  int * n_opt_arg O # option args
943  char * source_name O An alternate source (as in gbl
944  attrib source) name
945  int * grib_mode O Type of grib file the binary
946  file came from: GRIB_MODE_1 for
947  a GRIB 1 file, GRIB_MODE_2 for a
948  GRIB 2 file (NCEP std as of
949  Jan 2008)
950  char * grib2_t_str O string with time of the GRIB 2
951  data - used for setting file
952  name and attributes
953 
954  Note: This routine is custom for each program that uses it since
955  the arguments are different of course.
956 
957  Author: Brian D. Schieber, GSC, 10/93
958 
959  Mods: 10/4/93 BDS, new HDF inputs handle all 3 NCEP parms
960  W. Robinson, GSC, 4 Feb 97 changes for 5th param:rel_hum
961  W. Robinson, GSC, 18 Jun 98 add flexability to either accept
962  7 or 8 inputs for met data or 3 or 4 for ozone data
963  W. Robinson, SAIC, 12 May 2005 have optional argument -s
964  for an optional source name
965  W. Robinson, SAIC, 24 Jan 2008 add a grib mode -2 for grib 2
966  format files
967  *****************************************************************/ {
968  extern char *optarg;
969  extern int optind, optopt;
970  int c, opt_source_found, errflg;
971 
972  /*
973  * get the options first, one for the source name
974  */
975  *grib_mode = GRIB_MODE_1;
976  opt_source_found = 0;
977  errflg = 0;
978  *n_opt_arg = 0;
979  while ((c = getopt(argc, argv, ":s:2:")) != -1) {
980  switch (c) {
981  case 's':
982  strcpy(source_name, optarg);
983  opt_source_found = 1;
984  break;
985  case '2':
986  strcpy(grib2_t_str, optarg);
987  *grib_mode = GRIB_MODE_2;
988  break;
989  case ':': /* -s without operand */
990  fprintf(stderr,
991  "Option -%c requires an operand\n", optopt);
992  errflg++;
993  break;
994  case '?':
995  fprintf(stderr, "Unrecognized option: -%c\n", optopt);
996  errflg++;
997  }
998  }
999  if (!errflg) {
1000  *n_opt_arg = optind;
1001  /*
1002  * for regular arguments
1003  */
1004  strcpy(source_name, "NCEP");
1005 
1006  if (errflg) {
1007  printf("\n\nUsage:\n");
1008  printf("\t%s <metadata> <f1> <f2> <f3> <f4> <file> [outdir] [options]\n",
1009  argv[0]);
1010  printf("\t%s [-s<sname>] <metadata> [outdir]\n", argv[0]);
1011  printf("\nWhere:\n");
1012  printf("\tmetadata: DAAC-style HDF metadata (ASCII file)\n");
1013  printf("\tfiles: GRIB converted binary file to process\n");
1014  printf("\tFor met data, 6 input files (fX):\n");
1015  printf(
1016  "\t (geohgt.dat, tmp_sfc.dat, press.dat, c_water.dat soil_w.dat)\n");
1017  printf("\toutdir: Optional output directory ('.' default)\n");
1018  printf("\t Options:\n");
1019  printf("\t-s <sname> Optional source name to output file with:\n");
1020  printf("\t for MET data: QYYYYDDD00_<sname>.MET, default sname = NCEP\n");
1021  printf(
1022  "\t-2 <GRIB str> Specify the -2 with the <GRIB str> to process\n");
1023  printf(
1024  "\t binary files derived from a GRIB 2 format file. The\n");
1025  printf(
1026  "\t binary files are derived using wgrib2 with the -bin \n");
1027  printf(
1028  "\t option. The <GRIB str> is a required date / time\n");
1029  printf(
1030  "\t identification string gotten using wgrib -t\n");
1031  printf(
1032  "\t (see $SWFAPP/scripts/met_ingest2.scr for full example)\n");
1033  printf("\n");
1034  exit(-1);
1035  }
1036  }
1037  return (0);
1038 }
#define VGROUPNAME
int32_t setupGrid(int32_t fid, char *grpname)
Definition: ANCroutines.c:51
data_t t[NROOTS+1]
Definition: decode_rs.h:77
int j
Definition: decode_rs.h:73
int32_t day
int32_t SDSinFile(char *sdsname, char *longname, char *units, char *datafmt, int32_t datatype, int32_t sdfid, int32_t rank, int32_t *shape, void *data, int32_t gridid)
int32_t nl
Definition: atrem_corl1.h:132
int addAttr(int32_t sdsid, char *dataattr, int32_t datatype, char *dataunit)
Definition: ANCroutines.c:222
int8 check_usage(int argc, char *argv[], int *n_opt_arg, char *source_name, int *grib_mode, char *grib2_t_str)
#define NULL
Definition: decode_rs.h:63
int readgrib2(char *file, int npix, int nlin, int rgmode, float *data)
Definition: readgrib.c:77
int32 * msec
Definition: l1_czcs_hdf.c:31
float tm[MODELMAX]
#define WPHLONSZ
#define NPRFL_HGT
int main(int argc, char *argv[])
int nlin
Definition: get_cmp.c:28
#define VERSION
char descr[MAXDESCLEN]
Definition: ancil.h:72
#define GRIB_MODE_1
int wrtattr(int32_t dfile, struct annotation *annot, int numannarr)
Definition: ANCroutines.c:631
#define GRIB_MODE_2
void julian_(double *dtin, double *d_jd)
instead the metadata field ProcessingEnvinronment is filled in from the output of a call to the POSIX compliant function uname from within the L1B code A small bug in L1B_Tables an incorrect comparison of RVS coefficients for TEBs to RVS coefficients for RSBs was being made This was replaced with a comparison between TEB coefficients This error never resulted in an incorrect RVS correction but did lead to recalculating the coefficients for each detector in a thermal band even if the coefficients were the same for all detectors To reduce to overall size of the reflective LUT HDF fill values were eliminated from all LUTs previously dimensioned where and where NUM_TIMES is the number of time dependent table pieces In Preprocess a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed This counter is internal only and is not yet used for any chiefly to casting of were added to make it LINUX compatible Output of code run on LINUX machines displays differences of at most scaled sector incalculable values of the Emissive calibration factor and incalculable values of SV or BB averages was moved outside the loop over frames in Emissive_Cal c since none of these quantities are frame dependent Initialization of b1 and XMS values in Preprocess c routine Process_OBCENG_Emiss was moved inside the detector loops The code was altered so that if up to five scans are dropped between the leading middle or middle trailing the leading or trailing granule will still be used in emissive calibration to form a cross granule average QA bits and are set for a gap between the leading middle and middle trailing granules respectively This may in rare instances lead to a change in emissive calibration coefficients for scans at the beginning or end of a granule A small bug in the Band correction algorithm was corrected an uncertainty value was being checked against an upper bound whereas the proper quantity to be checked was the corresponding which is the product of the Band radiance times the ratio of the Band to Band scaling factors times the LUT correction value for that detector In addition a new LUT which allows for a frame offset with regard to the Band radiance was added A LUT which switches the correction off or on was also added Changes which do not affect scientific output of the the pixel is flagged with the newly created flag and the number of pixels for which this occurs is counted in the QA_common table The array of b1s in Preprocess c was being initialized to outside the loop over which meant that if b1 could not be the value of b1 from the previous band for that scan detector combination was used The initialization was moved inside the band loop Minor code changes were made to eliminate compiler warnings when the code is compiled in bit mode Temperature equations were upgraded to be MODIS AQUA or MODIS TERRA specific and temperature conversion coefficients for AQUA were MOD_PR02 will not cease execution if the value of this parameter is not but will print a message
Definition: HISTORY.txt:644
#define WPHLONSZ_GFS
int32_t wrtsds(int32_t sdfid, int rank, int32_t *shape, int32_t datatype, char *datalabel, void *data)
struct annotation * fillenv_annot(char *filename)
Definition: fillenv.c:15
int readgrib(char *file, int npix, int nlin, float *data, int *year, int *month, int *day, int *hour)
Definition: readgrib.c:6
int deattachHDFgrid(int32_t gridid)
Definition: ANCroutines.c:267
int grib2_t(char *grib2_t_str, int *year, int *doy, int *hour, int *npix, int *nlin, int *h_fcst)
Definition: readgrib.c:158
int closeHDFstructs(int32_t sdfid, int32_t fid)
Definition: ANCroutines.c:281
void pexit(char *string)
Definition: pexit.c:10
int readgrib2_3d(char *file, char *grib2_t_str, int npix, int nlin, float *data, int nprfl, int *year, int *month, int *day, int *hour)
Definition: readgrib.c:267
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that and then aggregated up to Resolved feature request Bug by adding three new int8 SDSs for each high resolution offsets between the high resolution geolocation and a bi linear interpolation extrapolation of the positions This can be used to reconstruct the high resolution geolocation Resolved Bug by delaying cumulation of gflags until after validation of derived products Resolved Bug by setting Latitude and Longitude to the correct fill resolving to support Near Real Time because they may be unnecessary if use of entrained ephemeris and attitude data is turned resolving bug report Corrected to filter out Aqua attitude records with missing status helping resolve bug MOD_PR03 will still correctly write scan and pixel data that does not depend upon the start time
Definition: HISTORY.txt:248
#define NPRFL
Extra metadata that will be written to the HDF4 file l2prod rank
#define WPHLATSZ_GFS
#define WPHLATSZ
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
int setSDSref(int32_t sdsid, int32_t gridid)
Definition: ANCroutines.c:245
#define MAXNAMELNG
Definition: ancil.h:43
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int k
Definition: decode_rs.h:73
string outfilename
Definition: color_dtdb.py:220
int npix
Definition: get_cmp.c:27
int startHDF(char *outfile, int32_t *sdfid, int32_t *fid, int32_t mode)
Definition: ANCroutines.c:27