Python efficiency with Rasters

1141
5
09-21-2012 12:54 PM
RobinCheskin
New Contributor III
The script below multiplies two rasters, where the cell value of one raster is a parameter.
#Import modules
import os
import arcpy
from arcpy import env
from arcpy.sa import *
arcpy.CheckOutExtension("Spatial")

#Set local variables
wks = arcpy.GetParameterAsText(0) # input workspace
inRaster1 = arcpy.GetParameterAsText(1) # input raster layer
env.workspace = wks

#Perform Constant Raster Function
constantValue = arcpy.GetParameterAsText(2) # input weight value
cellSize = 100
outExtent = Extent(871599.89, 982834.44, 912502.09, 1070920.9)
outConstRaster = CreateConstantRaster(constantValue, "FLOAT", cellSize, outExtent)
outConstRaster.save("temp1")

#Perform Times Function
outTimes = Raster(inRaster1)* Raster("temp1")
outRaster1 = "Wt_" + os.path.basename(inRaster1)
outTimes.save(outRaster1)

#Create script output and delete constant raster
arcpy.SetParameterAsText(3,outRaster1)
arcpy.Delete_management("temp1")


This works, but is not optimal and much slower than I would like.  I tried this code without saving outConstRaster and just calling it as a raster object, but I kept getting the same error: "TypeError: expected a raster or layer name."  This will also need to work for up to 10 different raster layers.

Any thoughts on making this more efficient?
Tags (2)
0 Kudos
5 Replies
ArkadiuszMatoszka
Occasional Contributor II
Hi,

First of all, don't save constant value raster, if you using it only ones, just use it in multiplication. It will remove few operations (saving, rereading and deleting). Another thing, is type of raster, use "Float" only if necessary, operations or floating numbers are much more complex for processor.
import os
import arcpy
from arcpy import env
from arcpy.sa import *
arcpy.CheckOutExtension("Spatial")

#Set local variables
wks = arcpy.GetParameterAsText(0) # input workspace
inRaster1 = arcpy.GetParameterAsText(1) # input raster layer
env.workspace = wks

#Perform Constant Raster Function
constantValue = arcpy.GetParameterAsText(2) # input weight value
cellSize = 100
outExtent = Extent(871599.89, 982834.44, 912502.09, 1070920.9)
if int(constantValue) == constantValue:
  type = 'INTEGER'
else:
  type = 'FLOAT'
outConstRaster = CreateConstantRaster(constantValue, type, cellSize, outExtent)

#Perform Times Function
outTimes = Raster(inRaster1)* outConstRaster
outRaster1 = "Wt_" + os.path.basename(inRaster1)
outTimes.save(outRaster1)

#Create script output and delete constant raster
arcpy.SetParameterAsText(3,outRaster1)
0 Kudos
RobinCheskin
New Contributor III
Thank you, this worked nicely for the single raster.  The challenge I am facing is creating the script for up to 10 rasters:
#Import modules
import os
import arcpy
from arcpy import env
from arcpy.sa import *
arcpy.CheckOutExtension("Spatial")

#Set local variables
wks = arcpy.GetParameterAsText(0) # input workspace
inRaster1 = arcpy.GetParameterAsText(1) # input raster layer
inRaster2 = arcpy.GetParameterAsText(2) # input raster layer
inRaster3 = arcpy.GetParameterAsText(3) # input raster layer (optional)
inRaster4 = arcpy.GetParameterAsText(4) # input raster layer (optional)
inRaster5 = arcpy.GetParameterAsText(5) # input raster layer (optional)
inRaster6 = arcpy.GetParameterAsText(6) # input raster layer (optional)
inRaster7 = arcpy.GetParameterAsText(7) # input raster layer (optional)
inRaster8 = arcpy.GetParameterAsText(8) # input raster layer (optional)
inRaster9 = arcpy.GetParameterAsText(9) # input raster layer (optional)
inRaster10 = arcpy.GetParameterAsText(10) # input raster layer (optional)
env.workspace = wks

#Multiply Raster by a constant with CreateConstantRaster
constantValue1 = arcpy.GetParameterAsText(11) # input weight value
constantValue2 = arcpy.GetParameterAsText(12) # input weight value
constantValue3 = arcpy.GetParameterAsText(13) # input weight value (optional)
constantValue4 = arcpy.GetParameterAsText(14) # input weight value (optional)
constantValue5 = arcpy.GetParameterAsText(15) # input weight value (optional)
constantValue6 = arcpy.GetParameterAsText(16) # input weight value (optional)
constantValue7 = arcpy.GetParameterAsText(17) # input weight value (optional)
constantValue8 = arcpy.GetParameterAsText(18) # input weight value (optional)
constantValue9 = arcpy.GetParameterAsText(19) # input weight value (optional)
constantValue10 = arcpy.GetParameterAsText(20) # input weight value (optional)
cellSize = 100
outExtent = Extent(871599.89, 982834.44, 912502.09, 1070920.9)

