Beispiel #1
0
void utl_ctim ( int len, char *curtim, int *iret )
/************************************************************************
 * utl_ctim                                                             *
 *                                                                      *
 * This function retrieves the current system time and converts it to   *
 * a character string of the form DDHHMM.				*
 *                                                                      *
 * utl_ctim ( len, curtim, iret )  					*
 *                                                                      *
 * Input parameters:                                                    *
 *                                                                      *
 *	len		int		Max length of 'curtim'		*
 * Output parameters:                                                   *
 *	*curtim		char		Current time as DDHHMM		*
 *      *iret           int		Return Code                     *
 *                                                                      *
 **                                                                     *
 * Log:                                                                 *
 * A. Hardy/NCEP	5/03		From VFCTIM  			*
 * B. Yin/SAIC          3/04   changed css_date calling sequences       *
 ***********************************************************************/
{
    char    dattim[7], zone[4];
    int     itype, iyr, imon, idy, ihr, imin, isc, julian, ier;
/*-------------------------------------------------------------------*/
    *iret = 0;
    itype = 1;
    curtim[0] = '\0';

   /*
    * Get current system time for UTC issue time of cancel product.
    */

    css_date ( &itype, &iyr, &imon, &idy, &ihr, &imin, &isc, &julian, 
               zone, iret);

    if ( (idy >= 1) && (idy <= 9 ) ) {
	cst_ncpy( curtim, "0", 1, &ier);
    }
    cst_inch ( idy, dattim, iret);
    cst_ncat (curtim, dattim, &len, iret);

    if ( (ihr >= 0) && (ihr <= 9 ) ) {
	cst_ncat( curtim, "0", &len, iret);
    }
    cst_inch ( ihr, dattim, iret );
    cst_ncat (curtim, dattim, &len, iret);

    if ( (imin >= 0) && (imin <= 9 ) ) {
	cst_ncat( curtim, "0", &len, iret);
    }
    cst_inch ( imin, dattim, iret );
    cst_ncat (curtim, dattim, &len, iret);
}
Beispiel #2
0
void vfctim ( int *iret )
/************************************************************************
 * vfctim                                                               *
 *                                                                      *
 * This function retrieves the current system time and converts it to   *
 * a character string.							*
 *                                                                      *
 * vfctim ( iret )                                             		*
 *                                                                      *
 * Input parameters:                                                    *
 *                                                                      *
 * Output parameters:                                                   *
 *      *iret            int            Return Code                     *
 *                                                                      *
 **                                                                     *
 * Log:                                                                 *
 * A. Hardy/GSC         11/99   Created                                 *
 * A. Hardy/GSC		 2/00   Extracted from SPCTXT                   *
 * A. Hardy/GSC		12/00   Removed '&' from iret			*
 * A. Hardy/NCEP	 6/03   Added tmzn to CSS_DATE			*
 * B. Yin/SAIC          03/04   changed css_date calling sequences      *
 ***********************************************************************/
{
    char    dattim[7], curtim[7], tmzn[4];
    int     itype, iyr, imon, idy, ihr, imin, isc, julian;
/*-------------------------------------------------------------------*/

    itype = 1;

   /*
    * Get current system time for UTC issue time of cancel product.
    */

    css_date ( &itype, &iyr, &imon, &idy, &ihr, &imin, &isc, &julian, 
               tmzn, iret);

    if ( (idy >= 1) && (idy <= 9 ) ) strcpy( curtim, "0");
    cst_inch ( idy, dattim, iret);
    strcpy ( curtim, dattim);
    if ( (ihr >= 0) && (ihr <= 9 ) ) strcat( curtim, "0");
    cst_inch ( ihr, dattim, iret );
    strcat (curtim, dattim);
    if ( (imin >= 0) && (imin <= 9 ) ) strcat( curtim, "0");
    cst_inch ( imin, dattim, iret );
    strcat (curtim, dattim);
    strcpy ( spcinfo.curtim, curtim);

}
Beispiel #3
0
void gb2_ctim ( int time, char *param )
/************************************************************************
 * gb2_ctim								*
 *									*
 * This routine replaces the "--" characters in a GEMPAK parameter      *
 * string with the number specified in variable time.                   *
 *									*
 * gb2_ctim ( time, param )	                			*
 *									*
 * Input parameters:							*
 *	time  	        int             Integer time range              *
 *									*
 * Input/Output parameters:						*
 *      *param         char             GEMPAK parameter string         *
 **									*
 * Log:									*
 * S. Gilbert       12/04                                               *
 * T. Piper/SAIC	07/06	Replaced strncpy with cst_ncpy		*
 ***********************************************************************/
{
    int  ier, len;
    char ctim[12], dash[]="--", *cptr;

    /*
    **   Convert integer to character
    */
    if ( time != IMISSD ) 
       if ( time >= 0 && time < 10 )
          sprintf ( ctim, "%.2d", time);
       else
          cst_inch ( time, ctim, &ier);
    else 
	cst_ncpy(ctim, "XX", 2, &ier);

    /*
    **   replace "--" or append time character in parameter string.
    */
    cptr = strstr( param, dash);
    if ( cptr != 0 )
       cst_rpst( param, dash, ctim, param, &ier);
    else
       if ( time > 0 )  cst_ncat( param, ctim, &len, &ier);

}
Beispiel #4
0
void dg_prft ( const char *time1, const char *time2, const int *level1,
               const int *level2, const int *ivcord, const char *parm,
	       int *num, int *iret )
