145 #define VGROUPCLASS "PlanetaryGrid"
148 #define REGISTRATION CENTER
153 #define MAX_NORTH 89.0
154 #define MAX_SOUTH -89.0
155 #define MAX_WEST -179.0
156 #define MAX_EAST 179.0
158 #define VALIDMIN -99.1
169 float32 minval = 1200.0;
170 float32 maxval = -100.0;
172 float32 loZ_WIND = -30.0;
173 float32 hiZ_WIND = 30.0;
174 float32 loM_WIND = -30.0;
175 float32 hiM_WIND = 30.0;
176 float32 loPRESS = 850.0;
177 float32 hiPRESS = 1100.0;
178 float32 loREL_HUM = 5.0;
179 float32 hiREL_HUM = 100.0;
180 float32 loP_WATER = 0.;
181 float32 hiP_WATER = 200.;
199 int32 shape_nrt[2], shape_clm[2];
213 int32 sdsid, sdfid, fid, gridid, geomid;
215 float32 stdlimit1, stdlimit2, stdlimit3;
221 float32 *float_SDSdataRT;
222 float32 *float_SDSdataCLMAVG;
223 float32 *float_SDSdataCLMSTD;
224 float32 *float_SDSdataQC;
225 float32 *c_avg, *c_std;
231 int resize_2d(
float *,
int,
int,
int,
int,
float *);
232 int rd_size(
char *,
int *,
int *);
241 strcpy(infileRT, argv[1]);
242 strcpy(infileCLM, argv[2]);
244 strcpy(monthstr, argv[4]);
246 if (!strcmp(
lowcase(argv[5]),
"ozone"))
247 pexit(
"OZONE parameter type not supported by this program.");
249 if (!strcmp(
lowcase(argv[5]),
"z_wind")) {
252 }
else if (!strcmp(
lowcase(argv[5]),
"m_wind")) {
255 }
else if (!strcmp(
lowcase(argv[5]),
"press")) {
258 }
else if (!strcmp(
lowcase(argv[5]),
"rel_hum")) {
261 }
else if (!strcmp(
lowcase(argv[5]),
"p_water")) {
266 "parameter must be 'z_wind', 'm_wind', 'press', 'rel_hum' or 'p_water'.");
268 strcpy(vgroupname, argv[5]);
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);
278 strncpy(gridflag, argv[14], 1);
281 if (
argc >= 15) ifileflag = atoi(argv[15]);
290 strcpy(sdsname, vgroupname);
291 strcat(sdsname,
"_mean");
293 strcpy(vgname,
"Geophysical Data");
294 strcpy(sdsname, vgroupname);
299 if (
rd_size(infileRT, (
int*) &shape_nrt[1], (
int*) &shape_nrt[0]) != 0) {
300 pexit(
"metqc: Unable to read the data field size");
310 array_size = shape_nrt[0] * shape_nrt[1];
312 if ((float_SDSdataRT =
313 (float32 *) malloc(
sizeof (float32) * array_size)) ==
NULL)
314 pexit(
"malloc float_SDSdataRT");
316 if ((float_SDSdataCLMAVG =
317 (float32 *) malloc(
sizeof (float32) * array_size)) ==
NULL)
318 pexit(
"malloc float_SDSdataCLMAVG");
320 if ((float_SDSdataCLMSTD =
321 (float32 *) malloc(
sizeof (float32) * array_size)) ==
NULL)
322 pexit(
"malloc float_SDSdataCLMSTD");
324 if ((float_SDSdataQC =
325 (float32 *) malloc(
sizeof (float32) * array_size)) ==
NULL)
326 pexit(
"malloc float_SDSdataQC");
331 if ((
rdsds(infileRT, vgname, sdsname, inShape,
332 float_SDSdataRT)) != 0)
pexit(
"rdsds RT");
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");
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");
355 (float32 *) malloc(
sizeof (float32) * shape_clm[0] * shape_clm[1]))
357 pexit(
"malloc float_SDSdataCLMAVG");
360 (float32 *) malloc(
sizeof (float32) * shape_clm[0] * shape_clm[1]))
362 pexit(
"malloc float_SDSdataCLMAVG");
366 strcpy(sdsname, vgroupname);
367 strcat(sdsname,
"_mean");
369 if ((
rdsds(infileCLM, vgname, sdsname, inShape,
370 c_avg)) != 0)
pexit(
"rdsds CLMAVG");
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");
378 strcpy(sdsname, vgroupname);
379 strcat(sdsname,
"_std_dev");
381 if ((
rdsds(infileCLM, vgname, sdsname, inShape,
382 c_std)) != 0)
pexit(
"rdsds CLMSTD");
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");
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");
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!");
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");
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");
446 for (
i = 0;
i < shape_nrt[0];
i++) {
447 for (
j = 0;
j < shape_nrt[1];
j++) {
448 float_SDSdataQC[
p] = 0.0;
455 if (float_SDSdataRT[
p] <=
VALIDMIN) rtmiss++;
456 if (float_SDSdataRT[
p] < minval) minval = float_SDSdataRT[
p];
457 if (float_SDSdataRT[
p] < loval) locnt++;
459 if ((!strcmp(gridflag,
"d")) || (!strcmp(gridflag,
"D"))) {
461 (float32) float_SDSdataRT[
p] - float_SDSdataCLMAVG[
p];
463 if (float_SDSdataCLMSTD[
p] > 0)
464 float_SDSdataQC[
p] = (float32)
465 (float_SDSdataRT[
p] - float_SDSdataCLMAVG[
p]) /
466 float_SDSdataCLMSTD[
p];
470 if (float_SDSdataRT[
p] < minval) minval = float_SDSdataRT[
p];
471 if (float_SDSdataRT[
p] > maxval) maxval = float_SDSdataRT[
p];
474 if (float_SDSdataRT[
p] < loval) locnt++;
475 if (float_SDSdataRT[
p] > hival) hicnt++;
477 if (float_SDSdataQC[
p] < -1.0) neg1cnt++;
478 if (float_SDSdataQC[
p] < -2.0) neg2cnt++;
479 if (float_SDSdataQC[
p] < -3.0) neg3cnt++;
481 if (float_SDSdataQC[
p] > 1.0) pos1cnt++;
482 if (float_SDSdataQC[
p] > 2.0) pos2cnt++;
483 if (float_SDSdataQC[
p] > 3.0) pos3cnt++;
499 totalpts = array_size - missing;
501 free(float_SDSdataRT);
502 free(float_SDSdataCLMAVG);
503 free(float_SDSdataCLMSTD);
507 for (
i = 0;
i < shape_nrt[0];
i++) {
508 for (
j = 0;
j < shape_nrt[1];
j++) {
509 float_SDSdataQC[
p] = 0.0;
525 pexit(
"Fatal error starting output HDF file");
541 pexit(
"Fatal error writing geometry");
547 strcpy(datalabel,
"QC array");
548 datatype = DFNT_FLOAT;
550 dataunit =
"std dev diff";
552 if ((sdsid =
wrtsds(sdfid,
rank, shape_nrt, datatype, datalabel,
553 float_SDSdataQC)) < 0)
pexit(
"main wrtsds");
555 free(float_SDSdataQC);
561 if ((
result =
addAttr(sdsid, dataattr, DFNT_CHAR, dataunit)) != 0)
588 if (!strcmp(gridflag,
"s")) {
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);
597 printf(
"Minimum value: %8.3f Maximum: %8.3f\n", minval, maxval);
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);
608 if (locnt >= outmax || hicnt >= outmax) {
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);
622 if (((
float) (totalpts - (pos1cnt + neg1cnt)) / totalpts * 100.0) <
630 printf(
"Total # points/percentage > 1 STD: %6d (%5.2f percent)\n",
631 pos1cnt, (
float) pos1cnt / totalpts * 100.0);
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);
640 if (((
float) (totalpts - (pos2cnt + neg2cnt)) / totalpts * 100.0) <
648 printf(
"Total # points/percentage > 2 STD: %6d (%5.2f percent)\n",
649 pos2cnt, (
float) pos2cnt / totalpts * 100.0);
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);
658 if (((
float) (totalpts - (pos3cnt + neg3cnt)) / totalpts * 100.0) <
666 printf(
"Total # points/percentage > 3 STD: %6d (%5.2f percent)\n",
667 pos3cnt, (
float) pos3cnt / totalpts * 100.0);
670 printf(
"Total # missing values: %6d\n", missing);
671 printf(
"Total # missing real-time: %6d", rtmiss);
672 if (rtmiss > maxmissing) {
678 printf(
"-------------------------------------------------------------\n");
686 printf(
"Threshold Status: FAILED\n");
689 printf(
"Threshold Status: SUCCESS\n");
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");