Beispiel #1
0
def interp(datain,lonsin,latsin,lonsout,latsout,checkbounds=False,mode='nearest',cval=0.0,order=3):
    """
 dataout = interp(datain,lonsin,latsin,lonsout,latsout,mode='constant',cval=0.0,order=3)

 interpolate data (datain) on a regularly spaced lat/lon grid (with lons=lonsin
 lats=latsin) to a grid with lons=lonsout, lats=latsout.

 datain is a rank-2 array with 1st dimension corresponding to longitude,
 2nd dimension latitude.

 lonsin, latsin are rank-1 Numeric arrays containing longitudes and latitudes
 of datain grid in increasing order (i.e. from Greenwich meridian eastward, and
 South Pole northward)

 lonsout, latsout are rank-2 Numeric arrays containing lons and lats out desired
 output grid (typically a native map projection grid).

 If checkbounds=True, values of lonsout and latsout are checked to see that
 they lie within the range specified by lonsin and latsing.  Default is
 False, and values outside the borders are handled in the manner described
 by the 'mode' parameter (default mode='nearest', which means the nearest
 boundary value is used). See section 20.2 of the numarray docs for 
 information on the 'mode' keyword.

 See numarray.nd_image.map_coordinates documentation for information on
 the other optional keyword parameters.  The order keyword can be 0 
 for nearest neighbor interpolation (nd_image only allows 1-6) - if
 order=0 bounds checking is done even if checkbounds=False.
    """
    # lons and lats must be monotonically increasing.
    # lonsin, latsin assumed equally spaced.
    # make sure lonsin, latsin increasing.
    if lonsin[-1]-lonsin[0] < 0 or latsin[-1]-latsin[0] < 0:
        raise ValueError, 'lonsin and latsin must be increasing!'
    # make sure lonsin, latsin are regularly spaced.
    delon = lonsin[1:]-lonsin[0:-1]
    delat = latsin[1:]-latsin[0:-1]
    if max(delat)-min(delat) > 1.e-4 or max(delon)-min(delon) > 1.e-4:
        raise ValueError, 'lat/lon grid must be uniform!'
    # optionally, check that lonsout,latsout are 
    # within region defined by lonsin,latsin.
    if checkbounds or order == 0:
        if min(N.ravel(lonsout)) < min(lonsin) or \
           max(N.ravel(lonsout)) > max(lonsin) or \
           min(N.ravel(latsout)) < min(latsin) or \
           max(N.ravel(latsout)) > max(latsin):
            raise ValueError, 'latsout or lonsout outside range of latsin or lonsin'
    xcoords = (len(lonsin)-1)*(lonsout-lonsin[0])/(lonsin[-1]-lonsin[0])
    ycoords = (len(latsin)-1)*(latsout-latsin[0])/(latsin[-1]-latsin[0])
    coords = [ycoords,xcoords]
    # interpolate to projection grid using numarray.nd_image spline filter.
    if order:
        return nd_image.map_coordinates(datain,coords,mode=mode,cval=cval,order=order)
    else:
        # nearest neighbor interpolation if order=0.
        # uses index arrays, so first convert to numarray.
        datatmp = N.array(datain,datain.typecode())
        xi = N.around(xcoords).astype('i')
        yi = N.around(ycoords).astype('i')
        return datatmp[yi,xi]
	def numarray_max(inputarray):
		'''
		faster than numarray.nd_image.max
		'''
		f = numarray.ravel(inputarray)
		i = numarray.argmax(f)
		return float(f[i])
