Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Note
Functions are a powerful, complex feature of Source that allow customisation of models by advanced users.

A model element's behaviour can depend on dynamic values within the model. Functions allow you to control this behaviour via an arithmetic expression. They are used in places where you might otherwise employ a time series or a single value (eg. a node's feature editor). This page provides general information about working with functions:

Table of Contents
maxLevel4

Refer to the following sub-pages for more specific information:

Anchor
FunctionsAsInput
FunctionsAsInput
Using functions as model inputs

Anchor
Element
Element
The ability to use a function as a model input is a powerful way to customise model behaviour. For the purposes of discussing functions, a model element is any part of the model that can use a function as an input instead of a data source or value. This includes:

  • Nodes
  • Links
  • Resource assessment
  • Rainfall runoff models

The ability to use a function as input is indicated in Source windows in one of two ways:

  • As a radio button. In this case, there is always the option of using a value or a data source as an input instead (Figure 1). When enabled, Function Editor will open below the radio button, embedded within the same window; or
  • As an ellipsis button. In this case, there is always the option of using a value as an input instead (Figure 1). When selected, the Function Editor will open in a new dialog.

When a function is used directly by a model element, that element is shown under the function in the function tree, see Figure 1. 

Figure 1. Using functions within a feature editor

Example use of a function

As an example, you can use a function at a Maximum Order Constraint node to limit the maximum orders for each time-step based on predicted inflow and orders. Assume that a channel constraint of 80 ML/day is required to prevent flows going overbank, except during floods (defined as more than 2,000 ML/day) when up to 3,000 ML/day is permitted as an environmental flow.

Figure 2 shows a fragment of the river network. Downstream demands are represented by a supply point and water user node. In the Function Editor, you specify the internal orders and unregulated river gain of the model using modelled variables. Maximum orders are then defined using a function.


Figure 2. Maximum Order Constraint node (example)


In this case, the following modelled variables will be assigned to these components:

  • $Orders assigned to the Requested Flow Rate of the Storage node; and

  • $predictedInflow assigned to the Inflow of the Inflow node.

Note that both variables will have a date range of Last Time Step, ML/day as designated units and Time of Evaluation as Ordering Phase.

Then, the following function will return a value of 3,000 ML/day if flows are above 2,000 ML/day but 80 ML/day otherwise.

