Complete sampling
    The most common way of exploring a model is by using a complete sampling:
    
 
val i = Val[Int]
val j = Val[Double]
val k = Val[String]
val l = Val[Long]
val explo =
  ExplorationTask (
    (i in (0 to 10 by 2)) x
    (j in (0.0 to 5.0 by 0.5)) x
    (k in List("hello", "world")) x
    (l in (UniformDistribution[Long]() take 10))
  )
val i = Val[Int]
val j = Val[Double]
val explo =
 ExplorationTask (
   (i in (0 to 10 by 2)) x
   (j in Range[Double]("0.0", "2 * i", "0.5"))
 )ZipSampling. It combines the elements of corresponding indices
      from two samplings. ZipSampling mimics the traditional zip operation from functional
      programming that combining elements from two lists. OpenMOLE implements the ZipSampling
      through the keyword zip.
       The second sampling from the Zip family is the ZipWithIndexSampling. Again, this is
      inspired from a common functional programming operation called zipWithIndex. Applying zipWithIndex to a list
      would create a new list of pairs formed by the elements of the original list and the index of their position in the
      list. For instance List('A', 'B', 'C') zipWithIndex would returns the new list
      List(('A',0), ('B',1), ('C',2)). ZipWithIndexSampling performs a
      similar operation in the dataflow. An integer variable from the dataflow is filled with the index instead of
      generating a new pair. OpenMOLE implements the ZipWithIndexSampling through the keyword
      withIndex.
       The following code snippet gives an example of how to use these two first Zip samplings.
      val p1 = Val[Int]
val p2 = Val[Int]
val s1 = p1 in (0 to 100) // Code to build sampling 1
val s2 = p2 in (0 to 100) // Code to build sampling 2
// Create a sampling by zipping line by line s1 and s2
val s3 = s1 zip s2
// Create a sampling containing an id for each experiment in a variable called id
val id = Val[Int]
val s4 = s2 withIndex idZipWithNameSampling. It maps the name
        the files from a FileDomain (see the next section for more details about exploring files) to a String variable
        in the dataflow. In the following excerpt, we map the name of the file and print it along to its size. In OpenMOLE file
        variables generally don't preserve the name of the file from which it was originally created. In order to save some
        output results depending on the input filename the filename should be transmitted in a variable of type String. When running
        this snippet, the file is renamed by the ScalaTask however, its name is saved in the name variable.
        val file = Val[File]
val name = Val[String]
val size = Val[Long]
val t = ScalaTask("val size = new java.io.File(workDir, \"file\").length") set (
  inputFiles += (file, "file"),
  inputs += name,
  outputs += (name, size)
)
ExplorationTask(file in (workDirectory / "dir") withName name) -< (t hook ToStringHook())val dir = Val[File]
val dirName = Val[String]
val file = Val[File]
val fileName = Val[String]
val name = Val[String]
val size = Val[Long]
val t = ScalaTask("val size = file.length") set (
  inputs += file,
  outputs += size,
  (inputs, outputs) += (fileName, dirName)
)
val explo =
  ExplorationTask(
    (dir in (workDirectory / "test") withName dirName) x
    (file in dir withName fileName)
  )
explo -< (t hook ToStringHook())take N on a Sampling, along with N an integer, OpenMOLE will generate a
    new Sampling from the first N values of the initial Sampling.
     Similarly, you can use sample N to create a new Sampling with N random values picked up
    at random from the initial Sampling.
     More advanced Sampling reductions happen through filter ("predicate"). It filters out all
    the values from the initial Sampling for which the given predicate is wrong.
     The 3 sampling operations presented in this section are put into play in the following example:
    val p1 = Val[Int]
val p2 = Val[Int]
val s1 = p1 in (0 to 100) // Code to build sampling 1
val s2 = p2 in (0 to 100) // Code to build sampling 2
// Create a sampling containing the 10 first values of s1
val s3 = s1 take 10
// Create a new sampling containing only the lines of s1 for which the given predicate is true
val s4 = (s1 x s2) filter ("p1 + p2 < 100")
// Sample 5 values from s1
val s5 = s1 sample 5shuffle that creates
    a new sampling which is a randomly shuffled version of the initial one.
     OpenMOLE can also generate a fresh new Sampling made of random numbers using
    UniformDistribution[T], with T the type of random numbers to be generated.
     Check the following script to discover how to use these random-based operations in a workflow:
    val p1 = Val[Int]
val p2 = Val[Int]
val s1 = p1 in (0 to 100) // Code to build sampling 1
val s2 = p2 in (0 to 100) // Code to build sampling 2
// Create a sampling containing the values of s1 in a random order
val s6 = s1.shuffle
// Replicate 100 times the sampling s1 and provide seed for each experiment
val seed = Val[Int]
val s7 = s1 x (seed in (UniformDistribution[Int]() take 100))repeat and
    bootstrap:
      val i = Val[Int]
val s1 = i in (0 to 100)
// Re-sample 10 times s1, the output is an array of array of values
val s2 = s1 repeat 10
// Create 10 samples of 5 values from s1, it is equivalent to "s1 sample 5 repeat 10", the output type is an
// array of array of values
val s3 = s1 bootstrap (5, 10)// This code compute 10 couples (for f1 and f2) of medians among 5 samples picked at random in f1 x f2
val p1 = Val[Double]
val p2 = Val[Double]
val f1 = p1 in (0.0 to 1.0 by 0.1)
val f2 = p2 in (0.0 to 1.0 by 0.1)
val e1 = ExplorationTask((f1 x f2) bootstrap (5, 10))
val stat = ScalaTask("val p1 = input.p1.median; val p2 = input.p2.median") set (
  inputs += (p1.toArray, p2.toArray),
  outputs += (p1, p2)
)
val mole = e1 -< (stat hook ToStringHook())val i = Val[Int]
val j = Val[Int]
val k = Val[Int]
val exploration =
  ExplorationTask(
    (i in (0 until 10)) x
    (j is "i * 2") x
    (k in Range[Int]("j", "j + 7"))
  )