[ref] moved functionality of results and sim objects into traits
- added Interfaces.scala for traits
This commit is contained in:
@@ -3,7 +3,7 @@ package scim
|
||||
import scim.components.{Parser, SimulationConfigParser, Output, Simulation}
|
||||
import scim.datastruct.{Cell, FunctionArgs, SharedMemory, SimulationBehaviours, Time}
|
||||
import scim.lib._
|
||||
import scim.lib.simulation.SimulationBehaviour
|
||||
import scim.lib.simInterfaces.SimulationBehaviour
|
||||
//package scim.components._
|
||||
object Main {
|
||||
|
||||
|
||||
@@ -4,10 +4,9 @@ import scim.datastruct.{Behaviour, BehaviourVector, Cell, Configuration, Functio
|
||||
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
||||
import scim.lib.debugUtil.{DebugType, debugf}
|
||||
import scim.lib.mapUtil._
|
||||
import scim.lib.parser._
|
||||
import scim.lib.simulation.SimulationBehaviour
|
||||
import scim.lib.simInterfaces.SimulationBehaviour
|
||||
import scim.lib.yml
|
||||
|
||||
import scim.lib.parserUtil._
|
||||
import scala.collection.mutable
|
||||
|
||||
class Parser() {
|
||||
@@ -55,11 +54,11 @@ class SimulationConfigParser(input: Map[String, Any], simulationBehaviours: Simu
|
||||
val configurationMapping = sensorList.map(cell => cell._1 -> cellMapper(cell._1, cell._2.toMap)).toMap
|
||||
|
||||
// construct shared memory sensor
|
||||
val sharedMemorySensor = Vector.tabulate(config.duration)(t => (Time(t, config.duration), sensorList.map(kv => kv._1 -> kv._2.map(kv2 => kv2._1 -> Vector.tabulate(kv2._2.count)(_ => SensorResult(new BroadcastObject()))).toMap).toMap))
|
||||
val sharedMemorySensor = Vector.tabulate(config.duration)(t => (Time(t, config.duration), sensorList.map(kv => kv._1 -> kv._2.map(kv2 => kv2._1 -> Vector.tabulate(kv2._2.count)(_ => SensorResult())).toMap).toMap))
|
||||
|
||||
def truthHelper(cell: Cell, list: Map[Group, List[(Group, Sensor, Option[GroundTruth])]]): (Cell, Map[Group, Truth]) = {
|
||||
val groupList: mutable.Map[Group, Truth] = mutable.Map()
|
||||
list.foreach(kv => kv._2.foreach(e => groupList(e._1) = Truth(new BroadcastObject())))
|
||||
list.foreach(kv => kv._2.foreach(e => groupList(e._1) = Truth()))
|
||||
cell -> groupList.toMap
|
||||
}
|
||||
|
||||
@@ -115,7 +114,7 @@ class SimulationConfigParser(input: Map[String, Any], simulationBehaviours: Simu
|
||||
}
|
||||
|
||||
private def parseCells(cells: Vector[Any]): Map[Cell, SensorCount] = {
|
||||
val parseCell: (Any) => (Cell, SensorCount) = (cell: Any) => cell match {
|
||||
val parseCell: Any => (Cell, SensorCount) = (cell: Any) => cell match {
|
||||
case cell: Vector[_] => val cellVector = cell.asInstanceOf[Vector[Int]]
|
||||
(Cell(cellVector(0), cellVector(1)), SensorCount(cellVector(2)))
|
||||
case cell: Map[_, _] => val cellMap = cell.asInstanceOf[Map[String, Int]]
|
||||
@@ -244,16 +243,15 @@ class SimulationConfigParser(input: Map[String, Any], simulationBehaviours: Simu
|
||||
val parseTruthHelper = (truthElement: Any) => {
|
||||
truthElement match {
|
||||
case truthObject: Vector[_] => {
|
||||
val truth: Truth = Truth(new BroadcastObject())
|
||||
println(truthElement)
|
||||
val truth: Truth = Truth()
|
||||
val start: Int = truthObject(0).asInstanceOf[Int]
|
||||
// val end: Option[Int] = None // Not used
|
||||
truth.set(parseDouble(truthObject(1)))
|
||||
Map[Time, Truth](Time(start, config.duration) -> truth)
|
||||
}
|
||||
case truthObject: Map[_, _] => {
|
||||
val truth: Truth = Truth(new BroadcastObject())
|
||||
lazy val endTruth: Truth = Truth(new BroadcastObject())
|
||||
val truth: Truth = Truth()
|
||||
lazy val endTruth: Truth = Truth()
|
||||
val truthObjectMap = truthObject.asInstanceOf[Map[String, Any]]
|
||||
val timeline: Vector[Any] = truthObjectMap("timeline").asInstanceOf[Vector[Any]]
|
||||
val timeLineVector: Vector[(Int, Option[Int])] = timeline.map(e => parseTimeLineElement(e))
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package scim.components
|
||||
|
||||
import scim.datastruct.{Behaviour, BehaviourVector, Cell, Configuration, FunctionArgs, GroundTruth, Group, Sensor, SensorCount, SensorResult, Time, Truth}
|
||||
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
||||
import scim.lib.simulation.SimulationBehaviour
|
||||
import scim.lib.simInterfaces.SimulationBehaviour
|
||||
import scim.lib.debugUtil.{DebugType, debug, debugf}
|
||||
|
||||
class Simulation(config: Configuration) {
|
||||
@@ -70,7 +69,7 @@ class Simulation(config: Configuration) {
|
||||
// pass either subGroup truth, if truth is available for subGroup, or the sensor parents truth
|
||||
val resTruth = if(subGroup.sensorParent.isEmpty) resultTruths(subGroup) else resultTruths(sharedMemory.groups(subGroup.parent.getOrElse(subGroup.name)))
|
||||
// construct dummy result for sensors with count 0
|
||||
val restSens = if(resultSensors.contains(subGroup)) resultSensors(subGroup) else Vector(SensorResult(new BroadcastObject()))
|
||||
val restSens = if(resultSensors.contains(subGroup)) resultSensors(subGroup) else Vector(SensorResult())
|
||||
simulate(time, cell, prevTruth, resTruth, restSens, element)
|
||||
})
|
||||
}
|
||||
@@ -96,7 +95,7 @@ class Simulation(config: Configuration) {
|
||||
val v: Vector[Option[(SimulationBehaviour, Option[FunctionArgs])]] = Vector.fill(time.duration)(None)
|
||||
GroundTruth(group, Some(Behaviour(BehaviourVector(v)))).simulate(cell, time, prevTruth, resultTruth)
|
||||
}
|
||||
debugf(DebugType.DEBUG, "simulate: Time: %s | Cell: %s | Group: %s | Truth: %s", time.toString, cell.toString, group.toString, resultTruth.value.peak())
|
||||
debugf(DebugType.DEBUG, "simulate: Time: %s | Cell: %s | Group: %s | Truth: %s", time.toString, cell.toString, group.toString, resultTruth.peak())
|
||||
// simulate the sensor
|
||||
sensor.simulate(time, resultTruth, resultSensors)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package scim.datastruct
|
||||
|
||||
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
||||
import scim.lib.simulation._
|
||||
|
||||
import scim.lib.ConcurrentBroadcast._
|
||||
import scim.lib.simInterfaces._
|
||||
import scim.lib.configInterfaces._
|
||||
import scala.collection.parallel.ForkJoinTaskSupport
|
||||
|
||||
// configuration
|
||||
@@ -59,26 +59,14 @@ case class SharedMemory(sensor: Map[Time, Map[Cell, Map[Group, Vector[SensorResu
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BroadcastHandler[A](broadcastObject: BroadcastObject[A]) {
|
||||
def get: A = {
|
||||
broadcastObject.watch()
|
||||
}
|
||||
def set(newValue: A): Unit = {
|
||||
broadcastObject.broadcast(newValue)
|
||||
}
|
||||
def exists: Boolean = {
|
||||
!broadcastObject.peak().isEmpty
|
||||
}
|
||||
def reset(): Unit = {
|
||||
broadcastObject.broadcastReset()
|
||||
}
|
||||
}
|
||||
case class SimulationBehaviours(functions: Map[String, SimulationBehaviour]) {
|
||||
def get(name: String): Option[SimulationBehaviour] = {
|
||||
if(functions.contains(name)) Some(functions(name)) else None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
case class SimulationConfig(duration: Int, runs: Int, tickfactor: Int = 1,
|
||||
parCell: Int = 0, parCellThreads: Int = 5,
|
||||
parGroup: Int = 0, parGroupThreads: Int = 5,
|
||||
@@ -87,7 +75,7 @@ case class SimulationConfig(duration: Int, runs: Int, tickfactor: Int = 1,
|
||||
val groupThreadPool: ForkJoinTaskSupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(parGroupThreads))
|
||||
val sensorThreadPool: ForkJoinTaskSupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(parSensorThreads))
|
||||
}
|
||||
case class SensorResult(result: BroadcastObject[(Group, Cell, Option[Double])]) extends BroadcastHandler(result)
|
||||
case class SensorResult() extends Result[(Group, Cell, Option[Double])]
|
||||
/* rough size estimation
|
||||
Group(name: String, sensorParent: Option[String] = None)
|
||||
String: 2*x, String: 2*x
|
||||
@@ -119,7 +107,8 @@ case class Group(name: String, sensorParent: Option[String] = None){
|
||||
}
|
||||
}
|
||||
}
|
||||
case class Truth(value: BroadcastObject[Option[Double]]) extends BroadcastHandler(value)
|
||||
|
||||
case class Truth() extends Result[Option[Double]]
|
||||
case class FunctionArgs(args: Map[String, Any])
|
||||
|
||||
case class BehaviourVector(function: Vector[Option[(SimulationBehaviour, Option[FunctionArgs])]],
|
||||
@@ -142,7 +131,7 @@ case class Behaviour(behaviour: BehaviourVector){
|
||||
|
||||
// while the gt depends on the cell, the object itself does not
|
||||
// unlike the sensor which is unique due to its count for each cell
|
||||
case class GroundTruth(group: Group, behaviour: Option[Behaviour]) {
|
||||
case class GroundTruth(group: Group, behaviour: Option[Behaviour]) extends SimObjectTruth {
|
||||
def simulate(cell: Cell, time: Time, prevTruth: Truth, result: Truth): Unit = {
|
||||
// don't need a truth, if the sensor uses another, but this should not happen
|
||||
// as the parser should not create a ground truth in this case
|
||||
@@ -157,7 +146,7 @@ case class GroundTruth(group: Group, behaviour: Option[Behaviour]) {
|
||||
}
|
||||
}
|
||||
|
||||
case class Sensor(group: Group, cell: Cell, count: SensorCount, behaviour: Behaviour, parSensor: Int, sensorThreadPool: ForkJoinTaskSupport) {
|
||||
case class Sensor(group: Group, cell: Cell, count: SensorCount, behaviour: Behaviour, parSensor: Int, sensorThreadPool: ForkJoinTaskSupport) extends SimObjectSensor {
|
||||
def simulate(time: Time, truth: Truth, results: Vector[SensorResult]): Unit = {
|
||||
if(count.count == 0) return // allows for dummy sensors in dependency chains
|
||||
if(parSensor != 0 && parSensor <= count.count) {
|
||||
|
||||
50
src/main/scala/scim/lib/Interfaces.scala
Normal file
50
src/main/scala/scim/lib/Interfaces.scala
Normal file
@@ -0,0 +1,50 @@
|
||||
package scim.lib
|
||||
|
||||
import scim.datastruct.{Behaviour, Cell, Group, SensorCount, SensorResult, Time, Truth}
|
||||
|
||||
import scala.collection.parallel.ForkJoinTaskSupport
|
||||
|
||||
package object simInterfaces {
|
||||
import scim.datastruct._
|
||||
// maybe change to by-name parameters? have to check performance gain
|
||||
type SimulationBehaviour = (Cell, Time, Option[Double], Option[FunctionArgs]) => Option[Double]
|
||||
|
||||
}
|
||||
|
||||
package object configInterfaces {
|
||||
|
||||
trait Result[A] {
|
||||
val result = new scim.lib.ConcurrentBroadcast.BroadcastObject[A]()
|
||||
def get: A = {
|
||||
result.watch()
|
||||
}
|
||||
def set(newValue: A): Unit = {
|
||||
result.broadcast(newValue)
|
||||
}
|
||||
def exists: Boolean = {
|
||||
!result.peak().isEmpty
|
||||
}
|
||||
def reset(): Unit = {
|
||||
result.broadcastReset()
|
||||
}
|
||||
def peak(): Option[A] = {
|
||||
result.peak()
|
||||
}
|
||||
}
|
||||
|
||||
trait SimObjectSensor {
|
||||
val cell: Cell
|
||||
val count: SensorCount
|
||||
val group: Group
|
||||
val parSensor: Int
|
||||
val sensorThreadPool: ForkJoinTaskSupport
|
||||
val behaviour: Behaviour
|
||||
def simulate(time: Time, truth: Truth, results: Vector[SensorResult]): Unit
|
||||
}
|
||||
|
||||
trait SimObjectTruth {
|
||||
val group: Group
|
||||
val behaviour: Option[Behaviour]
|
||||
def simulate(cell: Cell, time: Time, prevTruth: Truth, result:Truth): Unit
|
||||
}
|
||||
}
|
||||
@@ -322,13 +322,7 @@ package object yml {
|
||||
}
|
||||
}
|
||||
|
||||
package object simulation {
|
||||
import scim.datastruct._
|
||||
// maybe change to by-name parameters? have to check performance gain
|
||||
type SimulationBehaviour = (Cell, Time, Option[Double], Option[FunctionArgs]) => Option[Double]
|
||||
}
|
||||
|
||||
package object parser {
|
||||
package object parserUtil {
|
||||
def parseDouble(number: Any): Option[Double] = {
|
||||
number match {
|
||||
case t: java.lang.Number => Some(t.doubleValue())
|
||||
|
||||
Reference in New Issue
Block a user