Suggest edits
Documentation > Language


What is a Hook? 🔗

Tasks in OpenMOLE are mute pieces of software. They are not conceived to write files, display values, or generally present any side effects at all. The role of a task is to compute some output data from their input data. That's what guarantees that their execution can be deported to other machines.
OpenMOLE introduces a mechanism called Hook to save or display results generated during the execution of a workflow. Hooks are conceived to perform an action on the outputs of the task they are plugged to. Different hooks are available for different actions that need to be performed.

How to plug a hook to a task 🔗

Let's consider this simple workflow:

// Define the variable i
val i = Val[Int]

// Define a task which returns its input value multiplied by 2
val hello = ScalaTask("i = i * 2") set (
  inputs += i,
  outputs += i

// Define a Hook
val h = ToStringHook()

// Define an exploration task
  evaluation = (hello hook h),
  sampling = i in (0 to 9)

The hook h is plugged to the end of the hello task, which means that every time hello finishes, the hook h is executed. Here it means that the dataflow will be printed in the standard output, so all the output values for i will be displayed.

Plugging multiple hooks to the same task 🔗

You can define as many hooks as you want in a workflow, and plug them to the same task or to different tasks. See the following workflow:

val i = Val[Int]

val hello = ScalaTask("val i = 2") set (
  outputs += i

val h1 = ToStringHook()
val h2 = ToStringHook()
val h3 = ToStringHook()

(hello hook (h1, h2, h3))

Here the hooks h1, h2, and h3 are all plugged to the hello task and will all be executed upon its completion. However, we should point out that plugging the same hook multiple times to the same task is usually of limited interest...!

Hooks to write into files 🔗

AppendToFileHook, AppendToCSVFileHook, CopyFileHook

Write a string 🔗

Similarly to the AppendToFileHook, any string can be appended to a file, using the more general AppendToFileHook. The appended strings can be a combination of variables from the dataflow and plain text.

val h = AppendToFileHook("/path/of/the/file.txt", "string ${i} to append")

Write an entire file 🔗

Use the AppendFileFileHook as well.

val file = Val[File]
val h = AppendToFileHook("${file.content}", "/path/of/the/file")

Write into a CSV file 🔗

The CSVHook takes data from the dataflow and appends it to a file formatted as CSV:

val i = Val[Int]

val h = CSVHook("/path/to/a/file/or/dir${i}.csv")

The path is expanded using the variables from the dataflow (expressions between ${} are evaluated and replaced).

The optional last parameter of AppendToCSVFileHook is the list of variables to write to the CSV file. The default behaviour when this list is not specified is to dump all the variables from the dataflow to the file. You can restrict this behaviour by listing only the variables you want to save.

Some additional optional parameters can be passed to the CSVHook.
Setting header = "Col1, Col2, ColZ" customises the header of the CSV file to be created with the string it receives as a parameter. Please note that this only happens if the file doesn't exist when the hook is executed.
arrayOnRaw = true forces the flattening of the input lists such that all variables values are written to a single row/line of the CSV file.
For instance:
val i = Val[Int]
val j = Val[Array[Int]]

val h = CSVHook("/path/to/a/file/or/dir${i}.csv", values = Seq(i, j), header = "i, j", arrayOnRaw = true)

Hook to copy a file 🔗

The CopyFileHook makes it possible to copy a file/directory from the dataflow to a given location on the machine running OpenMOLE.

val file = Val[File]
val i = Val[Int]

val h = CopyFileHook(file, "/path/to/copy/the/file${i}.txt")

Hooks to display results 🔗

Display variables 🔗

To display a variable i from the workflow in the standard output, use the hook ToStringHook(i):

val i = Val[Int]
val j = Val[Int]

val h = ToStringHook(i, j)

If no variable is specified in ToStringHook(), the whole dataflow will be displayed. TODO whole dataflow = all outputs of the corresponding task?

Display strings 🔗

To display a string in the standard output, use the DisplayHook("string"). The string can be formed of plain text and/or variables. You can think of the DisplayHook as an OpenMOLE equivalent to Scala's println.

val i = Val[Int]

val h = DisplayHook("The value of i is ${i}.")

Conditional hooking 🔗

You may want to filter outputs that are redirected to a hook, i.e. do conditional hooking. You can use for that the when keyword, built from a hook and a condition:

val i = Val[Int]

val display = DisplayHook("The value of i is ${i}.") when "i > 0"

Decorators exist for a simpler syntax: ConditionHook(myhook,mycondition) is equivalent to myhook when mycondition and myhook condition mycondition (where the condition can be given as a condition or a string).