Commit ed7cb720 authored by Romain Reuillon's avatar Romain Reuillon

[Plugin] enh: support json output in sensitivity

parent e4c5a032
......@@ -141,7 +141,7 @@ package composition {
def hook[F](
output: WritableOutput,
values: Seq[Val[_]] = Vector.empty,
format: F = CSVOutputFormat())(implicit definitionScope: DefinitionScope, fileFormat: OutputFormat[F]): TaskNode = hook(FormattedFileHook(output = output, values = values, format = format))
format: F = CSVOutputFormat(append = true))(implicit definitionScope: DefinitionScope, fileFormat: OutputFormat[F]): TaskNode = hook(FormattedFileHook(output = output, values = values, format = format))
def source(sources: Source*) = copy(sources = this.sources ++ sources)
}
......
......@@ -21,7 +21,7 @@ object CSVHook {
arrayOnRow: Boolean = false,
overwrite: Boolean = false)(implicit name: sourcecode.Name, definitionScope: DefinitionScope): mole.FromContextHook =
FormattedFileHook(
format = CSVOutputFormat(header = header, arrayOnRow = arrayOnRow, overwrite = overwrite),
format = CSVOutputFormat(header = header, arrayOnRow = arrayOnRow, append = !overwrite),
output = output,
values = values,
exclude = exclude,
......@@ -39,14 +39,15 @@ object CSVHook {
output match {
case WritableOutput.FileValue(file)
val f = file.from(context)
val create = format.overwrite || f.isEmpty
val create = !format.append || f.isEmpty
val h = if (f.isEmpty) Some(headerLine) else None
if (create) f.atomicWithPrintStream { ps csv.writeVariablesToCSV(ps, h, variables.map(_.value), format.arrayOnRow) }
else f.withPrintStream(append = true, create = true) { ps csv.writeVariablesToCSV(ps, h, variables.map(_.value), format.arrayOnRow) }
case WritableOutput.PrintStreamValue(ps)
case WritableOutput.StreamValue(ps, prelude)
prelude.foreach(ps.print)
val header = Some(headerLine)
csv.writeVariablesToCSV(ps, header, variables, format.arrayOnRow)
}
......@@ -64,6 +65,6 @@ object CSVHook {
case class CSVOutputFormat(
header: OptionalArgument[FromContext[String]] = None,
arrayOnRow: Boolean = false,
overwrite: Boolean = false)
append: Boolean = false)
}
......@@ -25,12 +25,12 @@ object WritableOutput {
implicit def fromFile(file: File) = FileValue(file)
implicit def fromFileContext(file: FromContext[File]) = FileValue(file)
implicit def fromPrintStream(ps: PrintStream) = PrintStreamValue(ps)
implicit def fromPrintStream(ps: PrintStream) = StreamValue(ps)
type Display = PrintStream
case class FileValue(file: FromContext[File]) extends WritableOutput
case class PrintStreamValue(file: Display) extends WritableOutput
case class StreamValue(stream: Display, prelude: Option[String] = None) extends WritableOutput
def file(writableOutput: WritableOutput) =
writableOutput match {
......
......@@ -20,7 +20,8 @@ object JSONOutputFormat {
file.from(context).withPrintStream(append = false, create = true) { ps
ps.print(compact(render(variablesToJValue(variables))))
}
case WritableOutput.PrintStreamValue(ps)
case WritableOutput.StreamValue(ps, prelude)
prelude.foreach(ps.print)
ps.println(pretty(render(variablesToJValue(variables))))
}
}
......
......@@ -63,7 +63,7 @@ object SavePopulationHook {
}
def apply[T, F: OutputFormat](algorithm: T, output: WritableOutput, frequency: OptionalArgument[Long] = None, last: Boolean = false, format: F = CSVOutputFormat(overwrite = true))(implicit wfi: WorkflowIntegration[T], name: sourcecode.Name, definitionScope: DefinitionScope) = {
def apply[T, F: OutputFormat](algorithm: T, output: WritableOutput, frequency: OptionalArgument[Long] = None, last: Boolean = false, format: F = CSVOutputFormat())(implicit wfi: WorkflowIntegration[T], name: sourcecode.Name, definitionScope: DefinitionScope) = {
val t = wfi(algorithm)
hook(t, output, frequency.option, last = last, format = format)
}
......
......@@ -99,7 +99,7 @@ package object evolution {
implicit def workflowIntegration = WorkflowIntegration[DSLContainer[EvolutionWorkflow]](_.data)
implicit class EvolutionMethodContainer(dsl: DSLContainer[EvolutionWorkflow]) extends DSLContainerHook(dsl) {
def hook[F: OutputFormat](output: WritableOutput, frequency: OptionalArgument[Long] = None, last: Boolean = false, format: F = CSVOutputFormat(overwrite = true)): DSLContainer[EvolutionWorkflow] = {
def hook[F: OutputFormat](output: WritableOutput, frequency: OptionalArgument[Long] = None, last: Boolean = false, format: F = CSVOutputFormat()): DSLContainer[EvolutionWorkflow] = {
implicit val defScope = dsl.scope
dsl.hook(SavePopulationHook(dsl, output, frequency = frequency, last = last, format = format))
}
......
......@@ -5,38 +5,22 @@ import org.openmole.core.dsl.extension._
object MorrisHook {
def apply(dsl: DSLContainer[Sensitivity.MorrisParams], output: WritableOutput)(implicit name: sourcecode.Name, definitionScope: DefinitionScope) =
def apply[F](dsl: DSLContainer[Sensitivity.MorrisParams], output: WritableOutput, format: F = CSVOutputFormat())(implicit name: sourcecode.Name, definitionScope: DefinitionScope, outputFormat: OutputFormat[F]) =
Hook("MorrisHook") { p
import p._
import WritableOutput._
val inputs = ScalarOrSequenceOfDouble.prototypes(dsl.data.inputs)
output match {
case WritableOutput.FileValue(dirFC)
val dir = dirFC.from(context)
dir.mkdirs()
(dir / "mu.csv").withPrintStream() { ps
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Morris.mu(_, _)).from(context)
}
(dir / "muStar.csv").withPrintStream() { ps
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Morris.muStar(_, _)).from(context)
}
(dir / "sigma.csv").withPrintStream() { ps
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Morris.sigma(_, _)).from(context)
}
case WritableOutput.PrintStreamValue(ps)
ps.println("mu")
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Morris.mu(_, _)).from(context)
ps.println("mu star")
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Morris.muStar(_, _)).from(context)
ps.println("sigma")
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Morris.sigma(_, _)).from(context)
case FileValue(dirFC)
Sensitivity.writeResults(format, FileValue(dirFC / s"mu${outputFormat.extension}"), inputs, dsl.data.outputs, Morris.mu(_, _)).from(context)
Sensitivity.writeResults(format, FileValue(dirFC / s"muStar${outputFormat.extension}"), inputs, dsl.data.outputs, Morris.muStar(_, _)).from(context)
Sensitivity.writeResults(format, FileValue(dirFC / s"sigma${outputFormat.extension}"), inputs, dsl.data.outputs, Morris.sigma(_, _)).from(context)
case StreamValue(ps, prelude)
Sensitivity.writeResults(format, StreamValue(ps, Some(prelude.getOrElse("") + "mu\n")), inputs, dsl.data.outputs, Morris.mu(_, _)).from(context)
Sensitivity.writeResults(format, StreamValue(ps, Some("muStar\n")), inputs, dsl.data.outputs, Morris.muStar(_, _)).from(context)
Sensitivity.writeResults(format, StreamValue(ps, Some("sigma\n")), inputs, dsl.data.outputs, Morris.sigma(_, _)).from(context)
}
context
}
......
......@@ -5,30 +5,20 @@ import org.openmole.core.dsl.extension._
object SaltelliHook {
def apply(dsl: DSLContainer[Sensitivity.SaltelliParams], output: WritableOutput)(implicit name: sourcecode.Name, definitionScope: DefinitionScope) =
def apply[F](dsl: DSLContainer[Sensitivity.SaltelliParams], output: WritableOutput, format: F = CSVOutputFormat())(implicit name: sourcecode.Name, definitionScope: DefinitionScope, outputFormat: OutputFormat[F]) =
Hook("SaltelliHook") { p
import p._
import WritableOutput._
val inputs = ScalarOrSequenceOfDouble.prototypes(dsl.data.inputs)
output match {
case WritableOutput.FileValue(dirFC)
val dir = dirFC.from(context)
(dir / "firstOrderIndices.csv").withPrintStream(create = true) { ps
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Saltelli.firstOrder(_, _)).from(context)
}
(dir / "totalOrderIndices.csv").withPrintStream() { ps
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Saltelli.totalOrder(_, _)).from(context)
}
case WritableOutput.PrintStreamValue(ps)
ps.println("first order")
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Saltelli.firstOrder(_, _)).from(context)
ps.println("total order")
Sensitivity.writeResults(ps, inputs, dsl.data.outputs, Saltelli.totalOrder(_, _)).from(context)
case FileValue(dirFC)
Sensitivity.writeResults(format, FileValue(dirFC / s"firstOrderIndices${outputFormat.extension}"), inputs, dsl.data.outputs, Saltelli.firstOrder(_, _)).from(context)
Sensitivity.writeResults(format, FileValue(dirFC / s"totalOrderIndices${outputFormat.extension}"), inputs, dsl.data.outputs, Saltelli.totalOrder(_, _)).from(context)
case StreamValue(ps, prelude)
Sensitivity.writeResults(format, StreamValue(ps, Some(prelude.getOrElse("") + "first order\n")), inputs, dsl.data.outputs, Saltelli.firstOrder(_, _)).from(context)
Sensitivity.writeResults(format, StreamValue(ps, Some("total order\n")), inputs, dsl.data.outputs, Saltelli.totalOrder(_, _)).from(context)
}
context
......
......@@ -53,14 +53,18 @@ package object sensitivity {
}
def writeResults(ps: PrintStream, inputs: Seq[Val[_]], outputs: Seq[Val[_]], coefficient: (Val[_], Val[_]) Val[_]) = FromContext { p
def writeResults[F](format: F, output: WritableOutput, inputs: Seq[Val[_]], outputs: Seq[Val[_]], coefficient: (Val[_], Val[_]) Val[_])(implicit outputFormat: OutputFormat[F]) = FromContext { p
import p._
outputs.zipWithIndex.foreach { case (o, i)
def results = outputs.map { o
val vs = inputs.map { i coefficient(i, o) }
val headerLine = if(i == 0) Some(s"""output,${csv.header(inputs, vs)}""") else None
csv.writeVariablesToCSV(ps, headerLine, Seq(o.name) ++ vs.map(v context(v)))
Seq(o.name) ++ vs.map(v context(v))
}
def allVals = Seq(Val[String]("output")) ++ inputs
val data = (results.transpose zip allVals).map { case (value, v) => Variable.unsecure(v.array, value) }
outputFormat.write(format, output, data).from(context)
}
......@@ -73,9 +77,9 @@ package object sensitivity {
* @param dsl
*/
implicit class SaltelliMethodContainer(dsl: DSLContainer[Sensitivity.SaltelliParams]) extends DSLContainerHook(dsl) {
def hook(output: WritableOutput): DSLContainer[Sensitivity.SaltelliParams] = {
def hook[F: OutputFormat](output: WritableOutput, format: F = CSVOutputFormat()): DSLContainer[Sensitivity.SaltelliParams] = {
implicit val defScope = dsl.scope
dsl hook SaltelliHook(dsl, output)
dsl hook SaltelliHook(dsl, output, format)
}
}
......@@ -85,9 +89,9 @@ package object sensitivity {
* @param dsl
*/
implicit class MorrisMethodContainer(dsl: DSLContainer[Sensitivity.MorrisParams]) extends DSLContainerHook(dsl) {
def hook(output: WritableOutput): DSLContainer[Sensitivity.MorrisParams] = {
def hook[F: OutputFormat](output: WritableOutput, format: F = CSVOutputFormat()): DSLContainer[Sensitivity.MorrisParams] = {
implicit val defScope = dsl.scope
dsl hook MorrisHook(dsl, output)
dsl hook MorrisHook(dsl, output, format)
}
}
......
......@@ -20,6 +20,7 @@ package object json {
case v: Double JDouble(v)
case v: Array[_] JArray(v.map(toJSONValue).toList)
case v: java.io.File JString(v.getAbsolutePath)
case v: Seq[_] JArray(v.map(toJSONValue).toList)
case _ throw new UserBadDataError(s"Value $v of type ${v.getClass} is not convertible to JSON")
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment