Skip to content

PythonRasterFunction

Feroz Abdul-Kadar edited this page Jan 23, 2015 · 39 revisions

Anatomy of a Python Raster Function

This section describes methods that must be implemented by a class to be accepted by ArcGIS Python Raster Function. These methods enables ArcGIS and the end-user to have a "conversation" with your raster function towards obtaining properties, pixel values, mask, and metadata associated with the processed raster.

self.name = ""
self.description = ""

def getParameterInfo(self)
def getConfiguration(self, **scalars)
def updateRasterInfo(self, **kwargs)
def selectRasters(self, tlc, shape, props)
def updatePixels(self, tlc, shape, props, **pixelBlocks)
def updateKeyMetadata(self, names, bandIndex, **keyMetadata)

.getParameterInfo()

This method provides information on each parameter to the raster function. This method must be defined for the class to be recognized as a valid raster function.

Arguments

None

Returns

A list of dictionary objects where each dictionary contains attributes that describe a parameter. These are the recognized attributes of a parameter:

  • name

    Required. String.

    This attribute contains a keyword that uniquely identifies this parameter in the set of parameters accepted by the raster function object.

  • dataType

    Required. String.

    This attribute contains a keyword representing the data type of the value held by this parameter. Allowed values are: numeric, string, raster, rasters, and boolean.

  • value

    Required. Default: None.

    This attribute contains the default value associated with this parameter.

  • required

    Optional. Boolean. Default: False.

    This attribute contains a flag indicating whether this parameter is required or optional.

  • displayName

    Optional. String. Default: Value specified in the name attribute.

    This attribute contains text representing a friendly name for this parameter. The value of this attribute is used in Python raster function's property page and other UI components.

  • domain

    Optional. Tuple(string). None.

    This attribute contains a tuple representing the set of allowed values for this parameter. If specified, the property page shows a drop-down list pre-populated with these values. This attribute is applicable only to parameters where dataType='string'.

  • description

    Optional. String. Default: None.

    This attribute contains text that describes the parameter in detail. The text is also displayed as a tooltip in the Python raster function's property page.

def getParameterInfo(self):
    return [
        {
            'name': 'raster',
            'dataType': 'raster',
            'value': None,
            'required': True,
            'displayName': "Raster",
            'description': "The primary multi-band input raster containing red and infrared bands."
        },
        {
            'name': 'method',
            'dataType': 'string',
            'value': 'Colormap',
            'required': False,
            'domain': ('Raw', 'Grayscale', 'Colormap'),
            'displayName': "Output Image Type",
            'description': "The type of output expected from this function. Specify Raw for scientific analysis. Pick Grayscale or Colomap for visualization."
        },
    ]

.getConfiguration()

This method, if defined, manages how the output raster is constructed. It also controls aspects of parent dataset on which this raster function is applied. Decisions in this method may be based on the user-updated values of one or more scalar (non-raster) parameters. This method is invoked after .getParameterInfo() but before .updateRasterInfo() by which time all rasters will have been loaded.

Arguments

None

Returns

A dictionary describing the configuration. These are the recognized attributes:

  • extractBands

    Optional. Tuple(int). Default: None.

    Contains indexes of bands of the input raster that need to be extracted. The first band has index 0. If unspecified, all bands of the input raster are available in .updatePixels()

  • compositeRasters

    Optional. Boolean. Default: False.

    Indicates whether all input rasters are composited as a single multi-band raster. If set to True, a raster by the name composite is available in .updateRasterInfo() and .updatePixels().

  • inheritProperties

    Optional. Integer. Default: 0xFF.

    Bitwise-OR'd integer that indicates the set of input raster properties that are inherited by the output raster. If unspecified, all properties are inherited. These are the recognized values:

    Value Description
    1 Pixel type
    2 NoData
    4 Dimensions (spatial reference, extent, and cell-size)
    8 Resampling type
  • invalidateProperties

    Optional. Integer. Default: 0.

    A flag constructed as a bitwise-OR'd integer indicating the set of properties of the parent dataset that needs to be invalidated. If unspecified, no property gets invalidated. These are the recognized values:

    Value Description
    1 XForm stored by the function raster dataset
    2 Statistics stored by the function raster dataset
    4 Histogram stored by the function raster dataset
    8 The key properties stored by the function raster dataset
  • padding

    Optional. Integer. Default: 0.

    The number of extra pixels needed on each side of input pixel blocks.

  • inputMask

    Optional. Boolean. Default: False.

    Indicates whether NoData mask arrays associated with all input rasters are needed by this function for proper construction of output pixels and mask. Set this attribute to True only if you need the mask of the input raster(s) in the .updatePixels() method--perhaps to help you compute output mask. For improved performance, input masks are not made available if this attribute is unspecified.

