Commit 97f2188e authored by Romain Reuillon's avatar Romain Reuillon

Merge branch '4-dev' of github.com:openmole/openmole into 4-dev

Conflicts:
	openmole/bin/org.openmole.site/src/main/scalatex/org.openmole.site/documentation/console/task/NetLogo.scalatex
parents 80eb6b1c c93e0f8e
......@@ -39,6 +39,8 @@ object Objects {
}
highlight(code, "scala")
}
def openmoleNoTest(code: String) = openmole(code, test = false)
}
case class Parameter(name: String, `type`: String, description: String)
def parameters(p: Parameter*) = {
......
......@@ -179,71 +179,71 @@ object DocumentationPages { index ⇒
def allPages = root.allPages
def root = new DocumentationPage {
def name = "documentation"
def name = "Documentation"
def content = documentation.Documentation()
def children = Seq(console, gui, development)
def children = Seq(console, gui, tutorial, development)
def console =
new DocumentationPage {
def name = "console"
def children = Seq(task, sampling, transition, hook, environment, source, method, tutorial)
def name = "Console DSL"
def children = Seq(task, sampling, transition, hook, environment, source, method)
def content = documentation.Console()
def task = new DocumentationPage {
def name = "task"
def name = "Tasks"
def children = Seq(scala, systemExec, netLogo, mole)
def content = documentation.console.Task()
def scala = new DocumentationPage {
def name = "scala"
def name = "Scala"
def children = Seq()
def content = documentation.console.task.Scala()
}
def systemExec = new DocumentationPage {
def name = "systemexec"
def name = "SystemExec"
def children = Seq()
def content = documentation.console.task.SystemExec()
}
def netLogo = new DocumentationPage {
def name = "netlogo"
def name = "NetLogo"
def children = Seq()
def content = documentation.console.task.NetLogo()
}
def mole = new DocumentationPage {
def name = "mole"
def name = "Mole"
def children = Seq()
def content = documentation.console.task.MoleTask()
}
}
def sampling = new DocumentationPage {
def name = "sampling"
def name = "Samplings"
def children = Seq()
def content = documentation.console.Sampling()
}
def transition = new DocumentationPage {
def name = "transition"
def name = "Transitions"
def children = Seq()
def content = documentation.console.Transition()
}
def hook = new DocumentationPage {
def name = "hook"
def name = "Hooks"
def children = Seq()
def content = documentation.console.Hook()
}
def environment = new DocumentationPage {
def name = "environment"
def name = "Environments"
def children = Seq(multithread, ssh, egi, cluster, desktopGrid)
def content = documentation.console.Environment()
def multithread = new DocumentationPage {
def name = "multi-thread"
def name = "Multi-threads"
def children = Seq()
def content = documentation.console.environment.Multithread()
}
......@@ -261,13 +261,13 @@ object DocumentationPages { index ⇒
}
def cluster = new DocumentationPage {
def name = "cluster"
def name = "Clusters"
def children = Seq()
def content = documentation.console.environment.Cluster()
}
def desktopGrid = new DocumentationPage {
def name = "desktop grid"
def name = "Desktop Grid"
def children = Seq()
def content = documentation.console.environment.DesktopGrid()
}
......@@ -275,79 +275,79 @@ object DocumentationPages { index ⇒
}
def source = new DocumentationPage {
def name = "source"
def name = "Sources"
def children = Seq()
def content = documentation.console.Source()
}
def method = new DocumentationPage {
def name = "method"
def name = "Exploration Methods"
def children = Seq()
def content = documentation.console.Method()
}
}
def tutorial = new DocumentationPage {
def name = "tutorial"
def children = Seq(helloWorld, headlessNetLogo, netLogoGA, capsule)
def content = documentation.console.Tutorial()
def gui = new DocumentationPage {
def name = "GUI"
def children = Seq()
def content = documentation.GUI()
}
def helloWorld = new DocumentationPage {
def name = "Hello World"
def children = Seq()
def content = documentation.console.tutorial.HelloWorld()
}
def tutorial = new DocumentationPage {
def name = "Tutorials"
def children = Seq(helloWorld, headlessNetLogo, netLogoGA, capsule)
def content = documentation.console.Tutorial()
def headlessNetLogo = new DocumentationPage {
def name = "NetLogo Headless"
def children = Seq()
def content = documentation.console.tutorial.HeadlessNetLogo()
}
def helloWorld = new DocumentationPage {
def name = "Hello World"
def children = Seq()
def content = documentation.console.tutorial.HelloWorld()
}
def netLogoGA = new DocumentationPage {
def name = "NetLogo GA"
def children = Seq()
def content = documentation.console.tutorial.NetLogoGA()
}
def headlessNetLogo = new DocumentationPage {
def name = "NetLogo Headless"
def children = Seq()
def content = documentation.console.tutorial.HeadlessNetLogo()
}
def capsule = new DocumentationPage {
def name = "Capsule"
def children = Seq()
def content = documentation.console.tutorial.Capsule()
}
}
def netLogoGA = new DocumentationPage {
def name = "GA with NetLogo"
def children = Seq()
def content = documentation.console.tutorial.NetLogoGA()
}
def gui = new DocumentationPage {
def name = "GUI"
def children = Seq()
def content = documentation.GUI()
def capsule = new DocumentationPage {
def name = "Capsule"
def children = Seq()
def content = documentation.console.tutorial.Capsule()
}
}
def development = new DocumentationPage {
def name = "development"
def name = "Development"
def children = Seq(compilation, plugin, branching, webserver)
def content = documentation.Development()
def compilation = new DocumentationPage {
def name = "compilation"
def name = "Compilation"
def children = Seq()
def content = documentation.development.Compilation()
}
def plugin = new DocumentationPage {
def name = "plugin"
def name = "Plugins"
def children = Seq()
def content = documentation.development.Plugin()
}
def branching = new DocumentationPage {
def name = "branching"
def name = "Branching model"
def children = Seq()
def content = documentation.development.Branching()
}
def webserver = new DocumentationPage {
def name = "web server"
def name = "Web Server"
def children = Seq()
def content = documentation.development.WebServer()
}
......
......@@ -4,21 +4,27 @@
@sect{Download}
The version @version - @b{@name} - of OpenMOLE is available @a("here", href := openmole.file). It has been released on @generationDate.
The version @version - @b{@name} - of OpenMOLE is available @a("here", href := openmole.file). It was released on @generationDate.
@p Optionally the daemon for desktop computing is available @a("here", href := openmoleDaemon.file).
@sect{Install}
Just extract the archive, and you're done! OpenMOLE is installed.
Just extract the archive, and you're done! OpenMOLE is installed and works out of the box!
@p OpenMOLE requires that Java version 7 or above is installed and available on your computer.
@p OpenMOLE is fully working under OpenJDK 7 and 8. This is the recommended option. If you use the closed-source Oracle Java virtual machine (which is probably the case if you are working on Mac or Windows), you have to install the Java Cryptography Extension (JCE) available at the bottom of this @a("page", href := "http://www.oracle.com/technetwork/java/javase/downloads/index.html") in order for OpenMOLE to be fully functional. JCE is an archive containing a bunch of files that you should replace in you jre/lib/security directory of your java install location. It enables strong cryptographic algorithms.
@p OpenMOLE is fully working under OpenJDK 7 and 8. This is the recommended option. If you use the closed-source
Oracle Java virtual machine (which is probably the case if you are working on Mac or Windows), you have to install the
Java Cryptography Extension (JCE) available at the bottom of this
@a("page", href := "http://www.oracle.com/technetwork/java/javase/downloads/index.html") in order for OpenMOLE to be
fully functional. JCE is an archive containing a bunch of files that you should replace in the i{jre/lib/security}
directory of your java installation. It enables strong cryptographic algorithms.
@sect{Launch}
Once installed you should launch openmole by executing the @i{openmole} file in the installation directory (it is called @i{openmole.bat} for windozers). It will bring up the OpenMOLE graphical interface. Instruction to launch the console interface (basically @i{openmole -c}) are available in the @a("documentation", href := DocumentationPages.root.console.file).
Once installed you can launch OpenMOLE by executing the @i{openmole} file in the installation directory
(it is called @i{openmole.bat} for windozers). It will bring up the OpenMOLE graphical interface. Instructions to
launch the console interface (basically @i{openmole -c}) are available in the
@a("console documentation", href := DocumentationPages.root.console.file) section.
@sect{Old versions}
Old versions of OpenMOLE software and documentation are available @a("here", href := "http://www.openmole.org/all/").
......@@ -6,16 +6,15 @@
@sect{Active developers}
@Developer.active
@p The development activity can be seen from @a("github", href := "https://github.com/openmole/openmole").
@p The development activity can be seen on @a("GitHub", href := "https://github.com/openmole/openmole").
@sect{How to cite OpenMOLE}
@Publication.papers.map(_.print)
@sect{Communications}
All the papers citing OpenMOLE, conference slides, videos can be found at the @a("Contributions page", href := communications.file).
@sect{Communications}
All the papers citing OpenMOLE, conference slides, videos can be found at the @a("Contributions page", href := communications.file).
All the papers citing OpenMOLE, conference slides, videos can be found on the
@a("Contributions page", href := communications.file).
@sect{Contact us}
For any question regarding OpenMOLE contact us through the OpenMOLE user mailing list: users 'at' list.openmole.org (you should @a("subscribe", href := "http://list.openmole.org/") first).
For any question regarding OpenMOLE, contact us through the OpenMOLE user mailing list: users 'at' list.openmole.org
(you should @a("subscribe", href := "http://list.openmole.org/") first).
......@@ -4,49 +4,54 @@
@sect{Getting started}
@sect{Launch the console}
@p First you should open a system console (on windows the low quality console available by default is called cmd.exe, run that and a console will appear). Then you should go to the OpenMOLE install directory and launch the console use the -c option of OpenMOLE executable.
@p Start by opening a system console (on windows the low quality console available by default is called @i{cmd.exe}, run that and a console will appear). Change to the OpenMOLE installation directory and launch OpenMOLE with the -c option to switch to console mode.
@p Under Unix like shells: @hl.highlight("./openmole -c", "plain")
@p Under Windows Dos: @hl.highlight("openmole.bat -c", "plain")
@p Console provides a headless / batch mode for running scripts. To use it you should use the -s option: @hl.highlight("./openmole -c -s /path/to/you/mole/script", "plain")
@p In that case OpenMOLE still asks for you preference cyphering password. To provide it at launch time use the -pw option: @hl.highlight("./openmole -c -s /path/to/your/mole/script -pw password", "plain")
@p In batch mode in order for OpenMOLE to block until the execution of your mole has ended you may add at the end of your script:
@br @hl.openmole("""ex.waitUntilEnded // ex is the name of your mole execution variable""", test = false)
@p To load plugins in the OpenMOLE console you should use the -p option: @hl.highlight("./openmole -c -p /path/to/plugin.jar /path/to/anotherplugin.jar", "plain")
@sect{Batch / headless mode}
@p Console provides a headless / batch mode for running scripts. You can enable it thanks to the -s option: @hl.highlight("./openmole -c -s /path/to/you/mole/script", "plain")
@p In that case OpenMOLE still asks for you preferences cyphering password. To provide it at launch time use the -pw option: @hl.highlight("./openmole -c -s /path/to/your/mole/script -pw password", "plain")
@p OpenMOLE will wait until the execution of your mole has ended if you add at the end of your script:
@br @hl.openmoleNoTest("""ex.waitUntilEnded // ex is the name of your mole execution variable""")
@sect{Plugins}
@p The -p option load plugins in the OpenMOLE console: @hl.highlight("./openmole -c -p /path/to/plugin.jar /path/to/anotherplugin.jar", "plain")
@p Check @a("this section", href := DocumentationPages.root.development.plugin.file) to discover how to create your very own OpenMOLE plugins.
@sect{The OpenMOLE language}
@p The OpenMOLE console language is an extension of the scala language designed for distributed computing. It supports all the scala constructs and additional operators and classes especially designed to compose workflows. OpenMOLE workflows expose explicit parallel aspect of the workload that can be delegated to distributed computing environments in a transparent manner. The philosophy of OpenMOLE is test small (on your computer) and scale for free (on remote distributed computing environments).
@p The OpenMOLE console language is an extension of the Scala language designed for distributed computing. It supports all the scala constructs and additional operators and classes especially designed to compose workflows. OpenMOLE workflows expose explicit parallel aspect of the workload that can be delegated to distributed computing environments in a transparent manner. The philosophy of OpenMOLE is @i{test small} (on your computer) and @i{scale for free} (on remote distributed computing environments).
@p A good way to get a first glimpse at what OpenMOLE can do is to read this @a("research paper", href := "http://www.openmole.org/files/FGCS2013.pdf").
@sect{Basic scala constructs}
You need only a very basic understanding of the scala language in order to design OpenMOLE workflows.
@sect{To declare variables}
@hl.openmole("""
@sect{Declare variables}
@hl.openmoleNoTest("""
val a = 1 // declares a variable a of type Int
val b = "Text" // declares a variable a of type String
val c = if(condition) 5 else 10 // declare a variable c of type Int, the value of c depends on the condition""", test = false)
val c = if(condition) 5 else 10 // declare a variable c of type Int, the value of c depends on the condition""")
@sect{To constructing objects}
OpenMOLE takes advantage of the object oriented aspect of scala. It proposes a set of objects that you can build and assemble together to specify your workflow. In general an object is instantiated using the "new" keyword:
@sect{Construct objects}
OpenMOLE takes advantage of the object oriented aspect of scala. It proposes a set of objects that you can build and assemble together to specify your workflow. In general, an object is instantiated using the "new" keyword:
@br @hl.openmole("""val f = new File("/tmp/file.txt")""")
@p In OpenMOLE we have choosen to use factories instead of directly constructing objects, that's why most of the OpenMOLE scripts doesn't contain the "new" keyword at all.
@p For instance: @hl.openmole("""val l = File("/tmp/file.txt")""")
@p Under the hood, it calls a method that is in charge of building the file (the apply method of the object File)")
@p Under the hood, it calls a method that is in charge of building the file.")
@sect{Named parameters}
Functions calls generally require that the parameters are provided in a predefined order. In scala you can get rid of this ordering constraint by using named parameters. In OpenMOLE you will often find this pattern:
@br @hl.openmole("val t = SomeClass(value1, value2, otherParam = otherValue)", test = false)
@p It means that value1 and value2 are the values for the first two parameters and that the parameter named otherParam is set to the value otherValue, the other parameters are set to their default values.
@sect{Going further}
What you have red here should be be sufficient in order to start with OpenMOLE. To begin with the OpenMOLE syntax you should have a look at the @a("Task documentation", href := DocumentationPages.root.console.task.file). You may also want to look at the @a("Hello World tutorial", href := DocumentationPages.root.console.tutorial.helloWorld.file).
@p Scala is a very nice language with an extensive very well designed standard library. To get more insight on this language you should look at:
@ul
@li{ @a("the scala website", href := "http://www.scala-lang.org/") }
@li{ @a("the scala books", href := "http://www.scala-lang.org/node/959") }
@li{ @a("the standard API documentation", href := "http://www.scala-lang.org/api/current/index.html") }
@sect{API documentation}
You can browse the @a("automatically generated documentation", href := Resource.api.file + "/index.html")
Functions calls generally require the parameters to be provided in a predefined order. In scala you can get rid of this ordering constraint by using named parameters. OpenMOLE scripts will often make use of this pattern:
@br @hl.openmoleNoTest("val t = SomeClass(value1, value2, otherParam = otherValue)")
@p It means that @i{value1} and @i{value2} are the values for the first two parameters and that the parameter named @i{otherParam} is set to the value @i{otherValue}. Unspecified parameters are set to their default value.
@sect{Going further}
What you have read so far should be sufficient in order to get started with OpenMOLE. To begin with the OpenMOLE syntax you should have a look at the @a("Hello World tutorial", href := DocumentationPages.root.tutorial.helloWorld.file). You may also want to look at the @a("Task documentation", href := DocumentationPages.root.console.task.file) and other sections detailing specific concepts.
@p Scala is a very nice language with an extensive very well designed standard library. To get more insights on this language, check these links:
@ul
@li{ @a("Scala website", href := "http://www.scala-lang.org/") }
@li{ @a("Scala books", href := "http://www.scala-lang.org/node/959") }
@li{ @a("Standard API documentation", href := "http://www.scala-lang.org/api/current/index.html") }
@sect{API documentation}
You can browse OpenMOLE's @a("automatically generated documentation", href := Resource.api.file + "/index.html")
......@@ -4,7 +4,7 @@
@sect{Development}
This part of the documentation concern the development of OpenMOLE. It explains how to compile OpenMOLE, how to write the doc, how to develop plugins...
This part of the documentation concerns the development process of OpenMOLE. It explains how to compile OpenMOLE, how to write the documentation, how to develop plugins...
@p To interact with the OpenMOLE development team, you can post on the OpenMOLE development mailing list: devs 'at' list.openmole.org (you should @a("subscribe", href := "http://devlist.openmole.org/") first).
......
......@@ -3,8 +3,10 @@
@import org.openmole.site.DocumentationPages._
@sect{Documentation}
Welcome to OpenMOLE documentation.
Welcome to the OpenMOLE documentation.
@p OpenMOLE is a tool for high-performance parameter tuning that works with your own programs and on your own execution environments. It comes with 2 different flavors. The @a("scripting interface", href := root.console.file) (console) and the @a("graphical user interface", href := root.gui.file) (GUI). New features are always integrated in the console version first and then integrated in the GUI. If you are comfortable with writing scripts, getting into the console shouldn't be much of a problem. However using the graphical user interface is a good way to understand quickly the OpenMOLE core concepts such as Task, Transition, Environment, Workflow, Hook...
@p OpenMOLE is a scientific workflow engine that works with your own programs and on your own execution environments. OpenMOLE has a wide range of use cases from high-performance parameter tuning, to large datasets exploration, model calibration, and pretty much any other thing you can think of :)
@p The OpenMOLE community is very friendly. To get help post your question on the OpenMOLE user mailing list: users 'at' list.openmole.org (you should @a("subscribe", href := "http://list.openmole.org/") first).
@p OpenMOLE comes in 2 different flavours. The @a("scripting interface", href := root.console.file) (console) and the @a("Graphical User Interface", href := root.gui.file) (GUI). New features are always integrated in the console version first, before being mapped to the GUI controls. If you are comfortable with writing scripts, getting into the console shouldn't be much of a problem. However using the GUI is a good way to quickly understand OpenMOLE's core concepts such as @a("Tasks", href := DocumentationPages.root.console.task.file), @a("Transitions", href := DocumentationPages.root.console.transition.file), @a("Environments", href := DocumentationPages.root.console.environment.file), Workflow, @a("Hooks", href := DocumentationPages.root.console.hook.file), ...
@p The OpenMOLE community is very friendly. To get some help, don't hesitate to post your questions on the OpenMOLE user mailing list: users 'at' list.openmole.org (you should @a("subscribe", href := "http://list.openmole.org/") first).
......@@ -3,4 +3,5 @@
@import org.openmole.site.DocumentationPages._
@sect{GUI}
The graphical user interface is being entirely rewritten. So, there is no graphical user interface available for the version @version of OpenMOLE. You could get one using the @a("version 3.0 of OpenMOLE", href := "/all/3.0/") or you can use the @a("console", href := root.console.file) interface.
\ No newline at end of file
This section will contain the documentation on the new Graphical User Interface (GUI) of OpenMOLE once it's been released.
......@@ -3,7 +3,11 @@
@import DocumentationPages._
@sect{Environment}
A big feature in OpenMOLE is the possibility of delegating the workload to a remote execution environment. Tasks in OpenMOLE have been designed so that the delegation a part of the workload to a remote environment is declarative. To achieve it first define the environment, then tells OpenMOLE witch task to delegate.
A key feature in OpenMOLE is the possibility to delegate the workload to a remote execution environment. Tasks in OpenMOLE have been designed so that the delegation a part of the workload to a remote environment is declarative.
@sect{Defining an execution Environment}
You first need to define the environment(s) you want to use an authentication method. Then, the actual delegation of
the task is noted by the keyword @hl.openmoleNoTest("on") followed by a defined @i{Environment}:
@br @hl.openmole("""
val env = LocalEnvironment(10)
......@@ -13,20 +17,31 @@
val mole = t1 -- (t2 on env) -- t3""")
@p OpenMOLE will then delegate the execution of the task to the designated environment from bare metal. You do not need to install anything or perform any kind of configuration on the target execution environment for OpenMOLE to work on it. You will however be required to provide the authentication information in order for OpenMOLE to access the remote environment.
@p The use of a batch environment is generally not suited for short tasks (less than a 1 minute for a cluster to less than 1 hour for a grid). In case your tasks are short you can group several executions. To group the execution by 100 in each job submitted to the environment you should like that:
@br @hl.openmole("""val mole = explo -< (t1 on env by 100)""", header = """
@p You do not need to install anything or perform any kind of configuration on the target execution environment for
OpenMOLE to work. It reuses the infrastructure in place. You will however be required to provide the authentication
information in order for OpenMOLE to access the remote environment. At this point, just specify the credentials you're
using to login to this environment outside of OpenMOLE. Voila! That's all you need to do to use your environment
through OpenMOLE. In case you face authentication problems when targeting an environment through SSH, please refer
to the troubleshooting page.
@p When no specific environment is specified for a task, or a group of tasks, they will be executed sequentially on your
local machine.
@sect{Grouping}
@p The use of a batch environment is generally not suited for short tasks (less than a 1 minute for a cluster to less
than 1 hour for a grid). In case your tasks are short you can group several executions. To group the execution by 100
in each job submitted to the environment, use the keyword @hl.openmoleNoTest("by"):
@br @hl.openmole("""val mole = explo -< (t1 on env by 100)""", header = """
val env = LocalEnvironment(10)
val t1 = EmptyTask()
val i = Val[Int]
val explo = ExplorationTask(i in (0 to 10000))
""")
@p Depending on which environment you want to delegate your workload to you can check the following doc:
@ul
@li{@a("Multi-thread", href := root.console.environment.multithread.file), to execute the tasks concurrently on your machine,}
@li{@a("SSH", href := root.console.environment.ssh.file), to execute tasks on remote server through SSH,}
@li{@a("Clusters", href := root.console.environment.cluster.file), to execute tasks on a cluster managed by @a("PBS/Torque", href := root.console.environment.cluster.file + "#PBS/Torque"), @a("SGE", href := root.console.environment.cluster.file + "#SGE"), @a("Slurm", href := root.console.environment.cluster.file + "#SLURM"), @a("Condor", href := root.console.environment.cluster.file + "#Condor"), or @a("OAR", href := root.console.environment.cluster.file + "#OAR").}
@li{@a("EGI", href := root.console.environment.egi.file), to execute tasks on the @a("EGI grid", href := root.console.environment.egi.file + "#DelegatetasksonEGI") or using @a("DIRAC", href := root.console.environment.egi.file + "#DIRAC").}
@sect{Available environments}
@p Multiple environments are available to delegate your workload, check the following sections:
@ul
@li{@a("Multi-thread", href := root.console.environment.multithread.file), to execute the tasks concurrently on your machine,}
@li{@a("SSH", href := root.console.environment.ssh.file), to execute tasks on remote server through SSH,}
@li{@a("Clusters", href := root.console.environment.cluster.file), to execute tasks on a cluster managed by @a("PBS/Torque", href := root.console.environment.cluster.file + "#PBS/Torque"), @a("SGE", href := root.console.environment.cluster.file + "#SGE"), @a("Slurm", href := root.console.environment.cluster.file + "#SLURM"), @a("Condor", href := root.console.environment.cluster.file + "#Condor"), or @a("OAR", href := root.console.environment.cluster.file + "#OAR").}
@li{@a("EGI", href := root.console.environment.egi.file), to execute tasks on the @a("EGI grid", href := root.console.environment.egi.file + "#DelegatetasksonEGI") or using @a("DIRAC", href := root.console.environment.egi.file + "#DIRAC").}
......@@ -2,9 +2,14 @@
@import org.openmole.site.Objects._
@sect{Hook}
Task are mute pieces of software. It means that there are not conceived to write files or display values or have any side effects at all. Their role is to compute some output data from the input data. That's what guaranty that their executions can be deported on other computer. To save your results, you should use the hooks. Hooks are conceived to perform listen to perform some action when a task is finished.
@p Tasks are mute pieces of software. They are not conceived to write files, display values, nor more generally present
any side effects at all. Tasks' role is to compute some output data from their input data. That's what guaranties that
their execution can be deported to other machines.
@p OpenMOLE introduces a mechanims called @b{Hooks} to save or display results generated on remote environments. Hooks
are conceived to perform an action upon completion of the task they are attached to.
@sect{Plug a hook}
Let consider this simple workflow:
Let's consider this simple workflow:
@br @hl.openmole("""
val i = Val[Int]
val hello = ScalaTask("i = i * 2") set (
......@@ -17,7 +22,8 @@
val h = ToStringHook()
val ex = exploration -< (hello hook h) start""")
@p The hook @i{h} is plugged a the end of the task hello. Each time hello finishes the hook is executed. You can also plug multiple hooks on the same task using the syntax:
@p The hook @i{h} is plugged to the end of the @i{hello} task. Everytime @i{hello} finishes, the hook @i{h} is
executed. Multiple hooks can also be plugged to the same task as in the present example:
@br @hl.openmole("""
val i = Val[Int]
......@@ -30,36 +36,42 @@
val h3 = ToStringHook()
val ex = (hello hook (h1, h2, h3)) start""").
@sect{Save your data in CSV}
The AppendToCSVFileHook take data from the dataflow and copy them into a CSV file:
@p Hooks come in various declinations, with different actions on the results. The available hooks are described
hereafter.
@sect{Save your data as CSV}
The @i{AppendToCSVFileHook} takes data from the dataflow and appends it to a file formatted as CSV:
@br @hl.openmole("""
val i = Val[Int]
val h = AppendToCSVFileHook("/path/to/a/file/or/dir${i}.csv")""")
@p The path is expanded (expressions between ${} are evaluated and replaced).
@p The path is expanded using the variables from the dataflow (expressions between ${} are evaluated and replaced).
@sect{Save files computed by your tasks}
The copyFile hook makes it possible to copy a file / directory from the dataflow to a given location.
The @i{CopyFileHook} makes it possible to copy a file / directory from the dataflow to a given location on the machine
running OpenMOLE.
@br @hl.openmole("""
val file = Val[File]
val i = Val[Int]
val h = CopyFileHook(file, "/path/to/copy/the/file${i}.txt")""")
@sect{Append some content to a file}
To append a string to a file, use this hook:
Similarly to the @i{AppendToCSVFileHook}, any string can be appended to a file, using the more general
@i{AppendToFileHook}. The appended strings can be a combination of variables from the dataflow and plain text.
@br @hl.openmole("""
val h = AppendToFileHook("/path/to/copy/the/file.txt", "string ${i} to append")""")
@sect{To display some variables}
To display a variable in the console
@sect{Display variables}
To display a variable in the console, use the @i{ToStringHook}:
@br @hl.openmole("""
val i = Val[Int]
val j = Val[Int]
val h = ToStringHook(i, j)""")
If no prototype is provided it display all the content of the dataflow.
@sect{To display some result in the console}
To display a string in the console:
If no variable is specified, @i{ToStringHook} displays the whole dataflow.
@sect{Display results in the console}
To display a string formed of variables and plain text in the console, use the @i{DisplayHook}. You can think of the
@i{DisplayHook} as an OpenMOLE equivalent to Scala's @i{println}.
@br @hl.openmole("""
val i = Val[Int]
val h = DisplayHook("The value of i is ${i}.")""")
@import org.openmole.site.Objects._
@def model = """
......@@ -17,20 +16,25 @@
val modelCapsule = Capsule(modelTask)"""
@sect{Methods}
OpenMOLE provides advanced methods to explore space of parameters. These methods generates workflow automatically in order to solve exploration problems.
@sect{Automatic parameter exploration methods}
OpenMOLE provides advanced methods to help you explore your application's space of parameters. These methods
automatically generate workflows in order to solve exploration problems.
@sect{Genetic algorithms}
This workflow optimises a dummy model using generational NSGA II multi-objective algorithm. You are free to replace the dummy model with you own.
This workflow optimises a dummy model using the generational NSGA II multi-objective algorithm. You can replace the
instances of @i{modelCapsule} by your own model and adapt the variation range of its input variables. If you're not
familiar with parameter tuning using Genetic Algorithms (GA), you should first consult the
@a("tutorial explaining how to calibrate a NetLogo model with a GA", href := DocumentationPages.root.tutorial.netLogoGA.file).
@br @hl.openmole(s"""
$model
// Definition of the optimisation algorithm