Пример #1
0
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);       
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;

}
Пример #5
0
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;
}
Пример #6
0
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;

}
Пример #7
0
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;

	}

}
Пример #8
0
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;
}
Пример #9
0
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 );
	}

}
Пример #10
0
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);
}
Пример #11
0
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 );
    }  

}
Пример #12
0
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);
}