Skip to content

Model components

Each SWAP model is composed of components like lego blocks. This module defines all the components that can be used to build a SWAP model.

General settings

Model metadata.

Classes:

Name Description
Metadata

Metadata of a SWAP model.

Metadata

Bases: PySWAPBaseModel, SerializableMixin

Metadata of a SWAP model.

Metadata is intended more as a modelling exercise metadata than a model metadata. You should create one Metadata object at the beginning of your model script and pass it to all Model objects you create in between. It is used to describe model runs if they are stored in a database. Only project is passed to the swap file.

Attributes:

Name Type Description
author str

Author of the model.

institution str

Institution of the author.

email str

Email of the author.

project str

Name of the project.

swap_ver str

Version of SWAP used.

comment Optional[str]

Comment about the model.

Source code in pyswap/components/metadata.py
class Metadata(PySWAPBaseModel, SerializableMixin):
    """Metadata of a SWAP model.

    Metadata is intended more as a modelling exercise metadata than a model
    metadata. You should create one Metadata object at the beginning of your
    model script and pass it to all Model objects you create in between. It is
    used to describe model runs if they are stored in a database. Only `project`
    is passed to the swap file.

    Attributes:
        author (str): Author of the model.
        institution (str): Institution of the author.
        email (str): Email of the author.
        project (str): Name of the project.
        swap_ver (str): Version of SWAP used.
        comment (Optional[str]): Comment about the model.
    """

    author: String = Field(exclude=True)
    institution: String = Field(exclude=True)
    email: String = Field(exclude=True)
    project: String
    swap_ver: String = Field(exclude=True)
    comment: String | None = Field(default=None, exclude=True)

General settings for the simulation and settings for the Richards' equation.

Classes:

Name Description
GeneralSettings

General settings of the simulation.

RichardsSettings

Settings for the Richards' equation.

GeneralSettings

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

General settings of the simulation.

Attributes:

Name Type Description
pathwork str

Path to the working directory. Immutable attribute.

pathatm str

Path to folder with weather files. Immutable attribute.

pathcrop str

Path to folder with crop files. Immutable attribute.

pathdrain str

Path to folder with drainage files. Immutable attribute.

swscre Literal[0, 1, 3]

Switch, display progression of simulation run to screen

swerror Literal[0, 1]

Switch for printing errors to screen

tstart d

Start date of simulation run, give day-month-year

tend d

End date of simulation run, give day-month-year

nprintday int

Number of output times during a day

swmonth Literal[0, 1]

Switch, output each month

swyrvar Literal[0, 1]

Output times for overall water and solute balances in .BAL and .BLC file: choose output at a fixed date each year or at different dates

period Optional[int]

Fixed output interval

swres Optional[Literal[0, 1]]

Switch, reset output interval counter each year

swodat Optional[Literal[0, 1]]

Switch, extra output dates are given in table below

outdatin Optional[DateList]

list of specific dates

datefix Optional[DayMonth]

fixed date for output

outdat Optional[DateList]

specify all output dates

outfil str

Generic file name of output files. Immutable attribute.

swheader Literal[0, 1]

Print header at the start of each balance period

extensions list

list of file extensions SWAP should return. Available options are: ["wba", "end", "vap", "bal", "blc", "sba", "ate", "bma", "drf", "swb", "ini", "inc", "crp", "str", "irg", "csv", "csv_tz"]

inlist_csv Optional[StringList]

list of

inlist_csv_tz Optional[StringList]

list of variables for the csv tz output

swafo Literal[0, 1, 2]

Switch, output file with formatted hydrological data

swaun Literal[0, 1, 2]

Switch, output file with unformatted hydrological data

critdevmasbal Optional[float]

Critical Deviation in water balance during PERIOD

swdiscrvert Literal[0, 1]

Switch to convert vertical discretization

numnodnew Optional[int]

New number of nodes

dznew Optional[FloatList]

Thickness of compartments