/************************************************************************
 * dg_prft								*
 *									*
 * This subroutine accumulates precipitation over a given time period.	*
 * The time period is hh hours given in the parameter name which has	*
 * the form PhhM or PhhI.  Conversions to inches or millimeters will	*
 * be automatic.							*
 *									*
 * The following assumptions are made:					*
 *									*
 *	1.  The precipitation totals exist at forecast times		*
 *	    at regular intervals in whole hours.			*
 *									*
 *	2.  At regular intervals the precipitation is given for		*
 *	    the entire interval.  This is a major interval.		*
 *									*
 *	3.  At regular subintervals within the major intervals,		*
 *	    the precipitation is accumulated since the start of		*
 *	    the major interval.						*
 *									*
 * dg_prft ( time1, time2, level1, level2, ivcord, parm, num, iret )    *
 *									*
 * Input parameters:							*
 *      *time1          const char      Date/time                       *
 *      *time2          const char      Date/time                       *
 *      *level1         const int       Level                           *
 *      *level2         const int       Level                           *
 *      *ivcord         const int       Vertical coordinate             *
 *      *parm           const char      Parameter name                  *
 *									*
 * Input and output parameters:						*
 *      *num            int             Location of grid                *
 *									*
 * Output parameters:							*
 *      *iret           int             Return code                     *
 *					  0 = normal return		*
 *					 -7 = grid cannot be found	*
 **									*
 * Log:									*
 * K. Brill/NMC		10/92						*
 * K. Brill/NMC		 2/93	Use first character of parm 		*
 * M. desJardins/NMC	 7/92	DG_UHDR --> DG_UPSG			*
 * K. Brill/NMC		11/93	Take care of negative precip		*
 * M. desJardins/NMC	 3/94	Reorganize				*
 * S. Jacobs/NMC	10/94	Check for parms w/ PR which aren't rates*
 * K. Brill/NMC		 5/95	Add 3-h major interval			*
 * T. Lee/GSC		 4/96	Single dimension for dgg		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * K. Brill/HPC		 2/03	Call DG_FRIG to free internal grids	*
 * T. Lee/SAIC		10/03	Increased temporal resolution for hrly	*
 * T. Lee/SAIC		 1/04	Handled Canadian precip. grids		*
 * R. Tian/SAIC		 1/05	Fixed bug for GFS data			*
 * S. Jacobs/NCEP	 9/05	Fixed counter when in CANADIAN mode	*
 * R. Tian/SAIC          2/06   Recoded from Fortran                 	*
 * S. Jacobs/NCEP	 8/09	Added 1hr to major interval list	*
 ************************************************************************/
{
    /*
     * Set possible subinterval accumulation periods.
     */
    char cdt[NDT][3] = { "03", "06", "09", "12", "01", "02",
			 "04", "05", "07", "08", "10", "11", 
			 "24", "48" };
    int idt[NDT]     = {  3,    6,    9,    12,   1,    2,
    			  4,    5,    7,    8,    10,   11,
			  24,   48 };
    /*
     * Set possible major interval lengths (hours).
     */
    char cdtm[NDTM][4] = { "01", "03", "06", "12", "24" };
    int idtm[NDTM]     = {   1,    3,    6,   12,   24 };

    char thold[5], pnum[14], fstchr, lstchr, accum[73], ftype, ftime[4],
        time21[21], time22[21];
    float rmult, signp;
    int intdtf[3], jvcord, iacc, lenstr, ihrs, ihhlst, iptime, lenst,
        numsub, nummaj, majts, iz, itet, i, ier, ierr;
    int done;
/*----------------------------------------------------------------------*/
    *iret = -7;

    /*
     * Set the vertical coordinate to missing since it can be ignored.
     */
    jvcord = -1;

    /*
     * Check to see if precipitation rate is requested.  If so,
     * check for the data immediately.
     */
    if ( strncmp ( parm, "PR", 2 ) == 0 ) {
	strcpy ( accum, &parm[2] );
	cst_numb ( accum, &iacc, &ierr );
	if ( ierr == 0 ) {
	    dg_grdr ( time1, time2, level1, level2, &jvcord, parm, num, iret );
	}
	return;
    }

    /*
     * Check that precipitation in form P|S|C nnn I|M has been requested.
     */
    cst_lstr ( (char *)parm, &lenstr, &ier );
    if ( lenstr <= 2 ) return;
    fstchr = parm[0];
    if ( ( fstchr != 'P' ) && ( fstchr != 'S' ) && ( fstchr != 'C' ) ) return;
    lstchr = parm[lenstr-1];
    if ( ( lstchr != 'I' ) && ( lstchr != 'M' ) ) return;

    /*
     * Get number of hours for the precipitation accumulation.
     */
    strncpy ( pnum, &parm[1], lenstr - 2 );
    pnum[lenstr-2] = '\0';
    cst_numb ( pnum, &ihrs, &ier );
    if ( ier != 0 ) return;

    /*
     * Check to see if precipitation can be found as a rate or as a
     * combination of P, S, C precipitation values.
     */
    dg_prcp ( time1, time2, level1, level2, &jvcord, parm, num, iret );
    if ( *iret == 0 ) return;

    /*
     * Get the forecast time for this grid.
     */
    tg_ctoi ( (char *)time1, intdtf, &ier, strlen(time1) );
    if ( intdtf[2] == 0 ) return;

    /*
     * Read data based on forecast hours (for Canadian data)
     */
    ctg_cftm ( intdtf[2], &ftype, ftime, &ier );
    if ( ftime[0] == '0' ) { 
	pnum[0] = fstchr;
	strcpy ( &pnum[1], &ftime[1] );
	lenstr = strlen ( pnum );
	pnum[lenstr] = lstchr;
	pnum[lenstr+1] = '\0';
    } else {
	pnum[0] = fstchr;
	strcpy ( &pnum[1], ftime );
	lenstr = strlen ( pnum );
	pnum[lenstr] = lstchr;
	pnum[lenstr+1] = '\0';
    }
    dg_prcp ( time1, time2, level1, level2, &jvcord, pnum, num, &ier );

    /*
     * Get the accumulation at present time, over x hours, where
     * x is to be determined by looping over the possiblities.
     */
    if ( ier != 0 ) {
	i = -1;
	while ( ( ier != 0 ) && ( i < NDT - 1 ) ) {
	    i++;
	    if ( idt[i] != ihrs ) {
		pnum[0] = fstchr;
		strcpy ( &pnum[1], cdt[i] );
		lenstr = strlen ( pnum );
		pnum[lenstr] = lstchr;
		pnum[lenstr+1] = '\0';
		dg_prcp ( time1, time2, level1, level2, &jvcord, pnum,
		          num, &ier );
	    }
	}

	/*
	 * If some value for precipitation was found, check the number 
	 * of hours accumulated.
	 */
	if ( ier == 0 ) {
	    ihhlst = idt[i];
	} else {
	    return;
	}
    } else {
	cst_numb ( ftime, &ihhlst, iret );
    }

    strcpy ( time22, time2 );
    if ( ihhlst > ihrs ) {
	/*
	 * Go back IHRS hours, get the accumulation at that
	 * forecast time and subtract.
	 */
	intdtf[2] = intdtf[2] - ihrs * 100;
	ctg_itoc ( intdtf, time21, &ier );
	iptime = ihhlst - ihrs;
	cst_inch ( iptime, thold, &ier );
	cst_lstr ( thold, &lenst, &ier );
	if ( lenst == 1 ) {
	    pnum[0] = fstchr;
	    pnum[1] = '0';
	    pnum[2] = thold[0];
	    pnum[3] = lstchr;
	    pnum[4] = '\0';
	} else {
	    pnum[0] = fstchr;
	    strcpy ( &pnum[1], thold );
	    lenstr = strlen ( pnum );
	    pnum[lenstr] = lstchr;
	    pnum[lenstr+1] = '\0';
	}
	dg_nxts ( &numsub, &ier );
	dg_prcp ( time21, time22, level1, level2, &jvcord, pnum,
	          &numsub, iret );
	if ( *iret == 0 ) {
	    rmult = -1.;
	    pd_prcp ( _dggrid.dgg[(*num)-1].grid, _dggrid.dgg[numsub-1].grid,
		&rmult, &_dgfile.kxyd, _dggrid.dgg[(*num)-1].grid, &ier );
	}
	dg_frig ( &numsub, &ier );
    } else {
	/*
	 * Accumulate the precipitation.  Total elapsed time is itet.
	 */
	itet = ihhlst;
	dg_nxts ( &nummaj, &ier );
	done = G_FALSE;
	while ( done == G_FALSE ) {
	    /*
	     * Go back IHHLST hours, get accum. and sum it in.
	     */
	    intdtf[2] = intdtf[2] - ihhlst * 100;
	    ctg_itoc ( intdtf, time21, &ier );

	    /*
	     * Determine the major time step.
	     */
	    ier = 999;
	    i = -1;
	    while ( ( ier != 0 ) && ( i < NDTM - 1 ) ) {
		i++;
		pnum[0] = fstchr;
		strcpy ( &pnum[1], cdtm[i] );
		lenstr = strlen ( pnum );
		pnum[lenstr] = lstchr;
		pnum[lenstr+1] = '\0';
		dg_prcp ( time21, time22, level1, level2, &jvcord,
		          pnum, &nummaj, &ier );
	    }
	    if ( ier != 0 ) {
		*iret = -7;
		dg_frig ( &nummaj, &ier );
		return;
	    }
	    majts = idtm[i];

	    /*
	     * Add in the accumulation.
	     */
	    signp = 1.;
	    pd_prcp ( _dggrid.dgg[(*num)-1].grid, _dggrid.dgg[nummaj-1].grid,
		&signp, &_dgfile.kxyd, _dggrid.dgg[(*num)-1].grid, &ier );

	    /*
	     * Increment elapsed time.
	     */
	    itet += majts;
	    if ( itet == ihrs ) {
		done = G_TRUE;
		*iret = 0;
	    } else if ( itet < ihrs ) {
		ihhlst = majts;
	    } else {
		/*
		 * Subtract out over accumulation.
		 */
		iz = ( ihrs - itet ) + majts;
		intdtf[2] = intdtf[2] - iz * 100;
		ctg_itoc ( intdtf, time21, &ier );
		iptime = majts - iz;
		cst_inch ( iptime, thold, &ier );
		cst_lstr ( thold, &lenst, &ier );
		if ( lenst == 1 ) {
	    	    pnum[0] = fstchr;
	    	    pnum[1] = '0';
	    	    pnum[2] = thold[0];
	    	    pnum[3] = lstchr;
	    	    pnum[4] = '\0';
		} else {
	    	    pnum[0] = fstchr;
	    	    strcpy ( &pnum[1], thold );
	    	    lenstr = strlen ( pnum );
	    	    pnum[lenstr] = lstchr;
	    	    pnum[lenstr+1] = '\0';
		}
		dg_prcp ( time21, time22, level1, level2, &jvcord, pnum,
		          &nummaj, &ier );
		if ( ier == 0 ) {
		    signp = -1.;
		    pd_prcp ( _dggrid.dgg[(*num)-1].grid,
		              _dggrid.dgg[nummaj-1].grid, &signp, &_dgfile.kxyd,
			      _dggrid.dgg[(*num)-1].grid, &ier );
		    *iret = 0;
		} else {
		    *iret = -7;
		    dg_frig ( &nummaj, &ier );
		    return;
		}
		done = G_TRUE;
	    }
	}
	dg_frig ( &nummaj, &ier );
    }

    return;
}
Beispiel #5
0
void gdgpds ( const char *pdsval, const char *vercen, const float *rnvblk,
              const char *gparm, const int *ivcord, const int *level1,
	      const int *level2, const int *havbms, const int *ip10sc,
	      const char *lasttm, const char *gdttm1, const char *gdttm2,
	      const char *gbtbls, const int *igpds, int *nbpds,
              unsigned char *cpds, char *cdd, char *chhmm, int *iret )
/************************************************************************
 * gdgpds								*
 *									*
 * This subroutine bridges the gap between the user input and PDS_MAKE.	*
 * The PDS byte array is returned.					*
 * 									*
 * gdgpds  ( pdsval, vercen, rnvblk, gparm, ivcord, level1, level2,	*
 *           havbms, ip10sc, lasttm, gdttm1, gdttm2, gbtbls, igpds,	*
 *           nbpds, cpds, cdd, chhmm, iret )				*
 *									*
 * Input parameters:							*
 *	*pdsval		const char	User input override PDS numbers	*
 *	*vercen		const char	User input for octets 4,5,6,26  *
 *	*rnvblk		const float	Grid navigation block		*
 *	*gparm		const char	Grid parameter from DG_GRID	*
 *	*ivcord		connst int	Grid vert coord # from DG_GRID	*
 *	*level1		const int	Grid level from DG_GRID		*
 *	*level2		const int	Grid level from DG_GRID		*
 *	*havbms		const int	Flag for existence of BMS	*
 *	*ip10sc		const int	Power of 10 scale factor	*
 *	*lasttm		const char	Last grid time			*
 *	*gdttm1		const char	Grid time from DG_GRID		*
 *	*gdttm2		const char	Grid time from DG_GRID		*
 *	*gbtbls		const char	User input for GRIB tables	*
 *	*igpds		const int	Grid navigation # from CPYFIL	*
 *									*
 * Input and output parameter:						*
 *	*nbpds		int		Input:  Max length for PDS	*
 *					Output: Actual length of PDS	*
 * Output parameters:							*
 *	*cpds		unsigned char	PDS array			*
 *	*cdd		char		2-digit day of month		*
 *	*chhmm		char		Hour minute of data		*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 * Log:									*
 * K. Brill/HPC		08/99						*
 * K. Brill/HPC		 2/00	Add IGPDS				*
 * K. Brill/HPC		 3/00	Avoid character assignment to itself	*
 * R. Tian/SAIC		10/06	Recoded from Fortran			*
 ************************************************************************/
{
    char *pchr, gvcord[5], gdnbuf[LLMXLN], flgdtm1[21], flgdtm2[21],
         otime[21], oparm[13], ovcrd[13], olevl[17], c2d[3], cdum[3], cyr[3];
    int dowhat, inam, ihat, iaat, ipct, iyr, num, noptv, idoc, idngp,
        idosc, ipos[4], ier;
/*----------------------------------------------------------------------*/
    *iret = 0;
    inam = 0;
    ihat = 0;
    iaat = 0;
    ipct = 0;
    oparm[0] = '\0';
    otime[0] = '\0';
    olevl[0] = '\0';
    ovcrd[0] = '\0';

    /*
     * Decode the override grid identifier parameters:
     */
    if ( strlen(pdsval) > 0 ) {
        dowhat = DONAM;
	cst_lcuc ( (char *)pdsval, gdnbuf, &ier );
        for ( pchr = gdnbuf; *pchr != '\0'; pchr++ ) {
            if ( *pchr == '^' ) dowhat = DOHAT;
            if ( *pchr == '@' ) dowhat = DOAAT;
            if ( *pchr == '%' ) dowhat = DOPCT;

            switch ( dowhat ) {
                /*
                 * Retrieve grid name.
                 */
                case DONAM:
                    oparm[inam++] = *pchr;
                break;

                /*
                 * Retrieve in-line time.
                 */
                case DOHAT:
                    if ( *pchr == '^' ) continue;
                    otime[ihat++] = *pchr;
                break;

                /*
                 * Retrieve in-line level.
                 */
                case DOAAT:
                    if ( *pchr == '@' ) continue;
                    olevl[iaat++] = *pchr;
                break;

                /*
                 * Retrieve in-line vertical coordinate.
                 */
                case DOPCT:
                    if ( *pchr == '%' ) continue;
                    ovcrd[ipct++] = *pchr;
                break;
            }
        }
        oparm[inam] = '\0';
        otime[ihat] = '\0';
        olevl[iaat] = '\0';
        ovcrd[ipct] = '\0';
    }

    /*
     * Check for override on the date/time stamp.
     */
    if ( ihat > 0 ) {
        strcpy ( flgdtm1, otime );
	flgdtm2[0] = '\0';
    } else {
	/*
	 * Add century to YYMMDD.
	 */
	if ( strchr ( gdttm1, '/' ) - gdttm1 < 8 ) {
	    strncpy ( cyr, gdttm1, 2 );
	    cyr[2] = '\0';
	    cst_numb ( cyr, &iyr, &ier );
	    if ( iyr < 70 ) {
	        strcpy ( flgdtm1, "20" );
		strcat ( flgdtm1, gdttm1 );
	    } else {
	        strcpy ( flgdtm1, "19" );
		strcat ( flgdtm1, gdttm1 );
	    }
	} else {
            strcpy ( flgdtm1, gdttm1 );
	}
	flgdtm2[0] = '\0';
    }

    /*
     * Next, set the OCTET 4, 5, 6, and 26 values.
     */
    cst_ilst ( (char *)vercen, '/', 0, 4, ipos, &num, &ier );
    if ( ipos[0] != 0 ) {
	noptv = ipos[0];
    } else {
	noptv = 2;
    }
    if ( ipos[1] != 0 ) {
	idoc = ipos[1];
    } else {
	idoc = 7;
    }
    if  ( ipos[2] != 0 ) {
	idngp = ipos[2];
    } else {
	idngp = 0;
    }
    if ( ipos[3] != 0 ) {
	idosc = ipos[3];
    } else {
	idosc = 5;
    }

    /*
     * Translate vertical coordinate number as character string.
     */
    if ( *ivcord == 0 ) {
	strcpy ( gvcord, "NONE" );
    } else if ( *ivcord == 1 ) {
	strcpy ( gvcord, "PRES" );
    } else if ( *ivcord == 2 ) {
	strcpy ( gvcord, "THTA" );
    } else if ( *ivcord == 3 ) {
	strcpy ( gvcord, "HGHT" );
    } else if ( *ivcord == 4 ) {
	strcpy ( gvcord, "SGMA" );
    } else if ( *ivcord == 5 ) {
	strcpy ( gvcord, "DPTH" );
    } else {
	strcpy ( gvcord, "NULL" );
    }

    /*
     * Build the PDS now.
     */
    pds_make( &noptv, &idoc, &idngp, &idosc, rnvblk, gparm, oparm, gvcord,
        ovcrd, level1, level2, olevl, havbms, ip10sc, lasttm, flgdtm1, flgdtm2,
	gbtbls, igpds, nbpds, cpds, ipos, iret );

    /*
     * Convert day, hour, and minute in IPOS to characters.
     */
    cst_inch ( ipos[0], c2d, &ier );
    if ( ipos[0] < 10 ) {
        cdum[0] = '0';
        cdum[1] = c2d[0];
        cdum[2] = '\0';
    } else {
	strcpy ( cdum, c2d );
    }
    strcpy ( cdd, cdum );
    cst_inch ( ipos[1], c2d, &ier );
    if ( ipos[1] < 10 ) {
        cdum[0] = '0';
        cdum[1] = c2d[0];
        cdum[2] = '\0';
    } else {
	strcpy ( cdum, c2d );
    }
    strncpy ( chhmm, cdum, 2 );
    cst_inch ( ipos[2], c2d, &ier );
    if ( ipos[2] < 10 ) {
        cdum[0] = '0';
        cdum[1] = c2d[0];
        cdum[2] = '\0';
    } else {
	strcpy ( cdum, c2d );
    }
    strncpy ( &chhmm[2], cdum, 2 );
    chhmm[4] = '\0';

    return;
}
Beispiel #6
0
void dgc_subg ( const char *ijskip, int *maxgrid, int *imll, int *jmll, 
                int *imur, int *jmur, int *iret )
