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; }
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; }
void df_sm9s ( int *iret ) /************************************************************************ * df_sm9s * * * * This subroutine uses a 9 point smoother to smooth a scalar grid. * * * * df_sm9s ( iret ) * * * * Output parameters: * * *iret int Return code * * As for DG_GETS * ** * * Log: * * C.L. Shie/SSAI 12/93 Modified from DF_SM5S * * T. Lee/GSC 4/96 Single dimension for dgg * * K. Tyle/GSC 5/96 Moved IGDPT outside do-loop; rearranged * * K. Brill/HPC 1/02 CALL DG_SSUB and DG_ESUB * * R. Tian/SAIC 11/05 Recoded from Fortran * ************************************************************************/ { int ni, no, jgymin, jgymax, jgxmin, jgxmax, kxd, kyd, ksub1, ksub2; int i, j, ii, ip1, im1, jp1, jm1, imjm, ipjm, imjp, ipjp, ier, zero; float *gni, *gno, dsum, wsum, wt, wtc, wt4; float dip1, dim1, djp1, djm1, dimjm, dipjm, dimjp, dipjp; /*----------------------------------------------------------------------*/ *iret = 0; zero = 0; dg_ssub ( iret ); /* * Set filter weight for Diamond points weight */ wt = 2.0; /* * Corner points weight */ wtc = 1.0; /* * Center point weight */ wt4 = 4.0; /* * Get the grid number. */ dg_gets ( &ni, iret ); if ( *iret != 0 ) return; /* * Get a new grid number and do the smoothing. */ dg_nxts ( &no, iret ); if ( *iret != 0 ) return; /* * Grid number to grid. */ dg_getg ( &ni, &gni, &kxd, &kyd, &ksub1, &ksub2, iret ); dg_getg ( &no, &gno, &kxd, &kyd, &ksub1, &ksub2, iret ); /* * Apply nine-point variable smoother over subset grid. */ dg_qbnd ( &jgxmin, &jgxmax, &jgymin, &jgymax, iret ); for ( j = jgymin; j <= jgymax; j++ ) { for ( i = jgxmin; i <= jgxmax; i++ ) { ii = ( j - 1 ) * kxd + i; if ( ERMISS ( gni[ii-1] ) ) { /* * Check for missing data. */ gno[ii-1] = RMISSD; } else { ip1 = ii + 1; if ( i+1 > jgxmax ) { dip1 = RMISSD; } else { dip1 = gni[ip1-1]; } im1 = ii - 1; if ( i-1 < jgxmin ) { dim1 = RMISSD; } else { dim1 = gni[im1-1]; } jp1 = ii + kxd; if ( j+1 > jgymax ) { djp1 = RMISSD; } else { djp1 = gni[jp1-1]; } jm1 = ii - kxd; if ( j-1 < jgymin ) { djm1 = RMISSD; } else { djm1 = gni[jm1-1]; } imjm = jm1 - 1; if ( ( j-1 < jgymin ) || ( i-1 < jgxmin ) ) { dimjm = RMISSD; } else { dimjm = gni[imjm-1]; } ipjm = jm1 + 1; if ( ( j-1 < jgymin ) || ( i+1 > jgxmax ) ) { dipjm = RMISSD; } else { dipjm = gni[ipjm-1]; } imjp = jp1 - 1; if ( ( j+1 > jgymax ) || ( i-1 < jgxmin ) ) { dimjp = RMISSD; } else { dimjp = gni[imjp-1]; } ipjp = jp1 + 1; if ( ( j+1 > jgymax ) || ( i+1 > jgxmax ) ) { dipjp = RMISSD; } else { dipjp = gni[ipjp-1]; } dsum = gni[ii-1] * wt4; wsum = wt4; if ( ! ERMISS ( dip1 ) ) { dsum += dip1 * wt; wsum += wt; } else { dsum += gni[ii-1] * wt; wsum += wt; } if ( ! ERMISS ( dim1 ) ) { dsum += dim1 * wt; wsum += wt; } else { dsum += gni[ii-1] * wt; wsum += wt; } if ( ! ERMISS ( djp1 ) ) { dsum += djp1 * wt; wsum += wt; } else { dsum += gni[ii-1] * wt; wsum += wt; } if ( ! ERMISS ( djm1 ) ) { dsum += djm1 * wt; wsum += wt; } else { dsum += gni[ii-1] * wt; wsum += wt; } if ( ! ERMISS ( dimjm ) ) { dsum += dimjm * wtc; wsum += wtc; } else { dsum += gni[ii-1] * wtc; wsum += wtc; } if ( ! ERMISS ( dipjm ) ) { dsum += dipjm * wtc; wsum += wtc; } else { dsum += gni[ii-1] * wtc; wsum += wtc; } if ( ! ERMISS ( dimjp ) ) { dsum += dimjp * wtc; wsum += wtc; } else { dsum += gni[ii-1] * wtc; wsum += wtc; } if ( ! ERMISS ( dipjp ) ) { dsum += dipjp * wtc; wsum += wtc; } else { dsum += gni[ii-1] * wtc; wsum += wtc; } gno[ii-1] = dsum/wsum ; } } } /* * Make a name of the form 'SM9'//S and update header; * update stack. */ dg_updh ( "SM9", &no, &ni, &zero, iret ); dg_puts ( &no, iret ); dg_esub ( &no, &zero, &zero, &zero, &ier ); if ( ier != 0 ) *iret = ier; return; }