If(($predictedinflow+$orders) > 2000, 3000, 80

Function Management

Functions can be used extensively for defining model elements in Source, as well as being used within other functions and as a stand-alone evaluation tool. This can result in a large number of functions with complex relationships being present in a model. Source has inbuilt function management capability to assist you in keeping track of your functions and variables, which should be used in conjunction with the design of a systematic approach to function organisation during the model conceptualisation process.   

Anchor
FunctionManager
FunctionManager
Function Manager

The Function Manager (Figure 3) allows you to centrally manage all functions that have been defined in Source.

The Function Manager can be accessed in one of two ways:

  • Choosing View » Function Manager; or
  • Clicking on the Function Manager icon in the Scenario toolbar.

It will then open in the main screen

Anchor
FigureFunctionManager
FigureFunctionManager
Figure 3. Function Manager


Anchor
FunctionTree
FunctionTree
Function Tree Display

The Function Manager lists the functions and variables available within the active scenario in a tree menu. Items in this function tree are:

By default, when a function is used by a model element (in an inflow node for example), that element is shown in the tree under the function (function usage, Figure 3). If a function is used by multiple elements, then all usages are shown under the function in the function tree. The lock icon next to the element's name indicates that it the element is locked to using that function as an input (Crab Creek:Inflow is locked in Figure 3). See below for more information. 

In addition to the function tree, the Function Manager contains a Search bar, in which you can enter text to filter the function tree, and the Function Manager toolbar. 

Anchor
FunctionManagerToolbar
FunctionManagerToolbar
Shown in Figure 4, the Function Manager toolbar has the following features:

  • Add New... creates a new function, or variable of the type selected.
  • Add New Folder creates a new folder in the function tree.
  • Expand All expands all items in the function tree.
  • Collapse All collapses all items in the function tree.
  • Edit Functions... opens the Function Editor.
  • Filters items shown in tree opens the drop-down Filter menu, which toggles the display in the function tree of function and variables by their type and/or their use. By default all functions and variables are shown, regardless of their type or their use. Note that selections are also affected by text entered into the Function Manager search bar. 
  • Delete all unused is only active when Unused functions and variables is selected from the Filter menu. This button deletes all unused functions and variables in the function tree that also match the current filter options and text entered into the search bar. Unused items that meet the selection criteria, folders that contain only unused items, and empty folders will also be deleted. Built-in variables and custom functions will not be deleted.

  • Show function evaluation tree opens the Function Editor and displays the function evaluation tree for the selected function. This button is only enabled when a function is selected in the function tree.

  • Show all function and variable usages displays the usages of all function and variables in the function tree.
Anchor
FigureFunctionManagerToolbar
FigureFunctionManagerToolbar
Figure 4. Function Manager Toolbar

The contextual menus (accessed by right clicking within Function Manager, Figure 3) additionally allow you to:

  • Lock All Usages in the selected folder, or in the function tree;
  • Unlock All Usages in the selected folder, or in the function tree;
  • Rename the selected item;
  • Delete the selected item; and
  • Unlock or Lock the function usage by the selected model element

Anchor
Adding a variable or function
Adding a variable or function
Adding a function or variable

Functions and variables can be added through the Function Manager or Function Editor, the latter of which may be accessed from within other Source windows, wherever a model element indicates functions are available as an input (see above). 

Follow these steps to add a variable or function using the Function Manager toolbar:

  • In the function tree select the folder where you want the function to be created. If no folder is selected, the function will be added to the root folder;
  • Click on Add New... (Figure X) and choose the appropriate drop-down item (This is synonymous to right-clicking the folder and choosing Add from the contextual menu);
  • The Function Editor will open (if it was not open already); and
  • In the Function Editor, the display on the right will depend on the type of variable or function that has been specified.

The function/variable can now be defined.

Deleting a function or variable

To delete a variable or function, choose the appropriate item in the function tree, right click, and choose Delete from the contextual menu.

Info
iconfalse
Note: Source warns you if you attempt to delete a variable that is referenced in a function.

Naming functions, variables and folders

  • The names of functions, operators, variables and folders are not case sensitive;
  • All variable and function names must begin with the "$" character, this will be added automatically.

When created, functions, variables and folders have an automatically generated name. To rename an item, either double-click on the item or right-click on it and choose Rename from the contextual menu, then type the name you wish to assign.  

Functions and variables that are in different folders can have non-unique names. When called, they will be referenced using the full path to the function (incorporating the folder name). For example, consider the setup shown in Figure 5:

  • $Function1 and $Function2 are in the same folder, so expressions can reference each other directly. So, the following is valid: if($Function2=5, 0, 1);
  • If $Function3 references $Function2, which is in a different folder, you must use the full path to reference eg. if($Folder1.Function2=5, 0, 1); and
  • Any function can reference $Function4 directly because it is not in a folder.

Info
iconfalse

Note: To avoid errors and confusion, it is recommended that you reference a function by it's full name. The syntax is $FolderName.FunctionName. Sub folders are considered unique, and are defined using both parent and sub folder names eg. $Folder2.SubFolder3.Function5 (Figure 5).

Figure 5. Function Editor, Naming Example


Moving Folders and Functions

Folders and Functions can be moved to new locations in the Function Editor by left clicking and dragging the Folder or Function to the new location. When moving Folders or Function the referencing of the Functions components will be automatically updated to reflect the new mapping.

Anchor
UsagesAndReferences
UsagesAndReferences
Usages and references

Functions and variables can be used by other functions and model elements - this is called a usage. When a function uses another function or variable during evaluation, this is called a reference. Both usages and references can be displayed in Source, see below for more information.

Usages

By default, the direct use of a function by a model element is shown in the function tree (Figure 6). To see all other usages, select the Show all Functions and Variable usages button from the toolbar. Once toggled on (indicated by a blue box around the button), three types of usages are shown underneath applicable functions and variables in the tree:

  • Usage – when a function or variable is used by another function. Multiple levels of usages (eg. nested functions) can be shown. For example, Figure 6 shows that the function $count is used by the function $Percent, which in turn is used by the function $Storage_too_dry.

  • Recursive usage – when a function references itself. For example, $count references itself (Figure 6).

  • Indirect usage by a model element – when a function or variable is used indirectly as input for a model element. For example in Figure 6, the modelled variable $ModelledVar_StorVol is used by the function $TriggerFunction, which in turn is used as input for the trigger value of the 'Storage release' minimum flow requirement node.

If a function has multiple usages, it will be run once for each usage. For example, if a function has three usages it will be run once for each of the three usages. This can have implications if e.g. a function references itself because the function will reference the most recent data in the function. As an example of this: if a function uses a modelled variable on a node (which may be updated during the flow phase), usages that are before this node executes will have "yesterdays" data, but usages that execute after this node will have "today's" data. The function executes just before each node where it is used.

Figure 6. Function Usages, example

Anchor
LockingUsages
LockingUsages
Locking and unlocking function usages

When working with a large number of functions, it is important to ensure that functions assigned to model elements are not accidentally reassigned while browsing or editing other functions. For this reason, Source has the concept of 'locking' functions to a model element, which will require you to explicitly communicate your desire to change which function is the input. If the same function is used by multiple model elements it will be locked to each element. Similar to other model elements, if a modelled time series is used by a modelled variable, it will be locked to that modelled variable, and if a data source is used by a time series variable it will be locked to that time series variable. If a function only refers to another function or variable, that function will not be locked.

Function Manager and Function Editor

All model elements that have their function usage locked are indicated in the function manager and general function editor with a closed padlock icon. Similarly, the modelled time series attached to a modelled variable will be indicated with a closed padlock icon and the data source attached to a time series variable will be indicated with a closed padlock icon. To change a locked usage, right click on the locked item and choose Unlock Usage

Locking and unlocking usages can be managed in bulk in the function manager, or one by one in the function editor, by right clicking to access the context menu.   

Function Editor accessed from within other Source windows

When you select a function as an input through another Source window (eg. a model element's feature editor) the first function you click on or add will be used and its usage locked, which is indicated by a lock icon next to the function's name in the function tree (eg. $MaxExtractionRate in Figure Y). This means that you will be able to browse the other functions and variables listed without accidentally choosing another function as the input.

To unlock a function right click and select Unlock Usage from the contextual menu. The first function you subsequently select or create will become locked.

Alternatively, while a function is still locked you can right click on another function and select Force Selection from the contextual menu, this function will become locked instead.

Info
iconfalse

Note: To disable automatic locking of functions locking, navigate to Tools » Application Settings and toggle off Enable locking by default.

It is also possible to lock or unlock functions by using the contextual menus in the Function Manager window (Figure 3).

References and the Function Evaluation Tree

Selecting a function and enabling the Show function evaluation tree button will open the Function Editor and display the function evaluation tree. This displays in a tree menu structure all other functions and variables that provide values for the selected function, either directly or indirectly. For example, when the function $Storage_too_dry is evaluated, it references the function $Percent, which in turn uses several built-in variables and the functions $StorLevel and $count, and so on down the tree (Figure 7). When $Storage_too_dry is evaluated, all the other functions and variables listed are evaluated too.

Figure 7. Function Evaluation Tree, example.

Anchor
FunctionEditor
FunctionEditor
Function Editor

The Function Editor (shown in Figure 8) allows you to create, define, modify and delete functions and variables. It can be accessed in several ways:

  • From the main screen by choosing Edit » Functions…; or
  • Choosing the edit button  in the Function Manager toolbar; or
  • Right-clicking on the function or variable in the Function Manager, and choosing Edit from the contextual menu; or
  • From within other Source windows, see Using functions as model inputs for more information. 
Anchor
FigureFunctionEditor
FigureFunctionEditor
Figure 8. Function Editor


The Function Editor is comprised of a pane on the left side, which is similar to the Function Manager. The display to the right of the function tree is specific to the item you have selected in the tree, allowing you to define the function or variable. The display for a function is shown in Figure 8, it contains the Function Editor Toolbar along with options for configuring your function. Using the display to define a function is described below, how to define variables and custom functions is described in Types of functions and variables.

Anchor
FunctionEditorFeatures
FunctionEditorFeatures
Function Editor Features

Function Editor has several features to help with writing and testing functions:

  • Built-in functions – A complete list of built-in functions and operators is provided here. You can use them to to define complex functions using simple expressions. Press Ctrl+Space to view a list of available built-in functions, eg. 'min' or 'average'. These can also be viewed by using the Insert built-in function button on the toolbar (Figure 9);
  • Drag and Drop – You can drag and drop variable and functions from the function tree into a function.
  • Text Management – Using the Function Editor toolbar, you can load and save functions in *.txt, format, perform standard text management such as copy and paste, insert built-in functions and add or edit a note (Figure 9)
  • Auto-complete  – If you enter '$', you can choose which variable or function to using the list that appears. To select an item in a list, either double click it, or navigate to it with the arrow keys and press enter. Selecting items also works for the list of built-in functions (Figure 9);
  • Syntax highlighting – Within the body of your expression, numerals, built-in functions and correctly formatted function and variable names will be coloured using standard Excel-style syntax to allow easy recognition (Figure 8).
  • Inline comments – typing /* comment text example */ will allow you to add some descriptive text within functions that will not effect the mathematical expression (Figure 8). 
  • Parser – You can test your function at any time using the in-built parser. It allows you to define values for the variables and functions within your expression, and evaluates it to allow you to determine whether a) the function is valid b) returns an expected value for the variables specified. Refer to Testing Functions for more information. 

