Changeset 9299


Ignore:
Timestamp:
Aug 13, 2014, 5:11:19 PM (11 years ago)
Author:
davies
Message:

Smoother interpolation for makeGeotif + speedups in quantity_setting_functions and spatialInputUtils

Location:
trunk/anuga_core/source/anuga/utilities
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/anuga_core/source/anuga/utilities/plot_utils.py

    r9288 r9299  
    828828             output_dir='TIFS',
    829829             bounding_polygon=None,
    830              verbose=False):
     830             verbose=False,
     831             k_nearest_neighbours=3):
    831832    """
    832833        Make a georeferenced tif by nearest-neighbour interpolation of sww file outputs (or a 3-column array with xyz Points)
     
    852853                output_dir -- Write outputs to this directory
    853854                bounding_polygon -- polygon (e.g. from read_polygon) If present, only set values of raster cells inside the bounding_polygon
     855                k_nearest_neighbours -- how many neighbours to use in interpolation. If k>1, inverse-distance-weighted interpolation is used
    854856               
    855857    """
     
    860862    import scipy.io
    861863    import scipy.interpolate
     864    import scipy.spatial
    862865    import anuga
    863866    from anuga.utilities import plot_utils as util
     
    956959        print 'Making interpolation functions...'
    957960    swwXY=scipy.array([swwX[:],swwY[:]]).transpose()
    958     # Get index of nearest point
    959     index_qFun=scipy.interpolate.NearestNDInterpolator(swwXY,scipy.arange(len(swwX),dtype='int64').transpose())
    960     #index_qFun=scipy.interpolate.LinearNDInterpolator(swwXY,scipy.arange(len(swwX),dtype='int64').transpose())
    961 
    962     #print 'index_qFun', index_qFun
    963    
     961
     962    # Get function to interpolate quantity onto gridXY_array
    964963    gridXY_array=scipy.array([scipy.concatenate(gridX),scipy.concatenate(gridY)]).transpose()
    965     #gridXY_array=scipy.concatenate((gridX,gridY)).transpose()
    966    
    967964    gridXY_array=scipy.ascontiguousarray(gridXY_array)
    968     #print gridXY_array.flags['C_CONTIGUOUS']
    969     #print 'GRIDXY_ARRAY', gridXY_array.shape
    970 
    971     gridqInd=index_qFun(gridXY_array)
     965
     966    # Create Interpolation function
     967    #basic_nearest_neighbour=False
     968    if(k_nearest_neighbours==1):
     969        index_qFun=scipy.interpolate.NearestNDInterpolator(swwXY,scipy.arange(len(swwX),dtype='int64').transpose())
     970        gridqInd=index_qFun(gridXY_array)
     971        # Function to do the interpolation
     972        def myInterpFun(quantity):
     973            return quantity[gridqInd]
     974    else:
     975        # Combined nearest neighbours and inverse-distance interpolation
     976        index_qFun=scipy.spatial.cKDTree(swwXY)
     977        NNInfo=index_qFun.query(gridXY_array,k=3)
     978        # Weights for interpolation
     979        nn_wts=1./(NNInfo[0]+1.0e-100)
     980        nn_inds=NNInfo[1]
     981        def myInterpFun(quantity):
     982            denom=nn_wts[:,0]+nn_wts[:,1]+nn_wts[:,2]
     983            num = quantity[nn_inds[:,0]]*nn_wts[:,0]+\
     984                  quantity[nn_inds[:,1]]*nn_wts[:,1]+\
     985                  quantity[nn_inds[:,2]]*nn_wts[:,2]
     986            return (num/denom)
     987
     988
    972989
    973990    if(bounding_polygon is not None):
     
    9951012            if(type(myTS)==int):
    9961013                if(output_quantity=='stage'):
    997                     gridq=p2.stage[myTS,:][gridqInd]
     1014                    gridq=myInterpFun(p2.stage[myTS,:])
    9981015                if(output_quantity=='depth'):
    999                     gridq=p2.height[myTS,:][gridqInd]
     1016                    gridq=myInterpFun(p2.height[myTS,:])
    10001017                    gridq=gridq*(gridq>=0.) # Force positive depth (tsunami alg)
    10011018                if(output_quantity=='velocity'):
    1002                     gridq=p2.vel[myTS,:][gridqInd]
     1019                    gridq=myInterpFun(p2.vel[myTS,:])
    10031020                if(output_quantity=='friction'):
    1004                     gridq=p2.friction[gridqInd]
     1021                    gridq=myInterpFun(p2.friction)
    10051022                if(output_quantity=='depthIntegratedVelocity'):
    10061023                    swwDIVel=(p2.xmom[myTS,:]**2+p2.ymom[myTS,:]**2)**0.5
    1007                     gridq=swwDIVel[gridqInd]
     1024                    gridq=myInterpFun(swwDIVel)
    10081025                if(output_quantity=='elevation'):
    1009                     gridq=p2.elev[gridqInd]
     1026                    gridq=myInterpFun(p2.elev)
    10101027   
    10111028                if(myTSi is 'max'):
     
    10141031                    timestepString=str(round(p2.time[myTS]))
    10151032            elif(myTS=='pointData'):
    1016                 gridq=xyzPoints[:,2][gridqInd]
     1033                gridq=myInterpFun(xyzPoints[:,2])
    10171034
    10181035
  • trunk/anuga_core/source/anuga/utilities/quantity_setting_functions.py

    r9245 r9299  
    116116    import os
    117117    import numpy
    118     from matplotlib import path
     118    #from matplotlib import path
     119    from anuga.geometry.polygon import inside_polygon
    119120
    120121    def F(x,y):
     
    151152                continue
    152153
    153             # Get a 'true/false' flag for whether the point is in pi, and not set
     154            # Get indices fInds of points in pi which are not set
    154155            if(pi is 'All'):
    155156                fInside=(1-isSet)
     157                fInds=(fInside==1).nonzero()[0]
    156158            else:
    157159                if(pi is 'Extent' and type(fi) is str and os.path.exists(fi)):
     
    159161                    # Then we get the extent from the raster itself
    160162                    import anuga.utilities.spatialInputUtil as su
    161                     newpi=su.getRasterExtent(fi,asPolygon=True)
    162                     pi_path=path.Path(numpy.array(newpi))
     163                    pi_path=su.getRasterExtent(fi,asPolygon=True)
    163164                else:
    164                     # Try matplotlib -- make the path a matplotlib path object
    165                     pi_path=path.Path(numpy.array(pi))
    166 
    167                 fInside=xy_array_trans[:,0]*0.
    168                 for j in range(len(fInside)):
    169                     fInside[j] = pi_path.contains_point(xy_array_trans[j,:])
    170                
    171                 fInside=fInside*(1-isSet)
    172             #
    173             # Find indices of points we need to adjust
    174             fInds=(fInside==1.).nonzero()[0]
     165                    pi_path=pi
     166                notSet=(isSet==0.).nonzero()[0]
     167                fInds = inside_polygon(xy_array_trans[notSet,:], pi_path)
     168                fInds = notSet[fInds]
     169             
    175170            if(len(fInds)>0):
    176171                if(hasattr(fi,'__call__')):
  • trunk/anuga_core/source/anuga/utilities/spatialInputUtil.py

    r9293 r9299  
    4848import struct
    4949import numpy
    50 from matplotlib import path
     50#from matplotlib import path
     51from anuga.geometry.polygon import inside_polygon
    5152
    5253try:
     
    627628   
    628629                      The x/y point spacing on the trial-grid will be close to
    629                       approx_grid_spacing, but we ensure there are at least 3x3 points on the trial grid.
     630                      approx_grid_spacing, but we ensure there are at least 4x4 points on the trial grid.
    630631                      Also, we reduce the spacing so that the min_x+R and max_x-R
    631632                        are both similarly close to the polygon extents [see definition of R below]
     
    655656   
    656657        # Make a 'grid' of points which covers the polygon
    657         xGridCount=max( numpy.ceil( (poly_xmax-poly_xmin)/approx_grid_spacing[0]+1. ).astype(int), 3)
     658        xGridCount=max( numpy.ceil( (poly_xmax-poly_xmin)/approx_grid_spacing[0]+1. ).astype(int), 4)
    658659        R=(poly_xmax-poly_xmin)*eps
    659660        Xvals=numpy.linspace(poly_xmin+R,poly_xmax-R, xGridCount)
    660         yGridCount=max( numpy.ceil( (poly_ymax-poly_ymin)/approx_grid_spacing[1]+1. ).astype(int), 3)
     661        yGridCount=max( numpy.ceil( (poly_ymax-poly_ymin)/approx_grid_spacing[1]+1. ).astype(int), 4)
    661662        R=(poly_ymax-poly_ymin)*eps
    662663        Yvals=numpy.linspace(poly_ymin+R,poly_ymax-R, yGridCount)
     
    665666        Grid=numpy.vstack([xGrid.flatten(),yGrid.flatten()]).transpose()
    666667   
    667         # Now find the xy values which are actually inside the polygon
    668         polpath=path.Path(polygonArr)
    669         keepers=[]
    670         for i in range(len(Grid[:,0])):
    671            if(polpath.contains_point(Grid[i,:])):
    672                 keepers=keepers+[i]
    673         #import pdb
    674         #pdb.set_trace()
     668        keepers = inside_polygon(Grid, polygon)
     669        if(len(keepers)==0):
     670            import pdb
     671            pdb.set_trace()
     672        ## Now find the xy values which are actually inside the polygon
     673        #polpath=path.Path(polygonArr)
     674        #keepers=[]
     675        #for i in range(len(Grid[:,0])):
     676        #   if(polpath.contains_point(Grid[i,:])):
     677        #        keepers=keepers+[i]
     678        ##import pdb
     679        ##pdb.set_trace()
    675680        xyInside=Grid[keepers,:]
    676681   
  • trunk/anuga_core/source/anuga/utilities/test_quantity_setting_functions.py

    r9244 r9299  
    153153        allDat=numpy.vstack([xs,ys,elev]).transpose()
    154154        util.Make_Geotif(allDat, output_quantities=['ElevTest'], EPSG_CODE=32756,
    155                         output_dir='.', CellSize=1.)
     155                        output_dir='.', CellSize=1.,k_nearest_neighbours=1)
    156156
    157157        # Make a polygon-point pair which we use to set elevation in a 'channel'
     
    232232        allDat=numpy.vstack([xs,ys,elev]).transpose()
    233233        util.Make_Geotif(allDat, output_quantities=['ElevTest'], EPSG_CODE=32756,
    234                         output_dir='.', CellSize=1.)
     234                        output_dir='.', CellSize=1.,k_nearest_neighbours=1)
    235235
    236236        # Make a polygon-point pair which we use to set elevation in a 'channel'
Note: See TracChangeset for help on using the changeset viewer.