outConstRaster1 = CreateConstantRaster(constantValue1, "FLOAT", cellSize, outExtent)
outConstRaster2 = CreateConstantRaster(constantValue2, "FLOAT", cellSize, outExtent)
outConstRaster3 = CreateConstantRaster(constantValue3, "FLOAT", cellSize, outExtent)
outConstRaster4 = CreateConstantRaster(constantValue4, "FLOAT", cellSize, outExtent)
outConstRaster5 = CreateConstantRaster(constantValue5, "FLOAT", cellSize, outExtent)
outConstRaster6 = CreateConstantRaster(constantValue6, "FLOAT", cellSize, outExtent)
outConstRaster7 = CreateConstantRaster(constantValue7, "FLOAT", cellSize, outExtent)
outConstRaster8 = CreateConstantRaster(constantValue8, "FLOAT", cellSize, outExtent)
outConstRaster9 = CreateConstantRaster(constantValue9, "FLOAT", cellSize, outExtent)
outConstRaster10 = CreateConstantRaster(constantValue10, "FLOAT", cellSize, outExtent)

#Create weighted raster layer with Times
outTimes1 = Raster(inRaster1)* outConstRaster1
outTimes2 = Raster(inRaster2)* outConstRaster2
outTimes3 = Raster(inRaster3)* outConstRaster3
outTimes4 = Raster(inRaster4)* outConstRaster4
outTimes5 = Raster(inRaster5)* outConstRaster5
outTimes6 = Raster(inRaster6)* outConstRaster6
outTimes7 = Raster(inRaster7)* outConstRaster7
outTimes8 = Raster(inRaster8)* outConstRaster8
outTimes9 = Raster(inRaster9)* outConstRaster9
outTimes10 = Raster(inRaster10)* outConstRaster10

outRaster1 = "Wt_" + os.path.basename(inRaster1)
outRaster2 = "Wt_" + os.path.basename(inRaster2)
outRaster3 = "Wt_" + os.path.basename(inRaster3)
outRaster4 = "Wt_" + os.path.basename(inRaster4)
outRaster5 = "Wt_" + os.path.basename(inRaster5)
outRaster6 = "Wt_" + os.path.basename(inRaster6)
outRaster7 = "Wt_" + os.path.basename(inRaster7)
outRaster8 = "Wt_" + os.path.basename(inRaster8)
outRaster9 = "Wt_" + os.path.basename(inRaster9)
outRaster10 = "Wt_" + os.path.basename(inRaster10)

outTimes.save(outRaster1)
outTimes.save(outRaster2)
outTimes.save(outRaster3)
outTimes.save(outRaster4)
outTimes.save(outRaster5)
outTimes.save(outRaster6)
outTimes.save(outRaster7)
outTimes.save(outRaster8)
outTimes.save(outRaster9)
outTimes.save(outRaster10)

#Create script output
env.workspace = wks1
arcpy.SetParameterAsText(21,wks1)


I have been toying around with ToolValidator b/c the script has to skip over creating a constant raster & performing times if there is no parameter (after the first 2 raster layers & weight values the parameters are optional).  Unfortunately I am stuck again.

Help would be greatly appreciated...!
0 Kudos
RobinCheskin
New Contributor III
This is what I came up with, which seems to be working:
#Import modules
import os
import arcpy
from arcpy import env
from arcpy.sa import *
arcpy.CheckOutExtension("Spatial")

#Set local variables
wks = arcpy.GetParameterAsText(0) # input workspace
wks1 = wks
inRaster1 = arcpy.GetParameterAsText(1) # input raster layer
inRaster2 = arcpy.GetParameterAsText(2) # input raster layer
inRaster3 = arcpy.GetParameterAsText(3) # input raster layer
inRaster4 = arcpy.GetParameterAsText(4) # input raster layer
inRaster5 = arcpy.GetParameterAsText(5) # input raster layer
inRaster6 = arcpy.GetParameterAsText(6) # input raster layer
inRaster7 = arcpy.GetParameterAsText(7) # input raster layer
inRaster8 = arcpy.GetParameterAsText(8) # input raster layer
inRaster9 = arcpy.GetParameterAsText(9) # input raster layer
inRaster10 = arcpy.GetParameterAsText(10) # input raster layer
env.workspace = wks
cellSize = 100
outExtent = Extent(871599.89, 982834.44, 912502.09, 1070920.9)

#Multiply Raster by a constant with CreateConstantRaster
constantValue1 = arcpy.GetParameterAsText(11) # input weight value
outConstRaster1 = CreateConstantRaster(constantValue1, "FLOAT", cellSize, outExtent)
outTimes1 = Raster(inRaster1)* outConstRaster1
outRaster1 = "Wt_" + os.path.basename(inRaster1)
outTimes1.save(outRaster1) # save raster
      
constantValue2 = arcpy.GetParameterAsText(12) # input weight value
outConstRaster2 = CreateConstantRaster(constantValue2, "FLOAT", cellSize, outExtent)
outTimes2 = Raster(inRaster2)* outConstRaster2
outRaster2 = "Wt_" + os.path.basename(inRaster2)
outTimes2.save(outRaster2)