def getConfiguration(self, **scalars):
    return {
      'extractBands': (0, 2),            # we only need the first (red) and third (blue) band.
      'compositeRasters': False,
      'inheritProperties': 2 | 4 | 8,    # inherit everything but the pixel type (1)
      'invalidateProperties': 2 | 4 | 8, # invalidate these aspects because we are modifying pixel values and updating key properties.
      'padding': 0,                      # No padding needed. Return input pixel block as is. 
      'inputMask': False                 # Don't need mask in .updatePixels. 
    }

.updateRasterInfo()

This method, if defined, updates information that defines the output raster. It's invoked after .getConfiguration() and each time the dataset containing the python raster function is initialized.

def updateRasterInfo(self, **kwargs):
    kwargs['output_info']['bandCount'] = 1      # output is a single band raster
    kwargs['output_info']['statistics'] = ({'minimum': 0.0, 'maximum': 180}, )  # we know something about the stats of the outgoing HeatIndex raster. 
    kwargs['output_info']['histogram'] = ()     # we know nothing about the histogram of the outgoing raster.
    kwargs['output_info']['pixelType'] = 'f4'   # bit-depth of the outgoing HeatIndex raster based on user-specified parameters
    return kwargs

Arguments

The keyword argument kwargs contains all user-specified scalar values and information associated with each input rasters. Use kwargs['x'] to obtain the user-specified value of the scalar whose name attribute is x in the .getParameterInfo().

If x represents a raster, kwargs['x_info'] will be a dictionary containing information associated with the raster. You can access aspects of a particular raster's information like this: kwargs['<rasterName>_info']['<propertyName>'] where is the value of the name attribute of the raster parameter and is an aspect of the raster information.

If represents a parameter of type rasters, dataType='rasters', then kwargs['<rasterName>_info'] is a tuple of raster-info dictionaries.

kwargs['output_info'] is always available and populated with values inherited from the first raster and based on the attributes returned by .getConfiguration().

