Changeset 1383 in lmdz_wrf for trunk/tools


Ignore:
Timestamp:
Dec 14, 2016, 10:18:31 AM (8 years ago)
Author:
lfita
Message:

Adding:

`linearint_weights': Function to provide the weights for a linear interpolation of a value between a couple of values as a weighted distance mean
`linearint_3x3weights': Function to provide the weights for a linear interpolation of a value inside a 3x3 matrix of values as a weighted distance mean

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/generic_tools.py

    r1367 r1383  
    7171# latex_fig_array: Function to add an array of figures to an existing tex file
    7272# latex_text: Function to transform a text to LaTeX following style rules
     73# linearint_weights: Function to provide the weights for a linear interpolation of a value between a couple of values as a weighted distance mean
     74# linearint_3x3weights: Function to provide the weights for a linear interpolation of a value inside a 3x3 matrix of values as a weighted distance mean
    7375# list_combos: Function to construct a new list with all possible N-combinations of the list-values
    7476# list_coincidences: Function to provide the coincidences between two lists
     
    1078710789   else:
    1078810790      raise ValueError, 'input is not a valid roman numeral: %s' % input
     10791
     10792def linearint_weights(vals, intval):
     10793    """ Function to provide the weights for a linear interpolation of a value between a couple of values as a weighted distance mean
     10794      vals: couple of values
     10795      intval: value to interpolate between [vals]
     10796    >>> linearint_weights([1., 2.], 1.5)
     10797    [0.5  0.5]
     10798    >>> linearint_weights([-2., -1.], -1.0005)
     10799    [  5.00000000e-04   9.99500000e-01]
     10800    """
     10801    fname = 'linear_wegiths'
     10802
     10803    if vals[0] > vals[1]:
     10804        sign = 'neg'
     10805    else:
     10806        sign = 'pos'
     10807
     10808    if sign == 'neg' and not (intval <= vals[0] and intval >= vals[1]):
     10809        print errormsg
     10810        print '  ' + fname + ': wrong value:', intval , ' to interpolate for:',      \
     10811          vals, ' range'
     10812        quit(-1)
     10813
     10814    if sign == 'pos' and not (intval >= vals[0] and intval <= vals[1]):
     10815        print intval >= vals[0]
     10816        print intval <= vals[1]
     10817        print errormsg
     10818        print '  ' + fname + ': wrong value:', intval , ' to interpolate for:',      \
     10819          vals, ' range'
     10820        quit(-1)
     10821
     10822    inc = np.abs(vals[0] - vals[1])
     10823    linearwgt = [np.abs(intval - vals[0]), np.abs(intval - vals[1])]
     10824    linearwgt = 1. - linearwgt / inc
     10825
     10826    return linearwgt
     10827
     10828def linearint_3x3weights(xvals, yvals, intval):
     10829    """ Function to provide the weights for a linear interpolation of a value inside a 3x3 matrix of values as a weighted distance mean
     10830      xvals: 3x3 matrix of x-values
     10831      yvals: 3x3 matrix of y-values
     10832      intval: value to interpolate between [yintval, xintval]
     10833      It returns:
     10834        * 3x3 matrix with weights (zero if are above the 4th shortest distacce, masked values for outside dx,dy positions)
     10835        * Number of closest grid points (<=4)
     10836        * 2x9 matrix with distance-sorted positions within the 3x3 matrix
     10837    xvals = np.zeros(9).reshape(3,3)
     10838    xvals[:,0] = 1.
     10839    xvals[:,1] = 2.
     10840    xvals[:,2] = 3.
     10841    xvals[2,2] = None
     10842    yvals = xvals.transpose()
     10843    >>> linearint_3x3weights(xvals, yvals, [1.5, 2.5])
     10844    (masked_array(data =
     10845     [[0.0 0.25 0.25]
     10846     [0.0 0.25 0.25]
     10847     [0.0 0.0 --]],
     10848                 mask =
     10849     [[False False False]
     10850     [False False False]
     10851     [False False  True]],
     10852           fill_value = 1e+20)
     10853    , 4, array([[ 0,  0,  1,  1,  0,  1,  2,  2, -1],
     10854           [ 1,  2,  1,  2,  0,  0,  1,  0, -1]]))
     10855    """
     10856    fname = 'linear_wegiths'
     10857
     10858    # Assuming that values come from `vals_around' function (None, when outside matrix size)
     10859    xvalsma = ma.masked_equal(xvals,None)
     10860    yvalsma = ma.masked_equal(yvals,None)
     10861
     10862    # Check data
     10863    nx = np.min(xvals)
     10864    xx = np.max(xvals)
     10865    ny = np.min(yvals)
     10866    xy = np.max(yvals)
     10867
     10868    if not intval[1] >= nx and intval[1] <= xx:
     10869        print errormsg
     10870        print '  ' + fname + ': wrong value:', intval[1] , ' to interpolate for range:'
     10871        for i in range(3):
     10872            print '    ', xvals[:,i]
     10873        quit(-1)
     10874    if not intval[0] >= ny and intval[0] <= xy:
     10875        print errormsg
     10876        print '  ' + fname + ': wrong value:', intval[0] , ' to interpolate for range:'
     10877        for i in range(3):
     10878            print '    ', yvals[:,i]
     10879        quit(-1)
     10880
     10881    dist = np.sqrt( (xvalsma-intval[1])**2 + (yvalsma-intval[0])**2)
     10882    inc = np.sum(dist)
     10883    print 'inc:', inc, 'intval', intval
     10884    for i in range(3):
     10885        print dist[:,i]
     10886
     10887    ijvals = dist.copy()
     10888    distpos = np.ones((2,9), dtype=int)*(-1)
     10889
     10890    # shortest minium distance
     10891    sortdist = list(dist.flatten())
     10892    sortdist.sort()
     10893    iijj = 0   
     10894    if sortdist[0] == 0.:
     10895        ij = index_mat(ijvals,0.)
     10896        distpos[:,iijj] = ij[:]
     10897        wgt = np.zeros((3,3), dtype=np.float)
     10898        wgt[ij[0], ij[1]] = 1.
     10899        return wgt, 1, distpos
     10900
     10901    # Getting ij values of distances, removing he already localized values
     10902    iijj = 0
     10903    for ijdist in sortdist:
     10904        if ijdist is not ma.masked:
     10905            ij = index_mat(ijvals,ijdist)
     10906            distpos[:,iijj] = ij[:]
     10907            ijvals[ij[0],ij[1]] = fillValueF
     10908            iijj = iijj + 1
     10909
     10910    # Normalizing values (onlyl the first 4)
     10911    if iijj >= 3:
     10912        inc = np.sum(sortdist[0:4])
     10913        maxdist = sortdist[3]
     10914        Nvals = 4
     10915    else:
     10916        inc = np.sum(sortdist[0:iijj])
     10917        maxdist = sortdist[iijj]
     10918        Nvals = iijj
     10919
     10920    wgt = np.where(dist <= maxdist, dist / inc, 0.)
     10921
     10922    return wgt, Nvals, distpos
     10923
     10924def curvelocalize_2D(curve,xvals,yvals):
     10925    """ Function to provide the localization a curve in a 2D field of positions via the equivalent i,j-quads
     10926      within which the curve lays (-1, no value for the given quad [2x2 points around]) and provide the weights
     10927      of the quad to perform a distance-weighted mean at the given curve point
     10928             x,y_j,i       x,y_j,i+1
     10929
     10930                curve(t)
     10931
     10932                           curve(t+1)
     10933
     10934             x,y_j-1,i     x,y_j-1,i+1
     10935
     10936      curve= [2, Npts] matrix of values of the curve
     10937        yval0, xval0
     10938        yval1, xval1
     10939        (...)
     10940        yvalNpts, xvalNpts
     10941      xvals= 2D matrix of x-coordinate values
     10942      yvals= 2D matrix of y-coordinate values
     10943      RETURNS:
     10944        curvloc = [2,Npts] matrix with the closest i,j grid point in the 2D space of the field positions
     10945        curvweights = [3,3,Npts] 3x3 matrix weights around the curve position
     10946    """
     10947    fname = 'curvelocalize_2D'
     10948
     10949    Npts = curve.shape[1]
     10950
     10951    curvloc = np.ones((curve.shape), dtype=int)*(-1)
     10952    Nquad = np.ones((Npts), dtype=int)*(-1)
     10953    curvweights = np.zeros((3,3,Npts), dtype=float)
     10954
     10955    for icv in range(Npts):
     10956        # Closest grid-point
     10957        dist = np.sqrt((xvals - curve[1,icv])**2 + (yvals - curve[0,icv])**2)
     10958        mindist = np.min(dist)
     10959        ijloc = index_mat(dist,mindist)
     10960        iloc[icv] = ijloc[1]
     10961        jloc[icv] = ijloc[0]
     10962
     10963        # Values around the nearest 2D-point to the curve point
     10964        xaroundvls = vals_around(xvals,ijloc)
     10965        yaroundvls = vals_around(yvals,ijloc)
     10966
     10967        curveweights[, Npts, ijaorund3x3 = linearint_3x3weights(xvals, yvals, intval)
     10968       
     10969 
     10970    return
     10971
     10972
     10973#quit()
Note: See TracChangeset for help on using the changeset viewer.