Skip to content
Gregory Brunner edited this page May 22, 2018 · 3 revisions

Debugging Python Raster Functions

Python Raster functions can be debugged using several methods. Here are a few methods that we have found to work best.

Python Tools for Visual Studio (PTVS)

This method is applicable only if you have Visual Studio installed on your machine. We used Visual Studio 2013 and the following instructions may vary slightly depending on which version of Visual Studio you are using.

You can download Python Tools for Visual Studio from here. Once you have installed PTVS, navigate to the following link. Download the symbols and follow the steps outlined in the document to register the symbols in Visual Studio. If you are using ArcGIS 10.4/10.5, the Python version is 2.7.10. If you are using ArcGIS Pro, the Python version is 3.5.1. The symbols can be installed to a new Python environment other than the one embedded in ArcGIS.

Steps to debug Python Raster Functions:

  1. After you have installed and setup PTVS, open Visual studio and open the Python raster function script that you wish to debug. Insert a break point(s) somewhere in your updatePixels() method.

  2. Open ArcMap and apply the Python raster function to a raster using the Image Analysis window.

  3. Go back to Visual Studio and click on the ‘Attach’ button on the main toolbar.

  4. When the ‘Attach to Process’ dialog opens, hit the ‘Select’ button next to the ‘Attach To’ parameter. Check Python in the ‘Debug these code types’ list and click ‘Ok’. Make sure you uncheck “Native’ code type or any other code type that might be checked on.

  5. Next, select ArcMap.exe in the ‘Available Processes’ window and then click the ‘Attach’ button.

  6. At this point, you may need to go back to ArcMap and pan/zoom the image in order to invoke the function. Visual studio should react automatically.

  7. You should have hit the breakpoint set in step 1. You will now be able to step through your python code.

There is also an interactive Python window that is made available when you download PTVS. It can be found under: Tools > Python Tools > Python Debug Interactive.

This interactive debugger makes it easy to diagnose and resolve issues in your Python code. Detailed instructions on debugging Python code in Visual Studio can be found here.

Python with Debug View

Python raster functions can be traced using any Python IDE along with Debug View. The only additional software required for this method is Debug View. This can be downloaded for free from here.

  1. Once you have downloaded Debug View, open the Python raster function you are working with in any IDE.

  2. Import the following at the top of your script.

    from utils import ZonalAttributesTable, Trace
    
  3. Put the following somewhere in your init() method

    self.trace = Trace()
    
  4. Use this throughout your script to print whatever variable you want watch. Your script name will replace “YourScript” in the code snippet. The variable that you would like to see should go where “x” is. You can use this as many times as necessary throughout your script.

    self.trace.log("Trace|YourScript.getParameterInfo|x={0}, y={1}".format(str(x),    3434))
    
  5. Once you have saved your Python script, open ArcGIS Desktop or Pro and Debug View.

  6. Apply the function to a raster using ArcMap or ArcGIS Pro.

  7. At this point Debug View should start retuning outputs from ArcGIS. It will return quite a bit of information so you will likely need to use filtering (Edit > Filter/Highlight). Use the filter to find the variables that you set up in step 4.

Debugging with Pickle Files

Python pickle (.p) files can be used as an effective method of capturing and exporting the values in your pixel blocks as numpy arrays that can be explored outside of the Python Raster Function. These pickles can then be read into a script outside of the raster function so that algorithms can be developed against a pixel block. This method can be particularly helpful when first developing or prototyping a Python Raster Function.

To export a pixel block as a pickle, you can use the following code within the updatePixels function:

    import pickle
    import uuid
    import datatime

    debug_logs_directory = r'C:\raster-functions\pickles'

    fname = 'prf_' + uuid.uuid4().hex + '_{:%Y_%b_%d_%H_%M_%S}.txt'.format(datetime.datetime.now())
    filename = os.path.join(debug_logs_directory, fname)

    pix_blocks = pixelBlocks['rasters_pixels']
    pix_array = np.asarray(pix_blocks)

    pickle.dump(pix_array, open(filename,"wb"))

To explore this pickle outside of the raster function, you can write a script that reads in this pickle file. The pickle can be loaded as follows:

    import pickle
    import os

    pickle_file = os.path.join(path, filename)
    pix_array = pickle.load(open(pickle_file,"rb"))

From here, you can work with the exported pixel block and prototype the algorithm that you plan to deploy as a Python Raster Function.