These are the properties associated with a raster information:

  • bandCount

    Integer

    The number of bands in the raster.

  • pixelType

    String

    representation of pixel type of the raster. These are the allowed values: {t1, t2, t4, i1, i2, i4, u1, u2, u4, f4, f8} as described here

  • noData

    ndarray(<bandCount> x <dtype>)

    An array of one value per raster band representing NoData.

  • cellSize

    Tuple(2 x Floats)

    representing cell-size in the x- and y-direction.

  • nativeExtent

    Tuple(4 x Floats)

    representing XMin, YMin, XMax, YMax values of the native image coordinates.

  • nativeSpatialReference

    Integer

    representing the EPSG code of the native image coordinate system.

  • geodataXform

    String

    representation of the associated XForm between native image and map coordinate systems.

  • extent

    Tuple(4 x Floats)

    representing XMin, YMin, XMax, YMax values of the map coordinates.

  • spatialReference

    Integer

    representing the EPSG code of the raster's map coordinate system.

  • colormap

    Tuple(ndarray(int32), 3 x ndarray(uint8)

    A tuple of four arrays where the first array contains 32-bit integers corresponding to pixel values in the indexed raster. The subsequent three arrays contain unsigned 8-bit integers corresponding to the Red, Green, and Blue components of the mapped color. The sizes of all arrays must match and correspond to the number of colors in the RGB image.

  • rasterAttributeTable

    Tuple(String, Tuple(Strings)

    A tuple of a string representing the path of the attribute table, and another tuple representing field names. Use the information in this tuple with arcpy.da.TableToNumPyArray() to access the values.

  • levelOfDetails

    Integer

    The number of level of details in the input raster.

  • origin

    Tuple(Floats)

    Tuple of x- and y-coordinate of the origin.

  • resampling

    Optional. Boolean. Default: False.

    Indicates whether the Python raster function is capable of delivering pixels that have been resampled to match the resolution of the request.

    When resampling is False, the .updatePixels() method receives pixel blocks of the input raster at the native resolution of the input (or at the resolution of any image pyramid closest to the request resolution). Each pixel block corresponding to the output raster that's delivered by .updatePixels()--still in native resolution--eventually gets resampled by ArcGIS to match request resolution.

    When resampling is True, the .updatePixels() method receives resampled pixel blocks of the input raster at request resolution and, therefore, delivers output pixel blocks in request resolution.

    Note: The resolution of the output raster is made available to Python raster function's .selectRasters() and .updatePixels() methods via the cellSize property.

  • histogram

    Tuple(<bandCount> x numpy.ndarray)

    Tuple where each entry is an array of histogram values of a band.

  • statistics

    Tuple(<bandCount> x Dictionary)

    Tuple of statistics values. Each entry in the tuple is a dictionary containing the following attributes of band statistics:

    Attribute Data Type Description
    minimum Float Approximate lowest value.
    maximum Float Approximate highest value.
    mean Float Approximate average value.
    standardDeviation Float Approximate measure of spread of values about the mean.
    skipFactorX Integer Number of horizontal pixels between samples when calculating statistics.
    skipFactorY Integer Number of vertical pixels between samples when calculating statistics.

Note:

  • The tuple in cellSize and maximumCellSize attributes can be used to construct an arcpy.Point object.
  • The tuple in extent, nativeExtent and origin attributes can be used to construct an arcpy.Extent object.
  • The EPSG code in nativeSpatialReference and spatialReference attributes can be used to construct an arcpy.SpatialReference object.

Returns

A dictionary containing output raster info. This method can update the values of the dictionary in kwargs['output_info'] depending on the kind of operation in .updatePixels()


.selectRasters()

This method, if defined, enables the Python raster function to define a subset of input rasters from which pixels are read before being fed into the updatePixels method.

This method is only invoked when more than one parameter of type raster is defined in getParameterInfo().


.updatePixels()

This method, if defined, provides output pixels based on pixel blocks associated with all input rasters. A python raster function that doesn't actively modify output pixel values doesn't need to define this method.

Arguments

#####tlc Tuple(2 x Floats)

representing the coordinates of the top-left corner of the pixel request.

#####shape Tuple(ints)

Represents the shape of ndarray that defines the output pixel block. For a single-band pixel block, the tuple contains two ints (rows, columns). For multi-band output raster, the tuple defines a three-dimensional array (bands, rows, columns). The shape associated with the outgoing pixel block and mask must match this argument's value.

#####props dictionary

This argument contains properties that define the output raster from which a pixel block--of dimension and location is defined by the shape and tlc arguments--is being requested.

These are the available attributes in this dictionary:

  • extent: Tuple(4 x Floats) representing XMin, YMin, XMax, YMax values of the output raster's map coordinates.

  • pixelType: String representation of pixel type of the raster. These are the allowed values: {t1, t2, t4, i1, i2, i4, u1, u2, u4, f4, f8} as described here

  • spatialReference: Integer representing the EPSG code of the output raster's map coordinate system.

  • cellSize: Tuple(2 x Floats) representing cell-size in the x- and y-direction.

  • width: Integer representing number of columns of pixels in the output raster.

  • height: Integer representing number of rows of pixels in the output raster.

  • noData: Tuple(Numeric) representing invalid or excluded value per band.

#####pixelBlocks dictionary

Keyword argument containing pixels and mask associated with each input raster.

For a raster parameter with dataType='raster' and name='x', pixelBlocks['x_pixels'] and pixelBlocks['x_mask'] are numpy.ndarrays of pixel and mask values for that input raster. For a parameter of type rasters where dataType='rasters', these are tuples of ndarrays--one entry per raster.

The arrays are three-dimensional for multi-band rasters.

Note

  • The pixelBlocks dictionary does not contain any scalars parameters. Those are only available in .getConfiguration() or .updateRasterInfo().

Returns

A dictionary with a numpy array containing pixel values in the output_pixels key and, optionally, an array representing the mask in the output_mask key. The shape of both arrays must match the shape argument. The data type of the output_pixels array should be as indicated in props['pixelType'], and the data type of output_mask should be u1.


.updateKeyMetadata()

This method, if defined, updates dataset-level or band-level key metadata. When a request for a dataset's key metadata is made, this method allows the python raster function to invalidate or overwrite specific requests.

Arguments

  • names

    Tuple(string)

    containing names of the properties being requested. An empty tuple indicates that all properties are being requested.

  • bandIndex

    Integer

    representing the raster band for which key metadata is being requested. Values are zero-based. And bandIndex == -1 indicates that the request is for dataset-level key properties.

  • keyMetadata

    dictionary

    Keyword argument containing all currently known metadata (or a subset as defined by the names tuple).

####Returns The updated keyMetadata dictionary.


.isLicensed()

This method, if defined, indicates whether this python raster function is licensed to execute. It's invoked soon after the function object is constructed. It enables the python raster function to halt execution, given information about the parent product and the context of execution. It also allows the function to, optionally, indicate the expected product level and extension that must be available before execution can proceed.

Arguments

The productInfo keyword argument describes the current execution environment. It contains the following attributes:

  • productName

    String

    This attribute contains the name of the product {Desktop, Server, Engine, ...}

  • version

    String

    This attribute contains the version associated with the product.

  • path

    String

    This attribute contains the installation path of the product.

  • major

    Integer

    This attribute contains the major version number of the product.

  • minor

    Float

    This attribute contains the minor version number of the product.

  • build

    Integer

    This attribute contains the build number associated with the product.

  • spNumber

    Integer

    This attribute contains the service pack number, if applicable.

  • spBuild

    Integer

    This attribute contains the service pack build, if applicable.

Returns

A dictionary containing an attribute that indicates whether licensing checks specific to this python raster function has passed. The dictionary may contain additional attributes that control additional licensing checks enforced by ArcGIS Python Raster Function:

  • okToRun

    Required. Boolean.

    This attribute indicates whether it's OK to proceed with the use of this raster function object. This attribute must be present and specifically set to False for execution to halt. Otherwise, it's assumed to be True and that it's OK to proceed.

  • message

    Optional. String.

    This attribute contains message to be displayed to the user when okToRun is False.

  • productLevel

    Optional. String.

    This attribute contains the product license-level expected from the parent application. Allowed values include: Basic, Standard, Advanced.

  • extension

    Optional. String.

    This attribute contains the name of the extension that must be available before ArcGIS is allowed to use this raster function. The set of recognized extension names are enumerated here.

def isLicensed(self, **productInfo): 
    major = productInfo.get('major', 0) 
    minor = productInfo.get('minor', 0.0) 
    build = productInfo.get('build', 0)

    return {
        'okToRun': major >= 10 and minor >= 3.0 and build >= 4276,
        'message': "The python raster function is only compatible with ArcGIS 10.3 build 4276",
        'productLevel': 'Standard', 
        'extension': 'Image'
    }
Clone this wiki locally