Editing model parameters
Editing a model involves changing model parameter values. This task can be accomplished via
a unified method called edit_model() or edit_model_by_path() from ApsimModel Class
by specifying the model type, name and simulation name, or path, respectively.
Tip
Editing APSIM models in apsimNGpy does not require placing the target model inside a Replacements folder or node. However, when modifying cultivar parameters, it can be helpful to include a Replacements folder containing the relevant plant definition hosting that cultivar. In many cases, apsimNGpy will handle this automatically.
Selective editing
Selective editing allows you to apply modifications only to certain simulations. This is not possible when the same model instance is shared through a common Replacements folder. For reliable selective editing, each simulation should ideally reference a uniquely named model. However, even when model names are not unique, apsimNGpy still enables targeted editing through two mechanisms:
Exclusion strategy You can explicitly exclude simulations to which the edits should not be applied.
Specification strategy You can explicitly specify which simulations should have their models edited or replaced with new parameters.
edit_method function signature
edit_model(model_type: str, simulations: Union[str, list], model_name: str, **kwargs)
model_typestr, requiredType of the model component to modify (e.g., ‘Clock’, ‘Manager’, ‘Soils.Physical’, etc.). Please see more details here
simulationsUnion[str, list], optionalA simulation name or list of simulation names in which to search. Defaults to all simulations in the model.
model_namestr, requiredName of the model instance to modify.
The following additional kwargs are specific to each each model type.
**kwargs : dict, required
Weather: requires aweather_file(str) argument, describing path to the.metweather file.
Clock: Date properties such asStartandEndin ISO format (e.g., ‘2021-01-01’).
Manager: Variables to update in the Manager script usingupdate_mgt_by_path. The parameters in a manager script are specific to each script. See Inspect Model Parameters for more details. for more details. for more details. on how to inspect and retrieve these paramters without opening the file in a GUI
Physical | Chemical | Organic | Water:The supported key word arguments for each model type are given in the table below. Please note the values are layered and thus astrorlistis accepted. when a value is supplied asstr, then it goes to the top soil layer. In case of alist, value are replaced based on their respective index in the list. As a caution if the length of the list supplied exceeds the available number of layers in the profile, aRuntimeErrorduring modelrunswill be raised. It is possible to target a specific layer(s) by supplying the location of that layer(s) usingindiceskey word argument, if there is a need to target the bottom layer, useindices = [-1]
Soil Model Type
Supported key word arguments
Physical
AirDry, BD, DUL, DULmm, Depth, DepthMidPoints, KS, LL15, LL15mm, PAWC, PAWCmm, SAT, SATmm, SW, SWmm, Thickness, ThicknessCumulative
Organic
CNR, Carbon, Depth, FBiom, FInert, FOM, Nitrogen, SoilCNRatio, Thickness
Chemical
Depth, PH, Thickness
SurfaceOrganicMatter
InitialCNR: (int)
InitialResidueMass (int)
Report:
report_name(str): Name of the report model (optional depending on structure).
variable_spec(list[str] or str): Variables to include in the report.
set_event_names(list[str], optional): Events that trigger the report.
Cultivar:
commands(str, required): APSIM path to the cultivar model to update.
values(Any. required): Value to assign.
new_cultivar_name(str, required): the new name for the edited cultivar.
cultivar_manager(str, required): Name of the Manager script managing the cultivar, which must contain theCultivarNameparameter. Required to propagate updated cultivar values, as APSIM treats cultivars as read-only.
Warning
Raises the following errors:
ValueErrorIf the model instance is not found, required kwargs are missing, or
kwargsis empty.NotImplementedErrorIf the logic for the specified
model_typeis not implemented.
See also
API description:
edit_model()
Quick Examples:
Edit a cultivar model:
model.edit_model(
model_type='Cultivar',
simulations='Simulation',
commands='[Phenology].Juvenile.Target.FixedValue',
values=256,
new_cultivar_name = 'B_110-e',
model_name='B_110',
cultivar_manager='Sow using a variable rule')
Hint
model_name: 'B_110' is an existing cultivar in the Maize Model, which we want to edit. Please note that editing a cultivar without specifying the new_cultivar_name will throw a ValueError.
The name should be different to the the one being edited.
Edit a soil organic matter module:
model = ApsimModel(model='Maize')
model.edit_model(
model_type='Organic',
simulations='Simulation',
model_name='Organic',
Carbon=1.23)
Edit multiple soil layers:
model = ApsimModel(model='Maize')
model.edit_model(
model_type='Organic',
simulations='Simulation',
model_name='Organic',
Carbon=[1.23, 1.0])
Edit solute models:
model = ApsimModel(model='Maize')
model.edit_model(
model_type='Solute',
simulations='Simulation',
model_name='NH4',
InitialValues=0.2)
model.edit_model(
model_type='Solute',
simulations='Simulation',
model_name='Urea',
InitialValues=0.002)
Edit a manager script:
model = ApsimModel(model='Maize')
model.edit_model(
model_type='Manager',
simulations='Simulation',
model_name='Sow using a variable rule',
population=8.4)
Edit surface organic matter parameters:
model = ApsimModel(model='Maize')
model.edit_model(
model_type='SurfaceOrganicMatter',
simulations='Simulation',
model_name='SurfaceOrganicMatter',
InitialResidueMass=2500)
model.edit_model(
model_type='SurfaceOrganicMatter',
simulations='Simulation',
model_name='SurfaceOrganicMatter',
InitialCNR=85)
Edit Clock start and end dates:
model = ApsimModel(model='Maize')
model.edit_model(
model_type='Clock',
simulations='Simulation',
model_name='Clock',
Start='2021-01-01',
End='2021-01-12')
Edit report variables:
model = ApsimModel(model='Maize')
model.edit_model(
model_type='Report',
simulations='Simulation',
model_name='Report',
variable_spec='[Maize].AboveGround.Wt as abw')
Multiple report variables:
model = ApsimModel(model='Maize')
model.edit_model(
model_type='Report',
simulations='Simulation',
model_name='Report',
variable_spec=[
'[Maize].AboveGround.Wt as abw',
'[Maize].Grain.Total.Wt as grain_weight'
])
If you prefer little boiler plate code, we got you covered with edit_model_by_path
The edit_model_by_path method enables surgical model editing by using the full
APSIM component path to identify the exact target node. This direct addressing
avoids the need for recursive tree traversal, name-matching, or guessing which
simulation contains the intended model. As a result, users
can modify parameters reliably even in complex, deeply nested APSIM structures. Please refer to functional signature and examples
with ApsimModel(model='Maize') as model:
model.edit_model_by_path(path, **kwargs)
Hint
The method edit_model_by_path() from ApsimModel class operates on the same principle as edit_model(), where each model type requires specific keyword arguments.
For example, let’s edit a manager script: "Sow using a variable rule" that performs sowing operations such as plant population, sowing date etc.
with ApsimModel(model='Maize') as model
model.edit_model_by_path(path = '.Simulations.Simulation.Field.Sow using a variable rule', Population =12)
Warning
When using the full path, keep in mind that it inherently references a specific model type. The edit_model_by_path method internally detects this type and applies the appropriate logic.
Therefore, if you supply an argument that is not valid for that model type, a ValueError will be raised.
Tip
if in doubt, use detect_model_type followed by the corresponding full model path or use inspect_file()
with ApsimModel(model='Maize')
model_type = model.detect_model_type('.Simulations.Simulation.Field.Sow using a variable rule')
# outputs: Models.Manager
More examples about edit_model_by_path
from pathlib import Path
from os.path import realpath
from apsimNGpy.core.apsim import ApsimModel
The variable constants listed below are required for the subsequent demonstration example
from apsimNGpy.core.config import load_crop_from_disk
Fertilise_at_sowing = '.Simulations.Simulation.Field.Fertilise at sowing'
SurfaceOrganicMatter = '.Simulations.Simulation.Field.SurfaceOrganicMatter'
Clock = ".Simulations.Simulation.Clock"
Weather = '.Simulations.Simulation.Weather'
Organic = '.Simulations.Simulation.Field.Soil.Organic'
cultivar_path = '.Simulations.Simulation.Field.Maize.CultivarFolder.Generic.B_100'
cultivar_path_soybean ='.Simulations.Simulation.Field.Soybean.Cultivars.Generic.Generic_MG2'
cultivar_path_for_sowed_soybean = '.Simulations.Simulation.Field.Soybean.Cultivars.Australia.Davis'
cultivar_path_for_sowed_maize = '.Simulations.Simulation.Field.Maize.CultivarFolder.Dekalb_XL82'
# Create weather file on disk
met_file = realpath(Path('wf.met'))
met_file = load_crop_from_disk('AU_Goondiwindi', out=met_file, suffix='.met')
Edit cultivar and provide a custom new name
with ApsimModel('Maize') as model:
model.edit_model_by_path(
path=cultivar_path_for_sowed_maize,
commands='[Grain].MaximumGrainsPerCob.FixedValue',
values=20,
sowed=True,
rename='edm'
)
# Verify rename
edited = model.inspect_model_parameters_by_path(cultivar_path)
Mixed code examples for editing weather, organic, clock and manger nodes
with ApsimModel('Maize') as apsim:
#_________________________
# Apply edits
#_________________________
apsim.edit_model_by_path(Fertilise_at_sowing, Amount=12)
apsim.edit_model_by_path(Clock, start_date='01/01/2020')
apsim.edit_model_by_path(SurfaceOrganicMatter, InitialCNR=100)
apsim.edit_model_by_path(Weather, weather_file=realpath(met_file))
apsim.edit_model_by_path(Organic, Carbon=1.23)
#_________________________
# Inspect updated values
#_________________________
organic_params = apsim.inspect_model_parameters_by_path(Organic)
#_________________________
# use dict unpacking
#_________________________
apsim.edit_model_by_path(**dict(path=Organic, Carbon=1.20))
cc = apsim.inspect_model_parameters_by_path(Organic)
#_________________________
# use set_param method
#_________________________
apsim.set_params(dict(path=Organic, Carbon=1.58))
updated = apsim.inspect_model_parameters_by_path(Organic)
edit cultivar when not yet sowed. this is accomplished by providing the fullpath to the manager script sowing the cultivar
with ApsimModel('Maize') as model:
model.inspect_file(cultivar=True)
model.edit_model_by_path(
path='.Simulations.Simulation.Field.Maize.CultivarFolder.Dekalb_XL82',
commands='[Grain].MaximumGrainsPerCob.FixedValue',
values=50,
sowed=True,
rename='edit-added')
with ApsimModel('Maize') as model:
model.edit_model_by_path(
path=cultivar_path,
commands='[Grain].MaximumGrainsPerCob.FixedValue',
values=505,
update_manager=False,
manager_path='.Simulations.Simulation.Field.Sow using a variable rule',
manager_param='CultivarName',
rename='edit-added')
model.save()
params = model.inspect_model_parameters('Models.PMF.Cultivar', 'edit-added')
Edit cultivar parameters, when it is not sowed
with ApsimModel('Soybean') as model:
model.edit_model_by_path(
path=cultivar_path_soybean,
commands='[Grain].MaximumGrainsPerCob.FixedValue',
values=50,
sowed=False,
manager_path='.Simulations.Simulation.Field.Sow using a variable rule',
manager_param='CultivarName',
rename='edit-added')
model.save()
params = model.inspect_model_parameters('Models.PMF.Cultivar', 'edit-added')
Editing nested simulation models
apsimNGpy provides robust capabilities for editing and inspecting deeply nested APSIM NG models,
including models containing multiple simulations that users may wish to run in combination with different
inputs. The example below demonstrates the two complementary strategies for targeted modification—exclusion
and specification. Some of these ideas have already been introduced implicitly; for instance, apsimNGpy.core.apsim.ApsimModel.edit_model_by_path()
is an exclusion-based, surgical editing method that applies changes only to the model component identified by its full path.
More generally, the broader edit_model function offers two useful arguments—simulations and exclude— that
allow users to explicitly select which simulations should receive an edit and which should be omitted, as illustrated in the example that follows.
For this demonstration, we are going to use the ‘Report’ example under the folder Examples. Luckily, apsimNgpy can help us
retrieve this example just specifying its name as follows
from apsimNGpy.core.apsim import ApsimModel
from apsimNGpy.core.config import load_crop_from_disk
How many simulations are this file? let’s find out.
with ApsimModel('Report') as model:
sims = model.inspect_model('Models.Core.Simulation' fullpath= False)
print(sims)
['SimpleReportingSim',
'Annual Reporting In June',
'ContinuousWheatExample',
'Seasonal']
What about reports or database tables?
print(model.inspect_model("Models.Report", fullpath=False)
['ReportSimple', 'ReportOnEvents', 'ReportOnSpecificDaysEveryYear',
'ReportOnSpecificDates', 'ReportArrays',
'ReportDaily', 'ReportWeekly', 'ReportMonthly',
'ReportYearly', 'ReportSimulation', 'AnnualReporting',
'MonthlyReporting', 'DailyReporting', 'ReportInCropAnnually',
'ReportGrainOnHarvesting', 'ReportGrainDaily',
'ReportSpecificDates', 'SeasonalOverall', 'SeasonalByYear',
'SeasonalByYearWithOnKeyword']
What about Manager scripts?
model.inspect_model('Models.Manager')
['.Simulations.SimpleReportingSim.Field.Sowing',
'.Simulations.SimpleReportingSim.Field.Fertilise at sowing',
'.Simulations.SimpleReportingSim.Field.Harvest',
'.Simulations.SimpleReportingSim.Field.AutoIrrig',
'.Simulations.SimpleReportingSim.Field.ReportHelper',
'.Simulations.More Reporting Examples.Perennial Crop Example.Annual Reporting In June.Field.CutRotation',
'.Simulations.More Reporting Examples.Perennial Crop Example.Annual Reporting In June.Field.AutomaticFertiliser',
'.Simulations.More Reporting Examples.Perennial Crop Example.Annual Reporting In June.Field.FertiliseOnFixedDates',
'.Simulations.More Reporting Examples.Perennial Crop Example.Annual Reporting In June.Field.AutomaticIrrigation',
'.Simulations.More Reporting Examples.Perennial Crop Example.Annual Reporting In June.Field.ReportHelper',
'.Simulations.More Reporting Examples.Annual Crop Example.ContinuousWheatExample.Field.Sowing',
'.Simulations.More Reporting Examples.Annual Crop Example.ContinuousWheatExample.Field.Fertilise at sowing',
'.Simulations.More Reporting Examples.Annual Crop Example.ContinuousWheatExample.Field.Harvest',
'.Simulations.More Reporting Examples.Annual Crop Example.ContinuousWheatExample.Field.ReportHelper',
'.Simulations.Grouping.Seasonal.ClimateController',
'.Simulations.Grouping.Seasonal.Field.AutomaticIrrigation']
How many clock models are there?
model.inspect_model('Models.Clock')
['.Simulations.SimpleReportingSim.Clock',
'.Simulations.More Reporting Examples.Perennial Crop Example.Annual Reporting In June.Clock',
'.Simulations.More Reporting Examples.Annual Crop Example.ContinuousWheatExample.Clock',
'.Simulations.Grouping.Seasonal.Clock']
If you look at the simulation: Seasonal, it has a manager script named AutomaticIrrigation and it takes on
this path: .Simulations.Grouping.Seasonal.Field.AutomaticIrrigation. we can edit it in one of the following ways
edit by path
model.inspect_model_parameters_by_path('.Simulations.Grouping.Seasonal.Field.AutomaticIrrigation')
By the above code, it has the following parameters:
{'allowIrrigation': 'False',
'seasonStart': '15-Aug',
'seasonEnd': '30-May',
'seasonsAllocation': '10000',
'triggerDeficit': '50',
'targetDeficit': '99',
'returndays': '1',
'maximumAmount': '30',
'depthPAWC': '300'}
Now edit it by path, change returndays to 3, and maximumAmount to 20
model.edit_model_by_path('.Simulations.Grouping.Seasonal.Field.AutomaticIrrigation',
returndays=3, maximumAmount=20)
Inclusion. Inclusion works by specifying the simulation name where this script is located as follows
model.edit_model(model_type='Models.Manager',
model_name='AutomaticIrrigation',
simulations='Seasonal',
returndays=3, maximumAmount=21)
Next is the exclusion strategy, where we exclude all other simulations that do not have this script or we simply don’t want them edited
exclude_sims = ['SimpleReportingSim', 'Annual Reporting In June', 'ContinuousWheatExample']
model.edit_model(model_type='Models.Manager',
model_name='AutomaticIrrigation',
exclude = exclude_sims,
returndays=3, maximumAmount=21)
Lastly, check to confirm
model.inspect_model_parameters_by_path('.Simulations.Grouping.Seasonal.Field.AutomaticIrrigation')
{'allowIrrigation': 'False',
'seasonStart': '15-Aug',
'seasonEnd': '30-May',
'seasonsAllocation': '10000',
'triggerDeficit': '50',
'targetDeficit': '99',
'returndays': '3',
'maximumAmount': '20',
'depthPAWC': '300'}
Tip
After editing the file or model, you can save the file using the save() method.
Without specifying the full path to the desired storage location, the file will be saved in the current working directory.
In addition, the file will be saved to the current temporally or provided out_path during instantiation if filename is not provided
model.save('./edited_maize_model.apsimx', reload=False)# not reloaded back into memory
model.save('./edited_maize_model.apsimx', reload=True)# reloaded back into memory, this is the default