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

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.

0

Your Answer

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.