[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.components.{Parser, SimulationConfigParser, Output, Simulation}
|
||||||
import scim.datastruct.{Cell, FunctionArgs, SharedMemory, SimulationBehaviours, Time}
|
import scim.datastruct.{Cell, FunctionArgs, SharedMemory, SimulationBehaviours, Time}
|
||||||
import scim.lib._
|
import scim.lib._
|
||||||
import scim.lib.simulation.SimulationBehaviour
|
import scim.lib.simInterfaces.SimulationBehaviour
|
||||||
//package scim.components._
|
//package scim.components._
|
||||||
object Main {
|
object Main {
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import scim.datastruct.{Behaviour, BehaviourVector, Cell, Configuration, Functio
|
|||||||
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
||||||
import scim.lib.debugUtil.{DebugType, debugf}
|
import scim.lib.debugUtil.{DebugType, debugf}
|
||||||
import scim.lib.mapUtil._
|
import scim.lib.mapUtil._
|
||||||
import scim.lib.parser._
|
import scim.lib.simInterfaces.SimulationBehaviour
|
||||||
import scim.lib.simulation.SimulationBehaviour
|
|
||||||
import scim.lib.yml
|
import scim.lib.yml
|
||||||
|
import scim.lib.parserUtil._
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
||||||
class Parser() {
|
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
|
val configurationMapping = sensorList.map(cell => cell._1 -> cellMapper(cell._1, cell._2.toMap)).toMap
|
||||||
|
|
||||||
// construct shared memory sensor
|
// 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]) = {
|
def truthHelper(cell: Cell, list: Map[Group, List[(Group, Sensor, Option[GroundTruth])]]): (Cell, Map[Group, Truth]) = {
|
||||||
val groupList: mutable.Map[Group, Truth] = mutable.Map()
|
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
|
cell -> groupList.toMap
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +114,7 @@ class SimulationConfigParser(input: Map[String, Any], simulationBehaviours: Simu
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def parseCells(cells: Vector[Any]): Map[Cell, SensorCount] = {
|
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]]
|
case cell: Vector[_] => val cellVector = cell.asInstanceOf[Vector[Int]]
|
||||||
(Cell(cellVector(0), cellVector(1)), SensorCount(cellVector(2)))
|
(Cell(cellVector(0), cellVector(1)), SensorCount(cellVector(2)))
|
||||||
case cell: Map[_, _] => val cellMap = cell.asInstanceOf[Map[String, Int]]
|
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) => {
|
val parseTruthHelper = (truthElement: Any) => {
|
||||||
truthElement match {
|
truthElement match {
|
||||||
case truthObject: Vector[_] => {
|
case truthObject: Vector[_] => {
|
||||||
val truth: Truth = Truth(new BroadcastObject())
|
val truth: Truth = Truth()
|
||||||
println(truthElement)
|
|
||||||
val start: Int = truthObject(0).asInstanceOf[Int]
|
val start: Int = truthObject(0).asInstanceOf[Int]
|
||||||
// val end: Option[Int] = None // Not used
|
// val end: Option[Int] = None // Not used
|
||||||
truth.set(parseDouble(truthObject(1)))
|
truth.set(parseDouble(truthObject(1)))
|
||||||
Map[Time, Truth](Time(start, config.duration) -> truth)
|
Map[Time, Truth](Time(start, config.duration) -> truth)
|
||||||
}
|
}
|
||||||
case truthObject: Map[_, _] => {
|
case truthObject: Map[_, _] => {
|
||||||
val truth: Truth = Truth(new BroadcastObject())
|
val truth: Truth = Truth()
|
||||||
lazy val endTruth: Truth = Truth(new BroadcastObject())
|
lazy val endTruth: Truth = Truth()
|
||||||
val truthObjectMap = truthObject.asInstanceOf[Map[String, Any]]
|
val truthObjectMap = truthObject.asInstanceOf[Map[String, Any]]
|
||||||
val timeline: Vector[Any] = truthObjectMap("timeline").asInstanceOf[Vector[Any]]
|
val timeline: Vector[Any] = truthObjectMap("timeline").asInstanceOf[Vector[Any]]
|
||||||
val timeLineVector: Vector[(Int, Option[Int])] = timeline.map(e => parseTimeLineElement(e))
|
val timeLineVector: Vector[(Int, Option[Int])] = timeline.map(e => parseTimeLineElement(e))
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package scim.components
|
package scim.components
|
||||||
|
|
||||||
import scim.datastruct.{Behaviour, BehaviourVector, Cell, Configuration, FunctionArgs, GroundTruth, Group, Sensor, SensorCount, SensorResult, Time, Truth}
|
import scim.datastruct.{Behaviour, BehaviourVector, Cell, Configuration, FunctionArgs, GroundTruth, Group, Sensor, SensorCount, SensorResult, Time, Truth}
|
||||||
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
import scim.lib.simInterfaces.SimulationBehaviour
|
||||||
import scim.lib.simulation.SimulationBehaviour
|
|
||||||
import scim.lib.debugUtil.{DebugType, debug, debugf}
|
import scim.lib.debugUtil.{DebugType, debug, debugf}
|
||||||
|
|
||||||
class Simulation(config: Configuration) {
|
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
|
// 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)))
|
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
|
// 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)
|
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)
|
val v: Vector[Option[(SimulationBehaviour, Option[FunctionArgs])]] = Vector.fill(time.duration)(None)
|
||||||
GroundTruth(group, Some(Behaviour(BehaviourVector(v)))).simulate(cell, time, prevTruth, resultTruth)
|
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
|
// simulate the sensor
|
||||||
sensor.simulate(time, resultTruth, resultSensors)
|
sensor.simulate(time, resultTruth, resultSensors)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package scim.datastruct
|
package scim.datastruct
|
||||||
|
|
||||||
import scim.lib.ConcurrentBroadcast.BroadcastObject
|
import scim.lib.ConcurrentBroadcast._
|
||||||
import scim.lib.simulation._
|
import scim.lib.simInterfaces._
|
||||||
|
import scim.lib.configInterfaces._
|
||||||
import scala.collection.parallel.ForkJoinTaskSupport
|
import scala.collection.parallel.ForkJoinTaskSupport
|
||||||
|
|
||||||
// configuration
|
// 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]) {
|
case class SimulationBehaviours(functions: Map[String, SimulationBehaviour]) {
|
||||||
def get(name: String): Option[SimulationBehaviour] = {
|
def get(name: String): Option[SimulationBehaviour] = {
|
||||||
if(functions.contains(name)) Some(functions(name)) else None
|
if(functions.contains(name)) Some(functions(name)) else None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case class SimulationConfig(duration: Int, runs: Int, tickfactor: Int = 1,
|
case class SimulationConfig(duration: Int, runs: Int, tickfactor: Int = 1,
|
||||||
parCell: Int = 0, parCellThreads: Int = 5,
|
parCell: Int = 0, parCellThreads: Int = 5,
|
||||||
parGroup: Int = 0, parGroupThreads: 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 groupThreadPool: ForkJoinTaskSupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(parGroupThreads))
|
||||||
val sensorThreadPool: ForkJoinTaskSupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(parSensorThreads))
|
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
|
/* rough size estimation
|
||||||
Group(name: String, sensorParent: Option[String] = None)
|
Group(name: String, sensorParent: Option[String] = None)
|
||||||
String: 2*x, String: 2*x
|
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 FunctionArgs(args: Map[String, Any])
|
||||||
|
|
||||||
case class BehaviourVector(function: Vector[Option[(SimulationBehaviour, Option[FunctionArgs])]],
|
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
|
// 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
|
// 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 = {
|
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
|
// 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
|
// 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 = {
|
def simulate(time: Time, truth: Truth, results: Vector[SensorResult]): Unit = {
|
||||||
if(count.count == 0) return // allows for dummy sensors in dependency chains
|
if(count.count == 0) return // allows for dummy sensors in dependency chains
|
||||||
if(parSensor != 0 && parSensor <= count.count) {
|
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 {
|
package object parserUtil {
|
||||||
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 {
|
|
||||||
def parseDouble(number: Any): Option[Double] = {
|
def parseDouble(number: Any): Option[Double] = {
|
||||||
number match {
|
number match {
|
||||||
case t: java.lang.Number => Some(t.doubleValue())
|
case t: java.lang.Number => Some(t.doubleValue())
|
||||||
|
|||||||
Reference in New Issue
Block a user