Ejemplo n.º 1
0
void pd_sped ( const float *uwnd, const float *vwnd, const int *np,
               float *sped, int *iret )
/************************************************************************
 * pd_sped 								*
 *									*
 * This subroutine computes SPED from UWND and VWND.  The following	*
 * equation is used:				 			*
 * 									*
 *          SPED = SQRT ( (UWND**2) + (VWND**2) )			*
 *									*
 * pd_sped ( uwnd, vwnd, np, sped, iret )				*
 *									*
 * Input parameters:							*
 *	*uwnd		const float	U component			*
 *	*vwnd		const float	V component			*
 *	*np		const int	Number of points		*
 *									*
 * Output parameters:							*
 *	*sped		float		Wind speed 			*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 * Log:									*
 * M. desJardins/GSFC	 7/89	GEMPAK 5				*
 * K. Brill/HPC		11/02	Remove SUBFLG input logical array	*
 * R. Tian/SAIC		 9/05	Translated from FORTRAN			*
 ************************************************************************/
{
    float uuu, vvv;
    int npt, i;
/*----------------------------------------------------------------------*/
    *iret = 0;
    npt = *np;

    /*
     * Loop through all the points.
     */
    for ( i = 0; i < npt; i++ ) {
        uuu = uwnd [i];
        vvv = vwnd [i];

  	/*
	 * Check for missing data.
	 */
        if ( ERMISS ( uuu ) || ERMISS ( vvv ) ) {
	    sped [i] = RMISSD;
	} else {
	    sped [i] = sqrt ( uuu * uuu + vvv * vvv );
	}
    }

    return;
}
Ejemplo n.º 2
0
void pd_totl ( const float *t850, const float *td850, const float *t500,
               const int *np, float *totl, int *iret )
