# How to write a Veros plug-in¶

Writing a plug-in for Veros is relatively simple. A plug-in can be any Python package that accepts a VerosState object. The plug-in is then free to modify the model state in any way it pleases.

The only requirement for the plug-in to be usable in Veros setups is that it declares a special object in its top __init__.py file:

__VEROS_INTERFACE__ = dict(
name='my-plugin',
setup_entrypoint=my_setup_function,
run_entrypoint=my_main_function
)


The functions passed in setup_entrypoint and run_entrypoint are then called by Veros during model set-up and after each time step, respectively, with the model state as the sole argument.

An example for these functions could be:

from veros import veros_method

@veros_method
def my_setup_function(vs):
pass

@veros_method
def my_main_function(vs):
mask = np.logical_and(vs.temp[:, :, -1, vs.tau] * vs.maskT[:, :, -1] < -1.8,
vs.forc_temp_surface < 0.)


In this case, the setup function does nothing, while the main function sets temperature and salinity forcing to 0 where the surface temperature is smaller than -1.8 degrees (a very crude sea ice model).

## Custom settings, variables, and diagnostics¶

In real-world applications, you probably want to use custom settings, variables, and/or diagnostics in your plug-in. You can specify those as additional arguments to __VEROS_INTERFACE__:

__VEROS_INTERFACE__ = dict(
name='my-plugin',
setup_entrypoint=my_setup_function,
run_entrypoint=my_main_function,
settings=my_settings,
variables=my_variables,
conditional_variables=my_conditional_variables,
diagnostics=[MyDiagnostic]
)


In this case, my_settings is a dict mapping the name of the setting to a Setting object:

from collections import OrderedDict  # to preserve order
from veros.settings import Setting

my_settings = OrderedDict([
('enable_my_plugin', Setting(False, bool, 'Enable my plugin')),
('temperature_cutoff', Setting(-1.8, float, 'Cut-off surface temperature')),
])


Similarly, for variables and conditional variables:

from collections import OrderedDict  # to preserve order
from veros.variables import Variable, T_GRID

my_variables = OrderedDict([
('my_variable', Variable('Description', T_GRID, 'unit', 'Long description')),
])

my_conditional_variables = OrderedDict([
('enable_my_plugin',  # condition
OrderedDict([
('my_conditional_variable', Variable(
'description', T_GRID, 'unit', 'Long description'
)),
])),
])


The so-defined settings and variables are then available as attributes of the Veros state object, as usual:

@veros_method
def my_function(vs):
if vs.enable_my_plugin:
vs.my_variable[...] = 0.


For more inspiration on how to specify settings and variables, have a look at the built-in settings.py and variables.py files.

Diagnostics are defined similarly, but they have to be a subclass of VerosDiagnostic.

## Shipping custom model setups¶

You can use a special entrypoint in the setup.py file of your plug-in to inform the Veros command-line interface of your custom setups:

from setuptools import setup

setup(
name='my-plugin',
packages='my_plugin',
entry_points={
'veros.setup_dirs': [
'my_plugin = my_plugin.setup'
]
}
)


This assumes, that your custom setups are located in the folder my_plugin/setup. Then, veros copy-setup will automatically find your custom setups if the plug-in is installed:

$veros copy-setup --help Usage: veros copy-setup [OPTIONS] SETUP Copy a standard setup to another directory. Available setups: acc, acc_sector, eady, global_1deg, global_4deg, global_flexible, my_setup, north_atlantic, wave_propagation Example:$ veros copy-setup global_4deg --to ~/veros-setups/4deg-lowfric

Further directories containing setup templates can be added to this
command via the VEROS_SETUP_DIR environment variable.

Options:
--to PATH  Target directory, must not exist (default: copy to current
working directory)
--help     Show this message and exit.


In this case, the custom setup is located in the folder my_plugin/setup/my_setup, and thus shows up as my_setup.