Jython
By default, RiskScape will execute your Python function using the Java-based implementation, called Jython.
Alternatively, you can setup RiskScape to use CPython. You can also mix and match, and use CPython for some functions and Jython for other functions.
This page describes some of the behaviour specific to Jython in more detail.
Calling other RiskScape functions
You can call other user-defined Jython functions from your function, as well as some built-in RiskScape functions.
For example, we could call our hello
function from the hello world example from another different function:
# basic syntax is: functions.get(<function-name>).call(<arguments>)
greeting = functions.get('hello').call('Kia ora', 'Ronnie')
Note that currently this has the following limitations:
The types of the arguments must match exactly, e.g. you cannot pass an integer to something that expects a floating argument.
You must not omit any optional arguments.
Built-in RiskScape functions that support a wide range of argument-types (i.e. functions that accept or return the type
Anything
) are not supported.
Jython packages
If you have used Python (or more specifically, CPython) in the past, you may notice that Jython is a little different, in particular when importing and using packages.
For example, generating a random number between zero and one would usually look like the following in CPython.
import random
num = random.uniform(0, 1.0)
Whereas in Jython, it would look like this:
from java.util import Random
random = Random()
num = random.nextDouble()
Note
We recommend you call the built-in RiskScape functions where possible, rather than importing Jython packages.
For example, to achieve the same thing using the built-in RiskScape function:
num = functions.get('random_uniform').call(0.0, 1.0)
Tip
In general, once you start needing to import Python packages, it will be simpler to switch from using Jython to using CPython.
Basic loss function
Now let’s look at a more complicated example.
The below Python code (quake.py
) is an example of a basic loss function.
def function(building, hazard):
loss = {}
loss['replacement'] = building['replace']
loss['hazard'] = hazard
construction = building['construct']
if hazard is None:
loss['dr'] = 0
loss['loss'] = 0
else:
loss['dr'] = damage_function(construction, hazard)
loss['loss'] = loss['replacement'] * loss['dr']
return loss
CONSTRUCT_WOOD = 1
def damage_function(construction, hazard):
if construction == CONSTRUCT_WOOD:
mean = 0.22
stddev = 0.74
else:
mean = 0.92
stddev = 0.64
# call the built-in 'lognorm_cdf' riskscape function
return functions.get('lognorm_cdf').call(hazard, mean, stddev)
This function demonstrates many points we have already covered, such as:
The
building
argument is astruct
, and contains two attributes that we are interested in: construction type and replacement value. Note that the actual building input data file might contain many more attributes, but our function only cares about two of them.The
hazard
argument is nullable, i.e. it may beNone
.We call the builtin RiskScape function
lognorm_cdf
to calculate the cumulative log normal distribution.The return value is a
struct
, which we build up as a Python dictionary.
The INI file definition for this function might look like this:
[function quake]
description = Example loss function
location = quake.py
argument-types = [ building, hazard: nullable(floating) ]
return-type = shaking_result
[type building]
type.replace = integer
type.construct = integer
[type shaking_result]
type.hazard = nullable(floating)
type.loss = floating
type.dr = floating
type.replacement = integer
We have defined the building
argument and return-value
as separate types here, for clarity.
Older behaviour
If you have used older RiskScape releases, this next section covers some of the differences you might notice with Jython functions.
Function parameters
In previous releases, RiskScape used to support a special PARAMETERS
keyword for Jython functions.
These parameters were helpful if your function made certain assumptions when determining the consequence
for a given exposure and hazard - you could then vary these assumptions between model runs.
The function parameters applied across all exposure and hazard input data.
The PARAMETERS
keyword is no longer supported for Jython.
Instead, you can use model parameters to pass assumptions to your function,
and to vary these assumptions between model runs.
Defining argument/return types inline
An older approach used to define the function ID
, ARGUMENT_TYPES
, and RETURN_TYPE
inline in the
Python code, rather than in the INI file. This is still supported in the meantime for backwards compatibility.
If you are using this approach, Jython type usage has more examples of using types within a Python function.