int db_gFileNames ( const char *dir, int isearch, struct dirent ***ret_namelist) /************************************************************************ * * * db_gFileNames * * * * m.gamazaychikov/SAIC 11/08 Created * ************************************************************************/ { int possible_ens_nmbr = 100; int possible_fcst_hrs = 500; int max_file_name_length = 50; int max_number_components = 13; int max_component_length = 75; int possible_fileNames; int ii, jj, ier, ier1, len; int used, allocated,istmax; char modelName[30], dbTag[5], ensTag[20], timeTmpl[75]; char *fileNames; char **starr; struct dirent *entry=NULL, *entry2=NULL; struct dirent **namelist = NULL; /*---------------------------------------------------------------------*/ /* * Initialization */ modelName[0] = '\0'; dbTag[0] = '\0'; ensTag[0] = '\0'; timeTmpl[0] = '\0'; /* * Allocate memmory for starr and get the components */ starr = (char **)malloc((size_t)max_number_components * sizeof(char *)); istmax = 0; for( jj=0; jj < max_number_components; jj++ ) starr[jj] = (char *)malloc( max_component_length * sizeof(char)); cst_clst (dir, '_', " ", max_number_components, max_component_length, starr, &istmax, &ier); if ( istmax ==4 ) { sprintf ( modelName, "%s", starr[0] ); sprintf ( dbTag, "%s", starr[1] ); sprintf ( ensTag, "%s", starr[2] ); sprintf ( timeTmpl, "%s", starr[3] ); } else { if ( istmax > 4 ) { sprintf ( modelName, "%s", starr[0] ); sprintf ( dbTag, "%s", starr[1] ); sprintf ( ensTag, "%s", starr[2] ); for ( jj = 3; jj < istmax; jj ++ ) { if ( starr[jj][0] == '[' ) { sprintf ( timeTmpl, "%s", starr[jj] ); break; } else { strcat ( ensTag,"_" ); strcat ( ensTag,starr[jj] ); } } istmax = 4; } else { for ( jj = 0; jj < max_number_components; jj++ ) free( starr[jj] ); if( starr ) free( (char **)starr ); return(0); } } /* * Free memory allocated for starr */ for ( jj = 0; jj < max_number_components; jj++ ) free( starr[jj] ); if( starr ) free( (char **)starr ); /* * Allocate memmory for fileNames */ possible_fileNames = possible_ens_nmbr * possible_fcst_hrs; fileNames = (char *)malloc( possible_fileNames * max_file_name_length * sizeof(char)); db_scandb ( modelName, dbTag, ensTag, timeTmpl, fileNames, &ier); if ( ier != 0 ) { return (0); } /* * Allocate memmory for starr and * break the fileNames string into parts each representing 'file' */ starr = (char **)malloc((size_t)possible_fileNames * sizeof(char *)); istmax = 0; for( jj=0; jj < possible_fileNames; jj++ ) starr[jj] = (char *)malloc( max_file_name_length * sizeof(char)); cst_clst (fileNames, '|', " ", possible_fileNames, max_file_name_length, starr, &istmax, &ier); /* * Free memory allocated for fileNames */ free( fileNames ); /* * Fake scandir function to return back namelist structure */ used = 0; allocated = 2; namelist = malloc(allocated * sizeof(struct dirent *)); entry = (struct dirent *) malloc (sizeof(struct dirent)); for ( ii = 0; ii < istmax; ii++ ) { sprintf ( entry->d_name, "%s", starr[ii] ); len = offsetof(struct dirent, d_name) + strlen(entry->d_name) + 1; if ((entry2 = malloc(len)) == NULL) { for ( jj = 0; jj < possible_fileNames; jj++ ) free( starr[jj] ); if( starr ) free( (char **)starr ); free (entry); ier = -7; er_wmsg ( "DB", &ier, NULL, &ier1, 2, 0 ); return(0); } if (used >= allocated) { allocated *= 2; namelist = realloc(namelist, allocated * sizeof(struct dirent *)); if (!namelist) { for ( jj = 0; jj < possible_fileNames; jj++ ) free( starr[jj] ); if( starr ) free( (char **)starr ); free (entry); ier = -7; er_wmsg ( "DB", &ier, NULL, &ier1, 2, 0 ); ier = -7; er_wmsg ( "DB", &ier, NULL, &ier1, 2, 0 ); return(0); } } memcpy(entry2, entry, len); namelist[used++] = entry2; } free (entry); for ( jj=0; jj < possible_fileNames; jj++ ) free( starr[jj] ); if ( starr ) free( (char **)starr ); *ret_namelist = namelist; return(istmax); }
void de_prcntl ( const char *uarg, char *stprm, int *iret ) /************************************************************************ * de_prcntl * * * * This subroutine returns a value at each grid point such that the * * value returned is greater than or equal to the value found at the * * same grid point in P% of the weighted members of an ensemble. The * * value of P ranges between 0 and 100 and may vary from grid point to * * point. * * * * The relationship between the percentile value, p, and the index, k, * * in the order statistics of count N is * * * * ( k - 1 ) / ( N - 1 ) = p (1) * * * * Rewriting this in terms of equally weighted order statistics * * (multiplying both sides by (N-1)/N) yields * * * * (k-1)*(1/N) = p - p*(1/N) (2) * * * * Since k can have a fractional value, the weights may vary, and the * * (1/N) subtracted on both sides of (2) must be the first weight value * * (w(1)), the problem is one of finding integer K and residual weight * * wr such that * * * * K * * wr + SUM w(i) = p ( 1 - w(1) ) (3) * * i=2 * * * * The value of wr is easily obtained by solving (3) after summing the * * weights up to the point in the order statistics where adding on one * * more weight exceeds the value of the R.H.S of (3). The value of wr * * establishes the position in the weight summation to which to * * interpolate the values of the order statistics, x, according to the * * following linear relationship: * * * * wr / [ W(K+1) - W(K) ] = [ x - x(K) ] / [ x(K+1) - x(K) ] (4) * * * * In (4), W(K) is the summation of the weights from i=2 to K. The * * percentile value is found by solving (4) for x. Since the denom- * * inator on the L.H.S of (4) is just w(K+1), the value of x is * * * * x = x(K) + [ wr / w(K+1) ] * [ x(K+1) - x(K) ] (5) * * * * * * de_prcntl ( uarg, stprm, iret ) * * * * Input and parameters: * * *uarg const char Function argument string * * * * Output parameters: * * *stprm char Substitution string * * *iret int Return code * * +3 = Percentile < 0 * * +1 = Percentile > 100 * * 0 = normal return * * -8 = cannot parse argument * * -9 = ensemble cannot computed * * -15 = Incorrect # of arguments * ** * * Log: * * T. Lee/SAIC 01/05 * * R. Tian/SAIC 1/06 Translated from Fortran * * T. Piper/SAIC 08/06 Added G_DIFF * * K. Brill/HPC 08/06 Fix to remove low bias; document eqtns * * m.gamazaychikov/SAIC 01/08 Add ability to use weights * ************************************************************************/ { char tname[13], pdum[13], time1[21], time2[21]; char **argu; int igo, igp, num, kxd, kyd, ksub1, ksub2, nina, narg, level1, level2, ivcord, zero, one, three, ii, jj, kk, ll, ier; int wmesg, nmesg, iswflg, istop, iwpntr; int nsw, numw; float *gigo, *gigp, *gnum, data, swpbuf, pntt, psum, smw, wr, *gnumw, *gwgt, d1; /*----------------------------------------------------------------------*/ *iret = 0; zero = 0; one = 1; three = 3; dg_ssub ( iret ); /* * Get a new grid number. */ dg_nxts ( &igo, iret ); if ( *iret != 0 ) return; /* * Initialize the output grid. */ dg_getg ( &igo, &gigo, &kxd, &kyd, &ksub1, &ksub2, iret ); for ( ii = ksub1 - 1; ii < ksub2; ii++ ) { gigo[ii] = RMISSD; } /* * Set the number of input arguments. There are two arguments * for DE_PRCNTL. */ for ( ii = 0; ii < MXARGS; ii++ ) { _ensdiag.allarg[ii][0] = '\0'; } nina = 3; argu = (char **)cmm_malloc2d ( 3, MXFLSZ+1, sizeof(char), &ier ); cst_clst ( (char *)uarg, '&', " ", nina, MXFLSZ, argu, &narg, &ier ); for ( ii = 0; ii < narg; ii++ ) { strcpy ( _ensdiag.allarg[ii], argu[ii] ); } /* * If weight grid is provided get new grid number * for sum-weight grid and initialize it */ if ( narg == 3 ) { dg_nxts ( &nsw, iret ); if ( *iret != 0 ) return; dg_getg ( &nsw, &gwgt, &kxd, &kyd, &ksub1, &ksub2, iret ); for ( ii = ksub1 - 1; ii < ksub2; ii++ ) { gwgt[ii] = 0.; } } cmm_free2d ( (void **) argu, &ier ); if ( narg < 2 ) { *iret = -15; return; } /* * Scan the allarg array. */ de_scan ( &narg, iret ); if ( *iret != 0 ) return; /* * Evaluate the static argument defined by the second entry in * uarg or allarg (2). */ dg_pfun ( _ensdiag.allarg[1], iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") ); *iret = -8; return; } dg_driv ( &one, iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, _ensdiag.allarg[1], &ier, strlen("DG"), strlen(_ensdiag.allarg[1]) ); *iret = -9; return; } /* * Retrieve the output grid from the stack. Check that the * output is a scalar. */ dg_tops ( tname, &igp, time1, time2, &level1, &level2, &ivcord, pdum, iret ); dg_getg ( &igp, &gigp, &kxd, &kyd, &ksub1, &ksub2, iret ); /* * Loop over number of members set by DE_SCAN. */ for ( ii = 0; ii < _ensdiag.nummbr; ii++ ) { de_mset ( &ii, iret ); dg_pfun ( _ensdiag.allarg[0], iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") ); *iret = -8; return; } dg_driv ( &one, iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, _ensdiag.allarg[0], &ier, strlen("DG"), strlen(_ensdiag.allarg[0]) ); *iret = -9; return; } /* * Retrieve the output grid from the stack and store the * grid number. */ dg_tops ( tname, &num, time1, time2, &level1, &level2, &ivcord, pdum, iret ); _ensdiag.iglist[ii] = num; /* * If the weight grid present store the starting index * of the weight grid. */ if ( narg == 3 ) { dg_pfun ( _ensdiag.allarg[2], iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") ); *iret = -8; return; } dg_driv ( &one, iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, _ensdiag.allarg[2], &ier, strlen("DG"), strlen(_ensdiag.allarg[2]) ); *iret = -9; return; } dg_tops ( tname, &numw, time1, time2, &level1, &level2, &ivcord, pdum, iret ); dg_getg ( &numw, &gnumw, &kxd, &kyd, &ksub1, &ksub2, iret ); _ensdiag.iwlist[ii] = numw; /* * the weight summing grid */ for ( jj = ksub1 - 1; jj < ksub2; jj++ ) { d1 = gnumw[jj]; if ( ERMISS ( d1 ) || ERMISS ( gwgt[jj] ) ) { gwgt[jj] = RMISSD; } else { gwgt[jj] += gnumw[jj]; } } } } wmesg = G_FALSE; nmesg = G_FALSE; for ( ll = ksub1 - 1; ll < ksub2; ll++ ) { for ( ii = 0; ii < _ensdiag.nummbr; ii++ ) { num = _ensdiag.iglist[ii]; dg_getg ( &num, &gnum, &kxd, &kyd, &ksub1, &ksub2, iret ); data = gnum[ll]; /* * Fill out the weight array and normalize by the sum of weights */ if ( narg == 3 ) { numw = _ensdiag.iwlist[ii]; dg_getg ( &numw, &gnumw, &kxd, &kyd, &ksub1, &ksub2, iret ); _ensdiag.ewtval[ii] = gnumw[ll] / gwgt[ll]; } if ( ! ERMISS ( data ) ) { _ensdiag.emvalu[ii] = data; _ensdiag.igpntr[ii] = ii; if ( ii == _ensdiag.nummbr - 1 ) { /* * Bubble sorting the grid values in emvalu with * emvalue (1) lowest and emvalu (nummbr) highest. */ iswflg = 1; istop = _ensdiag.nummbr - 1; while ( iswflg != 0 && istop >= 0 ) { iswflg = 0; for ( kk = 0; kk < istop; kk++ ) { if ( _ensdiag.emvalu[kk] > _ensdiag.emvalu[kk+1] ) { iswflg = 1; swpbuf = _ensdiag.emvalu[kk]; iwpntr = _ensdiag.igpntr[kk]; _ensdiag.emvalu[kk] = _ensdiag.emvalu[kk+1]; _ensdiag.igpntr[kk] = _ensdiag.igpntr[kk+1]; _ensdiag.emvalu[kk+1] = swpbuf; _ensdiag.igpntr[kk+1] = iwpntr; } } istop--; } /* * Set normalized target percentile. */ pntt = gigp[ll] / 100.0F; if ( pntt >= 1. ) { gigo[ll] = _ensdiag.emvalu[_ensdiag.nummbr-1]; if ( pntt > 1.0F && wmesg == G_FALSE ) { er_wmsg ( "DE", &one, " ", &ier, strlen("DE"), strlen(" ") ); wmesg = G_TRUE; } } else if ( pntt <= 0. ) { gigo[ll] = _ensdiag.emvalu[0]; if ( pntt < 0.0F && nmesg == G_FALSE ) { er_wmsg ( "DE", &three, " ", &ier, strlen("DE"), strlen(" ") ); nmesg = G_TRUE; } } else { jj = 0; psum = 0.0; if ( narg == 3 ) { pntt = pntt * ( 1.0F - _ensdiag.ewtval[_ensdiag.igpntr[0]] ); } else { pntt = pntt * ( 1.0F - _ensdiag.enswts[_ensdiag.igpntr[0]] ); } while (jj < _ensdiag.nummbr - 1 && psum < pntt ) { jj++; /* * The 1st weight ([0]) must be omitted from the * summation. */ if ( narg == 3 ) { psum += _ensdiag.ewtval[_ensdiag.igpntr[jj]]; } else { psum += _ensdiag.enswts[_ensdiag.igpntr[jj]]; } } /* * Compute the percentile value for the output grid. */ if ( G_DIFF(psum, pntt) ) { gigo[ll] = _ensdiag.emvalu[jj]; } else { if ( narg == 3 ) { smw = psum - _ensdiag.ewtval[_ensdiag.igpntr[jj]]; wr = pntt - smw; if ( G_DIFF (_ensdiag.ewtval[_ensdiag.igpntr[jj]], 0.0F) ) { gigo[ll] = RMISSD; } else { gigo[ll] = _ensdiag.emvalu[jj-1] + ( wr / _ensdiag.ewtval[_ensdiag.igpntr[jj]] ) * (_ensdiag.emvalu[jj]-_ensdiag.emvalu[jj-1]); } } else { smw = psum - _ensdiag.enswts[_ensdiag.igpntr[jj]]; wr = pntt - smw; if ( G_DIFF (_ensdiag.enswts[_ensdiag.igpntr[jj]], 0.0F) ) { gigo[ll] = RMISSD; } else { gigo[ll] = _ensdiag.emvalu[jj-1] + ( wr / _ensdiag.enswts[_ensdiag.igpntr[jj]] ) * (_ensdiag.emvalu[jj]-_ensdiag.emvalu[jj-1]); } } } } } } } } /* * Reset DGCMN.CMN and set internal grid identifier. */ de_rset ( iret ); dg_udig ( "EXX_", &igo, &zero, &_ensdiag.idgens, stprm, iret ); dg_esub ( &igo, &zero, &zero, &zero, &ier ); if ( ier != 0 ) *iret = ier; return; }
void de_mbr1 ( const int *k, const char *infl, char *outfl, int *iret ) /************************************************************************ * de_mbr1 * * * * This subroutine parses a GDFILE entry to find and handle ensemble * * specifications. It is called from DG_NFIL. The routine turns an * * ensemble entry into a single entry that DG_NFIL can handle. * * * * de_mbr1 ( k, infl, outfl, iret ) * * * * Input parameters: * * *k const int GDFILE entry position number * * *infl const char Input file entry * * * * Output parameters: * * *outfl char* Output file replaces INFL * * *iret int Return code * * 0 = normal return * * -2 = grid file or template not * * exist * * * * Log: * * T. Lee/SAIC 12/04 * * T. Lee/SAIC 06/05 Parsed weight value * * R. Tian/SAIC 12/05 Translated from Fortran * * m.gamazaychikov/SAIC 04/06 Added idtmch flag to CTB_DTGET CS * * T. Piper/SAIC 04/07 Modified for cfl_scnt CSC * * F. J. Yen/NCEP 4/08 Added bin mins & mstrct to CTB_DTGET CSC* * S. Jacobs/NCEP 12/11 Fixed check if there is no table entry * * returned by ctb_dtget * ***********************************************************************/ { int index, nfarr, ic, is, iff, ir, ii, ino, ihb, mnb, iha, mna, mstrct, idtmch, nfile, istar, last, len, ier; long lens; char lsv[MXFLSZ], newfil[MXFLSZ], filnam[MXFLSZ], cycle[DTTMSZ], path[MXFLSZ], tmplt[MXFLSZ], dum[DTTMSZ], rplc[DTTMSZ], membr[17]; char *opnptr, *clsptr, *starp, *ptr, **farr, *def = " "; struct dirent **dnlist=NULL; /*----------------------------------------------------------------------*/ *iret = 0; outfl[0] = '\0'; /* * Check if INFL contains a curly-bracket enclosed ensemble spec. * If not, the first entry is not an ensemble grid. Do nothing. */ opnptr = strchr ( infl, '{' ); if ( ! opnptr ) { strcpy ( outfl, infl ); return; } /* * Save the string between curly brackets to ensspc (k). Get * the first element of the file(s). */ cst_opcl ( infl, opnptr, &clsptr, &ier ); if ( ier != 0 ) { *iret = -2; return; } for ( index = 0, ptr = opnptr + 1; ptr < clsptr; index++, ptr++ ) { _ensdiag.ensspc[*k-1][index] = *ptr; } _ensdiag.ensspc[*k-1][index] = '\0'; clsptr = strchr ( _ensdiag.ensspc[*k-1], ',' ); if ( ! clsptr ) { strcpy ( lsv, _ensdiag.ensspc[*k-1] ); } else { for ( index = 0, ptr = _ensdiag.ensspc[*k-1]; ptr < clsptr; index++, ptr++ ) { lsv[index] = *ptr; } lsv[index] = '\0'; } /* * If file name is not an alias, do nothing. */ cfl_inqr ( lsv, NULL, &lens, newfil, &ier ); if ( ier == 0 ) { strcpy ( outfl, lsv ); return; } /* * Get the template. If the template does not end with "*", * do nothing. */ farr = (char **)cmm_malloc2d ( 2, MXFLSZ, sizeof(char), &ier ); if ( strchr ( lsv, '%' ) ) { cst_clst ( lsv, '%', def, 2, MXFLSZ, farr, &nfarr, &ier ); strcpy ( lsv, farr[1] ); } cst_clst ( lsv, '|', def, 2, MXFLSZ, farr, &nfarr, &ier ); strcpy ( filnam, farr[0] ); strcpy ( cycle, farr[1] ); cmm_free2d ( (void **)farr, &ier ); ctb_dtget ( filnam, path, tmplt, &ic, &is, &iff, &ir, &ii, &ino, &ihb, &mnb, &iha, &mna, &mstrct, &idtmch, &ier ); if ( ier != 0 ) { strcpy ( outfl, lsv ); return; } else { starp = strchr ( tmplt, '*' ); istar = (int)( starp - tmplt ); if ( ! starp ) { strcpy ( outfl, lsv ); return; } } /* * If the template contains an "*", then it is an ensemble with * multiple members. The last member is the one sought. */ if ( strcmp ( cycle, def ) != 0 ) { cti_stan ( cycle, "YYMMDD/HHNN", dum, &ier ); if ( strstr ( tmplt, "YYYYMMDD" ) ) { strcpy ( rplc, "YY" ); strncat ( rplc, dum, 6 ); rplc[8] = '\0'; cst_rpst ( tmplt, "YYYYMMDD", rplc, tmplt, &ier ); } else { strncpy ( rplc, dum, 6 ); rplc[6] = '\0'; cst_rpst ( tmplt, "YYMMDD", rplc, tmplt, &ier ); } strncpy ( rplc, &dum[7], 2 ); rplc[2] = '\0'; cst_rpst ( tmplt, "HH", rplc, tmplt, &ier ); } /* * Retrieve the last member of the ensemble alias. */ cfl_scnt ( path, tmplt, -1, &dnlist, &nfile, &ier ); if ( nfile == 0 ) { *iret = -2; er_wmsg ( "DE", iret, " ", &ier, strlen("DE"), strlen(" ") ); return; } strcpy ( newfil, dnlist[0]->d_name ); for (ii=0;ii<nfile;ii++){ free(dnlist[ii]); } if ( dnlist != NULL ) free(dnlist); /* * Replace "*" in the template with member names. Note * that "*" may be embedded in the template. */ if ( *(starp+1) == '\0' ) { last = G_TRUE; } else { last = G_FALSE; } if ( last == G_TRUE ) { strcpy ( membr, &newfil[istar] ); } else { len = strlen ( newfil ) - strlen ( tmplt ) + 1; cst_ncpy ( membr, &newfil[istar], len, &ier ); } /* * Recombine the alias and last member with the cycle. */ strcpy ( outfl, filnam ); strcat ( outfl, ":" ); strcat ( outfl, membr ); if ( strcmp ( cycle, def ) != 0 ) { strcat ( outfl, "|" ); strcat ( outfl, cycle ); } return; }
void db_rdtr ( char *queryType, char *source, char *part, char *dattim, char *stid, char *dataUri, int *icnt, float *rdata, int *nword, int *iret ) /************************************************************************ * * * db_rdtr * * * * This function returns array of data values from the AWIPS II DB * * given certain data criteria. * * * * void db_rdtr ( char *queryType, char *source, char *part, * * char *dattim, char *stid, char *dataUri, int *icnt, * * float *rdata, int *nword, int *iret ) * * * * Input parameters: * * queryType char Type of query * * source char Source of data * * part char Part name * * dattim char The data time * * stid char Station ID * * dataUri char Data URI * * icnt int Number of stations (obsolete) * * * * Output parameters: * * rdata float Array of data values * * nword float Length of rdata array * * iret int Return code: * * 0 - normal return * * -1 - unable to get dataURI * * * ** * * Log: * * m.gamazaychikov/CWS 04/11 Created * ************************************************************************/ { int numberPayloadParts = 2; int payloadPartLength = 50; int bufferSize = 200000; char xsltFile[LLSCRN] = "response.xlt"; char xsltDir[LLSCRN] = "$NAWIPS/gempak/tables/xslt"; int ier, nbytes, ier1, nwrd, istmax, jj; long flen; char queryText[320], queryResult[bufferSize+1], xsltfile[FILE_FULLSZ]; char errStr[100], payload[100]; unsigned char* bigStr; char **starr; /*---------------------------------------------------------------------*/ /* * Initialization */ *iret = 0; queryText[0] = '\0'; queryResult[0] = '\0'; /* * Populate the query strings */ if (strcmp ( queryType, "gridDat" ) == 0 ) { if ( strcmp ( source, "GRID") == 0 ) { strcpy (eSrc, source); sprintf (eDistnctField, "%s", dataUri); sprintf (gDattim, "%s", dattim); eCount = 1; sprintf (eLibClass, "%s", "GempakGridLinkRequest"); } else { ier = -9; sprintf (errStr, "%s+", queryType); strcat (errStr, source); er_wmsg ( "DB", &ier, errStr, &ier1, 2, strlen(errStr) ); *iret = -1; return; } } else { ier = -8; er_wmsg ( "DB", &ier, queryType, &ier1, 2, strlen(queryType) ); *iret = -1; return; } /* * Get the query text */ db_getQueryText ( queryType, queryText, &ier); if ( ier !=0 ) { ier = -3; er_wmsg ( "DB", &ier, NULL, &ier1, 2, 0 ); *iret = -1; return; } /* * Connect to database and get the query result */ db_runQuery ( queryText, queryResult, &ier); if ( ier !=0 ) { ier = -4; er_wmsg ( "DB", &ier, NULL, &ier1, 2, 0 ); *iret = -1; return; } /* * Transform XML string to a string containing the name of the file * stored on the server side */ cfl_inqr(xsltFile, xsltDir, &flen, xsltfile, &ier); if ( ier !=0 ) { /* * XSLT file not found -> returning */ ier = -5; er_wmsg ( "DB", &ier, xsltFile, &ier1, 2, strlen(xsltFile) ); *iret = -1; return; } nbytes=xml_transform( queryResult, strlen(queryResult), xsltfile, &bigStr, &ier ); if ( ier !=0 || nbytes==0) { /* * XML Transform run unsuccessfully -> returning */ ier = -6; er_wmsg ( "DB", &ier, NULL, &ier1, 2, 0 ); G_FREE( bigStr, unsigned char ); *iret = -1; return; } sprintf( payload, "%s", bigStr ); G_FREE( bigStr, unsigned char ); /* * Break the payload string into parts containing the dbHost and fileName */ starr = (char **)malloc((size_t)numberPayloadParts * sizeof(char *)); for( jj=0; jj < numberPayloadParts; jj++ ) starr[jj] = (char *)malloc( payloadPartLength * sizeof(char)); cst_clst (payload, '|', " ", numberPayloadParts, payloadPartLength, starr, &istmax, &ier); if ( ier !=0 || istmax != 2 ) { ier = -13; er_wmsg ( "DB", &ier, source, &ier1, 2, strlen(source) ); *iret = -1; for ( jj = 0; jj < numberPayloadParts; jj++ ) free( starr[jj] ); if( starr ) free( (char **)starr ); return; } /* * Get the data from the server side */ db_getRData(starr[0], starr[1], rdata, &nwrd, &ier); for ( jj = 0; jj < numberPayloadParts; jj++ ) free( starr[jj] ); if( starr ) free( (char **)starr ); *nword = nwrd; if ( ier !=0 ) { if ( ier == -1 ) { ier = -10; er_wmsg ( "DB", &ier, source, &ier1, 2, strlen(source) ); *iret = -1; return; } if ( ier == -2 ) { ier = -15; er_wmsg ( "DB", &ier, NULL, &ier1, 2, 0 ); *iret = -1; return; } } return; }
void de_swsprd ( const char *uarg, char *stprm, int *iret ) /************************************************************************ * de_swsprd * * * * This subroutine computes the weighted ensemble spread of its scalar * * argument. * * * * de_swsprd ( uarg, stprm, iret ) * * * * Input and parameters: * * *uarg const char Function argument string * * * * Output parameters: * * *stprm char Substitution string * * *iret int Return code * * 0 = normal return * * -8 = cannot parse argument * * -9 = ensemble cannot computed * ** * * Log: * * m.gamazaychikov/SAIC 01/08 From de_ssprd * * m.gamazaychikov/SAIC 01/08 Fixed the calculation problem * * S. Jacobs/NCEP 8/09 Use double arrays internally * * K. Brill/HPC 11/10 Set any negative sqrt argument to zero * ************************************************************************/ { char tname[13], pdum[13], time1[21], time2[21]; char **argu; int ns, ns2, num, kxd, kyd, ksub1, ksub2, level1, level2, ivcord, nina, one, zero, i, j, ier, narg, numw, nsw; float *gns, *gnum, *gwgt, *gnumw; double *dgns, *dgns2, d1, d2, d3, d4; /*----------------------------------------------------------------------*/ *iret = 0; one = 1; zero = 0; dg_ssub ( iret ); /* * Get new grid numbers. */ dg_nxts ( &ns, iret ); if ( *iret != 0 ) return; dg_nxts ( &ns2, iret ); if ( *iret != 0 ) return; /* * Initialize the output grid. */ dg_getg ( &ns, &gns, &kxd, &kyd, &ksub1, &ksub2, iret ); G_MALLOC(dgns, double, kxd*kyd, "DE_SWSPRD"); G_MALLOC(dgns2, double, kxd*kyd, "DE_SWSPRD"); for ( i = ksub1 - 1; i < ksub2; i++ ) { gns[i] = 0.; dgns[i] = 0.; dgns2[i] = 0.; } /* * Set the number of input arguments. There could be two arguments. */ for ( i = 0; i < MXARGS; i++ ) { _ensdiag.allarg[i][0] = '\0'; } nina = 2; argu = (char **)cmm_malloc2d ( 2, LLMXLN, sizeof(char), &ier ); cst_clst ( (char *)uarg, '&', " ", nina, LLMXLN, argu, &narg, &ier ); for ( i = 0; i < narg; i++ ) { strcpy ( _ensdiag.allarg[i], argu[i] ); if ( i > 0 && strcmp(argu[i], " ") == 0 ) { cst_rlch ( RMISSD, 1, _ensdiag.allarg[i], &ier ); } } cmm_free2d ( (void **) argu, &ier ); if ( narg < 1 ) { *iret = -15; return; } else if ( narg == 1 ) { cst_rlch ( RMISSD, 1, _ensdiag.allarg[1], &ier ); } else if ( narg == 2 ) { dg_nxts ( &nsw, iret ); if ( *iret != 0 ) return; dg_getg ( &nsw, &gwgt, &kxd, &kyd, &ksub1, &ksub2, iret ); for ( i = ksub1 - 1; i < ksub2; i++ ) { gwgt[i] = 0.; } } /* * Scan the allarg array. */ de_scan ( &narg, iret ); if ( *iret != 0 ) return; /* * Loop over number of members set by DE_SCAN. */ for ( i = 0; i < _ensdiag.nummbr; i++ ) { if ( narg == 2 ) { de_mset ( &i, iret ); /* * Compute weight grid and retrieve it from the stack. */ dg_pfun ( _ensdiag.allarg[1], iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") ); *iret = -8; return; } dg_driv ( &one, iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, _ensdiag.allarg[1], &ier, strlen("DG"), strlen(_ensdiag.allarg[1]) ); *iret = -9; return; } dg_tops ( tname, &numw, time1, time2, &level1, &level2, &ivcord, pdum, iret ); dg_getg ( &numw, &gnumw, &kxd, &kyd, &ksub1, &ksub2, iret ); /* * Compute field grid and retrieve it from the stack. */ dg_pfun ( _ensdiag.allarg[0], iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") ); *iret = -8; return; } dg_driv( &one, iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, _ensdiag.allarg[0], &ier, strlen("DG"), strlen(_ensdiag.allarg[0]) ); *iret = -9; return; } /* * Retrieve the output grid from the stack. Check that the * output is a scalar. */ dg_tops ( tname, &num, time1, time2, &level1, &level2, &ivcord, pdum, iret ); dg_getg ( &num, &gnum, &kxd, &kyd, &ksub1, &ksub2, iret ); for ( j = ksub1 - 1; j < ksub2; j++ ) { d1 = gnum[j]; d2 = dgns[j]; d3 = dgns2[j]; d4 = gnumw[j]; if ( ERMISS ( d1 ) || ERMISS ( d2 ) || ERMISS ( d3 ) || ERMISS ( d4 ) ) { dgns[j] = RMISSD; dgns2[j] = RMISSD; gwgt[j] = RMISSD; } else { dgns[j] += d1 * d4; dgns2[j] += d1 * d1 * d4; gwgt[j] += d4; } } dg_frig ( &numw, &ier ); dg_frig ( &num, &ier ); } else if ( narg == 1 ) { de_mset ( &i, iret ); dg_pfun ( _ensdiag.allarg[0], iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") ); *iret = -8; return; } dg_driv( &one, iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, _ensdiag.allarg[0], &ier, strlen("DG"), strlen(_ensdiag.allarg[0]) ); *iret = -9; return; } /* * Retrieve the output grid from the stack. Check that the * output is a scalar. */ dg_tops ( tname, &num, time1, time2, &level1, &level2, &ivcord, pdum, iret ); dg_getg ( &num, &gnum, &kxd, &kyd, &ksub1, &ksub2, iret ); for ( j = ksub1 - 1; j < ksub2; j++ ) { d1 = gnum[j]; d2 = dgns[j]; d3 = dgns2[j]; if ( ERMISS ( d1 ) || ERMISS ( d2 ) || ERMISS ( d3 ) ) { dgns[j] = RMISSD; dgns2[j] = RMISSD;; } else { dgns[j] += d1 * _ensdiag.enswts[i]; dgns2[j] += d1 * d1 * _ensdiag.enswts[i]; } } dg_frig ( &num, &ier ); } } /* * Compute Variance. */ for ( i = ksub1 - 1; i < ksub2; i++ ) { d2 = dgns[i]; d3 = dgns2[i]; if ( ERMISS ( d2 ) || ERMISS ( d3 ) ) { dgns[i] = RMISSD; } else { if ( narg == 2) { d1 = gwgt[i]; if ( ERMISS ( d1 ) ) { dgns[i] = RMISSD; } else { dgns[i] = dgns[i]/gwgt[i]; dgns[i] = dgns2[i]/gwgt[i] - dgns[i] * dgns[i]; } } else if ( narg == 1 ) { dgns[i] = dgns2[i] - dgns[i] * dgns[i]; } } } /* * Compute spread (standard deviation). */ for ( i = ksub1 - 1; i < ksub2; i++ ) { d2 = dgns[i]; if ( ERMISS ( d2 ) ) { dgns[i] = RMISSD; } else { if ( dgns[i] < 0.0 ) { dgns[i] = 0.0; } dgns[i] = sqrt ( dgns[i] ); } } /* * Assign the result to the output array and free the internal arrays. */ for ( i = ksub1 - 1; i < ksub2; i++ ) { gns[i] = (float)dgns[i]; } G_FREE(dgns, double); G_FREE(dgns2, double); /* * Reset DGCMN.CMN and set internal grid identifier. */ de_rset ( iret ); dg_udig ( "EXX_", &ns, &zero, &_ensdiag.idgens, stprm, iret ); dg_esub ( &ns, &zero, &zero, &zero, &ier ); if ( ier != 0 ) *iret = ier; return; }
void gdmakewmo ( GDG2_input *input, GDG2_gemgrid *gemgrid, char *chdr, int *iret ) /************************************************************************ * gdmakewmo * * * * This routine generates a WMO Header from user input parameter WMOHDR * * and gempak grid date/time info, if necessary. * * * * Usage: * * gdmakewmo( input, gemgrid, chdr, iret ) * * * * Input Arguments: * * *input GDG2_input input structure for GDGRIB2 * * *gemgrid GDG2_gemgrid grid and Gempak info * * * * Output Arguments: * * *chdr char WMO Header * * *iret int Error return code. * * 0 = Normal * ** * * Log: * * S. Gilbert/NCEP 8/05 Orig * * S. Gilbert/NCEP 8/05 Changed string manipulations * * S. Jacobs/NCEP 2/11 Replaced strncpy with cst_ncpy * ***********************************************************************/ { int ret, num, j, ier2; int numparts = 3; char cparts[numparts][LLMXLN], *plist[numparts], *cdef="\0"; /* * Separate WMO Header parts from user input */ for ( j=0; j<numparts; j++) plist[j] = cparts[j]; cst_clst( input->wmohdr, '/', cdef, numparts, LLMXLN, plist, &num, &ret); /* * Set first six characters of WMO Header */ if ( strlen( plist[0] ) == (size_t)6 ) { cst_ncpy( chdr, plist[0], 6, &ret ); } else { *iret = -9; strcpy( chdr, cdef ); return; } /* * Insert space after first six characters of WMO Header */ strcat( chdr, " " ); /* * Set originating center identifier. */ if ( strlen( plist[1] ) == (size_t)4 ) { strcat( chdr, plist[1] ); } else { strcat( chdr, "KWBC" ); } /* * Insert space after originating center identifier. */ strcat( chdr, " " ); /* * Set Date/Time group */ if ( strlen( plist[2] ) == (size_t)6 ) { strcat( chdr, plist[2] ); } else { cst_ncpy ( chdr+12, gemgrid->ctime[0]+4, 2, &ier2 ); cst_ncpy ( chdr+14, gemgrid->ctime[0]+7, 4, &ier2 ); } /* * Add CR-CR-LF */ chdr[18] = CHCR; chdr[19] = CHCR; chdr[20] = CHLF; chdr[21] = CHNULL; return; }
void rsdatt ( char *pname, float *xsz, float *ysz, int *ileft, int *ibot, int *iright, int *itop, int *numclr, int *iret ) /************************************************************************ * rsdatt * * * * This subroutine defines the device attributes. * * * * rsdatt ( pname, xsz, ysz, ileft, ibot, iright, itop, numclr, iret ) * * * * Input parameters: * * *pname char Name of file as output * * *xsz float X size in inches or pixels * * *ysz float Y size in inches or pixels * * * * Output parameters: * * *ileft int Left device coordinate * * *ibot int Bottom device coordinate * * *iright int Right device coordinate * * *itop int Top device coordinate * * *numclr int Max number of colors for device * * *iret int Return code * ** * * Log: * * E. Wehner/EAi 3/96 Adopted from hsdatt.f * * S. Jacobs/NCEP 4/96 Added ileft,ibot,iright,itop,nncolr * * to calling sequence; added calculation * * of paper and device size * * E. Wehner/EAi 1/97 Use wheel to index fax products * * E. Wehner/Eai 3/97 Set x and ysize based on rotation * * S. Jacobs/NCEP 7/97 Rewrote and reorganized code * * S. Jacobs/NCEP 7/97 Cleaned up header and global variables * * S. Jacobs/NCEP 7/97 Added indent value from product table * * S. Jacobs/NCEP 7/97 Added check for 180 and 270 rotation * * S. Jacobs/NCEP 8/97 Added reserved value from prod table * * G. Krueger/EAI 10/97 CST_xLST: Removed RSPTB; Add str limit * * S. Jacobs/NCEP 5/98 Changed to allow for multiple subsets * * T. Piper/SAIC 02/04 Removed lenf parameter * ***********************************************************************/ { int ier, num, ii, fxfg; char tmpfil[133], **aryptr, twhl[5], tsub[5]; /*---------------------------------------------------------------------*/ *iret = G_NORMAL; if ( strchr ( pname, ';' ) != NULL ) { /* * If the product/file name contains a semi-colon, then parse * the name for the "wheel" and "subset" values. The wheel and * subset are then used to get the product information from the * FAX product table. * * The parsing searches for either a semi-colon or a space to * terminate each string. */ aryptr = (char **) malloc ( 2 * sizeof(char *) ); for ( ii = 0; ii < 2; ii++ ) { aryptr[ii] = (char *) malloc ( 80 * sizeof(char) ); } cst_clst ( pname, ';', " ", 2, 80, aryptr, &num, &ier ); strcpy ( twhl, aryptr[0] ); strcpy ( tsub, aryptr[1] ); for ( ii = 0; ii < 2; ii++ ) { free ( aryptr[ii] ); } free ( (char **) aryptr ); fxfg = G_TRUE; } else { /* * This is not a FAX product. However, still create a raster * image of the product. */ fxfg = G_FALSE; } /* * Save the file name. */ if ( fxfg ) { sprintf ( tmpfil, "%s.ras", twhl ); } else { strcpy ( tmpfil, pname ); } /* * If the passed in filename is different from the global filename, * change the name after closing the old file. */ if ( strcmp ( filnam, tmpfil ) != 0 ) { rclosp ( &ier ); if ( fxfg ) { /* * Find the requested product in the FAX product * definition table. */ strcpy ( wheel, twhl ); ctb_prod ( wheel, tsub, MAXSUB, &nsub, subset, descr, kbit, klin, krot, kind, krsv, &ier ); if ( ier != G_NORMAL ) { *iret = G_NOPROD; return; } faxflg = G_TRUE; } else { /* * Set the dimensions of the raster only output. */ if ( ERMISS ( *xsz ) || ERMISS ( *ysz ) ) { kbit[0] = 800; klin[0] = 800; } else { if ( *ysz > *xsz ) { kbit[0] = (int) *ysz; klin[0] = (int) *xsz; krot[0] = 90; } else { kbit[0] = (int) *xsz; klin[0] = (int) *ysz; krot[0] = 0; } } nsub = 1; faxflg = G_FALSE; } /* * Make sure that there are enough bytes per raster line. If the * number of bits is not divisible by 8 then add enough bits to * make the number divisible by 8. */ if ( kbit[0] % 8 != 0 ) { kbit[0] = kbit[0] + (8 - kbit[0]%8); } /* * If this is a FAX product and the number of bits per line is * greater than 1728, set the number to 1728. */ if ( kbit[0] > 1728 && faxflg ) { kbit[0] = 1728; } /* * Compute the number of bytes for this raster image. * If the size is larger than the maximum, return with an error. */ msize = (kbit[0]/8) * klin[0]; if ( msize > MAXSIZ ) { *iret = G_NIDSIZ; return; } /* * Clear the entire image. */ rclear ( &ier ); /* * Set the device bounds. */ if ( ( krot[0] == 0 ) || ( krot[0] == 180 ) ) { *ileft = 1; *ibot = klin[0]; *iright = kbit[0]; *itop = 1; } else if ( ( krot[0] == 90 ) || ( krot[0] == 270 ) ) { *ileft = 1; *ibot = kbit[0]; *iright = klin[0]; *itop = 1; } /* * Set file to initially closed. */ opnfil = G_FALSE; /* * If the new file name is not empty, set the current file name. */ if ( tmpfil[0] != CHNULL ) { strcpy ( filnam, tmpfil ); *iret = G_NEWWIN; } /* * Set the number of colors to be returned to DEVCHR. * * nncolr (numclr) = number of device colors * ( A maximum of MXCLNM = 32 may be initialized. ) */ nncolr = 1; *numclr = nncolr; } }
void de_cval ( const char *uarg, char *stprm, int *iret ) /************************************************************************ * de_cval * * * * This function determines the value of the function defined by PARM * * for which the probability is PRB that the observed value is less * * than or equal to that computed value based on an idealized ensemble * * forecast. * * * * GFUNC syntax: ENS_CVAL ( PARM & PRB & LWRBND & UPRBND ) * * * * de_cval ( uarg, stprm, iret ) * * * * Input and parameters: * * *uarg const char Function argument string * * * * Output parameters: * * *stprm char Substitution string * * *iret int Return code * * +3 = Percentile < 0 * * +1 = Percentile > 100 * * 0 = normal return * * -8 = cannot parse argument * * -9 = ensemble cannot computed * * -15 = Incorrect # of arguments * ** * * Log: * * M. Li/SAIC 10/06 * * M. Li/SAIC 10/06 Added a check for missing value * * K. Brill/HPC 20080131 Add intrinsic weight computations; fix * * eliminate duplicates coding error * * K. Brill/HPC 20101118 Check for single value order stats case * ************************************************************************/ { char tname[13], pdum[13], time1[21], time2[21]; char **argu; int igo, igp, num, kxd, kyd, ksub1, ksub2, nina, narg, level1, level2, ivcord, zero, one, ii, jj, kk, ll, mm, nn, ier; int iswflg, istop; float *gigo, *gigp, *gnum, data, swpbuf, psum; float *gilwr, *giupr, *tmpwt, wtbuf, tol; float *zwts, *zfreq; float zsum; float vn, qlt, qrt, fta, cta, aa, bb, cc; Boolean ibreak; /*----------------------------------------------------------------------*/ *iret = 0; zero = 0; one = 1; dg_ssub ( iret ); /* * Get a new grid number. */ dg_nxts ( &igo, iret ); if ( *iret != 0 ) return; /* * Initialize the output grid. */ dg_getg ( &igo, &gigo, &kxd, &kyd, &ksub1, &ksub2, iret ); for ( ii = ksub1 - 1; ii < ksub2; ii++ ) { gigo[ii] = RMISSD; } /* * Set the number of input arguments. There are up to four arguments * for DE_CVAL. */ for ( ii = 0; ii < MXARGS; ii++ ) { _ensdiag.allarg[ii][0] = '\0'; } nina = 4; argu = (char **)cmm_malloc2d ( 4, MXFLSZ+1, sizeof(char), &ier ); cst_clst ( (char *)uarg, '&', " ", nina, MXFLSZ, argu, &narg, &ier ); for ( ii = 0; ii < narg; ii++ ) { strcpy ( _ensdiag.allarg[ii], argu[ii] ); if ( ii > 0 && strcmp(argu[ii], " ") == 0 ) { cst_rlch ( RMISSD, 1, _ensdiag.allarg[ii], &ier ); } } if ( narg == 2 ) { cst_rlch ( RMISSD, 1, _ensdiag.allarg[2], &ier ); cst_rlch ( RMISSD, 1, _ensdiag.allarg[3], &ier ); } if ( narg == 3 ) { cst_rlch ( RMISSD, 1, _ensdiag.allarg[3], &ier ); } cmm_free2d ( (void **) argu, &ier ); if ( narg < 2 ) { *iret = -15; return; } /* * Scan the allarg array. */ de_scan ( &nina, iret ); if ( *iret != 0 ) return; /* * Evaluate the static arguments. */ for ( ii = 2; ii < nina; ii++ ) { dg_pfun ( _ensdiag.allarg[ii], iret ); dg_driv ( &one, iret ); dg_tops ( tname, &igp, time1, time2, &level1, &level2, &ivcord, pdum, iret ); if ( ii == 2 ) { dg_getg ( &igp, &gilwr, &kxd, &kyd, &ksub1, &ksub2, iret ); } else { dg_getg ( &igp, &giupr, &kxd, &kyd, &ksub1, &ksub2, iret ); } } dg_pfun ( _ensdiag.allarg[1], iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") ); *iret = -8; return; } dg_driv ( &one, iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, _ensdiag.allarg[1], &ier, strlen("DG"), strlen(_ensdiag.allarg[1]) ); *iret = -9; return; } /* * Retrieve the output grid from the stack. Check that the * output is a scalar. */ dg_tops ( tname, &igp, time1, time2, &level1, &level2, &ivcord, pdum, iret ); dg_getg ( &igp, &gigp, &kxd, &kyd, &ksub1, &ksub2, iret ); /* * Loop over number of members set by DE_SCAN. */ for ( ii = 0; ii < _ensdiag.nummbr; ii++ ) { de_mset ( &ii, iret ); dg_pfun ( _ensdiag.allarg[0], iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") ); *iret = -8; return; } dg_driv ( &one, iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, _ensdiag.allarg[0], &ier, strlen("DG"), strlen(_ensdiag.allarg[0]) ); *iret = -9; return; } /* * Retrieve the output grid from the stack and store the * grid number. */ dg_tops ( tname, &num, time1, time2, &level1, &level2, &ivcord, pdum, iret ); _ensdiag.iglist[ii] = num; } /* * Get memory for intrinsic weights (zwts), intrinsic weight * frequency (zfreq), and temporary weights. */ G_MALLOC ( zwts, float, _ensdiag.nummbr+1, "x" ); G_MALLOC ( zfreq, float, _ensdiag.nummbr+1, "x" ); G_MALLOC ( tmpwt, float, _ensdiag.nummbr+2, "x" ); for ( ll = ksub1 - 1; ll < ksub2; ll++ ) { if ( ERMISS(gigp[ll]) ) continue; if ( gigp[ll] < 0.0F || gigp[ll] > 1.0F ) continue; for ( ii = 0; ii < _ensdiag.nummbr; ii++ ) { ibreak = False; num = _ensdiag.iglist[ii]; dg_getg ( &num, &gnum, &kxd, &kyd, &ksub1, &ksub2, iret ); data = gnum[ll]; if ( ! ERMISS ( data ) ) { _ensdiag.emvalu[ii+1] = data; tmpwt[ii+1] = _ensdiag.enswts[ii]; if ( ii == _ensdiag.nummbr - 1 ) { /* * Bubble sorting the grid values in emvalu with * emvalue (1) lowest and emvalu (nummbr) highest. */ iswflg = 1; istop = _ensdiag.nummbr; while ( iswflg != 0 && istop > 0 ) { iswflg = 0; for ( kk = 1; kk < istop; kk++ ) { if ( _ensdiag.emvalu[kk] > _ensdiag.emvalu[kk+1] ) { iswflg = 1; swpbuf = _ensdiag.emvalu[kk]; wtbuf = tmpwt[kk]; _ensdiag.emvalu[kk] = _ensdiag.emvalu[kk+1]; tmpwt[kk] = tmpwt[kk+1]; _ensdiag.emvalu[kk+1] = swpbuf; tmpwt[kk+1] = wtbuf; } } istop--; } /* * Check for identical values and compute intrinsic weight * frequency (zfreq). */ mm = _ensdiag.nummbr; nn = mm; /* * Initialize intrinsic weight frequency array. */ for (kk = 1; kk <= nn; kk++){ zfreq[kk] = 1.0F; } tol = 0.001F * (_ensdiag.emvalu[mm]-_ensdiag.emvalu[1]) / mm; for (kk = 1; kk < mm; kk++) { if ( G_ABS(_ensdiag.emvalu[kk] - _ensdiag.emvalu[kk+1]) <= tol ) { tmpwt[kk] += tmpwt[kk+1]; zfreq[kk] = zfreq[kk] + 1.0F; mm--; for (jj = kk+1; jj <= mm; jj++) { _ensdiag.emvalu[jj] = _ensdiag.emvalu[jj+1]; tmpwt[jj] = tmpwt[jj+1]; } /* This algorithm was originally coded incorrectly. The value * of kk must also be held back to correctly eliminate three * or more identical values. */ kk--; } } /* * Fabricate order statistics if it has collapsed to a single value. */ if ( mm == 1 ) { if ( G_DIFF(_ensdiag.emvalu[1], 0.0F) ) { _ensdiag.emvalu[1] = -0.00001F; _ensdiag.emvalu[2] = 0.00001F; } else { _ensdiag.emvalu[2] = _ensdiag.emvalu[1] + 0.00001F * G_ABS(_ensdiag.emvalu[1]); _ensdiag.emvalu[1] -= 0.00001F * G_ABS(_ensdiag.emvalu[1]); } tmpwt[1] = 0.5F; tmpwt[2] = 0.5F; mm = 2; zfreq[1] = 1.0F; zfreq[2] = 1.0F; } /* *Compute and sum intrinsic weights. */ zwts[1] = zfreq[1] / ( _ensdiag.emvalu[2] - _ensdiag.emvalu[1] ); zsum = zwts[1]; for (kk=2; kk < mm; kk++){ zwts[kk] = ( zfreq[kk] * 2.0F ) / ( _ensdiag.emvalu[kk+1] - _ensdiag.emvalu[kk-1] ); zsum = zsum + zwts[kk]; } zwts[mm] = zfreq[mm] / ( _ensdiag.emvalu[mm] - _ensdiag.emvalu[mm-1] ); zsum = zsum + zwts[mm]; /* * Scale external weights by normalized intrinsic weights and * normalize. */ psum = 0.0F; for (kk=1; kk <= mm; kk++ ){ tmpwt[kk] = ( zwts[kk] / zsum ) * tmpwt[kk]; psum = psum + tmpwt[kk]; } for (kk=1; kk <= mm; kk++ ){ tmpwt[kk] = tmpwt[kk] / psum; } } /*End "if" for all members ready check.*/ } else { ibreak = True; break; } /*End "if" for check for non-missing value.*/ } /*End "for" loop over members.*/ if ( ibreak ) continue; /* * Compute Qun, the area; Vn, the normalized value; * w(), normalized weight; and qlt, qrt. */ vn = 0.0F; for ( kk = 2; kk <= mm; kk++ ) { vn += 0.5 * (tmpwt[kk] + tmpwt[kk-1]) * (_ensdiag.emvalu[kk] - _ensdiag.emvalu[kk-1]); } /* * If the distribution is a Dirac spike over a single value, then set the result to * that single value. */ if ( G_DIFF ( vn, 0.0 ) ) { gigo[ll] = _ensdiag.emvalu[1]; continue; } vn = vn / (1.0F - 2.0F / (nn+1)); for ( kk = 1; kk <= mm; kk++ ) { tmpwt[kk] = tmpwt[kk] / vn; } qlt = _ensdiag.emvalu[1] - 2.0F / (tmpwt[1] * (nn + 1)); qrt = _ensdiag.emvalu[mm] + 2.0F / (tmpwt[mm] * (nn + 1)); tmpwt[0] = 0.0F; tmpwt[mm+1] = 0.0F; _ensdiag.emvalu[0] = qlt; _ensdiag.emvalu[mm+1] = qrt; psum = 0.0F; for ( kk = 1; kk <= mm + 1; kk++ ) { /* * Compute CTA. */ cta = 0.5F * (tmpwt[kk] + tmpwt[kk-1]) * (_ensdiag.emvalu[kk] - _ensdiag.emvalu[kk-1]); psum += cta; if ( kk == mm + 1 ) psum = 1.0F; /* * If psum = PRB, assign q[i] to output grid and move on to next grid point. * (This was coded incorrectly and fixed on 20080205 -KB.) */ if ( G_DIFF ( gigp[ll], psum ) ) { gigo[ll] = _ensdiag.emvalu[kk]; break; } /* * If psum > PRB. Solve the quadratic equation. */ if ( psum > gigp[ll] ) { psum -= cta; fta = gigp[ll] - psum; aa = (tmpwt[kk] - tmpwt[kk-1]) / (_ensdiag.emvalu[kk] - _ensdiag.emvalu[kk-1]); bb = 2.0F * tmpwt[kk-1]; cc = 2.0F * fta; if ( G_DIFF ( aa, 0.0F ) ) { gigo[ll] = _ensdiag.emvalu[kk-1] + cc / bb; } else { gigo[ll] = _ensdiag.emvalu[kk-1] + (sqrt(bb * bb + 4 * aa * cc) - bb) / (2 * aa); } if ( ! ERMISS(gilwr[ll]) && gigo[ll] < gilwr[ll] ) gigo[ll] = gilwr[ll]; if ( ! ERMISS(giupr[ll]) && gigo[ll] > giupr[ll] ) gigo[ll] = giupr[ll]; break; } } } G_FREE (tmpwt, float); G_FREE (zfreq, float); G_FREE (zwts, float); /* * Reset DGCMN.CMN and set internal grid identifier. */ de_rset ( iret ); dg_udig ( "EXX_", &igo, &zero, &_ensdiag.idgens, stprm, iret ); dg_esub ( &igo, &zero, &zero, &zero, &ier ); if ( ier != 0 ) *iret = ier; return; }
void cst_flst ( char *str, char sep, char *defstr, int nexp, int maxchr, char **namptr, int *num, int *iret ) /************************************************************************ * cst_flst * * * * This subroutine breaks a string containing a list of file names into * * array of file names. The separator for the strings is input as SEP. * * If the seperator is a blank, multiple blanks will be treated as one. * * If null strings are encountered or fewer than NEXP strings are found * * in the string, the appropriate NAMPTR locations are set to DEFSTR. * * * * If the first file name has two "\"s in it, the subsequent file names * * are used to replace the text delineated by the "\"s in order to * * generate new file names. * * * * cst_flst ( str, sep, defstr, nexp, maxchr, namptr, num, iret ) * * * * Input parameters: * * *str char Input string * * sep char Separator * * *defstr char Default string * * nexp int Number of expected values * * maxchr int Maximum characters in strings * * * * Output parameters: * * **namptr char Pointer to file names * * *num int Number of names returned * * *iret int Return code * * 2 = string too long * * 1 = more than nexpv values * * 0 = normal * * -1 = invalid nexp * ** * * Log: * * L. Williams/EAI 4/96 * * S. Jacobs/NCEP 8/96 Updated header format * * G. Krueger/EAI 10/97 Removed MALLOC, RSPTB; Add str limit * ***********************************************************************/ { char *ptr, *ptr1, *ptr2; int count; int i, len1, len2, leni; /*---------------------------------------------------------------------*/ *iret = 0; *num = 0; /* * check the number of expected values. */ if( nexp <= 0 ) { namptr = NULL; *iret = -1; return; } cst_clst( str, sep, defstr, nexp, maxchr, namptr, num, iret ); if ( *iret != 0 ) return; if( *num == 0 ) return; ptr = namptr[0]; /* * check if the first file name has two "\"s */ count=0; while( *ptr ) { if( *ptr == CHBKSL ) ++count; ++ptr; } /* * if two "\"s were found process the new file names */ if( count == 2 ) { /* * identify first part of file name */ ptr1 = strchr( namptr[0], CHBKSL ) - 1; len1 = ptr1 - namptr[0] + 1; /* * identify second part of file name */ ptr2 = strchr( ptr1 + 2, CHBKSL ) + 1; len2 = strlen( ptr2 ); /* * add file name to file extensions */ for( i=1; i < *num; i++ ) { leni = strlen(namptr[i]); memmove( &namptr[i][len1], namptr[i], leni + 1 ); memcpy( namptr[i], namptr[0], len1 ); strcat( namptr[i], ptr2 ); } /* * remove the two backslashes from the first string */ memmove( ptr2 - 1, ptr2, len2 + 1 ); len2 = strlen( ptr1 + 2 ); memmove( ptr1 + 1, ptr1 + 2, len2 + 1 ); } }
void wbc_area ( char *locnam, char *vorstr, int len, char *areastr, int *iret ) /************************************************************************ * wbc_area * * * * This function converts the VOR stations string to the VOR watch area * * string,containing distance, direction, county names and state ids. * * * * Input example: * * 17 WNW DEC;26 E FAM;26 WNW FAM;55 SSE COU;22 NNW UIN;47 ENE UIN; * * * * Output example: * * 17 WNW OF DECATUR, IL..TO 26 E OF FARMINGTON, MO..TO 26 WNW OF * * FARMINGTON, MO..TO 55 SSE OF COLUMBIA, MO..TO 22 NNW OF QUINCY, * * IL..TO 47 ENE OF QUINCY, IL. * * * * wbc_area ( locnam, vorstr, len, areastr, iret ) * * * * Input parameters: * * *locnam char Locator type * * *vorstr char Polygon text string * * len int Max length of 'areastr' * * * * Output parameters: * * *areastr char Polygon area text string * * *iret int Return value * * -5 = VORSTR too big * * * ** * * Log: * * A. Hardy/NCEP 5/03 From VF_AREA * ************************************************************************/ { int ii, nstn, maxlen, nstr, np, icnt, ier, exp, max, len1; char tmpstr[420], holdstr[200], qstate[1], pstn[180]; char arrgrp[15], **aryvor, county[30], state[3]; /*---------------------------------------------------------------------*/ *iret = 0; np = 1; icnt = 1; max = 6; exp = 4; qstate[0] = '\0'; tmpstr[0] = '\0'; maxlen = sizeof(pstn); if ( strcmp ( locnam, "VOR") != 0 ) { *iret = -2; return; } cst_lstr ( vorstr, &len1, &ier ); if ( len1 >= 400 ) { *iret = -5; return; } /* * Set up the memory space to break up the VOR area string. */ clo_init ( &ier ); aryvor = (char **) malloc(sizeof(char *) * 4); for ( ii = 0; ii < 4; ii++ ) { aryvor[ii] = (char *) malloc(6) ; } /* * Get the city and state of the VOR station. */ for ( ii = 0; ii < 6; ii++) { vorstr = (char *) cst_split ( vorstr, ';', 12, arrgrp, &ier); cst_clst ( arrgrp, ' ', " ", exp, max, aryvor, &nstr, &ier); if ( nstr == 3 ) { clo_findstn ( locnam, aryvor[2], qstate, np, maxlen, &nstn, pstn, &ier); } else if ( nstr == 2) { clo_findstn ( locnam, aryvor[1], qstate, np, maxlen, &nstn, pstn, &ier); } cst_gtag ( "NAME", pstn, " ", county, &ier ); cst_gtag ( "ST", pstn, " ", state, &ier ); cst_rnan (county, county, &ier); /* * Create the watch area string. */ holdstr[0] = '\0'; if ( icnt < 6 ) { if ( strcmp ( aryvor[0], "..") != 0 ) { sprintf( holdstr," %s %s OF %s, %s..TO ",aryvor[0], aryvor[1], county, state); } else { /* * Print string for zero distance and no direction. */ sprintf( holdstr," %s, %s..TO ", county, state); } } else { if ( strcmp ( aryvor[0], "..") != 0 ) { sprintf( holdstr," %s %s OF %s, %s.",aryvor[0], aryvor[1], county, state); } else { /* * Print string for zero distance and no direction. */ sprintf( holdstr," %s, %s.", county, state); } } icnt++; cst_ncat ( tmpstr, holdstr, &len1, &ier); } len1 = G_MIN ( len, (int)strlen(tmpstr) ); cst_ncpy( areastr, tmpstr, len1, &ier); /* * Free memory space. */ for ( ii = 0; ii < 4; ii++ ) { free ( aryvor[ii] ); } free ( aryvor); }
void nmp_sovlattr ( int lp, int ovl, nmpovlstr_t ovlattr, int *iret ) /************************************************************************ * nmp_sovlattr * * * * This function sets the current attribute values for a given overlay * * and loop. * * * * void nmp_sovlattr ( lp, ovl, ovlattr, iret ) * * * * Input parameters: * * lp int loop number * * ovl int overlay number * * ovlattr nmpovlstr_t attribute values * * * * Output parameters: * * *iret int Return code * * = 0 OK * * = -2 table not read * * = -3 attribute not match* * = -11 lp out of range * * = -12 invalid overlay # * * = -13 invalid ovlattr * * Return parameters: * * NONE * * * ** * * Log: * * M. Li/GSC 12/00 Created * * M. Li/GSC 12/00 Added nmpovlstr_t * * M. Li/GSC 01/01 Added a check for invalid input * * M. Li/GSC 02/01 Modifed the table element * * J. Wu/SAIC 08/03 allow decimal point in attr string * * T. Piper/SAIC 08/04 Added support for scale legend * * T. Piper/SAIC 10/04 Changed cst_ilst to cst_clst * ***********************************************************************/ { int ii, ier, ityp; size_t jj; char *strarr[10]; /*---------------------------------------------------------------------*/ *iret = 0; /* * Check for invalid loop index */ if (lp < 0 || lp >= MAX_LOOP ) { *iret = -11; return; } if ( overlay[lp].novl <= 0 ) { *iret = -2; return; } /* * Check for invalid overlay number. */ if (ovl < 0 || ovl >= overlay[lp].novl ) { *iret = -12; return; } /* * Check for invalid overlay attribute input */ for (jj = 0; jj < strlen(ovlattr); jj++) { if ( ! ( isdigit(ovlattr[jj]) || isspace(ovlattr[jj]) ) && (ovlattr[jj] != '.' && ovlattr[jj] != '-' && ovlattr[jj] != ';')) { *iret = -13; return; } } ityp = overlay[lp].mapovl[ovl].ityp; for ( jj=0; jj<(size_t)10; jj++) { strarr[jj] = (char*)malloc(64); } cst_clst(ovlattr, ' ', "?", 10, 64, &strarr[0], &ii, &ier); for ( jj=0; jj<(size_t)10; jj++) { free(strarr[jj]); } if ( (ityp == 0 && ii != 5) || (ityp == 1 && ii != 3) || (ityp == 2 && ii != 6) || (ityp == 5 && ii != 10)) { *iret = -3; } else { strcpy (overlay[lp].mapovl[ovl].attr, ovlattr ); } }
void clo_blasso ( char *bndtyp, char *key, int *npts, char *btags, gpc_polygon *union_poly, int *iret ) /************************************************************************ * clo_blasso * * * * This function takes a string of bound tags, semi-colon separated, and* * returns a polygon structure from the union of the polygons designated* * by the bound tags. A return code of 1 due to a bad bounds key tag * * could mean the tag name (eg., <FIPS>) is invalid and/or the tag value* * (eg., 51059 -- a FIPS code) is invalid. Processing continues, so the* * invoking routine may also want to check the number of polygons for 0,* * in which case it would most likely be caused by an invalid tag name. * * * * Note that the tag name may or may not be enclosed with '<' and '>'. * * If it is not, they will be added to the tag name. * * * * clo_blasso ( bndtyp, key, npts, btags, union_poly, iret ) * * * * Input parameters: * * *bndtyp char Bounds file alias name (eg., WBCMZ_BNDS)* * *key char Search tag name in bounds file * * (eg., <FIPS> or FIPS, <STATE> or STATE)* * *npts int No. of bounds tag values in string btags* * *btags char Bounds tag values, delimited by ";" * * (eg., 51059;51057;51053) * * * * Output parameters: * * *union_poly gpc_polygon GPC polygon structure of union * * iret int Return code * * = 0 Normal * * = 1 No bound area found for a tag * * due to bad tag name or value * * = -1 Bounds file open error return * * or illegal bounds name * * * ** * * Log: * * F. J. Yen/NCEP 1/05 * * F. J. Yen/NCEP 2/05 Increased size of btagkey; Enclosed tag * * name with '<' and '>' if missing. * * J. Wu/SAIC 6/05 remove reference to LLMXPT * * F.Yen&D.Plummer/NCEP 7/05 Redesigned for performance. * * D.W.Plummer/NCEP 8/05 Add final GPC_UNION to rm spurious pts * ***********************************************************************/ { char **arrptr, btagkey[80]; char *tag_start = { "<" }; char *tag_end = { ">" }; int ii, maxexp, minp, ier, ierro, mxpts, end; int narr, numTmp, len, hole, initl; float *xTmp, *yTmp; float rlatmn, rlonmn, dlatmx, dlonmx, filter; gpc_polygon polygon; gpc_vertex_list verts; /*---------------------------------------------------------------------*/ *iret = 0; ier = 0; minp = 0; hole = 0; filter = 0.0; maxexp = 400; /* * Initalize the gpc polygon structure variables */ union_poly->num_contours = 0; union_poly->hole = (int *)NULL; union_poly->contour = (gpc_vertex_list *)NULL; clo_bstype ( bndtyp , &ier ); /* Set the bounds file */ if ( ier != 0 ) { *iret = -1; return; } /* * Set the bounds area */ rlatmn = -90.0; dlatmx = +90.0; rlonmn = -180.0; dlonmx = +180.0; clo_bsarea ( &rlatmn, &rlonmn, &dlatmx, &dlonmx, &ier ); /* * Initialize the clo library */ clo_init ( &ier); /* * Allocate memory */ clo_qmxpts ( "BOUNDS", &mxpts, &ier ); G_MALLOC ( xTmp, float, mxpts, "CLO_BLASSO" ); G_MALLOC ( yTmp, float, mxpts, "CLO_BLASSO" ); /* * Break apart the bounds tag values */ arrptr = (char **)malloc(*npts * sizeof(char *)); for (ii = 0; ii < *npts; ii++) { arrptr[ii] = (char *) malloc(maxexp); } cst_clst ( btags, ';', " ", *npts, maxexp, arrptr, &narr, &ier ); /* * initialize single bounds polygon */ polygon.num_contours = 0; polygon.hole = (int *)NULL; polygon.contour = (gpc_vertex_list *)NULL; /* * Loop over bounds tag values */ for (ii=0;ii < narr; ii++) { cst_rmbl ( arrptr[ii], arrptr[ii], &len, &ier ); if ( len > 0 ) { ierro = 0; /* * Create the key tag to search on ( eg. <FIPS>51097 ). First, * check for '<' at beginning of tag. Add it if it isn't there. */ btagkey[0] = '\0'; if( key[0] != '<' ) { strcpy( btagkey, tag_start ); } strcat ( btagkey, key ); /* * Check for '>' at end of key tag. Add it if it isn't there. */ end = strlen ( key ); if ( key [ end - 1 ] != '>' ) { strcat ( btagkey, tag_end ); } strcat ( btagkey, arrptr[ii]); clo_bstype ( bndtyp , &ier ); /* Set the bounds file */ clo_bstag ( btagkey, &ier ); /* Set the bounds key tag (eg <FIPS>51097 ) */ /* * Find the bound key tag polygon */ initl = 1; while ( ierro == 0 ) { /* * Get next bounds */ clo_bgnext (&minp, &mxpts, &filter, &numTmp, xTmp, yTmp, &ierro ); if ( initl == 1 ) { initl = 0; if ( ierro != 0 ) { /* * No bound area (polygon) found for current bounds * key tag in btagkey due to either an invalid tag * name (eg, <FIPS> or <STATE>) and/or invalid tag * value (ie, if the tag name is <FIPS>, the tag * value would be a FIPS code such as 13009). */ *iret = 1; } } if ( ierro == 0 ) { /* * initialize vertex list */ verts.vertex = (gpc_vertex*)NULL; verts.num_vertices =0; gpc_cvlist (numTmp, xTmp, yTmp, &verts, &ier ); gpc_add_contour ( &polygon, &verts, hole); free ( verts.vertex ); } } /* end for while loop */ } /* end for length check */ } /* end for loop */ /* * union the polygon with a NULL polygon (union) to get the union */ gpc_polygon_clip (GPC_UNION, &polygon, union_poly, union_poly ); gpc_free_polygon ( &polygon); gpc_polygon_clip (GPC_UNION, &polygon, union_poly, union_poly ); /* * Free memory space. */ G_FREE ( xTmp, float ); G_FREE ( yTmp, float ); for ( ii = 0; ii < *npts; ii++ ) { free ( arrptr[ii] ); } free ( arrptr); }