Source code in pyswap/components/simsettings.py
class GeneralSettings(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """General settings of the simulation.

    Attributes:
        pathwork (str): Path to the working directory. Immutable attribute.
        pathatm (str): Path to folder with weather files. Immutable attribute.
        pathcrop (str): Path to folder with crop files. Immutable attribute.
        pathdrain (str): Path to folder with drainage files. Immutable attribute.
        swscre (Literal[0, 1, 3]): Switch, display progression of simulation
            run to screen
        swerror (Literal[0, 1]): Switch for printing errors to screen
        tstart (d): Start date of simulation run, give day-month-year
        tend (d): End date of simulation run, give day-month-year
        nprintday (int): Number of output times during a day
        swmonth (Literal[0, 1]): Switch, output each month
        swyrvar (Literal[0, 1]): Output times for overall water and solute
            balances in *.BAL and *.BLC file: choose output at a fixed date
            each year or at different dates
        period (Optional[int]): Fixed output interval
        swres (Optional[Literal[0, 1]]): Switch, reset output interval counter
            each year
        swodat (Optional[Literal[0, 1]]): Switch, extra output dates are given
            in table below
        outdatin (Optional[DateList]): list of specific dates
        datefix (Optional[DayMonth]): fixed date for output
        outdat (Optional[DateList]): specify all output dates
        outfil (str): Generic file name of output files. Immutable attribute.
        swheader (Literal[0, 1]): Print header at the start of each
            balance period
        extensions (list): list of file extensions SWAP should return.
            Available options are: ["wba", "end", "vap", "bal", "blc", "sba", "ate",
            "bma", "drf", "swb", "ini", "inc", "crp", "str", "irg", "csv", "csv_tz"]
        inlist_csv (Optional[StringList]): list of
        inlist_csv_tz (Optional[StringList]): list of variables for
            the csv tz output
        swafo (Literal[0, 1, 2]): Switch, output file with
            formatted hydrological data
        swaun (Literal[0, 1, 2]): Switch, output file with
            unformatted hydrological data
        critdevmasbal (Optional[float]): Critical Deviation in
            water balance during PERIOD
        swdiscrvert (Literal[0, 1]): Switch to convert vertical discretization
        numnodnew (Optional[int]): New number of nodes
        dznew (Optional[FloatList]): Thickness of compartments
    """

    model_config = _ConfigDict(
        validate_assignment=True, use_enum_values=True, extra="ignore"
    )
    _all_extensions: _ClassVar[list[str]] = _EXTENSIONS
    extensions: list[str] = _Field(default_factory=list, exclude=True)
    exts: _Subsection[_ExtensionMixin] | None = None

    pathwork: _String = _Field(default=_BASE_PATH, frozen=True)
    pathatm: _String = _Field(default=_BASE_PATH, frozen=True)
    pathcrop: _String = _Field(default=_BASE_PATH, frozen=True)
    pathdrain: _String = _Field(default=_BASE_PATH, frozen=True)
    swscre: _Literal[0, 1, 3] = 0
    swerror: _Literal[0, 1] = 0

    tstart: _date | None = None
    tend: _date | None = None

    nprintday: int = _Field(default=1, ge=1, le=1440)
    swmonth: _Literal[0, 1] | None = None  # 1
    swyrvar: _Literal[0, 1] | None = None  # 0
    period: int | None = _Field(default=None, **_YEARRANGE)
    swres: _Literal[0, 1] | None = None
    swodat: _Literal[0, 1] | None = None
    outdatin: _Arrays | None = None
    datefix: _DayMonth | None = None
    outdat: _Arrays | None = None

    outfil: _String = _Field(default=_FNAME_OUT, frozen=True)
    swheader: _Literal[0, 1] = 0

    inlist_csv: _StringList | None = None
    inlist_csv_tz: _StringList | None = None
    swafo: _Literal[0, 1, 2] = 0
    swaun: _Literal[0, 1, 2] = 0
    critdevmasbal: float | None = _Field(default=None, **_UNITRANGE)
    swdiscrvert: _Literal[0, 1] = 0
    numnodnew: int | None = None
    dznew: _Arrays | None = None

    @_model_validator(mode="after")
    def validate_extensions(self):
        invalid_extensions = [
            ext for ext in self.extensions if ext not in self._all_extensions
        ]
        if invalid_extensions:
            msg = f"Invalid extensions: {', '.join(invalid_extensions)}"
            raise ValueError(msg)

        # Create the _ExtensionMixin object without triggering validation
        object.__setattr__(
            self,
            "exts",
            _ExtensionMixin(**{
                ext: 1 if ext in self.extensions else 0 for ext in self._all_extensions
            }),
        )
        return self

RichardsSettings

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Settings for the Richards' equation.

Attributes:

Name Type Description
swkmean Literal[1, 2, 3, 4, 5, 6]

Switch for averaging method of hydraulic conductivity

swkimpl Literal[0, 1]

Switch for updating hydraulic conductivity during iteration

dtmin float

Minimum timestep [1.d-7..0.1 d]

dtmax float

Maximum timestep [dtmin..1 d]

gwlconv float

Maximum difference of groundwater level between time steps [1.d-5..1000 cm]

critdevh1cp float

Maximum relative difference in pressure heads per compartment [1.0d-10..1.d3]

critdevh2cp float

Maximum absolute difference in pressure heads per compartment [1.0d-10..1.d3 cm]

critdevponddt float

Maximum water balance error of ponding layer [1.0d-6..0.1 cm]

maxit int

Maximum number of iteration cycles [5..100]

maxbacktr int

Maximum number of back track cycles within an iteration cycle [1..10]

Source code in pyswap/components/simsettings.py
class RichardsSettings(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Settings for the Richards' equation.

    Attributes:
        swkmean (Literal[1, 2, 3, 4, 5, 6]): Switch for averaging method of hydraulic conductivity
        swkimpl (Literal[0, 1]): Switch for updating hydraulic conductivity during iteration
        dtmin (float): Minimum timestep [1.d-7..0.1 d]
        dtmax (float): Maximum timestep [dtmin..1 d]
        gwlconv (float): Maximum difference of groundwater level between time steps [1.d-5..1000 cm]
        critdevh1cp (float): Maximum relative difference in pressure heads per compartment [1.0d-10..1.d3]
        critdevh2cp (float): Maximum absolute difference in pressure heads per compartment [1.0d-10..1.d3 cm]
        critdevponddt (float): Maximum water balance error of ponding layer [1.0d-6..0.1 cm]
        maxit (int): Maximum number of iteration cycles [5..100]
        maxbacktr (int): Maximum number of back track cycles within an iteration cycle [1..10]
    """

    swkmean: _Literal[1, 2, 3, 4, 5, 6] | None = None
    swkimpl: _Literal[0, 1] | None = None
    dtmin: float | None = _Field(default=0.000001, ge=1e-7, le=0.1)
    dtmax: float | None = _Field(default=0.04, ge=0.000001, le=1.0)
    gwlconv: float | None = _Field(default=100.0, ge=1e-5, le=1000.0)
    critdevh1cp: float | None = _Field(default=0.01, ge=1e-10, le=1e3)
    critdevh2cp: float | None = _Field(default=0.1, ge=1e-10, le=1e3)
    critdevponddt: float | None = _Field(default=0.0001, ge=1e-6, le=0.1)
    maxit: int | None = _Field(default=30, ge=5, le=100)
    maxbacktr: int | None = _Field(default=3, ge=1, le=10)

Meteorological settings

Meteorology settings and data.

This module contains the classes and functions to handle meteorological settings and data for simulations.

Classes:

Name Description
MetFile

Meteorological data for the .met file.

Meteorology

Meteorological settings of the simulation.

Functions:

Name Description
load_from_csv

Load meteorological data from a CSV file.

load_from_knmi

Load meteorological data from KNMI API.

MetFile

Bases: PySWAPBaseModel, FileMixin, SerializableMixin

Meteorological data for the .met file.

This object is created by functions fetching or loading meteorological data from various sources. The data is stored as a pandas.DataFrame, but is formatted with a custom field serializer of the CSVTable field type.

Attributes:

Name Type Description
metfil str

name of the .met file

content CSVTable

meteorological data file

Source code in pyswap/components/meteorology.py
class MetFile(_PySWAPBaseModel, _FileMixin, _SerializableMixin):
    """Meteorological data for the .met file.

    This object is created by functions fetching or loading meteorological data
    from various sources. The data is stored as a pandas.DataFrame, but
    is formatted with a custom field serializer of the CSVTable field type.

    Attributes:
        metfil (str): name of the .met file
        content (CSVTable): meteorological data file
    """

    # None, because the extension has to be added to metfil
    _extension: bool = _PrivateAttr(default=None)

    metfil: _String
    content: _CSVTable | None = _Field(default=None, exclude=True)

Meteorology

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Meteorological settings of the simulation.

Note

SWRAIN and SWETSINE should be optional, but Fortran code evaluates its presence anyway. They are set to 0 by default.

Attributes:

Name Type Description
meteo_location Location

a point GIS object. If provided, lat and alt must not be provided. By default they are overwritten.

lat Decimal

latitude of the meteo station [degrees].

swetr int

Switch type of weather data for potential evapotranspiration:

  • 0 - Use basic weather data and apply Penman-Monteith equation.
  • 1 - Use reference evapotranspiration data in combination with crop factors.
swdivide int

Switch for distribution of E and T. Defaults to 0:

  • 0 - Based on crop and soil factors.
  • 1 - Based on direct application of Penman-Monteith.
swmetdetail int

Switch for time interval of evapotranspiration and rainfall weather data:

  • 0 - Daily data.
  • 1 - Subdaily data.
swrain int

Switch for use of actual rainfall intensity, defaults to 0:

  • 0 - Use daily rainfall amounts.
  • 1 - Use daily rainfall amounts + mean intensity.
  • 2 - Use daily rainfall amounts + duration.
  • 3 - Use detailed rainfall records (dt < 1 day), as supplied in separate file.
swetsine int

Switch, distribute daily Tp and Ep according to sinus wave, default to 0:

  • 0 - No distribution.
  • 1 - Distribute Tp and Ep according to sinus wave.
metfile MetFile

MetFile model containing meteorological data to be saved to .met file.

alt Decimal

Altitude of the meteo station [m].

altw Decimal

Altitude of the wind [m].

angstroma Decimal

Fraction of extraterrestrial radiation reaching the earth on overcast days.

angstromb Decimal

Additional fraction of extraterrestrial radiation reaching the earth on clear days.

table_rainflux Table

rainfall intensity RAINFLUX as function of time TIME.

rainfil str

file name of file with detailed rainfall data.

nmetdetail int

Number of weather data records each day.

Properties

met: Returns the string representation of the met file.

Methods:

Name Description
write_met

Writes the .met file.

Source code in pyswap/components/meteorology.py
class Meteorology(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Meteorological settings of the simulation.

    !!! note
        SWRAIN and SWETSINE should be optional,
        but Fortran code evaluates its presence anyway. They are set to
        0 by default.


    Attributes:
        meteo_location (Location): a point GIS object. If provided, lat
            and alt must not be provided. By default they are overwritten.
        lat (Decimal): latitude of the meteo station [degrees].
        swetr (int): Switch type of weather data for
            potential evapotranspiration:

            * 0 - Use basic weather data and apply Penman-Monteith equation.
            * 1 - Use reference evapotranspiration data in combination with
                crop factors.

        swdivide (int): Switch for distribution of E and T. Defaults to 0:

            * 0 - Based on crop and soil factors.
            * 1 - Based on direct application of Penman-Monteith.

        swmetdetail (int): Switch for time interval of evapotranspiration and
            rainfall weather data:

            * 0 - Daily data.
            * 1 - Subdaily data.

        swrain (int): Switch for use of actual rainfall intensity,
            defaults to 0:

            * 0 - Use daily rainfall amounts.
            * 1 - Use daily rainfall amounts + mean intensity.
            * 2 - Use daily rainfall amounts + duration.
            * 3 - Use detailed rainfall records (dt < 1 day), as supplied in
                separate file.

        swetsine (int): Switch, distribute daily Tp and Ep according to
            sinus wave, default to 0:

            * 0 - No distribution.
            * 1 - Distribute Tp and Ep according to sinus wave.

        metfile (MetFile): MetFile model containing meteorological data to
            be saved to .met file.
        alt (Decimal): Altitude of the meteo station [m].
        altw (Decimal): Altitude of the wind [m].
        angstroma (Decimal): Fraction of extraterrestrial radiation reaching
            the earth on overcast days.
        angstromb (Decimal): Additional fraction of extraterrestrial radiation
            reaching the earth on clear days.
        table_rainflux (Table): rainfall intensity RAINFLUX as function
            of time TIME.
        rainfil (str): file name of file with detailed rainfall data.
        nmetdetail (int): Number of weather data records each day.

    Properties:
        met: Returns the string representation of the met file.

    Methods:
        write_met: Writes the .met file.
    """

    lat: _Decimal2f | None = _Field(default=None, ge=-90, le=90)
    meteo_location: _Location | None = _Field(default=None, exclude=True)
    swetr: _Literal[0, 1] | None = None
    swdivide: _Literal[0, 1] | None = None
    swrain: _Literal[0, 1, 2, 3] | None = 0
    swetsine: _Literal[0, 1] = 0
    metfile: _File | None = _Field(default=None, repr=False)
    alt: _Decimal2f | None = _Field(default=None, ge=-400.0, le=3000.0)
    altw: _Decimal2f = _Field(default=None, ge=0.0, le=99.0)
    angstroma: _Decimal2f = _Field(default=None, **_UNITRANGE)
    angstromb: _Decimal2f = _Field(default=None, **_UNITRANGE)
    swmetdetail: _Literal[0, 1] | None = None
    table_rainflux: _Table | None = None
    rainfil: _String | None = None
    nmetdetail: int | None = _Field(default=None, ge=1, le=96)

    @property
    def met(self):
        return self.metfile.content.to_csv(index=False, lineterminator="\n")

    def model_post_init(self, __context=None):
        """Set lat, and alt from `meteo_location` if Location object is provided."""
        if self.meteo_location:
            self.lat = self.meteo_location.lat
            self.alt = self.meteo_location.alt

        self._validation = True
        self.validate_with_yaml()
        self._validation = False

    def write_met(self, path: str):
        """Write the .met file.

        !!! note

            in this function the extension is not passed because
            swp file requires the metfile parameter to be passed already with
            the extension.

        Parameters:
            path (str): Path to the file.
        """

        self.metfile.save_file(string=self.met, fname=self.metfile.metfil, path=path)

model_post_init(__context=None)

Set lat, and alt from meteo_location if Location object is provided.

Source code in pyswap/components/meteorology.py
def model_post_init(self, __context=None):
    """Set lat, and alt from `meteo_location` if Location object is provided."""
    if self.meteo_location:
        self.lat = self.meteo_location.lat
        self.alt = self.meteo_location.alt

    self._validation = True
    self.validate_with_yaml()
    self._validation = False

write_met(path)

Write the .met file.

Note

in this function the extension is not passed because swp file requires the metfile parameter to be passed already with the extension.

Parameters:

Name Type Description Default
path str

Path to the file.

required
Source code in pyswap/components/meteorology.py
def write_met(self, path: str):
    """Write the .met file.

    !!! note

        in this function the extension is not passed because
        swp file requires the metfile parameter to be passed already with
        the extension.

    Parameters:
        path (str): Path to the file.
    """

    self.metfile.save_file(string=self.met, fname=self.metfile.metfil, path=path)

metfile_from_csv(metfil, csv_path, **kwargs)

Method for loading meteorological data from a CSV file.

Parameters:

Name Type Description Default
metfil str

name of the .met file

required
csv_path str

path to the CSV file

required
**kwargs dict

keyword arguments for pandas.read_csv

{}

Returns:

Type Description
MetFile

MetFile object.

Source code in pyswap/components/meteorology.py
def metfile_from_csv(metfil: str, csv_path: str, **kwargs) -> MetFile:
    """Method for loading meteorological data from a CSV file.

    Parameters:
        metfil (str): name of the .met file
        csv_path (str): path to the CSV file
        **kwargs (dict): keyword arguments for pandas.read_csv

    Returns:
        MetFile object.
    """

    return MetFile(metfil=metfil, content=_read_csv(csv_path, **kwargs))

metfile_from_knmi(metfil, stations, variables, start='20000101', end='20200101', frequency='day', inseason=False)

Retrieves the meteorological data from KNMI API using knmi-py and enforces SWAP required format.

Parameters:

Name Type Description Default
metfil str

name of the .met file

required
stations str | list

station number(s) to retrieve data from

required
variables str | list

variables to retrieve

required
start str | dt

start date of the data

'20000101'
end str | dt

end date of the data

'20200101'
frequency Literal[day, hour]

frequency of the data (day or hour)

'day'
inseason bool

whether to retrieve in-season data

False

Returns:

Type Description
MetFile

MetFile object.

Source code in pyswap/components/meteorology.py
def metfile_from_knmi(
    metfil: str,
    stations: str | list,
    variables: list[
        _Literal[
            "WIND",
            "TEMP",
            "SUNR",
            "PRCP",
            "VICL",
            "WEER",
            "DD",
            "FH",
            "FF",
            "FX",
            "T",
            "T10N",
            "TD",
            "SQ",
            "Q",
            "DR",
            "RH",
            "P",
            "VV",
            "N",
            "U",
            "WW",
            "IX",
            "M",
            "R",
            "S",
            "O",
            "Y",
            "UG",
            "FG",
            "UX",
            "UN",
        ]
    ],
    start: str | _datetime = "20000101",
    end: str | _datetime = "20200101",
    frequency: _Literal["day", "hour"] = "day",
    inseason: bool = False,
) -> MetFile:
    """Retrieves the meteorological data from KNMI API using knmi-py and
    enforces SWAP required format.

    Parameters:
        metfil (str): name of the .met file
        stations (str | list): station number(s) to retrieve data from
        variables (str | list): variables to retrieve
        start (str | dt): start date of the data
        end (str | dt): end date of the data
        frequency (Literal['day', 'hour']): frequency of the data (day or hour)
        inseason (bool): whether to retrieve in-season data

    Returns:
        MetFile object.
    """

    if isinstance(stations, str):
        stations = [stations]
    if isinstance(variables, str):
        variables = [variables]

    if not variables:
        variables = ["TEMP", "PRCP", "Q", "UG", "FG", "UX", "UN"]

    get_func = (
        _get_day_data_dataframe if frequency == "day" else _get_hour_data_dataframe
    )

    df = get_func(
        stations=stations, start=start, end=end, variables=variables, inseason=inseason
    )

    # rename some columns
    required_column_names = {
        "STN": "Station",
        "TN": "Tmin",
        "TX": "Tmax",
        "UG": "HUM",
        "DR": "WET",
        "FG": "WIND",
        "RH": "RAIN",
        "EV24": "ETref",
        "Q": "RAD",
    }

    df = df.rename(columns=required_column_names)

    # recalculation of the parameters, the original unit is 0.1 Unit
    df[["Tmin", "Tmax", "ETref", "RAIN", "WIND"]] = df[
        ["Tmin", "Tmax", "ETref", "RAIN", "WIND"]
    ].multiply(0.1)

    # The required unit is days
    df["WET"] = df["WET"].multiply(0.1).multiply(24)

    return MetFile(metfil=metfil, content=df)

Crop settings

Crop settings and crop files for SWAP model.

Similar to the .dra or .swp files, the .crp file is a configuration file for the SWAP model. The classes in this module represent distincs sections of the .crp file. The main class is the CropFile class which holds the settings for the crop simulation.

SWAP has three modes for crop simulations which users define in the CROPROTATION _table in the .swp file:

* 1 - simple crop settings - use CropDevelopmentSettingsFixed
* 2 - detailed, WOFOST general settings - use CropDevelopmentSettingsWOFOST
* 3 - dynamic grass growth model - use CropDevelopmentSettingsGrass

For each choice, the .crp file will look different. Therefore, multiple classes are defined in this module to deal with thos different settings.

Classes:

Name Description
CropFile

Class for the .crp file.

CropDevelopmentSettingsWOFOST

Class for the crop development settings in WOFOST.

CropDevelopmentSettingsFixed

Class for the fixed crop development settings.

CropDevelopmentSettingsGrass

Class for the grass crop development settings.

OxygenStress

Class for the oxygen stress settings.

DroughtStress

Class for the drought stress settings.

SaltStress

Class for the salt stress settings.

CompensateRWUStress

Class for the compensate root water uptake stress settings.

Interception

Class for the interception settings.

CO2Correction

Class for the CO2 correction settings.

ScheduledIrrigation

Class for the scheduled irrigation settings.

Preparation

Class for the preparation settings.

AMAXTB

Bases: BaseTableModel

maximum CO2 assimilation rate [0..100 kg/ha/hr, R] as function of development stage [0..2 -, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

AMAX Series[float]

Maximum CO2 assimilation rate.

Source code in pyswap/components/tables.py
class AMAXTB(BaseTableModel):
    """maximum CO2 assimilation rate [0..100 kg/ha/hr, R] as function of development stage [0..2 -, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        AMAX (Series[float]): Maximum CO2 assimilation rate.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    AMAX: Series[float] = pa.Field(ge=0.0, le=100.0)

CFTB

Bases: BaseTableModel

Crop Height [0..1.d4 cm, R], as function of dev. stage [0..2 -, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

CF Series[float]

Crop factor.

Source code in pyswap/components/tables.py
class CFTB(BaseTableModel):
    """Crop Height [0..1.d4 cm, R], as function of dev. stage [0..2 -, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        CF (Series[float]): Crop factor.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    CH: Series[float] | None
    CF: Series[float] | None

CO2Correction

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin, WOFOSTUpdateMixin

CO2 correction settings for WOFOST-type .crp file.

Attributes:

Name Type Description
swco2 Literal[0, 1]

Switch for assimilation correction due to CO2 impact

  • 0 - No CO2 assimilation correction
  • 1 - CO2 assimilation correction
atmofil Optional[str]

alternative filename for atmosphere.co2

co2amaxtb Optional _Arrays]

Correction of photosynthesis as a function of atmospheric CO2 concentration

co2efftb Optional _Arrays]

orrection of radiation use efficiency as a function of atmospheric CO2 concentration

co2tratb Optional _Arrays]

Correction of transpiration as a function of atmospheric CO2 concentration

Source code in pyswap/components/crop.py
class CO2Correction(
    _PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin, _WOFOSTUpdateMixin
):
    """CO2 correction settings for WOFOST-type .crp file.

    Attributes:
        swco2 (Literal[0, 1]): Switch for assimilation correction due to CO2 impact

            * 0 - No CO2 assimilation correction
            * 1 - CO2 assimilation correction

        atmofil (Optional[str]): alternative filename for atmosphere.co2
        co2amaxtb (Optional _Arrays]): Correction of photosynthesis as a function of atmospheric CO2 concentration
        co2efftb (Optional _Arrays]): orrection of radiation use efficiency as a function of atmospheric CO2 concentration
        co2tratb (Optional _Arrays]): Correction of transpiration as a function of atmospheric CO2 concentration
    """

    _validation: bool = _PrivateAttr(default=False)
    wofost_variety: _CropVariety | None = _Field(default=None, exclude=True)

    swco2: _Literal[0, 1] | None = None
    atmofil: str | None = None
    co2amaxtb: _Arrays | None = None
    co2efftb: _Arrays | None = None
    co2tratb: _Arrays | None = None

CROPROTATION

Bases: BaseTableModel

Crop rotation settings

Attributes:

Name Type Description
CROPSTART Series[DateTime]

Start date of the crop.

CROPEND Series[DateTime]

End date of the crop.

CROPFIL Series[str]

Crop file name.

CROPTYPE Series[int]

Crop module type

  • 1 - simple
  • 2 - detailed, WOFOST general
  • 3 - detailed, WOFOST grass
Source code in pyswap/components/tables.py
class CROPROTATION(BaseTableModel):
    """Crop rotation settings

    Attributes:
        CROPSTART (Series[pa.DateTime]): Start date of the crop.
        CROPEND (Series[pa.DateTime]): End date of the crop.
        CROPFIL (Series[str]): Crop file name.
        CROPTYPE (Series[int]): Crop module type

            * 1 - simple
            * 2 - detailed, WOFOST general
            * 3 - detailed, WOFOST grass
    """

    CROPSTART: Series[pa.DateTime]
    CROPEND: Series[pa.DateTime]
    CROPFIL: Series[str]
    CROPTYPE: Series[int] = pa.Field(ge=1, le=3)

CompensateRWUStress

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Compensate root water uptake stress settings for .crp file.

Attributes:

Name Type Description
swcompensate Literal[0, 1, 2]

Switch for compensate root water uptake stress

  • 0 - No compensation
  • 1 - Compensation according to Jarvis (1989)
  • 2 - Compensation according to Walsum (2019)
swstressor Optional[Literal[1, 2, 3, 4, 5]]

Switch for stressor

  • 1 - Compensation of all stressors
  • 2 - Compensation of drought stress
  • 3 - Compensation of oxygen stress
  • 4 - Compensation of salinity stress
  • 5 - Compensation of frost stress
alphacrit Optional[float]

Critical stress index for compensation of root water uptake

dcritrtz Optional[float]

Threshold of rootzone thickness after which compensation occurs

Source code in pyswap/components/crop.py
class CompensateRWUStress(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Compensate root water uptake stress settings for .crp file.

    Attributes:
        swcompensate (Literal[0, 1, 2]): Switch for compensate root water uptake stress

            * 0 - No compensation
            * 1 - Compensation according to Jarvis (1989)
            * 2 - Compensation according to Walsum (2019)

        swstressor (Optional[Literal[1, 2, 3, 4, 5]]): Switch for stressor

            * 1 - Compensation of all stressors
            * 2 - Compensation of drought stress
            * 3 - Compensation of oxygen stress
            * 4 - Compensation of salinity stress
            * 5 - Compensation of frost stress

        alphacrit (Optional[float]): Critical stress index for compensation of root water uptake
        dcritrtz (Optional[float]): Threshold of rootzone thickness after which compensation occurs
    """

    swcompensate: _Literal[0, 1, 2] | None = None
    swstressor: _Literal[1, 2, 3, 4, 5] | None = None
    alphacrit: float | None = _Field(default=None, ge=0.2, le=1.0)
    dcritrtz: float | None = _Field(default=None, ge=0.02, le=100.0)

Crop

Bases: PySWAPBaseModel, SerializableMixin, FileMixin, YAMLValidatorMixin

Crop settings of the simulation.

Attributes:

Name Type Description
swcrop int

Switch for crop:

  • 0 - Bare soil.
  • 1 - Simulate crop.
rds Optional[float]

Rooting depth of the crop [cm].

_table_croprotation Optional[Table]

_Table with crop rotation data.

cropfiles Optional[List[CropFile]]

List of crop files.

Methods:

Name Description
write_crop

Write the crop files.

Source code in pyswap/components/crop.py
class Crop(_PySWAPBaseModel, _SerializableMixin, _FileMixin, _YAMLValidatorMixin):
    """Crop settings of the simulation.

    Attributes:
        swcrop (int): Switch for crop:

            * 0 - Bare soil.
            * 1 - Simulate crop.

        rds (Optional[float]): Rooting depth of the crop [cm].
        _table_croprotation (Optional[_Table]): _Table with crop rotation data.
        cropfiles (Optional[List[CropFile]]): List of crop files.

    Methods:
        write_crop: Write the crop files.
    """

    swcrop: _Literal[0, 1, None] = None
    rds: float | None = _Field(default=None, ge=1, le=5000)
    croprotation: _Table | None = None
    cropfiles: dict[str, CropFile] = _Field(default_factory=dict, exclude=True)

    def write_crop(self, path: str):
        for name, cropfile in self.cropfiles.items():
            cropfile.save_file(string=cropfile.crp, fname=name, path=path)

CropDevelopmentSettingsFixed

Bases: _CropDevelopmentSettings

Fixed crop development settings (Additionaly to CropDevelopmentSettings).

Attributes:

Name Type Description
idev Literal[1, 2]

Duration of crop growing period

  • 1 - Duration is fixed
  • 2 - Duration is variable
lcc Optional[int]

Duration of the crop growing period

swgc Literal[1, 2]

Choose between Leaf Area Index or Soil Cover Fraction

  • 1 - LAI
  • 2 - SCF
gctb _Arrays

Soil Cover Fraction as a function of development stage

Source code in pyswap/components/crop.py
class CropDevelopmentSettingsFixed(_CropDevelopmentSettings):
    """Fixed crop development settings (Additionaly to CropDevelopmentSettings).

    Attributes:
        idev (Literal[1, 2]): Duration of crop growing period

            * 1 - Duration is fixed
            * 2 - Duration is variable

        lcc (Optional[int]): Duration of the crop growing period
        swgc (Literal[1, 2]): Choose between Leaf Area Index or Soil Cover Fraction

            * 1 - LAI
            * 2 - SCF

        gctb  _Arrays): Soil Cover Fraction as a function of development stage
    """

    idev: _Literal[1, 2] | None = None
    lcc: int | None = _Field(default=None, **_YEARRANGE)
    swgc: _Literal[1, 2] | None = None
    gctb: _Arrays | None = None
    kytb: _Arrays | None = None

CropDevelopmentSettingsGrass

Bases: CropDevelopmentSettingsWOFOST

Crop development settings specific to grass growth.

Attributes:

Name Type Description
swtsum Literal[0, 1, 2]

Select either sum air temperatures or soil temperature at particular depth

  • 0 - no delay of start grass growth
  • 1 - start of grass growth based on sum air temperatures > 200 degree C
  • 2 - start of grass growth based on soil temperature at particular depth
tsumtemp Optional[float]

Specific stem area [0..1 ha/kg, R]

tsumdepth Optional[float]

Life span under leaves under optimum conditions [0..366 d, R]

tsumtime Optional[float]

Lower threshold temperature for ageing of leaves [-10..30 degree C, R]

Source code in pyswap/components/crop.py
class CropDevelopmentSettingsGrass(CropDevelopmentSettingsWOFOST):
    """Crop development settings specific to grass growth.

    Attributes:
        swtsum (Literal[0, 1, 2]): Select either sum air temperatures or soil temperature at particular depth

            * 0 - no delay of start grass growth
            * 1 - start of grass growth based on sum air temperatures > 200 degree C
            * 2 - start of grass growth based on soil temperature at particular depth

        tsumtemp (Optional[float]): Specific stem area [0..1 ha/kg, R]
        tsumdepth (Optional[float]): Life span under leaves under optimum conditions [0..366 d, R]
        tsumtime (Optional[float]): Lower threshold temperature for ageing of leaves [-10..30 degree C, R]
    """

    swtsum: _Literal[0, 1, 2] | None = None
    tsumtemp: float | None = None
    tsumdepth: float | None = None
    tsumtime: float | None = None

CropDevelopmentSettingsWOFOST

Bases: _CropDevelopmentSettings

Additional settings as defined for the WOFOST model.

idsl (Literal[0, 1, 2]): Switch for crop development. dtsmtb _Arrays): List increase in temperature sum as function of daily average temperature. dlo (Optional[float]): Optimum day length for crop development. dlc (Optional[float]): Minimum day length. vernsat (Optional[float]): Saturated vernalisation requirement. vernbase (Optional[float]): Base vernalisation requirement. verndvs (Optional[float]): Critical development stage after which the effect of vernalisation is halted. verntb (Optional _Arrays]): _Table with rate of vernalisation as function of average air temperature. tdwi (float): Initial total crop dry weight. laiem (float): Leaf area index at emergence. rgrlai (float): Maximum relative increase in LAI. spa (float): Specific pod area. ssa (float): Specific stem area. span (float): Life span under leaves under optimum conditions. slatb _Arrays): List specific leaf area as function of crop development stage. eff (float): Light use efficiency for real leaf. amaxtb _Arrays): List maximum CO2 assimilation rate as function of development stage. tmpftb _Arrays): List reduction factor of AMAX as function of average day temperature. tmnftb _Arrays): List reduction factor of AMAX as function of minimum day temperature. cvo (float): Efficiency of conversion into storage organs. cvl (float): Efficiency of conversion into leaves. cvr (float): Efficiency of conversion into roots. cvs (float): Efficiency of conversion into stems. q10 (float): Increase in respiration rate with temperature. rml (float): Maintenance respiration rate of leaves. rmo (float): Maintenance respiration rate of storage organs. rmr (float): Maintenance respiration rate of roots. rms (float): Maintenance respiration rate of stems. rfsetb _Arrays): List reduction factor of senescence as function of development stage. frtb _Arrays): List fraction of total dry matter increase partitioned to the roots as function of development stage. fltb _Arrays): List fraction of total above ground dry matter increase partitioned to the leaves as function of development stage. fstb _Arrays): List fraction of total above ground dry matter increase partitioned to the stems as function of development stage. fotb _Arrays): List fraction of total above ground dry matter increase partitioned to the storage organs as function of development stage. perdl (float): Maximum relative death rate of leaves due to water stress. rdrrtb _Arrays): List relative death rates of roots as function of development stage. rdrstb _Arrays): List relative death rates of stems as function of development stage.

Source code in pyswap/components/crop.py
class CropDevelopmentSettingsWOFOST(_CropDevelopmentSettings):
    """Additional settings as defined for the WOFOST model.

    idsl (Literal[0, 1, 2]): Switch for crop development.
    dtsmtb  _Arrays): List increase in temperature sum as function of daily average temperature.
    dlo (Optional[float]): Optimum day length for crop development.
    dlc (Optional[float]): Minimum day length.
    vernsat (Optional[float]): Saturated vernalisation requirement.
    vernbase (Optional[float]): Base vernalisation requirement.
    verndvs (Optional[float]): Critical development stage after which the effect of vernalisation is halted.
    verntb (Optional _Arrays]): _Table with rate of vernalisation as function of average air temperature.
    tdwi (float): Initial total crop dry weight.
    laiem (float): Leaf area index at emergence.
    rgrlai (float): Maximum relative increase in LAI.
    spa (float): Specific pod area.
    ssa (float): Specific stem area.
    span (float): Life span under leaves under optimum conditions.
    slatb  _Arrays): List specific leaf area as function of crop development stage.
    eff (float): Light use efficiency for real leaf.
    amaxtb  _Arrays): List maximum CO2 assimilation rate as function of development stage.
    tmpftb  _Arrays): List reduction factor of AMAX as function of average day temperature.
    tmnftb  _Arrays): List reduction factor of AMAX as function of minimum day temperature.
    cvo (float): Efficiency of conversion into storage organs.
    cvl (float): Efficiency of conversion into leaves.
    cvr (float): Efficiency of conversion into roots.
    cvs (float): Efficiency of conversion into stems.
    q10 (float): Increase in respiration rate with temperature.
    rml (float): Maintenance respiration rate of leaves.
    rmo (float): Maintenance respiration rate of storage organs.
    rmr (float): Maintenance respiration rate of roots.
    rms (float): Maintenance respiration rate of stems.
    rfsetb  _Arrays): List reduction factor of senescence as function of development stage.
    frtb  _Arrays): List fraction of total dry matter increase partitioned to the roots as function of development stage.
    fltb  _Arrays): List fraction of total above ground dry matter increase partitioned to the leaves as function of development stage.
    fstb  _Arrays): List fraction of total above ground dry matter increase partitioned to the stems as function of development stage.
    fotb  _Arrays): List fraction of total above ground dry matter increase partitioned to the storage organs as function of development stage.
    perdl (float): Maximum relative death rate of leaves due to water stress.
    rdrrtb  _Arrays): List relative death rates of roots as function of development stage.
    rdrstb  _Arrays): List relative death rates of stems as function of development stage.
    """

    idsl: _Literal[0, 1, 2] | None = None
    dtsmtb: _Arrays | None = None
    dlo: float | None = _Field(default=None, ge=0.0, le=24.0)
    dlc: float | None = _Field(default=None, ge=0.0, le=24.0)
    vernsat: float | None = _Field(default=None, ge=0.0, le=100.0)
    vernbase: float | None = _Field(default=None, ge=0.0, le=100.0)
    verndvs: float | None = _Field(default=None, ge=0.0, le=0.3)
    verntb: _Arrays | None = None
    tdwi: float | None = _Field(default=None, ge=0.0, le=10_000)
    laiem: float | None = _Field(default=None, ge=0.0, le=10)
    rgrlai: float | None = _Field(default=None, **_UNITRANGE)
    spa: float | None = _Field(**_UNITRANGE, default=None)
    ssa: float | None = _Field(default=None, **_UNITRANGE)
    span: float | None = _Field(default=None, **_YEARRANGE)
    slatb: _Arrays | None = None
    eff: float | None = _Field(default=None, ge=0.0, le=10.0)
    amaxtb: _Arrays | None = None
    tmpftb: _Arrays | None = None
    tmnftb: _Arrays | None = None
    cvo: float | None = _Field(default=None, **_UNITRANGE)
    cvl: float | None = _Field(default=None, **_UNITRANGE)
    cvr: float | None = _Field(default=None, **_UNITRANGE)
    cvs: float | None = _Field(default=None, **_UNITRANGE)
    q10: float | None = _Field(default=None, ge=0.0, le=5.0)
    rml: float | None = _Field(default=None, **_UNITRANGE)
    rmo: float | None | None = _Field(**_UNITRANGE, default=None)
    rmr: float | None = _Field(default=None, **_UNITRANGE)
    rms: float | None = _Field(default=None, **_UNITRANGE)
    rfsetb: _Arrays | None = None
    frtb: _Arrays | None = None
    fltb: _Arrays | None = None
    fstb: _Arrays | None = None
    fotb: _Arrays | None = None
    perdl: float | None = _Field(default=None, ge=0.0, le=3.0)
    rdrrtb: _Arrays | None = None
    rdrstb: _Arrays | None = None

CropFile

Bases: PySWAPBaseModel, FileMixin, SerializableMixin

Main class for the .crp file.

This class collects all the settings for the crop file. Currently the types of the attributes are set to Any because the validation is not yet implemented.

Attributes:

Name Type Description
name str

Name of the crop

path Optional[str]

Path to the .crp file

prep Optional[Preparation]

Preparation settings

cropdev_settings Optional[CropDevelopmentSettings]

Crop development settings

oxygenstress Optional[OxygenStress]

Oxygen stress settings

droughtstress Optional[DroughtStress]

Drought stress settings

saltstress Optional[SaltStress]

Salt stress settings

compensaterwu Optional[CompensateRWUStress]

Compensate root water uptake stress settings

interception Optional[Interception]

Interception settings

scheduledirrigation Optional[ScheduledIrrigation]

Scheduled irrigation settings

grassland_management Optional[GrasslandManagement]

Grassland management settings

Source code in pyswap/components/crop.py
class CropFile(_PySWAPBaseModel, _FileMixin, _SerializableMixin):
    """Main class for the .crp file.

    This class collects all the settings for the crop file. Currently the types of the
    attributes are set to Any because the validation is not yet implemented.

    Attributes:
        name (str): Name of the crop
        path (Optional[str]): Path to the .crp file
        prep (Optional[Preparation]): Preparation settings
        cropdev_settings (Optional[CropDevelopmentSettings]): Crop development settings
        oxygenstress (Optional[OxygenStress]): Oxygen stress settings
        droughtstress (Optional[DroughtStress]): Drought stress settings
        saltstress (Optional[SaltStress]): Salt stress settings
        compensaterwu (Optional[CompensateRWUStress]): Compensate root water uptake stress settings
        interception (Optional[Interception]): Interception settings
        scheduledirrigation (Optional[ScheduledIrrigation]): Scheduled irrigation settings
        grassland_management (Optional[GrasslandManagement]): Grassland management settings
    """

    _extension: bool = _PrivateAttr(default="crp")

    name: str = _Field(exclude=True)
    path: str | None = None
    prep: _Subsection[Preparation] | None = None
    cropdev_settings: (
        _Subsection[
            CropDevelopmentSettingsFixed
            | CropDevelopmentSettingsWOFOST
            | CropDevelopmentSettingsGrass
        ]
        | None
    ) = None
    oxygenstress: _Subsection[OxygenStress] | None = None
    droughtstress: _Subsection[DroughtStress] | None = None
    saltstress: _Subsection[SaltStress] | None = SaltStress(swsalinity=0)
    compensaterwu: _Subsection[CompensateRWUStress] | None = CompensateRWUStress(
        swcompensate=0
    )
    interception: _Subsection[Interception] | None = None
    scheduledirrigation: _Subsection[_ScheduledIrrigation] | None = (
        _ScheduledIrrigation(schedule=0)
    )
    grasslandmanagement: _Subsection[GrasslandManagement] | None = None
    co2correction: _Subsection[CO2Correction] | None = None

    @property
    def crp(self) -> str:
        """Return the model string of the .crp file."""
        return self.model_string()

crp: str property

Return the model string of the .crp file.

DMGRZTB

Bases: BaseTableModel

threshold of above ground dry matter [0..1d6 kg DM/ha, R] to trigger grazing as function of daynumber [1..366 d, R]

Attributes:

Name Type Description
DNR Series[float]

Day number.

DMGRZ Series[float]

Dry matter growth rate of roots.

Source code in pyswap/components/tables.py
class DMGRZTB(BaseTableModel):
    """threshold of above ground dry matter [0..1d6 kg DM/ha, R] to trigger grazing as function of daynumber [1..366 d, R]

    Attributes:
        DNR (Series[float]): Day number.
        DMGRZ (Series[float]): Dry matter growth rate of roots.
    """

    DNR: Series[float] = pa.Field(**YEARRANGE)
    DMGRZ: Series[float] = pa.Field(ge=0.0, le=1.0e6)

DMMOWDELAY

Bases: BaseTableModel

Relation between dry matter harvest [0..1d6 kg/ha, R] and days of delay in regrowth [0..366 d, I] after mowing

Attributes:

Name Type Description
DMMOWDELAY Series[float]

Dry matter harvest [0..1d6 kg/ha, R]

DAYDELAY Series[int]

days of delay in regrowth [0..366 d, I]

Source code in pyswap/components/tables.py
class DMMOWDELAY(BaseTableModel):
    """Relation between dry matter harvest [0..1d6 kg/ha, R] and days of delay in regrowth [0..366 d, I] after mowing

    Attributes:
        DMMOWDELAY (Series[float]): Dry matter harvest [0..1d6 kg/ha, R]
        DAYDELAY (Series[int]): days of delay in regrowth [0..366 d, I]
    """

    DMMOWDELAY: Series[float] = pa.Field(ge=0.0, le=1.0e6)
    DAYDELAY: Series[int] = pa.Field(**YEARRANGE)

DMMOWTB

Bases: BaseTableModel

List threshold of above ground dry matter [0..1d6 kg DM/ha, R] to trigger mowing as function of daynumber [1..366 d, R]

Note

maximum 20 records

Attributes:

Name Type Description
DNR Series[float]

Day number.

DMMOW Series[float]

threshold of above ground dry matter [0..1d6 kg DM/ha, R]

Source code in pyswap/components/tables.py
class DMMOWTB(BaseTableModel):
    """List threshold of above ground dry matter [0..1d6 kg DM/ha, R] to trigger mowing as function of daynumber [1..366 d, R]

    !!! note

        maximum 20 records


    Attributes:
        DNR (Series[float]): Day number.
        DMMOW (Series[float]): threshold of above ground dry matter [0..1d6 kg DM/ha, R]
    """

    DNR: Series[float] = pa.Field(**YEARRANGE)
    DMMOW: Series[float] = pa.Field(ge=0.0, le=1.0e6)

DTSMTB

Bases: BaseTableModel

increase in temperature sum [0..60 oC, R] as function of daily average temperature [0..100 oC, R]

Attributes:

Name Type Description
TAV Series[float]

Daily average temperature.

DTSM Series[float]

Increase in temperature sum.

Source code in pyswap/components/tables.py
class DTSMTB(BaseTableModel):
    """increase in temperature sum [0..60 oC, R] as function of daily average temperature [0..100 oC, R]

    Attributes:
        TAV (Series[float]): Daily average temperature.
        DTSM (Series[float]): Increase in temperature sum.
    """

    TAV: Series[float] = pa.Field(ge=0.0, le=100.0)
    DTSM: Series[float] = pa.Field(ge=0.0, le=60.0)

DroughtStress

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Drought stress settings for .crp file.

Attributes:

Name Type Description
swdrought Literal[1, 2]

Switch for drought stress

  • 1 - Drought stress according to Feddes et al. (1978)
  • 2 - rought stress according to De Jong van Lier et al. (2008)
swjarvis Optional[Literal[0, 1, 2, 3, 4]]

DEPRECATED Switch for Jarvis model for water uptake reduction

alphcrit float | None

Optional[float] = DEPRECATED Critical stress index (Jarvis, 1989) for compensation of root water uptake [0.2..1 -, R]

hlim3h Optional[float]

Pressure head below which water uptake reduction starts at high Tpot

hlim3l Optional[float]

Pressure head below which water uptake reduction starts at low Tpot

hlim4 Optional[float]

No water extraction at lower soil water pressure heads

adcrh Optional[float]

Level of high atmospheric demand, corresponding to HLIM3H

adcrl Optional[float]

Level of low atmospheric demand, corresponding to HLIM3L

wiltpoint Optional[float]

Minimum pressure head in leaves

kstem Optional[float]

Hydraulic conductance between leaf and root xylem

rxylem Optional[float]

Xylem radius

rootradius Optional[float]

Root radius

kroot Optional[float]

Radial hydraulic conductivity of root tissue

rootcoefa Optional[float]

Defines relative distance between roots at which mean soil water content occurs

swhydrlift Optional[Literal[0, 1]]

Switch for possibility hydraulic lift in root system

rooteff Optional[float]

Root system efficiency factor

stephr Optional[float]

Step between values of hroot and hxylem in iteration cycle

criterhr Optional[float]

Maximum difference of Hroot between iterations; convergence criterium

taccur Optional[float]

Maximum absolute difference between simulated and calculated potential transpiration rate

Source code in pyswap/components/crop.py
class DroughtStress(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Drought stress settings for .crp file.

    Attributes:
        swdrought (Literal[1, 2]): Switch for drought stress

            * 1 - Drought stress according to Feddes et al. (1978)
            * 2 - rought stress according to De Jong van Lier et al. (2008)

        swjarvis (Optional[Literal[0, 1, 2, 3, 4]]): _DEPRECATED_ Switch for Jarvis model for water uptake reduction
        alphcrit: Optional[float] = _DEPRECATED_ Critical stress index (Jarvis, 1989) for compensation of root water uptake [0.2..1 -, R]
        hlim3h (Optional[float]): Pressure head below which water uptake reduction starts at high Tpot
        hlim3l (Optional[float]): Pressure head below which water uptake reduction starts at low Tpot
        hlim4 (Optional[float]): No water extraction at lower soil water pressure heads
        adcrh (Optional[float]): Level of high atmospheric demand, corresponding to HLIM3H
        adcrl (Optional[float]): Level of low atmospheric demand, corresponding to HLIM3L
        wiltpoint (Optional[float]): Minimum pressure head in leaves
        kstem (Optional[float]): Hydraulic conductance between leaf and root xylem
        rxylem (Optional[float]): Xylem radius
        rootradius (Optional[float]): Root radius
        kroot (Optional[float]): Radial hydraulic conductivity of root tissue
        rootcoefa (Optional[float]): Defines relative distance between roots at which mean soil water content occurs
        swhydrlift (Optional[Literal[0, 1]]): Switch for possibility hydraulic lift in root system
        rooteff (Optional[float]): Root system efficiency factor
        stephr (Optional[float]): Step between values of hroot and hxylem in iteration cycle
        criterhr (Optional[float]): Maximum difference of Hroot between iterations; convergence criterium
        taccur (Optional[float]): Maximum absolute difference between simulated and calculated potential transpiration rate
    """

    swdrought: _Literal[1, 2] | None = None
    swjarvis: _Literal[0, 1, 2, 3, 4] | None = None
    alphcrit: float | None = _Field(default=None, ge=0.2, le=1.0)
    hlim3h: float | None = _Field(default=None, ge=-1.0e4, le=100.0)
    hlim3l: float | None = _Field(default=None, ge=-1.0e4, le=100.0)
    hlim4: float | None = _Field(default=None, ge=-1.6e4, le=100.0)
    adcrh: float | None = _Field(default=None, ge=0.0, le=5.0)
    adcrl: float | None = _Field(default=None, ge=0.0, le=5.0)
    wiltpoint: float | None = _Field(default=None, ge=-1.0e8, le=-1.0e2)
    kstem: float | None = _Field(default=None, ge=1.0e-10, le=10.0)
    rxylem: float | None = _Field(default=None, ge=1.0e-4, le=1.0)
    rootradius: float | None = _Field(default=None, ge=1.0e-4, le=1.0)
    kroot: float | None = _Field(default=None, ge=1.0e-10, le=1.0e10)
    rootcoefa: float | None = _Field(default=None, **_UNITRANGE)
    swhydrlift: _Literal[0, 1] | None = None
    rooteff: float | None = _Field(default=None, **_UNITRANGE)
    stephr: float | None = _Field(default=None, ge=0.0, le=10.0)
    criterhr: float | None = _Field(default=None, ge=0.0, le=10.0)
    taccur: float | None = _Field(default=None, ge=1.0e-5, le=1.0e-2)