To note:

  • To avoid errors, variables and functions used in a function must be defined;
  • White-space, including new-line markers, are ignored; and
  • A blank function returns zero.
Figure 9. Function Editor, Writing Functions

Anchor
Adding a note to a function
Adding a note to a function
Adding a note to a function

You can include a text-based message, or note, to be associated with a function. Refer to About notes for more information. Additionally, you can insert an inline comment within the body of the function's expression. 

Info
iconfalse

Note: You can add a note to a function only, variables can currently not have notes.

To associate a note with a function (as shown in Figure 5):

  • Open the Function Editor;
  • Click on the function you want to add a note to;
  • In the Function Editor toolbar, click on the Add/Edit Note icon; and
  • Add the text message in the window that appears.

Functions with notes are indicated by a note icon next to their name, if you hover your mouse over that icon, the note will display as a tooltip (Figure 5). 

Figure 10. Function Editor, Adding a note

Anchor
WritingFunctions
WritingFunctions
Writing Functions

To write or edit a function, first open the Function Editor. Either add a new function or edit an existing one, as follows:

  • Type in your function. Features of the function editor help with this, see above
  • From the Result Units drop-down menu, choose which units the function will output, these need to be commensurate with where you want to use the function (eg. choose a rate if you want to use the function as an input for the Inflow node). If the result units of the function are not the same as the required units of the model input, a conversion is done of the function result before it passes the value to the model (Figure 9).