/************************************************************************
 * dgc_subg								*
 *									*
 * This subroutine sets the internal subset grid given the reference	*
 * grid navigation set in GPLT and the map projection set in GPLT.	*
 * If the reference grid is globe wrapping with the addition of an	*
 * extra grid column, then the navigation set in GPLT must be that for	*
 * the grid with the extra column.					*
 * 									*
 * The subset grid is larger by five grid points than that strictly	*
 * needed to cover the map projection area.  This extension permits	*
 * more accurate computation of derivatives.  The subset grid relative	*
 * coordinates of the region strictly needed for the map are returned.	*
 * 									*
 *									*
 * IJSKIP is parsed by IN_GSKP.  IJSKIP information is entered using	*
 * the following format, where items in square brackets are optional:	*
 *									*
 *	IJSKIP = Iskip[;Istart][;Iend][/Jskip[;Jstart][;Jend]],		*
 *									*
 *	IJSKIP=Y[ES], or IJSKIP=N[O]					*
 *									*
 * The following rules apply in using IJSKIP input:			*
 *									*
 * 1.  If only Iskip is entered, then I and J skips are Iskip.  The	*
 *     beginning points and ending points are determined by querying	*
 *     the display projection to find the area on the reference grid	*
 *     needed to cover it.						*
 *									*
 * 2.  If any bounding value is omitted, it is determined automatically *
 *     by querying the display projection as in 1 above.		*
 *									*
 * 3.  If IJSKIP is blank or NO, skipping is not used to determine the	*
 *     internal grid navigation.					*
 * 									*
 * 4.  If IJSKIP is YES, all skip parameters are determined		*
 *     automatically.							*
 * 									*
 * dgc_subg ( ijskip, maxgrid, imll, jmll, imur, jmru, iret )		*
 *									*
 * Input parameters:							*
 *	*ijskip		const char	User input for skip subsetting	*
 *	*maxgrid	int		Maximum grid size               *
 *									*
 * Output parameters:							*
 *	*IMLL		int		Lower left map I bound		*
 *	*JMLL		int		Lower left map J bound		*
 *	*IMUR		int		Upper right map I bound		*
 *	*JMUR		int		Upper right map J bound		*
 * 	*IRET		int		Return code			*
 *					  0 = normal return		*
 *					-37 = no ref grid navigation set*
 *					-38 = glb wrap grd inconsistency*
 *					-39 = map projection is not set *
 *					-40 = subset grd bound error	*
 *					-41 = subset grid is too big	*
 *					-43 = cannot rearrange grid	*
 *					-44 = error set subset grid nav	*
 *					-48 = both I bounds required	*
 **									*
 * Log:									*
 * K. Brill/HPC		08/02						*
 * K. Brill/HPC		 9/02	Also initialize gparmd () to blank	*
 * S. Jacobs/NCEP	11/02	Added check for current nav vs saved nav*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * K. Brill/HPC		12/02	Use IJSKIP input for subset by skipping *
 * R. Tian/SAIC		 3/04	Add check for outflg			*
 * R. Tian/SAIC		 5/04	Added call to DG_CONE			*
 * R. Tian/SAIC		 2/06	Recoded from Fortran			*
 * S. Gilbert/NCEP	 5/07	Added maxgrid argument                  *
 ************************************************************************/
{
    char gprj[5], cnum[5];
    float aglt1, agln1, aglt2, agln2, ag1, ag2, ag3, rimn, rjmn, rimx,
        rjmx, rglt[2], rgln[2], tnav[LLNNAV];
    double a, b, c;
    int lmx, mx, my, imn, jmn, imx, jmx, nx, ny, ix1, ix2, nsx, iy1, iy2,
        nsy, n, idx, idy, ichk, iadlx, iadly, iadrx, iadry, kxsg, kysg,
	kxysg, nu, mxnu, imn2, jmn2, imx2, jmx2, iadd, navsz;
    int nc, tobig, autos, angflg, navflg, done, ishf, ier, ierr, iir, i, k;

   /*
    * timing vars
    */
    struct   timeb t_gsgprj1, t_gsgprj2, t_gsgprj3, t_gqgprj1, t_gqgprj2, 
             t_gsgprj4, t_setr, t_gqbnd, t_gskp, t_gtrans1, t_mnav, t_cnav, 
             t_cone, t_current;
/*----------------------------------------------------------------------*/
    *iret = 0;
    _dgsubg.dgsubg = G_TRUE;

    for ( i = 0; i < NGDFLS; i++ ) {
	if ( _nfile.outflg[i] == G_TRUE ) {
	    *iret = -63;
	    return;
	}
    }

    /*
     * Set LMX to maximum allowed threshold for ijskip=yes
     */
    lmx = LLMXTH;

    /*
     * Set the reference grid navigation in GPLT.
     */
    cst_itos ( (int *)(&_dgsubg.refnav[1]), 1, &nc, gprj, &ier );
    cst_rmbl ( gprj, gprj, &nc, &ier );
    mx = G_NINT ( _dgsubg.refnav[4] );
    my = G_NINT ( _dgsubg.refnav[5] );
    agln1 = _dgsubg.refnav[7];
    if ( _dgfile.addcol == G_TRUE ) {
	mx += 1;
	agln2 = _dgsubg.refnav[7];
    } else {
	agln2 = _dgsubg.refnav[9];
    }
    ftime(&t_gsgprj1);
    gsgprj ( gprj, &_dgsubg.refnav[10], &_dgsubg.refnav[11], 
             &_dgsubg.refnav[12], &mx, &my, &_dgsubg.refnav[6],
	     &_dgsubg.refnav[7], &_dgsubg.refnav[8], &agln2, &ier,
	     strlen(gprj) );
    ftime(&t_current);
    if ( ier != 0 ) {
	er_wmsg ( "GEMPLT", &ier, " ", &ierr, strlen("GEMPLT"), strlen(" ") );
	*iret = -37;
	return;
    } else if ( _dgsubg.gwrapg == G_TRUE &&
        ( ! COMPAR ( agln1, agln2 ) && ! COMPAR ( (agln1+360.), agln2 ) ) ) {
	*iret = -38;
	return;
    }

    /*
     * Get the shift for re-arranging any globe wrapping grid.
     * ISHIFT is stored in DGCMN.CMN.
     */
    ftime(&t_setr);
    grc_setr ( &mx, &my, &_dgsubg.ishift, &ier );
    ftime(&t_current);
    if ( ier == -22 ) {
	*iret = -39;
	return;
    } else if ( ier != 0 ) {
	*iret = -43;
	return;
    }
    ftime(&t_gqgprj1);
    gqgprj ( gprj, &ag1, &ag2, &ag3, &mx, &my, &aglt1, &agln1, &aglt2,
             &agln2, &ier, sizeof(gprj) );
    ftime(&t_current);
    gprj[4] = '\0';
    cst_lstr ( gprj, &nc, &ier );
    gprj[nc] = '\0';

    /*
     * Get the grid index bounds for the subset grid.
     */
    ftime(&t_gqbnd);
    gqbnd ( sys_G, &rimn, &rjmn, &rimx, &rjmx, &ier, strlen(sys_D) );
    ftime(&t_current);
    if ( ier != 0 ) {
	er_wmsg ( "GEMPLT", &ier, " ", &ierr, strlen("GEMPLT"), strlen(" ") );
	*iret = -40;
	return;
    }
    imn = (int)rimn;
    jmn = (int)rjmn;
    imx = G_NINT ( rimx + .5 );
    if ( G_DIFFT((float)((int)rimx), rimx, GDIFFD) ) imx = (int)rimx;
    jmx = G_NINT ( rjmx + .5 );
    if ( G_DIFFT((float)((int)rjmx), rjmx, GDIFFD) ) jmx = (int)rjmx;
    if ( imn < 1 ) imn = 1;
    if ( jmn < 1 ) jmn = 1;
    if ( imx > mx ) imx = mx;
    if ( jmx > my ) jmx = my;
    nx = imx - imn + 1;
    ny = jmx - jmn + 1;
    if ( nx * ny > lmx ) {
        tobig = G_TRUE;
    } else {
        tobig = G_FALSE;
    }

    /*
     * Check for subsetting by skipping.
     *
     * The bounds are returned from IN_GSKP as IMISSD if
     * not provided.  The skip value returned is converted
     * to a stride value by adding one, i.e. IDX=1 means
     * no skipping, IDX=2 means skip one point.
     *
     * The mathematical relationship stating that the
     * original number of grid points from IMN to IMX must
     * equal the number of points skipped plus the number
     * kept is this:
     *
     *	    (IMX - IMN + 1) = N + (N - 1) * nskip
     *
     * where N is the number of points remaining after
     * skipping and nskip is the number of points skipped
     * between the points that are kept.
     *
     * This equation appears a number of times in various
     * forms below.
     */
    ftime(&t_gskp);
    in_gskp ( ijskip, &ix1, &ix2, &nsx, &iy1, &iy2, &nsy, &autos, &ier );
    ftime(&t_current);
    if ( ier != 0 ) {
	er_wmsg ( "IN", &ier, " ", &iir, strlen("IN"), strlen(" ") );
	*iret = -40;
	return;
    }
    if ( ix2 > mx ) {
	ier = -49;
	er_wmsg ( "DG", &ier, "I", &iir, strlen("DG"), strlen("I") );
	*iret = -40;
	return;
    } else if ( iy2 > my ) {
	ier = -49;
	er_wmsg ( "DG", &ier, "J", &iir, strlen("DG"), strlen("J") );
	*iret = -40;
	return;
    }
    if ( autos == G_TRUE && tobig == G_TRUE ) {
	a = (double)( lmx - 1 );
	b = (double)( nx + ny - 2 * lmx );
	c = (double)( lmx - nx * ny );
	n = (int)( ( b + sqrt ( b * b - 4. * a * c ) ) / ( 2. * a ) );
	nsx = n + 1;
	nsy = nsx;
	cst_inch ( nsx, cnum, &ier );
	ier = 7;
	er_wmsg ( "DG", &ier, cnum, &iir, strlen("DG"), strlen(cnum) );
    }
    idx = nsx + 1;
    idy = nsy + 1;
    if ( nsx > 0 ) {
	ichk = nx / nsx;
	if ( ichk <= 4 ) {
	    ier = 6;
	    er_wmsg ( "DG", &ier, "I", &iir, strlen("DG"), strlen("I") );
	}
    }
    if ( nsy > 0 ) {
	ichk = ny / nsy;
	if ( ichk <= 4 ) {
	    ier = 6;
	    er_wmsg ( "DG", &ier, "J", &iir, strlen("DG"), strlen("J") );
	}
    }

    /*
     * Extend the grid bounds if possible.
     */
    iadlx = 0;
    iadly = 0;
    iadrx = 0;
    iadry = 0;
    imn2 = imn;
    jmn2 = jmn;
    imx2 = imx;
    jmx2 = jmx;
    iadd = 0;
    done = G_FALSE;
    while ( done == G_FALSE && iadd < 5 ) {
	iadd += 1;
	if ( imn2 > idx ) {
	    imn2 -= idx;
	    iadlx += idx;
	}
	if ( jmn2 > idy ) {
	    jmn2 -= idy;
	    iadly += idy;
	}
	if ( imx2 < ( mx - idx ) ) {
	    imx2 += idx;
	    iadrx += idx;
	}
	if ( jmx2 < ( my - idy ) ) {
	    jmx2 += idy;
	    iadry += idy;
	}
	kxsg = G_NINT ( (float)( imx2 - imn2 + 1 + nsx ) / (float)( 1 + nsx ) );
	kysg = G_NINT ( (float)( jmx2 - jmn2 + 1 + nsy ) / (float)( 1 + nsy ) );
	kxysg = kxsg * kysg;
	if ( (kxysg > *maxgrid) && (*maxgrid != IMISSD) ) {
	    done = G_TRUE;
	    if ( imn != imn2 ) {
		imn = imn2 + idx;
		iadlx -= idx;
	    }
	    if ( jmn != jmn2 ) {
		jmn = jmn2 + idy;
		iadly -= idy;
	    }
	    if ( imx != imx2 ) {
		imx = imx2 - idx;
		iadrx -= idx;
	    }
	    if ( jmx != jmx2 ) {
		jmx = jmx2 - idy;
		iadry -= idy;
	    }
	} else {
	    imn = imn2;
	    jmn = jmn2;
	    imx = imx2;
	    jmx = jmx2;
	}
    }

    /*
     * Adjust extend margins using the stride values.
     */
    iadlx = iadlx / idx;
    iadrx = iadrx / idx;
    iadly = iadly / idy;
    iadry = iadry / idy;

    /*
     * Set the I dimension extraction bounds.  No shifting
     * is done if the user provides these bounds.  No
     * extend region is allowed if user provides bounds.
     */
    ishf = _dgsubg.ishift;
    if ( ix1 > 0 ) {
	_dgsubg.ishift = 0;
	iadlx = 0;
	imn = ix1;
    }
    if ( ix2 > 0 ) {
	_dgsubg.ishift = 0;
	iadrx = 0;
	imx = ix2;
    }
    if ( ishf != _dgsubg.ishift ) {
	if ( ix1 < 0 || ix2 < 0 ) {
	    *iret = -48;
	    return;
	}

	/*
	 * Reset the grid projection in GPLT.
	 */
	mx = G_NINT ( _dgsubg.refnav[4] );
	my = G_NINT ( _dgsubg.refnav[5] );
	agln1 = _dgsubg.refnav[7];
	if ( _dgfile.addcol == G_TRUE ) {
	    mx += 1;
	    agln2 = _dgsubg.refnav[7];
	} else {
	    agln2 = _dgsubg.refnav[9];
	}
    ftime(&t_gsgprj2);
	gsgprj ( gprj, &_dgsubg.refnav[10], &_dgsubg.refnav[11], 
	    &_dgsubg.refnav[12], &mx, &my, &_dgsubg.refnav[6],
	    &_dgsubg.refnav[7], &_dgsubg.refnav[8], &agln2, &ier,
	    strlen(gprj) );
    ftime(&t_current);
    ftime(&t_gqgprj2);
	gqgprj ( gprj, &ag1, &ag2, &ag3, &mx, &my, &aglt1, &agln1, 
	    &aglt2, &agln2, &ier, sizeof(gprj) );
    ftime(&t_current);
    if ( diagClbkPtr != NULL )
	gprj[4] = '\0';
	cst_lstr ( gprj, &nc, &ier );
	gprj[nc] = '\0';
	ierr = 5;
	er_wmsg ( "DG", &ierr, " ", &ier, strlen("DG"), strlen(" ") );
    }

    /*
     * Adjust IMX and IMN for skipping.
     */
    if ( idx > 1 ) {
	nu = G_NINT ( (float)( imx - imn + 1 + nsx ) / (float)( 1 + nsx ) );
	mxnu = nu * ( 1 + nsx ) + imn - 1 - nsx;
	if ( mxnu > ( mx - idx ) && mxnu != ix2 ) {
	    mxnu = mx;
	    imn = mxnu - nu * ( 1 + nsx ) + 1 + nsx;
	    if ( imn < 1 ) {
		/*
		 * Start at 1 when full range is needed.
		 */
		imn = 1;
		nu = ( mxnu - imn + 1 + nsx ) / ( 1 + nsx );
		mxnu = nu * ( 1 + nsx ) + imn - 1 - nsx;
	    }
	}
	imx = mxnu;
	if ( ( ix2 > 0 && imx != ix2 ) || 
	     ( ix1 > 0 && imn != ix1 ) ) {
	    ierr = 4;
	    er_wmsg ( "DG", &ierr, "I", &ier, strlen("DG"), strlen("I") );
	}
    }

    /*
     * Set the J dimension extraction bounds. No extend
     * region is allowed if user provides bounds.
     */
    if ( iy1 > 0 ) {
	iadly = 0;
	jmn = iy1;
    }
    if ( iy2 > 0 ) {
	iadry = 0;
	jmx = iy2;
    }

    /*
     * Adjust JMX and JMN for skipping.
     */
    if ( idy > 1 ) { 
	nu = G_NINT ( (float)( jmx - jmn + 1 + nsy ) / (float)( 1 + nsy ) );
	mxnu = nu * ( 1 + nsy ) + jmn - 1 - nsy;
	if ( mxnu > ( my - idy ) && mxnu != iy2 ) {
	    mxnu = my;
	    jmn = mxnu - nu * ( 1 + nsy ) + 1 + nsy;
	    if ( jmn < 1 ) {
		/*
		 * Start at 1 when full range is needed.
		 */
		jmn = 1;
		nu = ( mxnu - jmn + 1 + nsy ) / ( 1 + nsy );
		mxnu = nu * ( 1 + nsy ) + jmn - 1 - nsy;
	    }
	}
	jmx = mxnu;
	if ( ( iy2 > 0 && jmx != iy2 ) || ( iy1 > 0 && jmn != iy1 ) ) {
	    ierr = 4;
	    er_wmsg ( "DG", &ierr, "J", &ier, strlen("DG"), strlen("J") );
	}
    }

    /*
     * Compute subset grid final dimensions.
     */
    kxsg = ( imx - imn + 1 + nsx ) / ( 1 + nsx );
    kysg = ( jmx - jmn + 1 + nsy ) / ( 1 + nsy );
    if ( kxsg <= 0 || kysg <= 0 ) {
	*iret = -40;
	return;
    }
    kxysg = kxsg * kysg;
	

    /*
     * Set common block subset coordinates on reference grid.
     */
    _dgsubg.jsgxmn = imn;
    _dgsubg.jsgymn = jmn;
    _dgsubg.jsgxmx = imx;
    _dgsubg.jsgymx = jmx;
    _dgsubg.jsgxsk = idx;
    _dgsubg.jsgysk = idy;

    /*
     * Set DG_HILO area bounds on subset grid.
     */
    _dgarea.kgxmin = iadlx + 1;
    _dgarea.kgymin = iadly + 1;
    _dgarea.kgxmax = kxsg - iadrx;
    _dgarea.kgymax = kysg - iadry;

    /*
     * Strict map bounds are same as above.
     */
    *imll = _dgarea.kgxmin;
    *jmll = _dgarea.kgymin;
    *imur = _dgarea.kgxmax;
    *jmur = _dgarea.kgymax;

    /*
     * Set the DGAREA common grid bounds calculation flag.
     */
    _dgarea.jgxmin = 1;
    _dgarea.jgxmax = kxsg;
    _dgarea.jgymin = 1;
    _dgarea.jgymax = kysg;
    _dgarea.ksub1 = 1;
    _dgarea.ksub2 = kxysg;

    /*
     * Compute grid size and maximum number of internal grids
     * for the common block.
     */
    if ( (kxysg > *maxgrid) && (*maxgrid != IMISSD) ) {
	/*
	 * Here is the future location to set up some other
	 * remapping.
	 */
	*iret = -41;
	return;
    }

    _dgfile.kxd = kxsg;
    _dgfile.kyd = kysg;
    _dgfile.kxyd = kxysg;
    _dggrid.maxdgg = NDGRD;

    /*
     * Compute the navigation of the internal (subset) grid.
     */
    strcpy ( _dgfile.cprj, gprj );
    rglt[0] = _dgsubg.jsgxmn;
    rgln[0] = _dgsubg.jsgymn;
    rglt[1] = _dgsubg.jsgxmx;
    rgln[1] = _dgsubg.jsgymx;
    nc = 2;
    ftime(&t_gtrans1);
    gtrans ( sys_G, sys_M, &nc, rglt, rgln, rglt, rgln, &ier,
        strlen(sys_G), strlen(sys_M) );
    ftime(&t_current);
    if ( G_ABS ( rgln[0] - 180. ) < .01 || G_ABS ( rgln[0] + 180. ) < .01 )
        rgln[0] = -180.;
    if ( G_ABS ( rgln[1] - 180. ) < .01 || G_ABS ( rgln[1] + 180. ) < .01 )
        rgln[0] = 180.;
    if ( G_ABS ( rgln[0] - rgln[1]) < 0.01 )
        rgln[1] = rgln[0];
    ftime(&t_gsgprj3);
    gsgprj ( _dgfile.cprj, &ag1, &ag2, &ag3, &_dgfile.kxd, &_dgfile.kyd, 
        &rglt[0], &rgln[0], &rglt[1], &rgln[1], &ier, strlen(_dgfile.cprj) );
    ftime(&t_current);
    if ( ier != 0 ) {
	if ( _dgsubg.gwrapg == G_TRUE) {
	    ag2 += 180.;
	    if ( ag2 >= 360. ) ag2 -= 360.;
    ftime(&t_gsgprj4);
	    gsgprj ( _dgfile.cprj, &ag1, &ag2, &ag3, &_dgfile.kxd, &_dgfile.kyd,
		&rglt[0], &rgln[0], &rglt[1], &rgln[1], &ier,
		strlen(_dgfile.cprj) ) ;
    ftime(&t_current);
	if ( ier != 0 ) {
		*iret = -44;
		return;
	    }
	} else {
	    *iret = -44;
	    return;
	}
    }
    angflg = G_TRUE;
    ftime(&t_mnav);
    grc_mnav ( _dgfile.cprj, &_dgfile.kxd, &_dgfile.kyd, &rglt[0], &rgln[0],
	&rglt[1], &rgln[1], &ag1, &ag2, &ag3, &angflg, tnav, &ier );
    ftime(&t_current);

    /*
     * Check the current navigation against the saved navigation.
     * If they are different, then set the navigation flag to False.
     */
    navsz = LLNNAV;
    ftime(&t_cnav);
    grc_cnav ( tnav, _dgfile.snav, &navsz, &navflg, &ier );
    ftime(&t_current);

    /*
     * Save the current navigation.
     */
    for ( k = 0; k < LLNNAV; k++ ) {
	_dgfile.snav[k] = tnav[k];
    }

    db_retsubgcrs (_dgfile.cprj, _dgfile.kxd, _dgfile.kyd, rglt[0], rgln[0],
                       rglt[1], rgln[1],ag1, ag2, ag3,&ier); 
    /*
     * Set the constant of the cone for various projections (code
     * duplicated from UPDCON.FOR in GEMPLT).
     */
    _dgfile.anglr1 = ag1 * DTR;
    _dgfile.anglr2 = ag2 * DTR;
    _dgfile.anglr3 = ag3 * DTR;
    ftime(&t_cone);
    dg_cone ( _dgfile.cprj, &_dgfile.anglr1, &_dgfile.anglr3,
    	      &_dgfile.concon, iret );
    ftime(&t_current);

    /*
     * Set lat/lon,  map scale factor, and rotation matrix
     * internal grid pointers to zero.
     */
    _dgfile.idglat = 0;
    _dgfile.idglon = 0;
    _mapscl.ixmscl = 0;
    _mapscl.iymscl = 0;
    _mapscl.ixmsdy = 0;
    _mapscl.iymsdx = 0;
    _dgrtwd.irtcos = 0;
    _dgrtwd.irtsin = 0;
    _dglndc.lndsea = 0;

    /*
     * Initialize orientation angle.
     */
    _dgovec.ornang = RMISSD;

    /*
     * Free all existing grids since navigation is changed.
     */
    if ( navflg == G_FALSE ) {
        dg_fall ( &ier );
    }

    /*
     * Initialize the origin for M calculation.
     */
    _dgorig.orglat = RMISSD;
    _dgorig.orglon = RMISSD;
    _dgorig.orgxpt = RMISSD;
    _dgorig.orgypt = RMISSD;

    /*
     * Since there were no errors, set flag saying dg package has
     * been initialized.
     */
    _dgfile.dgset = G_TRUE;

    /*
     * Initialize the pointer in the internal grid arrays.
     */
    _dggrid.idglst = 0;

    return;
}
Beispiel #7
0
void da_getfilhdr ( int *iflno, char *fhdnam, int *mxword,
			float *rheadr, int *nword, int *iret )
