Skip to content

Instantly share code, notes, and snippets.

@mgd722
Last active May 16, 2023 00:56
Show Gist options
  • Save mgd722/d51dbd005f3eee0c26fa5afb55a0ef35 to your computer and use it in GitHub Desktop.
Save mgd722/d51dbd005f3eee0c26fa5afb55a0ef35 to your computer and use it in GitHub Desktop.
ChronoCards Script & Tool Logging Examples

Prompt

How does the plug-in track automation scripts in python or model builder or GP tools?

Sample project

River access points need to be within 800 meters of NHD rivers to be considered valid. The map below displays some points that are out of range. Using three different methods to run the same Arc commands, we will remove out of range points.

image

Interactive Python shell from within Arc

Screenshot with commands run interactively:

image

How it looks in ChronoCards timeline, documenting the mistake I made:

image

Detailed outputs of the each tool as viewed in ChronoCards:

image

image

Ran as a model

I ran the following model two times: once while I was building it (to test it) and then again as part of my Toolbox. It executes silently during development, but logs output when ran from the geoprocessing toolbar.

image

ChronoCards timeline, documenting that the first run was not logged (edited for brevity):

image

Detailed output of the tool, as viewed in ChronoCards (my annotations are in red):

image

As the analyst note on the timeline says, I didn't include any logging into my model so it didn't output anything other than the raw steps it took. If it did log custom messages from the model into geoprocessing history, those would be reflected in ChronoCards as well.

Ran as a custom Python-based GP tool

This is pretty similar to the output of running a model, but with more control. I ran a custom tool I wrote (PyDeletePointsMoreThan800MetersFromRivers.pyt below) which does the same thing as the model but with more descriptive logging.

Output as seen in Arc:

image

ChronoCards timeline:

image

Detailed output:

image

As you can see here, ChronoCards will catch whatever errors, warnings, or informational messages you pass in your Python-based GP tool. The two middle lines are custom things I told Arc to log.

Closing

  1. It should be noted that each item on the timeline counts as an Arc event to ChronoCards. If you have an analyst who does everything by hand and he is running each step of a tool manually, he will appear to have more events than someone who is using a tool that combines all events.
  2. We can potentially log more information regarding each of these events, but we leave a some things out to cut down on the noise. If there's something missing that you think should be included, feel free to let me know and we can investigate the feasibility of adding it in.
  3. Python scripts run entirely headlessly outside of ArcGIS Pro will not submit any events to ChronoCards. The ChronoCards ArcGIS Pro addin is not instantiated if ArcGIS Pro is not open and thus we cannot catch those events.
  4. When many items are deleted using a single tool, that is reflected as a single GP tool event in ChronoCards instead of an arbitrary number of edit events.
# -*- coding: utf-8 -*-
import arcpy
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "PyDeletePointsMoreThan800MetersFromRivers"
self.alias = "PyDeletePointsMoreThan800MetersFromRivers"
# List of tool classes associated with this toolbox
self.tools = [Tool]
class Tool(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "PyDeletePointsMoreThan800MetersFromRivers"
self.description = "Deletes river access points greater than 800 meters from the river."
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
params = None
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
error_features = arcpy.management.SelectLayerByLocation('RiverAccessPoints', 'WITHIN_A_DISTANCE', 'NHDArea',
'800 meters', invert_spatial_relationship=True)
messages.addMessage(f'{len(error_features)} were too far from the river and will be deleted.')
arcpy.management.DeleteFeatures(error_features)
messages.addMessage('Features successfully removed. Enjoy your clean data!')
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment