Due to the lapse in federal government funding, NASA is not updating this website. We sincerely regret this inconvenience.
NASA Logo
Ocean Color Science Software

ocssw V2022
metqc.c
Go to the documentation of this file.
1 /*****************************************************************
2  * FILE: metqc.c
3  *
4  * PURPOSE: QC HDF ancillary real time datafile against climatology
5  * for one of four parameters.
6  *
7  * DESCRIPTION: This program will create a HDF with:
8  *
9  * HDF Geometry Vdata of Lat/Lon limits and steps.
10  * 2-D std dev of NRT vs CLM for z_wind or,
11  * 2-D std dev of NRT vs CLM for m_wind or,
12  * 2-D std dev of NRT vs CLM for press or,
13  * 2-D std dev of NRT vs CLM for rel_hum.
14  *
15  * A ASCII text file of %points in each STD category.
16  *
17  * For MET data:
18  * The real time parameter is read into array
19  * z_windRT, m_windRT, pressRT or rel_humRT
20  *
21  * Real-time files are dimensioned 73x144. The COADS based
22  * climatology is 90x180. A regridded COADS climatology
23  * (S19461990_COADS.REGRID.MET) is therefore used by this program.
24  *
25  * The climatological averages and standard deviations for the same time
26  * period (month) are read into:
27  * z_windCLMAVG, m_windCLMAVG, pressCLMAVG or rel_humCLMAVG and
28  * z_windCLMSTD, m_windCLMAVG, pressCLMSTD or rel_humCLMSTD respectively.
29 
30  *
31  * PROCEDURE:
32  *
33  * The CLMAVG array is subtracted from the RT array and
34  * divided by the CLMSTD array to produce an array of the number
35  * of std deviations from the mean for the real-time data.
36  *
37  * An option for an array of just the differences can be run by envoking
38  * the 'd' (difference) flag on the command line.
39  *
40  * As the data is processed a tally of points falling + and - 1, 2, and 3
41  * STDs from the mean will be stored for later writing of percentages in
42  * each category (if 'difference' option not used).
43  *
44  * INPUT PARMS: command line arguments (argv[?])
45  * [1] char *nrtfile - real-time input file to process
46  * ("S199310200_NMC.MET")
47  * [2] char *climfile - regridded climatology input file to process
48  * ("S19461990_COADS.REGRID.MET")
49  * [3] char *outfile - output QC filename.
50  * Note: FNOC could be used in place of NMC.
51  * [4] char monthstr - month being processed
52  * [5] - field to compare: 'z_wind', 'm_wind', 'press', 'rel_hum' or 'p_water'
53  * [6] float32 stdlimit1 - % w/in 1 STD
54  * [7] float32 stdlimit2 - % w/in 2 STD
55  * [8] float32 stdlimit3 - % w/in 3 STD
56  * [9] int maxmissing - max num missing pts.
57  *
58  * Optional inputs: on command line
59  * (args are read in order so preceeding optionals are required in order
60  * to use succeeding ones.)
61  *
62  * [10] float32 loval - lowest allowed value
63  * [11] float32 hival - highest allowed value
64  * [12] int outmax - max num allowed outliers before error flag set.
65  * [13] char gridflag - 'S'tandard deviation [default] or 'D'ifference calc.
66  * Note, difference calculations do not product reports.
67  * [14] int ifileflag - 0 = file is NRT file [default],
68  * 1 = file in CLM file (stats on one CLM vs another)
69  *
70  * OUTPUT PARMS:
71  * prints report to standard out.
72  * returns a SUCCESS (0) or FAILURE(5) value as Standard Deviation
73  * threshold exit status. This value can be checked with a C-shell
74  * $status flag.
75  *
76  * output name is similar to the input real-time file.
77  * Example name: "S199310200_NMC.MET.'parm'.qc"
78  * ('parm' = z_wind, m_wind, press, rel_hum or p_water)
79  *
80  * RETURNS: Program returns success or failure codes to a calling
81  * 'shell' script.
82  *
83  * LOCAL VARS: variables for storing HDFs.
84  *
85  * Subs called: int rdsds - reads an HDF SDS data grid
86  * int8 check_usage - confirm args
87  * int startHDF - open HDF file for output
88  * int setupGrid - setup HDF geometry struct
89  * int writeGeom - write HDF geometry struct
90  * int wrtsds - write HDF SDS array
91  * int addAttr - add HDF SDS attributes
92  * int setSDSref - set HDF SDS reference
93  * void deattachHDFgrid - detach HDF grid struct
94  * int closeHDFstructs - close HDF files
95  * int rd_size - read field size
96  * int resize_2d - resize climatology field to match nrt
97  *
98  * HISTORY: none
99  *
100  * NOTE: This program is meant to generate HDF QC SDS data sets.
101  *
102  * AUTHOR: Brian D. Schieber, GSC, 4/93
103  *
104  * MODIFICATION HISTORY:
105  *
106  * 10/14/93 BDS - Subtantial mods to process all three MET parameters
107  * at once and to handle the NEW HDF format specs.
108  * 12/06/93 BDS - Make that all 4 parms (z_wind,m_wind,press,rel_hum).
109  * Verifying the exclusion of missings from CLM in
110  * these calcs (in NRT, 0.0's passed through).
111  * Defined VALIDMIN to -99.1 (catches CDFMINVAL (-99.9)
112  * in CLM) as min threshold for QC valid points to
113  * calculate.
114  * 3/94 BDS - prep for call from script which used SYBASE calls.
115  * Append parm type to 'qc' file name.
116  * Return pass or fail STD DEV thresholds as file status.
117  * 5/94 BDS - allow specification of output directory
118  * 8/14/95 BDS - revised for OAPS spec 2.7
119  * 11/95 BDS, add ability to sum number of values in image < or >
120  * two specified range arguments and return FAIL if > outmax.
121  * Values for LO(lower range), HI (upper range),
122  * and OUTMAX (MAX. Pts allowed outside range) hardcoded within
123  * for each of the four parameters.
124  * Also, print min and max value of data.
125  * 8/21/96 BDS - renamed 'perror' to 'pexit' to avoid HDF4.0 conflict.
126  * W. Robinson, GSC, 6 Feb 97 add p_water and make code work independently
127  * of the nrt and climatology sizes
128  *****************************************************************/
129 #include <mfhdf.h>
130 
131 #include "ancil.h"
132 #include "l1io.h"
133 #include <genutils.h>
134 
135 /*
136  * Note on all data sizes: old (pre march 97) data sizes
137  * met nrt: 73 lines, 144 pixels
138  * met climatology: 90 lines, 180 pixels
139  * met climatology gridded: 73 lines, 144 pixels - same as nrt
140  */
141 /*
142  * MET specific settings
143  */
144 
145 #define VGROUPCLASS "PlanetaryGrid" /* all inner Vgroups use same name */
146 
147 #define BIN_METH 2 /* geometry structure settings */
148 #define REGISTRATION CENTER /* " */
149 
150 /* MET file settings */
151 #define VSIZE 2.5 /* " */
152 #define HSIZE 2.5 /* " */
153 #define MAX_NORTH 89.0 /* " */
154 #define MAX_SOUTH -89.0 /* " */
155 #define MAX_WEST -179.0 /* " */
156 #define MAX_EAST 179.0 /* " */
157 
158 #define VALIDMIN -99.1 /* using '.1' to compensate float */
159 #define CLMfile 1
160 
162 
163 int main(int argc, char *argv[]) {
164  int i, j, p;
165  int rank;
166  int result = 0;
167  int missing = 0;
168 
169  float32 minval = 1200.0; /* initial minimum value */
170  float32 maxval = -100.0; /* initial maximum value */
171 
172  float32 loZ_WIND = -30.0; /* default lo range threshold */
173  float32 hiZ_WIND = 30.0; /* default hi range threshold */
174  float32 loM_WIND = -30.0; /* default lo range threshold */
175  float32 hiM_WIND = 30.0; /* default hi range threshold */
176  float32 loPRESS = 850.0; /* default lo range threshold */
177  float32 hiPRESS = 1100.0; /* default hi range threshold */
178  float32 loREL_HUM = 5.0; /* default lo range threshold */
179  float32 hiREL_HUM = 100.0; /* default hi range threshold */
180  float32 loP_WATER = 0.; /* as above precip. water */
181  float32 hiP_WATER = 200.;
182  float32 loval; /* default actual range threshold */
183  float32 hival; /* default actual range threshold */
184  int outmax = 25; /* max num pts allowed to fall
185  outside range */
186 
187  int locnt; /* pts under lo range limit */
188  int hicnt; /* pts above hi range limit */
189  int rtmiss = 0;
190  int totalpts = 0;
191  int neg1cnt = 0;
192  int neg2cnt = 0;
193  int neg3cnt = 0;
194  int pos1cnt = 0;
195  int pos2cnt = 0;
196  int pos3cnt = 0;
197  int failed = 0;
198  int array_size = 0;
199  int32 shape_nrt[2], shape_clm[2];
200  int32 inShape[2];
201  char infileRT[MAXNAMELNG];
202  char infileCLM[MAXNAMELNG];
203  char outfile[MAXNAMELNG];
204  char gridflag[2];
205  char datalabel[MAXNAMELNG];
206  int32 datatype;
207  char *dataattr;
208  char *dataunit;
209  char vgname[MAXNAMELNG];
210  char monthstr[13];
211  char sdsname[MAXNAMELNG];
212  char vgroupname[21];
213  int32 sdsid, sdfid, fid, gridid, geomid;
214  int ifileflag = 0;
215  float32 stdlimit1, stdlimit2, stdlimit3;
216  int maxmissing;
217  /*
218  * data type array pointers
219  */
220 
221  float32 *float_SDSdataRT;
222  float32 *float_SDSdataCLMAVG;
223  float32 *float_SDSdataCLMSTD;
224  float32 *float_SDSdataQC;
225  float32 *c_avg, *c_std; /* new avg, std dev for pre-resized climatology */
226 
227  /* functions used from this file */
228 
229  int8 check_usage();
230 
231  int resize_2d(float *, int, int, int, int, float *);
232  int rd_size(char *, int *, int *);
233 
234  /*
235  * ------- check command line arguments and set args ------------------
236  */
237 
238  strcpy(gridflag, "s"); /* says: use std as default output QC field */
239  if ((check_usage(argc, argv)) != 0) pexit("insufficient args provided");
240 
241  strcpy(infileRT, argv[1]);
242  strcpy(infileCLM, argv[2]);
243  strcpy(outfile, argv[3]);
244  strcpy(monthstr, argv[4]);
245 
246  if (!strcmp(lowcase(argv[5]), "ozone"))
247  pexit("OZONE parameter type not supported by this program.");
248 
249  if (!strcmp(lowcase(argv[5]), "z_wind")) {
250  loval = loZ_WIND;
251  hival = hiZ_WIND;
252  } else if (!strcmp(lowcase(argv[5]), "m_wind")) {
253  loval = loM_WIND;
254  hival = hiM_WIND;
255  } else if (!strcmp(lowcase(argv[5]), "press")) {
256  loval = loPRESS;
257  hival = hiPRESS;
258  } else if (!strcmp(lowcase(argv[5]), "rel_hum")) {
259  loval = loREL_HUM;
260  hival = hiREL_HUM;
261  } else if (!strcmp(lowcase(argv[5]), "p_water")) {
262  loval = loP_WATER;
263  hival = hiP_WATER;
264  } else
265  pexit(
266  "parameter must be 'z_wind', 'm_wind', 'press', 'rel_hum' or 'p_water'.");
267 
268  strcpy(vgroupname, argv[5]);
269 
270  sscanf(argv[6], "%f", &stdlimit1);
271  sscanf(argv[7], "%f", &stdlimit2);
272  sscanf(argv[8], "%f", &stdlimit3);
273  sscanf(argv[9], "%d", &maxmissing);
274  if (argc >= 11) sscanf(argv[10], "%f", &loval);
275  if (argc >= 12) sscanf(argv[11], "%f", &hival);
276  if (argc >= 13) sscanf(argv[12], "%d", &outmax);
277  if (argc >= 14) {
278  strncpy(gridflag, argv[14], 1);
279  gridflag[1] = '\0';
280  }
281  if (argc >= 15) ifileflag = atoi(argv[15]);
282 
283 
284  /*
285  * ------- Read Z/M_WIND, PRESS, REL_HUM or OZONE real-time array files ---------
286  */
287 
288  if (ifileflag == CLMfile) {
289  strcpy(vgname, monthstr);
290  strcpy(sdsname, vgroupname);
291  strcat(sdsname, "_mean");
292  } else {
293  strcpy(vgname, "Geophysical Data");
294  strcpy(sdsname, vgroupname);
295  }
296  /*
297  * Read the size of the NRT field and set the size here
298  */
299  if (rd_size(infileRT, (int*) &shape_nrt[1], (int*) &shape_nrt[0]) != 0) {
300  pexit("metqc: Unable to read the data field size");
301  }
302  /*
303  * allocate the nrt-size arrays here
304  * RT - met field
305  * CLMAVG - mean climatology
306  * CLMSTD - Standard deviation of observations around the mean
307  * QC - output QC field
308  */
309  rank = 2;
310  array_size = shape_nrt[0] * shape_nrt[1];
311 
312  if ((float_SDSdataRT =
313  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
314  pexit("malloc float_SDSdataRT");
315 
316  if ((float_SDSdataCLMAVG =
317  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
318  pexit("malloc float_SDSdataCLMAVG");
319 
320  if ((float_SDSdataCLMSTD =
321  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
322  pexit("malloc float_SDSdataCLMSTD");
323 
324  if ((float_SDSdataQC =
325  (float32 *) malloc(sizeof (float32) * array_size)) == NULL)
326  pexit("malloc float_SDSdataQC");
327  /*
328  * Read Z/M_WIND, PRESS, REL_HUM, P_WATER or OZONE real-time array files
329  */
330 
331  if ((rdsds(infileRT, vgname, sdsname, inShape,
332  float_SDSdataRT)) != 0) pexit("rdsds RT");
333 
334  if ((inShape[0] != shape_nrt[0]) || (inShape[1] != shape_nrt[1])) {
335  printf("inShape[0] %d shape_nrt[0] %d inShape[1] %d shape_nrt[1] %d\n",
336  inShape[0], shape_nrt[0], inShape[1], shape_nrt[1]);
337  pexit("real-time dimensions not matching expected");
338  }
339 
340  /*
341  * ------- Determine appropriate climatology month (SDS) to match ------
342  * real time file. Get the average and std.dev. SDSs.
343  */
344 
345  /*
346  * Read the size of the CLM field and set the size here
347  */
348  if (rd_size(infileCLM, (int*) &shape_clm[1], (int*) &shape_clm[0]) != 0) {
349  pexit("metqc: Unable to read the climatology data field size");
350  }
351  /*
352  * allocate the space
353  */
354  if ((c_avg =
355  (float32 *) malloc(sizeof (float32) * shape_clm[0] * shape_clm[1]))
356  == NULL) {
357  pexit("malloc float_SDSdataCLMAVG");
358  }
359  if ((c_std =
360  (float32 *) malloc(sizeof (float32) * shape_clm[0] * shape_clm[1]))
361  == NULL) {
362  pexit("malloc float_SDSdataCLMAVG");
363  }
364 
365  strcpy(vgname, monthstr);
366  strcpy(sdsname, vgroupname);
367  strcat(sdsname, "_mean");
368 
369  if ((rdsds(infileCLM, vgname, sdsname, inShape,
370  c_avg)) != 0) pexit("rdsds CLMAVG");
371 
372  if ((inShape[0] != shape_clm[0]) || (inShape[1] != shape_clm[1])) {
373  printf("inShape[0] %d shape_clm[0] %d inShape[1] %d shape_clm[1] %d\n",
374  inShape[0], shape_clm[0], inShape[1], shape_clm[1]);
375  pexit("clim avg dimensions not matching expected");
376  }
377 
378  strcpy(sdsname, vgroupname);
379  strcat(sdsname, "_std_dev");
380 
381  if ((rdsds(infileCLM, vgname, sdsname, inShape,
382  c_std)) != 0) pexit("rdsds CLMSTD");
383 
384  if ((inShape[0] != shape_clm[0]) || (inShape[1] != shape_clm[1])) {
385  printf("inShape[0] %d shape_clm[0] %d inShape[1] %d shape_clm[1] %d\n",
386  inShape[0], shape_clm[0], inShape[1], shape_clm[1]);
387  pexit("clim std dimensions not matching expected");
388  }
389 
390  /*
391  l = 0;
392  for (i = 0; i < shape_nrt[0]; i++) {
393  printf ("\n");
394  for (j = 0; j < shape_nrt[1]; j++) {
395  printf ("%f ", float_SDSdataRT[l]);
396  l++;
397  }
398  }
399  */
400 
401  /*
402  * reconcile the climatology array size to that of the met field
403  */
404  printf("NRT field size is - pixels: %d, lines: %d\n",
405  shape_nrt[1], shape_nrt[0]);
406  if (shape_clm[0] != shape_nrt[0] || shape_clm[1] != shape_nrt[1]) {
407  printf("NOTE: Climatology field size is different\n");
408  printf(" Pixels: %d, lines: %d\n", shape_clm[1], shape_clm[0]);
409  printf(" Resizing climatology to match NRT\n");
410  }
411 
412  if ((shape_clm[0] <= 0) || (shape_clm[1] <= 0) ||
413  (shape_nrt[0] <= 0) || (shape_nrt[1] <= 0)) {
414  pexit("metqc: one of shape_clm, shape_nrt dimensions <= 0!");
415  }
416  if (resize_2d(c_avg, shape_clm[1], shape_clm[0],
417  shape_nrt[1], shape_nrt[0], float_SDSdataCLMAVG) != 0) {
418  pexit("metqc: resize_2d problem for CLMAVG, exiting");
419  }
420 
421  if (resize_2d(c_std, shape_clm[1], shape_clm[0],
422  shape_nrt[1], shape_nrt[0], float_SDSdataCLMSTD) != 0) {
423  pexit("metqc: resize_2d problem for CLMSTD, exiting");
424  }
425  free(c_avg);
426  free(c_std);
427 
428  /*
429  * ------- Compute variance of real-time from climatology -----------
430  * and tally #0s (and/or missing), #+ & - 1,2,3 std dev
431  * for writing to file for mailing.
432  */
433 
434  p = 0;
435  missing = 0;
436  locnt = 0;
437  hicnt = 0;
438  rtmiss = 0;
439  neg1cnt = 0;
440  neg2cnt = 0;
441  neg3cnt = 0;
442  pos1cnt = 0;
443  pos2cnt = 0;
444  pos3cnt = 0;
445 
446  for (i = 0; i < shape_nrt[0]; i++) {
447  for (j = 0; j < shape_nrt[1]; j++) {
448  float_SDSdataQC[p] = 0.0; /* initialize each point */
449 
450  /* pt. is missing, NRT missing, a MIN val, and counted as out of
451  lower range */
452  if ((float_SDSdataRT[p] <= VALIDMIN) ||
453  (float_SDSdataCLMAVG[p] <= VALIDMIN)) {
454  missing++;
455  if (float_SDSdataRT[p] <= VALIDMIN) rtmiss++;
456  if (float_SDSdataRT[p] < minval) minval = float_SDSdataRT[p];
457  if (float_SDSdataRT[p] < loval) locnt++;
458  } else {
459  if ((!strcmp(gridflag, "d")) || (!strcmp(gridflag, "D"))) {
460  float_SDSdataQC[p] =
461  (float32) float_SDSdataRT[p] - float_SDSdataCLMAVG[p];
462  } else {
463  if (float_SDSdataCLMSTD[p] > 0)
464  float_SDSdataQC[p] = (float32)
465  (float_SDSdataRT[p] - float_SDSdataCLMAVG[p]) /
466  float_SDSdataCLMSTD[p];
467  }
468 
469  /* find min and max of all points */
470  if (float_SDSdataRT[p] < minval) minval = float_SDSdataRT[p];
471  if (float_SDSdataRT[p] > maxval) maxval = float_SDSdataRT[p];
472 
473  /* sum up points outside lo/hi range (LO adds to missing counts)*/
474  if (float_SDSdataRT[p] < loval) locnt++;
475  if (float_SDSdataRT[p] > hival) hicnt++;
476 
477  if (float_SDSdataQC[p] < -1.0) neg1cnt++;
478  if (float_SDSdataQC[p] < -2.0) neg2cnt++;
479  if (float_SDSdataQC[p] < -3.0) neg3cnt++;
480 
481  if (float_SDSdataQC[p] > 1.0) pos1cnt++;
482  if (float_SDSdataQC[p] > 2.0) pos2cnt++;
483  if (float_SDSdataQC[p] > 3.0) pos3cnt++;
484  }
485  /*
486  if ((j > 100) && (j < 150)) {
487  printf("QC [%d][%d]: %f\n", i,j,float_SDSdataQC[p]);
488  printf("RT [%d][%d]: %f\n", i,j,float_SDSdataRT[p]);
489  printf("AVG [%d][%d]: %f\n", i,j,float_SDSdataCLMAVG[p]);
490  printf("STD [%d][%d]: %f\n", i,j,float_SDSdataCLMSTD[p]);
491  }
492  printf("[%d][%d]: %f %f %f\n", i,j,float_SDSdataRT[p],
493  float_SDSdataCLMAVG[p], float_SDSdataCLMSTD[p]);
494  */
495  p++;
496  } /* for j */
497  } /* for i */
498 
499  totalpts = array_size - missing;
500 
501  free(float_SDSdataRT);
502  free(float_SDSdataCLMAVG);
503  free(float_SDSdataCLMSTD);
504 
505 #if 0
506  p = 0;
507  for (i = 0; i < shape_nrt[0]; i++) {
508  for (j = 0; j < shape_nrt[1]; j++) {
509  float_SDSdataQC[p] = 0.0; /* initialize each point */
510  p++;
511  } /* for j */
512  } /* for i */
513 #endif
514 
515  /*
516  * ----------------- Write QC SDS ----------------------------
517  */
518 
519  /*
520  * Create HDF file
521  */
522 
523 
524  if ((startHDF(outfile, &sdfid, &fid, DFACC_CREATE)) != 0)
525  pexit("Fatal error starting output HDF file");
526 
527  /*
528  * Create grid structure
529  */
530 
531  /* gridid = setupGrid(fid, VGROUPCLASS, vgroupname); */
532  gridid = setupGrid(fid, vgroupname);
533 
534  /*
535  * Write geometry Vdata, get ref, and add to grid Vgroup (geomid not used)
536  */
537 
538  if ((geomid = writeGeom(fid, gridid, GEOMNAME, BIN_METH, REGISTRATION,
540  MAX_WEST, MAX_EAST)) == ERROR)
541  pexit("Fatal error writing geometry");
542 
543  /*
544  * Write SDS grid
545  */
546 
547  strcpy(datalabel, "QC array");
548  datatype = DFNT_FLOAT;
549  dataattr = "UNITS";
550  dataunit = "std dev diff";
551 
552  if ((sdsid = wrtsds(sdfid, rank, shape_nrt, datatype, datalabel,
553  float_SDSdataQC)) < 0) pexit("main wrtsds");
554 
555  free(float_SDSdataQC);
556 
557  /*
558  * set SDS attribute
559  */
560 
561  if ((result = addAttr(sdsid, dataattr, DFNT_CHAR, dataunit)) != 0)
562  pexit("addAttr");
563 
564  /*
565  * add SDS to Vgroup and deattach SDS
566  */
567 
568  if ((result = setSDSref(sdsid, gridid)) != 0) pexit("setSDSref");
569 
570  /*
571  * deattach HDF grid
572  */
573 
574  deattachHDFgrid(gridid);
575 
576  /*
577  * close HDF structures
578  */
579 
580  if ((result = closeHDFstructs(sdfid, fid)) != 0) pexit("closeHDFstructs");
581 
582  /*
583  * ----------------- Print stats to standard output -----------
584  */
585 
586  /* printf("gridflag [%s]\n",gridflag); */
587 
588  if (!strcmp(gridflag, "s")) {
589  printf("\n");
590  printf("-------------------------------------------------------------\n");
591  printf("Results of comparison of real-time and climatological files:\n");
592  printf("%s\n%s\n", infileRT, infileCLM);
593  printf("Month: %s\t\tParameter: %s\n", monthstr, argv[5]);
594  printf("Thresholds: %8.3f %8.3f %8.3f Max Missings: %d",
595  stdlimit1, stdlimit2, stdlimit3, maxmissing);
596  printf("\n");
597  printf("Minimum value: %8.3f Maximum: %8.3f\n", minval, maxval);
598 
599  printf("Total # non-missing values: %6d\n", totalpts);
600  printf("Total # values <%8.3f: %d >%8.3f: %d allowed: %d",
601  loval, locnt, hival, hicnt, outmax);
602 
603  /* if (locnt >= outmax) failed = 1; lo points out of range exceeded */
604  /* if (hicnt >= outmax) failed = 1; hi points out of range exceeded */
605  /*
606  * WDR if fail in either case, append a set of astrisks
607  */
608  if (locnt >= outmax || hicnt >= outmax) {
609  failed = 1;
610  printf(" ***\n");
611  } else {
612  printf("\n");
613  }
614 
615  printf("\n");
616  printf("Total # points/percentage < -1 STD: %6d (%5.2f percent)\n",
617  neg1cnt, (float) neg1cnt / totalpts * 100.0);
618  printf("Total # points/percentage +/- 1 STD: %6d (%5.2f percent)",
619  totalpts - (neg1cnt + pos1cnt),
620  (float) (totalpts - (pos1cnt + neg1cnt)) / totalpts * 100.0);
621 
622  if (((float) (totalpts - (pos1cnt + neg1cnt)) / totalpts * 100.0) <
623  stdlimit1) {
624  failed = 1;
625  printf(" ***\n");
626  } else {
627  printf("\n");
628  }
629 
630  printf("Total # points/percentage > 1 STD: %6d (%5.2f percent)\n",
631  pos1cnt, (float) pos1cnt / totalpts * 100.0);
632  printf("\n");
633 
634  printf("Total # points/percentage < -2 STD: %6d (%5.2f percent)\n",
635  neg2cnt, (float) neg2cnt / totalpts * 100.0);
636  printf("Total # points/percentage +/- 2 STD: %6d (%5.2f percent)",
637  totalpts - (neg2cnt + pos2cnt),
638  (float) (totalpts - (pos2cnt + neg2cnt)) / totalpts * 100.0);
639 
640  if (((float) (totalpts - (pos2cnt + neg2cnt)) / totalpts * 100.0) <
641  stdlimit2) {
642  failed = 1;
643  printf(" ***\n");
644  } else {
645  printf("\n");
646  }
647 
648  printf("Total # points/percentage > 2 STD: %6d (%5.2f percent)\n",
649  pos2cnt, (float) pos2cnt / totalpts * 100.0);
650  printf("\n");
651 
652  printf("Total # points/percentage < -3 STD: %6d (%5.2f percent)\n",
653  neg3cnt, (float) neg3cnt / totalpts * 100.0);
654  printf("Total # points/percentage +/- 3 STD: %6d (%5.2f percent)",
655  totalpts - (neg3cnt + pos3cnt),
656  (float) (totalpts - (pos3cnt + neg3cnt)) / totalpts * 100.0);
657 
658  if (((float) (totalpts - (pos3cnt + neg3cnt)) / totalpts * 100.0) <
659  stdlimit3) {
660  failed = 1;
661  printf(" ***\n");
662  } else {
663  printf("\n");
664  }
665 
666  printf("Total # points/percentage > 3 STD: %6d (%5.2f percent)\n",
667  pos3cnt, (float) pos3cnt / totalpts * 100.0);
668  printf("\n");
669 
670  printf("Total # missing values: %6d\n", missing);
671  printf("Total # missing real-time: %6d", rtmiss);
672  if (rtmiss > maxmissing) {
673  failed = 1;
674  printf(" ***\n");
675  } else {
676  printf("\n");
677  }
678  printf("-------------------------------------------------------------\n");
679  printf("\n\n");
680 
681  }
682 
683  /* set exit value to reflect threshold checks */
684 
685  if (failed) {
686  printf("Threshold Status: FAILED\n");
687  return (FAILURE);
688  } else {
689  printf("Threshold Status: SUCCESS\n");
690  return (SUCCESS);
691  }
692 } /* main */
693 
694 /*****************************************************************
695  *
696  * check user parameters and show example if not all parms given
697  *
698  *****************************************************************/
699 
700 int8 check_usage(int argc, char *argv[]) {
701  if (argc < 9) {
702  printf("\n\nUsage:\n");
703  printf("\t%s <file><file><outfile><monthstr><param><t1><t2><t2><maxmiss><lo><hi><outmax>[diff][type] \n", argv[0]);
704  printf("\nWhere:\n");
705  printf("\tfile: Real-time file to process\n");
706  printf("\tfile: Climatology file\n");
707  printf("\toutfile: Output QC file\n");
708  printf("\tmonthstr: Month in string form (i.e., January)\n");
709  printf("\tparam: Parameter to run: z_wind m_wind press rel_hum p_water\n");
710  printf("\tt1: Threshold percent of pts w/in 1 STD DEV of clim\n");
711  printf("\tt2: Threshold percent of pts w/in 2 STD DEV of clim\n");
712  printf("\tt3: Threshold percent of pts w/in 3 STD DEV of clim\n");
713  printf("\tmaxmiss: Max num of missing NRT points permitted\n");
714  printf("\tlo: Lowest allowed value in NRT file\n");
715  printf("\thi: Highest allowed value in NRT file\n");
716  printf("\tlo: Maximum # of NRT points allowed outside of lo/hi before returning an error flag\n");
717  printf("\t [optional] parameters follow. Preceeding args \n");
718  printf("\t are required for subsequent ones used\n");
719  printf("\tdiff: [optional] Enter 'd' to see a simple difference output\n");
720  printf("\t grid rather than the default STD variance 's'\n");
721  printf("\t Difference calculations do not product reports\n");
722  printf("\ttype [optional] Enter 1 if NRT file is actually a CLM file\n");
723  printf("\t This will allow the program to read the CLM\n");
724  printf("\t as of test of CLM to itself\n");
725  printf("\n");
726  return (ERROR);
727  }
728  return 0;
729 }
struct annotation * annot
Definition: metqc.c:161
int32_t setupGrid(int32_t fid, char *grpname)
Definition: ANCroutines.c:51
#define SUCCESS
Definition: ObpgReadGrid.h:15
int j
Definition: decode_rs.h:73
#define CLMfile
Definition: metqc.c:159
char * lowcase(char *instr)
Definition: lowcase.c:10
int addAttr(int32_t sdsid, char *dataattr, int32_t datatype, char *dataunit)
Definition: ANCroutines.c:222
int8 check_usage(int argc, char *argv[])
Definition: metqc.c:700
int main(int argc, char *argv[])
Definition: metqc.c:163
#define NULL
Definition: decode_rs.h:63
int rd_size(char *file, int *npix, int *nlin)
Definition: rd_size.c:4
#define MAX_SOUTH
Definition: metqc.c:154
#define HSIZE
Definition: metqc.c:152
#define MAX_EAST
Definition: metqc.c:156
int resize_2d(float *in_arr, int inpix, int inlin, int outpix, int outlin, float *out_arr)
Definition: resize_2d.c:1
#define VALIDMIN
Definition: metqc.c:158
#define BIN_METH
Definition: metqc.c:147
int32_t wrtsds(int32_t sdfid, int rank, int32_t *shape, int32_t datatype, char *datalabel, void *data)
int deattachHDFgrid(int32_t gridid)
Definition: ANCroutines.c:267
#define VSIZE
Definition: metqc.c:151
int closeHDFstructs(int32_t sdfid, int32_t fid)
Definition: ANCroutines.c:281
void pexit(char *string)
Definition: pexit.c:10
int32_t writeGeom(int32_t fid, int32_t gridid, char *geomname, int32_t bin_meth, int32_t registration, float vsize, float hsize, float max_north, float max_south, float max_west, float max_east)
Definition: ANCroutines.c:92
#define FAILURE
Definition: ancil.h:25
Extra metadata that will be written to the HDF4 file l2prod rank
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
#define REGISTRATION
Definition: metqc.c:148
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
#define GEOMNAME
Definition: ancil.h:44
#define MAX_NORTH
Definition: metqc.c:153
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define MAX_WEST
Definition: metqc.c:155
int rdsds(char *filename, char *vgname, char *sdsname, int32_t *dimsizes, void *inData)
float p[MODELMAX]
Definition: atrem_corl1.h:131
int startHDF(char *outfile, int32_t *sdfid, int32_t *fid, int32_t mode)
Definition: ANCroutines.c:27
#define ERROR
Definition: ancil.h:24