#isinstnace test for parameter input      
constantValue3 = arcpy.GetParameterAsText(13) # input weight value
if isinstance(constantValue3, ()):
      outConstRaster3 = CreateConstantRaster(constantValue3, "FLOAT", cellSize, outExtent)
      outTimes3 = Raster(inRaster3)* outConstRaster3
      outRaster3 = "Wt_" + os.path.basename(inRaster3)
      outTimes3.save(outRaster3)
else: 
      arcpy.SetParameterAsText(21,wks1)
      sys.exit()

constantValue4 = arcpy.GetParameterAsText(14) # input weight value
if isinstance(constantValue4, ()):
      outConstRaster4 = CreateConstantRaster(constantValue4, "FLOAT", cellSize, outExtent)
      outTimes4 = Raster(inRaster4)* outConstRaster4
      outRaster4 = "Wt_" + os.path.basename(inRaster4)
      outTimes4.save(outRaster4)
else: 
      arcpy.SetParameterAsText(21,wks1)
      sys.exit()

constantValue5 = arcpy.GetParameterAsText(15) # input weight value
if isinstance(constantValue5, ()):
      outConstRaster5 = CreateConstantRaster(constantValue5, "FLOAT", cellSize, outExtent)
      outTimes5 = Raster(inRaster5)* outConstRaster5
      outRaster5 = "Wt_" + os.path.basename(inRaster5)
      outTimes5.save(outRaster5)
else: 
      arcpy.SetParameterAsText(21,wks1)
      sys.exit()

constantValue6 = arcpy.GetParameterAsText(16) # input weight value      
if isinstance(constantValue6, ()):
      outConstRaster6 = CreateConstantRaster(constantValue6, "FLOAT", cellSize, outExtent)
      outTimes6 = Raster(inRaster6)* outConstRaster6
      outRaster6 = "Wt_" + os.path.basename(inRaster6)
      outTimes6.save(outRaster6)
else: 
      arcpy.SetParameterAsText(21,wks1)
      sys.exit()

constantValue7 = arcpy.GetParameterAsText(17) # input weight value
if isinstance(constantValue7, ()):
      outConstRaster7 = CreateConstantRaster(constantValue7, "FLOAT", cellSize, outExtent)
      outTimes7 = Raster(inRaster7)* outConstRaster7
      outRaster7 = "Wt_" + os.path.basename(inRaster7)
      outTimes7.save(outRaster7)
else: 
      arcpy.SetParameterAsText(21,wks1)
      sys.exit()

constantValue8 = arcpy.GetParameterAsText(18) # input weight value
if isinstance(constantValue8, ()):
      outConstRaster8 = CreateConstantRaster(constantValue8, "FLOAT", cellSize, outExtent)
      outTimes8 = Raster(inRaster8)* outConstRaster8
      outRaster8 = "Wt_" + os.path.basename(inRaster8)
      outTimes8.save(outRaster8)
else: 
      arcpy.SetParameterAsText(21,wks1)
      sys.exit()

constantValue9 = arcpy.GetParameterAsText(19) # input weight value
if isinstance(constantValue9, ()):
      outConstRaster9 = CreateConstantRaster(constantValue9, "FLOAT", cellSize, outExtent)
      outTimes9 = Raster(inRaster9)* outConstRaster9
      outRaster9 = "Wt_" + os.path.basename(inRaster9)
      outTimes9save(outRaster9)
else: 
      arcpy.SetParameterAsText(21,wks1)
      sys.exit()

constantValue10 = arcpy.GetParameterAsText(20) # input weight value
if isinstance(constantValue10, ()):
      outConstRaster10 = CreateConstantRaster(constantValue10, "FLOAT", cellSize, outExtent)
      outTimes10 = Raster(inRaster10)* outConstRaster10
      outRaster10 = "Wt_" + os.path.basename(inRaster10)
      outTimes10.save(outRaster10)
else: 
      arcpy.SetParameterAsText(21,wks1)
      sys.exit()
0 Kudos
curtvprice
MVP Esteemed Contributor
I have been toying around with ToolValidator b/c the script has to skip over creating a constant raster & performing times if there is no parameter (after the first 2 raster layers & weight values the parameters are optional). 


I'm not so clear how you are using the isinstance() function. The usual way to do this with arcpy is by examining the returned value of arcpy.GetParameterAsText(). If the argument was not provided (and was not populated using script tool defaults or in validation code) the GetParameterAsText() result will be an empty string (not None, since the function always returns a text string).

if arcpy.GetParameterAsText(2) != "":
    do stuff with arcpy.GetParameterAsText(2)
0 Kudos
ArkadiuszMatoszka
Occasional Contributor II


if arcpy.GetParameterAsText(2) != "":
    do stuff with arcpy.GetParameterAsText(2)


Right, you can also use simple:
if arcpy.GetParameterAsText(2):
   do stuff with arcpy.GetParameterAsText(2)

Empty string is treated as Boolean False, so if there is no parameters nothing will be done.
0 Kudos