/************************************************************************
 * da_getfilhdr								*
 *									*
 * This function reads the real values for the given file header from	*
 * a non-GEMPAK data source.						*
 *									*
 * da_getfilhdr ( iflno, fhdnam, mxword, rheadr, nword, iret )		*
 *									*
 * Input parameters:							*
 *	iflno		int*		GEMPAK file number		*
 *	fhdnam		char*		Name of the file header section	*
 *	mxword		int*		Maximum words to return		*
 *									*
 * Output parameters:							*
 *	rheadr		float*		File header			*
 *	nword		int*		Header length			*
 *	iret		int*		Return code			*
 **									*
 * S. Jacobs/NCEP	 6/13	Created					*
 * S. Jacobs/NCEP	12/13	Save NX and NY for later use		*
 ************************************************************************/
{
    int		ii, jj, gflnum, ier;
    char	arrlen[12], model[MXFLSZ];
    char	pyfile[MXFLSZ], pymeth[MXFLSZ];
/*---------------------------------------------------------------------*/
    *iret = 0;

    gflnum = *iflno - 1;

    for ( jj = 0; jj < common[gflnum].numfhdrs; jj++ ) {
	if ( strcmp ( common[gflnum].fhdrs[jj].name, fhdnam ) == 0 ) {
	    strcpy ( model, common[gflnum].fhdrs[jj].dbkey );
	    strcpy ( pyfile, common[gflnum].fhdrs[jj].pyfile );
	    strcpy ( pymeth, common[gflnum].fhdrs[jj].pymeth );
	    cst_inch ( common[gflnum].fhdrs[jj].length, arrlen, &ier );
	}
    }

    /* Set the arguments for input to the request script */
    danarg = 4;
    daargs = (char **) malloc ( danarg * sizeof(char *) );
    for ( ii = 0; ii < danarg; ii++ ) {
	daargs[ii] = (char *) malloc ( STRSIZE * sizeof(char) );
    }
    ii = 0;
    strcpy ( daargs[ii], common[gflnum].dbserver );	ii++;
    strcpy ( daargs[ii], common[gflnum].dbtable );	ii++;
    strcpy ( daargs[ii], model );		ii++;
    strcpy ( daargs[ii], arrlen );		ii++;

    /* Get the header data */
    /* Run the Python script to make the actual request */
    datype = DAFLOAT;
    da_runpy ( pyfile, pymeth, &ier );

    /* Assign the output array of floats */
    for ( ii = 0; ii < danumf; ii++ ) {
	rheadr[ii] = daoutf[ii];
    }
    *nword = danumf;

    /* If this is a grid navigation, save the number of points */
    if ( strcmp ( fhdnam, "NAVB" ) == 0 ) {
	dacmn.nx = rheadr[4];
	dacmn.ny = rheadr[5];
    }

    /* Free all allocated memory */
    for ( ii = 0 ; ii < danarg; ii++ ) {
	free ( daargs[ii] );
    }
    free ( daargs );
    free ( daoutf );
}
Beispiel #8
0
void dc_dlog ( char *messag, int *lenm, int *iret )
/************************************************************************
 * dc_dlog								*
 *									*
 * This routine opens the decoder log file, writes the given message	*
 * and closes the file.							*
 *									*
 * dc_dlog  ( messag, lenm, iret )					*
 *									*
 * Input parameters:							*
 *	*messag		char		Message to write to the log	*
 *	*lenm		int		Number of chars in the message	*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					   0 = normal return		*
 *					  -2 = error writing to log	*
 *									*
 **									*
 * Log:									*
 * S. Jacobs/NMC	 7/95						*
 * S. Jacobs/NCEP	 6/96	Updated documentation; Removed check	*
 *				for log file not opened; Changed to use	*
 *				a FILE stream with CFL_WRIT		*
 * S. Jacobs/NCEP	 7/96	Added open and close of log file	*
 * K. Tyle/GSC		 1/97	Remove prog. name and dattim; remove	*
 *				loglev variable				*
 * S. Jacobs/NCEP	 2/01	Removed all references to ulog		*
 ***********************************************************************/
{

	char	mesg[DCMXLN+8], tstr[12];
	int	lens, ier;

	FILE	*fplog;

/*---------------------------------------------------------------------*/
	*iret = 0;

/*
**	Start the output message with the process ID.
*/
	cst_inch ( ipid, tstr, &ier );
	strcpy ( mesg, "[" );
	strcat ( mesg, tstr );
	strcat ( mesg, "] " );

/*
**	Concatenate the input message to the output string.
*/
	strcat ( mesg, messag );
	cst_lstr ( mesg, &lens, &ier );

/*
**	Get the length of the message and add a Line Feed and
**	a NULL to the end.
*/
	if  ( lens > (DCMXLN+8) - 2 ) {
	    mesg [lens-1] = CHLF;
	    mesg [lens]   = CHNULL;
	}
	else {
	    mesg [lens]   = CHLF;
	    mesg [++lens] = CHNULL;
	}

/*
**	Open the decoder log file.
*/
	fplog = NULL;
	if  ( dcdlog[0] == '-' )
	{
/*
**	    If the file name is "-", open standard error for logging.
*/
	    fplog = stderr;
	}
	else
	{
/*
**	    Try to open the decoder log file.
*/
	    fplog = cfl_aopn ( dcdlog, &ier );
	    if  ( ier != 0 )
	    {
/*
**		If there is an error opening the file, open standard
**		error for real-time processing, otherwise write an
**		error message to the LDM log.
*/
		if  ( irltim )
		{
		    fplog = stderr;
		}
		else
		{
		    *iret = -3;
		    return;
		}
	    }
	}

/*
**	Write the message to the log file.
*/
	cfl_writ ( fplog, lens, (unsigned char *)mesg, &ier );
	if  ( ier != 0 ) {
	    *iret = -2;
	}

/*
**	Close the decoder log file.
*/
	if  ( fplog == stderr )
	{
/*
**	    If standard error is being used for logging, do nothing.
*/
	}
	else if ( fplog != NULL )
	{
/*
**	    Otherwise, close the log file.
*/
	    cfl_clos ( fplog, &ier );
	}

}
Beispiel #9
0
void vfwsel ( char strin[], int *iret )
/************************************************************************
 * vfwsel                                                               *
 *                                                                      *
 * This program opens, creates and closes the Weather Watch SEL text    *
 * product file.					                *
 *                                                                      *
 * vfwsel ( strin, iret )                                      		*
 *                                                                      *
 * Input parameters:                                                    *
 * 	strin[]		char		Continuing Watches String	*
 *									*
 * Output parameters:                                                   *
 *      *iret            int            Return Code                     *
 *                                                                      *
 **                                                                     *
 * Log:                                                                 *
 * A. Hardy/GSC          8/99   Created                                 *
 * A. Hardy/GSC          9/99   Changed truncation method for lats/lons *
 * M. Li/GSC		10/99	Added two more arguments to clo_cmpwds	*
 * M. Li/GSC		10/99	Modified output format			*
 * A. Hardy/GSC         11/99   Added ongoing/replacement statements;   *
 *                              Cleaned up line lengths                 *
 * A. Hardy/GSC		 2/00   Extracted from SPCTXT                   *
 * A. Hardy/GSC		 3/00   Removed \r\n after lightning.Fixed lens.*
 * A. Hardy/GSC		 3/00   Used cst_wrap to even line lengths      *
 * A. Hardy/GSC		 5/00   Changed cfl_aopn to cfl_wopn; Use	*
 *				AWIPS/WMO header ids.;removed 'NNNN'	*
 * A. Hardy/GSC		 5/00   Added check for continue watch nos.     *
 * A. Hardy/GSC		10/00   Added ck for '0' dist. anchor points    *
 * A. Hardy/GSC		12/00   Removed '&' from iret and ti_dayw       *
 * A. Hardy/GSC		 5/01   Removed parameter 'vmin' from vfgtod	*
 * A. Hardy/SAIC	10/01   Added check for old/new WMO header flag *
 * A. Hardy/SAIC	12/01   Removed unused varible 'i'		*
 * R. Tian/SAIC		06/02	Modified to meet the SPC requirement	*
 * R. Tian/SAIC		06/02	Added 'NWS' before 'STORM PRED...'	*
 * R. Tian/SAIC         04/03   Corrected if(iret == 0) syntax error    *
 * A. Hardy/NCEP	 4/03   Fixed replacement time;removed '...'    *
 *                              fixed line length with 'EFFECTIVE' line *
 * G. Grosshans/SPC	 5/03   Add 'OCCASIONALLY' statement;fixed typo *
 * A. Hardy/NCEP	 5/03	Change hail size to string for decimals *
 * A. Hardy/NCEP	11/03	Modified to use wbc/utl libraries; and  *
 *				to check if 'TEST' watch		*
 * G. Grosshans/SPC	 3/04	Removed extra EOLs before and after	*
 *				OTHER WATCH section			*
 * A. Hardy/NCEP        10/04   Corrected replace. wtch ck 1000->10000  *
 * G. Grosshans/SPC	10/04	Added ADD_WATCH_APPROX check		*
 * A. Hardy/NCEP         3/05   Added irmzn to wbc_dsts call seq.	*
 * G. Grosshans/SPC	10/05	Added LATLON_SAW_FORMAT tag to turn	*
 *				off lat-lon info at bottom of product.	*
 * T. Piper/SAIC	12/05	Updated for cst_wrap CSC		*
 * J. Wu/SAIC		04/06	Added parameter in cst_wrap 		*
 * H. Zeng/SAIC		06/06	Removed MIDNIGHT processing(fix wch#281)*
 ***********************************************************************/
{
    FILE    *ifpsel;
    char    ifname[256], chmon[4], chdwk[4], iampm[3], vampm[3];
    char    blank[2]={' '}, words1[16], words2[16], *arrch; 
    char    cname1[32], cname2[32], eampm[3];
    char    chnum[5], lclzn[4], avnstr[500], constr[500], perstr[180];
    char    tmpsel[500], holdsel[200], selstr[100], newname[132],
            efen[12], efst[12], stzstr[500], sttstr[500], hdlstr[180],
	    stlst[256], hailstr[4];
    char    prefs_tag[20];
    int     ier, time, datwk, inewtm, vnewtm, enewtm; 
    int     itmarr[5], iarr[5],etime[5], earr[5], vtime[5], varr[5]; 
    int     j, ipos, iin, iout, ireplace, newnum, irplen;
    int     len, leng, lenc, lenp, lena, len1, len2, irmzn;
    Boolean useln;
/*-------------------------------------------------------------------*/
    ier = 0;
    inewtm = 0;
    vnewtm = 0;
    enewtm = 0;
    ireplace = 0;
   /*
    *  Create output file for appending.
    */

    sprintf ( ifname, "WW%04d.SEL", spcinfo.wnum );
    ifpsel = cfl_wopn ( ifname, &ier );

   /*
    * Set up state zones and state name information.
    */

    irmzn = 1;
    len1 = sizeof ( stzstr );
    len2 = sizeof ( sttstr );
    strcpy (stlst, spcinfo.states);
    wbc_dsts ( stlst, &len1, &irmzn, stzstr, sttstr, &ier );

    spcinfo.sssnum = spcinfo.wnum % 10;
    fprintf ( ifpsel, "WWUS20 KWNS %02d%s\n", spcinfo.itime.day,
                                           spcinfo.itime.hour);
    fprintf( ifpsel, "SEL%d\n", spcinfo.sssnum);
    fprintf ( ifpsel, "%cSPC WW %02d%s\n", CHRS, spcinfo.itime.day,
                                       spcinfo.itime.hour);
    fprintf ( ifpsel, "%s-%02d%s-\n\n",
                      stzstr, spcinfo.etime.day, spcinfo.etime.hour );
   /*
    * Set up urgent section.
    */

    hdlstr[0] = '\0';
    len = sizeof ( hdlstr );
    wbc_dhdl ( spcinfo.wtype, spcinfo.status, &(spcinfo.wnum), len, hdlstr, &ier );
    strcat (hdlstr, EOL );
    fprintf ( ifpsel, hdlstr );

   /*
    * Getting all of the information to create the the time line string.
    */

    time  = atoi(spcinfo.itime.hour);
    itmarr[0] = spcinfo.itime.year;
    itmarr[1] = spcinfo.itime.month;
    itmarr[2] = spcinfo.itime.day;
    itmarr[3] = time / 100;
    itmarr[4] = time % 100;

    time     = atoi(spcinfo.vtime.hour);
    vtime[0] = spcinfo.vtime.year;
    vtime[1] = spcinfo.vtime.month;
    vtime[2] = spcinfo.vtime.day;
    vtime[3] = time / 100;
    vtime[4] = time % 100;

    time     = atoi(spcinfo.etime.hour);
    etime[0] = spcinfo.etime.year;
    etime[1] = spcinfo.etime.month;
    etime[2] = spcinfo.etime.day;
    etime[3] = time / 100;
    etime[4] = time % 100;

    strcpy ( lclzn, spcinfo.timzone );
    utl_ivet ( lclzn, itmarr, vtime, etime, iarr, &inewtm,
               iampm, chmon, chdwk, varr, &vnewtm, vampm,
               earr, &enewtm, eampm, &datwk, &ier );
  
    fprintf ( ifpsel, "%d%02d %s %s %s %s %d %d\n\n", inewtm, iarr[4], 
	      iampm, spcinfo.timzone, chdwk, chmon, iarr[2], iarr[0]);
   
			 
   /*
    * Set up general area description section.
    * Check status of watch.
    */

    if ( strcmp(spcinfo.status, "TEST") == 0 ) {
        fprintf ( ifpsel, "THE NWS STORM PREDICTION CENTER HAS ISSUED ");
        fprintf ( ifpsel, "A...TEST...\n ");
    }
    else {
        fprintf ( ifpsel, "THE NWS STORM PREDICTION CENTER HAS ISSUED A\n");
    }
    fprintf ( ifpsel, "%s WATCH FOR PORTIONS OF \n", spcinfo.wtype );
    fprintf ( ifpsel, sttstr);
    fprintf ( ifpsel, "\n\n");

   /*
    * Get the general time of day string.
    */

    leng = sizeof ( spcinfo.genday );
    utl_gtod ( vnewtm, enewtm, earr[4], vampm, eampm, datwk, leng, 
             spcinfo.genday, &ier);

   /*
    * Set up effective time of day string.
    */

    len1 = sizeof ( efst );
    len2 = sizeof ( efen );
    wbc_defl ( vnewtm, varr[4], vampm, enewtm, earr[4], eampm,
               spcinfo.timzone, len1, len2, efst, efen, &ier );

    len = LINE_LEN;
    tmpsel[0] = '\0';
    sprintf ( tmpsel, "EFFECTIVE THIS%s FROM %s UNTIL %s.",
              spcinfo.genday, efst, efen );

    strcat (tmpsel, EOL );
    strcat (tmpsel, EOL );
    len = LINE_LEN;
    cst_wrap ( tmpsel, blank, &len, EOL, (char *)NULL, tmpsel, &ier );
    fprintf ( ifpsel, tmpsel);

   /*
    * Add some phases if the watch is a 'PDS'
    */

    if ( strcmp ( spcinfo.pdsn,"PDS" ) == 0 )
        fprintf ( ifpsel, "...THIS IS A PARTICULARLY DANGEROUS SITUATION...\n\n"); 

   /*
    * Change hail size to string.
    */

    if ( ( (int) (spcinfo.hailsz * 10.0F) % 2) == 0 ) {
	sprintf( hailstr, "%1.*f", 0, spcinfo.hailsz );
    }
    else {
	sprintf( hailstr, "%3.*f", 1, spcinfo.hailsz );
    }

   /*
    * Set up hail, wind gusts and lightning section.
    */

    if ( strcmp(spcinfo.wtype,"TORNADO") == 0 ) {
        if ( strcmp(spcinfo.pdsn, "PDS") == 0 ) {
            tmpsel[0] = '\0'; 
            holdsel[0] = '\0'; 
            sprintf ( tmpsel, "DESTRUCTIVE TORNADOES...");
            if ( G_DIFF(spcinfo.hailsz, 0.0F) ){ 
	        sprintf ( holdsel, "THUNDERSTORM WIND GUSTS TO %d MPH", spcinfo.maxmph );
		strcat(tmpsel, holdsel);
	    }
            else if ( (spcinfo.hailsz > 0.0F ) && (spcinfo.hailsz <= 1.0F ) ) {
                sprintf ( holdsel, "LARGE HAIL TO %s INCH ", hailstr );
		strcat(tmpsel, holdsel);
	        sprintf ( holdsel, "IN DIAMETER... THUNDERSTORM WIND GUSTS TO %d MPH", spcinfo.maxmph );
		strcat(tmpsel, holdsel);
	    }
            else if ( spcinfo.hailsz > 1.0F ){
                sprintf ( holdsel, "LARGE HAIL TO %s INCHES ", hailstr );
		strcat(tmpsel, holdsel);
	        sprintf ( holdsel, "IN DIAMETER... THUNDERSTORM WIND GUSTS TO %d MPH", spcinfo.maxmph );
		strcat(tmpsel, holdsel);
	    }
            sprintf ( holdsel,  "...AND DANGEROUS LIGHTNING ARE POSSIBLE IN THESE AREAS.");
	    strcat(tmpsel, holdsel);
            strcat (tmpsel, EOL );
            strcat (tmpsel, EOL );
            len = LINE_LEN;
            cst_wrap ( tmpsel, blank, &len, EOL, (char *)NULL, tmpsel, &ier );
            fprintf ( ifpsel, tmpsel);
	}
        else {
            tmpsel[0] = '\0'; 
            holdsel[0] = '\0'; 
            sprintf ( tmpsel, "TORNADOES...");

            if ( G_DIFF(spcinfo.hailsz,0.0F) ) {
                sprintf ( holdsel, "THUNDERSTORM WIND GUSTS TO %d MPH...AND DANGEROUS LIGHTNING ", 
                          spcinfo.maxmph);
		strcat(tmpsel, holdsel);
	    }
            
            else if ( ( spcinfo.hailsz > 0.0F ) && ( spcinfo.hailsz <= 1.0F ) ) {
                sprintf ( holdsel, "HAIL TO %s INCH IN DIAMETER...THUNDERSTORM WIND ",
                          hailstr);
		strcat(tmpsel, holdsel);
                sprintf ( holdsel, "GUSTS TO %d MPH...AND DANGEROUS LIGHTNING ", spcinfo.maxmph);
		strcat(tmpsel, holdsel);
            }      
            else {
                sprintf ( holdsel, "HAIL TO %s INCHES IN DIAMETER...THUNDERSTORM WIND ",
                          hailstr);
		strcat(tmpsel, holdsel);
                sprintf ( holdsel, "GUSTS TO %d MPH...AND DANGEROUS LIGHTNING ", spcinfo.maxmph);
		strcat(tmpsel, holdsel);
            }
            sprintf ( holdsel, "ARE POSSIBLE IN THESE AREAS.");
	    strcat(tmpsel, holdsel);
            strcat (tmpsel, EOL );
            strcat (tmpsel, EOL );
            len = LINE_LEN;
            cst_wrap ( tmpsel, blank, &len, EOL, (char *)NULL, tmpsel, &ier );
            fprintf ( ifpsel, tmpsel);
        }
    }

    if ( strcmp(spcinfo.wtype,"SEVERE THUNDERSTORM") == 0 ) {
        if ( strcmp(spcinfo.pdsn, "PDS") == 0 ) {
            tmpsel[0] = '\0'; 
            holdsel[0] = '\0'; 
            sprintf ( tmpsel, "EXTREMELY DAMAGING THUNDERSTORM WIND GUSTS TO %d ", spcinfo.maxmph );
            if ( ( spcinfo.hailsz > 0.0F ) && ( spcinfo.hailsz <= 1.0F ) )  {
                sprintf ( holdsel, "MPH...LARGE HAIL TO %s INCH IN DIAMETER...", hailstr);
		strcat(tmpsel, holdsel);
	    }
            if ( spcinfo.hailsz > 1.0F ) { 
                sprintf ( holdsel, "MPH...LARGE HAIL TO %s INCHES IN DIAMETER...", hailstr);
		strcat(tmpsel, holdsel);
	    }
            sprintf ( holdsel, "AND DANGEROUS LIGHTNING ARE POSSIBLE IN THESE AREAS.");
	    strcat(tmpsel, holdsel);
            strcat (tmpsel, EOL );
            strcat (tmpsel, EOL );
            len = LINE_LEN;
            cst_wrap ( tmpsel, blank, &len, EOL, (char *)NULL, tmpsel, &ier );
            fprintf ( ifpsel, tmpsel);

        }
        else {
            tmpsel[0] = '\0'; 
            holdsel[0] = '\0'; 
            if ( G_DIFF(spcinfo.hailsz,0.0F) ) {
                sprintf ( tmpsel, "THUNDERSTORM WIND GUSTS TO %d MPH...",spcinfo.maxmph);
		strcat(tmpsel, holdsel);
	    }
            else if ( ( spcinfo.hailsz > 0.0F ) && (spcinfo.hailsz <= 1.0F ) ) {
                sprintf ( holdsel, "HAIL TO %s INCH IN DIAMETER...THUNDERSTORM WIND ",
                          hailstr);
		strcat(tmpsel, holdsel);
                sprintf ( holdsel, "GUSTS TO %d MPH...", spcinfo.maxmph);
		strcat(tmpsel, holdsel);
            }      
            else if ( spcinfo.hailsz > 1.0F ) {
                sprintf ( holdsel, "HAIL TO %s INCHES IN DIAMETER...THUNDERSTORM WIND ",
                          hailstr);
		strcat(tmpsel, holdsel);
                sprintf ( holdsel, "GUSTS TO %d MPH...", spcinfo.maxmph);
		strcat(tmpsel, holdsel);
            }        
            sprintf ( holdsel, "AND DANGEROUS LIGHTNING ARE POSSIBLE IN THESE AREAS.");
	    strcat(tmpsel, holdsel);
            strcat (tmpsel, EOL );
            strcat (tmpsel, EOL );
            len = LINE_LEN;
            cst_wrap ( tmpsel, blank, &len, EOL, (char *)NULL, tmpsel, &ier );
            fprintf ( ifpsel, tmpsel);
        }
    }

   /*
    * Set watch area section.
    */

    clo_cmpwds ( spcinfo.ancrpt.dirct1, &iin, words1, &iout, &ier );
    clo_cmpwds ( spcinfo.ancrpt.dirct2, &iin, words2, &iout, &ier );

    utl_gname ( spcinfo.ancrpt.stn1, spcinfo.ancrpt.stnnam1, 
		spcinfo.ancrpt.stateid1, &ier );
    utl_gname ( spcinfo.ancrpt.stn2, spcinfo.ancrpt.stnnam2, 
		spcinfo.ancrpt.stateid2, &ier );

    tb_idst ( spcinfo.ancrpt.stateid1, spcinfo.ancrpt.statnm1, &ier,
              strlen ( spcinfo.ancrpt.stateid1), sizeof(spcinfo.ancrpt.statnm1));
    tb_idst ( spcinfo.ancrpt.stateid2, spcinfo.ancrpt.statnm2, &ier,
              strlen ( spcinfo.ancrpt.stateid2), sizeof(spcinfo.ancrpt.statnm2));

    cst_rnan ( spcinfo.ancrpt.stnnam1, cname1, &ier );
    cst_rmst ( cname1, ".", &ipos, cname1, &ier );
    cst_rnan ( spcinfo.ancrpt.stnnam2, cname2, &ier );
    cst_rmst ( cname2, ".", &ipos, cname2, &ier );

   /*
    * Set up the watch area lines.
    */

    tmpsel[0] = '\0'; 
    holdsel[0] = '\0'; 

   /*
    * Check status of watch and also check if the APPROXIMATE verbage 
    * needs to be included in the text.
    */
    strcpy (prefs_tag, "ADD_WATCH_APPROX");
    ctb_pfbool (prefs_tag, &useln, &ier );
    if ( useln == TRUE ) {
       if (strcmp (spcinfo.status, "TEST") == 0 ) {
           sprintf ( tmpsel, "THE TEST %s WATCH AREA IS APPROXIMATELY ALONG AND %d STATUTE MILES ", 
                     spcinfo.wtype, spcinfo.ancatt.dist);
       }
       else {
           sprintf ( tmpsel, "THE %s WATCH AREA IS APPROXIMATELY ALONG AND %d STATUTE MILES ", 
                     spcinfo.wtype, spcinfo.ancatt.dist);
            }
    }
    else {
        if (strcmp (spcinfo.status, "TEST") == 0 ) {
            sprintf ( tmpsel, "THE TEST %s WATCH AREA IS ALONG AND %d STATUTE MILES ", 
                  spcinfo.wtype, spcinfo.ancatt.dist);
        }
        else {
            sprintf ( tmpsel, "THE %s WATCH AREA IS ALONG AND %d STATUTE MILES ", 
                  spcinfo.wtype, spcinfo.ancatt.dist);
        }
    }

    if ( (spcinfo.ancrpt.dist1 > 0 ) && ( spcinfo.ancrpt.dist2 > 0 ) ){
        sprintf ( holdsel, "%s OF A LINE FROM %d MILES %s OF %s %s",
                  spcinfo.ancatt.dirc, spcinfo.ancrpt.dist1, words1,
                  cname1, spcinfo.ancrpt.statnm1);
        strcat(tmpsel, holdsel);
        sprintf ( holdsel, " TO %d MILES %s OF %s %s.",
                  spcinfo.ancrpt.dist2, words2, cname2, 
		  spcinfo.ancrpt.statnm2);
    }
    else if ( (spcinfo.ancrpt.dist1 <= 0 ) && ( spcinfo.ancrpt.dist2 > 0 ) ){
        sprintf ( holdsel, "%s OF A LINE FROM %s %s",
                  spcinfo.ancatt.dirc, cname1, spcinfo.ancrpt.statnm1);
        strcat(tmpsel, holdsel);
        sprintf ( holdsel, " TO %d MILES %s OF %s %s.",
                  spcinfo.ancrpt.dist2, words2, cname2, 
		  spcinfo.ancrpt.statnm2);
    }
    else if ( (spcinfo.ancrpt.dist1 > 0 ) && ( spcinfo.ancrpt.dist2 <= 0 ) ){
        sprintf ( holdsel, "%s OF A LINE FROM %d MILES %s OF %s %s",
                  spcinfo.ancatt.dirc, spcinfo.ancrpt.dist1, words1,
                  cname1, spcinfo.ancrpt.statnm1);
        strcat(tmpsel, holdsel);
        sprintf ( holdsel, " TO %s %s.", cname2, spcinfo.ancrpt.statnm2);
    }
    else if ( (spcinfo.ancrpt.dist1 <= 0 ) && ( spcinfo.ancrpt.dist2 <= 0 ) ){
        sprintf ( holdsel, "%s OF A LINE FROM %s %s",
                  spcinfo.ancatt.dirc, cname1, spcinfo.ancrpt.statnm1);
        strcat(tmpsel, holdsel);
        sprintf ( holdsel, " TO %s %s.", cname2, spcinfo.ancrpt.statnm2);
    }
    strcat(tmpsel, holdsel);
    if ( useln == TRUE ) {
        sprintf (holdsel, "  FOR A COMPLETE DEPICTION OF THE WATCH SEE THE ");
        strcat(tmpsel, holdsel);
	sprintf (holdsel, "ASSOCIATED WATCH OUTLINE UPDATE (WOUS64 KWNS WOU%d).", spcinfo.sssnum);
        strcat(tmpsel, holdsel);
    }

    strcat (tmpsel, EOL );
    strcat (tmpsel, EOL );
    len = LINE_LEN;
    cst_wrap ( tmpsel, blank, &len, EOL, (char *)NULL, tmpsel, &ier );
    fprintf ( ifpsel, tmpsel);

   /*
    * Set up watch explanation section.
    */

    tmpsel[0] = '\0'; 
    lenc = sizeof ( constr );
    lenp = sizeof ( perstr );
    wbc_dcon ( spcinfo.wtype, lenc, lenp, constr, perstr, &ier );

    strcat ( tmpsel, "REMEMBER..."); 

    strcat ( tmpsel, constr );
    strcat ( tmpsel, perstr );

    if ( strcmp(spcinfo.wtype,"SEVERE THUNDERSTORM") == 0 ){
      strcat ( tmpsel, " SEVERE THUNDERSTORMS CAN AND OCCASIONALLY DO ");
      strcat ( tmpsel, "PRODUCE TORNADOES.");
    }

    strcat (tmpsel, EOL );
    len = LINE_LEN;
    cst_wrap ( tmpsel, blank, &len, EOL, (char *)NULL, tmpsel, &ier );
    fprintf ( ifpsel, tmpsel);
    
   /*
    * Check for ongoing and replacement watches.
    */

    tmpsel[0] = '\0'; 
    holdsel[0] = '\0'; 
    if ( strcmp ( spcinfo.replcnm[0], "NONE") != 0 ) {
	strcat (tmpsel, EOL);
        strcat ( tmpsel, "OTHER WATCH INFORMATION...");

       /*
        *  If there are replacement watches listed, retrieve the type
        *  for each replacement watch.
        */

        if ( strcmp ( spcinfo.replcnm[0], "NONE") != 0 ) {
            strcpy ( newname, "ww");
            strcat ( newname, spcinfo.replcnm[0] );
            strcat ( newname, ".txt" );
            strcpy ( newinfo.file_info.filnam,newname);
            vfrptxt (newname, iret);
            if ( *iret == 0 ){
                sprintf ( holdsel, "THIS %s WATCH REPLACES %s WATCH NUMBER %d.",
	                  spcinfo.wtype, newinfo.wtype, atoi(spcinfo.replcnm[0]) ); 
                strcat (tmpsel, holdsel );
            }
        }

       /*
        *  If there are more that 1 replacement watches listed,
        *  proceed with the loop.
        */
        if ( spcinfo.wwrepnm >= 1 ){
            for(j = 1; j <= spcinfo.wwrepnm; j++) {
                strcpy ( newname, "ww");
                strcat ( newname, spcinfo.replcnm[j] );
                strcat ( newname, ".txt" );
                strcpy ( newinfo.file_info.filnam,newname);
                vfrptxt (newname, iret);
                if ( *iret == 0 ){
	            sprintf ( holdsel, "..%s WATCH NUMBER %d.",
	                   newinfo.wtype, atoi(spcinfo.replcnm[j]) );
                    strcat (tmpsel, holdsel );
                }
	    }
        }

        sprintf ( holdsel, " WATCH NUMBER ");
        strcat (tmpsel, holdsel );
        for(j = 0; j <= spcinfo.wwrepnm; j++) {
            strcpy ( newname, "ww");
            strcat ( newname, spcinfo.replcnm[j] );
            strcat ( newname, ".txt" );
            strcpy ( newinfo.file_info.filnam,newname);
            vfrptxt (newname, iret);
            if ( *iret == 0 ){
                sprintf ( holdsel, "%d ", atoi(spcinfo.replcnm[j]) ) ; 
                strcat (tmpsel, holdsel );
	    }
	}

       /*
        * Set cancellation time with the replacement watch's valid time.
        */

        strcat ( tmpsel, "WILL NOT BE IN EFFECT AFTER " );
        if ( (vnewtm == 12) && (varr[4] ==0) && (strcmp(vampm, "AM") == 0) ) {
            sprintf ( holdsel, "MIDNIGHT %s. ", spcinfo.timzone );
            strcat (tmpsel, holdsel );
	}
        else if ( (vnewtm == 12) && (varr[4] ==0) && (strcmp(vampm, "PM") == 0) ) {
            sprintf ( holdsel, "NOON %s. ", spcinfo.timzone );
            strcat (tmpsel, holdsel );
	}
        else {
            sprintf ( holdsel, "%d%02d %s %s. ", vnewtm, varr[4], vampm, 
	              spcinfo.timzone );
            strcat (tmpsel, holdsel );
	}
	ireplace = 1;
    }

    cst_lstr ( strin, &irplen, iret );
    strcpy ( selstr, strin);
    if ( irplen > 0 ) {
        holdsel[0] = '\0'; 
        if ( ireplace != 1 ) {
            strcat (tmpsel, EOL);
	    strcat( tmpsel, "OTHER WATCH INFORMATION...");
	}
        strcat ( tmpsel, "CONTINUE...");
        arrch = strtok( selstr, " " );
	while ( arrch != NULL ) {
	    newnum = atoi(arrch);
	    if ( (newnum > 0 ) && ( newnum < 10000 ) ) {
	        strcat ( tmpsel,"WW ");
	        cst_inch ( newnum, chnum, iret);
	        strcat ( tmpsel, chnum);
	        strcat ( tmpsel, "...");
	    }
	    arrch = strtok( NULL," " );
	}
    strcat (tmpsel, EOL);
    }

    if (( ireplace == 1 ) && ( irplen < 1 )) {
    strcat (tmpsel, EOL);
    }
    cst_wrap ( tmpsel, blank, &len, EOL, (char *)NULL, tmpsel, &ier );
    fprintf ( ifpsel, tmpsel);

   /*
    * Check status of watch.
    */

    if (strcmp (spcinfo.status, "TEST") == 0 ) {
        fprintf ( ifpsel, "\nDISCUSSION...THIS IS A TEST...");
        fprintf ( ifpsel, "THIS IS A TEST...\n\n");
    }
    else {
        fprintf ( ifpsel, "\nDISCUSSION...\n\n");
    }

   /*
    * Create the aviation string.
    */

    lena = sizeof ( avnstr );
    wbc_davn ( spcinfo.wtype, &(spcinfo.hailsz), &(spcinfo.maxgust),
               &(spcinfo.maxtops), &(spcinfo.motion.deg), 
	       &(spcinfo.motion.speed), lena, avnstr, &ier );

    strcat (avnstr, EOL );
    strcat (avnstr, EOL );
    strcat (avnstr, EOL );
    len = LINE_LEN;
    cst_wrap ( avnstr, blank, &len, EOL, (char *)NULL, avnstr, &ier );
    fprintf ( ifpsel, avnstr);

   /*
    * Print out forecaster's name.
    */

    fprintf ( ifpsel, "...%s\n\n",spcinfo.frcstr);

   /*
    *  Get the value for LATLON_SAW_FORMAT flag from the prefs.tbl
    *  If FALSE then its before February 2006 and the less
    *  precise lat-lon data is retained in the SEL.  When this
    *  is TRUE then more precise lat-lon data will be located 
    *  in the SAW product.
    */
    strcpy (prefs_tag, "LATLON_SAW_FORMAT");
    ctb_pfbool (prefs_tag, &useln, &ier );
    if ( useln == FALSE ) {

        /* 
         * Converting hundreths into minutes.
         */

         utl_tomin ( &(spcinfo.wcpnt1.lat),  &(spcinfo.wcpnt1.lon), 
       		&(spcinfo.wcpnt1.newlat),  &(spcinfo.wcpnt1.newlon), iret );
         utl_tomin ( &(spcinfo.wcpnt2.lat),  &(spcinfo.wcpnt2.lon), 
   		&(spcinfo.wcpnt2.newlat),  &(spcinfo.wcpnt2.newlon), iret );
         utl_tomin ( &(spcinfo.wcpnt3.lat),  &(spcinfo.wcpnt3.lon), 
    		&(spcinfo.wcpnt3.newlat),  &(spcinfo.wcpnt3.newlon), iret );
         utl_tomin ( &(spcinfo.wcpnt4.lat),  &(spcinfo.wcpnt4.lon), 
   		&(spcinfo.wcpnt4.newlat),  &(spcinfo.wcpnt4.newlon), iret );

       /*
        *  The statement below will truncate the minutes at the 10's position.
        *  No rounding takes place.
        */

        fprintf ( ifpsel, ";%d,%04d %d,%04d %d,%04d %d,%04d; \n\n",
            (int)(spcinfo.wcpnt1.newlat*10.0F), (int)(spcinfo.wcpnt1.newlon*10.0F),
            (int)(spcinfo.wcpnt2.newlat*10.0F), (int)(spcinfo.wcpnt2.newlon*10.0F),
            (int)(spcinfo.wcpnt3.newlat*10.0F), (int)(spcinfo.wcpnt3.newlon*10.0F),
            (int)(spcinfo.wcpnt4.newlat*10.0F), (int)(spcinfo.wcpnt4.newlon*10.0F));
    }

   /*
    *  Close output file.
    */

    cfl_clos ( ifpsel, &ier );
}