Con tool error: The truth value of a raster is ambiguous

3801
2
08-29-2013 02:49 AM
JoannaGrand
New Contributor
I'm trying to execute the Con statement below in a Python script and keep getting the error: 'The value of the truth raster is ambiguous'.  I've read all the postings on this subject and tried every possible combination of parentheses I can think of but the problem persists. 

outGrid = Con(((Raster(pSaltmarsh) > 0) & ((Raster(pLuwet) == 5940) or (Raster(pLuwet) == 5942) or (Raster(pLuwet) == 5943) or (Raster(pLuwet) == 5944) or (Raster(pLuwet) == 5955) or (Raster(pLuwet) == 5947) or (Raster(pLuwet) == 5948) or (Raster(pLuwet) == 5949) or (Raster(pLuwet) == 5950) or (Raster(pLuwet) == 5952) or (Raster(pLuwet) == 5958) or (Raster(pLuwet) == 5959) or (Raster(pLuwet) == 259260) or (Raster(pLuwet) == 894516) or (Raster(pLuwet) == 59400) or (Raster(pLuwet) == 59490) or (Raster(pLuwet) == 59500))),pSaltmarsh,pLuwet)

Any help would be much appreciated!
0 Kudos
2 Replies
DanPatterson_Retired
MVP Esteemed Contributor
You can't next multiple "or" statements like that  What is your intent?  Why not reclassify one of the rasters into a binary grid prior using the con statement
0 Kudos
RyanDeBruyn
Esri Contributor
jgrand, your issue is the use of the python boolean "or" instead of the map albegra operator "|".

Please refer to the help topic for working with map algebra operators and their precedence: http://resources.arcgis.com/en/help/main/10.1/index.html#//00p600000008000000


Regarding the ambiguos error....
This exception has to do with the overloading of operators. The bitwise operators (like '&') are used in arcpy.sa to overload the Spatial Analyst boolean operators (unfortunately, we cannot overload the boolean operators). But we don't control the operator precedence rules, so arcpy.sa's boolean 'and' has the precedense of Python's bitwise 'and'.

Look here for Python's precedence rules: http://docs.python.org/2/reference/expressions.html#operator-precedence

This error is always thrown when Python tries to coerce a raster to a single boolean value. The general Python rule is that class instances always evaluate to True. However we need to think of rasters as number-like objects, not as Raster class instances. While you can cast a single number to a single boolean value, you cannot do it for a collection of numbers like a numpy array and a raster.

So, whatever values are in the raster, if we don't catch this situation like we do, a raster instance always evaluates to True. People would be writing code like this and be confused:

if raster:
  print "True!"
else:
  print "False!"


False will never be printed, whatever the values in the raster are. By throwing an exception we want to guard people from assuming that we support spatial conditions.

Here is another example:

>>> out = raster1 == 1 & raster2 == 2
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
ValueError: The truth value of a raster is ambiguous. Invalid use of raster with Boolean operator or function. Check the use of parentheses where applicable.


From the precedence table it can be seen that the bitwise operators have a higher precedence than the comparison operators, so they will execute first:
out = raster1 == (1 & raster2) == 2


This is equivalent to:
tmpA = 1 & raster2
out = raster1 == tmpA and tmpA == 2


Using types
out = rasterA and rasterB


Now Python tries to coerce the raster operands to boolean values, which triggers the exception.

Providing correct perenthesis the expression will execute successfully.
>>> out = (raster1 == 1) & (raster2 == 2)
0 Kudos