# Tutorial¶

The tutorial gives a short introduction into the usage of the arrayed variables in Python.

## Importing the module¶

To use the arrayed variables in your Python script use:

from PCRaster.Collection import *


## Creating collection index types¶

In oldcalc, index types are created as follows:

# oldcalc
PlantSpecies = [
Species1,
Species2,
Species3];


In Python, an index type is created as:

# Python
PlantSpecies = Index(["Species1", "Species2"])


The indices are given as a list of names.

## Creating variable collections¶

In oldcalc, arrayed variables are created as follows:

# oldcalc
Variable1[Species1] = ...;
Variable1[Species2] = ...;


In Python, you create a variable collection object by using the index types:

# Python
PlantSpecies = Index(["Species1", "Species2"])
Variable1 = VariableCollection([PlantSpecies], value=None)


This will initialise the indices with the default value None. Afterwards, you can assign values as:

Variable1[PlantSpecies.Species1] = ...
Variable1[PlantSpecies.Species2] = ...


As an alternative, you can use an external parameter file to initialise the values (collection values not specified in the external file will be set to the default value None) like:

# Python
Variable1 = VariableCollection([PlantSpecies], value=ValueFromParameterTable("Variable1", "values.tbl", dataType=Scalar))


where Variable1 is the name of the collection variable referred to in the external file, values.tbl the filename of the external file and Scalar the PCRaster data type of the collection. In case of initialising collection indices with PCRaster field objects, i.e. reading maps from disk, set the dataType argument to None.

### Creating multidimensional collections¶

Multidimensional collections are created in a similar way as one-dimensional arrays:

# Python
PlantSpecies = Index(["Plant1", "Plant2"])
Herbivores = Index(["Species1", "Species2", "Species3"])

Interaction = VariableCollection([Herbivores, PlantSpecies], value=None)


This will create a variable Interaction holding a 2-dimensional collection. You can set values like:

Interaction[Herbivores.Species1, PlantSpecies.Plant1] = scalar(2.5)
# repeat initialisation for the remaining Herbivore-PlantSpecies combinations


Again, the variable can be initialised from a parameter file insetead:

Interaction = VariableCollection([Herbivores, PlantSpecies], value=ValueFromParameterTable("Interaction", "interaction.tbl", dataType=Scalar))


The parameter file looks similar to:

#interaction.tbl
Interaction  Species1 Plant1 0.2
Interaction  Species1 Plant2 0.35
Interaction  Species2 Plant1 0.33
Interaction  Species2 Plant2 0.35
Interaction  Species3 Plant1 0.4
Interaction  Species3 Plant2 0.5

## Iterating over the collection¶

While in oldcalc a foreach construct iterates over the array:

# oldcalc
foreach species in PlantSpecies {
Variable1[species] = ...;
Variable2[species] = ...;
}

In Python there are two options to iterate over the collection. First, you can use the for in construct and iterate over the index types:

for species in PlantSpecies:
Variable1[species] = ...
Variable2[species] = ...


Iterating over multidimensional collections can be done with nested for in statements:

for herb in Herbivores:
for plant in Plants:
Interaction[herb, plant] = ...


As a second option you can iterate over the collection:

for herb, plant in Interaction:
Interaction[herb, plant] = ...


### Using None values in a collection¶

Not necessarily all values in a collection need to be specified. E.g. in our Herbivore-PlantSpecies interaction example, some interactions between species do not appear. If so, you can assign None to that variable:

Interaction[Herbivores.Species3, PlantSpecies.Plant2] = None


When iterating over index types, it is now required to test if values are set:

for herb in Herbivores:
for plant in Plants:
if not Interaction[herb, plant] is None:
Interaction[herb, plant] = ...


The collection iterator only operates on values being not None, therefore it is not necessary to change the code:

for herb, plant in Interaction:
Interaction[herb, plant] = ...


## Reporting timeseries¶

To report timeseries for each collection index the variable collection class needs to be initialised with the ValueTimeoutputTimeseries class:

InteractionTss = VariableCollection([Herbivores, PlantSpecies], value=ValueTimeoutputTimeseries("Interaction", self, idMap="locations.map", noHeader=False)))

Afterwards you can sample values for each collection index:

for herb, plant in Interaction:
InteractionTss[herb, plant].sample(Interaction[herb, plant])


The resulting output files will be named like Interaction-Species3-Plant2.tss.

## Linking variable names to external names¶

In the case you want to use variable names in your model script different from the ones in the parameter files you can link those external names to variable names while you initialise the Index class:

Herbs = Index(["ES=EvergreenShrub", "SPG=ShortPerennialGrass", "Cal=Calluna"])
GrowthFactor = VariableCollection([Herbs], value=ValueFromParameterTable("GrowthFactor", "parameterFile.tbl", Scalar))


To assign external names use the format Modelname = Externalname. Here, you create in your model script a collection variable GrowthFactor with the three indices Herbs.ES, Herbs.SPG and Herbs.Cal. In the parameter file you can refer to the external names EvergreenShrub, ShortPerennialGrass and Calluna:

GrowthFactor  EvergreenShrub       0.3
GrowthFactor  ShortPerennialGrass  0.37
GrowthFactor  Calluna              0.29