0

I have a long and complex python tool. In brief, I can't seem to get the default values for my tool, or any parameter updates for that matter, to work through my UpdateParameters definition. UpdateMessages for whatever reason, does seem to be functional in the full script.

Partial code below.

Sample Code

"""Imports and installs"""
import arcpy, pandas as pd, datetime as dt, numpy as np, os
from collections import namedtuple
from scipy.optimize import curve_fit
# from plotnine import ggplot, aes, geom_point
# from sklearn.metrics import r2_score, mean_squared_error
temp = "in_memory" # Using in-memory workspace for temporary processing
timestamp = dt.datetime.now().strftime("%Y_%m_%d_%H_%M") # Global timestamp in the format YYYY_MM_DD_HH_MM
class Toolbox:
 def __init__(self):
 """Define the toolbox (the name of the toolbox is the name of the .pyt file)"""
 self.label = "XXXX"
 self.alias = "XXXX"
 # List of tool classes associated with this toolbox
 self.tools = [XXXX]
class XXXX:
 def __init__(self):
 """Define the tool (tool name is the name of the class)."""
 self.label = "XXXX"
 self.description = "XXXX"
 self.param_dict = {} # Initialize empty parameter dictionary
 self.getParameterInfo() # Call to initialize parameters
 def create_parameter(self, param_displayname, param_name, param_datatype, param_type, param_direction, param_category, param_enabled=True, param_filtertype=None, param_filterlist=None, param_columns=None, param_values=None):
 """Helper function to create parameters for ArcGIS Pro toolbox."""
 
 param = arcpy.Parameter(
 displayName=param_displayname,
 name=param_name,
 datatype=param_datatype,
 parameterType=param_type,
 direction=param_direction,
 category=param_category,
 enabled=param_enabled
 )
 
 if param_filtertype:
 param.filter.type = param_filtertype
 param.filter.list = param_filterlist
 if param_columns:
 param.columns = param_columns
 if param_values:
 param.values = param_values
 
 return param
 def getParameterInfo(self):
 """Define the tool parameters."""
 
 params = [
 self.create_parameter("Model Initialization Year", "year_init", "GPLong", "Required", "Input", "Model Initialization Terms"),
 self.create_parameter("Model Horizon Year", "year_hori", "GPLong", "Required", "Input", "Model Initialization Terms"),
 self.create_parameter("Formatting Run", "trig_rmod", "GPBoolean", "Required", "Input", "Model Initialization Terms"),
 self.create_parameter("Model Initialization Table", "init_tbl", "DETable", "Optional", "Input", "Model Initialization Terms"),
 self.create_parameter("User Control Table", "uc_tbl", "DETable", "Optional", "Input", "Model Initialization Terms"),
 self.create_parameter("Output Directory", "out_dir", "DEWorkspace", "Required", "Output", "Model Initialization Terms"),
 ]
 # Create a dictionary for easy access
 self.param_dict = {param.name: param for param in params}
 return params
 def isLicensed(self):
 """Set whether the 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."""
 """Set default values."""
 default_values = {
 'year_init': dt.date.today().year + 1,
 'year_hori': dt.date.today().year + 41,
 }
 
 for param, default in default_values.items():
 if self.param_dict[param].value is None:
 self.param_dict[param].value = default
 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 dir_setup(self, output_directory):
 """Setup the runtime directory in the specified location."""
 print("Creating runtime directory...")
 
 root_path = f"{output_directory}/XXXX_Run_{timestamp}"
 plot_path = f"{root_path}/summary_plots"
 gdb_path = f"{root_path}/XXXX_Run_{timestamp}"
 
 try:
 print("Creating runtime folders...")
 
 os.makedirs(root_path, exist_ok=False) # create runtime root directory
 os.makedirs(plot_path, exist_ok=False) # create runtime plot directory
 
 print("Creating runtime geodatabase...")
 arcpy.CreateFileGDB_management(*os.path.split(output_directory))
 
 print(f"Runtime saved to: {root_path}")
 except Exception as e:
 print(f"Failed to create runtime directory: {e}")
 
 return root_path, plot_path, gdb_path
 
 def init_tbl(self, root_path):
 """Create the runtime initialization settings table."""
 print("Creating a runtime initialization file...")
 
 # Extract parameter names and values from param_dict
 mi_data = [(name, param.value) for name, param in self.param_dict.items()]
 mi_df = pd.DataFrame(mi_data, columns=['Parameter', 'Value'])
 
 # Create an init filepath
 filename = f"UrCGM_InitFile_{timestamp}.csv"
 init_path = os.path.join(root_path, filename)
 
 # Save the DataFrame to CSV
 try:
 mi_df.to_csv(init_path, sep='\t', encoding='utf-8', index=False)
 print(f"Model initialization file saved to: {init_path}.")
 except Exception as e:
 print(f"Failed to save model initialization file: {e}")
 
 return init_path
 
 def uc_tbl(self, root_path):
 """Check if uct is provided; create the uct if not."""
 
 # Access the 'uct' parameter from param_dict
 uct_param = self.param_dict.get("uct")
 
 if not uct_param or not uct_param.value:
 print("User control table not provided. Creating the table...")
 
 # Extract parameter names and values
 uct_data = [(name, param.value) for name, param in self.param_dict.items()]
 uct_df = pd.DataFrame(uct_data, columns=['Parameter', 'Value'])
 
 # Create the uct file path
 filename = "XXXX_UCT.csv"
 uct_path = os.path.join(root_path, filename)
 
 try:
 uct_df.to_csv(uct_path, sep='\t', encoding='utf-8', index=False)
 print(f"User control table saved to: {uct_path}.")
 except Exception as e:
 print(f"Failed to save user control table: {e}")
 
 else:
 print(f"User control table provided: {uct_param.value}")
 
 return uct_param.value if uct_param else None # Return the uct path
 def execute(self, parameters, messages):
 """The source code of the tool."""
 try:
 # User-specified output directory
 output_directory = next(p for p in parameters if p.name == "out_dir").valueAsText
 
 # Call the dir_setup function with user output directory
 root_path, plot_path, gdb_path = self.dir_setup(output_directory)
 
 # Call the init_tbl function to create the initialization table
 init_path = self.init_tbl(parameters, root_path)
 
 # Call the uc_tbl function to create the initialization table
 uct_path = self.uc_tbl(parameters, root_path)
 
 # Only run the model where it is not a formatting run
 if self.param_dict['trig_rmod'].value == 0:
 None 
 
 except Exception as e:
 print(f"An error occurred during execution: {e}")
 return
 def postExecute(self, parameters):
 """This method takes place after outputs are processed and
 added to the display."""
 return
PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Oct 27, 2024 at 3:30

1 Answer 1

3

ArcGIS doesn’t know about param_dict, so your updateParameters() method needs to update the values of the parameters list directly. The values in param_dict are copies of the initial Parameter objects, not references to the same instances.

answered Oct 27, 2024 at 6:13
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.