Beispiel #3
0
def _min_or_max_filter(input, size, footprint, structure, output, mode, cval,
                       origin, minimum):
    if structure is None:
        if footprint is None:
            if size is None:
                raise RuntimeError, "no footprint provided"
            separable = True
        else:
            footprint = numarray.asarray(footprint, numarray.Bool)
            if numarray.alltrue(numarray.ravel(footprint)):
                size = footprint.shape
                footprint = None
                separable = True
            else:
                separable = False
    else:
        structure = numarray.asarray(structure, type=numarray.Float64)
        separable = False
        if footprint is None:
            footprint = numarray.ones(structure.shape, numarray.Bool)
        else:
            footprint = numarray.asarray(footprint, numarray.Bool)
    input = numarray.asarray(input)
    if isinstance(input.type(), numarray.ComplexType):
        raise TypeError, 'Complex type not supported'
    output, return_value = _ni_support._get_output(output, input)
    origins = _ni_support._normalize_sequence(origin, input.rank)
    if separable:
        sizes = _ni_support._normalize_sequence(size, input.rank)
        axes = range(input.rank)
        axes = [(axes[ii], sizes[ii], origins[ii]) for ii in range(len(axes))
                if sizes[ii] > 1]
        if minimum:
            filter = minimum_filter1d
        else:
            filter = maximum_filter1d
        if len(axes) > 0:
            for axis, size, origin in axes:
                filter(input, int(size), axis, output, mode, cval, origin)
                input = output
        else:
            output[...] = input[...]
    else:
        fshape = [ii for ii in footprint.shape if ii > 0]
        if len(fshape) != input.rank:
            raise RuntimeError, 'footprint array has incorrect shape.'
        for origin, lenf in zip(origins, fshape):
            if (lenf // 2 + origin < 0) or (lenf // 2 + origin > lenf):
                raise ValueError, 'invalid origin'
        if not footprint.iscontiguous():
            footprint = footprint.copy()
        if structure is not None:
            if len(structure.shape) != input.rank:
                raise RuntimeError, 'structure array has incorrect shape'
            if not structure.iscontiguous():
                structure = structure.copy()
        mode = _ni_support._extend_mode_to_code(mode)
        _nd_image.min_or_max_filter(input, footprint, structure, output, mode,
                                    cval, origins, minimum)
    return return_value
	def numarray_max(inputarray):
		'''
		faster than numarray.nd_image.max
		'''
		f = numarray.ravel(inputarray)
		i = numarray.argmax(f)
		return float(f[i])
Beispiel #5
0
def _min_or_max_filter(input, size, footprint, structure, output, mode, cval, origin, minimum):
    if structure is None:
        if footprint is None:
            if size is None:
                raise RuntimeError, "no footprint provided"
            separable = True
        else:
            footprint = numarray.asarray(footprint, numarray.Bool)
            if numarray.alltrue(numarray.ravel(footprint)):
                size = footprint.shape
                footprint = None
                separable = True
            else:
                separable = False
    else:
        structure = numarray.asarray(structure, type=numarray.Float64)
        separable = False
        if footprint is None:
            footprint = numarray.ones(structure.shape, numarray.Bool)
        else:
            footprint = numarray.asarray(footprint, numarray.Bool)
    input = numarray.asarray(input)
    if isinstance(input.type(), numarray.ComplexType):
        raise TypeError, "Complex type not supported"
    output, return_value = _ni_support._get_output(output, input)
    origins = _ni_support._normalize_sequence(origin, input.rank)
    if separable:
        sizes = _ni_support._normalize_sequence(size, input.rank)
        axes = range(input.rank)
        axes = [(axes[ii], sizes[ii], origins[ii]) for ii in range(len(axes)) if sizes[ii] > 1]
        if minimum:
            filter = minimum_filter1d
        else:
            filter = maximum_filter1d
        if len(axes) > 0:
            for axis, size, origin in axes:
                filter(input, int(size), axis, output, mode, cval, origin)
                input = output
        else:
            output[...] = input[...]
    else:
        fshape = [ii for ii in footprint.shape if ii > 0]
        if len(fshape) != input.rank:
            raise RuntimeError, "footprint array has incorrect shape."
        for origin, lenf in zip(origins, fshape):
            if (lenf // 2 + origin < 0) or (lenf // 2 + origin > lenf):
                raise ValueError, "invalid origin"
        if not footprint.iscontiguous():
            footprint = footprint.copy()
        if structure is not None:
            if len(structure.shape) != input.rank:
                raise RuntimeError, "structure array has incorrect shape"
            if not structure.iscontiguous():
                structure = structure.copy()
        mode = _ni_support._extend_mode_to_code(mode)
        _nd_image.min_or_max_filter(input, footprint, structure, output, mode, cval, origins, minimum)
    return return_value
Beispiel #6
0
    def __call__(self, lon, lat, inverse=False):
        """
 Calling a Proj class instance with the arguments lon, lat will
 convert lon/lat (in degrees) to x/y native map projection 
 coordinates (in meters).  If optional keyword 'inverse' is
 True (default is False), the inverse transformation from x/y
 to lon/lat is performed.

 For cylindrical equidistant projection ('cyl'), this
 does nothing (i.e. x,y == lon,lat).

 For mercator projection ('merc'), x == lon, but y has units
 of meters.

 lon,lat can be either scalar floats or N arrays.
        """
        if self.projection == 'cyl':  # for cyl x,y == lon,lat
            return lon, lat
        # if inputs are numarray arrays, get shape and typecode.
        try:
            shapein = lon.shape
            lontypein = lon.typecode()
            lattypein = lat.typecode()
        except:
            shapein = False
        # make sure inputs have same shape.
        if shapein and lat.shape != shapein:
            raise ValueError, 'lon, lat must be scalars or numarrays with the same shape'
        if shapein:
            x = N.ravel(lon).tolist()
            y = N.ravel(lat).tolist()
            if inverse:
                outx, outy = self._inv(x, y)
            else:
                outx, outy = self._fwd(x, y)
            outx = N.reshape(N.array(outx, lontypein), shapein)
            outy = N.reshape(N.array(outy, lattypein), shapein)
        else:
            if inverse:
                outx, outy = self._inv(lon, lat)
            else:
                outx, outy = self._fwd(lon, lat)
        return outx, outy
Beispiel #7
0
    def __call__(self,lon,lat,inverse=False):
        """
 Calling a Proj class instance with the arguments lon, lat will
 convert lon/lat (in degrees) to x/y native map projection 
 coordinates (in meters).  If optional keyword 'inverse' is
 True (default is False), the inverse transformation from x/y
 to lon/lat is performed.

 For cylindrical equidistant projection ('cyl'), this
 does nothing (i.e. x,y == lon,lat).

 For mercator projection ('merc'), x == lon, but y has units
 of meters.

 lon,lat can be either scalar floats or N arrays.
        """
        if self.projection == 'cyl': # for cyl x,y == lon,lat
            return lon,lat
        # if inputs are numarray arrays, get shape and typecode.
        try:
            shapein = lon.shape
            lontypein = lon.typecode()
            lattypein = lat.typecode()
        except:
            shapein = False
        # make sure inputs have same shape.
        if shapein and lat.shape != shapein:
            raise ValueError, 'lon, lat must be scalars or numarrays with the same shape'
        if shapein:
            x = N.ravel(lon).tolist()
            y = N.ravel(lat).tolist()
            if inverse:
                outx, outy = self._inv(x,y)
            else:
                outx, outy = self._fwd(x,y)
            outx = N.reshape(N.array(outx,lontypein),shapein)
            outy = N.reshape(N.array(outy,lattypein),shapein)
        else:
            if inverse:
                outx,outy = self._inv(lon,lat)
            else:
                outx,outy = self._fwd(lon,lat)
        return outx,outy
Beispiel #8
0
 def run(self):
     x = self.args[0] * self.args[0]
     for i in range(10000):
         SIZE = 10**int(random.random() * 3)
         a = numarray.arange(1, SIZE * SIZE + 1, shape=(SIZE, SIZE))
         a.transpose()
         b = a.copy()
         a = a * x
         assert numarray.logical_and.reduce(numarray.ravel((a / x) == b))
         # if (i % 100 == 0):
         print self.getName(),
         sys.stdout.flush()
Beispiel #9
0
 def run(self):
     x = self.args[0]*self.args[0]
     for i in range(10000):
         SIZE = 10**int(random.random()*3)
         a = numarray.arange(1, SIZE*SIZE+1, shape=(SIZE,SIZE))
         a.transpose()
         b = a.copy()
         a = a * x
         assert numarray.logical_and.reduce(numarray.ravel((a / x) == b))
         # if (i % 100 == 0):
         print self.getName(),
         sys.stdout.flush()
Beispiel #10
0
def interp(datain,
           lonsin,
           latsin,
           lonsout,
           latsout,
           checkbounds=False,
           mode='nearest',
           cval=0.0,
           order=3):
    """
 dataout = interp(datain,lonsin,latsin,lonsout,latsout,mode='constant',cval=0.0,order=3)

 interpolate data (datain) on a rectilinear lat/lon grid (with lons=lonsin
 lats=latsin) to a grid with lons=lonsout, lats=latsout.

 datain is a rank-2 array with 1st dimension corresponding to longitude,
 2nd dimension latitude.

 lonsin, latsin are rank-1 Numeric arrays containing longitudes and latitudes
 of datain grid in increasing order (i.e. from Greenwich meridian eastward, and
 South Pole northward)

 lonsout, latsout are rank-2 Numeric arrays containing lons and lats out desired
 output grid (typically a native map projection grid).

 If checkbounds=True, values of lonsout and latsout are checked to see that
 they lie within the range specified by lonsin and latsing.  Default is
 False, and values outside the borders are handled in the manner described
 by the 'mode' parameter (default mode='nearest', which means the nearest
 boundary value is used). See section 20.2 of the numarray docs for 
 information on the 'mode' keyword.

 See numarray.nd_image.map_coordinates documentation for information on
 the other optional keyword parameters.  The order keyword can be 0 
 for nearest neighbor interpolation (nd_image only allows 1-6) - if
 order=0 bounds checking is done even if checkbounds=False.
    """
    # lonsin and latsin must be monotonically increasing.
    if lonsin[-1] - lonsin[0] < 0 or latsin[-1] - latsin[0] < 0:
        raise ValueError, 'lonsin and latsin must be increasing!'
    # optionally, check that lonsout,latsout are
    # within region defined by lonsin,latsin.
    # (this check is always done if nearest neighbor
    # interpolation (order=0) requested).
    if checkbounds or order == 0:
        if min(N.ravel(lonsout)) < min(lonsin) or \
           max(N.ravel(lonsout)) > max(lonsin) or \
           min(N.ravel(latsout)) < min(latsin) or \
           max(N.ravel(latsout)) > max(latsin):
            raise ValueError, 'latsout or lonsout outside range of latsin or lonsin'
    # compute grid coordinates of output grid.
    delon = lonsin[1:] - lonsin[0:-1]
    delat = latsin[1:] - latsin[0:-1]
    if max(delat) - min(delat) < 1.e-4 and max(delon) - min(delon) < 1.e-4:
        # regular input grid.
        xcoords = (len(lonsin) - 1) * (lonsout - lonsin[0]) / (lonsin[-1] -
                                                               lonsin[0])
        ycoords = (len(latsin) - 1) * (latsout - latsin[0]) / (latsin[-1] -
                                                               latsin[0])
    else:
        # irregular (but still rectilinear) input grid.
        lonsoutflat = N.ravel(lonsout)
        latsoutflat = N.ravel(latsout)
        ix = N.searchsorted(lonsin, lonsoutflat) - 1
        iy = N.searchsorted(latsin, latsoutflat) - 1
        xcoords = N.zeros(ix.shape, 'f')
        ycoords = N.zeros(iy.shape, 'f')
        for n, i in enumerate(ix):
            if i < 0:
                xcoords[n] = -1  # outside of range on lonsin (lower end)
            elif i >= len(lonsin) - 1:
                xcoords[n] = len(lonsin)  # outside range on upper end.
            else:
                xcoords[n] = float(i) + (lonsoutflat[n] - lonsin[i]) / (
                    lonsin[i + 1] - lonsin[i])
        xcoords = N.reshape(xcoords, lonsout.shape)
        for m, j in enumerate(iy):
            if j < 0:
                ycoords[m] = -1  # outside of range of latsin (on lower end)
            elif j >= len(latsin) - 1:
                ycoords[m] = len(latsin)  # outside range on upper end
            else:
                ycoords[m] = float(j) + (latsoutflat[m] - latsin[j]) / (
                    latsin[j + 1] - latsin[j])
        ycoords = N.reshape(ycoords, latsout.shape)
    coords = [ycoords, xcoords]
    # interpolate to output grid using numarray.nd_image spline filter.
    if order:
        return nd_image.map_coordinates(datain,
                                        coords,
                                        mode=mode,
                                        cval=cval,
                                        order=order)
    else:
        # nearest neighbor interpolation if order=0.
        # uses index arrays, so first convert to numarray.
        datatmp = N.array(datain, datain.typecode())
        xi = N.around(xcoords).astype('i')
        yi = N.around(ycoords).astype('i')
        return datatmp[yi, xi]
Beispiel #11
0
    def __call__(self,lon,lat,inverse=False):
        """
 Calling a Proj class instance with the arguments lon, lat will
 convert lon/lat (in degrees) to x/y native map projection 
 coordinates (in meters).  If optional keyword 'inverse' is
 True (default is False), the inverse transformation from x/y
 to lon/lat is performed.

 Example usage:
 >>> from proj import Proj
 >>> params = {}
 >>> params['proj'] = 'lcc' # lambert conformal conic
 >>> params['lat_1'] = 30.  # standard parallel 1
 >>> params['lat_2'] = 50.  # standard parallel 2
 >>> params['lon_0'] = -96  # central meridian
 >>> map = Proj(params)
 >>> x,y = map(-107,40)     # find x,y coords of lon=-107,lat=40
 >>> print x,y
 -92272.1004461 477477.890988


 lon,lat can be either scalar floats or numarray arrays.
        """
	npts = 1
        # if inputs are numarray arrays, get shape and total number of pts.
	try:
	    shapein = lon.shape
	    npts = reduce(lambda x, y: x*y, shapein)
	    lontypein = lon.typecode()
	    lattypein = lat.typecode()
	except:
            shapein = False
        # make sure inputs have same shape.
	if shapein and lat.shape != shapein:
            raise ValueError, 'lon, lat must be scalars or numarray arrays with the same shape'
        # make a rank 1 array with x/y (or lon/lat) pairs.
        xy = numarray.zeros(2*npts,'d')
        xy[::2] = numarray.ravel(lon)
        xy[1::2] = numarray.ravel(lat)
        # convert degrees to radians, meters to cm.
	if not inverse:
           xy = _dg2rad*xy
        else:
           xy = 10.*xy
        # write input data to binary file.
        xyout = array.array('d')
        xyout.fromlist(xy.tolist())
	# set up cmd string, scale factor for output.
	if inverse:
            cmd = self.projcmd+' -I'
	    scale = _rad2dg
        else:
            cmd = self.projcmd
	    scale = 0.1
	# use pipes for input and output if amount of 
	# data less than default buffer size (usually 8192).
	# otherwise use pipe for input, tempfile for output
	if 2*npts*8 > 8192:
            fd, fn=tempfile.mkstemp(); os.close(fd); stdout=open(fn,'rb')
            cmd = cmd+' > '+fn
            stdin=os.popen(cmd,'w')
	    xyout.tofile(stdin)
	    stdin.close()
            outxy = scale*numarray.fromstring(stdout.read(),'d')
	    stdout.close()
	    os.remove(fn)
        else:
            stdin,stdout=os.popen2(cmd,mode='b')
	    xyout.tofile(stdin)
	    stdin.close()
            outxy = scale*numarray.fromstring(stdout.read(),'d')
	    stdout.close()
        # return numarray arrays or scalars, depending on type of input.
	if shapein:
            outx = numarray.reshape(outxy[::2],shapein).astype(lontypein)
            outy = numarray.reshape(outxy[1::2],shapein).astype(lattypein)
        else:
            outx = outxy[0]; outy = outxy[1]
        return outx,outy
Beispiel #12
0
    urcornerx = dx*(nx-1); urcornery = dy*(ny-1)
    llcornerlon, llcornerlat = awips221(llcornerx, llcornery, inverse=True)
    lrcornerlon, lrcornerlat = awips221(lrcornerx, lrcornery, inverse=True)
    urcornerlon, urcornerlat = awips221(urcornerx, urcornery, inverse=True)
    ulcornerlon, ulcornerlat = awips221(ulcornerx, ulcornery, inverse=True)
    print '4 corners of AWIPS grid 221:'
    print llcornerlon, llcornerlat
    print lrcornerlon, lrcornerlat
    print urcornerlon, urcornerlat
    print ulcornerlon, ulcornerlat
    print 'from GRIB docs'
    print '(see http://www.nco.ncep.noaa.gov/pmb/docs/on388/tableb.html)'
    print '   -145.5  1.0'
    print '   -68.318 0.897'
    print '   -2.566 46.352'
    print '   148.639 46.635'
# compute lons and lats for the whole AWIPS grid 221 (377x249).
    x = numarray.zeros((nx,ny),'d')
    y = numarray.zeros((nx,ny),'d')
    x = dx*numarray.indices(x.shape)[0,:,:]
    y = dy*numarray.indices(y.shape)[1,:,:]
    import time; t1 = time.clock()
    lons, lats = awips221(x, y, inverse=True)
    t2 = time.clock()
    print 'compute lats/lons for all points on AWIPS 221 grid (%sx%s)' %(nx,ny)
    print 'max/min lons'
    print min(numarray.ravel(lons)),max(numarray.ravel(lons))
    print 'max/min lats'
    print min(numarray.ravel(lats)),max(numarray.ravel(lats))
    print 'took',t2-t1,'secs'
Beispiel #13
0
def distance_transform_bf(input,
                          metric="euclidean",
                          sampling=None,
                          return_distances=True,
                          return_indices=False,
                          distances=None,
                          indices=None):
    """Distance transform function by a brute force algorithm.

    This function calculates the distance transform of the input, by
    replacing each background element (zero values), with its
    shortest distance to the foreground (any element non-zero). Three
    types of distance metric are supported: 'euclidean', 'city_block'
    and 'chessboard'.

    In addition to the distance transform, the feature transform can
    be calculated. In this case the index of the closest background
    element is returned along the first axis of the result.

    The return_distances, and return_indices flags can be used to
    indicate if the distance transform, the feature transform, or both
    must be returned.

    Optionally the sampling along each axis can be given by the
    sampling parameter which should be a sequence of length equal to
    the input rank, or a single number in which the sampling is assumed
    to be equal along all axes. This parameter is only used in the
    case of the euclidean distance transform.

    This function employs a slow brute force algorithm, see also the
    function distance_transform_cdt for more efficient city_block and
    chessboard algorithms.

    the distances and indices arguments can be used to give optional
    output arrays that must be of the correct size and type (Float64
    and Int32).
    """
    if (not return_distances) and (not return_indices):
        msg = 'at least one of distances/indices must be specified'
        raise RuntimeError, msg
    tmp1 = numarray.asarray(input) != 0
    struct = generate_binary_structure(tmp1.rank, tmp1.rank)
    tmp2 = binary_dilation(tmp1, struct)
    tmp2 = numarray.logical_xor(tmp1, tmp2)
    tmp1 = tmp1.astype(numarray.Int8) - tmp2.astype(numarray.Int8)
    del tmp2
    metric = metric.lower()
    if metric == 'euclidean':
        metric = 1
    elif metric == 'cityblock':
        metric = 2
    elif metric == 'chessboard':
        metric = 3
    else:
        raise RuntimeError, 'distance metric not supported'
    if sampling != None:
        sampling = _ni_support._normalize_sequence(sampling, tmp1.rank)
        sampling = numarray.asarray(sampling, type=numarray.Float64)
        if not sampling.iscontiguous():
            sampling = sampling.copy()
    if return_indices:
        ft = numarray.zeros(tmp1.shape, type=numarray.Int32)
    else:
        ft = None
    if return_distances:
        if distances == None:
            if metric == 1:
                dt = numarray.zeros(tmp1.shape, type=numarray.Float64)
            else:
                dt = numarray.zeros(tmp1.shape, type=numarray.UInt32)
        else:
            if distances.shape != tmp1.shape:
                raise RuntimeError, 'distances array has wrong shape'
            if metric == 1:
                if distances.type() != numarray.Float64:
                    raise RuntimeError, 'distances array must be Float64'
            else:
                if distances.type() != numarray.UInt32:
                    raise RuntimeError, 'distances array must be UInt32'
            dt = distances
    else:
        dt = None
    _nd_image.distance_transform_bf(tmp1, metric, sampling, dt, ft)
    if return_indices:
        if isinstance(indices, numarray.NumArray):
            if indices.type() != numarray.Int32:
                raise RuntimeError, 'indices must of Int32 type'
            if indices.shape != (tmp1.rank, ) + tmp1.shape:
                raise RuntimeError, 'indices has wrong shape'
            tmp2 = indices
        else:
            tmp2 = numarray.indices(tmp1.shape, type=numarray.Int32)
        ft = numarray.ravel(ft)
        for ii in range(tmp2.shape[0]):
            rtmp = numarray.ravel(tmp2[ii, ...])[ft]
            rtmp.setshape(tmp1.shape)
            tmp2[ii, ...] = rtmp
        ft = tmp2
    # construct and return the result
    result = []
    if return_distances and not isinstance(distances, numarray.NumArray):
        result.append(dt)
    if return_indices and not isinstance(indices, numarray.NumArray):
        result.append(ft)
    if len(result) == 2:
        return tuple(result)
    elif len(result) == 1:
        return result[0]
    else:
        return None
Beispiel #14
0
def interp(datain,lonsin,latsin,lonsout,latsout,checkbounds=False,mode='nearest',cval=0.0,order=3):
    """
 dataout = interp(datain,lonsin,latsin,lonsout,latsout,mode='constant',cval=0.0,order=3)

 interpolate data (datain) on a rectilinear lat/lon grid (with lons=lonsin
 lats=latsin) to a grid with lons=lonsout, lats=latsout.

 datain is a rank-2 array with 1st dimension corresponding to longitude,
 2nd dimension latitude.

 lonsin, latsin are rank-1 Numeric arrays containing longitudes and latitudes
 of datain grid in increasing order (i.e. from Greenwich meridian eastward, and
 South Pole northward)

 lonsout, latsout are rank-2 Numeric arrays containing lons and lats out desired
 output grid (typically a native map projection grid).

 If checkbounds=True, values of lonsout and latsout are checked to see that
 they lie within the range specified by lonsin and latsing.  Default is
 False, and values outside the borders are handled in the manner described
 by the 'mode' parameter (default mode='nearest', which means the nearest
 boundary value is used). See section 20.2 of the numarray docs for 
 information on the 'mode' keyword.

 See numarray.nd_image.map_coordinates documentation for information on
 the other optional keyword parameters.  The order keyword can be 0 
 for nearest neighbor interpolation (nd_image only allows 1-6) - if
 order=0 bounds checking is done even if checkbounds=False.
    """
    # lonsin and latsin must be monotonically increasing.
    if lonsin[-1]-lonsin[0] < 0 or latsin[-1]-latsin[0] < 0:
        raise ValueError, 'lonsin and latsin must be increasing!'
    # optionally, check that lonsout,latsout are 
    # within region defined by lonsin,latsin.
    # (this check is always done if nearest neighbor 
    # interpolation (order=0) requested).
    if checkbounds or order == 0:
        if min(N.ravel(lonsout)) < min(lonsin) or \
           max(N.ravel(lonsout)) > max(lonsin) or \
           min(N.ravel(latsout)) < min(latsin) or \
           max(N.ravel(latsout)) > max(latsin):
            raise ValueError, 'latsout or lonsout outside range of latsin or lonsin'
    # compute grid coordinates of output grid.
    delon = lonsin[1:]-lonsin[0:-1]
    delat = latsin[1:]-latsin[0:-1]
    if max(delat)-min(delat) < 1.e-4 and max(delon)-min(delon) < 1.e-4:
        # regular input grid.
        xcoords = (len(lonsin)-1)*(lonsout-lonsin[0])/(lonsin[-1]-lonsin[0])
        ycoords = (len(latsin)-1)*(latsout-latsin[0])/(latsin[-1]-latsin[0])
    else:
        # irregular (but still rectilinear) input grid.
        lonsoutflat = N.ravel(lonsout)
        latsoutflat = N.ravel(latsout)
        ix = N.searchsorted(lonsin,lonsoutflat)-1
        iy = N.searchsorted(latsin,latsoutflat)-1
        xcoords = N.zeros(ix.shape,'f')
        ycoords = N.zeros(iy.shape,'f')
        for n,i in enumerate(ix):
            if i < 0:
                xcoords[n] = -1 # outside of range on lonsin (lower end)
            elif i >= len(lonsin)-1:
                xcoords[n] = len(lonsin) # outside range on upper end.
            else:
                xcoords[n] = float(i)+(lonsoutflat[n]-lonsin[i])/(lonsin[i+1]-lonsin[i])
        xcoords = N.reshape(xcoords,lonsout.shape)
        for m,j in enumerate(iy):
            if j < 0:
                ycoords[m] = -1 # outside of range of latsin (on lower end)
            elif j >= len(latsin)-1:
                ycoords[m] = len(latsin) # outside range on upper end
            else:
                ycoords[m] = float(j)+(latsoutflat[m]-latsin[j])/(latsin[j+1]-latsin[j])
        ycoords = N.reshape(ycoords,latsout.shape)
    coords = [ycoords,xcoords]
    # interpolate to output grid using numarray.nd_image spline filter.
    if order:
        return nd_image.map_coordinates(datain,coords,mode=mode,cval=cval,order=order)
    else:
        # nearest neighbor interpolation if order=0.
        # uses index arrays, so first convert to numarray.
        datatmp = N.array(datain,datain.typecode())
        xi = N.around(xcoords).astype('i')
        yi = N.around(ycoords).astype('i')
        return datatmp[yi,xi]
Beispiel #15
0
def distance_transform_cdt(input,
                           structure='chessboard',
                           return_distances=True,
                           return_indices=False,
                           distances=None,
                           indices=None):
    """Distance transform for chamfer type of transforms.

    The structure determines the type of chamfering that is done. If
    the structure is equal to 'cityblock' a structure is generated
    using generate_binary_structure with a squared distance equal to
    1. If the structure is equal to 'chessboard', a structure is
    generated using generate_binary_structure with a squared distance
    equal to the rank of the array. These choices correspond to the
    common interpretations of the cityblock and the chessboard
    distance metrics in two dimensions.

    In addition to the distance transform, the feature transform can
    be calculated. In this case the index of the closest background
    element is returned along the first axis of the result.

    The return_distances, and return_indices flags can be used to
    indicate if the distance transform, the feature transform, or both
    must be returned.
    
    The distances and indices arguments can be used to give optional
    output arrays that must be of the correct size and type (both Int32).
    """
    if (not return_distances) and (not return_indices):
        msg = 'at least one of distances/indices must be specified'
        raise RuntimeError, msg
    ft_inplace = isinstance(indices, numarray.NumArray)
    dt_inplace = isinstance(distances, numarray.NumArray)
    input = numarray.asarray(input)
    if structure == 'cityblock':
        rank = input.rank
        structure = generate_binary_structure(rank, 1)
    elif structure == 'chessboard':
        rank = input.rank
        structure = generate_binary_structure(rank, rank)
    else:
        try:
            structure = numarray.asarray(structure)
        except:
            raise RuntimeError, 'invalid structure provided'
        for s in structure.shape:
            if s != 3:
                raise RuntimeError, 'structure sizes must be equal to 3'
    if not structure.iscontiguous():
        structure = structure.copy()
    if dt_inplace:
        if distances.type() != numarray.Int32:
            raise RuntimeError, 'distances must be of Int32 type'
        if distances.shape != input.shape:
            raise RuntimeError, 'distances has wrong shape'
        dt = distances
        dt[...] = numarray.where(input, -1, 0).astype(numarray.Int32)
    else:
        dt = numarray.where(input, -1, 0).astype(numarray.Int32)
    rank = dt.rank
    if return_indices:
        sz = dt.nelements()
        ft = numarray.arange(sz, shape=dt.shape, type=numarray.Int32)
    else:
        ft = None
    _nd_image.distance_transform_op(structure, dt, ft)
    dt = dt[tuple([slice(None, None, -1)] * rank)]
    if return_indices:
        ft = ft[tuple([slice(None, None, -1)] * rank)]
    _nd_image.distance_transform_op(structure, dt, ft)
    dt = dt[tuple([slice(None, None, -1)] * rank)]
    if return_indices:
        ft = ft[tuple([slice(None, None, -1)] * rank)]
        ft = numarray.ravel(ft)
        if ft_inplace:
            if indices.type() != numarray.Int32:
                raise RuntimeError, 'indices must of Int32 type'
            if indices.shape != (dt.rank, ) + dt.shape:
                raise RuntimeError, 'indices has wrong shape'
            tmp = indices
        else:
            tmp = numarray.indices(dt.shape, type=numarray.Int32)
        for ii in range(tmp.shape[0]):
            rtmp = numarray.ravel(tmp[ii, ...])[ft]
            rtmp.setshape(dt.shape)
            tmp[ii, ...] = rtmp
        ft = tmp

    # construct and return the result
    result = []
    if return_distances and not dt_inplace:
        result.append(dt)
    if return_indices and not ft_inplace:
        result.append(ft)
    if len(result) == 2:
        return tuple(result)
    elif len(result) == 1:
        return result[0]
    else:
        return None
Beispiel #16
0
def distance_transform_cdt(input, structure = 'chessboard',
                        return_distances = True, return_indices = False,
                        distances = None, indices = None):
    """Distance transform for chamfer type of transforms.

    The structure determines the type of chamfering that is done. If
    the structure is equal to 'cityblock' a structure is generated
    using generate_binary_structure with a squared distance equal to
    1. If the structure is equal to 'chessboard', a structure is
    generated using generate_binary_structure with a squared distance
    equal to the rank of the array. These choices correspond to the
    common interpretations of the cityblock and the chessboard
    distance metrics in two dimensions.

    In addition to the distance transform, the feature transform can
    be calculated. In this case the index of the closest background
    element is returned along the first axis of the result.

    The return_distances, and return_indices flags can be used to
    indicate if the distance transform, the feature transform, or both
    must be returned.
    
    The distances and indices arguments can be used to give optional
    output arrays that must be of the correct size and type (both Int32).
    """
    if (not return_distances) and (not return_indices):
        msg = 'at least one of distances/indices must be specified'
        raise RuntimeError, msg    
    ft_inplace = isinstance(indices, numarray.NumArray)
    dt_inplace = isinstance(distances, numarray.NumArray)
    input = numarray.asarray(input)
    if structure == 'cityblock':
        rank = input.rank
        structure = generate_binary_structure(rank, 1)
    elif structure == 'chessboard':
        rank = input.rank
        structure = generate_binary_structure(rank, rank)
    else:
        try:
            structure = numarray.asarray(structure)
        except:
            raise RuntimeError, 'invalid structure provided'
        for s in structure.shape:
            if s != 3:
                raise RuntimeError, 'structure sizes must be equal to 3'
    if not structure.iscontiguous():
        structure = structure.copy()
    if dt_inplace:
        if distances.type() != numarray.Int32:
            raise RuntimeError, 'distances must be of Int32 type'    
        if distances.shape != input.shape:
            raise RuntimeError, 'distances has wrong shape'
        dt = distances
        dt[...] = numarray.where(input, -1, 0).astype(numarray.Int32)
    else:
        dt = numarray.where(input, -1, 0).astype(numarray.Int32)
    rank = dt.rank
    if return_indices:
        sz = dt.nelements()
        ft = numarray.arange(sz, shape=dt.shape, type = numarray.Int32)
    else:
        ft = None
    _nd_image.distance_transform_op(structure, dt, ft)
    dt = dt[tuple([slice(None, None, -1)] * rank)]
    if return_indices:
        ft = ft[tuple([slice(None, None, -1)] * rank)]
    _nd_image.distance_transform_op(structure, dt, ft)
    dt = dt[tuple([slice(None, None, -1)] * rank)]
    if return_indices:
        ft = ft[tuple([slice(None, None, -1)] * rank)]
        ft = numarray.ravel(ft)
        if ft_inplace:
            if indices.type() != numarray.Int32:
                raise RuntimeError, 'indices must of Int32 type'
            if indices.shape != (dt.rank,) + dt.shape:
                raise RuntimeError, 'indices has wrong shape'
            tmp = indices
        else:
            tmp = numarray.indices(dt.shape, type = numarray.Int32)
        for ii in range(tmp.shape[0]):
            rtmp = numarray.ravel(tmp[ii, ...])[ft]
            rtmp.setshape(dt.shape)
            tmp[ii, ...] = rtmp
        ft = tmp

    # construct and return the result
    result = []
    if return_distances and not dt_inplace:
        result.append(dt)
    if return_indices and not ft_inplace:
        result.append(ft)
    if len(result) == 2:
        return tuple(result)
    elif len(result) == 1:
        return result[0]
    else:
        return None
Beispiel #17
0
def distance_transform_bf(input, metric = "euclidean", sampling = None,
                          return_distances = True, return_indices = False,
                          distances = None, indices = None):
    """Distance transform function by a brute force algorithm.

    This function calculates the distance transform of the input, by
    replacing each background element (zero values), with its
    shortest distance to the foreground (any element non-zero). Three
    types of distance metric are supported: 'euclidean', 'city_block'
    and 'chessboard'.

    In addition to the distance transform, the feature transform can
    be calculated. In this case the index of the closest background
    element is returned along the first axis of the result.

    The return_distances, and return_indices flags can be used to
    indicate if the distance transform, the feature transform, or both
    must be returned.

    Optionally the sampling along each axis can be given by the
    sampling parameter which should be a sequence of length equal to
    the input rank, or a single number in which the sampling is assumed
    to be equal along all axes. This parameter is only used in the
    case of the euclidean distance transform.

    This function employs a slow brute force algorithm, see also the
    function distance_transform_cdt for more efficient city_block and
    chessboard algorithms.

    the distances and indices arguments can be used to give optional
    output arrays that must be of the correct size and type (Float64
    and Int32).
    """
    if (not return_distances) and (not return_indices):
        msg = 'at least one of distances/indices must be specified'
        raise RuntimeError, msg
    tmp1 = numarray.asarray(input) != 0
    struct = generate_binary_structure(tmp1.rank, tmp1.rank)
    tmp2 = binary_dilation(tmp1, struct)
    tmp2 = numarray.logical_xor(tmp1, tmp2)
    tmp1 = tmp1.astype(numarray.Int8) - tmp2.astype(numarray.Int8)
    del tmp2
    metric = metric.lower()
    if metric == 'euclidean':
        metric = 1
    elif metric == 'cityblock':
        metric = 2
    elif metric == 'chessboard':
        metric = 3
    else:
        raise RuntimeError, 'distance metric not supported'
    if sampling != None:
        sampling = _ni_support._normalize_sequence(sampling, tmp1.rank)
        sampling = numarray.asarray(sampling, type = numarray.Float64)
        if not sampling.iscontiguous():
            sampling = sampling.copy()
    if return_indices:
        ft = numarray.zeros(tmp1.shape, type = numarray.Int32)
    else:
        ft = None
    if return_distances:
        if distances == None:
            if metric == 1:
                dt = numarray.zeros(tmp1.shape, type = numarray.Float64)
            else:
                dt = numarray.zeros(tmp1.shape, type = numarray.UInt32)
        else:
            if distances.shape != tmp1.shape:
                raise RuntimeError, 'distances array has wrong shape'
            if metric == 1:
                if distances.type() != numarray.Float64:
                    raise RuntimeError, 'distances array must be Float64'
            else:
                if distances.type() != numarray.UInt32:
                    raise RuntimeError, 'distances array must be UInt32'
            dt = distances
    else:
        dt = None
    _nd_image.distance_transform_bf(tmp1, metric, sampling, dt, ft)
    if return_indices:
        if isinstance(indices, numarray.NumArray):
            if indices.type() != numarray.Int32:
                raise RuntimeError, 'indices must of Int32 type'
            if indices.shape != (tmp1.rank,) + tmp1.shape:
                raise RuntimeError, 'indices has wrong shape'
            tmp2 = indices
        else:
            tmp2 = numarray.indices(tmp1.shape, type = numarray.Int32)
        ft = numarray.ravel(ft)
        for ii in range(tmp2.shape[0]):
            rtmp = numarray.ravel(tmp2[ii, ...])[ft]
            rtmp.setshape(tmp1.shape)
            tmp2[ii, ...] = rtmp
        ft = tmp2
    # construct and return the result
    result = []
    if return_distances and not isinstance(distances, numarray.NumArray):
        result.append(dt)
    if return_indices and not isinstance(indices, numarray.NumArray):
        result.append(ft)
    if len(result) == 2:
        return tuple(result)
    elif len(result) == 1:
        return result[0]
    else:
        return None
Beispiel #18
0
def _isClose(a, b, *args, **kargs):
    return bool(na.allclose(na.ravel(a), na.ravel(b), *args, **kargs))
Beispiel #19
0
    def __call__(self, lon, lat, inverse=False):
        """
 Calling a Proj class instance with the arguments lon, lat will
 convert lon/lat (in degrees) to x/y native map projection 
 coordinates (in meters).  If optional keyword 'inverse' is
 True (default is False), the inverse transformation from x/y
 to lon/lat is performed.

 Example usage:
 >>> from proj import Proj
 >>> params = {}
 >>> params['proj'] = 'lcc' # lambert conformal conic
 >>> params['lat_1'] = 30.  # standard parallel 1
 >>> params['lat_2'] = 50.  # standard parallel 2
 >>> params['lon_0'] = -96  # central meridian
 >>> map = Proj(params)
 >>> x,y = map(-107,40)     # find x,y coords of lon=-107,lat=40
 >>> print x,y
 -92272.1004461 477477.890988


 lon,lat can be either scalar floats or numarray arrays.
        """
        npts = 1
        # if inputs are numarray arrays, get shape and total number of pts.
        try:
            shapein = lon.shape
            npts = reduce(lambda x, y: x * y, shapein)
            lontypein = lon.typecode()
            lattypein = lat.typecode()
        except:
            shapein = False
        # make sure inputs have same shape.
        if shapein and lat.shape != shapein:
            raise ValueError, 'lon, lat must be scalars or numarray arrays with the same shape'
        # make a rank 1 array with x/y (or lon/lat) pairs.
        xy = numarray.zeros(2 * npts, 'd')
        xy[::2] = numarray.ravel(lon)
        xy[1::2] = numarray.ravel(lat)
        # convert degrees to radians, meters to cm.
        if not inverse:
            xy = _dg2rad * xy
        else:
            xy = 10. * xy
        # write input data to binary file.
        xyout = array.array('d')
        xyout.fromlist(xy.tolist())
        # set up cmd string, scale factor for output.
        if inverse:
            cmd = self.projcmd + ' -I'
            scale = _rad2dg
        else:
            cmd = self.projcmd
            scale = 0.1

# use pipes for input and output if amount of
# data less than default buffer size (usually 8192).
# otherwise use pipe for input, tempfile for output
        if 2 * npts * 8 > 8192:
            fd, fn = tempfile.mkstemp()
            os.close(fd)
            stdout = open(fn, 'rb')
            cmd = cmd + ' > ' + fn
            stdin = os.popen(cmd, 'w')
            xyout.tofile(stdin)
            stdin.close()
            outxy = scale * numarray.fromstring(stdout.read(), 'd')
            stdout.close()
            os.remove(fn)
        else:
            stdin, stdout = os.popen2(cmd, mode='b')
            xyout.tofile(stdin)
            stdin.close()
            outxy = scale * numarray.fromstring(stdout.read(), 'd')
            stdout.close()
        # return numarray arrays or scalars, depending on type of input.
        if shapein:
            outx = numarray.reshape(outxy[::2], shapein).astype(lontypein)
            outy = numarray.reshape(outxy[1::2], shapein).astype(lattypein)
        else:
            outx = outxy[0]
            outy = outxy[1]
        return outx, outy
Beispiel #20
0
    lrcornerlon, lrcornerlat = awips221(lrcornerx, lrcornery, inverse=True)
    urcornerlon, urcornerlat = awips221(urcornerx, urcornery, inverse=True)
    ulcornerlon, ulcornerlat = awips221(ulcornerx, ulcornery, inverse=True)
    print '4 corners of AWIPS grid 221:'
    print llcornerlon, llcornerlat
    print lrcornerlon, lrcornerlat
    print urcornerlon, urcornerlat
    print ulcornerlon, ulcornerlat
    print 'from GRIB docs'
    print '(see http://www.nco.ncep.noaa.gov/pmb/docs/on388/tableb.html)'
    print '   -145.5  1.0'
    print '   -68.318 0.897'
    print '   -2.566 46.352'
    print '   148.639 46.635'
    # compute lons and lats for the whole AWIPS grid 221 (377x249).
    x = numarray.zeros((nx, ny), 'd')
    y = numarray.zeros((nx, ny), 'd')
    x = dx * numarray.indices(x.shape)[0, :, :]
    y = dy * numarray.indices(y.shape)[1, :, :]
    import time
    t1 = time.clock()
    lons, lats = awips221(x, y, inverse=True)
    t2 = time.clock()
    print 'compute lats/lons for all points on AWIPS 221 grid (%sx%s)' % (nx,
                                                                          ny)
    print 'max/min lons'
    print min(numarray.ravel(lons)), max(numarray.ravel(lons))
    print 'max/min lats'
    print min(numarray.ravel(lats)), max(numarray.ravel(lats))
    print 'took', t2 - t1, 'secs'