FLTB

Bases: BaseTableModel

fraction of total above ground dry matter increase partitioned to the leaves [kg/kg, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

FL Series[float]

Fraction of total above ground dry matter increase partitioned to the leaves.

Source code in pyswap/components/tables.py
class FLTB(BaseTableModel):
    """fraction of total above ground dry matter increase partitioned to the leaves [kg/kg, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        FL (Series[float]): Fraction of total above ground dry matter increase partitioned to the leaves.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    FL: Series[float] = pa.Field(ge=0.0, le=1.0)

FOTB

Bases: BaseTableModel

fraction of total above ground dry matter increase partitioned to the storage organs [kg/kg, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

FO Series[float]

Fraction of total above ground dry matter increase partitioned to the storage organs.

Source code in pyswap/components/tables.py
class FOTB(BaseTableModel):
    """fraction of total above ground dry matter increase partitioned to the storage organs [kg/kg, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        FO (Series[float]): Fraction of total above ground dry matter increase partitioned to the storage organs.
    """

    DVS: Series[float] = pa.Field(**DVSRANGE)
    FO: Series[float] = pa.Field(ge=0.0, le=1.0)

FRTB

Bases: BaseTableModel

fraction of total dry matter increase partitioned to the roots [kg/kg, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

FR Series[float]

Fraction of total dry matter increase partitioned to the roots.

Source code in pyswap/components/tables.py
class FRTB(BaseTableModel):
    """fraction of total dry matter increase partitioned to the roots [kg/kg, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        FR (Series[float]): Fraction of total dry matter increase partitioned to the roots.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    FR: Series[float] = pa.Field(ge=0.0, le=1.0)

FSTB

Bases: BaseTableModel

fraction of total above ground dry matter increase partitioned to the stems [kg/kg, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

FS Series[float]

Fraction of total above ground dry matter increase partitioned to the stems.

Source code in pyswap/components/tables.py
class FSTB(BaseTableModel):
    """fraction of total above ground dry matter increase partitioned to the stems [kg/kg, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        FS (Series[float]): Fraction of total above ground dry matter increase partitioned to the stems.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    FS: Series[float] = pa.Field(ge=0.0, le=1.0)

GCTB

Bases: BaseTableModel

Leaf Area Index [0..12 (m2 leaf)/(m2 soil), R], as function of dev. stage [0..2 -, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

LAI Series[float]

Leaf Area Index of the crop.

Source code in pyswap/components/tables.py
class GCTB(BaseTableModel):
    """Leaf Area Index [0..12 (m2 leaf)/(m2 soil), R], as function of dev. stage [0..2 -, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        LAI (Series[float]): Leaf Area Index of the crop.
    """

    DVS: Series[float] = pa.Field(**DVSRANGE)
    LAI: Series[float] = pa.Field(ge=0.0, le=12.0)

GrasslandManagement

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Settings specific to the dynamic grass growth module.

Attributes:

Name Type Description
seqgrazmow IntList

sequence of periods with different practices within calender year. Available options:

  • 1 - Grazing
  • 2 - Mowing
  • 3 - Grazing with dewooling
swharvest Literal[1, 2]

Switch for timing harvest, either for mowing or grazing

  • 1 - Use dry matter threshold
  • 2 - Use fixed dates
dateharvest Optional[_DateList]

harvest dates (maximum 999)

swdmgrz Optional[Literal[1, 2]]

Switch for dry matter threshold to trigger harvest by grazing

  • 1 - Use fixed threshold
  • 2 - Use flexible threshold
dmgrazing Optional[ _Arrays)]

Minimum dry matter amount for cattle to enter the field [0..1d6 kg DM/ha, R]

dmgrztb Optional[int]

List threshold of above ground dry matter [0..1d6 kg DM/ha, R] to trigger grazing as function of daynumber [1..366 d, R]

maxdaygrz Optional[int]

Maximum growing period after harvest [1..366 -, I]

swlossgrz Optional[Literal[0, 1]]

Switch for losses due to insufficient pressure head during grazing

  • 0 - No loss
  • 1 - Losses due to treading
tagprest Optional[float]

Minimum amount of above ground DM after grazing [0..1d6 kg DM/ha, R]

dewrest Optional[float]

Remaining yield above ground after dewooling event [0..1d6 kg DM/ha, R]

_table_lsda Optional[Table]

Actual livestock density of each grazing period

_table_lsdb Optional[Table]

Relation between livestock density, number of grazing days and dry matter uptake

swdmmow Optional[int]

Switch for dry matter threshold to trigger harvest by mowing

  • 1 - Use fixed threshold
  • 2 - Use flexible threshold
dmharvest Optional[float]

Threshold of above ground dry matter to trigger mowing [0..1d6 kg DM/ha, R]

daylastharvest Optional[int]

Last calendar day on which mowing may occur [1..366 -, I]

dmlastharvest Optional[float]

Minimum above ground dry matter for mowing on last date [0..1d6 kg DM/ha, R]

dmmowtb Optional[int]

Dry matter mowing threshold

maxdaymow Optional[int]

Maximum growing period after harvest [1..366 -, I]

swlossmow Optional[int]

Switch for losses due to insufficient pressure head during mowing

  • 0 - No loss
  • 1 - Losses due to treading
mowrest Optional[float]

Remaining yield above ground after mowing event [0..1d6 kg DM/ha, R]

_table_dmmowdelay Optional[Optional[Table]]

Relation between dry matter harvest [0..1d6 kg/ha, R] and days of delay in regrowth [0..366 d, I] after mowing

swpotrelmf int

Switch for calculation of potential yield

  • 1 - theoretical potential yield
  • 2 - attainable yield
relmf float

Relative management factor to reduce theoretical potential yield to attainable yield [0..1 -, R]

Source code in pyswap/components/crop.py
class GrasslandManagement(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Settings specific to the dynamic grass growth module.

    Attributes:
        seqgrazmow (_IntList): sequence of periods with different practices within calender year. Available options:

            * 1 - Grazing
            * 2 - Mowing
            * 3 - Grazing with dewooling

        swharvest (Literal[1, 2]): Switch for timing harvest, either for mowing or grazing

            * 1 - Use dry matter threshold
            * 2 - Use fixed dates

        dateharvest Optional[(_DateList)]: harvest dates (maximum 999)
        swdmgrz Optional[(Literal[1, 2])]: Switch for dry matter threshold to trigger harvest by grazing

            * 1 - Use fixed threshold
            * 2 - Use flexible threshold

        dmgrazing Optional[ _Arrays)]: Minimum dry matter amount for cattle to enter the field [0..1d6 kg DM/ha, R]
        dmgrztb Optional[(int)]: List threshold of above ground dry matter [0..1d6 kg DM/ha, R] to trigger grazing as function of daynumber [1..366 d, R]
        maxdaygrz Optional[(int)]: Maximum growing period after harvest [1..366 -, I]
        swlossgrz Optional[(Literal[0, 1])]: Switch for losses due to insufficient pressure head during grazing

            * 0 - No loss
            * 1 - Losses due to treading

        tagprest Optional[(float)]: Minimum amount of above ground DM after grazing [0..1d6 kg DM/ha, R]
        dewrest Optional[(float)]: Remaining yield above ground after dewooling event [0..1d6 kg DM/ha, R]
        _table_lsda (Optional[_Table]): Actual livestock density of each grazing period
        _table_lsdb (Optional[_Table]): Relation between livestock density, number of grazing days and dry matter uptake
        swdmmow Optional[(int)]: Switch for dry matter threshold to trigger harvest by mowing

            * 1 - Use fixed threshold
            * 2 - Use flexible threshold

        dmharvest Optional[(float)]: Threshold of above ground dry matter to trigger mowing [0..1d6 kg DM/ha, R]
        daylastharvest Optional[(int)]: Last calendar day on which mowing may occur [1..366 -, I]
        dmlastharvest Optional[(float)]: Minimum above ground dry matter for mowing on last date [0..1d6 kg DM/ha, R]
        dmmowtb Optional[(int)]: Dry matter mowing threshold
        maxdaymow Optional[(int)]:Maximum growing period after harvest [1..366 -, I]
        swlossmow Optional[(int)]: Switch for losses due to insufficient pressure head during mowing

            * 0 - No loss
            * 1 - Losses due to treading

        mowrest Optional[(float)]: Remaining yield above ground after mowing event [0..1d6 kg DM/ha, R]
        _table_dmmowdelay Optional[(Optional[_Table])]: Relation between dry matter harvest [0..1d6 kg/ha, R] and days of delay in regrowth [0..366 d, I] after mowing
        swpotrelmf (int): Switch for calculation of potential yield

            * 1 - theoretical potential yield
            * 2 - attainable yield

        relmf (float): Relative management factor to reduce theoretical potential yield to attainable yield [0..1 -, R]
    """

    seqgrazmow: _IntList | None = None
    swharvest: _Literal[1, 2] | None = None
    dateharvest: _Arrays | None = None
    swdmgrz: _Literal[1, 2] | None = None
    dmgrazing: _Decimal2f | None = None
    dmgrztb: _Arrays | None = None
    maxdaygrz: int | None = None
    swlossgrz: _Literal[0, 1] | None = None
    tagprest: _Decimal2f | None = None
    dewrest: _Decimal2f | None = None
    lsda: _Table | None = None
    lsdb: _Table | None = None
    swdmmow: int | None = None
    dmharvest: _Decimal2f | None = None
    daylastharvest: int | None = None
    dmlastharvest: _Decimal2f | None = None
    dmmowtb: _Arrays | None = None
    maxdaymow: int | None = None
    swlossmow: int | None = None
    mowrest: _Decimal2f | None = None
    dmmowdelay: _Table | None = None
    swpotrelmf: int | None = None
    relmf: _Decimal2f | None = None

Interception

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Interception settings for .crp file.

Attributes:

Name Type Description
swinter Literal[0, 1, 2]

Switch for rainfall interception method

  • 0 - No interception
  • 1 - Agricultural crops (Von Hoyningen-Hune and Braden)
  • 2 - Trees and forests (Gash)
cofab Optional[float]

Interception coefficient, corresponding to maximum interception amount

_table_intertb Optional[Table]

_table with the following columns as a function of time T:

  • PFREE - Free throughfall coefficient
  • PSTEM - Stemflow coefficient
  • SCANOPY - Canopy storage coefficient
  • AVPREC = Average rainfall intensity
  • AVEVAP = Average evaporation intensity during rainfall from a wet canopy
Source code in pyswap/components/crop.py
class Interception(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Interception settings for .crp file.

    Attributes:
        swinter (Literal[0, 1, 2]): Switch for rainfall interception method

            * 0 - No interception
            * 1 - Agricultural crops (Von Hoyningen-Hune and Braden)
            * 2 - Trees and forests (Gash)

        cofab (Optional[float]): Interception coefficient, corresponding to maximum interception amount
        _table_intertb (Optional[_Table]): _table with the following columns as a function of time T:

            * PFREE - Free throughfall coefficient
            * PSTEM - Stemflow coefficient
            * SCANOPY - Canopy storage coefficient
            * AVPREC = Average rainfall intensity
            * AVEVAP = Average evaporation intensity during rainfall from a wet canopy
    """

    swinter: _Literal[0, 1, 2] | None = None
    cofab: float | None = _Field(default=None, **_UNITRANGE)
    intertb: _Table | None = None

KYTB

Bases: BaseTableModel

Yield response factor [0..5 -, R], as function of dev. stage [0..2 -, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

KY Series[float]

Yield response factor of the crop.

Source code in pyswap/components/tables.py
class KYTB(BaseTableModel):
    """Yield response factor [0..5 -, R], as function of dev. stage [0..2 -, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        KY (Series[float]): Yield response factor of the crop.
    """

    DVS: Series[float] = pa.Field(**DVSRANGE)
    KY: Series[float] = pa.Field(ge=0.0, le=5.0)

LSDATB

Bases: BaseTableModel

Actual livestock density of each grazing period

Note

total number of periods should be equal to number of periods in SEQGRAZMOW

Attributes:

Name Type Description
SEQNR Series[int]

number of the sequence period with mowing/grazing [0..366 d, I]

LSDA Series[float]

Actual Live Stock Density of the grazing period [0.0..1000.0 LS/ha, R]

Source code in pyswap/components/tables.py
class LSDATB(BaseTableModel):
    """Actual livestock density of each grazing period

    !!! note

        total number of periods should be equal to number of periods in SEQGRAZMOW

    Attributes:
        SEQNR (Series[int]): number of the sequence period with mowing/grazing [0..366 d, I]
        LSDA (Series[float]): Actual Live Stock Density of the grazing period [0.0..1000.0 LS/ha, R]
    """

    SEQNR: Series[int] = pa.Field(**YEARRANGE)
    LSDA: Series[float] = pa.Field(ge=0.0, le=1000.0)

LSDBTB

Bases: BaseTableModel

Relation between livestock density, number of grazing days and dry matter uptake

Attributes:

Name Type Description
LSDB Series[float]

Basic Live Stock Density [0.0..1000.0 LS/ha, R]

DAYSGRAZING Series[float]

Maximum days of grazing [0.0..366.0 d, R]

UPTGRAZING Series[float]

Dry matter uptake by grazing [0.0..1000.0 kg/ha, R] (kg/ha DM)

LOSSGRAZING Series[float]

Dry matter loss during grazing due to droppings and treading [0.0..1000.0 kg/ha, R] (kg/ha DM)

Source code in pyswap/components/tables.py
class LSDBTB(BaseTableModel):
    """Relation between livestock density, number of grazing days and dry matter uptake

    Attributes:
        LSDB (Series[float]): Basic Live Stock Density [0.0..1000.0 LS/ha, R]
        DAYSGRAZING (Series[float]): Maximum days of grazing [0.0..366.0 d, R]
        UPTGRAZING (Series[float]): Dry matter uptake by grazing [0.0..1000.0 kg/ha, R] (kg/ha DM)
        LOSSGRAZING (Series[float]): Dry matter loss during grazing due to droppings and treading [0.0..1000.0 kg/ha, R] (kg/ha DM)
    """

    LSDb: Series[float] = pa.Field(ge=0.0, le=1000.0)
    DAYSGRAZING: Series[float] = pa.Field(**YEARRANGE)
    UPTGRAZING: Series[float] = pa.Field(ge=0.0, le=1000.0)
    LOSSGRAZING: Series[float] = pa.Field(ge=0.0, le=1000.0)

MRFTB

Bases: BaseTableModel

Ratio root total respiration / maintenance respiration [1..5.0 -, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

MAX_RESP_FACTOR Series[float]

Ratio root total respiration / maintenance respiration.

Source code in pyswap/components/tables.py
class MRFTB(BaseTableModel):
    """Ratio root total respiration / maintenance respiration [1..5.0 -, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        MAX_RESP_FACTOR (Series[float]): Ratio root total respiration / maintenance respiration.
    """

    DVS: Series[float] = pa.Field(**DVSRANGE)
    MAX_RESP_FACTOR: Series[float] = pa.Field(ge=1.0, le=5.0)

OxygenStress

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Oxygen stress settings for .crp file.

Attributes:

Name Type Description
swoxygen Literal[0, 1, 2]

Switch for oxygen stress

  • 0 - No oxygen stress
  • 1 - Oxygen stress according to Feddes et al. (1978)
  • 2 - Oxygen stress according to Bartholomeus et al. (2008)
swoxygentype Optional[Literal[1, 2]]

switch for physical processes or repro. functions to calculate oxygen stress

  • 1 - physical processes
  • 2 - reproduction functions
swwrtnonox Literal[0, 1]

Switch for checking aerobic conditions in root zone to stop root(zone) development

aeratecrit Optional[float]

Threshold to stop root extension in case of oxygenstress; 0.0 maximum oxygen stress

hlim1 Optional[float]

No water extraction at higher pressure heads

hlim2u Optional[float]

H below which optimum water extr. starts for top layer

hlim2l Optional[float]

H below which optimum water extr. starts for sub layer

q10_microbial Optional[float]

Relative increase in microbial respiration at temperature increase of 10 C

specific_resp_humus Optional[float]

Respiration rate of humus at 25 C

srl Optional[float]

Specific root length

swrootradius Optional[Literal[1, 2]]

Switch for calculation of root radius

  • 1 - Calculate root radius
  • 2 - Root radius given in an input file
dry_mat_cont_roots Optional[float]

Dry matter content of roots

air_filled_root_por Optional[float]

Air filled root porosity

spec_weight_root_tissue Optional[float]

Specific weight of non-airfilled root tissue

var_a Optional[float]

Variance of root radius

root_radiuso2 Optional[float]

Root radius for oxygen stress module

q10_root Optional[float]

Relative increase in root respiration at temperature increase of 10 oC

f_senes Optional[float]

Reduction factor for senescence, used for maintenance respiration

c_mroot Optional[float]

Maintenance coefficient of root

_table_max_resp_factor Optional[Table]

Ratio root total respiration / maintenance respiration as a function of development stage

_table_dvs_w_root_ss Optional[Table]

List dry weight of roots at soil surface as a function of development stage

TODO: Find a way to validate the parameters that are required when the croptype=1 and swoxygen=2 (currently I cannot access the croptype parameter)

move it to the Model class validation at the end, when all the params are available

Source code in pyswap/components/crop.py
class OxygenStress(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Oxygen stress settings for .crp file.

    Attributes:
        swoxygen (Literal[0, 1, 2]): Switch for oxygen stress

            * 0 - No oxygen stress
            * 1 - Oxygen stress according to Feddes et al. (1978)
            * 2 - Oxygen stress according to Bartholomeus et al. (2008)

        swoxygentype (Optional[Literal[1, 2]]): switch for physical processes or repro. functions to calculate oxygen stress

            * 1 - physical processes
            * 2 - reproduction functions

        swwrtnonox (Literal[0, 1]): Switch for checking aerobic conditions in root zone to stop root(zone) development
        aeratecrit (Optional[float]): Threshold to stop root extension in case of oxygenstress; 0.0 maximum oxygen stress
        hlim1 (Optional[float]): No water extraction at higher pressure heads
        hlim2u (Optional[float]): H below which optimum water extr. starts for top layer
        hlim2l (Optional[float]): H below which optimum water extr. starts for sub layer
        q10_microbial (Optional[float]): Relative increase in microbial respiration at temperature increase of 10 C
        specific_resp_humus (Optional[float]): Respiration rate of humus at 25 C
        srl (Optional[float]): Specific root length
        swrootradius (Optional[Literal[1, 2]]): Switch for calculation of root radius

            * 1 - Calculate root radius
            * 2 - Root radius given in an input file

        dry_mat_cont_roots (Optional[float]): Dry matter content of roots
        air_filled_root_por (Optional[float]): Air filled root porosity
        spec_weight_root_tissue (Optional[float]): Specific weight of non-airfilled root tissue
        var_a (Optional[float]): Variance of root radius
        root_radiuso2 (Optional[float]): Root radius for oxygen stress module
        q10_root (Optional[float]): Relative increase in root respiration at temperature increase of 10 oC
        f_senes (Optional[float]): Reduction factor for senescence, used for maintenance respiration
        c_mroot (Optional[float]): Maintenance coefficient of root
        _table_max_resp_factor (Optional[_Table]): Ratio root total respiration / maintenance respiration as a function of development stage
        _table_dvs_w_root_ss (Optional[_Table]): List dry weight of roots at soil surface as a function of development stage

    TODO: Find a way to validate the parameters that are required when the
    croptype=1 and swoxygen=2 (currently I cannot access the croptype parameter)
    >> move it to the Model class validation at the end, when all the params are available
    """

    swoxygen: _Literal[0, 1, 2] | None = None
    swwrtnonox: _Literal[0, 1] | None = None
    swoxygentype: _Literal[1, 2] | None = None
    aeratecrit: float | None = _Field(default=None, ge=0.0001, le=1.0)
    hlim1: float | None = _Field(default=None, ge=-100.0, le=100.0)
    hlim2u: float | None = _Field(default=None, ge=-1000.0, le=100.0)
    hlim2l: float | None = _Field(default=None, ge=-1000.0, le=100.0)
    q10_microbial: float | None = _Field(default=None, ge=1.0, le=4.0)
    specific_resp_humus: float | None = _Field(default=None, **_UNITRANGE)
    srl: float | None = _Field(default=None, ge=0.0, le=1.0e10)
    swrootradius: _Literal[1, 2] | None = None
    dry_mat_cont_roots: float | None = _Field(default=None, **_UNITRANGE)
    air_filled_root_por: float | None = _Field(default=None, **_UNITRANGE)
    spec_weight_root_tissue: float | None = _Field(default=None, ge=0.0, le=1.0e5)
    var_a: float | None = _Field(default=None, **_UNITRANGE)
    root_radiuso2: float | None = _Field(default=None, ge=1.0e-6, le=0.1)
    q10_root: float | None = _Field(default=None, ge=1.0, le=4.0)
    f_senes: float | None = _Field(default=None, **_UNITRANGE)
    c_mroot: float | None = _Field(default=None, **_UNITRANGE)
    mrftb: _Arrays | None = None
    wrtb: _Arrays | None = None

Preparation

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Preparation, sowing and germination settings for .crp file.

Attributes:

Name Type Description
swprep Literal[0, 1]

Switch for preparation

swsow Literal[0, 1]

Switch for sowing

swgerm Literal[0, 1, 2]

Switch for germination

  • 0 - No germination
  • 1 - Germination with temperature sum
  • 2 - Germination with temperature sum and water potential
swharv Literal[0, 1]

Switch for harvest

  • 0 - Timing of harvest depends on end of growing period (CROPEND)
  • 1 - Timing of harvest depends on development stage (DVSEND)
dvsend Optional[float]

Development stage at harvest

zprep Optional[float]

Z-level for monitoring work-ability for the crop

hprep Optional[float]

Maximum pressure head during preparation

maxprepdelay Optional[int]

Maximum delay of preparation from start of growing season

zsow Optional[float]

Z-level for monitoring work-ability for the crop

hsow Optional[float]

Maximum pressure head during sowing

ztempsow Optional[float]

Z-level for monitoring temperature for sowing

tempsow Optional[float]

Soil temperature needed for sowing

maxsowdelay Optional[int]

Maximum delay of sowing from start of growing season

tsumemeopt Optional[float]

Temperature sum needed for crop emergence

tbasem Optional[float]

Minimum temperature, used for germination trajectory

teffmx Optional[float]

Maximum temperature, used for germination trajectory

hdrygerm Optional[float]

Pressure head rootzone for dry germination trajectory

hwetgerm Optional[float]

Pressure head rootzone for wet germination trajectory

zgerm Optional[float]

Z-level for monitoring average pressure head

agerm Optional[float]

A-coefficient Eq. 24/25 Feddes & Van Wijk

Source code in pyswap/components/crop.py
class Preparation(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Preparation, sowing and germination settings for .crp file.

    Attributes:
        swprep (Literal[0, 1]): Switch for preparation
        swsow (Literal[0, 1]): Switch for sowing
        swgerm (Literal[0, 1, 2]): Switch for germination

            * 0 - No germination
            * 1 - Germination with temperature sum
            * 2 - Germination with temperature sum and water potential

        swharv (Literal[0, 1]): Switch for harvest

            * 0 - Timing of harvest depends on end of growing period (CROPEND)
            * 1 - Timing of harvest depends on development stage (DVSEND)

        dvsend (Optional[float]): Development stage at harvest
        zprep (Optional[float]): Z-level for monitoring work-ability for the crop
        hprep (Optional[float]): Maximum pressure head during preparation
        maxprepdelay (Optional[int]): Maximum delay of preparation from start of growing season
        zsow (Optional[float]): Z-level for monitoring work-ability for the crop
        hsow (Optional[float]): Maximum pressure head during sowing
        ztempsow (Optional[float]): Z-level for monitoring temperature for sowing
        tempsow (Optional[float]): Soil temperature needed for sowing
        maxsowdelay (Optional[int]): Maximum delay of sowing from start of growing season
        tsumemeopt (Optional[float]): Temperature sum needed for crop emergence
        tbasem (Optional[float]): Minimum temperature, used for germination trajectory
        teffmx (Optional[float]): Maximum temperature, used for germination trajectory
        hdrygerm (Optional[float]): Pressure head rootzone for dry germination trajectory
        hwetgerm (Optional[float]): Pressure head rootzone for wet germination trajectory
        zgerm (Optional[float]): Z-level for monitoring average pressure head
        agerm (Optional[float]): A-coefficient Eq. 24/25 Feddes & Van Wijk
    """

    swprep: _Literal[0, 1] | None = _Field(default=None)
    swsow: _Literal[0, 1] | None = None
    swgerm: _Literal[0, 1, 2] | None = None
    swharv: _Literal[0, 1] | None = None
    dvsend: float | None = _Field(default=None, ge=0.0, le=3.0)
    zprep: float | None = _Field(default=None, ge=-100.0, le=0.0)
    hprep: float | None = _Field(default=None, ge=-200.0, le=0.0)
    maxprepdelay: int | None = _Field(default=None, ge=1, le=366)
    zsow: float | None = _Field(default=None, ge=-100.0, le=0.0)
    hsow: float | None = _Field(default=None, ge=-200.0, le=0.0)
    ztempsow: float | None = _Field(default=None, ge=-100.0, le=0.0)
    tempsow: float | None = _Field(default=None, ge=0.0, le=30.0)
    maxsowdelay: int | None = _Field(default=None, ge=1, le=366)
    tsumemeopt: float | None = _Field(default=None, ge=0.0, le=1000.0)
    tbasem: float | None = _Field(default=None, ge=0.0, le=1000.0)
    teffmx: float | None = _Field(default=None, ge=0.0, le=1000.0)
    hdrygerm: float | None = _Field(default=None, ge=-1000.0, le=1000.0)
    hwetgerm: float | None = _Field(default=None, ge=-100.0, le=1000.0)
    zgerm: float | None = _Field(default=None, ge=-100.0, le=1000.0)
    agerm: float | None = _Field(default=None, ge=0.0, le=1000.0)

RDCTB

Bases: BaseTableModel

List root density [0..100 cm/cm3, R] as function of relative rooting depth [0..1 -, R]

Attributes:

Name Type Description
RRD Series[float]

Relative rooting depth of the crop.

RDENS Series[float]

Root density of the crop.

Source code in pyswap/components/tables.py
class RDCTB(BaseTableModel):
    """List root density [0..100 cm/cm3, R] as function of relative rooting depth [0..1 -, R]

    Attributes:
        RRD (Series[float]): Relative rooting depth of the crop.
        RDENS (Series[float]): Root density of the crop.

    """

    RRD: Series[float] = pa.Field(ge=0.0, le=100.0)
    RDENS: Series[float] = pa.Field(**UNITRANGE)

RDRRTB

Bases: BaseTableModel

relative death rates of roots [kg/kg/d] as function of development stage [0..2 -, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

RDRR Series[float]

Relative death rates of roots.

Source code in pyswap/components/tables.py
class RDRRTB(BaseTableModel):
    """relative death rates of roots [kg/kg/d] as function of development stage [0..2 -, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        RDRR (Series[float]): Relative death rates of roots.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    RDRR: Series[float] = pa.Field(ge=0.0)

RDRSTB

Bases: BaseTableModel

relative death rates of stems [kg/kg/d] as function of development stage [0..2 -, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

RDRS Series[float]

Relative death rates of stems.

Source code in pyswap/components/tables.py
class RDRSTB(BaseTableModel):
    """relative death rates of stems [kg/kg/d] as function of development stage [0..2 -, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        RDRS (Series[float]): Relative death rates of stems.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    RDRS: Series[float] = pa.Field(ge=0.0)

RDTB

Bases: BaseTableModel

Rooting Depth [0..1000 cm, R], as a function of development stage [0..2 -, R].

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

RD Series[float]

Rooting depth of the crop.

Source code in pyswap/components/tables.py
class RDTB(BaseTableModel):
    """Rooting Depth [0..1000 cm, R], as a function of development stage [0..2 -, R].

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        RD (Series[float]): Rooting depth of the crop.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    RD: Series[float] = pa.Field(ge=0.0, le=100.0)

RFSETB

Bases: BaseTableModel

reduction factor of senescence [-, R] as function of development stage [0..2 -, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

RFSE Series[float]

Reduction factor of senescence.

Source code in pyswap/components/tables.py
class RFSETB(BaseTableModel):
    """reduction factor of senescence [-, R] as function of development stage [0..2 -, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        RFSE (Series[float]): Reduction factor of senescence.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    RFSE: Series[float] = pa.Field(ge=0.0, le=1.0)

RLWTB

Bases: BaseTableModel

rooting depth RL [0..5000 cm, R] as function of root weight RW [0..5000 kg DM/ha, R]

Attributes:

Name Type Description
RW Series[float]

rooting depth

RL Series[float]

root weight

Source code in pyswap/components/tables.py
class RLWTB(BaseTableModel):
    """rooting depth RL [0..5000 cm, R] as function of root weight RW [0..5000 kg DM/ha, R]

    Attributes:
        RW (Series[float]): rooting depth
        RL (Series[float]): root weight
    """

    RW: Series[float] = pa.Field(ge=0.0, le=5000.0)
    RL: Series[float] = pa.Field(ge=0.0, le=5000.0)

SLATB

Bases: BaseTableModel

leaf area [0..1 ha/kg, R] as function of crop development stage [0..2 -, R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

SLA Series[float]

Leaf area.

Source code in pyswap/components/tables.py
class SLATB(BaseTableModel):
    """leaf area [0..1 ha/kg, R] as function of crop development stage [0..2 -, R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        SLA (Series[float]): Leaf area.
    """

    DVS: Series[float] | None = pa.Field(**DVSRANGE)
    DNR: Series[float] | None = pa.Field(**YEARRANGE)
    SLA: Series[float] = pa.Field(ge=0.0, le=1.0)

SaltStress

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Salt stress settings for .crp file.

Attributes:

Name Type Description
swsalinity Literal[0, 1, 2]

Switch for salt stress

  • 0 - No salt stress
  • 1 - Maas and Hoffman reduction function
  • 2 - Use osmotic head
saltmax Optional[float]

Threshold salt concentration in soil water

saltslope Optional[float]

Decline of root water uptake above threshold

salthead Optional[float]

Conversion factor salt concentration (mg/cm3) into osmotic head (cm)

Source code in pyswap/components/crop.py
class SaltStress(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Salt stress settings for .crp file.

    Attributes:
        swsalinity (Literal[0, 1, 2]): Switch for salt stress

            * 0 - No salt stress
            * 1 - Maas and Hoffman reduction function
            * 2 - Use osmotic head

        saltmax (Optional[float]): Threshold salt concentration in soil water
        saltslope (Optional[float]): Decline of root water uptake above threshold
        salthead (Optional[float]): Conversion factor salt concentration (mg/cm3) into osmotic head (cm)
    """

    swsalinity: _Literal[0, 1, 2] | None = None
    saltmax: float | None = _Field(default=None, ge=0.0, le=100.0)
    saltslope: float | None = _Field(default=None, **_UNITRANGE)
    salthead: float | None = _Field(default=None, ge=0.0, le=1000.0)

TMNFTB

Bases: BaseTableModel

reduction factor of AMAX [-, R] as function of minimum day temperature [-10..50 oC, R]

Attributes:

Name Type Description
TMNR Series[float]

Minimum temperature.

TMNF Series[float]

Reduction factor of AMAX.

Source code in pyswap/components/tables.py
class TMNFTB(BaseTableModel):
    """reduction factor of AMAX [-, R] as function of minimum day temperature [-10..50 oC, R]

    Attributes:
        TMNR (Series[float]): Minimum temperature.
        TMNF (Series[float]): Reduction factor of AMAX.
    """

    TMNR: Series[float] = pa.Field(ge=-10.0, le=50.0)
    TMNF: Series[float] = pa.Field(ge=0.0, le=1.0)

TMPFTB

Bases: BaseTableModel

reduction factor of AMAX [-, R] as function of average day temperature [-10..50 oC, R]

Attributes:

Name Type Description
TAVD Series[float]

Minimum temperature.

TMPF Series[float]

Reduction factor of AMAX.

Source code in pyswap/components/tables.py
class TMPFTB(BaseTableModel):
    """reduction factor of AMAX [-, R] as function of average day temperature [-10..50 oC, R]

    Attributes:
        TAVD (Series[float]): Minimum temperature.
        TMPF (Series[float]): Reduction factor of AMAX.
    """

    TAVD: Series[float] = pa.Field(ge=-10.0, le=50.0)
    TMPF: Series[float] = pa.Field(ge=0.0, le=1.0)

WRTB

Bases: BaseTableModel

dry weight of roots at soil surface [0..10 kg/m3, R], as a function of development stage [0..2 -,R]

Attributes:

Name Type Description
DVS Series[float]

Development stage of the crop.

W_ROOT_SS Series[float]

Dry weight of roots at soil surface.

Source code in pyswap/components/tables.py
class WRTB(BaseTableModel):
    """dry weight of roots at soil surface [0..10 kg/m3, R], as a function of development stage [0..2 -,R]

    Attributes:
        DVS (Series[float]): Development stage of the crop.
        W_ROOT_SS (Series[float]): Dry weight of roots at soil surface.
    """

    DVS: Series[float] = pa.Field(**DVSRANGE)
    W_ROOT_SS: Series[float] = pa.Field(ge=0.0, le=10.0)

Crop database

Classes that wrap the crop parameters database for WOFOST (A. de Wit).

From the classes here, only the WOFOSTCropDB is directly accessed by the user, however, the final usable object will be the CropVariety.

Classes:

Name Description
WOFOSTCropFile

Manage a single WOFOST crop file content.

CropVariety

Manage crop variety parameters.

WOFOSTCropDB

Manage a single WOFOST crop file content.

CropVariety

Bases: BaseModel

Manage crop variety parameters.

Attributes:

Name Type Description
variety dict

Parameters for crop variety from the YAML file (with metadata).

Properties

parameters: Bare parameters of the variety (all metadata removed). metadata: The metadata of the variety.

Source code in pyswap/db/cropdb.py
class CropVariety(BaseModel):
    """Manage crop variety parameters.

    Attributes:
        variety: Parameters for crop variety from the YAML file (with metadata).

    Properties:
        parameters: Bare parameters of the variety (all metadata removed).
        metadata: The metadata of the variety.
    """

    variety: dict

    @computed_field(return_type=dict)
    def parameters(self):
        params = {
            k.lower(): v[0]
            for k, v in self.variety.items()
            if k != "Metadata" and v[0] != -99.0
        }
        return self._format_tables(params)

    @computed_field(return_type=dict)
    def metadata(self):
        return self.variety["Metadata"]

    @staticmethod
    def _format_tables(table: dict) -> dict[str, list[list]]:
        """pre-format tables from YAML to a list of lists.

        In the YAML file, the tables are seem to be formatted
        in a way where the odd elements in the lists are one
        column and the even elements are the other. This method
        converts this format to a dictionary with two lists.
        """

        formatted = {
            k: [list(row) for row in zip(v[::2], v[1::2], strict=False)]
            if isinstance(v, list)
            else v
            for k, v in table.items()
        }

        return formatted

WOFOSTCropDB

Bases: BaseModel

Simple class for managing crop parameters files.

Initially, it's meant to be used with A. de Wit's WOFOST crop parameters database which is a collection of YAML files. However, it can be easily extended to support other formats and databases when they emerge. All methods should return the content as WOFOSTCropFile instances. This way we ensure that whatever the source format is, the content is always usable in the same way.

Attributes:

Name Type Description
libdir Path

Path to the directory with crop parameters

Properties

croptypes: List all available crop types (files in the directory)

Methods:

Name Description
load_crop_file

Load a specific crop file and return the content as a WOFOSTCropFile instance

Source code in pyswap/db/cropdb.py
class WOFOSTCropDB(BaseModel):
    """Simple class for managing crop parameters files.

    Initially, it's meant to be used with A. de Wit's WOFOST crop parameters
    database which is a collection of YAML files. However, it can be easily
    extended to support other formats and databases when they emerge. All
    methods should return the content as WOFOSTCropFile instances. This way
    we ensure that whatever the source format is, the content is always
    usable in the same way.

    Attributes:
        libdir: Path to the directory with crop parameters

    Properties:
        croptypes: List all available crop types (files in the directory)

    Methods:
        load_crop_file: Load a specific crop file and return the content as a
            WOFOSTCropFile instance
    """

    libdir: Path = crop_params

    @computed_field(return_type=None)
    def croptypes(self):
        """Print the list of available files"""
        pprint(load_yaml(crop_params / "crops.yaml")["available_crops"])

    def load_crop_file(self, crop: str) -> WOFOSTCropFile:
        """Load a specific crop file and return the content as a dictionary"""
        path = (
            self.libdir / f"{crop}"
            if crop.endswith(".yaml")
            else self.libdir / f"{crop}.yaml"
        )
        return WOFOSTCropFile(yaml_content=load_yaml(path))

croptypes()

Print the list of available files

Source code in pyswap/db/cropdb.py
@computed_field(return_type=None)
def croptypes(self):
    """Print the list of available files"""
    pprint(load_yaml(crop_params / "crops.yaml")["available_crops"])

load_crop_file(crop)

Load a specific crop file and return the content as a dictionary

Source code in pyswap/db/cropdb.py
def load_crop_file(self, crop: str) -> WOFOSTCropFile:
    """Load a specific crop file and return the content as a dictionary"""
    path = (
        self.libdir / f"{crop}"
        if crop.endswith(".yaml")
        else self.libdir / f"{crop}.yaml"
    )
    return WOFOSTCropFile(yaml_content=load_yaml(path))

WOFOSTCropFile

Bases: BaseModel

Manage a single WOFOST crop file content.

Attributes:

Name Type Description
yaml_content dict

The entire content of the YAML file.

Properties

metadata: Metadata of the crop file. ecotypes: List of eco-types. genericc3: Generic settings for C3 crop types. genericc4: Generic settings for C4 crop types. varieties: List of available varieties.

Methods:

Name Description
get_variety

Get the parameters of a specific variety.

Source code in pyswap/db/cropdb.py
class WOFOSTCropFile(BaseModel):
    """Manage a single WOFOST crop file content.

    Attributes:
        yaml_content: The entire content of the YAML file.

    Properties:
        metadata: Metadata of the crop file.
        ecotypes: List of eco-types.
        genericc3: Generic settings for C3 crop types.
        genericc4: Generic settings for C4 crop types.
        varieties: List of available varieties.

    Methods:
        get_variety: Get the parameters of a specific variety.
    """

    yaml_content: dict

    @computed_field(return_type=dict)
    def metadata(self):
        """Metadata of the yaml crop file"""
        return self.yaml_content["Metadata"]

    @computed_field(return_type=dict)
    def ecotypes(self):
        return list(self.yaml_content["CropParameters"]["EcoTypes"])

    @computed_field(return_type=dict)
    def genericc3(self):
        """Get generic settings for C3 crop types - plants that bind CO2 into
        3-phosphoglycerate having three carbon atoms. E.g., wheat, rice"""
        return self.yaml_content["CropParameters"]["GenericC3"]

    @computed_field(return_type=dict)
    def genericc4(self):
        """Get generic settings for C4 crop types - plants that bind CO2 into
        oxaloacetate having four carbon atoms. E.g., maize, sugarcane"""
        return self.yaml_content["CropParameters"]["GenericC4"]

    @computed_field(return_type=dict)
    def varieties(self):
        return list(self.yaml_content["CropParameters"]["Varieties"])

    def get_variety(self, variety: str):
        return CropVariety(
            variety=self.yaml_content["CropParameters"]["Varieties"][variety]
        )

genericc3()

Get generic settings for C3 crop types - plants that bind CO2 into 3-phosphoglycerate having three carbon atoms. E.g., wheat, rice

Source code in pyswap/db/cropdb.py
@computed_field(return_type=dict)
def genericc3(self):
    """Get generic settings for C3 crop types - plants that bind CO2 into
    3-phosphoglycerate having three carbon atoms. E.g., wheat, rice"""
    return self.yaml_content["CropParameters"]["GenericC3"]

genericc4()

Get generic settings for C4 crop types - plants that bind CO2 into oxaloacetate having four carbon atoms. E.g., maize, sugarcane

Source code in pyswap/db/cropdb.py
@computed_field(return_type=dict)
def genericc4(self):
    """Get generic settings for C4 crop types - plants that bind CO2 into
    oxaloacetate having four carbon atoms. E.g., maize, sugarcane"""
    return self.yaml_content["CropParameters"]["GenericC4"]

metadata()

Metadata of the yaml crop file

Source code in pyswap/db/cropdb.py
@computed_field(return_type=dict)
def metadata(self):
    """Metadata of the yaml crop file"""
    return self.yaml_content["Metadata"]

Irrigation

Irrigation settings for the SWAP simuluation.

Classes:

Name Description
IrgFile

The irrigation file.

FixedIrrigation

Fixed irrigation settings.

ScheduledIrrigation

Irrigation scheduling settings.

Functions:

Name Description
irg_from_csv

Load the irrigation file from a CSV file.

FixedIrrigation

Bases: PySWAPBaseModel, SerializableMixin, FileMixin, YAMLValidatorMixin

Fixed irrigation settings in the .swp file.

Attributes:

Name Type Description
swirfix Literal[0, 1]

Switch for fixed irrigation applications

swirgfil Literal[0, 1]

Switch for separate file with fixed irrigation applications

irrigevents Optional[Table]
irgfil Optional[str]
Source code in pyswap/components/irrigation.py
class FixedIrrigation(
    _PySWAPBaseModel, _SerializableMixin, _FileMixin, _YAMLValidatorMixin
):
    """Fixed irrigation settings in the .swp file.

    Attributes:
        swirfix (Literal[0, 1]): Switch for fixed irrigation applications
        swirgfil (Literal[0, 1]): Switch for separate file with fixed irrigation applications
        irrigevents (Optional[Table]):
        irgfil (Optional[str]):
    """

    _extension = _PrivateAttr(default="irg")

    swirfix: _Literal[0, 1] | None = None
    swirgfil: _Literal[0, 1] | None = None
    irgfil: _String = _Field(default=_FNAME_IN, frozen=True)
    irrigevents: _Table | None = None

    def model_string(self, **kwargs) -> str:
        """Override the model_string to handle optional file generation.

        Return the full section if swirgfil is set to 1, otherwise, irrigevents
        is excluded from the string and saved in a separate .irg file.
        """
        if self.swirgfil == 1:
            return super().model_string(exclude={"irrigevents"}, **kwargs)
        else:
            return super().model_string()

    @property
    def irg(self):
        return super().model_string(include={"irrigevents"})

    def write_irg(self, path: _Path):
        """Write irrigation data to .irg file.

        This method is only available when the swirgfil attribute is set to 1.

        Parameters:
            path (Path): Path to the directory where the .irg file will be
                saved.
        """
        if self.swirgfil != 1:
            msg = "Irrigation data are not set to be written to a .irg file."
            raise ValueError(msg)

        self.save_file(string=self.irg, fname=self.irgfil, path=path)

model_string(**kwargs)

Override the model_string to handle optional file generation.

Return the full section if swirgfil is set to 1, otherwise, irrigevents is excluded from the string and saved in a separate .irg file.

Source code in pyswap/components/irrigation.py
def model_string(self, **kwargs) -> str:
    """Override the model_string to handle optional file generation.

    Return the full section if swirgfil is set to 1, otherwise, irrigevents
    is excluded from the string and saved in a separate .irg file.
    """
    if self.swirgfil == 1:
        return super().model_string(exclude={"irrigevents"}, **kwargs)
    else:
        return super().model_string()

write_irg(path)

Write irrigation data to .irg file.

This method is only available when the swirgfil attribute is set to 1.

Parameters:

Name Type Description Default
path Path

Path to the directory where the .irg file will be saved.

required
Source code in pyswap/components/irrigation.py
def write_irg(self, path: _Path):
    """Write irrigation data to .irg file.

    This method is only available when the swirgfil attribute is set to 1.

    Parameters:
        path (Path): Path to the directory where the .irg file will be
            saved.
    """
    if self.swirgfil != 1:
        msg = "Irrigation data are not set to be written to a .irg file."
        raise ValueError(msg)

    self.save_file(string=self.irg, fname=self.irgfil, path=path)

IRRIGEVENTS

Bases: BaseTableModel

information for each fixed irrigation event.

Attributes:

Name Type Description
IRDATE Series[datetime]

date of irrigation.

IRDEPTH Series[float]

amount of water [0..1000 mm, R].

IRCONC Series[float]

concentration of irrigation water [0..1000 mg/cm3, R].

IRTYPE Series[int]

type of irrigation

  • 0 - sprinkling
  • 1 - surface
Source code in pyswap/components/tables.py
class IRRIGEVENTS(BaseTableModel):
    """information for each fixed irrigation event.

    Attributes:
        IRDATE (Series[datetime]):date of irrigation.
        IRDEPTH (Series[float]): amount of water [0..1000 mm, R].
        IRCONC (Series[float]): concentration of irrigation water [0..1000 mg/cm3, R].
        IRTYPE (Series[int]): type of irrigation

            * 0 - sprinkling
            * 1 - surface

    """

    IRDATE: Series[pa.DateTime]
    IRDEPTH: Series[float] | None = pa.Field(default=None, ge=0.0, le=1000.0)
    IRCONC: Series[float] = pa.Field(ge=0.0, le=1000.0)
    IRTYPE: Series[int] = pa.Field(ge=0, le=1)

ScheduledIrrigation

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Irrigation scheduling settings in the .crp file.

Attributes:

Name Type Description
schedule Literal[0, 1]

Switch for application irrigation scheduling

startirr str

Specify day and month at which irrigation scheduling starts

endirr str

Specify day and month at which irrigation scheduling stops

cirrs float

Solute concentration of irrigation water

isuas int

Switch for type of irrigation method

  • 0 - Sprinkler irrigation
  • 1 - Surface irrigation
tcs int

Choose one of the following timing criteria options

  • 1 - Ratio actual/potential transpiration
  • 2 - Depletion of Readily Available Water
  • 3 - Depletion of Totally Available Water
  • 4 - Depletion of absolute Water Amount
  • 6 - Fixed weekly irrigation
  • 7 - Pressure head
  • 8 - Moisture content
phFieldCapacity float

Soil water pressure head at field capacity

irgthreshold Optional[float]

Threshold value for weekly irrigation

dcrit Optional[float]

Depth of the sensor

swcirrthres Optional[bool]

Switch for over-irrigation

cirrthres Optional[float]

Threshold salinity concentration above which over-irrigation occur

perirrsurp Optional[float]

Over-irrigation of the usually scheduled irrigation depth

tcsfix Optional[int]

Switch for minimum time interval between irrigation applications

irgdayfix Optional[int]

Minimum number of days between irrigation applications

phormc Optional[int]

Switch for the use of pressure head or water content

  • 0 - Pressure head
  • 1 - Water content
dvs_tc1 Optional[Table]
dvs_tc2 Optional[Table]
dvs_tc3 Optional[Table]
dvs_tc4 Optional[Table]
dvs_tc5 Optional[Table]
Source code in pyswap/components/irrigation.py
class ScheduledIrrigation(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Irrigation scheduling settings in the .crp file.

    Attributes:
        schedule (Literal[0, 1]): Switch for application irrigation scheduling
        startirr (str): Specify day and month at which irrigation scheduling starts
        endirr (str): Specify day and month at which irrigation scheduling stops
        cirrs (float): Solute concentration of irrigation water
        isuas (int): Switch for type of irrigation method

            * 0 - Sprinkler irrigation
            * 1 - Surface irrigation

        tcs (int): Choose one of the following timing criteria options

            * 1 - Ratio actual/potential transpiration
            * 2 - Depletion of Readily Available Water
            * 3 - Depletion of Totally Available Water
            * 4 - Depletion of absolute Water Amount
            * 6 - Fixed weekly irrigation
            * 7 - Pressure head
            * 8 - Moisture content

        phFieldCapacity (float): Soil water pressure head at field capacity
        irgthreshold (Optional[float]): Threshold value for weekly irrigation
        dcrit (Optional[float]): Depth of the sensor
        swcirrthres (Optional[bool]): Switch for over-irrigation
        cirrthres (Optional[float]): Threshold salinity concentration above which over-irrigation occur
        perirrsurp (Optional[float]): Over-irrigation of the usually scheduled irrigation depth
        tcsfix (Optional[int]): Switch for minimum time interval between irrigation applications
        irgdayfix (Optional[int]): Minimum number of days between irrigation applications
        phormc (Optional[int]): Switch for the use of pressure head or water content

            * 0 - Pressure head
            * 1 - Water content

        dvs_tc1 (Optional[Table]):
        dvs_tc2 (Optional[Table]):
        dvs_tc3 (Optional[Table]):
        dvs_tc4 (Optional[Table]):
        dvs_tc5 (Optional[Table]):
    """

    schedule: _Literal[0, 1] | None = None
    startirr: _DayMonth | None = None
    endirr: _DayMonth | None = None
    cirrs: float | None = _Field(default=None, ge=0.0, le=100.0)
    isuas: _Literal[0, 1] | None = None
    tcs: _Literal[1, 2, 3, 4, 6, 7, 8] | None = None

    phfieldcapacity: float | None = _Field(default=None, ge=-1000.0, le=0.0)
    irgthreshold: float | None = _Field(default=None, ge=0.0, le=20.0)
    dcrit: float | None = _Field(default=None, ge=-100.0, le=0.0)
    swcirrthres: _Literal[0, 1] | None = None
    cirrthres: float | None = _Field(default=None, ge=0.0, le=100.0)
    perirrsurp: float | None = _Field(default=None, ge=0.0, le=100.0)
    tcsfix: _Literal[0, 1] | None = None
    irgdayfix: int | None = _Field(default=None, **_YEARRANGE)
    dcs: _Literal[0, 1] | None = None
    dcslim: _Literal[0, 1] | None = None
    irgdepmin: float | None = _Field(default=None, ge=0.0, le=100.0)
    irgdepmax: float | None = _Field(default=None, ge=0.0, le=1.0e7)
    tc1tb: _Table | None = None
    tc2tb: _Table | None = None
    tc3tb: _Table | None = None
    tc4tb: _Table | None = None
    tc7tb: _Table | None = None
    tc8tb: _Table | None = None
    dc1tb: _Table | None = None
    dc2tb: _Table | None = None

Soil-water

Evaporation

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Evaporation settings.

Attributes:

Name Type Description
swcfbs Literal[0, 1]

Switch for use of soil factor CFBS to calculate Epot from ETref.

swredu Literal[0, 1, 2]

Switch for the method for reduction of potential soil evaporation:

  • 0 - reduction to maximum Darcy flux.
  • 1 - reduction to maximum Darcy flux and to maximum Black (1969).
  • 2 - reduction to maximum Darcy flux and to maximum Boesten/Stroosnijder (1986).
cfevappond Optional[Decimal2f]

When ETref is used, evaporation coefficient in case of ponding [0..3].

cfbs Optional[Decimal2f]

Coefficient for potential soil evaporation [0.5..1.5].

rsoil Optional[Decimal2f]

Soil resistance of wet soil [0..1000.0].

cofredbl Optional[Decimal2f]

Soil evaporation coefficient of Black [0..1].

rsigni Optional[Decimal2f]

Minimum rainfall to reset method of Black [0..100].

cofredbo Optional[Decimal2f]

Soil evaporation coefficient of Boesten/Stroosnijder [0..1].

Source code in pyswap/components/soilwater.py
class Evaporation(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Evaporation settings.

    Attributes:
        swcfbs (Literal[0, 1]): Switch for use of soil factor CFBS to calculate Epot from ETref.
        swredu (Literal[0, 1, 2]): Switch for the method for reduction of potential soil evaporation:

            * 0 - reduction to maximum Darcy flux.
            * 1 - reduction to maximum Darcy flux and to maximum Black (1969).
            * 2 - reduction to maximum Darcy flux and to maximum Boesten/Stroosnijder (1986).

        cfevappond (Optional[Decimal2f]): When ETref is used, evaporation coefficient in case of ponding [0..3].
        cfbs (Optional[Decimal2f]): Coefficient for potential soil evaporation [0.5..1.5].
        rsoil (Optional[Decimal2f]): Soil resistance of wet soil [0..1000.0].
        cofredbl (Optional[Decimal2f]): Soil evaporation coefficient of Black [0..1].
        rsigni (Optional[Decimal2f]): Minimum rainfall to reset method of Black [0..100].
        cofredbo (Optional[Decimal2f]): Soil evaporation coefficient of Boesten/Stroosnijder [0..1].
    """

    swcfbs: _Literal[0, 1] | None = None
    swredu: _Literal[0, 1, 2] | None = None
    cfevappond: _Decimal2f | None = _Field(default=None, ge=0, le=3)
    cfbs: _Decimal2f | None = _Field(default=None, ge=0.5, le=1.5)
    rsoil: _Decimal2f | None = _Field(default=None, ge=0, le=1000.0)
    cofredbl: _Decimal2f | None = _Field(default=None, **_UNITRANGE)
    rsigni: _Decimal2f | None = _Field(default=None, ge=0, le=100)
    cofredbo: _Decimal2f | None = _Field(default=None, **_UNITRANGE)

SOILHYDRFUNC

Bases: BaseTableModel

Soil hydraulic functions table.

!!! warning
    ALFAW required only when the hysteresis option is set to 1 or 2. This column is set as optional column and (for now) is not checked.

('ORES', 'OSAT', 'ALFA', 'NPAR', 'KSATFIT', 'LEXP', 'ALFAW', 'H_ENPR', 'KSATEXM', 'BDENS') Attributes: ORES (Series[float]): Residual water content [0..1 cm3/cm3, R] OSAT (Series[float]): Saturated water content [0..1 cm3/cm3, R] ALFA (Series[float]): Parameter alfa of main drying curve [0.0001..100 /cm, R] NPAR (Series[float]): Parameter n [1.001..9 -, R] LEXP (Series[float]): Exponent in hydraulic conductivity function [-25..25 -, R] KSATFIT (Series[float]): Fitting parameter Ksat of hydraulic conductivity function [1.d-5..1d5 cm/d, R] H_ENPR (Series[float]): Air entry pressure head [-40.0..0.0 cm, R] KSATEXM (Series[float]): Measured hydraulic conductivity at saturated conditions [1.d-5..1d5 cm/d, R] BDENS (Series[float]): Dry soil bulk density [100..1d4 mg/cm3, R] ALFAW (Optional[Series[float]]): Alfa parameter of main wetting curve in case of hysteresis [0.0001..100 /cm, R]

Source code in pyswap/components/tables.py
class SOILHYDRFUNC(BaseTableModel):
    """Soil hydraulic functions table.

        !!! warning
            ALFAW required only when the hysteresis option is set to 1 or 2. This column is set as optional column and (for now) is not checked.
    ('ORES', 'OSAT', 'ALFA', 'NPAR', 'KSATFIT', 'LEXP', 'ALFAW', 'H_ENPR', 'KSATEXM', 'BDENS')
        Attributes:
            ORES (Series[float]): Residual water content [0..1 cm3/cm3, R]
            OSAT (Series[float]): Saturated water content [0..1 cm3/cm3, R]
            ALFA (Series[float]): Parameter alfa of main drying curve [0.0001..100 /cm, R]
            NPAR (Series[float]): Parameter n [1.001..9 -, R]
            LEXP (Series[float]): Exponent in hydraulic conductivity function [-25..25 -, R]
            KSATFIT (Series[float]): Fitting parameter Ksat of hydraulic conductivity function [1.d-5..1d5 cm/d, R]
            H_ENPR (Series[float]): Air entry pressure head [-40.0..0.0 cm, R]
            KSATEXM (Series[float]): Measured hydraulic conductivity at saturated conditions [1.d-5..1d5 cm/d, R]
            BDENS (Series[float]): Dry soil bulk density [100..1d4 mg/cm3, R]
            ALFAW (Optional[Series[float]]): Alfa parameter of main wetting curve in case of hysteresis [0.0001..100 /cm, R]
    """

    ORES: Series[float] = pa.Field(ge=0.0, le=1.0)
    OSAT: Series[float] = pa.Field(ge=0.0, le=1.0)
    ALFA: Series[float] = pa.Field(ge=0.0001, le=100.0)
    NPAR: Series[float] = pa.Field(ge=1.001, le=9.0)
    LEXP: Series[float] = pa.Field(ge=-25.0, le=25.0)
    KSATFIT: Series[float] = pa.Field(ge=1.0e-5, le=1.0e5)
    H_ENPR: Series[float] = pa.Field(ge=-40.0, le=0.0)
    KSATEXM: Series[float] = pa.Field(ge=1.0e-5, le=1.0e5)
    BDENS: Series[float] = pa.Field(ge=100.0, le=1.0e4)
    ALFAW: Series[float] | None = pa.Field(ge=0.0001, le=100.0)

SOILPROFILE

Bases: BaseTableModel

Vertical discretization of soil profile

Attributes:

Name Type Description
ISUBLAY Series[int]

Series[int]: number of sub layer, start with 1 at soil surface [1..MACP, I].

ISOILLAY Series[int]

Series[int]: number of soil physical layer, start with 1 at soil surface [1..MAHO, I].

HSUBLAY Series[float]

Series[float]: height of sub layer [0..1.d4 cm, R].

HCOMP Series[float]

Series[float]: height of compartments in the sub layer [0.0..1000.0 cm, R].

NCOMP Series[int]

Series[int]: number of compartments in the sub layer (Mind NCOMP = HSUBLAY/HCOMP) [1..MACP, I].

Source code in pyswap/components/tables.py
class SOILPROFILE(BaseTableModel):
    """Vertical discretization of soil profile

    Attributes:
        ISUBLAY: Series[int]: number of sub layer, start with 1 at soil surface [1..MACP, I].
        ISOILLAY: Series[int]: number of soil physical layer, start with 1 at soil surface [1..MAHO, I].
        HSUBLAY: Series[float]: height of sub layer [0..1.d4 cm, R].
        HCOMP: Series[float]: height of compartments in the sub layer [0.0..1000.0 cm, R].
        NCOMP: Series[int]: number of compartments in the sub layer (Mind NCOMP = HSUBLAY/HCOMP) [1..MACP, I].
    """

    ISOILLAY: Series[int] = pa.Field(ge=1)
    ISUBLAY: Series[int] = pa.Field(ge=1)
    HSUBLAY: Series[float] = pa.Field(ge=0.0, le=1.0e4)
    HCOMP: Series[float] = pa.Field(ge=0.0, le=1.0e3)
    NCOMP: Series[int] = pa.Field(ge=1)

SnowAndFrost

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Snow and frost settings for the model.

Attributes:

Name Type Description
swsnow Literal[0, 1]

Switch for calculation of snow accumulation and melt.

swfrost Literal[0, 1]

Switch, in case of frost reduce soil water flow.

snowinco Optional[Decimal2f]

Initial snow water equivalent [0..1000 cm].

teprrain Optional[Decimal2f]

Temperature above which all precipitation is rain [0..10 oC].

teprsnow Optional[Decimal2f]

Temperature below which all precipitation is snow [-10..0 oC].

tfroststa Optional[Decimal2f]

Soil temperature (oC) where reduction of water fluxes starts [-10.0..5.0 oC].

tfrostend Optional[Decimal2f]

Soil temperature (oC) where reduction of water fluxes ends [-10.0..5.0 oC].

Source code in pyswap/components/soilwater.py
class SnowAndFrost(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Snow and frost settings for the model.

    Attributes:
        swsnow (Literal[0, 1]): Switch for calculation of
            snow accumulation and melt.
        swfrost (Literal[0, 1]): Switch, in case of frost reduce
            soil water flow.
        snowinco (Optional[Decimal2f]): Initial snow water equivalent [0..1000 cm].
        teprrain (Optional[Decimal2f]): Temperature above which all
            precipitation is rain [0..10 oC].
        teprsnow (Optional[Decimal2f]): Temperature below which all
            precipitation is snow [-10..0 oC].
        tfroststa (Optional[Decimal2f]): Soil temperature (oC) where reduction
            of water fluxes starts [-10.0..5.0 oC].
        tfrostend (Optional[Decimal2f]): Soil temperature (oC) where reduction
            of water fluxes ends [-10.0..5.0 oC].
    """

    swsnow: _Literal[0, 1] | None = None
    swfrost: _Literal[0, 1] | None = None
    snowinco: _Decimal2f | None = _Field(default=None, ge=0, le=1000)
    teprrain: _Decimal2f | None = _Field(default=None, ge=0, le=10)
    teprsnow: _Decimal2f | None = _Field(default=None, ge=-10, le=0)
    tfroststa: _Decimal2f | None = _Field(default=None, ge=-10, le=5)
    tfrostend: _Decimal2f | None = _Field(default=None, ge=-10, le=5)

SoilMoisture

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Soil moisture content and water balance.

Attributes:

Name Type Description
swinco Literal[1, 2, 3]

Switch for the type of initial soil moisture condition:

  • 1 - pressure head as function of soil depth.
  • 2 - pressure head of each compartment is in hydrostatic equilibrium with initial groundwater level.
  • 3 - read final pressure heads from output file of previous Swap simulation.
head_soildepth Optional[Table]

Table with head and soil depth data.

gwli Optional[Decimal2f]

Initial groundwater level [-10000..100 cm].

inifil Optional[str]

name of output file *.END which contains initial values.

Source code in pyswap/components/soilwater.py
class SoilMoisture(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Soil moisture content and water balance.

    Attributes:
        swinco (Literal[1, 2, 3]): Switch for the type of initial soil moisture condition:

            * 1 - pressure head as function of soil depth.
            * 2 - pressure head of each compartment is in
                hydrostatic equilibrium with initial groundwater level.
            * 3 - read final pressure heads from output file of previous
                Swap simulation.

        head_soildepth (Optional[Table]): Table with head and
            soil depth data.
        gwli (Optional[Decimal2f]): Initial groundwater level [-10000..100 cm].
        inifil (Optional[str]): name of output file *.END which contains
            initial values.
    """

    swinco: _Literal[1, 2, 3] | None = None
    head_soildepth: _Table | None = None
    gwli: _Decimal2f | None = _Field(default=None, ge=-10000, le=100)
    inifil: _String | None = None

SoilProfile

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Vertical discretization of soil profile, soil hydraulic functions and hysteresis of soil water retention.

Covers parts 4, 5, 6 and 7 of the .swp file.

Attributes:

Name Type Description
swsophy Literal[0, 1]

Switch for analytical functions or tabular input

  • 0 - Analytical functions with input of Mualem - van Genuchten parameters
  • 1 - Soil physical tables
swhyst Literal[0, 1, 2]

Hysteresis of soil water retention function

  • 0 - No hysteresis
  • 1 - Hysteresis, initial conditions wetting
  • 2 - Hysteresis, initial conditions drying
filenamesophy Optional[str]

Names of input files with soil hydraulic tables for each soil layer

tau Optional[Decimal2f]

Minimum pressure head difference to change wetting-drying [0..1000].

swmacro Literal[0, 1]

Switch for preferential flow due to macropores

soilprofile Table

Table with soil profile data

soilhydrfunc Optional[Table]

Table with soil hydraulic functions

Source code in pyswap/components/soilwater.py
class SoilProfile(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Vertical discretization of soil profile, soil hydraulic functions and
        hysteresis of soil water retention.

    Covers parts 4, 5, 6 and 7 of the .swp file.

    Attributes:
        swsophy (Literal[0, 1]): Switch for analytical functions or
            tabular input

            * 0 - Analytical functions with input of Mualem -
                van Genuchten parameters
            * 1 - Soil physical tables

        swhyst (Literal[0, 1, 2]): Hysteresis of soil water retention function

            * 0 - No hysteresis
            * 1 - Hysteresis, initial conditions wetting
            * 2 - Hysteresis, initial conditions drying

        filenamesophy (Optional[str]): Names of input files with
            soil hydraulic tables for each soil layer
        tau (Optional[Decimal2f]): Minimum pressure head difference to change
            wetting-drying [0..1000].
        swmacro (Literal[0, 1]): Switch for preferential flow due to macropores
        soilprofile (Table): Table with soil profile data
        soilhydrfunc (Optional[Table]): Table with
            soil hydraulic functions
    """

    _validation: bool = _PrivateAttr(default=False)

    swsophy: _Literal[0, 1] | None = None
    swhyst: _Literal[0, 1, 2] | None = None
    swmacro: _Literal[0, 1] | None = None
    filenamesophy: _String | None = None
    tau: _Decimal2f | None = _Field(default=None, ge=0, le=1000)
    soilprofile: _Table | None = None
    soilhydrfunc: _Table | None = None

SurfaceFlow

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Surface flow settings (ponding, runoff and runon).

Attributes:

Name Type Description
swpondmx Literal[0, 1]

Switch for variation ponding threshold for runoff

  • 0 - Ponding threshold for runoff is constant
  • 1 - Ponding threshold for runoff varies in time
swrunon Literal[0, 1]

Switch for runon

  • 0 - No runon
  • 1 - Use runon data
rsro Optional[Decimal2f]

Drainage resistance for surface runoff [0.001..1.0].

rsroexp Optional[Decimal2f]

Exponent for drainage equation of surface runoff [0.01..10.0].

pondmx Optional[Decimal2f]

In case of ponding, minimum thickness for runoff [0..1000].

rufil Optional[str]

Name of the runon file.

pondmxtb Optional[Table]

Minimum thickness for runoff as a function of time.

Source code in pyswap/components/soilwater.py
class SurfaceFlow(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Surface flow settings (ponding, runoff and runon).

    Attributes:
        swpondmx (Literal[0, 1]): Switch for variation ponding
            threshold for runoff

            * 0 - Ponding threshold for runoff is constant
            * 1 - Ponding threshold for runoff varies in time

        swrunon (Literal[0, 1]): Switch for runon

            * 0 - No runon
            * 1 - Use runon data

        rsro (Optional[Decimal2f]): Drainage resistance for surface runoff [0.001..1.0].
        rsroexp (Optional[Decimal2f]): Exponent for drainage equation of surface runoff [0.01..10.0].
        pondmx (Optional[Decimal2f]): In case of ponding, minimum thickness for runoff [0..1000].
        rufil (Optional[str]): Name of the runon file.
        pondmxtb (Optional[Table]): Minimum thickness for runoff as a function of time.
    """

    swpondmx: _Literal[0, 1] | None = None
    swrunon: _Literal[0, 1] | None = None
    rsro: _Decimal3f | None = _Field(default=None, ge=0.001, le=1.0)
    rsroexp: _Decimal2f | None = _Field(default=None, ge=0.01, le=10.0)
    pondmx: _Decimal2f | None = _Field(default=None, ge=0, le=1000)
    rufil: _String | None = None
    pondmxtb: _Table | None = None

Drainage

Lateral drainage settings

Settings for the lateral drainage of the .swp file, including the .dra file settings.

Classes:

Name Description
Flux

Fluxes between drainage levels in .dra file.

DraFile

Drainage file (.dra) settings.

Drainage

The lateral drainage settings of .swp file.

DraFile

Bases: PySWAPBaseModel, FileMixin, SerializableMixin

Content of the drainage file (.dra).

Attributes:

Name Type Description
dramet Literal[1, 2, 3]

Method of lateral drainage calculation

  • 1 - Use table of drainage flux - groundwater level relation.
  • 2 - Use drainage formula of Hooghoudt or Ernst.
  • 3 - Use drainage/infiltration resistance, multi-level if needed.
swdivd Literal[1, 2]

Calculate vertical distribution of drainage flux in groundwater.

cofani Optional[FloatList]

specify anisotropy factor COFANI (horizontal/vertical saturated hydraulic conductivity) for each soil layer (maximum MAHO)

swdislay Literal[0, 1, 2, 3, '-']

Switch to adjust upper boundary of model discharge layer.

  • 0 - No adjustment
  • 1 - Adjustment based on depth of top of model discharge
  • 2 - Adjustment based on factor of top of model discharge
lm1 float

Drain spacing

table_qdrntb Table

Table of drainage flux - groundwater level.

lm1 float | None

float = _Field(ge=1.0, le=1000.0)

qdrntb Table | None

_Table

lm2 float

Drain spacing.

shape float

Shape factor to account for actual location between drain and water divide.

wetper float

Wet perimeter of the drain.

zbotdr float

Level of drain bottom.

entres float

Drain entry resistance.

ipos Literal[1, 2, 3, 4, 5]

Position of drain

  • 1 - On top of an impervious layer in a homogeneous profile
  • 2 - Above an impervious layer in a homogeneous profile
  • 3 - At the interface of a fine upper and a coarse lower soil layer
  • 4 - In the lower, more coarse soil layer
  • 5 - In the upper, more fine soil layer
basegw float

Level of impervious layer.

khtop float

Horizontal hydraulic conductivity of the top layer.

khbot Optional[float]

Horizontal hydraulic conductivity of the bottom layer.

zintf Optional[float]

Interface level of the coarse and fine soil layer.

kvtop Optional[float]

Vertical hydraulic conductivity of the top layer.

kvbot Optional[float]

Vertical hydraulic conductivity of the bottom layer.

geofac Optional[float]

Geometric factor of Ernst.

nrlevs int

Number of drainage levels.

swintfl Literal[0, 1]

Option for interflow in highest drainage level (shallow system with short residence time).

cofintflb float

Coefficient for interflow relation.

expintflb float

Exponent for interflow relation.

swtopnrsrf Literal[0, 1]

Switch to enable adjustment of model discharge layer.

fluxes Subsection

List of level fluxes.

altcu float

Altitude of the control unit relative to reference level.

nrsrf int

Number of subsurface drainage levels.

swnrsrf Literal[0, 1, 2]

Switch to introduce rapid subsurface drainage.

rsurfdeep Optional[float]

Maximum resistance of rapid subsurface drainage.

rsurfshallow Optional[float]

Minimum resistance of rapid subsurface drainage.

swsrf Literal[1, 2, 3]

Switch for interaction with surface water system.

swsec Optional[Literal[1, 2]]

Option for surface water level of secondary system.

wlact Optional[float]

Initial surface water level.

osswlm Optional[float]

Criterium for warning about oscillation.

nmper Optional[int]

Number of management periods.

swqhr Optional[Literal[1, 2]]

Switch for type of discharge relationship.

sofcu Optional[float]

Size of the control unit.

Source code in pyswap/components/drainage.py
class DraFile(_PySWAPBaseModel, _FileMixin, _SerializableMixin):
    """Content of the drainage file (.dra).

    Attributes:
        dramet (Literal[1, 2, 3]): Method of lateral drainage calculation

            * 1 - Use table of drainage flux - groundwater level relation.
            * 2 - Use drainage formula of Hooghoudt or Ernst.
            * 3 - Use drainage/infiltration resistance, multi-level if needed.

        swdivd (Literal[1, 2]): Calculate vertical distribution of
            drainage flux in groundwater.
        cofani (Optional[FloatList]): specify anisotropy factor COFANI
            (horizontal/vertical saturated hydraulic conductivity) for
            each soil layer (maximum MAHO)
        swdislay (Literal[0, 1, 2, 3, '-']): Switch to adjust
            upper boundary of model discharge layer.

            * 0 - No adjustment
            * 1 - Adjustment based on depth of top of model discharge
            * 2 - Adjustment based on factor of top of model discharge
        lm1 (float): Drain spacing
        table_qdrntb (Table): Table of drainage flux - groundwater level.
        lm1: float = _Field(ge=1.0, le=1000.0)
        qdrntb: _Table
        lm2 (float): Drain spacing.
        shape (float): Shape factor to account for actual location between
            drain and water divide.
        wetper (float): Wet perimeter of the drain.
        zbotdr (float): Level of drain bottom.
        entres (float): Drain entry resistance.
        ipos (Literal[1, 2, 3, 4, 5]): Position of drain

            * 1 - On top of an impervious layer in a homogeneous profile
            * 2 - Above an impervious layer in a homogeneous profile
            * 3 - At the interface of a fine upper and a coarse lower
                soil layer
            * 4 - In the lower, more coarse soil layer
            * 5 - In the upper, more fine soil layer

        basegw (float): Level of impervious layer.
        khtop (float): Horizontal hydraulic conductivity of the top layer.
        khbot (Optional[float]): Horizontal hydraulic conductivity of
            the bottom layer.
        zintf (Optional[float]): Interface level of the coarse and
            fine soil layer.
        kvtop (Optional[float]): Vertical hydraulic conductivity of
            the top layer.
        kvbot (Optional[float]): Vertical hydraulic conductivity of
            the bottom layer.
        geofac (Optional[float]): Geometric factor of Ernst.
        nrlevs (int): Number of drainage levels.
        swintfl (Literal[0, 1]): Option for interflow in highest
            drainage level (shallow system with short residence time).
        cofintflb (float): Coefficient for interflow relation.
        expintflb (float): Exponent for interflow relation.
        swtopnrsrf (Literal[0, 1]): Switch to enable adjustment of
            model discharge layer.
        fluxes (Subsection): List of level fluxes.
        altcu (float): Altitude of the control unit relative to reference level.
        nrsrf (int): Number of subsurface drainage levels.
        swnrsrf (Literal[0, 1, 2]): Switch to introduce rapid subsurface drainage.
        rsurfdeep (Optional[float]): Maximum resistance of rapid subsurface drainage.
        rsurfshallow (Optional[float]): Minimum resistance of rapid subsurface drainage.
        swsrf (Literal[1, 2, 3]): Switch for interaction with surface water system.
        swsec (Optional[Literal[1, 2]]): Option for surface water level of secondary system.
        wlact (Optional[float]): Initial surface water level.
        osswlm (Optional[float]): Criterium for warning about oscillation.
        nmper (Optional[int]): Number of management periods.
        swqhr (Optional[Literal[1, 2]]): Switch for type of discharge relationship.
        sofcu (Optional[float]): Size of the control unit.
    """

    _extension = _PrivateAttr("dra")
    # General
    dramet: _Literal[1, 2, 3] | None = None
    swdivd: _Literal[1, 2] | None = None
    cofani: _FloatList | None = None
    swdislay: _Literal[0, 1, 2, 3, "-"] | None = None
    # Drainage flux table
    lm1: float | None = _Field(default=None, ge=1.0, le=1000.0)
    qdrntb: _Table | None = None
    # Drainage formula
    lm2: float | None = _Field(default=None, ge=1.0, le=1000.0)
    shape: float | None = _Field(default=None, **_UNITRANGE)
    wetper: float | None = _Field(default=None, ge=0.0, le=1000.0)
    zbotdr: float | None = _Field(default=None, ge=-1000.0, le=0.0)
    entres: float | None = _Field(default=None, ge=0.0, le=1000.0)
    ipos: _Literal[1, 2, 3, 4, 5] | None = None
    basegw: float | None = _Field(default=None, ge=-1.0e4, le=0.0)
    khtop: float | None = _Field(default=None, ge=0.0, le=1000.0)
    khbot: float | None = _Field(default=None, ge=0.0, le=1000.0)
    zintf: float | None = _Field(default=None, ge=-1.0e4, le=0.0)
    kvtop: float | None = _Field(default=None, ge=0.0, le=1000.0)
    kvbot: float | None = _Field(default=None, ge=0.0, le=1000.0)
    geofac: float | None = _Field(default=None, ge=0.0, le=100.0)
    # Drainage infiltration resistance
    nrlevs: int | None = _Field(default=None, ge=1, le=5)
    swintfl: _Literal[0, 1] | None = None
    cofintflb: float | None = _Field(default=None, ge=0.01, le=10.0)
    expintflb: float | None = _Field(default=None, ge=0.1, le=1.0)
    swtopnrsrf: _Literal[0, 1] | None = None
    fluxes: _Subsection | None = None
    # Extended section
    altcu: float | None = _Field(default=None, ge=-300000.0, le=300000.0)
    drntb: _Table | None = None
    nrsrf: int | None = _Field(default=None, ge=1, le=5)
    swnrsrf: _Literal[0, 1, 2] | None = None
    rsurfdeep: float | None = _Field(default=None, ge=0.001, le=1000.0)
    rsurfshallow: float | None = _Field(default=None, ge=0.001, le=1000.0)
    cofintfl: float | None = _Field(default=None, ge=0.01, le=10.0)
    expintfl: float | None = _Field(default=None, ge=0.01, le=10.0)
    swsrf: _Literal[1, 2, 3] | None = None
    swsec: _Literal[1, 2] | None = None
    secwatlvl: _Table | None = None
    wlact: float | None = _Field(default=None, ge=-300000.0, le=300000.0)
    osswlm: float | None = _Field(default=None, ge=0.0, le=10.0)
    nmper: int | None = _Field(default=None, ge=1, le=3660)
    swqhr: _Literal[1, 2] | None = None
    sofcu: float | None = _Field(default=None, ge=0.1, le=100000.0)
    mansecwatlvl: _Table | None = None
    drainageleveltopparams: _Table | None = None
    qweir: _Table | None = None
    qweirtb: _Table | None = None
    priwatlvl: _Table | None = None

    @property
    def dra(self):
        return self.model_string()

Drainage

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

The lateral drainage settings inside .swp file.

Attributes:

Name Type Description
swdra Literal[0, 1, 2]

Switch for lateral drainage.

  • 0 - No drainage.
  • 1 - Simulate with a basic drainage routine.
  • 2 - Simulate with surface water management.
drfil str

Name of the file. This attribute is frozen, there is no need to change it.

drafile Optional[Any]

Content of the drainage file.

Source code in pyswap/components/drainage.py
class Drainage(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """The lateral drainage settings inside .swp file.

    Attributes:
        swdra (Literal[0, 1, 2]): Switch for lateral drainage.

            * 0 - No drainage.
            * 1 - Simulate with a basic drainage routine.
            * 2 - Simulate with surface water management.

        drfil (str): Name of the file. This attribute is frozen, there is no
            need to change it.
        drafile (Optional[Any]): Content of the drainage file.
    """

    swdra: _Literal[0, 1, 2] | None = None
    drfil: _String | None = _Field(default=_FNAME_IN, frozen=True)
    drafile: _File | None = _Field(default=None, exclude=True)

    def write_dra(self, path: str) -> None:
        self.drafile.save_file(string=self.drafile.dra, fname=self.drfil, path=path)
        return None

Flux

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Fluxes between drainage levels in .dra file.

Note

This was rewritten to be a single class instead of a list of classe. Simplicity over DRY. Anyway, the prefered way to set this up would be through the table from the extended section I guess.

Attributes:

Name Type Description
drares float

Drainage resistance.

infres float

Infiltration resistance.

swallo Literal[1, 2]

Switch to allow drainage from this level.

l Optional[float]

Drain spacing.

zbotdr float

Level of the bottom of the drain.

swdtyp Literal[1, 2]

Drainage type.

  • 1 - drain tube.
  • 2 - open channel.
datowltb Table

date DATOWL [date] and channel water level LEVEL. Add suffix to the dataframe headers according to the level number.

Source code in pyswap/components/drainage.py
class Flux(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Fluxes between drainage levels in .dra file.

    !!! note

        This was rewritten to be a single class instead of a list of classe.
        Simplicity over DRY. Anyway, the prefered way to set this up would be
        through the table from the extended section I guess.

    Attributes:
        drares (float): Drainage resistance.
        infres (float): Infiltration resistance.
        swallo (Literal[1, 2]): Switch to allow drainage from this level.
        l (Optional[float]): Drain spacing.
        zbotdr (float): Level of the bottom of the drain.
        swdtyp (Literal[1, 2]): Drainage type.

            * 1 - drain tube.
            * 2 - open channel.

        datowltb (Table): date DATOWL [date] and channel water
            level LEVEL. Add suffix to the dataframe headers
            according to the level number.
    """

    drares1: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    infres1: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    swallo1: _Literal[1, 2, 3] | None = None
    l1: float | None = _Field(default=None, ge=1.0, le=1.0e5)
    zbotdr1: float = _Field(default=None, ge=-1000.0, le=0.0)
    swdtyp1: _Literal[1, 2] | None = None
    datowltb1: _Table | None = None
    # level 2
    drares2: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    infres2: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    swallo2: _Literal[1, 2, 3] | None = None
    l2: float | None = _Field(default=None, ge=1.0, le=1.0e5)
    zbotdr2: float | None = _Field(default=None, ge=-1000.0, le=0.0)
    swdtyp2: _Literal[1, 2] | None = None
    datowltb2: _Table | None = None
    # level 3
    drares3: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    infres3: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    swallo3: _Literal[1, 2, 3] | None = None
    l3: float | None = _Field(default=None, ge=1.0, le=1.0e5)
    zbotdr3: float | None = _Field(default=None, ge=-1000.0, le=0.0)
    swdtyp3: _Literal[1, 2] | None = None
    datowltb3: _Table | None = None
    # level 4
    drares4: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    infres4: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    swallo4: _Literal[1, 2, 3] | None = None
    l4: float | None = _Field(default=None, ge=1.0, le=1.0e5)
    zbotdr4: float | None = _Field(default=None, ge=-1000.0, le=0.0)
    swdtyp4: _Literal[1, 2] | None = None
    datowltb4: _Table | None = None
    # level 5
    drares5: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    infres5: float | None = _Field(default=None, ge=10.0, le=1.0e5)
    swallo5: _Literal[1, 2, 3] | None = None
    l5: float | None = _Field(default=None, ge=1.0, le=1.0e5)
    zbotdr5: float | None = _Field(default=None, ge=-1000.0, le=0.0)
    swdtyp5: _Literal[1, 2] | None = None
    datowltb5: _Table | None = None

Boundary conditions

Boundary conditions settings.

Classes:

BottomBoundary: Bottom boundary settings.

BottomBoundary

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin, FileMixin

Bottom boundary settings.

Technically in SWAP boundary conditions can be specified either inside the .swp file or in a separate .bbc file. The swbbcfile attribute determines whether the boundary conditions are written to a .bbc file.

Attributes:

Name Type Description
swbbcfile Optional[Literal[0, 1]]

Specify boundary conditions in current file (0) or in a separate .bbc file (1). The preferred is to define the boundary conditions in the .swp file. bbcfil might become deprecated in the future.

swbotb Optional[Literal[1, 2, 3, 4, 5, 6, 7, 8]]

Switch for type of bottom boundary.

  • 1 - prescribe groundwater level;
  • 2 - prescribe bottom flux;
  • 3 - calculate bottom flux from hydraulic head of deep aquifer;
  • 4 - calculate bottom flux as function of groundwater level;
  • 5 - prescribe soil water pressure head of bottom compartment;
  • 6 - bottom flux equals zero;
  • 7 - free drainage of soil profile;
  • 8 - free outflow at soil-air interface.
sw2 Optional[Literal[1, 2]]

Specify whether a sinus function or a table are used for the bottom flux.

  • 1 - sinus function;
  • 2 - table.
sw3 Optional[Literal[1, 2]]

Specify whether a sinus function or a table are used for the hydraulic head in the deep aquifer.

  • 1 - sinus function;
  • 2 - table.
sw4 Optional[Literal[0, 1]]

An extra groundwater flux can be specified which is added to above specified flux.

  • 0 - no extra flux;
  • 1 - extra flux.
swbotb3resvert Optional[Literal[0, 1]]

Switch for vertical hydraulic resistance between bottom boundary and groundwater level.

  • 0 - Include vertical hydraulic resistance
  • 1 - Suppress vertical hydraulic resistance
swbotb3impl Optional[Literal[0, 1]]

Switch for numerical solution of bottom flux.

  • 0 - Explicit solution (choose always when SHAPE < 1.0);
  • 1 - Implicit solution.
swqhbot Optional[Literal[1, 2]]

Specify whether an exponential relation or a table is used.

  • 1 - bottom flux is calculated with an exponential relation
  • 2 - bottom flux is derived from a table
bbcfil Optional[String]

Name of file with bottom boundary data (without .BBC extension).

sinave Optional[Decimal2f]

Average value of bottom flux.

sinamp Optional[Decimal2f]

Amplitude of bottom flux sine function.

sinmax Optional[Decimal2f]

Time of the year with maximum bottom flux.

shape Optional[Decimal2f]

Shape factor to derive average groundwater level.

hdrain Optional[Decimal2f]

Mean drain base to correct for average groundwater level.

rimlay Optional[Decimal2f]

Vertical resistance of aquitard.

aqave Optional[Decimal2f]

Average hydraulic head in underlaying aquifer.

aqamp Optional[Decimal2f]

Amplitude hydraulic head sinus wave.

aqtmax Optional[Decimal2f]

First time of the year with maximum hydraulic head.

aqper Optional[Decimal2f]

Period of hydraulic head sinus wave.

cofqha Optional[Decimal2f]

Coefficient A for exponential relation for bottom flux.

cofqhb Optional[Decimal2f]

Coefficient B for exponential relation for bottom flux.

cofqhc Optional[Decimal2f]

Coefficient C for exponential relation for bottom flux.

gwlevel Optional[Table]

Table with groundwater level data.

qbot Optional[Table]

Table with bottom flux data.

haquif Optional[Table]

Table with average pressure head in underlaying aquifer.

qbot4 Optional[Table]

Table with bottom flux data.

qtab Optional[Table]

Table with groundwater level-bottom flux relation.

hbot5 Optional[Table]

Table with the bottom compartment pressure head.

Source code in pyswap/components/boundary.py
class BottomBoundary(
    _PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin, _FileMixin
):
    """Bottom boundary settings.

    Technically in SWAP boundary conditions can be specified either inside the
    .swp file or in a separate .bbc file. The `swbbcfile` attribute determines
    whether the boundary conditions are written to a .bbc file.

    Attributes:
        swbbcfile (Optional[Literal[0, 1]]): Specify boundary conditions in
            current file (0) or in a separate .bbc file (1). The preferred is to
            define the boundary conditions in the .swp file. bbcfil might become
            deprecated in the future.

        swbotb (Optional[Literal[1, 2, 3, 4, 5, 6, 7, 8]]): Switch for type of
            bottom boundary.

            * 1 - prescribe groundwater level;
            * 2 - prescribe bottom flux;
            * 3 - calculate bottom flux from hydraulic head of deep aquifer;
            * 4 - calculate bottom flux as function of groundwater level;
            * 5 - prescribe soil water pressure head of bottom compartment;
            * 6 - bottom flux equals zero;
            * 7 - free drainage of soil profile;
            * 8 - free outflow at soil-air interface.

        sw2 (Optional[Literal[1, 2]]): Specify whether a sinus function or
            a table are used for the bottom flux.

            * 1 - sinus function;
            * 2 - table.

        sw3 (Optional[Literal[1, 2]]): Specify whether a sinus function or
            a table are used for the hydraulic head in the deep aquifer.

            * 1 - sinus function;
            * 2 - table.

        sw4 (Optional[Literal[0, 1]]): An extra groundwater flux can be
            specified which is added to above specified flux.

            * 0 - no extra flux;
            * 1 - extra flux.

        swbotb3resvert (Optional[Literal[0, 1]]): Switch for vertical
            hydraulic resistance between bottom boundary and groundwater level.

            * 0 - Include vertical hydraulic resistance
            * 1 - Suppress vertical hydraulic resistance

        swbotb3impl (Optional[Literal[0, 1]]): Switch for numerical solution
            of bottom flux.

            * 0 - Explicit solution (choose always when SHAPE < 1.0);
            * 1 - Implicit solution.

        swqhbot (Optional[Literal[1, 2]]): Specify whether an exponential
            relation or a table is used.

            * 1 - bottom flux is calculated with an exponential relation
            * 2 - bottom flux is derived from a table

        bbcfil (Optional[String]): Name of file with bottom boundary data
            (without .BBC extension).
        sinave (Optional[Decimal2f]): Average value of bottom flux.
        sinamp (Optional[Decimal2f]): Amplitude of bottom flux sine function.
        sinmax (Optional[Decimal2f]): Time of the year with maximum bottom flux.
        shape (Optional[Decimal2f]): Shape factor to derive average groundwater
            level.
        hdrain (Optional[Decimal2f]): Mean drain base to correct for average
            groundwater level.
        rimlay (Optional[Decimal2f]): Vertical resistance of aquitard.
        aqave (Optional[Decimal2f]): Average hydraulic head in underlaying
            aquifer.
        aqamp (Optional[Decimal2f]): Amplitude hydraulic head sinus wave.
        aqtmax (Optional[Decimal2f]): First time of the year with maximum
            hydraulic head.
        aqper (Optional[Decimal2f]): Period of hydraulic head sinus wave.
        cofqha (Optional[Decimal2f]): Coefficient A for exponential relation for
            bottom flux.
        cofqhb (Optional[Decimal2f]): Coefficient B for exponential relation for
            bottom flux.
        cofqhc (Optional[Decimal2f]): Coefficient C for exponential relation for
            bottom flux.
        gwlevel (Optional[Table]): Table with groundwater level data.
        qbot (Optional[Table]): Table with bottom flux data.
        haquif (Optional[Table]): Table with average pressure head in
            underlaying aquifer.
        qbot4 (Optional[Table]): Table with bottom flux data.
        qtab (Optional[Table]): Table with groundwater level-bottom
            flux relation.
        hbot5 (Optional[Table]): Table with the bottom compartment
            pressure head.
    """

    _extension = _PrivateAttr(default="bbc")

    swbbcfile: _Literal[0, 1] | None = None
    bbcfil: _String | None = None
    swbotb: _Literal[1, 2, 3, 4, 5, 6, 7, 8] | None = None
    sw2: _Literal[1, 2] | None = None
    sw4: _Literal[0, 1] | None = None
    swbotb3resvert: _Literal[0, 1] | None = None
    swbotb3impl: _Literal[0, 1] | None = None
    swqhbot: _Literal[1, 2] | None = None
    sinave: _Decimal2f | None = _Field(ge=-10.0, le=10.0, default=None)
    sinamp: _Decimal2f | None = _Field(ge=-10.0, le=10.0, default=None)
    sinmax: _Decimal2f | None = _Field(**_YEARRANGE, default=None)
    shape: _Decimal2f | None = _Field(**_UNITRANGE, default=None)
    hdrain: _Decimal2f | None = _Field(ge=-10000.0, le=0.0, default=None)
    rimlay: _Decimal2f | None = _Field(ge=0, le=100000.0, default=None)
    aqave: _Decimal2f | None = _Field(ge=-10000, le=1000, default=None)
    aqamp: _Decimal2f | None = _Field(ge=0, le=1000.0, default=None)
    aqtmax: _Decimal2f | None = _Field(**_YEARRANGE, default=None)
    aqper: _Decimal2f | None = _Field(**_YEARRANGE, default=None)
    cofqha: _Decimal2f | None = _Field(ge=-100.0, le=100.0, default=None)
    cofqhb: _Decimal2f | None = _Field(ge=-1.0, le=1.0, default=None)
    cofqhc: _Decimal2f | None = _Field(ge=-10.0, le=10.0, default=None)
    gwlevel: _Table | None = None
    qbot: _Table | None = None
    haquif: _Table | None = None
    qbot4: _Table | None = None
    qtab: _Table | None = None
    hbot5: _Table | None = None

    def bbc(self) -> str:
        """Return the string representing the bbc file."""
        return self._model_string(exclude={"swbbcfile", "bbcfil"})

    def _model_string(self, **kwargs) -> str:
        """Internal method to handle model string generation.

        This was implemented to avoid pydantic from raising a maximum recursion
        depth error when calling the model_string method from the super class.
        """
        return super().model_string(**kwargs)

    def model_string(self, **kwargs) -> str:
        """Override model_string method to handle the swbbcfile attribute.

        This method is called in the final serialization step, when each section
        is converted into a string representation. So, depending on the
        swbbcfile attribute, this function will return:

            - a full section string representation, as for when all boundary
                conditions are included in the .swp file, or;
            - it will only include swbbcfile and bbcfil (the name of the file
                when the other parameters are defined). In that case, the other
                parameters are written to a separate .bbc file using the
                write_bbc method.
        """
        if self.swbbcfile == 1:
            return super().model_string(include={"swbbcfile", "bbcfil"}, **kwargs)
        else:
            return super().model_string()

    def write_bbc(self, path: _Path):
        """Write bottom boundary conditions to a .bbc file.

        This method is only available when the swbbcfile attribute is set to 1.
        Writes entire setion settings (except swbbcfile and bbcfil, defined in
        the .swp file) to a separate .bbc file.

        Parameters:
            path (Path): Path to the directory where the .bbc file will be
                saved.
        """
        if self.swbbcfile != 1:
            msg = "Bottom boundary conditions are not set to be written to a .bbc file."
            raise ValueError(msg)

        self.save_file(string=self.bbc(), fname=self.bbcfil, path=path)

bbc()

Return the string representing the bbc file.

Source code in pyswap/components/boundary.py
def bbc(self) -> str:
    """Return the string representing the bbc file."""
    return self._model_string(exclude={"swbbcfile", "bbcfil"})

model_string(**kwargs)

Override model_string method to handle the swbbcfile attribute.

This method is called in the final serialization step, when each section is converted into a string representation. So, depending on the swbbcfile attribute, this function will return:

- a full section string representation, as for when all boundary
    conditions are included in the .swp file, or;
- it will only include swbbcfile and bbcfil (the name of the file
    when the other parameters are defined). In that case, the other
    parameters are written to a separate .bbc file using the
    write_bbc method.
Source code in pyswap/components/boundary.py
def model_string(self, **kwargs) -> str:
    """Override model_string method to handle the swbbcfile attribute.

    This method is called in the final serialization step, when each section
    is converted into a string representation. So, depending on the
    swbbcfile attribute, this function will return:

        - a full section string representation, as for when all boundary
            conditions are included in the .swp file, or;
        - it will only include swbbcfile and bbcfil (the name of the file
            when the other parameters are defined). In that case, the other
            parameters are written to a separate .bbc file using the
            write_bbc method.
    """
    if self.swbbcfile == 1:
        return super().model_string(include={"swbbcfile", "bbcfil"}, **kwargs)
    else:
        return super().model_string()

write_bbc(path)

Write bottom boundary conditions to a .bbc file.

This method is only available when the swbbcfile attribute is set to 1. Writes entire setion settings (except swbbcfile and bbcfil, defined in the .swp file) to a separate .bbc file.

Parameters:

Name Type Description Default
path Path

Path to the directory where the .bbc file will be saved.

required
Source code in pyswap/components/boundary.py
def write_bbc(self, path: _Path):
    """Write bottom boundary conditions to a .bbc file.

    This method is only available when the swbbcfile attribute is set to 1.
    Writes entire setion settings (except swbbcfile and bbcfil, defined in
    the .swp file) to a separate .bbc file.

    Parameters:
        path (Path): Path to the directory where the .bbc file will be
            saved.
    """
    if self.swbbcfile != 1:
        msg = "Bottom boundary conditions are not set to be written to a .bbc file."
        raise ValueError(msg)

    self.save_file(string=self.bbc(), fname=self.bbcfil, path=path)

Transport

HeatFlow

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Heat flow settings for SWAP simulation.

Attributes:

Name Type Description
swhea Literal[0, 1]

Switch for heat flow.

swcalt Optional[Literal[1, 2]]
  • 1 - analytical method
  • 2 - numerical method
tampli Optional[Decimal2f]

Amplitude of annual temperature wave at soil surface [0..50 oC, R]

tmean Optional[Decimal2f]

Mean annual temperature at soil surface [-10..30 oC, R]

timref Optional[Decimal2f]

Time at which the sinus temperature wave reaches its top [0..366.0 d, R]

ddamp Optional[Decimal2f]

Damping depth of soil temperature wave [1..500 cm, R]

swtopbhea Optional[Literal[1, 2]]

Define top boundary condition * 1 - use air temperature of meteo input file as top boundary * 2 - use measured top soil temperature as top boundary

tsoilfile Optional[str]

Name of input file with soil surface temperatures without extension .TSS

swbotbhea Optional[Literal[1, 2]]

Define bottom boundary condition * 1 - no heat flux * 2 - prescribe bottom temperature

soiltextures Optional[Table]

For each physical soil layer the soil texture (g/g mineral parts) and the organic matter content (g/g dry soil)

initsoil Optional[Table]

Initial temperature TSOIL [-50..50 oC, R] as function of soil depth ZH [-100000..0 cm, R]

bbctsoil Optional[Table]

Bottom boundary temperature TBOT [-50..50 oC, R] as function of date DATET [date]

Source code in pyswap/components/transport.py
class HeatFlow(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Heat flow settings for SWAP simulation.

    Attributes:
        swhea (Literal[0, 1]): Switch for heat flow.
        swcalt (Optional[Literal[1, 2]]):
            * 1 - analytical method
            * 2 - numerical method
        tampli (Optional[Decimal2f]): Amplitude of annual temperature wave at soil surface [0..50 oC, R]
        tmean (Optional[Decimal2f]): Mean annual temperature at soil surface [-10..30 oC, R]
        timref (Optional[Decimal2f]): Time at which the sinus temperature wave reaches its top [0..366.0 d, R]
        ddamp (Optional[Decimal2f]): Damping depth of soil temperature wave [1..500 cm, R]
        swtopbhea (Optional[Literal[1, 2]]): Define top boundary condition
            * 1 - use air temperature of meteo input file as top boundary
            * 2 - use measured top soil temperature as top boundary
        tsoilfile (Optional[str]): Name of input file with soil surface temperatures without extension .TSS
        swbotbhea (Optional[Literal[1, 2]]): Define bottom boundary condition
            * 1 - no heat flux
            * 2 - prescribe bottom temperature
        soiltextures (Optional[Table]): For each physical soil layer the soil texture (g/g mineral parts) and the organic matter content (g/g dry soil)
        initsoil (Optional[Table]): Initial temperature TSOIL [-50..50 oC, R] as function of soil depth ZH [-100000..0 cm, R]
        bbctsoil (Optional[Table]): Bottom boundary temperature TBOT [-50..50 oC, R] as function of date DATET [date]
    """

    swhea: _Literal[0, 1] | None = None
    swcalt: _Literal[1, 2] | None = None
    tampli: _Decimal2f | None = _Field(None, ge=0, le=50)
    tmean: _Decimal2f | None = _Field(None, ge=-10, le=30)
    timref: _Decimal2f | None = _Field(None, **_YEARRANGE)
    ddamp: _Decimal2f | None = _Field(None, ge=1, le=500)
    swtopbhea: _Literal[1, 2] | None = None
    tsoilfile: _String | None = None
    swbotbhea: _Literal[1, 2] | None = None
    soiltextures: _Table | None = None
    initsoiltemp: _Table | None = None
    bbctsoil: _Table | None = None

INITSOILTEMP

Bases: BaseTableModel

Table for initial soil temperature.

Attributes:

Name Type Description
ZH float

Depth of soil layer [cm, R]

TSOIL float

Initial temperature [oC, R]

Source code in pyswap/components/tables.py
class INITSOILTEMP(BaseTableModel):
    """Table for initial soil temperature.

    Attributes:
        ZH (float): Depth of soil layer [cm, R]
        TSOIL (float): Initial temperature [oC, R]
    """

    ZH: float = pa.Field(ge=-100000, le=0)
    TSOIL: float = pa.Field(ge=-50, le=50)

SOILTEXTURES

Bases: BaseTableModel

Table for soil textures.

Attributes:

Name Type Description
PSAND float

Depth of soil layer [cm, R]

PSILT float

Sand content [g/g mineral parts, R]

PCLAY float

Clay content [g/g mineral parts, R]

ORGMAT float

Organic matter content [g/g dry soil, R]

Source code in pyswap/components/tables.py
class SOILTEXTURES(BaseTableModel):
    """Table for soil textures.

    Attributes:
        PSAND (float): Depth of soil layer [cm, R]
        PSILT (float): Sand content [g/g mineral parts, R]
        PCLAY (float): Clay content [g/g mineral parts, R]
        ORGMAT (float): Organic matter content [g/g dry soil, R]
    """

    PSAND: float
    PSILT: float
    PCLAY: float
    ORGMAT: float

SoluteTransport

Bases: PySWAPBaseModel, SerializableMixin, YAMLValidatorMixin

Solute transport settings.

Attributes:

swsolu (Literal[0, 1]): Switch for simulation of solute transport.
cpre (Optional[Decimal2f]): Solute concentration in precipitation [0..100 mg/cm3].
cdrain (Optional[Decimal2f]): Solute concentration in surface water [0..100 mg/cm3].
swbotbc (Optional[Literal[0, 1, 2]]): Switch for groundwater concentration in case of upward flow (seepage).
cseep (Optional[Decimal2f]): Solute concentration in surface water [0..100 mg/cm3].
ddif (Optional[Decimal2f]): Molecular diffusion coefficient [0..10 cm2/d].
tscf (Optional[Decimal2f]): Relative uptake of solutes by roots [0..10].
swsp (Optional[Literal[0, 1]]): Switch, consider solute adsorption.
frexp (Optional[Decimal2f]): Freundlich exponent [0..10].
cref (Optional[Decimal2f]): Reference solute concentration for adsorption [0..1000 mg/cm3].
swdc (Optional[Literal[0, 1]]): Switch, consider solute decomposition.
gampar (Optional[Decimal2f]): Factor reduction decomposition due to temperature [0..0.5 /C].
rtheta (Optional[Decimal2f]): Minimum water content for potential decomposition [0..0.4 cm3/cm3].
bexp (Optional[Decimal2f]): Exponent in reduction decomposition due to dryness [0..2].
swbr (Optional[Literal[0, 1]]): Switch, consider mixed reservoir of saturated zone.
daquif (Optional[Decimal2f]): Thickness saturated part of aquifer [0..10000 cm].
poros (Optional[Decimal2f]): Porosity of aquifer [0..0.6].
kfsat (Optional[Decimal2f]): Linear adsorption coefficient in aquifer [0..100 cm3/mg].
decsat (Optional[Decimal2f]): Decomposition rate in aquifer [0..10 /d].
cdraini (Optional[Decimal2f]): Initial solute concentration in groundwater [0..100 mg/cm3].
cseeparrtb (Optional[Table]): Table for groundwater concentration as function of time.
inissoil (Optional[Table]): Table for initial solute concentration as function of soil depth.
miscellaneous (Optional[Table]): Table for miscellaneous parameters as function of soil depth.
Source code in pyswap/components/transport.py
class SoluteTransport(_PySWAPBaseModel, _SerializableMixin, _YAMLValidatorMixin):
    """Solute transport settings.

    Attributes:

        swsolu (Literal[0, 1]): Switch for simulation of solute transport.
        cpre (Optional[Decimal2f]): Solute concentration in precipitation [0..100 mg/cm3].
        cdrain (Optional[Decimal2f]): Solute concentration in surface water [0..100 mg/cm3].
        swbotbc (Optional[Literal[0, 1, 2]]): Switch for groundwater concentration in case of upward flow (seepage).
        cseep (Optional[Decimal2f]): Solute concentration in surface water [0..100 mg/cm3].
        ddif (Optional[Decimal2f]): Molecular diffusion coefficient [0..10 cm2/d].
        tscf (Optional[Decimal2f]): Relative uptake of solutes by roots [0..10].
        swsp (Optional[Literal[0, 1]]): Switch, consider solute adsorption.
        frexp (Optional[Decimal2f]): Freundlich exponent [0..10].
        cref (Optional[Decimal2f]): Reference solute concentration for adsorption [0..1000 mg/cm3].
        swdc (Optional[Literal[0, 1]]): Switch, consider solute decomposition.
        gampar (Optional[Decimal2f]): Factor reduction decomposition due to temperature [0..0.5 /C].
        rtheta (Optional[Decimal2f]): Minimum water content for potential decomposition [0..0.4 cm3/cm3].
        bexp (Optional[Decimal2f]): Exponent in reduction decomposition due to dryness [0..2].
        swbr (Optional[Literal[0, 1]]): Switch, consider mixed reservoir of saturated zone.
        daquif (Optional[Decimal2f]): Thickness saturated part of aquifer [0..10000 cm].
        poros (Optional[Decimal2f]): Porosity of aquifer [0..0.6].
        kfsat (Optional[Decimal2f]): Linear adsorption coefficient in aquifer [0..100 cm3/mg].
        decsat (Optional[Decimal2f]): Decomposition rate in aquifer [0..10 /d].
        cdraini (Optional[Decimal2f]): Initial solute concentration in groundwater [0..100 mg/cm3].
        cseeparrtb (Optional[Table]): Table for groundwater concentration as function of time.
        inissoil (Optional[Table]): Table for initial solute concentration as function of soil depth.
        miscellaneous (Optional[Table]): Table for miscellaneous parameters as function of soil depth.
    """

    swsolu: _Literal[0, 1] | None = None
    cpre: _Decimal2f | None = _Field(None, ge=0, le=100)
    cdrain: _Decimal2f | None = _Field(None, ge=0, le=100)
    swbotbc: _Literal[0, 1, 2] | None = None
    cseep: _Decimal2f | None = _Field(None, ge=0, le=100)
    ddif: _Decimal2f | None = _Field(None, ge=0, le=10)
    tscf: _Decimal2f | None = _Field(None, ge=0, le=10)
    swsp: _Literal[0, 1] | None = None
    frexp: _Decimal2f | None = _Field(None, ge=0, le=10)
    cref: _Decimal2f | None = _Field(None, ge=0, le=1000)
    swdc: _Literal[0, 1] | None = None
    gampar: _Decimal2f | None = _Field(None, ge=0, le=0.5)
    rtheta: _Decimal2f | None = _Field(None, ge=0, le=0.4)
    bexp: _Decimal2f | None = _Field(None, ge=0, le=2)
    swbr: _Literal[0, 1] | None = None
    daquif: _Decimal2f | None = _Field(None, ge=0, le=10000)
    poros: _Decimal2f | None = _Field(None, ge=0, le=0.6)
    kfsat: _Decimal2f | None = _Field(None, ge=0, le=100)
    decsat: _Decimal2f | None = _Field(None, ge=0, le=10)
    cdraini: _Decimal2f | None = _Field(None, ge=0, le=100)
    cseeparrtb: _Table | None = None
    inissoil: _Table | None = None
    misc: _Table | None = None

Database

Plot

Plotting functionality for pySWAP.

Plotting of results depends heavily on the application of the model. Therefore, in this module, I only inclduded a few examples of how to plot results for specific cases.

Modules:

Name Description
evapotranspiration

Functions for plotting evapotranspiration data.

watercontent

Functions for plotting water content data as heat map.

water_content(df, depth_col, date_col, wcontent_col, title='Water content')

Plot water content as heatmap.

For this function to work, the user should either use the vap output converted to a dataframe, or make sure that in the csv_tz output they provide, only the water content data is present.

Parameters:

Name Type Description Default
df DataFrame

DataFrame containing the water content data

required
depth_col str

Column name for depth data

required
date_col str

Column name for date data

required
wcontent_col str

Column name for water content data

required
title str

Title of the plot. Defaults to 'Water content'.

'Water content'
Source code in pyswap/core/plot/watercontent.py
def water_content(
    df: pd.DataFrame,
    depth_col: str,
    date_col: str,
    wcontent_col: str,
    title: str = "Water content",
):
    """Plot water content as heatmap.

    For this function to work, the user should either use the `vap` output
    converted to a dataframe, or make sure that in the csv_tz output they
    provide, only the water content data is present.

    Parameters:
        df (pd.DataFrame): DataFrame containing the water content data
        depth_col (str): Column name for depth data
        date_col (str): Column name for date data
        wcontent_col (str): Column name for water content data
        title (str, optional): Title of the plot. Defaults to 'Water content'.
    """

    sns.set_context("poster")

    df_wcont = df[[depth_col, date_col, wcontent_col]]

    df_wcont.loc[:, date_col] = pd.to_datetime(df_wcont[date_col])
    df_wcont.loc[:, depth_col] = df_wcont[depth_col].astype(float)
    df_wcont.loc[:, wcontent_col] = df_wcont[wcontent_col].astype(float)

    pivot_table = df_wcont.pivot(columns=date_col, index=depth_col, values=wcontent_col)
    pivot_table = pivot_table.sort_index(axis=1)

    plt.figure(figsize=(34, 8))
    sns.heatmap(pivot_table, cmap="YlGnBu")
    plt.title(title)
    plt.xlabel("Date")
    plt.ylabel("Depth (cm)")

    plt.gca().invert_yaxis()

    plt.xticks(rotation=45)

    format_months = lambda x, p: pivot_table.columns[int(x)].strftime("%Y-%m")
    plt.gca().xaxis.set_major_formatter(plt.FuncFormatter(format_months))

evapotranspiration

Plot evapotranspiration (potential vs actual) and compute the RMSE.

evapotranspiration(potential, actual, title='Evapotranspiration')

Plot evapotranspiration (potential vs actual) and compute the RMSE.

Paremeters

potential (DataFrame): DataFrame containing dates and values for potential evapotranspiration. actual (DataFrame): DataFrame containing dates and values for actual evapotranspiration. title (str, optional): Title of the plot. Defaults to 'Evapotranspiration'.

Source code in pyswap/core/plot/evapotranspiration.py
def evapotranspiration(
    potential: DataFrame, actual: DataFrame, title: str = "Evapotranspiration"
):
    """Plot evapotranspiration (potential vs actual) and compute the RMSE.

    Paremeters:
        potential (DataFrame): DataFrame containing dates and values for potential evapotranspiration.
        actual (DataFrame): DataFrame containing dates and values for actual evapotranspiration.
        title (str, optional): Title of the plot. Defaults to 'Evapotranspiration'.
    """

    sns.set_context("poster")

    fig, ax = plt.subplots(figsize=(34, 8))
    sns.lineplot(data=potential, ax=ax, label="Potential", color="black", linewidth=1)
    sns.lineplot(
        data=actual, ax=ax, label="Actual", color="orange", linewidth=1, linestyle="--"
    )

    ax.set_title(title, pad=20)
    ax.set_xlabel("Date")
    ax.set_ylabel("Evapotranspiration")

    ax.tick_params(axis="x", rotation=45)
    ax.legend()
    plt.tight_layout()
    plt.show()

watercontent

Functions:

Name Description
water_content

Plot water content as heatmap.

water_content(df, depth_col, date_col, wcontent_col, title='Water content')

Plot water content as heatmap.

For this function to work, the user should either use the vap output converted to a dataframe, or make sure that in the csv_tz output they provide, only the water content data is present.

Parameters:

Name Type Description Default
df DataFrame

DataFrame containing the water content data

required
depth_col str

Column name for depth data

required
date_col str

Column name for date data

required
wcontent_col str

Column name for water content data

required
title str

Title of the plot. Defaults to 'Water content'.

'Water content'
Source code in pyswap/core/plot/watercontent.py
def water_content(
    df: pd.DataFrame,
    depth_col: str,
    date_col: str,
    wcontent_col: str,
    title: str = "Water content",
):
    """Plot water content as heatmap.

    For this function to work, the user should either use the `vap` output
    converted to a dataframe, or make sure that in the csv_tz output they
    provide, only the water content data is present.

    Parameters:
        df (pd.DataFrame): DataFrame containing the water content data
        depth_col (str): Column name for depth data
        date_col (str): Column name for date data
        wcontent_col (str): Column name for water content data
        title (str, optional): Title of the plot. Defaults to 'Water content'.
    """

    sns.set_context("poster")

    df_wcont = df[[depth_col, date_col, wcontent_col]]

    df_wcont.loc[:, date_col] = pd.to_datetime(df_wcont[date_col])
    df_wcont.loc[:, depth_col] = df_wcont[depth_col].astype(float)
    df_wcont.loc[:, wcontent_col] = df_wcont[wcontent_col].astype(float)

    pivot_table = df_wcont.pivot(columns=date_col, index=depth_col, values=wcontent_col)
    pivot_table = pivot_table.sort_index(axis=1)

    plt.figure(figsize=(34, 8))
    sns.heatmap(pivot_table, cmap="YlGnBu")
    plt.title(title)
    plt.xlabel("Date")
    plt.ylabel("Depth (cm)")

    plt.gca().invert_yaxis()

    plt.xticks(rotation=45)

    format_months = lambda x, p: pivot_table.columns[int(x)].strftime("%Y-%m")
    plt.gca().xaxis.set_major_formatter(plt.FuncFormatter(format_months))