API Reference

class simulatr.ApsimXFile(fname: str, generated: bool | None = False, contents: dict | None = None, fname_orig: str | None = None)[source]

Bases: CropModelFile

Container for manipulating .apsimx model files.

Parameters:
  • fname – Path to a .apsimx model file.

  • generated – If True, this file was generated.

  • contents – Contents to initialize the file with.

property parameter_nodes: Any

Get the cached property value, computing it if needed.

classmethod available_crops() List[str][source]

Get the crops that can be simulated via this model.

Returns:

Available crop names.

Return type:

list

classmethod available_cultivars(crop_name: str) List[str][source]

Get the cultivars for a given crop that can be simulated via this model.

Parameters:

crop_name – Crop name.

Returns:

Available crop cultivar names.

Return type:

list

classmethod find_example(crop_name: str) str[source]

Locate an example model file for a given crop name.

Parameters:

crop_name – Crop name.

Returns:

Model input file for the specified crop.

Return type:

str

classmethod from_example(src: str | ApsimXFile, dst: str | None = None, interactive: bool = False, actions: List[str] | None = None) CropModelFile[source]

Create an input model file from an example.

Parameters:
  • src (str, ApsimXFile) – Path to the source .apsimx model.

  • dst (str, optional) – Path to the location where the generated .apsimx model should be saved.

  • interactive – If True, make the file interactive.

  • actions – Interactive actions that should be added.

Returns:

Constructed model input file.

Return type:

CropModelFile

classmethod from_crop_name(crop_name: str, dst: str | None = None, interactive: bool = False, actions: List[str] | None = None) CropModelFile[source]

Create an input model file for a given crop name.

Parameters:
  • crop_name – Crop name.

  • dst – Path to the location where the generated file should be saved.

  • interactive – If True, make the file interactive.

  • actions – Interactive actions that should be added.

Returns:

Constructed model input file.

Return type:

CropModelFile

property formal_crop_name: str

Crop name used for resources.

Type:

str

property is_interactive: Any

Get the cached property value, computing it if needed.

disable_parameter_conflicts(name: str, info: dict | None = None, node: dict | None = None) None[source]

Disable nodes that conflict with a parameter/action.

Parameters:
  • name – Action name.

  • info – Information about the parameter.

  • node – Parameter/action node to avoid disabling.

add_parameter(name: str, info: dict | None = None, parent: dict | None = None) dict[source]

Add a node to facilitate use of a parameter/action if it is missing.

Parameters:
  • name – Action name.

  • info – Information about how to add the parameter.

  • parent – Parent node that the action node should be added to if it is missing.

Returns:

Action node.

Return type:

dict

disable_action(name: str, **kwargs: Any) None[source]

Disable any nodes that automatically control an action.

Parameters:
  • name – Action name.

  • **kwargs – Additional keyword arguments are passed to find_parameter.

enable_action(name: str, parent: dict | None = None, **kwargs: Any) dict | None[source]

Enable any nodes that automatically control an action.

Parameters:
  • name – Action name.

  • parent – Parent node that the action node should be added to if it is missing.

  • **kwargs – Additional keyword arguments are passed to find_parameter.

Returns:

Action node.

Return type:

dict

disable(name: str, **kwargs: Any) None[source]

Disable a node in the file if it exists.

Parameters:
  • name – Name of the node to disable.

  • **kwargs – Additional keyword arguments are passed to find.

classmethod includes_constraints(info: dict) bool[source]

Check if a set of node requirements constrain the node.

Parameters:

info – Node requirements.

Returns:

True if info constrains the node, False otherwise.

Return type:

bool

classmethod node_matches(node: Any, errors: list | None = None, name: str | None = None, field: str | None = None, parameter: str | None = None, internal: str | None = None, contains: list | set | dict | None = None, equals: Any | None = None, fvalid: Callable | None = None, calls: str | None = None, anyOf: list | None = None, nested: dict | None = None, **kwargs: Any) bool[source]

Check if a node matches the specified requirements.

Parameters:
  • node – Node to check.

  • errors – If a list is provided, errors will be added to this list.

  • name – Name that the node must have.

  • field – Name of a field that must be present.

  • parameter – Name of a parameter that must be present.

  • contains – Fields/elements that the node must contain. If a set is provided, only one of the elements must be present. If a dict is provided, the values in the node must match the values in the provided dict.

  • equals – Value that the node must be equivalent to.

  • fvalid – Function that returns True if the node is valid, and False otherwise.

  • calls – Name of a function called in the node code block.

  • anyOf – List of kwargs for node_matches that should be checked. If the node satisfies any of these requirements, True will be returned.

  • nested – Set of requirements for individual fields.

  • **kwargs – Additional keyword arguments are ignored.

Returns:

True if the node matches, False otherwise.

Return type:

bool

findall_parameters(name: str, info: dict | None = None, **kwargs: Any) Iterator[dict][source]

Find all parameters nodes in this file matching the parameter info.

Parameters:
  • name – Parameter name.

  • info – Information about how to locate the parameter.

  • **kwargs – Additional keyword arguments are passed to findall.

Yields:

dict – The nodes matching the parameter info.

Raises:

KeyError – If info not provided and name is not a valid parameter/action.

find_parameter(name: str, add_missing: bool | dict | None = False, info: dict | None = None, **kwargs: Any) dict[source]

Find a parameter node in the file.

Parameters:
  • name – Parameter name.

  • add_missing – If True or dict, the default for the parameter will be added if it cannot be located. If a dict is provided, the parameter default will be added to this if the parameter cannot be located.

  • info – Information about how to locate the parameter.

  • **kwargs – Additional keyword arguments are passed to find.

Returns:

The node matching the specified name. Empty if no

node can be found.

Return type:

dict

Raises:

KeyError – If required is True and the node cannot be located.

findall(name: str | None = None, current: dict | None = None, parent: bool | None = False, requirements: dict | None = None) Iterator[dict][source]

Find a node in the file.

Parameters:
  • name – Name of the node to find.

  • current – The current node being searched.

  • parent – If True, the parent node will be returned.

  • requirements – Set of requirements that the node must satisfy (see node_matches for a description of the available options).

Yields:

dict – All nodes matching the specified name.

find(name: str | None = None, current: dict | None = None, parent: bool | None = False, required: bool | None = False, requirements: dict | None = None) dict[source]

Find a node in the file.

Parameters:
  • name – Name of the node to find.

  • current – The current node being searched.

  • parent – If True, the parent node will be returned.

  • required – If True, an error will be raised if the node cannot be located.

  • requirements – Set of requirements that the node must satisfy (see node_matches for a description of the available options).

Returns:

The node matching the specified name. Empty if no

node can be found.

Return type:

dict

Raises:

KeyError – If required is True and the node cannot be located.

class simulatr.ApsimXEngine(*, model_file: str | List[str] | BaseModelFile | None = None, model_suffix: str | None = None, output_dir: str | None = None, start_time: datetime | None = None, end_time: datetime | None = None, duration: timedelta | None = None, param: dict | None = None, actions: List[str] | None = None, action_map: dict | ModelActionSet | None = None, action_param: dict | None = None, crop_name: str | None = None, crop_variety: str | None = None, sow_date: date | None = None, harvest_date: date | None = None, season_length: int | timedelta | None = None, year: int | None = None, latitude: float | None = None, longitude: float | None = None, weather_file: str | None = None, from_example: bool | str | None = True, **extra_data: Any)[source]

Bases: CropModelEngine

Class for managing communication with an APSIMX server running in another process.

INPUT_FILE_TYPE

alias of ApsimXFile

WEATHER_FILE_TYPE

alias of ApsimXWeatherFile

model_post_init(_ApsimXEngine__context: Any) None[source]

Initialize the engine.

Parameters:
  • model_file – Path to a .apsimx model input file.

  • **kwargs – Additional keyword arguments are passed to the CropModelEngine constructor.

classmethod apsim_srv() str[source]

Path to the apsimx server.

classmethod is_installed() bool[source]

Check if the model is installed in the specified directory.

Returns:

True if the model is installed, False otherwise.

Return type:

bool

create_model_file() CropModelFile[source]

Create a model input file.

Returns:

Constructed model input file.

Return type:

CropModelFile

property is_running: bool

True if the model engine is still running.

Type:

bool

property is_operable: bool

True if the model engine is running and functioning.

Type:

bool

property current_time: datetime

Current simulation time.

Type:

datetime.datetime

property status: str | None

Current simulation status.

Type:

str

property output_file: str

Path to the .db output file that will be produced.

Type:

str

get_output_vars() List[str][source]

Get the output variables specified by the model file.

Returns:

Output variables

Return type:

list

send_command(command: str, args: list | None = None) None[source]

Send a command to the server process, e.g. resume/set/get.

