.. _ui-parameters: # Customizing the model run form This document specifies how an expert user would setup their `project.ini` file so that it's easier for non-expert users to configure and run models in the RiskScape Platform. Currently we define a parameter and its default value in the `project.ini`. Defining parameters is currently only supported for *pipeline* models. For example, to define a parameter called `perils` for model `foo`, we can use: ```ini [model foo] framework = pipeline location = foo.txt param.perils = ['EQ', 'TS', 'TC'] ``` Alternatively, you can define a *project* parameter, which will be used for *any* model that has a `perils` parameter, like this: ```ini [parameter perils] default = ['EQ', 'TS', 'TC'] ``` The difference is the `param.perils` approach is configuring a parameter for a *single* model, whereas the `[parameter perils]` approach is configuring a parameter for *all* models (where applicable). ## Labels and help descriptions By default the parameter name will be displayed in the UI. This automatically gets 'prettied' somewhat, for example a `loss-type` parameter would be displayed in the web UI as *Loss type*. To display a nicer label for a parameter in the UI, you could add something like the following line to your `project.ini` file: ```ini [parameter perils] label = Select which perils to include in the analysis. ``` You could also specify more detailed help text that would be available, e.g. ```ini [parameter perils] description = ''' Tropical Cyclone includes wind and storm surge losses produced by tropical cyclones. Earthquake includes losses from ground shaking... ''' ``` .. |help-icon| image:: ../icons/help.png This will appear as a |help-icon| help icon in the RiskScape Platform. When the user clicks on the icon, it will bring up the description as a pop-up modal. When the description spans multiple-lines you will need to use triple-quotes (e.g. `'''`) at the start and end of the description. Alternatively, you can use a `\` backslash at the end of each line, except for the last line. The `\` is a line-continuation character that is part of the standard INI file format. Yet another approach is to specify multiple `description` lines like this: ```ini [parameter perils] description = Tropical Cyclone includes wind and storm surge description = losses produced by tropical cyclones. description = Earthquake includes losses from ground shaking... ``` The description may include [Markdown](https://www.markdownguide.org/basic-syntax/). For example: ```ini [parameter use_category] description = ''' Building use category. *One* of: - Residential - Commercial [Click here](https://en.wikipedia.org/wiki/Building_occupancy_classifications) for more details. ''' ``` .. tip:: If you want to use markdown features such as bullet points, you will find it easiest to use the multi-line triple-quote approach (i.e. ``'''``) for your parameter's description. ## Properties A parameter's 'properties' gives you a flexible way to control the input fields on the UI. For example, you could use the parameter properties to hide a parameter you don't really want users to know about: ```ini [parameter return_periods] properties = hidden ``` Or you could mark the field as read-only, so users can see the setting, but cannot change the value by default. ```ini [parameter return_periods] properties = readonly ``` .. tip:: Properties can also convey information about the *type* of value we expect, which we will look at next. ## Numeric values Currently pipeline parameters can be any expression, e.g. they could be `exposure.foo`, `'bar'`, or `3.14`. There is no checking that the parameter is the correct type, which means the user could specify a text string where a numeric value is expected. To improve this, you can specify the type of value that you want the expression to be. For example, where you require something to be a numeric value, you can specify: ```ini [parameter shaking_percentile] properties = numeric ``` .. note:: These type-based properties do not 100% match the RiskScape types. For example, many RiskScape expressions would accept *either* an ``integer`` or a ``floating``, but the RiskScape type system forces you to explicitly pick one, rather than instead just saying it should be a numeric value. .. tip:: Type-based properties like this only work for *constant* or fixed values (also known as *literal* values in programming languages). This means that for a ``properties = numeric`` parameter, the constant value ``10`` would be accepted, but an *expression* that results in an integer, such as ``exposure.road_length``, would be rejected. .. tip:: In some situations, RiskScape will display large numbers with commas for readability (e.g. 1,024). If you wish to disable this behaviour, you can simply add the ``unformatted`` property to the parameter. This is useful for displaying years as 2024 rather than 2,024. ## Select/drop-down parameters In the `perils` example, there is a predefined list of possible choices that the user can enter. Instead of the user having to type out `'EQ'` manually and getting it exactly right, it'd be nicer to give them a drop-down list of choices. Adding the following would turn the UI parameter into a drop-down/select box: ```ini [parameter perils] choices = 'TC' choices = 'EQ' choices = 'TS' ``` The choices would be displayed to the user with the `'`s stripped off, i.e. `TC`, `EQ`, or `TS`. You can also specify choices as comma-separated values, like this: ```ini [parameter perils] choices = 'TC', 'EQ', 'TS' ``` Note that in this case, we have omitted the `[`, `]` brackets that we would normally use with a list expression. To make the drop-down choices in the model run form more meaningful, you can specify a more user-friendly label for each option, in the format `choices = "LABEL": VALUE`. For example: ```ini [parameter perils] choices = "Tropical Cyclone": 'TC' choices = Earthquake: 'EQ' choices = Tsunami: 'TS' ``` Here, the Platform user will see the `Tropical Cyclone` label instead of `TC` in the drop-down. .. note:: Labels containing spaces will need ``""`` double-quotes around them. The label ``"Tropical Cyclone"`` is valid, but specifying the same thing without quotes (i.e. ``Tropical Cyclone``) would be rejected. Again, we can specify all the choices together on the same line. We just need to make sure a comma separates each choice, e.g. ```ini [parameter perils] choices = "Tropical Cyclone": 'TC', Earthquake: 'EQ', Tsunami: 'TS' ``` Generally, it is simpler and clearer to specify each choice on a separate line. .. note:: Specifying the choices is *similar* syntax to RiskScape ``struct`` and ``list`` expressions, however, it is not *exactly* the same. Do not use ``{ }`` or ``[ ]`` characters when specifying choices in the ``project.ini`` file, unless the underlying pipeline specifically requires the expressions to be in that form. ## Multi-select parameters In this case the `perils` parameter can have a list of values. So we want the user to be able to make multiple selections in the UI, i.e. a set of check-boxes instead of a drop-down. We could control this behaviour via a property, e.g. ```ini [parameter perils] # for a multiselect input: properties = multiselect # or for checkbox inputs: properties = checkbox ``` .. note:: Your pipeline code **always** needs to accept a ``list`` type when ``multiselect`` or ``checkbox`` is used for a parameter. ## Inferring properties from default values If you do not specify any properties for a parameter, RiskScape will sometimes infer properties from the default value. For example, take the following model parameter: ```ini param.return_periods = [ 50, 100, 500 ] ``` RiskScape can infer this is a `list` and `numeric`, and therefore it should probably be a `multiselect` input field in the Platform UI. Currently these inferred properties are used in the Platform UI, but they will *not* result in model run errors if you enter a different value. For example, you can still enter something like `-p "return_periods=exposure.return_periods"`, where the value is *not* a numeric list, without any errors. If you do not like the inferred properties, you can override them by specifying *any* property for a parameter. For example: ```ini [parameter foo] properties = expression # or alternatively just use a plain text-box input field in the Platform UI: properties = textbox ``` ## Parameter templates The project parameters we have been defining using `[parameter foo]` are actually called parameter *templates*. By default, RiskScape will use the template that matches your parameter's name. For example, adding a `$foo` parameter to your pipeline will automatically try to use the `[parameter foo]` template. However, you can also define templates that get reused for multiple different parameters, which may have different names. For example, you could define a parameter template like this: ```ini [parameter percentile] properties = integer, min: 1, max: 99 label = Enter a percentile description = This should be a whole number between 1 and 99 ``` You can then reuse this parameter template for other model parameters that accept a percentile value, like this: ```ini [parameter shaking_percentile] template = percentile ``` The `shaking_percentile` parameter then inherits the `properties`, `label`, and `description` that are defined in the `percentile` template. This can simplify the amount of INI configuration you need for your Platform model. You can also override parts of the template with more specific details for a parameter. This lets you refine the label or description used for a parameter, e.g. ```ini [parameter shaking_percentile] template = percentile # this next line overrides the percentile parameter's label with a more specific one label = Enter the percentile of shaking to model ``` You can also give templates a `default` value. This will be used if the parameter does not provide a value. If the value is a file path (i.e. has the property `bookmark` or `file`), and begins with `./`, then it will be resolved relative to the file it was defined in. This means you can have your shared parameter template and default data in a different location to the models that use it. ## Bookmark parameters By specifying that a parameter is a 'bookmark' type, it means you no longer need to specify single-quotes for the file-path. For example: ```ini [parameter portfolio] default = buildings.csv properties = bookmark ``` The validation of the `portfolio` parameter now behaves the same way as specifying an input file for a wizard model - RiskScape checks that the specified value is a valid file that can be successfully read as input data. The main benefit to using the `bookmark` property is that it will give you an 'input file chooser' widget on the model run form. For example, when opened, the file chooser will look like this: .. image:: ../screenshots/select-input-default.png :target: ../_images/select-input-default.png :alt: The view when the 'Choose An Input' dialog box is first opened The other thing to note is the value inserted into your model pipeline will always be a bookmark *expression* when this property is used, e.g. `bookmark('buildings.csv')` will be inserted into the pipeline code in this case. This will generally result in your pipeline code being slightly simpler, as it means one less `bookmark()` function call you have to write yourself. For example, instead of writing: ``` select({ *, sample_one(exposure, to_coverage(bookmark($regions))) as region }) ``` You can now instead simply use: ``` select({ *, sample_one(exposure, to_coverage($regions)) as region }) ``` .. note:: The ``file`` parameter property will also give you the file input chooser widget, but it won't try to turn the given value into a bookmark expression. This can be handy if you want to build the bookmark expression in your pipeline - for example, you might also want to use other model parameters in the same bookmark expression. ### Bookmark templates You can also specify a *template* bookmark that represents the format that you expect the input data to be in. This is useful when the input data always follows the *exact* same layout, but the values within the file may differ. For example, if you had a building portfolio that gets updated yearly, then you might have several different files that all contain very similar data. These files may share common qualities, such as CSV files that contain well-known-text (WKT) in EPSG:4326 `long`,`lat` format, as well as a `Replacement_Cost` column name that contains integer values. You could define this using the following bookmark: ```ini [bookmark building_data] location = placeholder.csv crs-name = EPSG:4326 crs-longitude-first = true set-attribute.geom = geom_from_wkt(WKT) set-attribute.Replacement_Cost = int(Replacement_Cost) ``` You could then add the following model parameter, which will expect a CSV file-path that conforms to the `building_data` bookmark: ```ini [parameter portfolio] default = buildings.csv properties = bookmark-template: building_data ``` In this case, the `location` of the `building_data` bookmark will be swapped out for the file-path specified. For example, the default parameter value of `buildings.csv` will be inserted into the pipeline code as `bookmark('building_data', { location: 'buildings.csv' })`. ### Bookmark types The `bookmark-template` approach is useful in some cases, but can be limiting in others. For example, say you had alternative building data, but it was a *shapefile* rather than a CSV file, or say the data contained a replacement cost, but the attribute was called `Rateable_Value`. In these cases, your model would be *incompatible* with the alternative building data. In this case, we want to support uploading bookmark data, but also map the data format to what we expect. We can do this by using a RiskScape `type` that describes the data we expect, e.g. ```ini [type building] type.geom = geometry type.Replacement_Cost = integer ``` In the parameter properties, you then specify the type that you expect the bookmark data to have, e.g. ```ini [parameter portfolio] default = building_data properties = bookmark, type: building ``` If the user uploads a data source with different attributes, they will be presented with UI widgets for mapping the attributes in the input data to the type that is expected. For example: .. image:: ../screenshots/attribute-mapping.png :target: ../_images/attribute-mapping.png :alt: Mapping attributes from one input data source to match what the model expects This is useful for dealing with geospatial data (GeoPackage, GeoJSON, etc) where the names used for the input data attributes can vary. However, it is less useful for CSV-based data, as it does not support WKT or `lat`,`long` conversion into geometry currently. ## Available properties Below is a list of the properties that you can configure for parameters. ### Properties for constant values These properties are useful when you want the user to specify a *constant* or fixed value of a particular type (e.g. they should always enter a numeric value). Typically you only want to pick *one* property from the table below. .. rst-class:: reference-table | Property | Description | |-----------|--------------| | expression| The parameter accepts *any* expression. RiskScape can sometimes *infer* what type of values should be accepted (e.g. numeric values). Specifying `expression` will override anything RiskScape tries to do automatically | | integer | The parameter *only* accepts whole numbers, e.g. year of construction. | | list | The parameter only accepts list expressions, e.g. `[ 1, 2, 3]` | | numeric | The parameter only accepts *constant* numeric values (can be `integer` or `floating`) | | text | The parameter only accepts *constant* text strings. RiskScape will automatically add single-quotes so that it is a valid expression, e.g. entering `foo` would become `'foo'` | .. note:: Using these parameter properties will result in model run errors if the user enters an incorrect value, such as text instead of a numeric value, or if a non-constant expression is used, such as ``exposure.road_length`` or ``3.14 * 2``. ### Input field properties These properties describe what sort of input field the user should get in the web UI form for a given parameter, e.g. `textbox`, `dropdown`, etc. Typically you only want to pick *one* property from the table below. .. rst-class:: reference-table | Property | Description | |-----------|--------------| | `bookmark` | Adds a file input chooser to the UI. The user-specified value will be turned into a `bookmark()` expression | | `checkbox` | Requires that `choices` are defined. Similar to `multiselect`, except the choices appear as check-boxes in the web UI | | `dropdown` | Requires that `choices` are defined. Specify explicitly that the UI should be a drop-down select box. Normally this is inferred when `choices` are present | | `file` | Adds a file input chooser to the UI. The user-specified value will be turned into a text string | | `hidden` | Hide the parameter by default, so it does not appear in the web UI form | | `multiselect` | The user can enter *multiple* values. These either come from a set of pre-defined *choices*, or as free-form *numeric* values | | `readonly` | The user can see this parameter by default, but cannot change its value in the web UI | | `textbox` | A simple `textbox` (the default input field). You can specify this explicitly to prevent RiskScape inferring that the input field should be `multiselect` | .. tip:: To get the 'attribute mapping' widget for an input data file, use the ``type`` property in the next section below. ### Key-value properties These properties help validate that the user has provided an appropriate input value. For example, when specifying a percentile parameter, `-1` is a valid integer, but not an appropriate value to use. These properties are typically specified as a key-value pair, e.g. `min: 1` or `max: 99`. You can generally specify *multiple* properties from the table below. However, some properties are incompatible with other type-based properties, e.g. `min` and `bookmark` cannot be used together. .. rst-class:: reference-table | Property | Description | |-----------|--------------| | bookmark-template | Specifies the ID of an existing bookmark. The value specified for the parameter must conform to (i.e. be compatible with) that bookmark | | type | Specifies the ID of an existing type. The bookmark value specified for the parameter must conform to (i.e. be compatible with) that type | | min | Only supported for *numeric* parameters. Checks that the user enters a value that is greater than or equal to a specified minimum | | max | Only supported for *numeric* parameters. Checks that the user enters a value that is less than or equal to a specified maximum | | step | Only supported for *numeric* parameters, when `min` and `max` are specified. This controls the 'step' increment for the 'slider' UI widget | .. note:: Some of these properties, like ``min`` and ``max``, will result in model run errors if the user enters a value that falls outside that range. ## Exercise: setting up the model run form If you want to practise configuring the model run form, we have put together an example project to get you started. You may want to create a new Platform project for this exercise, or someone (e.g. the organization admin) may have already created a project workspace for you. ### Part 1: project setup 1. Click [here](../model-parameters.zip) to download an example project. Unzip the files locally. 2. In a file explorer, navigate to the unzipped directory. Make sure you can see the `project.ini` file. 3. Select all the project files, including the `project.ini` file, and :ref:`drag_n_drop` the files into the Platform 'Files' page for your project. Alternatively you can use WebDAV to copy the files into the Platform, if you feel comfortable with that. 3. Once you have copied the files into the Platform, click the 'Reload Project' button for your project. 4. A new 'Model-Run-Form' model should appear. Double-check that the model runs OK, i.e. that all the project files have been copied to the Platform correctly. ### Part 2: configure the model run form The model will initially load with text-boxes for all the model parameters. Look at the `requirements.md` in your project directory and make the changes it describes to the model run form by modifying your `project.ini` file. Use the above reference page to translate the `requirements.md` recommendations into model parameter configuration (e.g. by changing parameter `properties`, `description`, `choices`, etc in the INI file). It might be simplest to try changing one parameter at a time, and then reload the project to check the model run form changes appropriately.