Note that for the Boolean function and some conditional functions, such as the condition function in Resource Assessment Trigger, Result Units is not applicable and can choose use the option of no unit selected.

  • Enter an Initial Value if necessary. The initial value is used until the first evaluation of the function. This means that even on the first time step, it may not be used, depending on the chosen time of evaluation. It is often useful when a function references itself.
  • By default, if a function is not referenced at any model input, or by any other functions, it is not evaluated during a scenario run. Toggle on Force Evaluation to force a function to evaluate during a scenario run. This is generally used when you wish to record a function that is not used by a model element, or if a modelled variable points to a function that is not evaluated. Note that if you toggle this on for all functions, system performance is reduced.
  • Under Time of Evaluation, select which simulation phase you want to evaluate the function in. It is important to choose this correctly, to ensure the correct information is used at the right time. For more information, see Functions Time of Evaluation.

Constant Functions

Note that you can set a function to a constant value. If you do so, Initial Value and Time of Evaluation will have no effect. Constant functions are evaluated before all Time of Evaluation phases.

A function is considered to be constant if it:

  • has a constant expression which can be evaluated once and never change during the run (e.g. "77 + 55")
  • only references other constant functions (e.g. "42 + $OtherConstantFunction")
  • does not have Force Evaluate turned on.

If a function changes value from the Command Line Runner (with Modifying parameters) during a run or through a plugin such as the SubSource Plugin, then Force Evaluation needs to be turned on. Otherwise, the value of the function at the start of the run will be maintained for the entire model run. 

Info
titleConstant functions and Force Evaluate
  1. Any constant function is assigned its expression value at run initialisation, and not evaluated again.
  2. Any non-constant function is assigned its Initial Value at run initialisation. It is only assigned its expression value at its Time of Evaluation(s).
  3. When you turn on Force Evaluate on a constant function, it evaluates like a non-constant function - i.e. it will be assigned the Initial Value and not change again. 


Operator precedence

Unless you use parentheses to modify the order of evaluation, operations are performed according to the precedence rules shown in Table 1. Where two operators have the same level of precedence, the operations are performed left-to-right.

Table 1. Function Editor (Evaluation order)
Order of precedenceOperator symbolMeaning
1 (highest)( )explicit ordering
2-negation
3** and ^exponentiation
4

* and /

multiplication and division
5+ and -addition and subtraction
6<  <=  =  >=  >  <>comparison operators

Referencing

...