Parameters:
  • command – Command to send.

  • args – Additional arguments to send with the commaned.

recv_reply(unpack: bool | None = False) Any[source]

Receive a reply from the server process.

Parameters:

unpack – If True, the message will be unpacked using msgpack.

Returns:

Received message.

Return type:

object

check_paused() None[source]

Check that the simulation server is paused.

stop_on_error(record: tuple | None = None, allow_error: bool | None = False) Iterator[None][source]

Context manager that stops the simulation on an error.

Parameters:
  • record – Action to log when successful.

  • allow_error – If True, a RecoverableError error will not result in the simulation being stopped.

resume(wait: bool | None = False) None[source]

Resume the simulation.

Parameters:

wait – If True, wait for the simulation to pause.

model_config = {'arbitrary_types_allowed': True, 'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class simulatr.ApsimXEnv(*, action_space: Any = None, observation_space: Any = None, model_file: str | List[str] | BaseModelFile | None = None, start_time: datetime | None = None, end_time: datetime | None = None, intervention_interval: int | timedelta | None = 7, output_vars: List[str] | None = None, num_levels: int | None = 4, actions: List[str] | None = None, action_map: dict | ModelActionSet | None = None, revenue_var: Dict[str, str | float] | None = None, model_param: dict | None = None, action_param: dict | None = None, allow_donothing: bool | None = True, exclusive: bool | None = True, scale_action_amounts_by_interval: bool | None = False, **extra_data: Any)[source]

Bases: CropModelEnv

ApsimX environment.

MODEL_ENGINE_CLASS

alias of ApsimXEngine

LLM_PROMPT_GENERATOR_CLASS

alias of ApsimXLLMPromptGenerator

model_config = {'arbitrary_types_allowed': True, 'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class simulatr.base.NoDefault[source]

Bases: object

Dummy class for defaults.

exception simulatr.base.RecoverableError[source]

Bases: RuntimeError

Error that does not stop the engine.

exception simulatr.base.ModelEngineError[source]

Bases: RuntimeError

Error raised by the model engine.

exception simulatr.base.RecoverableModelEngineError[source]

Bases: RecoverableError

Error raised by the model engine that does not stop the engine.

exception simulatr.base.InvalidActionError[source]

Bases: RecoverableError

Error raised when an action is invalid.

simulatr.base.readonly_cached_property(method: Callable) Callable[source]

Decorator for a read-only cached property.

Parameters:

method – Method to wrap.

class simulatr.base.CachedPropertyMixin(*args: Any, **kwargs: Any)[source]

Bases: object

Mixin class for enabling read-only cached properties.

__init__(*args: Any, **kwargs: Any) None[source]

Initialize the cached property mixin.

Parameters:
  • *args – Positional arguments passed to the parent class.

  • **kwargs – Keyword arguments passed to the parent class.

class simulatr.base.ModelAction(name: str, description: str, alias: str | None = None, keywords: List[str] | None = None, cost: float | None = None, action_param: str | None = None, num_levels: int | None = 0, levels: List[str | float | ndarray] | None = None, bounds: Tuple[float, float] | Tuple[ndarray, ndarray] | None = None, param_desc: dict | None = None, param: dict | None = None, allow_donothing: bool | None = True, offset: int | None = 0)[source]

Bases: CachedPropertyMixin

Wrapper for a model action.

Parameters:
  • name – Action name.

  • alias – Action alias.

  • keywords – Key words or phrases identifying this action.

  • cost – Action cost. If the action produces a float, this should be the cost per action unit.

  • action_param – Parameter that action will set.

  • num_levels – Number of levels that the action supports for the action parameter. 0 indicates a continuous action, -1 indicates a boolean action.

  • level – Explicit levels for the action parameter.

  • bounds – Explicit bounds for the action parameter (numbers only).

  • param_desc – Descriptions of parameters supported by the action.

  • param – Values for additional parameters that should be used.

  • allow_donothing – If True, the action should allow for a choice to do nothing.

  • offset – Action offset when part of a discrete set.

__init__(name: str, description: str, alias: str | None = None, keywords: List[str] | None = None, cost: float | None = None, action_param: str | None = None, num_levels: int | None = 0, levels: List[str | float | ndarray] | None = None, bounds: Tuple[float, float] | Tuple[ndarray, ndarray] | None = None, param_desc: dict | None = None, param: dict | None = None, allow_donothing: bool | None = True, offset: int | None = 0) None[source]

Initialize a model action.

Parameters:
  • name – Action name.

  • description – Action description.

  • alias – Action alias.

  • keywords – Key words or phrases identifying this action.

  • cost – Action cost. If the action produces a float, this should be the cost per action unit.

  • action_param – Parameter that action will set.

  • num_levels – Number of levels that the action supports for the action parameter. 0 indicates a continuous action, -1 indicates a boolean action.

  • levels – Explicit levels for the action parameter.

  • bounds – Explicit bounds for the action parameter (numbers only).

  • param_desc – Descriptions of parameters supported by the action.

  • param – Values for additional parameters that should be used.

  • allow_donothing – If True, the action should allow for a choice to do nothing.

  • offset – Action offset when part of a discrete set.

property additional_param: Any

Get the cached property value, computing it if needed.

property additional_param_args: Any

Get the cached property value, computing it if needed.

property bounds: Any

Get the cached property value, computing it if needed.

property levels: Any

Get the cached property value, computing it if needed.

property numeric: Any

Get the cached property value, computing it if needed.

property ndim: Any

Get the cached property value, computing it if needed.

property shape: tuple

Shape of action parameter.

Type:

tuple

property dtype: Any

Get the cached property value, computing it if needed.

property choices: Any

Get the cached property value, computing it if needed.

set_param(param: dict, src: str | None = 'set_param') None[source]

Update the action parameters.

Parameters:
  • param – Action parameters.

  • src – Description of how the parameter is being updated for logging parameter conflicts.

scale_action_amounts(scale: int | float) None[source]

Scale action limits/levels.

Parameters:

scale – Amount to scale values by.

property num_choices: int

Number of discrete choices allowed for this action.

Type:

int

property discrete: bool

True if the action is discrete.

Type:

bool

property boolean: bool

True if the action is boolean.

Type:

bool

property example_value: Any

Get the cached property value, computing it if needed.

property example_args: Any

Get the cached property value, computing it if needed.

property example_description: Any

Get the cached property value, computing it if needed.

property description: Any

Get the cached property value, computing it if needed.

property description_regex: Any

Get the cached property value, computing it if needed.

property space: Any

Get the cached property value, computing it if needed.

combine_args_and_kwargs(args: tuple, kwargs: dict) dict[source]

Combine positional and keyword arguments into a single dict for the action based on the available action parameters.

Parameters:
  • args – Positional arguments.

  • kwargs – Keyword arguments.

Returns:

Combined keyword arguments.

Return type:

dict

args2cost(args: tuple) float[source]

Convert a set of action arguments to the action cost.

Parameters:

args – Action arguments.

Returns:

Cost of the action.

Return type:

float

description2action(description: str) int | ndarray[source]

Parse a description to get an action ID.

Parameters:

description – Action description.

Returns:

Action ID.

Return type:

object

search_description(description: str) Match[source]

Search a description for a match to this action using regex.

Parameters:

description – Action description.

Returns:

Search result.

Return type:

re.Match

fuzzy_search_description(description: str) Any[source]

Search a description for a match to this action by looking for keywords.

Parameters:

description – Action description.

Returns:

Value from fuzzy search.

Return type:

object

match2value(match: Match) Any[source]

Convert a regex search result into an action value.

Parameters:

match – Regex search result.

Returns:

Action value.

Return type:

object

description2value(description: str) Any[source]

Parse a description for a action value.

Parameters:

description – Action description.

Returns:

Action value.

Return type:

object

value2action(value: Any) int | ndarray[source]

Convert an action value into an action ID.

Parameters:

value – Action value.

Returns:

Action ID.

Return type:

int, np.ndarray

action2value(action: int | ndarray) Any[source]

Convert an action ID into a parameter value.

Parameters:

action – Action ID.

Returns:

Parameter value.

Return type:

object

value2args(value: Any) tuple[source]

Convert an action value to arguments.

Parameters:

value – Action value.

Returns:

Action arguments.

Return type:

tuple

action2description(action: int | ndarray) str[source]

Convert an action ID into a natural language description.

Parameters:

action – Action ID.

Returns:

Action description.

Return type:

str

action2args(action: int | ndarray) tuple[source]

Convert an action ID into arguments that can be passed to BaseModelEngine.act.

Parameters:

action – Action ID.

Returns:

Parameter act arguments.

Return type:

tuple

format_description(value: Any | None = None, param: dict | None = None) str[source]

Format a description of the action.

Parameters:
  • value – Action value to include in the description.

  • param – Alternate action parameter values to include in the description.

Returns:

Formatted action description.

Return type:

str

format_description_regex(param: dict | None = None, param_regex: dict | None = None) str[source]

Create a regex string for extracting parameters from an action description.

Parameters:
  • param – Parameter values that should be included in the description regex as constants.

  • param_regex – Regex strings for parameters that should be matched in the description regex.

Returns:

Description regex.

Return type:

str

property constraint: Any

Get the cached property value, computing it if needed.

class simulatr.base.DoNothingModelAction(name: str | None = 'donothing', description: str | None = 'Do nothing.', keywords: list | None = ['do nothing', 'take no action'])[source]

Bases: ModelAction

Specific case of a model action to do nothing.

__init__(name: str | None = 'donothing', description: str | None = 'Do nothing.', keywords: list | None = ['do nothing', 'take no action']) None[source]

Initialize a do-nothing model action.

Parameters:
  • name – Action name.

  • description – Action description.

  • keywords – Key words or phrases identifying this action.

class simulatr.base.ModelActionSet(action_map: dict, num_levels: int | None = 0, allow_donothing: bool | None = True, exclusive: bool | None = True, default_action_map: dict | None = None, param: dict | None = None)[source]

Bases: CachedPropertyMixin

Set of model actions.

Parameters:
  • action_map – Mapping between action names and descriptions.

  • num_levels – Number of levels per action if not specified in action_map (0 for continuous, -1 for boolean).

  • allow_donothing – Include non-action as a possible action.

  • exclusive – Don’t allow more than one action per step.

  • default_action_map – Mapping of default action descriptions that should be used to fill in missing information in action_map.

  • param – Action parameters to use keyed to action names.

__init__(action_map: dict, num_levels: int | None = 0, allow_donothing: bool | None = True, exclusive: bool | None = True, default_action_map: dict | None = None, param: dict | None = None) None[source]

Initialize a set of model actions.

Parameters:
  • action_map – Mapping between action names and descriptions.

  • num_levels – Number of levels per action if not specified in action_map (0 for continuous, -1 for boolean).

  • allow_donothing – Include non-action as a possible action.

  • exclusive – Don’t allow more than one action per step.

  • default_action_map – Mapping of default action descriptions that should be used to fill in missing information in action_map.

  • param – Action parameters to use keyed to action names.

classmethod create(action_map: ModelActionSet | dict, **kwargs: Any) ModelActionSet[source]

Create a ModelActionSet from a dictionary. If an existing ModelActionSet instance is provided, it is returned.

Parameters:
  • action_map – Existing ModelActionSet or dictionary.

  • **kwargs – Additional keyword arguments are passed to the constructor if action_map is not a ModelActionSet instance.

Returns:

ModelActionSet instance.

items() Any[source]

Action items.

keys() Any[source]

Action keys.

values() Any[source]

Action values.

pop(k: str, default: Any = <class 'simulatr.base.NoDefault'>) Any[source]

Remove an action.

set_param(param: dict, action: str | None = None, src: str | None = 'set_param') None[source]

Update the action parameters that match the provided keywords.

Parameters:
  • param – Action parameters.

  • action – Name of the action that should be updated. If not provided, all actions with matching parameters will be updated.

  • src – Description of how the parameter is being updated for logging parameter conflicts.

scale_action_amounts(scale: int | float) None[source]

Scale action limits/levels.

Parameters:

scale – Amount to scale values by.

property action_order: Any

Get the cached property value, computing it if needed.

property num_choices: Any

Get the cached property value, computing it if needed.

property ndim: Any

Get the cached property value, computing it if needed.

property discrete: Any

Get the cached property value, computing it if needed.

property donothin_action: Any

Get the cached property value, computing it if needed.

property example_value: Any

Get the cached property value, computing it if needed.

property example_args: Any

Get the cached property value, computing it if needed.

property example_description: Any

Get the cached property value, computing it if needed.

property description_lines: Any

Get the cached property value, computing it if needed.

property description: Any

Get the cached property value, computing it if needed.

property space: Any

Get the cached property value, computing it if needed.

description2action(description: str) int | tuple | dict[source]

Parse a description to get an action ID.

Parameters:

description – Action description.

Returns:

Action ID.

Return type:

object

description2value(description: str) dict[source]

Parse a description for a action value.

Parameters:

description – Action description.

Returns:

Action value map.

Return type:

dict

value2action(value: dict) int | tuple | dict[source]

Convert an action value into an action ID.

Parameters:

value – Action value map.

Returns:

Action ID.

Return type:

int, tuple, dict

action2value(action: int | tuple | dict | ndarray) dict[source]

Convert an action ID into a map of action values.

Parameters:

action – Action ID.

Returns:

Action value map.

Return type:

dict

value2args(value: dict) Dict[str, tuple][source]

Convert an action value map to an argument map.

Parameters:

value – Action value.

Returns:

Action argument map.

Return type:

dict

action2description(action: int | tuple | dict | ndarray) str[source]

Convert an action ID into a natural language description.

Parameters:

action – Action ID.

Returns:

Action description.

Return type:

str

action2args(action: int | tuple | dict | ndarray) dict[source]

Convert an action ID into a parameter argument map for actvars.

Parameters:

action – Action ID.

Returns:

Parameter to argument map.

Return type:

dict

format_description(value: dict | None = None, return_lines: bool | None = False) str[source]

Format a description of the action.

Parameters:
  • value – Action value to include in the description.

  • return_lines – If True, return a list of lines instead of a merged string.

Returns:

Formatted action description. A list will be returned

if return_lines is True.

Return type:

str

class simulatr.base.BaseModelFile(fname: str, generated: bool | None = False, contents: dict | None = None, fname_orig: str | None = None)[source]

Bases: CachedPropertyMixin, ABC

Base class for managing model input files.

Parameters:
  • fname – Path to a model file.

  • generated – If True, this file was generated.

  • contents – Contents to initialize the file with.

  • fname_orig – Original model file that this one was generated from.

__init__(fname: str, generated: bool | None = False, contents: dict | None = None, fname_orig: str | None = None) None[source]

Initialize a model file wrapper.

Parameters:
  • fname – Path to a model file.

  • generated – If True, this file was generated.

  • contents – Contents to initialize the file with.

  • fname_orig – Original model file that this one was generated from.

cleanup() None[source]

Cleanup any generated file.

static parameter_property(method: Callable) property[source]

Decorator for a BaseModelFile method that produces the default value that should be used if a KeyError is not raised by BaseModelFile.get(<property name>).

Parameters:

method – BaseModelFile method being wrapped.

property contents: Any[source]

File contents.

Type:

object

property is_interactive: Any

Get the cached property value, computing it if needed.

prevent_overwrite(suffix: str | None = '-Modified') Iterator[None][source]

Context to ensure that a duplicate is made if the context exits successfully during modification of the file contents.

Parameters:

suffix – File suffix to add if a new file name is generated.

property output_vars

Get the parameter value, computing it if missing.

property exists: bool

True if the file exists.

Type:

bool

get(name: str, default: Any = <class 'simulatr.base.NoDefault'>) Any[source]

Get a parameter from the model file.

Parameters:
  • name – Parameter name.

  • default – Value to return if the parameter can’t be found.

Returns:

Parameter value.

set(name: str, value: Any) None[source]

Set a parameter in the model file.

Parameters:
  • name – Parameter name.

  • value – Parameter value.

Raises:

KeyError – If name is not a valid parameter name.

write(new_contents: dict | None = None, overwrite: bool | None = False) None[source]

Write a new set of contents to the file.

Parameters:
  • new_contents – New contents to write.

  • overwrite – If True, overwrite the existing file.

move(dst: str | None = None, suffix: str | None = None, directory: str | None = None) str[source]

Change the path to the file the contents will be written to when write is called.

Parameters:
  • dst – Path to the new location where the model should be saved when write is called.

  • suffix – Suffix to add to the current filename if dst is not provided.

  • directory – Path to the directory that the model should be written to when write is called.

Returns:

The new model file path.

Return type:

str

copy(**kwargs: Any) BaseModelFile[source]

Create a copy of this .apsimx model.

Parameters:

**kwargs – Addiitonal keyword arguments are passed to move.

Returns:

Copied .apsimx model.

Return type:

ApsimXFile

make_interactive(actions: list) None[source]

Modify this file to make it interactive.

Parameters:

actions – List of actions that should be enabled.

class simulatr.base.BaseModelEngine(*, model_file: str | List[str] | BaseModelFile, model_suffix: str | None = None, output_dir: str | None = None, start_time: datetime | None = None, end_time: datetime | None = None, duration: timedelta | None = None, param: dict | None = None, actions: List[str] | None = None, action_map: dict | ModelActionSet | None = None, action_param: dict | None = None, **extra_data: Any)[source]

Bases: BaseModel, ABC

Base class for exposing a model as an environment engine.

model_config = {'arbitrary_types_allowed': True, 'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseModelEngine__context: Any) None[source]

Initialize the model engine.

Parameters:
  • model_file – Path to one or more model input files.

  • model_suffix – Additional suffix to add to a copy of the provided model file to ensure that it is unique.

  • output_dir – Path to the directory where output should be saved.

  • start_time – Simulation start time.

  • end_time – Simulation end time.

  • duration – Simulation duration. Only used if either start_time or end_time is not provided.

  • param – Model parameters to update at the beginning of the simulation.

  • actions – Names of actions to include. Only used if action_map not provided.

  • action_map – Description of actions available via the act method.

  • action_param – Action parameters to use keyed to action names.

classmethod model_dir() str[source]

Get the directory containing the model.

Returns:

The directory containing the model.

Return type:

str

classmethod is_installed() bool[source]

Check if the model is installed in the specified directory.

Returns:

True if the model is installed, False otherwise.

Return type:

bool

classmethod install() None[source]

Install the model if it is not installed.

has_param(name: str, skip_file: bool | None = False) bool[source]

Check if a model has a parameter value set.

Parameters:
  • name – Name of parameter to check.

  • skip_file – If True, don’t try to read the parameter from the file.

Returns:

True if the parameter is set, False otherwise.

Return type:

bool

del_param(name: str, src: List[str] | None = None) bool[source]

Clear a model parameter.

Parameters:
  • name – Name of parameter to clear.

  • src – If provided, only delete the parameter if the source is one of the listed values.

set_param(name: str, value: Any, src: str | None = 'USER', dont_update: bool | None = False) bool[source]

Set a model parameter, updating the value for actions where appropriate.

Parameters:
  • name – Name of parameter to set.

  • value – Parameter value.

  • src – Description of where the parameter came from.

  • dont_update – If True, don’t update the model file.

Returns:

True if the set was successful.

Return type:

bool

get_param(name: str, default: Any | None = <class 'simulatr.base.NoDefault'>, skip_file: bool | None = False, skip_calc: bool | None = False, skip_default: bool | None = False, skip_src: List[str] | None = None) Any[source]

Get a model parameter.

Parameters:
  • name – Name of parameter to get.

  • default – Default to return if the parameter cannot be located.

  • skip_file – If True, don’t try to read the parameter from the file.

  • skip_calc – If True, don’t try to calculate missing parameters.

  • skip_default – If True, don’t use values in DEFAULT_PARAM for missing parameters.

  • skip_src – Set of sources that should be ignored.

Returns:

Parameter value.

Raises:

KeyError – If a parameter value cannot be located and default is not provided.

calc_param(name: str, default: Any | None = <class 'simulatr.base.NoDefault'>, **kwargs: Any) Any[source]

Calculate a parameter from other parameters.

Parameters:
  • name – Parameter to calculate.

  • default – Default to return if the parameter cannot be calculated.

  • **kwargs – Additional keyword arguments are passed to get_param when getting parameters used in the calculation.

Returns:

Calculated parameter value.

update_param_in_file(names: List[str] | None = None, required: bool | None = False) bool[source]

Update a parameter in the model file if it has changed.

Parameters:
  • names – Names of parameters to set. If not provided, all parameters that have been updated since the last time update_param_in_file was called will be set.

  • required – If True, a KeyError will be raised if a value cannot be updated for any of the specified names.

Returns:

True if the update was successful.

Return type:

bool

sync_param(names: List[str] | None = None, required: bool | None = False, dont_update: bool | None = False, skip_file: bool | None = False, **kwargs: Any) None[source]

Set/get explicit model file parameters.

Parameters:
  • names – Names of parameters to synchronize.

  • required – If True, a KeyError will be raised if a value cannot be found for any of the specified names.

  • dont_update – If True, don’t update the model file.

  • skip_file – If True, only sync parameters between initial_param and attributes for EXPLICIT_PARAM, but do not inspect the file.

  • **kwargs – Additional keyword arguments are passed to get_param for each name.

Raises:

KeyError – If required is True and a value cannot be found for any of the specified names.

abstractmethod create_model_file() BaseModelFile[source]

Create the model input file.

Returns:

Constructed model input file.

Return type:

BaseModelFile

update_model_file() None[source]

Update the model file to make it interactive and set the start/end times.

classmethod select_actions(actions: List[str] | None = None, action_map: dict | None = None) dict[source]

Select a set of default actions.

Parameters:
  • actions – Set of actions to select.

  • action_map – Map that actions should be selected from.

Returns:

Description of selected actions.

Return type:

dict

get_output_vars() List[str][source]

Get the output variables specified by the model file.

Returns:

Output variables

Return type:

list

property is_complete: bool

True if the simulation is complete.

Type:

bool

abstract property is_running: bool

True if the model engine is still running.

Type:

bool

property is_operable: bool

True if the model engine is running and functioning.

Type:

bool

abstract property current_time: datetime

Current simulation time.

Type:

datetime.datetime

start() None[source]

Start the model engine.

stop(cleanup: bool | None = False) None[source]

Stop the model engine.

Parameters:

cleanup – If True, cleanup the generated model file.

cleanup(remove_output: bool | None = False) None[source]

Cleanup the model.

cleanup_output() None[source]

Cleanup model output.

reset() None[source]

Re-start the model.

stop_on_error(record: tuple | None = None, allow_error: bool | None = False) Iterator[None][source]

Context manager that stops the simulation on an error.

Parameters:
  • record – Action to log when successful.

  • allow_error – If True, a RecoverableError error will not result in the simulation being stopped.

get(name: str, allow_error: bool | None = False) Any[source]

Send a request to get the current value of a simulation state variable.

Parameters:
  • name – Name of variable to get the value of.

  • allow_error – If True, a RecoverableError error will not result in the simulation being stopped.

Returns:

Current variable value.

Return type:

object

set(name: str, value: Any, allow_error: bool | None = False) Any[source]

Send a request to set a simulation state variable.

Parameters:
  • name – Name of the variable to update.

  • value – New value for the named variable.

  • allow_error – If True, a RecoverableError error will not result in the simulation being stopped.

act(action: str, *args: Any, allow_error: bool | None = False, **kwargs: Any) Any[source]

Perform an action.

Parameters:
  • name – Name of the action to perform.

  • *args – Additional positional arguments provide action parameters in the order specified by "param" in the action_map.

  • allow_error – If True, a RecoverableError error will not result in the simulation being stopped.

  • **kwargs – Additional keyword arguments provide action parameters by name.

getvars(names: list, allow_error: bool | None = False) dict[source]

Send a request to get the current value of a set of simulation state variables.

Parameters:
  • names – Names of variables to get values for.

  • allow_error – If True, a RecoverableError error will not result in the simulation being stopped.

Returns:

Mapping between state variable names and retrieved

values.

Return type:

dict

setvars(values: dict, allow_error: bool | None = False) None[source]

Send a request to set simulation state variables.

Parameters:
  • values – Mapping between state variable names and the values they should be set to.

  • allow_error – If True, a RecoverableError error will not result in the simulation being stopped.

actvars(values: dict, allow_error: bool | None = False) None[source]

Perform multiple actions.

Parameters:
  • values – Mapping between action names and tuples of action parameters.

  • allow_error – If True, a RecoverableError error will not result in the simulation being stopped.

record(*args: Any) None[source]

Record an action.

Parameters:

*args – Positional arguments are stored in the history.

scrub(time: datetime | timedelta | int | str) None[source]

Fast forwrad or rewind the simulation to the desired time.

Parameters:

time – Time that simulation should be run/rewond to or the the time that the simulation should be run for with negative value indicating the time that the simulation should be rewond by (timedelta). If an integer is provided, it is assumed to be the number of days in a timedelta.

fast_forward(time: datetime | timedelta | int | str | None = None) None[source]

Fast forward the simulation to the desired time.

Parameters:

time – Time that simulation should be run to or the the time that the simulation should be run for (timedelta).

rewind(time: datetime | timedelta | int | str | None = None) None[source]

Rewind the simulation to a previous time.

Parameters:

time – Time to rewind to or time to rewind by (timedelta).

abstractmethod resume(wait: bool | None = False) None[source]

Resume the simulation.

Parameters:

wait – If True, wait for the simulation to pause.

class simulatr.base.BaseModelLLMPromptGenerator(num_levels: int | None = 4, intervention_interval: int | None = 7, output_vars: List[str] | None = None, desc_map: Dict[str, Tuple[str, str]] | None = None, action_map: dict | ModelActionSet | None = None, reward: str | None = None, state_descriptor: str | None = None, allow_donothing: bool | None = True, exclusive: bool | None = True, require_think: bool = False, thinking_mode: str = 'grounding_decision', think_tag: str = 'think', answer_tag: str = 'answer')[source]

Bases: CachedPropertyMixin, ABC

Generate LLM prompts for environments.

This class handles the creation of system prompts and turn prompts for LLM-based agricultural management agents.

__init__(num_levels: int | None = 4, intervention_interval: int | None = 7, output_vars: List[str] | None = None, desc_map: Dict[str, Tuple[str, str]] | None = None, action_map: dict | ModelActionSet | None = None, reward: str | None = None, state_descriptor: str | None = None, allow_donothing: bool | None = True, exclusive: bool | None = True, require_think: bool = False, thinking_mode: str = 'grounding_decision', think_tag: str = 'think', answer_tag: str = 'answer') None[source]

Initialize the prompt generator.

Parameters:
  • num_levels – Number of levels per action if not specified in action_map (0 for continuous).

  • intervention_interval – Days between decisions

  • output_vars – List of observation variable names

  • desc_map – Custom description mapping for variables

  • action_map – Custom description mapping for actions

  • reward – Description of the reward that should be used.

  • state_descriptor – Description of the overall type of state information.

  • allow_donothing – Include non-action as a possible action.

  • exclusive – Don’t allow more than one action per step.

  • require_think – Whether to require thinking before answering

  • thinking_mode – Thinking prompt variant when require_think=True. Supported values: “minimal”, “think” (alias of “grounding_decision”), “grounding_decision”

  • think_tag – Tag name for thinking (default: “think”, e.g. “tool_call”)

  • answer_tag – Tag name for answer (default: “answer”)

property reward_inline: Any

Get the cached property value, computing it if needed.

property state_grounding: Any

Get the cached property value, computing it if needed.

abstractmethod turn_context(observation: ndarray) str[source]

Generate a string to summarize the current turn at a high level with the context of the simulation.

Parameters:

observation – Current state.

Returns:

Turn summary.

Return type:

str

abstractmethod get_system_prompt() str[source]

Generate the system prompt for the LLM agent.

Returns:

System prompt string

get_turn_prompt(observation: ndarray) str[source]

Generate the complete per-turn user prompt.

Supports plain-answer mode plus two thinking guidance variants. Structure: intro → observation → actions → guidance → format.

describe_action(action_id: int | dict | tuple) str[source]

Convert action ID to natural language description.

Parameters:

action_id – Integer action ID from the environment

Returns:

Natural language description in <answer>…</answer> format

parse_action_response(response: str) int | dict | tuple | None[source]

Parse LLM response to extract action ID.

Both modes use strict fullmatch — any extra content is invalid. Model-inherent thinking is extracted by the model interface layer before the response reaches this method.

  • require_think=True: <tag>...</tag><answer>...</answer>

  • require_think=False: <answer>...</answer> only

classmethod from_env(env: BaseModelEnv, **kwargs: Any) BaseModelLLMPromptGenerator[source]

Create prompt generator from a model gym environment.

Parameters:
  • env – model gym environment instance

  • **kwargs – Additional keyword arguments are passed to the class constructor.

Returns:

BaseModelLLMPromptGenerator instance configured for the

environment.

class simulatr.base.BaseModelEnv(*, action_space: Any = None, observation_space: Any = None, model_file: str | List[str] | BaseModelFile | None = None, start_time: datetime | None = None, end_time: datetime | None = None, intervention_interval: int | timedelta | None = 7, output_vars: List[str] | None = None, num_levels: int | None = 4, actions: List[str] | None = None, action_map: dict | ModelActionSet | None = None, revenue_var: Dict[str, str | float] | None = None, model_param: dict | None = None, action_param: dict | None = None, allow_donothing: bool | None = True, exclusive: bool | None = True, scale_action_amounts_by_interval: bool | None = False, **extra_data: Any)[source]

Bases: BaseModel, Env

Base model environment.

model_config = {'arbitrary_types_allowed': True, 'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseModelEnv__context: Any) None[source]

Initialize the environment.

Parameters:
  • model_file – Path to one or more model input files.

  • start_time – Simulation start time.

  • end_time – Simulation end time.

  • intervention_interval – Time between decisions. If an integer is provided, the units will be assumed to be days.

  • output_vars – List of observation variable names.

  • num_levels – Number of levels per action if not specified in action_map (0 for continuous, -1 for boolean).

  • actions – Names of actions to include. Only used if action_map not provided.

  • action_map – Custom description mapping for actions.

  • revenue_var – Description of how profit should be calculated from an output variable.

  • model_param – Initial model parameters to set in the model file and/or when the simulation begins.

  • action_param – Action parameters to use keyed to action names.

  • allow_donothing – Include non-action as a possible action.

  • exclusive – Don’t allow more than one action per step.

  • scale_action_amounts_by_interval – If True, scale action amounts by the intervention interval.

  • **kwargs – Additional keyword arguments are passed to the model engine constructor.

property current_time: datetime

Current time.

Type:

datetime.dateime

property intervention_timedelta: timedelta

Intervention interval as delta.

Type:

datetime.timedelta

get_output_vars() List[str][source]

Get the output variables specified by the model file.

Returns:

Output variables

Return type:

list

create_model(**kwargs: Any) BaseModelEngine[source]

Create a new model engine.

close() None[source]

Close the environment.

get_llm_prompt_generator(**kwargs: Any) BaseModelLLMPromptGenerator[source]

Create an LLM prompt generator for this environment.

Parameters:

**kwargs – Keyword arguments are passed to the from_env method of the LLM_PROMPT_GENERATOR_CLASS type.

Returns:

LLM prompt generator.

Return type:

BaseModelLLMPromptGenerator

reset(seed: int | None = None, options: dict | None = None) tuple[ndarray, dict][source]

Start a new episode.

Parameters:
  • seed – Random seed for reproducible episodes

  • options – Additional configuration

Returns:

(observation, info) for the initial state

Return type:

tuple

step(action: int | ndarray) tuple[ndarray, float, bool, bool, dict][source]

Execute one timestep within the environment.

Parameters:

action – The action to take (modification of state variable).

Returns:

(observation, reward, terminated, truncated, info)

Return type:

tuple

class simulatr.crop.CropModelFile(fname: str, generated: bool | None = False, contents: dict | None = None, fname_orig: str | None = None)[source]

Bases: BaseModelFile

Base class for managing crop model input files.

abstractmethod classmethod available_crops() List[str][source]

Get the crops that can be simulated via this model.

Returns:

Available crop names.

Return type:

list

abstractmethod classmethod available_cultivars(crop_name: str) List[str][source]

Get the cultivars for a given crop that can be simulated via this model.

Parameters:

crop_name – Crop name.

Returns:

Available crop cultivar names.

Return type:

list

classmethod validate_crop_name(crop_name: str) str[source]

Ensure the crop name is one of those that can be simulated, normalizing it if necessary.

Parameters:

crop_name – Crop name.

Returns:

Normalized crop name.

Return type:

str

abstractmethod classmethod from_crop_name(crop_name: str, dst: str | None = None, interactive: bool = False, actions: List[str] | None = None) CropModelFile[source]

Create an input model file for a given crop name.

Parameters:
  • crop_name – Crop name.

  • dst – Path to the location where the generated file should be saved.

  • interactive – If True, make the file interactive.

  • actions – Interactive actions that should be added.

Returns:

Constructed model input file.

Return type:

CropModelFile

property crop_name

Get the parameter value, computing it if missing.

property crop_variety

Get the parameter value, computing it if missing.

property location

Get the parameter value, computing it if missing.

property field_area

Get the parameter value, computing it if missing.

class simulatr.crop.BaseWeatherFile(fname: str, generated: bool | None = False, contents: dict | None = None, fname_orig: str | None = None)[source]

Bases: BaseModelFile

Base class for weather files.

property parameters: list

Set of power parameters contained by this file.

Type:

list

abstract property dates: ndarray

Dates covered by this file.

Type:

np.ndarray

abstract property latitude: float

Latitude (degrees).

Type:

float

abstract property longitude: float

Longitude (degrees).

Type:

float

property start_date: date

Minimum date covered by this file.

Type:

datetime.date

property end_date: date

Maximum date covered by this file.

Type:

datetime.date

classmethod fetch_data(*args: Any, **kwargs: Any) str[source]

Look for an existing file that contains the data for the requested location and dates. If one does not exist, create it by downloading data from NASA POWER and converting it to the correct format.

Parameters:
  • *args – Arguments are passed along to from_location.

  • **kwargs

    Arguments are passed along to from_location.

Returns:

File name.

Return type:

str

classmethod from_location(*args: Any, **kwargs: Any) BaseWeatherFile[source]

Create a weather file from a location by requesting NASA power weather data.

Parameters:
  • *args – Arguments are passed to NASAPOWERWeatherFile.from_location.

  • **kwargs

    Arguments are passed to NASAPOWERWeatherFile.from_location.

Returns:

File instance.

Return type:

BaseWeatherFile

classmethod from_power(fpower: str | NASAPOWERWeatherFile, fname: str | None = None) BaseWeatherFile[source]

Create a weather file from NASA power weather data.

Parameters:
  • src – JSON file containing NASA POWER data.

  • fname – File name where the weather data should be written to.

covers_range(start: date | datetime, end: date | datetime, latitude: float | None = None, longitude: float | None = None) bool[source]

Check if the file contains data for the specified date/time range.

Parameters:
  • start – Start of range.

  • end – End of range.

  • latitude – Latitude that data should cover.

  • longitude – Longitude that data should cover.

Returns:

True if the range is covered, False otherwise.

Return type:

bool

class simulatr.crop.NASAPOWERWeatherFile(fname: str, generated: bool | None = False, contents: dict | None = None, fname_orig: str | None = None)[source]

Bases: BaseWeatherFile

Wrapper for loading NASA POWER data.

property parameters: Any

Get the cached property value, computing it if needed.

property dates: Any

Get the cached property value, computing it if needed.

property latitude: Any

Get the cached property value, computing it if needed.

property longitude: Any

Get the cached property value, computing it if needed.

property start_date: Any

Get the cached property value, computing it if needed.

property end_date: Any

Get the cached property value, computing it if needed.

add_missing_param(parameters: List[str]) None[source]

Fill in any missing parameters.

Parameters:

parameters – Set of parameters that must be present.

classmethod format_filename(latitude: float, longitude: float, start_date: date | None = None, end_date: date | None = None, cache_dir: str | None = None) str[source]

Construct the file name for the cached NASA power file containing the requested data.

Parameters:
  • latitude – Location latitude (degrees).

  • longitude – Location longitude (degrees).

  • start_date – Starting date for data.

  • end_date – Ending date for data.

  • cache_dir – Directory where the data should be cached.

Returns:

File name.

Return type:

str

classmethod from_location(latitude: float, longitude: float, start_date: date | datetime, end_date: date | datetime, parameters: List[str] | None = None, cache_dir: str | None = None) NASAPOWERWeatherFile[source]

Look for an existing file that contains the data for the requested location and dates. If one does not exist, create it by downloading data from NASA POWER.

Parameters:
  • latitude – Location latitude (degrees).

  • longitude – Location longitude (degrees).

  • start_date – Starting date for data.

  • end_date – Ending date for data.

  • parameters – Set of parameters that should be included in the data.

  • cache_dir – Directory where the data should be cached.

Returns:

File instance.

Return type:

NASAPOWERWeatherFile

classmethod download_data(latitude: float, longitude: float, start_date: date | None, end_date: date | None, parameters: List[str] | None = None) dict[source]

Use REST API to get NASA POWER data for a location.

Parameters:
  • latitude – Location latitude (degrees).

  • longitude – Location longitude (degrees).

  • start_date – Starting date for data.

  • end_date – Ending date for data.

  • parameters – Set of parameters to request.

Returns:

JSON result.

Return type:

dict

class simulatr.crop.CropModelEngine(*, model_file: str | List[str] | BaseModelFile | None = None, model_suffix: str | None = None, output_dir: str | None = None, start_time: datetime | None = None, end_time: datetime | None = None, duration: timedelta | None = None, param: dict | None = None, actions: List[str] | None = None, action_map: dict | ModelActionSet | None = None, action_param: dict | None = None, crop_name: str | None = None, crop_variety: str | None = None, sow_date: date | None = None, harvest_date: date | None = None, season_length: int | timedelta | None = None, year: int | None = None, latitude: float | None = None, longitude: float | None = None, weather_file: str | None = None, **extra_data: Any)[source]

Bases: BaseModelEngine

Class for managining communication with a crop simulation model.

Parameters:
  • model_file – Path to one or more model input files.

  • crop_name – Name of the crop.

  • crop_variety – Name of the crop variety/cultivar.

  • sow_date – Date that the crop should be sown.

  • harvest_date – Date that the crop should be harvested.

  • season_length – Time between sowing and harvest. Only used if only one of sow_date or harvest_date are used. If an integer is provided, it is assumed to be in units of days.

  • year – Year to use to get weather data.

  • latitude – Field latitude to use to get weather data.

  • longitude – Field longitude to use to get weather data.

  • weather_file – Path to a file containing NASA power weather data.

  • **kwargs – Additional keywords arguments are passed along to BaseModelEngine.__init__.

model_config = {'arbitrary_types_allowed': True, 'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_CropModelEngine__context: Any) None[source]

Initialize the crop model engine.

Parameters:
  • model_file – Path to one or more model input files.

  • crop_name – Name of the crop.

  • crop_variety – Name of the crop variety/cultivar.

  • sow_date – Date that the crop should be sown.

  • harvest_date – Date that the crop should be harvested.

  • season_length – Time between sowing and harvest. Only used if only one of sow_date or harvest_date are used.

  • year – Year to use to get weather data.

  • latitude – Field latitude to use to get weather data.

  • longitude – Field longitude to use to get weather data.

  • weather_file – Path to a file containing NASA power weather data.

  • **kwargs – Additional keywords arguments are passed along to BaseModelEngine.__init__.

create_model_file() CropModelFile[source]

Create a model input file.

Returns:

Constructed model input file.

Return type:

CropModelFile

update_model_file() None[source]

Update the model file to make it interactive and set the start/end times.

calc_param(name: str, default: Any | None = <class 'simulatr.base.NoDefault'>, **kwargs: Any) Any[source]

Calculate a parameter from other parameters.

Parameters:
  • name – Parameter to calculate.

  • default – Default to return if the parameter cannot be calculated.

  • **kwargs – Additional keyword arguments are passed to parent class’s calc_param.

Returns:

Calculated parameter value.

property location: str

Description of the field location.

Type:

str

property field_area: float

Field area

Type:

float

class simulatr.crop.CropModelLLMPromptGenerator(crop_name: str | None = 'the crop', crop_variety: str | None = None, start_date: date | None = None, season_length: int | None = 241, location: str | None = 'the field', **kwargs: Any)[source]

Bases: BaseModelLLMPromptGenerator

Crop model LLM prompt generator.

__init__(crop_name: str | None = 'the crop', crop_variety: str | None = None, start_date: date | None = None, season_length: int | None = 241, location: str | None = 'the field', **kwargs: Any) None[source]

Initialize the prompt generator.

Parameters:
  • crop_name – Name of the crop being cultivated

  • crop_variety – Name of the crop varient/cultivar being cultivated

  • start_date – Calendar start date of the simulation

  • season_length – Total length of growing season in days

  • location – Geographic location description

  • **kwargs – Additional keyword arguments are forwarded to the BaseModelLLMPromptGenerator.__init__ method.

classmethod from_env(env: CropModelEnv, **kwargs: Any) CropModelLLMPromptGenerator[source]

Create prompt generator from a model gym environment.

Parameters:
  • env – model gym environment instance

  • **kwargs – Additional keyword arguments are passed to the class constructor.

Returns:

CropModelLLMPromptGenerator instance configured for the

environment.

property crop_description: str

Crop description including provided info.

Type:

str

get_system_prompt() str[source]

Generate the system prompt for the LLM agent.

Returns:

System prompt string

turn_context(observation: ndarray) str[source]

Generate a string to summarize the current turn at a high level with the context of the simulation.

Parameters:

observation – Current state.

Returns:

Turn summary.

Return type:

str

class simulatr.crop.CropModelEnv(*, action_space: Any = None, observation_space: Any = None, model_file: str | List[str] | BaseModelFile | None = None, start_time: datetime | None = None, end_time: datetime | None = None, intervention_interval: int | timedelta | None = 7, output_vars: List[str] | None = None, num_levels: int | None = 4, actions: List[str] | None = None, action_map: dict | ModelActionSet | None = None, revenue_var: Dict[str, str | float] | None = None, model_param: dict | None = None, action_param: dict | None = None, allow_donothing: bool | None = True, exclusive: bool | None = True, scale_action_amounts_by_interval: bool | None = False, **extra_data: Any)[source]

Bases: BaseModelEnv

Crop model environment.

get_output_vars() List[str][source]

Get the output variables specified by the model file.

Returns:

Output variables

Return type:

list

model_config = {'arbitrary_types_allowed': True, 'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class simulatr.apsimx.ApsimXWeatherFile(fname: str, generated: bool | None = False, contents: dict | None = None, fname_orig: str | None = None)[source]

Bases: BaseWeatherFile

Container for ApsimX weather data.

property dates: Any

Get the cached property value, computing it if needed.

property latitude: Any

Get the cached property value, computing it if needed.

property longitude: Any

Get the cached property value, computing it if needed.

class simulatr.apsimx.ApsimXFileNode(contents: dict, parent: ApsimXFileNode | None = None, **kwargs: Any)[source]

Bases: object

Container for node in ApsimXFile.

Parameters:
  • contents – Contents of the node.

  • parent – Parent node.

  • **kwargs – Additional keywords are added directly to the node.

__init__(contents: dict, parent: ApsimXFileNode | None = None, **kwargs: Any) None[source]

Initialize a new node.

Parameters:
  • contents – Contents of the node.

  • parent – Parent node.

  • **kwargs – Additional keywords are added directly to the node.

classmethod from_param(node_type: str, **kwargs: Any) ApsimXFileNode[source]

Create a new node from the provided parameters.

Parameters:
  • node_type – Node type.

  • **kwargs – Additional keyword arguments are passed to the class constructor.

Returns:

New node.

Return type:

ApsimXFileNode

classmethod from_file(fname: str, **kwargs: Any) ApsimXFileNode[source]

Create a new node by loading code from the provided JSON file.

Parameters:
  • fname – Full path to file.

  • **kwargs – Additional keyword arguments are passed to the class constructor.

Returns:

New node.

Return type:

ApsimXFileNode

classmethod from_data(name: str, **kwargs: Any) ApsimXFileNode[source]

Create a new node by loading code from a data file.

Parameters:
  • name – Name of the data file resource.

  • **kwargs – Additional keyword arguments are passed to the class constructor.

Returns:

New node.

Return type:

ApsimXFileNode

property root: ApsimXFileNode[source]

Root node

property absolute_path: str[source]

Absolute path to the node from the root node.

Type:

str

property children: Iterator[ApsimXFileNode]

Child nodes.

Type:

list

get(name: str, default: Any) Any[source]

Get the value of the named element from the node.

Parameters:
  • name – Name of the element.

  • default – Value returned if the element is not present.

Returns:

Value of the named element.

Return type:

object

keys() Iterator[str][source]

Get the keys in the node.

values() Iterator[Any][source]

Get the values in the node.

items() Iterator[Any][source]

Get the items in the node.

specialize_crop(crop_name: str, parameter_name: str = 'Crop') None[source]

Specialize the crop referenced by the node.

Parameters:
  • crop_name – Name of crop to specialize.

  • parameter_name – Parameter name where the crop name is stored.

has_parameter(name: str | set) bool[source]

Check if the node has a parameter of a given name.

Parameters:

name – Parameter name.

Returns:

True if the parameter is present, False otherwise.

Return type:

bool

get_parameter(name: str) Any[source]

Get a node parameter value.

Parameters:

name – Parameter name.

Returns:

Parameter value.

Raises:

KeyError – If name is not a valid parameter name.

set_parameter(name: str, value: Any) None[source]

Set a node parameter.

Parameters:
  • name – Parameter name.

  • value – Parameter value.

Raises:

KeyError – If name is not a valid parameter name.

findall(name: str | None = None, requirements: dict | None = None) Iterator[ApsimXFileNode][source]

Find a node in the file.

Parameters:
  • name – Name of the node to find.

  • requirements – Set of requirements that the node must satisfy (see node_matches for a description of the available options).

Yields:

ApsimXFileNode – All nodes matching the specified name.

find(name: str | None = None, required: bool | None = False, requirements: dict | None = None) ApsimXFileNode[source]

Find a node in the file.

Parameters:
  • name – Name of the node to find.

  • required – If True, an error will be raised if the node cannot be located.

  • requirements – Set of requirements that the node must satisfy (see node_matches for a description of the available options).

Returns:

The node matching the specified name.

Empty if no node can be found.

Return type:

ApsimXFileNode

Raises:

KeyError – If required is True and the node cannot be located.

matches(errors: list | None = None, name: str | None = None, field: str | None = None, parameter: str | None = None, internal: str | None = None, contains: list | set | dict | None = None, equals: Any | None = None, fvalid: Callable | None = None, calls: str | None = None, anyOf: list | None = None, nested: dict | None = None, **kwargs: Any) bool[source]

Check if a node matches the specified requirements.

Parameters:
  • errors – If a list is provided, errors will be added to this list.

  • name – Name that the node must have.

  • field – Name of a field that must be present.

  • parameter – Name of a parameter that must be present.

  • contains – Fields/elements that the node must contain. If a set is provided, only one of the elements must be present. If a dict is provided, the values in the node must match the values in the provided dict.

  • equals – Value that the node must be equivalent to.

  • fvalid – Function that returns True if the node is valid, and False otherwise.

  • calls – Name of a function called in the node code block.

  • anyOf – List of kwargs for node_matches that should be checked. If the node satisfies any of these requirements, True will be returned.

  • nested – Set of requirements for individual fields.

  • **kwargs – Additional keyword arguments are ignored.

Returns:

True if the node matches, False otherwise.

Return type:

bool

class simulatr.apsimx.ApsimXFile(fname: str, generated: bool | None = False, contents: dict | None = None, fname_orig: str | None = None)[source]

Bases: CropModelFile

Container for manipulating .apsimx model files.

Parameters:
  • fname – Path to a .apsimx model file.

  • generated – If True, this file was generated.

  • contents – Contents to initialize the file with.

property parameter_nodes: Any

Get the cached property value, computing it if needed.

classmethod available_crops() List[str][source]

Get the crops that can be simulated via this model.

Returns:

Available crop names.

Return type:

list

classmethod available_cultivars(crop_name: str) List[str][source]

Get the cultivars for a given crop that can be simulated via this model.

Parameters:

crop_name – Crop name.

Returns:

Available crop cultivar names.

Return type:

list

classmethod find_example(crop_name: str) str[source]

Locate an example model file for a given crop name.

Parameters:

crop_name – Crop name.

Returns:

Model input file for the specified crop.

Return type:

str

classmethod from_example(src: str | ApsimXFile, dst: str | None = None, interactive: bool = False, actions: List[str] | None = None) CropModelFile[source]

Create an input model file from an example.

Parameters:
  • src (str, ApsimXFile) – Path to the source .apsimx model.

  • dst (str, optional) – Path to the location where the generated .apsimx model should be saved.

  • interactive – If True, make the file interactive.

  • actions – Interactive actions that should be added.

Returns:

Constructed model input file.

Return type:

CropModelFile

classmethod from_crop_name(crop_name: str, dst: str | None = None, interactive: bool = False, actions: List[str] | None = None) CropModelFile[source]

Create an input model file for a given crop name.

Parameters:
  • crop_name – Crop name.

  • dst – Path to the location where the generated file should be saved.

  • interactive – If True, make the file interactive.

  • actions – Interactive actions that should be added.

Returns:

Constructed model input file.

Return type:

CropModelFile

property formal_crop_name: str

Crop name used for resources.

Type:

str

property is_interactive: Any

Get the cached property value, computing it if needed.

disable_parameter_conflicts(name: str, info: dict | None = None, node: dict | None = None) None[source]

Disable nodes that conflict with a parameter/action.

Parameters:
  • name – Action name.

  • info – Information about the parameter.

  • node – Parameter/action node to avoid disabling.

add_parameter(name: str, info: dict | None = None, parent: dict | None = None) dict[source]

Add a node to facilitate use of a parameter/action if it is missing.

Parameters:
  • name – Action name.

  • info – Information about how to add the parameter.

  • parent – Parent node that the action node should be added to if it is missing.

Returns:

Action node.

Return type:

dict

disable_action(name: str, **kwargs: Any) None[source]

Disable any nodes that automatically control an action.

Parameters:
  • name – Action name.

  • **kwargs – Additional keyword arguments are passed to find_parameter.

enable_action(name: str, parent: dict | None = None, **kwargs: Any) dict | None[source]

Enable any nodes that automatically control an action.

Parameters:
  • name – Action name.

  • parent – Parent node that the action node should be added to if it is missing.

  • **kwargs – Additional keyword arguments are passed to find_parameter.

Returns:

Action node.

Return type:

dict

disable(name: str, **kwargs: Any) None[source]

Disable a node in the file if it exists.

Parameters:
  • name – Name of the node to disable.

  • **kwargs – Additional keyword arguments are passed to find.

classmethod includes_constraints(info: dict) bool[source]

Check if a set of node requirements constrain the node.

Parameters:

info – Node requirements.

Returns:

True if info constrains the node, False otherwise.

Return type:

bool

classmethod node_matches(node: Any, errors: list | None = None, name: str | None = None, field: str | None = None, parameter: str | None = None, internal: str | None = None, contains: list | set | dict | None = None, equals: Any | None = None, fvalid: Callable | None = None, calls: str | None = None, anyOf: list | None = None, nested: dict | None = None, **kwargs: Any) bool[source]

Check if a node matches the specified requirements.

Parameters:
  • node – Node to check.

  • errors – If a list is provided, errors will be added to this list.

  • name – Name that the node must have.

  • field – Name of a field that must be present.

  • parameter – Name of a parameter that must be present.

  • contains – Fields/elements that the node must contain. If a set is provided, only one of the elements must be present. If a dict is provided, the values in the node must match the values in the provided dict.

  • equals – Value that the node must be equivalent to.

  • fvalid – Function that returns True if the node is valid, and False otherwise.

  • calls – Name of a function called in the node code block.

  • anyOf – List of kwargs for node_matches that should be checked. If the node satisfies any of these requirements, True will be returned.

  • nested – Set of requirements for individual fields.

  • **kwargs – Additional keyword arguments are ignored.

Returns:

True if the node matches, False otherwise.

Return type:

bool

findall_parameters(name: str, info: dict | None = None, **kwargs: Any) Iterator[dict][source]

Find all parameters nodes in this file matching the parameter info.

Parameters:
  • name – Parameter name.

  • info – Information about how to locate the parameter.

  • **kwargs – Additional keyword arguments are passed to findall.

Yields:

dict – The nodes matching the parameter info.

Raises:

KeyError – If info not provided and name is not a valid parameter/action.

find_parameter(name: str, add_missing: bool | dict | None = False, info: dict | None = None, **kwargs: Any) dict[source]

Find a parameter node in the file.

Parameters:
  • name – Parameter name.

  • add_missing – If True or dict, the default for the parameter will be added if it cannot be located. If a dict is provided, the parameter default will be added to this if the parameter cannot be located.

  • info – Information about how to locate the parameter.

  • **kwargs – Additional keyword arguments are passed to find.

Returns:

The node matching the specified name. Empty if no

node can be found.

Return type:

dict

Raises:

KeyError – If required is True and the node cannot be located.

findall(name: str | None = None, current: dict | None = None, parent: bool | None = False, requirements: dict | None = None) Iterator[dict][source]

Find a node in the file.

Parameters:
  • name – Name of the node to find.

  • current – The current node being searched.

  • parent – If True, the parent node will be returned.

  • requirements – Set of requirements that the node must satisfy (see node_matches for a description of the available options).

Yields:

dict – All nodes matching the specified name.

find(name: str | None = None, current: dict | None = None, parent: bool | None = False, required: bool | None = False, requirements: dict | None = None) dict[source]

Find a node in the file.

Parameters:
  • name – Name of the node to find.

  • current – The current node being searched.

  • parent – If True, the parent node will be returned.

  • required – If True, an error will be raised if the node cannot be located.

  • requirements – Set of requirements that the node must satisfy (see node_matches for a description of the available options).

Returns:

The node matching the specified name. Empty if no

node can be found.

Return type:

dict

Raises:

KeyError – If required is True and the node cannot be located.

class simulatr.apsimx.ApsimXEngine(*, model_file: str | List[str] | BaseModelFile | None = None, model_suffix: str | None = None, output_dir: str | None = None, start_time: datetime | None = None, end_time: datetime | None = None, duration: timedelta | None = None, param: dict | None = None, actions: List[str] | None = None, action_map: dict | ModelActionSet | None = None, action_param: dict | None = None, crop_name: str | None = None, crop_variety: str | None = None, sow_date: date | None = None, harvest_date: date | None = None, season_length: int | timedelta | None = None, year: int | None = None, latitude: float | None = None, longitude: float | None = None, weather_file: str | None = None, from_example: bool | str | None = True, **extra_data: Any)[source]

Bases: CropModelEngine

Class for managing communication with an APSIMX server running in another process.

INPUT_FILE_TYPE

alias of ApsimXFile

WEATHER_FILE_TYPE

alias of ApsimXWeatherFile

model_post_init(_ApsimXEngine__context: Any) None[source]

Initialize the engine.

Parameters:
  • model_file – Path to a .apsimx model input file.

  • **kwargs – Additional keyword arguments are passed to the CropModelEngine constructor.

classmethod apsim_srv() str[source]

Path to the apsimx server.

classmethod is_installed() bool[source]

Check if the model is installed in the specified directory.

Returns:

True if the model is installed, False otherwise.

Return type:

bool

create_model_file() CropModelFile[source]

Create a model input file.

Returns:

Constructed model input file.

Return type:

CropModelFile

property is_running: bool

True if the model engine is still running.

Type:

bool

property is_operable: bool

True if the model engine is running and functioning.

Type:

bool

property current_time: datetime

Current simulation time.

Type:

datetime.datetime

property status: str | None

Current simulation status.

Type:

str

property output_file: str

Path to the .db output file that will be produced.

Type:

str

get_output_vars() List[str][source]

Get the output variables specified by the model file.

Returns:

Output variables

Return type:

list

send_command(command: str, args: list | None = None) None[source]

Send a command to the server process, e.g. resume/set/get.

Parameters:
  • command – Command to send.

  • args – Additional arguments to send with the commaned.

recv_reply(unpack: bool | None = False) Any[source]

Receive a reply from the server process.

Parameters:

unpack – If True, the message will be unpacked using msgpack.

Returns:

Received message.

Return type:

object

check_paused() None[source]

Check that the simulation server is paused.

stop_on_error(record: tuple | None = None, allow_error: bool | None = False) Iterator[None][source]

Context manager that stops the simulation on an error.

Parameters:
  • record – Action to log when successful.

  • allow_error – If True, a RecoverableError error will not result in the simulation being stopped.

resume(wait: bool | None = False) None[source]

Resume the simulation.

Parameters:

wait – If True, wait for the simulation to pause.

model_config = {'arbitrary_types_allowed': True, 'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class simulatr.apsimx.ApsimXLLMPromptGenerator(crop_name: str | None = 'the crop', crop_variety: str | None = None, start_date: date | None = None, season_length: int | None = 241, location: str | None = 'the field', **kwargs: Any)[source]

Bases: CropModelLLMPromptGenerator

ApsimX LLM prompt generator.

class simulatr.apsimx.ApsimXEnv(*, action_space: Any = None, observation_space: Any = None, model_file: str | List[str] | BaseModelFile | None = None, start_time: datetime | None = None, end_time: datetime | None = None, intervention_interval: int | timedelta | None = 7, output_vars: List[str] | None = None, num_levels: int | None = 4, actions: List[str] | None = None, action_map: dict | ModelActionSet | None = None, revenue_var: Dict[str, str | float] | None = None, model_param: dict | None = None, action_param: dict | None = None, allow_donothing: bool | None = True, exclusive: bool | None = True, scale_action_amounts_by_interval: bool | None = False, **extra_data: Any)[source]

Bases: CropModelEnv

ApsimX environment.

MODEL_ENGINE_CLASS

alias of ApsimXEngine

LLM_PROMPT_GENERATOR_CLASS

alias of ApsimXLLMPromptGenerator

model_config = {'arbitrary_types_allowed': True, 'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

simulatr.cli.run(simulator: str, timestep: int = 0, state_variables: List[str] | None = None, **kwargs: Any) None[source]

Run a simulation.

Parameters:
  • simulator – Name of the simulator to run.

  • timestep – Time between actions (in days). 0 for continuous.

  • state_variables – Set of state variables to request at each timestep.

  • **kwargs – Additional keyword arguments are passed along to the engine class constructor.

simulatr.cli.main() None[source]

Run the command line interface.

simulatr.utils.promptuser(prompt: str, _gha_default: str = 'INVALID')[source]

Prompt for input from the user. Set to default if GITHUB_ACTIONS environment variable is set.

Parameters:
  • prompt – Prompt to provide the user with.

  • _gha_default – Default when GITHUB_ACTIONS set.

Returns:

User response.

Return type:

str

class simulatr.utils.LogPipe(pipe: BufferedReader, level: str | int | None = 'INFO', prefix: str | None = '', daemon: bool | None = True, **kwargs: Any)[source]

Bases: Thread

Thread to move output from a process PIPE to the logger.

Parameters:
  • pipe – Pipe that output should be streamed from.

  • level – Integer logging level or the name of the logging level.

  • prefix – Prefix to add to log messages.

  • daemon – True if thread should be daemon.

  • **kwargs – Additional keyword arguments are passed to the threading.Thread constructor.

__init__(pipe: BufferedReader, level: str | int | None = 'INFO', prefix: str | None = '', daemon: bool | None = True, **kwargs: Any) None[source]

Initialize the LogPipe thread.

Parameters:
  • pipe – Pipe that output should be streamed from.

  • level – Integer logging level or the name of the logging level.

  • prefix – Prefix to add to log messages.

  • daemon – True if thread should be daemon.

  • **kwargs – Additional keyword arguments are passed to the threading.Thread constructor.

close() None[source]

Close the pipe.

run() None[source]

Run the thread, moving messages from the pipe to the logger.