/************************************************************************
 * pd_totl                                                              *
 *                                                                      *
 * This subroutine computes TOTL from t850, td850, and t500.		*
 * The following equation is used:                                      *
 *                                                                      *
 *	TOTL = the total totals index					*
 *	     = (t850 - t500) + (td850 - t500)				*
 *                                                                      *
 * pd_totll( t850, td850, t500, np, totl, iret )			*
 *                                                                      *
 * Input parameters:                                                    *
 *      *t850		const float	850 mb temperature in Celsius   *
 *      *td850		const float	850 mb dewpoint in Celsius      *
 *      *t500		const float	500 mb temperature in Celsius   *
 *      *np             const int	Number of points                *
 *                                                                      *
 * Output parameters:                                                   *
 *      *totl		float		The Total Totals Index 		*
 *      *iret           int		Return code                     *
 *                                        0 = normal return             *
 **                                                                     *
 * Log:                                                                 *
 * D. Keiser/GSC        7/95                                            *
 * K. Brill/HPC		11/02	Remove SUBFLG input logical array	*
 * R. Tian/SAIC		 9/05	Translated from FORTRAN			*
 ************************************************************************/
{
    int npt, i;
/*----------------------------------------------------------------------*/
    *iret = 0;
    npt = *np;

    /*
     * Loop through all the points.
     */
    for ( i = 0; i < npt; i++ ) {
	/*
	 * Check for missing data.
	 */
	if ( ( ERMISS ( t850 [i] ) ) || ( ERMISS ( td850 [i] ) ) ||
             ( ERMISS ( t500 [i] ) ) ) {
	    totl [i] = RMISSD;
	} else {
	    /*
	     * Find the total totals index.
	     */
	    totl [i] = ( t850 [i] - t500 [i] ) + ( td850 [i] - t500 [i] );
	}
    }
}
Ejemplo n.º 3
0
void pd_shmr ( const float *spfh, const int *np, float *mixr, int *iret )
/************************************************************************
 * pd_shmr								*
 *									*
 * This subroutine computes MIXR from SPFH.  The following equation is	*
 * used:								*
 *									*
 *         MIXR = SPFC / ( 1 - SPFH ) .					*
 *									*
 * pd_shmr ( spfh, np, mixr, iret )					*
 *									*
 * Input parameters:							*
 *	*spfh		const float	Specific humidity in g/g	*
 *	*np		const int	Number of points		*
 *									*
 * Output parameters:							*
 *	*mixr		float		Mixing ratio in g/g		*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 * Log:									*
 * J. Whistler/SSAI	 5/91						*
 * K. Brill/HPC		11/02	Remove SUBFLG input logical array	*
 * R. Tian/SAIC		 9/05	Translated from FORTRAN			*
 ************************************************************************/
{
    int npt, i;
/*----------------------------------------------------------------------*/
    *iret = 0;
    npt = *np;

    /*
     * Loop through all the points.
     */
    for ( i = 0; i < npt; i++ ) {
	/*
	 * Check for missing data.
	 */
	if ( ERMISS ( spfh [i] ) ) {
	    mixr [i] = RMISSD;
	} else {
	    /*
	     * Calculate mixing ratio.
	     */
	    mixr [i] = spfh [i] / ( 1.0F - spfh [i] );
	}
    }

    return;
}
Ejemplo n.º 4
0
void pd_knms ( const float *sknt, const int *np, float *sped, int *iret )
/************************************************************************
 * pd_knms								*
 *									*
 * This subroutine computes SPED from SKNT.  The following equation is	*
 * used:								*
 *									*
 *               SPED = SKNT / 1.9425					*
 *									*
 * pd_knms ( sknt, np, sped, iret )					*
 *									*
 * Input parameters:							*
 *	*sknt		const float	Speed in knots			*
 *	*np		const int	Number of points		*
 *									*
 * Output parameters:							*
 *	*sped		float		Speed in meters/second		*
 *	iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 *Log:									*
 * M. desJardins/GSFC	 7/89	GEMPAK 5				*
 * L. Sager/NCEP	 4/96	Updated value of knots to m/sec 	*
 *				conversion				*
 * K. Brill/HPC		11/02	Remove SUBFLG input logical array	*
 * R. Tian/SAIC		 9/05	Translated from FORTRAN			*
 ************************************************************************/
{
    int npt, i;
/*----------------------------------------------------------------------*/
    *iret = 0;
    npt = *np;     

    /*
     * Loop through all the points.
     */
    for ( i = 0; i < npt; i++ ) {
        /*
         * Check for missing data.
         */
        if ( ERMISS ( sknt [i] ) ) {
	    sped [i] = RMISSD;
        } else {
	    sped [i] = sknt [i] / 1.9425F;
        }
    }

    return;
}
Ejemplo n.º 5
0
void dv_def ( int *iret )
/************************************************************************
 * dv_def								*
 *									*
 * This subroutine computes the total deformation of a vector:		*
 *									*
 *     DEF ( V ) = ( STR (V) ** 2 + SHR (V) ** 2 ) ** .5		*
 *									*
 * DEF generates a scalar grid.						*
 *									*
 * dv_def ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV			*
 **									*
 * Log:									*
 * M. desJardins/GSFC	10/85						*
 * I. Graffman/RDS	 7/88	Call to DG_UPDH				*
 * G. Huffman/GSC	 9/88	New stack functions			*
 * G. Huffman/GSC	 9/88	Error messages				*
 * K. Brill/GSC		 8/89   Subsetting				*
 * K. Brill/GSC		10/89   Subsetting				*
 * T. Lee/GSC            4/96   Single dimension for dgg		*
 * T. Lee/GSC		 5/96	Moved IGDPT outside DO loop		*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEC	11/05	Translation from Fortran                *
 ************************************************************************/
{
    int             i, kxd, kyd, ksub1, ksub2, ier, zero=0;
    int		numu, numv, nstr, nshr, numout;
    float           *grstr, *grshr, *grout;
    float           dshr, dstr;
    /*------------------------------------------------------------------------*/
    *iret = 0;
    dg_ssub ( iret );

    /*
     *	Get the vector grid.
     */
    dg_getv  ( &numu, &numv, iret );
    if  ( *iret != 0 ) return;

    /*
     *	Put the vector on the stack, compute the stretching deformation,
     *	and get the result.
     */
    dg_putv  ( &numu, &numv, iret );
    if  ( *iret != 0 ) return;
    dv_str  ( iret );
    if  ( *iret != 0 ) return;
    dg_gets  ( &nstr, iret );
    if  ( *iret != 0 ) return;

    /*
     *	Put the vector on the stack, compute the shearing deformation,
     *	and get the result.
     */
    dg_putv  ( &numu, &numv, iret );
    if  ( *iret != 0 ) return;
    dv_shr  ( iret );
    if  ( *iret != 0 ) return;
    dg_gets  ( &nshr, iret );
    if  ( *iret != 0 ) return;

    /*
     *	Get a number for the deformation grid and compute DEF
     */
    dg_nxts  ( &numout, iret );
    if  ( *iret != 0 )  return;

    dg_getg ( &nshr, &grshr, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &nstr, &grstr, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &numout, &grout, &kxd, &kyd, &ksub1, &ksub2, iret );

    for ( i = ksub1 - 1; i < ksub2; i++ ) {
        dshr  =  grshr[i];
        dstr  =  grstr[i];
        if  ( ERMISS (dshr) || ERMISS (dstr) )
            grout[i] = RMISSD;
        else
            grout[i] = (float) sqrt (dshr*dshr + dstr*dstr);

    }

    /*
     *	Make a name of the form 'DEF'//u and update header;
     *	update stack.
     */
    dg_updh  ( "DEF", &numout, &numu, &zero, iret );
    dg_puts  ( &numout, iret );
    dg_esub  ( &numout, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 6
0
void df_gele ( int *iret )
/************************************************************************
 * df_gele								*
 * 									*
 * This subroutine checks if x1 is greater than or equal to x2 and	*
 * less than or equal to x3 and returns the result of comparison:	*
 *	1 if  x1 >= x2 and x1 <= x3					*
 *	0     otherwise							*
 *	RMISS if either grid is missing					*
 * 									*
 * df_gele ( iret )                                            		*
 * 									*
 * Input parameters:							*
 * 									*
 * Output parameters:							*
 *      *iret		int		Return code			*
 *					0 - normal return 		*
 **									*
 * Log:									*
 * m.gamazaychikov/SAIC	09/05						*
 * R. Tian/SAIC		11/05	Recoded from Fortran			*
 ************************************************************************/
{
    int num1, num2, num3, num, kxd, kyd, ksub1, ksub2, fidx, cidx,
        zero, ier;
    float *gnum1, *gnum2, *gnum3, *gnum, dg1, dg2, dg3;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get three grids from the stack.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num2, iret );
    if ( *iret != 0 ) return;;
    dg_gets ( &num3, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid number and check the grids.
     */
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    /*
     * Grid number to grid.
     */
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num2, &gnum2, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num3, &gnum3, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    for ( fidx = ksub1; fidx <= ksub2; fidx++ ) {
        cidx = fidx - 1;
	dg1 = gnum1[cidx];
	dg2 = gnum2[cidx];
	dg3 = gnum3[cidx];
	if ( ERMISS ( dg1 ) || ERMISS ( dg2 ) || ERMISS ( dg3 ) ) {
	    gnum[cidx] = RMISSD;
	} else {
	    if ( ( dg1 >= dg2 ) && ( dg1 <= dg3 ) ) {
		gnum[cidx] = 1.0;
	    } else {
		gnum[cidx] = 0.0;
	    }
	}
    }

    /*
     * Get a name of the form 'GELE'//S1//S2//S3 and update header;
     * update stack.
     */
    dg_updh ( "GELE", &num, &num1, &num2, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
void df_lav ( int *iret )
/************************************************************************
 * df_lav								*
 *									*
 * This subroutine computes the layer average of a scalar grid:		*
 *									*
 *     LAV (S) = [ S (level1) + S (level2) ] / 2. 			*
 *									*
 * df_lav ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * M. desJardins/GSFC	10/85						*
 * M. desJardins/GSFC	 7/88	Added new stack subroutines		*
 * G. Huffman/GSC	 9/88	Error messages				*
 * K. Brill/GSC		 8/89   Subsetting				*
 * K. Brill/GSC         10/89   Subsetting				*
 * T. Lee/GSC		 4/96	Single dimension for dgg		*
 * K. Tyle/GSC           5/96   Moved IGDPT outside do-loop             *
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * R. Tian/SAIC		10/05	Recoded from Fortran			*
 ************************************************************************/
{
    int num1, num2, num, kxd, kyd, ksub1, ksub2, zero, fidx, cidx, ier;
    float *gnum1, *gnum2, *gnum, dg1, dg2;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get the two grids.
     */
    dg_getl ( &num1, &num2, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid.
     */
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    /*
     * Grid number to grid.
     */
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num2, &gnum2, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    /*
     * Average the grids.
     */
    for ( fidx = ksub1; fidx <= ksub2; fidx++ ) {
	cidx = fidx - 1;
        dg1 = gnum1[cidx];
        dg2 = gnum2[cidx];
        if ( ERMISS (dg1) || ERMISS (dg2) ) {
	    gnum[cidx] = RMISSD;
	} else {
	    gnum[cidx] = ( dg1 + dg2 ) / 2.;
	}
    }

    /*
     * Make a name of the form 'LAV'//S and update header;
     * update stack.
     */
    dg_updh ( "LAV", &num, &num1, &num2, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 9
0
void dv_shr ( int *iret )
/************************************************************************
 * dv_shr				     				*
 *									*
 * This subroutine computes the shearing deformation of a vector:	*
 *									*
 *     SHR ( V ) = DDX ( v ) + DDY ( u ) + v * {(mx/my)*[d(my)/dx]}	*
 *					 + u * {(my/mx)*[d(mx)/dy]}	*
 *									*
 * where mx and my are scale factors along x and y, respectively.	*
 * The quantities in braces are assumed to exist in common arrays	*
 * YMSDX and XMSDY, respectively.  SHR generates a scalar grid.		*
 *									*
 * dv_shr ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV			*
 **									*
 * Log:									*
 * M. desJardins/GSFC	10/85						*
 * I. Graffman/RDS	 7/88	Call to DG_UPDH				*
 * G. Huffman/GSC	 9/88	New stack functions			*
 * G. Huffman/GSC	 9/88	Error messages				*
 * K. Brill/GSC          4/89   Map scale factor code			*
 * K. Brill/GSC          8/89   Subsetting				*
 * K. Brill/GSC         10/89   Subsetting				*
 * T. Lee/GSC		 4/96   Single dimension for dgg		*
 * T. Lee/GSC		 5/96   Moved IGDPT outside DO loop		*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		 5/02	Eliminate LLMXGD declarations in DGCMN	*
 *				using int grds for scl fctr derivatives *
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEP	11/05	Translation from Fortran                *
 ************************************************************************/
{
        const int       zero=0;
        int             i, ier, nval, kxd, kyd, ksub1, ksub2;
	int		numu, numv, nddx, nddy, ixmsdy, iymsdx, numout;
	float		*gru, *grv, *grddx, *grddy, *grxmdy, *grymdx, *grout;
        float           dx, dy, vv, dd;

/*----------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

        /*
         *	Get the vector.
         */
	dg_getv  ( &numu, &numv, iret );
	if  ( *iret != 0 ) return;

        /*
         *   Put the v component on the stack, compute DDX, and get the result.
         */
	dg_puts  ( &numv, iret );
	if  ( *iret != 0 ) return;
	df_ddx  ( iret );
	if  ( *iret != 0 ) return;
	dg_gets  ( &nddx, iret );
	if  ( *iret != 0 ) return;

        /*
         *   Put the u component on the stack, compute DDY, and get the result.
         */
	dg_puts  ( &numu, iret );
	if  ( *iret != 0 ) return;
	df_ddy  ( iret );
	if  ( *iret != 0 ) return;
	dg_gets  ( &nddy, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Compute map scale factor derivative coefficients.
         */
	dg_dmsf ( iret );
	if ( *iret != 0 ) return;

        nval = 1;
        dg_iget ( "IXMSDY", &nval, &ixmsdy, iret );
        dg_iget ( "IYMSDX", &nval, &iymsdx, iret );
        dg_getg ( &ixmsdy, &grxmdy, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &iymsdx, &grymdx, &kxd, &kyd, &ksub1, &ksub2, iret );

        /*
         *	Get a new grid and compute the shearing deformation.
         */
	dg_nxts  ( &numout, iret );
	if  ( *iret != 0 )  return;

        dg_getg ( &numu, &gru, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numv, &grv, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nddx, &grddx, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nddy, &grddy, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numout, &grout, &kxd, &kyd, &ksub1, &ksub2, iret );

	for ( i = ksub1 - 1; i < ksub2; i++ ) {
		dx =  grddx[i];
		dy =  grddy[i];
		dd =  gru[i];
		vv =  grv[i];
		if  ( ERMISS (dx) || ERMISS (dy) ||
     		      ERMISS (dd) || ERMISS (vv) )
		    grout[i] = RMISSD;
		else
		    grout[i] = dx + dy + dd * grxmdy[i] + vv * grymdx[i] ;
		
        }

        /*
         *	Make a name of the form 'SHR'//u and update header;
         *	update the stack.
         */
	dg_updh  ( "SHR", &numout, &numu, &zero, iret );
	dg_puts  ( &numout, iret );
	dg_esub  ( &numout, &zero, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
void df_nmax ( int *iret )
/************************************************************************
 * df_nmax								*
 *									*
 * This subroutine computes NMAX (S,ROI), the neigborhood maximum	*
 * value of a scalar field (S) within some radius of influence    	*
 * (ROI; meters). Masking could be used [e.g., SGT(S1,S2)] to subset *
 * and filter the grid beforehand to allow for faster processing.      	*
 *									*
 * df_nmax ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * C. Melick/SPC	06/12						*
 ************************************************************************/
{
    int num1, num2, num3, num, kxd, kyd, ksub1, ksub2, zero, indx, ier;
    int ixmscl, iymscl, jgymin, jgymax, jgxmin, jgxmax, idglat, idglon;
    int row, col, ibeg, iend, jbeg, jend, ibox, jbox, boxindx, nval;
    float  gddx, gddy, gdspdx, gdspdy, radius;
    float *gnum1, *gnumn, *gkxms, *gkyms, *gnumroi, *glat, *glon, *dist;
    /*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Compute map scale factors.
     */
    dg_mscl ( iret );
    if ( *iret != 0 ) return;

    /*
     * Query DGCMN.CMN idglat/idglon.
    */

    nval = 1;
    dg_iget ( "IDGLAT", &nval, &idglat, iret );
    if ( *iret != 0 ) return;
    dg_iget ( "IDGLON", &nval, &idglon, iret );
    if ( *iret != 0 ) return;

    /*
     * Get the grids from the stack.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num2, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid number.
     */
    dg_nxts ( &num3, iret );
    if ( *iret != 0 ) return;
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    dg_qmsl ( &ixmscl, &iymscl, &gddx, &gddy, &ier );
    dg_qbnd ( &jgxmin, &jgxmax, &jgymin, &jgymax, &ier );
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &num,  &gnumn,  &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &ixmscl, &gkxms, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &iymscl, &gkyms, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &num2, &gnumroi, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &idglat, &glat, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &idglon, &glon, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &num3, &dist, &kxd, &kyd, &ksub1, &ksub2, &ier );

    radius = gnumroi[0];

    /*  QC check on lower and upper bounds of radius of influence.  */

    if ( radius < 0 ) {
        radius = 0.0;
        printf ("\n WARNING : RADIUS value less than zero.  "
                "Resetting to zero.\n");
    }

    if ( radius > 0.5*gddx*(float)(kxd)) {
        radius = 0.5*gddx*(float)(kxd);
        printf ("\n WARNING : RADIUS value too high.  "
                "Resetting to half the distance in X (%f meters).\n",radius);
    }

    /*
     * Loop over all grid points to initialize output grid.
     */
    for ( row = jgymin; row <= jgymax; row++ ) {
        for ( col = jgxmin; col <= jgxmax; col++ ) {
            indx=(row-1)*kxd+(col-1);
            if ( ERMISS ( gnum1[indx] ) ) {
                gnumn[indx] = RMISSD;
            } else {
                gnumn[indx] = gnum1[indx];
            }
        }
    }

    /*
     * Loop over all grid points to determine neighborhood maximum for each grid point.
     */

    for ( row = jgymin; row <= jgymax; row++ ) {
        for ( col = jgxmin; col <= jgxmax; col++ ) {
            indx=(row-1)*kxd+(col-1);
            if ( ! ERMISS ( gnum1[indx] ) ) {
                gdspdx= gddx / gkxms[indx];
                gdspdy= gddy / gkyms[indx];

                /*  Constructing box for each grid point */
                ibeg = col- G_NINT(radius / gdspdx);
                iend = col+ G_NINT(radius / gdspdx);
                jbeg = row- G_NINT(radius / gdspdy);
                jend = row+ G_NINT(radius / gdspdy);
                if (ibeg < jgxmin) {
                    ibeg = jgxmin;
                }
                if (iend > jgxmax) {
                    iend = jgxmax;
                }
                if (jbeg < jgymin) {
                    jbeg = jgymin;
                }
                if (jend > jgymax) {
                    jend = jgymax;
                }
                for ( ibox = ibeg; ibox <= iend; ibox++ ) {
                    for ( jbox = jbeg; jbox <= jend; jbox++ ) {
                        boxindx=(jbox-1)*kxd+(ibox-1);
                        if ((glat[indx] == glat[boxindx]) && (glon[indx] == glon[boxindx])) {
                            dist[boxindx]=0.0;
                        } else {
                            /* Great Circle Distance calculation */
                            dist[boxindx] = acos(sin(glat[boxindx])*sin(glat[indx]) + cos(glat[boxindx])*cos(glat[indx])*cos((glon[boxindx])-(glon[indx])));
                            dist[boxindx] = RADIUS * dist[boxindx];
                        }
                        /* Check maximum value if neighboring point is defined and within radius of influence. */
                        if ( (dist[boxindx] <= radius) && (! ERMISS ( gnum1[boxindx] ) ) ) {
                            if ( gnum1[boxindx] > gnumn[indx] ) {
                                gnumn[indx] = gnum1[boxindx];
                            }
                        }
                    }
                }
                for ( ibox = ibeg; ibox <= iend; ibox++ ) {
                    for ( jbox = jbeg; jbox <= jend; jbox++ ) {
                        boxindx=(jbox-1)*kxd+(ibox-1);
                        /* Spreading the response around to surrounding undefined values */
                        if ( ERMISS ( gnum1[boxindx] ) ) {
                            if (dist[boxindx] <= radius) {
                                if ( ERMISS ( gnumn[boxindx] ) ) {
                                    gnumn[boxindx] = gnumn[indx];
                                } else if ( gnum1[indx] > gnumn[boxindx] ) {
                                    gnumn[boxindx] = gnum1[indx];
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /*
     * Make a name of the form 'NMAX'//S and update header;
     * update stack.
     */
    dg_updh ( "NMAX", &num, &num1, &num2, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 12
0
void de_ssum ( const char *uarg, char *stprm, int *iret )
/************************************************************************
 * de_ssum								*
 *									*
 * This subroutine computes the sum over the ensemble of a scalar.	*
 *									*
 * de_ssum ( 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:									*
 * K. Brill/HPC         08/10	Created from de_ssprd			*
 ************************************************************************/
{
    char tname[13], pdum[13], time1[21], time2[21];
    int ns, num, kxd, kyd, ksub1, ksub2, level1, level2, ivcord,
        nina, one, zero, i, j, ier;
    float *gns, *gnum;
    double *dgns, d1, d2;
/*----------------------------------------------------------------------*/
    *iret = 0;
    one = 1;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get a new grid number.
     */
    dg_nxts ( &ns, iret );
    if ( *iret != 0 ) return;

    /*
     * Initialize the output grid.
     * Allocate internal double arrays.
     */
    dg_getg ( &ns,  &gns,  &kxd, &kyd, &ksub1, &ksub2, iret );
    G_MALLOC(dgns, double, kxd*kyd, "DE_SSUM");
    for ( i = ksub1 - 1; i < ksub2; i++ ) {
        gns[i] = 0.;
        dgns[i] = 0.;
    }

    /*
     * Set the number of input arguments.  There is only one argument
     * for DE_SSUM.
     */
    nina = 1;
    for ( i = 0; i < MXARGS; i++ ) {
	_ensdiag.allarg[i][0] = '\0';
    }
    strcpy ( _ensdiag.allarg[0], uarg );

    /*
     * Scan the allarg array.
     */
    de_scan ( &nina, iret );
    if ( *iret != 0 ) return;

    /*
     * Loop over number of members set by DE_SCAN.
     */
    for ( i = 0; i < _ensdiag.nummbr; i++ ) {
	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];
	    if ( ERMISS ( d1 ) || ERMISS ( d2 ) ) {
		dgns[j] = RMISSD;
	    } else {
		dgns[j] += gnum[j];
	    }
	}
	dg_frig ( &num, &ier );
    }

    /*
     * 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);

    /*
     * 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;
}
Ejemplo n.º 13
0
void df_log ( int *iret )
/************************************************************************
 * df_log								*
 *									*
 * This subroutine computes the logarithm to the base 10 of a scalar 	*
 * grid:								*
 *									*
 *     LOG (S) = LOG10 (S)						*
 *									*
 * using the standard FORTRAN function LOG10.				*
 *									*
 * df_log ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * M. Goodman/RDS	11/85						*
 * W. Skillman/GSFC	 5/88	Added new stack subroutines		*
 * G. Huffman/GSC	 9/88	Error messages				*
 * K. Brill/GSC		 8/89   Subsetting				*
 * K. Brill/GSC		10/89	Subsetting				*
 * T. Lee/GSC		 4/96	Single dimension for dgg		*
 * K. Tyle/GSC           5/96   Moved IGDPT outside do-loop             *
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * R. Tian/SAIC		11/05	Recoded from Fortran			*
 ************************************************************************/
{
    int num1, num, kxd, kyd, ksub1, ksub2, zero, ier, i, im1;
    float *gnum1, *gnum, dg1;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get the first grid number.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 )  return;

    /*
     * Get a new grid number and compute the log base 10.
     */
    dg_nxts ( &num, iret );
    if ( *iret != 0 )  return;

    /*
     * Grid number to grid.
     */
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    for ( i = ksub1; i <= ksub2; i++ ) {
	im1 = i - 1;      
	dg1 = gnum1[im1];
	if ( ( dg1 <= 0. ) || ERMISS (dg1) ) {
	    gnum[im1] = RMISSD;
	} else {
	    gnum[im1] = log10 ( dg1 );
	}
    }

    /*
     * Make a name of the form 'LOG'//S and update header;
     * update stack.
     */
    dg_updh ( "LOG", &num, &num1, &zero, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 14
0
void pd_thta ( const float *tmpc, const float *pres, const int *np,
               float *thta, int *iret )
/************************************************************************
 * pd_thta								*
 *									*
 * This subroutine computes THTA from TMPC and PRES using Poisson's	*
 * equation:								*
 *									*
 *            THTA = TMPK * ( 1000 / PRES ) ** RKAPPA			*
 *									*
 * It can also be used to compute STHA from TMPC and PALT, THTV from	*
 * TVRC and PRES, and THTV from TVRC and PALT.				*
 *									*
 * pd_thta ( tmpc, pres, np, thta, iret )				*
 *									*
 * Input parameters:							*
 *	*tmpc		const float	Temperature in Celsius		*
 *	*pres		const float	Pressure in millibars		*
 *	*np		const int	Number of points		*
 *									*
 * Output parameters:							*
 *	*thta		float		Potential temperature in K	*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 * Log:									*
 * M. desJardins/GSFC	 7/89	GEMPAK 5				*
 * G. Krueger/EAI        4/96   Replaced C->K constant with TMCK	*
 * K. Brill/HPC		11/02	Remove SUBFLG input logical array	*
 * R. Tian/SAIC		 9/05	Translated from FORTRAN			*
 ************************************************************************/
{
    float tmpk;
    int npt, i;
/*----------------------------------------------------------------------*/
    *iret = 0;
    npt = *np;

    /*
     * Loop through all the points.
     */
    for ( i = 0; i < npt; i++ ) {
	/*
	 * Check for missing data.
	 */
    	if ( ( ERMISS ( tmpc [i] ) ) || ( ERMISS ( pres [i] ) ) || 
             ( pres [i] <= 0.0F ) ) {
	    thta [i] = RMISSD;
	} else {
	    /*
	     * Change temperature in Celsius to Kelvin.
	     */
	    tmpk = tmpc [i] + TMCK;

	    /*
	     * Calculate theta.
	     */
	    thta [i] = tmpk * pow ( 1000.0F / pres [i], RKAPPA ) ;
	}
    }

    return;
}
Ejemplo n.º 15
0
void dv_vge  ( int *iret )
/************************************************************************
 * dv_vge								*
 *									*
 * This subroutine finds values of the magnitude of V which are greater *
 * than or equal to S.							*
 *									*
 *     VGE (V, S) IF |V| >= S THEN V ELSE RMISSD			*
 *									*
 * dv_vge  ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * S. Maxwell/GSC        8/97                                           *
 * S. Maxwell/GSC        8/97     Corrected header documentation        *
 * K. Brill/HPC		 1/02	CALL DG_SSUB, DG_ESUB; CHK iret & RTRN	*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEP	11/05	Translation from Fortran                *
 ************************************************************************/
{
        const int       zero = 0;
	int		i, ier, kxd, kyd, ksub1, ksub2;
        int             numu, numv, num1, nmag, nu, nv;
        float           *grnumu, *grnumv, *grnum1, *grmag, *gru, *grv;

/*----------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

        /*
         *	Get the vector and the scalar.
         */
	dg_getv ( &numu, &numv, iret );
	if ( *iret != 0 ) return;
	dg_gets ( &num1, iret );
	if ( *iret != 0 ) return;

        /*
         *	Compute the magnitude of the vector.
         */
	dg_putv ( &numu, &numv, iret );
	if ( *iret != 0 ) return;
	dv_mag ( iret );
	if ( *iret != 0 ) return;

        /*
         *	Get the magnitude.
         */
	dg_gets ( &nmag, iret );
	if ( *iret != 0 ) return;

        /*
         *	Get a new vector.
         */
	dg_nxtv ( &nu, &nv, iret );
	if ( *iret != 0 ) return;

        dg_getg ( &nu, &gru, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nv, &grv, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numu, &grnumu, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numv, &grnumv, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &num1, &grnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nmag, &grmag, &kxd, &kyd, &ksub1, &ksub2, iret );

        /*
         *	Check all of the grid points.
         */
	for ( i= ksub1 - 1; i < ksub2; i++ ) {
	   if ( ERMISS ( grmag[i]) || ERMISS ( grnum1[i]) ) {
		gru[i] = RMISSD;
		grv[i] = RMISSD;
           }
	   else {
		if ( grmag[i] >= grnum1[i] ) {
		    gru[i] = grnumu[i];
		    grv[i] = grnumv[i];
		}
		else {
		    gru[i] = RMISSD;
		    grv[i] = RMISSD;
		}
           }

	}

        /*
         *	Make a name of the form 'VGE'//V//S and 
         *	update both grid headers; update the stack.
         */
	dg_updv ( "VGE", &nu, &nv, &numu, &num1, iret );
	dg_putv ( &nu, &nv, iret );
	dg_esub  ( &nu, &nv, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}
Ejemplo n.º 16
0
void pd_kinx ( const float *t850, const float *t700, const float *t500,
               const float *td850, const float *td700, const int *np,
               float *rkinx, int *iret )
/************************************************************************
 * pd_kinx								*
 *									*
 * This subroutine computes KINX from t850, t700, t500, td850, and	* 
 * td850. The following equation is used:				*
 *									*
 *									*
 *	RKINX = the 'K' index						*
 *	      = (t850 - t500) + td850 - (t700 - td700 )			*
 *									*
 * pd_kinx ( t850, t700, t500, td850, td700, np, rkinx, iret )		*
 *									*
 * Input parameters:							*
 *	*t850		const float	850 mb temperature in Celsius	*
 *	*t700		const float     700 mb temperature in Celsius   *
 *	*t500		const float	500 mb temperature in Celsius	*
 *      *td850		const float	850 mb dewpoint in Celsius	*
 *      *td700		const float	700 mb dewpoint in Celsius   	*
 *	*np		const int	Number of points		*
 *									*
 * Output parameters:							*
 *	*rkinx		float		The 'K' Index			*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 * Log:									*
 * D. Keiser/GSC	 6/95						*
 * T. Piper/GSC		 3/99	Corrected prolog			*
 * K. Brill/HPC		11/02	Remove SUBFLG input logical array	*
 * R. Tian/SAIC		 9/05	Translated from FORTRAN			*
 ************************************************************************/
{
    int npt, i;
/*----------------------------------------------------------------------*/
    *iret = 0;
    npt = *np;

    /*
     * Loop through all the points.
     */
    for ( i = 0; i < npt; i++ ) {
        /*
         * Check for missing data.
         */
        if ( ( ERMISS ( t850 [i] ) ) || ( ERMISS ( t700 [i] ) ) ||
      	     ( ERMISS ( t500 [i] ) ) || ( ERMISS ( td850 [i] ) ) ||
       	     ( ERMISS ( td700 [i] ) ) ) {
	    rkinx [i] = RMISSD;
        } else {
            /*
             * Find the 'K' index.
             */
	    rkinx [i] = ( t850 [i] - t500 [i] ) + td850 [i] -
     		        ( t700 [i] - td700 [i] );
        }
    }

    return;
}
Ejemplo n.º 17
0
void df_yav ( int *iret )
/************************************************************************
 * df_yav								*
 *									*
 * This subroutine computes the average value of a scalar internal grid	*
 * at all valid points along a column:					*
 *									*
 *     YAV (S) = [ S (Y1) + S (Y2) + ... + S (KYD) ] / KNT		*
 *									*
 *               Where: KYD = number of points in column		*
 *                      KNT = number of non-missing points in column	*
 *									*
 * The YAV for a column is stored at every point in that column.	*
 *									*
 * df_yav ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * I. Graffman/RDS	 1/87						*
 * M. desJardins/GSFC	 7/88	Added new stack subroutines		*
 * G. Huffman/GSC	 9/88	Error messages				*
 * T. Lee/GSC		 4/96	Single dimension for dgg		*
 * K. Tyle/GSC           5/96   Moved IGDPT outside do-loop             *
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Avg only on JGX/YMIN -> JGX/YMAX	*
 * R. Tian/SAIC         12/02   Try to make loop more clear             *
 * R. Tian/SAIC		11/05	Recoded from Fortran			*
 ************************************************************************/
{
    int num1, num, jgymin, jgymax, jgxmin, jgxmax, kxd, kyd, ksub1, ksub2,
        knt, iy, ix, ii, ier, zero;
    float *gnum1, *gnum, sum, avg;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get the scalar grid.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid number.
     */
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    /*
     * Grid number to grid.
     */
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    /*
     * Compute the average for each column.
     */
    dg_qbnd ( &jgxmin, &jgxmax, &jgymin, &jgymax, iret );
    for ( ix = jgxmin; ix <= jgxmax; ix++ ) {
	sum = 0.0;
	knt = 0;
	for ( iy = jgymin; iy <= jgymax; iy++ ) {
	    ii = ( iy - 1 ) * kxd + ix;
	    if ( ! ERMISS ( gnum1[ii-1] ) ) {
		knt++;
		sum += gnum1[ii-1];
	    }
	}
	if ( knt == 0 ) {
	    avg = RMISSD;
	} else {
	    avg = sum / knt;
	}
	for ( iy = jgymin; iy <= jgymax; iy++ ) {
	    ii = ( iy - 1 ) * kxd + ix ;
	    if ( ! ERMISS ( gnum1[ii-1] ) ) {
		gnum[ii-1] = avg;
	    } else {
		gnum[ii-1] = RMISSD;
	    }
	}
    }

    /*
     * Make a name of the form 'YAV'//S and update header;
     * update stack.
     */
    dg_updh ( "YAV", &num, &num1, &zero, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 18
0
void de_srng ( const char *uarg, char *stprm, int *iret )
/************************************************************************
 * de_srng								*
 *									*
 * This subroutine computes the range of its scalar arguments among	*
 * ensemble members. The range is the difference between the maximum	*
 * and the minimum.							*
 *									*
 * de_srng ( 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:									*
 * R. Tian/SAIC 	 6/05						*
 * R. Tian/SAIC		 1/06	Translated from Fortran			*
 ************************************************************************/
{
    char tname[13], pdum[13], time1[21], time2[21];
    int nsmax, nsmin, num, kxd, kyd, ksub1, ksub2, level1, level2,
        ivcord, nina, one, zero, i, j, ier;
    float *gnsmax, *gnsmin, *gnum, d1, d2, d3;
/*----------------------------------------------------------------------*/
    *iret = 0;
    one = 1;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get new grid numbers for maximum and minimum fields.
     */
    dg_nxts ( &nsmax, iret );
    if ( *iret != 0 ) return;
    dg_nxts ( &nsmin, iret );
    if ( *iret != 0 ) return;

    /*
     * Initialize the output grid.
     */
    dg_getg ( &nsmax, &gnsmax, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &nsmin, &gnsmin, &kxd, &kyd, &ksub1, &ksub2, iret );
    for ( i = ksub1 - 1; i < ksub2; i++ ) {
	gnsmax[i] = -FLT_MAX;
	gnsmin[i] =  FLT_MAX;
    }

    /*
     * Set the number of input arguments.  There is only one argument
     * for DE_SRNG.
     */
    nina = 1;
    for ( i = 0; i < MXARGS; i++ ) {
	_ensdiag.allarg[i][0] = '\0';
    }
    strcpy ( _ensdiag.allarg[0], uarg );

    /*
     * Scan the allarg array.
     */
    de_scan ( &nina, iret );
    if ( *iret != 0 ) return;

    /*
     * Loop over number of members set by DE_SCAN.
     */
    for ( i = 0; i < _ensdiag.nummbr; i++ ) {
	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 );

	/*
	 * Compute the maximum and minimum.
	 */
	for ( j = ksub1 - 1; j < ksub2; j++ ) {
	    d1 = gnum[j];
	    d2 = gnsmax[j];
	    d3 = gnsmin[j];
	    if ( ERMISS ( d1 ) ) {
		gnsmax[j] = RMISSD;
		gnsmin[j] = RMISSD;
	    } else {
		if ( ! ERMISS ( d2 ) ) {
		    gnsmax[j] = G_MAX ( d1, d2 );
		}
		if ( ! ERMISS ( d2 ) ) {
		    gnsmin[j] = G_MIN ( d1, d3 );
		}
	    }
	}
	dg_frig ( &num, &ier );
    }

    /*
     * Compute the range.
     */
    for ( i = ksub1 - 1; i < ksub2; i++ ) {
	d1 = gnsmax[i];
	d2 = gnsmin[i];
	if ( ERMISS ( d1 ) || ERMISS ( d2 ) ) {
	    gnsmax[i] = RMISSD;
	} else {
	    gnsmax[i] = d1 - d2;
	}
    }
    dg_frig ( &nsmin, &ier );

    /*
     * Reset DGCMN.CMN and set internal grid identifier.
     */
    de_rset ( iret );
    dg_udig ( "EXX_", &nsmax, &zero, &_ensdiag.idgens, stprm, iret );
    dg_esub ( &nsmax, &zero, &zero, &zero, &ier );
    if ( ier != 0 )  *iret = ier;

    return;
}
Ejemplo n.º 19
0
void df_not ( int *iret )
/************************************************************************
 * df_not								*
 *									*
 * This function is invoked as  NOT ( S ).  It returns 1 if S == 0;	*
 * otherwise 0.								*
 *									*
 * df_not ( iret )							*
 *									*
 * Input parameters:							*
 *									*
 * Output parameters:							*
 	*iret		int		Return code			*
 *					0 - normal return 		*
 **									*
 * Log:									*
 * m.gamazaychikov/SAIC	09/05						*
 * R. Tian/SAIC		11/05	Recoded from Fortran			*
 ************************************************************************/
{
    int num1, num, kxd, kyd, ksub1, ksub2, i, im1, zero, ier;
    float *gnum1, *gnum, dg1;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get ONE grid from the stack.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid number for the output grid.
     */
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    for ( i = ksub1; i <= ksub2; i++ ) {
        im1 = i - 1;
	dg1 = gnum1[im1];
	if ( ERMISS ( dg1 ) ) {
	    gnum[im1] = RMISSD;
	} else {
	    if( G_DIFFT(dg1, 0.0F, GDIFFD) ) {
		gnum[im1] = 1.0F;
	    } else {
	  	gnum[im1] = 0.0F;
	    }
	}
    }

    /*
     * Get a name of the form 'NOT'//S1/ and update header;
     * update stack.
     */
    dg_updh ( "NOT", &num, &num1, &zero, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 20
0
void pd_prcp ( const float *prc1, const float *prc2, const float *rmult,
               const int *np, float *total, int *iret )
/************************************************************************
 * pd_prcp								*
 *									*
 * This subroutine is used to add or subtract two precipitation 	*
 * amounts.								*
 *									*
 * The total precipitation is computed as:				*
 *									*
 *		TOTAL = PRC1 + RMULT * PRC2				*
 *									*
 * pd_prcp ( prc1, prc2, rmult, np, total, iret )			*
 *									*
 * Input parameters:							*
 *	*prc1		const float	First precipitation amount	*
 *	*prc2		const float	Second precipitation amount	*
 *	*rmult		const float	Multiplier			*
 *	*np		const int	Number of points		*
 *									*
 * Output parameters:							*
 *	*total		float		Total precipitation		*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 * Log:									*
 * M. desJardins/NMC	 3/94						*
 * K. Brill/HPC		11/02	Remove SUBFLG input logical array	*
 * R. Tian/SAIC		 9/05	Translated from FORTRAN			*
 ************************************************************************/
{
    float zerov, fvalue;
    int npt, first, ii;
/*----------------------------------------------------------------------*/
    *iret = 0;
    npt = *np;
    first  = G_TRUE;
/*
 * Set a default value for 0.  Change if a negative number is found.
 */
    zerov  = VALUE0;
    fvalue = VALUE0;
/*
 * Loop through all the points.
 */
    for ( ii = 0; ii < npt; ii++ ) {
/*
 * Check for missing data.
 */
	if ( ( ERMISS ( prc1[ii] ) ) || ( ERMISS ( prc2[ii] ) ) ) {
	    total[ii] = RMISSD;
/*
 * Check for amounts less than 0.  These values are used
 * for the 0 value so that 0 can be used as a contour level.
 */
	} else if ( ( prc1[ii] < 0.0F ) && ( prc2[ii] < 0.0F ) ) {
	    zerov = prc1[ii];
	    total[ii] = prc1 [ii];
	} else if ( ( prc1[ii] < 0.0F ) ) {
	    zerov = prc1[ii];
	    total[ii] = prc2[ii];
	} else if ( ( prc2[ii] < 0.0F ) ) {
	    zerov = prc2[ii];
	    total[ii] = prc1[ii];
/*
 * Add the two values together using the multiplier.
 */
	} else {
	    total[ii] = prc1[ii] + (*rmult) * prc2[ii];
	    if ( total[ii] <= 0.0F ) {
	        total[ii] = zerov;
		if ( first ) {
		    fvalue = zerov;
		    first  = G_FALSE;
		}
	    }
	}
    }
/*
 * Check that the first missing value is correct.
 */
    if ( ( !G_DIFF(zerov, VALUE0) ) && ( !G_DIFF(fvalue, zerov) ) ) {
        for ( ii = 0; ii < npt; ii++ ) {
	    if ( ( total[ii] <= 0.0F ) && ( ! ERMISS ( total[ii] ) ) ) {
	        total[ii] = zerov;
	    }
	}
    }

    return;
}
Ejemplo n.º 21
0
void dg_scal ( const char *parm, const int *num, int *iret )
/************************************************************************
 * dg_scal								*
 *									*
 * This subroutine scales grids to store them in MKS units.  This	*
 * is necessary for MIXR, SMXR and PSYM since the standard GEMPAK	*
 * units are not MKS units.  Whenever these parameters are returned	*
 * directly to the user, they will be rescaled to standard GEMPAK	*
 * units.								*
 *									*
 * dg_scal ( parm, num, iret )						*
 *									*
 * Input parameters:							*
 *	*parm		const char	Parameter name			*
 *	*num		const int	Number of internal grid		*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *				  	  0 = normal return		*
 **									*
 * Log:									*
 * M. desJardins/GSFC	 5/88						*
 * M. desJardins/NMC	 3/92	Add check for MIXS and SMXS		*
 * T. Lee/GSC		 4/96	Single dimension for dgg		*
 * K. Tyle/GSC           5/96   Moved IGDPT outside do-loop             *
 * T. Piper/GSC		11/98	Updated prolog				*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * R. Tian/SAIC		 2/06	Recoded from Fortran			*
 ************************************************************************/
{
    float scale;
    int gidx, i;
/*----------------------------------------------------------------------*/
    *iret = 0;

    /*
     * Check that grid number is valid.
     */
    if ( *num <= 0 ) return;

    /*
     * Get scaling factor.
     */
    if ( ( strcmp ( parm, "MIXR" ) == 0 ) ||
         ( strcmp ( parm, "SMXR" ) == 0 ) ||
	 ( strcmp ( parm, "MIXS" ) == 0 ) ||
	 ( strcmp ( parm, "SMXS" ) == 0 ) ) {
	scale = .001;
    } else if ( strcmp ( parm, "PSYM" ) == 0 ) {
	scale = 100.;
    } else {
	return;
    }

    /*
     * Scale the data.
     */
    gidx = (*num) - 1;
    for ( i = _dgarea.ksub1; i <= _dgarea.ksub2; i++ ) {
	if ( ! ERMISS ( _dggrid.dgg[gidx].grid[i-1] ) ) {
	    _dggrid.dgg[gidx].grid[i-1] *= scale;
	}
    }

    return;
}
Ejemplo n.º 22
0
void dv_mrad ( int *iret )
/************************************************************************
 * dv_mrad								*
 *									*
 * This routine computes the magnitude of the radial component of	*
 * the wind.  A unit vector between the center of the storm and the 	*
 * grid point vector is determined using oblique spherical triangles.	*
 * The radial component of the wind is determined using the equation:	*
 *		RAD =   V dot r.					*
 * Inflow to the storm is set to be positive and outflow is set to be	*
 * negative.								*
 * Wind is set to 0 when grid point = storm point, using flagged value  *
 * set in DG_AZST subroutine.                                           *
 *									*
 * dv_mrad ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV			*
 **									*
 * Log:									*
 * J. Whistler/SSAI	 6/91	Modified DV_RAD				*
 * K. Tyle/GSC		 9/95	Declared level (2) as integer		*
 * K. Tyle/GSC		 9/95	Set radial wind = 0 at storm point	*
 * T. Lee/GSC		 4/96   Single dimension for dgg		*
 * T. Lee/GSC		 5/96   Moved IGDPT outside DO loop		*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEP	11/05	Translation from Fortran                *
 ************************************************************************/
{
        int             i, ier, kxd, kyd, kxyd, ksub1, ksub2, zero=0;
   
	int		numu, numv, ilat, ilon, numout;
        float           *gru, *grv, *grout;
        int             ix, iy, iazst, idir, ispd;
        float           *grx, *gry, *grazst, *grdir, *grspd;

	char	        grid[13], parm[13], time1[21], time2[21];
	int		level1, level2, ignum, ivcord;

/*------------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

        /*
         *	Read the information from the top of the stack.
         */
	dg_tops ( grid, &ignum, time1, time2, &level1, &level2, 
                         &ivcord, parm, iret );

        /*
         *	Get the (wind) vector.
         */
	dg_getv  ( &numu, &numv, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Get scalar grids.
         */
	dg_gets ( &ilat, iret );
	if ( *iret != 0 ) return;
	dg_gets ( &ilon, iret );
	if ( *iret != 0 ) return;
	dg_gets ( &idir, iret );
	if ( *iret != 0 ) return;
	dg_gets ( &ispd, iret );
	if ( *iret != 0 ) return;

        /*
         *	Get a new grid number.
         */
	dg_nxts  ( &ix, iret );
	if ( *iret != 0 ) return;
	dg_nxts  ( &iy, iret );
	if ( *iret != 0 ) return;
	dg_nxts  ( &numout, iret );
	if ( *iret != 0 ) return;

        /*
         *	Set the latitude and longitude of the grid points.
         */
	dg_ltln ( iret );

        /*
         * 	Calculate the azimuth angle between the storm and the grid
         *	points.
         */
	dg_azst ( &ilat, &ilon, &iazst, iret );
	if ( *iret != 0 ) return;

        /*
         *	Calculate the x and y components of the directional unit
         *	vector.
         */
        dg_getg ( &ix, &grx, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &iy, &gry, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &iazst, &grazst, &kxd, &kyd, &ksub1, &ksub2, iret );

	for ( i = ksub1 - 1; i < ksub2; i++ ) {
	    if ( ERMISS ( grazst[i] ) )  {
		grx[i] = RMISSD;
		gry[i] = RMISSD;
            }

            /*
             *	    Set wind = 0 at storm point.
             */
	    else if ( grazst[i] > ( 2. * PI ) ) {
		grx[i] = 0.0;
		gry[i] = 0.0;
            }
	    else {
		grx[i] = sin ( grazst[i] );
		gry[i] = cos ( grazst[i] );
	    }
	}

        /*
         *	Change the x and y components of the unit vector from 
         *	North relative to Grid relative.
         */
 	dg_grel (  grx, gry, grx, gry, iret );
 	if ( *iret != 0 ) return;

        /*
         *	Compute u and v grid fields for the storm motion then subtract
         *	the storm motion from the wind field.
         */
        dg_getg ( &idir, &grdir, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &ispd, &grspd, &kxd, &kyd, &ksub1, &ksub2, iret );

	kxyd = kxd * kyd;
	pd_sduv  ( grspd, grdir, &kxyd, grspd, grdir, iret );
 	if ( *iret != 0 ) return;

        /*
         *	Change storm motion components to grid relative.
         */
 	dg_grel (  grspd, grdir, grspd, grdir, iret );
 	if ( *iret != 0 ) return;

        /*
         *	Subtracting u-component.
         */
	dg_puts ( &ispd, iret );
	if ( *iret != 0 ) return;
	dg_puts ( &numu, iret );
	if ( *iret != 0 ) return;
	df_sub ( iret );
	if ( *iret != 0 ) return;
	dg_gets ( &numu, iret );
	if ( *iret != 0 ) return;

        /*
         *	Subtracting v-component.
         */
	dg_puts ( &idir, iret );
	if ( *iret != 0 ) return;
	dg_puts ( &numv, iret );
	if ( *iret != 0 ) return;
	df_sub ( iret );
	if ( *iret != 0 ) return;
	dg_gets ( &numv, iret );
	if ( *iret != 0 ) return;

        /*
         *	Compute the u and v components of the radial wind.
         */
        dg_getg ( &numu, &gru, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numv, &grv, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numout, &grout, &kxd, &kyd, &ksub1, &ksub2, iret );

	for ( i = ksub1 - 1; i < ksub2; i++ ) {
	    if ( ERMISS ( grx[i] ) || ERMISS ( gry[i] ) ||
     	         ERMISS ( gru[i] ) || ERMISS ( grv[i] ) )
		grout[i] = RMISSD;
	    else

		 grout[i] = ( gru[i] * grx[i] ) + ( grv[i] * gry[i] );
	    
	}
	

        /*
         *	Update grid header.  Use wind type as parameter name.
         */
	dg_updh  ( "MRAD", &numout, &numu, &zero, &ier );

        /*
         *	Update stack.
         */
	dg_puts  ( &numout, iret );
	dg_esub  ( &numout, &zero, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}
Ejemplo n.º 23
0
void pd_heat  ( const float *tmpf, const float *relh, const int *np,
                float *heat, int *iret )
/************************************************************************
 * pd_heat								*
 *									*
 * This subroutine computes HEAT, the Southern Region/CPC Rothfusz heat	*
 * index, from TMPF and RELH.  The output will be calculated in degrees *
 * Fahrenheit.								*
 *									*
 *	Source:  NWS Southern Region SSD Technical Attachment SR 90-23	*
 * 		 7/1/90.  Heat Index was originally known as the	*
 *		 apparent temperature index (Steadman, JAM, July, 1979).*
 *									*
 * The Rothfusz regression is optimal for TMPF > ~80 and RELH > ~40%.	*
 * This code applies a simple heat index formula and then resorts to	*
 * the Rothfusz regression only if the simple heat index exceeds 80,	*
 * implying temperatures near, but slightly below 80.  To make the	*
 * simple calculation continuous with the values obtained from the	*
 * Rothfusz regression, the simple result is averaged with TMPF in	*
 * computing the simple heat index value.				*
 *									*
 * This code includes adjustments made by the CPC for low RELH at high	*
 * TMPF and high RELH for TMPF in the mid 80's.				*
 *									*
 * pd_heat ( tmpf, relh, np, heat, iret )				*
 *									*
 * Input parameters:							*
 *	*tmpf		const float	Temperature in Fahrenheit	*
 *	*relh		const float	Relative humidity in percent	*
 *	*np		const int	Number of points		*
 *									*
 * Output parameters:							*
 *	*heat		float		Heat Index in Fahrenheit	*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 * Log:									*
 * S. Jacobs/NCEP	 3/02	Initial coding				*
 * K. Brill/HPC		11/02	Remove SUBFLG input logical array	*
 * K. Brill/HPC		 1/03	Fix discontinuity around 77 F		*
 * R. Tian/SAIC		 9/05	Translated from FORTRAN			*
 ************************************************************************/
{
    float t2, r2, adj1, tval, adj2, adj;
    int npt, i;
/*----------------------------------------------------------------------*/
    *iret = 0;
    npt = *np;

    /*
     * Loop through all the points.
     */
    for ( i = 0; i < npt; i++ ) {
        /*
         * If either the Temperature or Relative Humidity are missing,
         * then set the result to missing.
         */
        if ( ERMISS (tmpf[i]) || ERMISS (relh[i]) ) {
	    heat[i] = RMISSD;
        } else {
            /*
    	     * If the temperature is less than 40 degrees, then set the
	     * heat index to the temperature.
             */
	    if ( tmpf[i] <= 40.0F ) {
	        heat[i] = tmpf[i];
            } else {
                /*
	         * Compute a simple heat index. If the value is less
	         * than 80 degrees, use it.
                 */
		heat[i] = 61.0F + (tmpf[i]-68.0F) * 1.2F + relh[i] * .094F;
		heat[i] = .5F * ( tmpf[i] + heat[i] );
		if ( heat[i] >= 80.0F ) {
                    /*
	    	     * Otherwise, compute the full regression value
	    	     * of the heat index.
                     */
		    t2 = tmpf[i] * tmpf[i];
		    r2 = relh[i] * relh[i];
		    heat[i] = -42.379F
     			      +  2.04901523F * tmpf[i]
     			      + 10.14333127F * relh[i] 
     			      -  0.22475541F * tmpf[i] * relh[i]
     			      -  0.00683783F * t2 
     			      -  0.05481717F * r2
     			      +  0.00122874F * t2 * relh[i]
     			      +  0.00085282F * tmpf[i] *r2
     			      -  0.00000199F * t2 * r2;
                    /*
	    	     * Adjust for high regression at low RH for temps
	    	     * above 80 degrees F.
                     */
		    if ( ( relh[i] <= 13.0F ) &&
     			 ( ( tmpf[i] >=  80.0F ) &&
     			   ( tmpf[i] <= 112.0F ) ) ) {
		        adj1 = ( 13.0F - relh[i] ) / 4.0F;
			tval = 17.0F - fabs ( tmpf[i] - 95.0F );
			adj2 = sqrt ( tval / 17.0F );
			adj  = adj1 * adj2;
			heat[i] -= adj;

                    /*
		     * Adjust for low regression at high RH and temps
		     * in the mid 80s.
		     */
		    } else if ( ( relh[i] > 85.0F ) && 
     			      ( ( tmpf[i] >= 80.0F ) &&
     				( tmpf[i] <= 87.0F ) ) ) {
		        adj1 = ( ( relh[i] - 85.0F ) / 10.0F );
			adj2 = ( ( 87.0F - tmpf[i] ) / 5.0F );
			adj  = adj1 * adj2;
			heat[i] += adj;
                    }
		}
	    }
	}
    }

    return;
}
Ejemplo n.º 24
0
void df_ddt ( int *iret )
/************************************************************************
 * df_ddt								*
 *									*
 * This subroutine computes the time derivative:			*
 *									*
 *     DDT (S) = [ S (time1) - S (time2) ] / (time1 - time2)		*
 *									*
 * where the time difference is in seconds.				*
 *									*
 * df_ddt ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * M. Goodman/RDS	12/85						*
 * M. desJardins/GSFC	 7/88	Added new stack subroutines		*
 * G. Huffman/GSC	 8/88	Revised name generation; error messages	*
 * K. Brill/GSC		 8/89	Subsetting				*
 * K. Brill/GSC         10/89   Subsetting				*
 * K. Brill/GSC         11/89   Call TG_DIFF instead of TI_DIFF		*
 * M. desJardins/NMC	 7/93	Changed update scheme			*
 * T. Lee/GSC		 4/96	Single dimension for dgg		*
 * K. Tyle/GSC           5/96   Moved IGDPT outside do-loop             *
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * R. Tian/SAIC		10/05	Recoded from Fortran			*
 ************************************************************************/
{
    char gp[13], time1[21], time2[21], parm[13], gfunc[13];
    int ntdf, kxd, kyd, ksub1, ksub2, fidx, cidx; 
    int level1, level2, ivcord, imins, zero, ier;
    float *gntdf;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Compute the scalar difference over time.
     */
    df_tdf ( iret );
    if ( *iret != 0 ) return;

    /*
     * Get the pointer to the time difference; save the scalar name.
     */
    dg_tops ( gfunc, &ntdf, time1, time2, &level1, &level2, &ivcord,
	      parm, iret );
    if ( *iret != 0 ) return;

    /*
     * Convert the date/time range into seconds.
     */
    tg_diff ( time1, time2, &imins, &ier, strlen(time1), strlen(time2) );

    /*
     * Divide the scalar difference by the number of seconds.
     */
    dg_getg ( &ntdf, &gntdf, &kxd, &kyd, &ksub1, &ksub2, iret );
    for ( fidx = ksub1; fidx <= ksub2; fidx++ ) {
        cidx = fidx - 1;
	if ( imins == 0 || ERMISS ( gntdf[cidx] ) ) {
	    gntdf[cidx] = RMISSD;
	} else {
            gntdf[cidx] /= ( imins * 60 );
	}
    }

    /*
     * Make a name of the form 'DDT'//S and update header;
     * the stack is current.  DG_UPDH is not used here because
     * the scalar name was buried in the TDF parameter name.
     */
    strcpy ( gp, "DDT" );
    strcat ( gp, &parm[3] );
    dg_upsg ( time1, time2, &level1, &level2, &ivcord, &zero, gp,
	      &ntdf, iret );
    dg_esub ( &ntdf, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 25
0
void df_ne ( int *iret )
/************************************************************************
 * df_ne								*
 *									*
 * This function is invoked as  NE ( S1, S2, S3 ).  It returns 1 	*
 * if |S1-S2| > S3; otherwise 0.					*
 *									*
 * df_ne ( iret )							*
 *									*
 * Input parameters:							*
 *									*
 * Output parameters:							*
 	*iret		int		Return code			*
 *					0 - normal return 		*
 **									*
 * Log:									*
 * m.gamazaychikov/SAIC	09/05						*
 * R. Tian/SAIC		11/05	Recoded from Fortran			*
 ************************************************************************/
{
    int num1, num2, num3, num, kxd, kyd, ksub1, ksub2, i, im1, zero, ier;
    float *gnum1, *gnum2, *gnum3, *gnum, dg1, dg2, dg3;
/*----------------------------------------------------------------------*/
    *iret = 0;

    dg_ssub ( iret );

    /*
     * Get three grids from the stack.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num2, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num3, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid number and check the grids.
     */ 
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    /*
     * Grid number to grid.
     */
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num2, &gnum2, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num3, &gnum3, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    for ( i = ksub1; i <= ksub2; i++ ) {
	im1 = i - 1;
	dg1 = gnum1[im1];
	dg2 = gnum2[im1];
	dg3 = gnum3[im1];
	if ( ERMISS ( dg1 ) || ERMISS ( dg2 ) || ERMISS ( dg3 ) ) {
	    gnum[im1] = RMISSD;
	} else {
	    if ( G_ABS ( dg1 - dg2 ) > dg3 ) {
		gnum[im1] = 1.0;
	    } else {
		gnum[im1] = 0.0;
	    }
	}
    }

    /*
     * Get a name of the form 'NE'//S1//S2 and update header;
     * update stack.
     */
    dg_updh ( "NE", &num, &num1, &num2, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 26
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;

	}

}
Ejemplo n.º 27
0
void dv_vasv ( int *iret )
/************************************************************************
 * dv_vasv								*
 *									*
 * This subroutine computes the vector component of the first vector	*
 * along the second vector.						*
 *									*
 *     VASV ( V1, V2 ) = [ DOT (V1,V2) / MAG (V2) ** 2 ] V2		*
 *									*
 * VASV generates a vector field.					*
 *									*
 * dv_vasv  ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV			*
 **									*
 * Log:									*
 * K. Brill/NMC		 1/93 						* 
 * S. Chiswell/Unidata	 2/96	Redefined mag as REAL rmg		*
 * T. Lee/GSC		 4/96   Single dimension for dgg		*
 * T. Lee/GSC		 5/96   Moved IGDPT outside DO loop		*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEP	11/05	Translation from Fortran                *
 ************************************************************************/
{
        const int       zero=0;
        int             i, ier, kxd, kyd, ksub1, ksub2 ;
	int		numu1, numv1, numu2, numv2, nu, nv;
	float		*gru1, *grv1, *gru2, *grv2, *gru, *grv;
        float           du1, dv1, du2, dv2, dot, rmg;

/*----------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

        /*
         *	Get the two vectors.
         */
	dg_getv  ( &numu1, &numv1, iret );
	if  ( *iret != 0 ) return;
	dg_getv  ( &numu2, &numv2, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Get new grid numbers and compute the along stream vector.
         */
	dg_nxtv ( &nu, &nv, iret );
	if  ( *iret != 0 ) return;

        dg_getg ( &nu, &gru, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nv, &grv, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numu1, &gru1, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numv1, &grv1, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numu2, &gru2, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numv2, &grv2, &kxd, &kyd, &ksub1, &ksub2, iret );

	for ( i = ksub1 - 1; i < ksub2; i++ ) {
	    du1 = gru1[i];
	    dv1 = grv1[i];
	    du2 = gru2[i];
	    dv2 = grv2[i];
	    if  ( ERMISS (du1) || ERMISS (dv1) ||
     		  ERMISS (du2) || ERMISS (dv2) ) {
		gru[i] = RMISSD;
		grv[i] = RMISSD;
            }
	    else {
		dot = du1 * du2  +  dv1 * dv2;
		rmg = du2 * du2  +  dv2 * dv2;
		if ( rmg < 1.e-20 ) {
		    gru[i] = RMISSD;
		    grv[i] = RMISSD;
		}
		else {
		    gru[i] = ( dot / rmg ) * du2;
		    grv[i] = ( dot / rmg ) * dv2;
		}
            }
	}

        /*
         *	Make a name of the form 'VASV'//u1//u2 and update header;
         *	update stack.
         */
	dg_updv  ( "VASV", &nu, &nv, &numu1, &numu2, iret );
	dg_putv  ( &nu, &nv, iret );
	dg_esub  ( &nu, &nv, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}
Ejemplo n.º 28
0
void df_atn2 ( int *iret )
/************************************************************************
 * df_atn2								*
 *									*
 * This subroutine computes the arc tangent of the quotient of two 	*
 * scalar grids:							*
 *									*
 *     ATAN2 (S1, S2) = ATAN2 ( S1 / S2 )				*
 *									*
 * df_atn2 ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * M. Goodman/RDS	11/85						*
 * W. Skillman/GSFC	 5/88	Added new stack subroutines		*
 * G. Huffman/GSC	 8/88	Correct answer at infinity		*
 * G. Huffman/GSC	 9/88	Error messages				*
 * G. Huffman/GSC	 4/89	Correct first infinity test to denom.	*
 * K. Brill/GSC          8/89   Subsetting				*
 * K. Brill/GSC         10/89   Subsetting				*
 * T. Lee/GSC		 4/96	Single dimension for dgg		*
 * K. Tyle/GSC           5/96   Moved IGDPT outside do-loop             *
 * T. Piper/GSC		11/98	Updated prolog				*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * R. Tian/SAIC		10/05	Translated from Fortran			*
 ************************************************************************/
{
    int num1, num2, num, kxd, kyd, ksub1, ksub2, fidx, cidx, zero, ier;
    float *gnum1, *gnum2, *gnum, dg1, dg2;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get the two grids from the stack.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num2, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid.
     */
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    /*
     * Grid number to grid.
     */
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num2, &gnum2, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    /*
     * Compute the arc tangent.
     */
    for ( fidx = ksub1; fidx <= ksub2; fidx++ ) {
	cidx = fidx - 1;
        dg1 = gnum1[cidx];
        dg2 = gnum2[cidx];

	/*
    	 * Cases are error, non-zero denom., zero denom. with neg. 
	 * numerator, zero denom. with non-neg. numerator.
	 */
        if ( ERMISS ( dg1 ) || ERMISS ( dg2 ) ) {
	    gnum[cidx] = RMISSD;
        } else if  ( !G_DIFFT(dg2, 0.0F, GDIFFD) ) {
	    gnum[cidx] = atan2 ( dg1, dg2 );
        } else if ( dg1 < 0.0F ) {
	    gnum[cidx] = -HALFPI;
        } else {
	    gnum[cidx] = HALFPI;
	}
    }

    /*
     * Get a name of the form 'ATAN'//S1//S2 and update header;
     * update stack.
     */
    dg_updh ( "ATAN", &num, &num1, &num2, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Ejemplo n.º 29
0
void clo_closest ( float *lat, float *lon, int npts, float plat,
                   float plon, int nclose, int *order, int *iret )
/************************************************************************
 * clo_closest								*
 *									*
 * This function returns the order of the lat/lon arrays in terms of	*
 * their geographical closeness to the point in question, ie., the pair	*
 * (lat[order[0]],lon[order[0]]) is closest to point (plat,plon).	*
 * Only the closest nclose pairs will be determined.			*
 *									*
 * clo_closest  ( lat, lon, npts, plat, plon, nclose, order, iret )	*
 *									*
 * Input parameters:							*
 *	*lat		float		Latitude array			*
 *	*lon		float		Longitude array			*
 *	npts		int		Number of lat/lon pairs		*
 *	plat		float		Latitude of point		*
 *	plon		float		Longitude of point		*
 *	nclose		int		Return this number of indices	*
 *									*
 * Output parameters:							*
 *	*order		int		Index into lat/lon arrays	*
 *	*iret		int		Return code			*
 **									*
 * Log:									*
 * D.W.Plummer/NCEP	 1/99	Add nclose to calling sequence;		*
 *				re-write algorithm to use clo_dist.	*
 * D.W.Plummer/NCEP	 4/99	Added check for npts == 0 		*
 * M. Li/GSC		10/99	Modified clo_dist code			*
 * M. Li/GSC		10/99	Added multi-points cal. to clo_dist	*
 * D.W.Plummer/NCEP	 1/00	bug fix when some lat/lons are invalid	*
 ***********************************************************************/
{
    int	i, j, which, ier;
    float	*dist, mindist;
    /*---------------------------------------------------------------------*/
    *iret = 0;

    if ( npts == 0 )  {
        *iret = -1;
        return;
    }

    dist = (float *) malloc ( (size_t)npts * sizeof(float) );
    clo_dist( &plat, &plon, &npts, lat, lon, dist, &ier );

    for ( i = 0 ; i < nclose ; i++ )  {

        mindist = FLT_MAX;
        which = IMISSD;
        for ( j = 0 ; j < npts ; j++ )  {

            if ( !ERMISS(dist[j]) && dist[j] <= mindist )  {
                which = j;
                order[i] = which;
                mindist = dist[which];
            }

        }

        if ( which != IMISSD )  {
            dist[which] = RMISSD;
        }
        else  {
            order[i] = IMISSD;
        }

    }

    free ( dist );

}
Ejemplo n.º 30
0
void df_le ( int *iret )
/************************************************************************
 * df_le								*
 * 									*
 * This subroutine checks if x1 is less than or equal to x2 and		*
 * returns the result of comparison:					*
 *	1 if x1 <= x2							*
 *	0 if x1 >  x2							*
 *	RMISS if either grid is missing					*
 * 									*
 * df_le ( iret )                                              		*
 * 									*
 * Input parameters:							*
 * 									*
 * Output parameters:							*
 *      *iret		int		Return code			*
 *					0 - normal return		*
 **									*
 * Log:									*
 * m.gamazaychikov/SAIC	09/05						*
 * R. Tian/SAIC		11/05	Recoded from Fortran			*
 ************************************************************************/
{
    int num1, num2, num, kxd, kyd, ksub1, ksub2, i, im1, zero, ier;
    float *gnum1, *gnum2, *gnum, dg1, dg2;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get two grids from the stack.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num2, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid number and check the grids.
     */
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    /*
     * Grid number to grid.
     */
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num2, &gnum2, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    for ( i = ksub1; i <= ksub2; i++ ) {
        im1 = i - 1;
	dg1 = gnum1[im1];
	dg2 = gnum2[im1];
	if ( ERMISS ( dg1 ) || ERMISS ( dg2 ) ) {
	    gnum[im1] = RMISSD;
	} else {
	    if ( dg1 <= dg2 ) {
		gnum[im1] = 1.0;
	    } else {
		gnum[im1] = 0.0;
	    }
	}
    }

    /*
     * Get a name of the form 'LE'//S1//S2 and update header;
     * update stack.
     */
    dg_updh ( "LE", &num, &num1, &num2, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}