[add] added missing block parsing
- added mergeMaps function to library - added block function to Cell class
This commit is contained in:
@@ -39,11 +39,10 @@ sensors:
|
|||||||
# all cells are declared to output the gt
|
# all cells are declared to output the gt
|
||||||
# of baseline for each into the console
|
# of baseline for each into the console
|
||||||
- group: baseline
|
- group: baseline
|
||||||
cells:
|
blocks:
|
||||||
- [0, 0, 0]
|
- start: [0, 0]
|
||||||
- [1, 1, 0]
|
end: [6, 6]
|
||||||
- [2, 2, 0]
|
count: 0
|
||||||
- [3, 3, 0]
|
|
||||||
|
|
||||||
groundtruths:
|
groundtruths:
|
||||||
- group: baseline
|
- group: baseline
|
||||||
|
|||||||
@@ -89,7 +89,9 @@ class SimulationConfigParser(input: Map[String, Any], simulationBehaviours: Simu
|
|||||||
private def parseSensor(sensor: Map[String, Any]): Unit = {
|
private def parseSensor(sensor: Map[String, Any]): Unit = {
|
||||||
val groupString = sensor("group").asInstanceOf[String]
|
val groupString = sensor("group").asInstanceOf[String]
|
||||||
val parentString: Option[String] = if(sensor.contains("parent")) Some(sensor("parent").asInstanceOf[String]) else None
|
val parentString: Option[String] = if(sensor.contains("parent")) Some(sensor("parent").asInstanceOf[String]) else None
|
||||||
val cells: Map[Cell, SensorCount] = parseCells(sensor("cells").asInstanceOf[Vector[Any]])
|
val cellsParsed: Map[Cell, SensorCount] = if(sensor.contains("cells")) parseCells(sensor("cells").asInstanceOf[Vector[Any]]) else Map()
|
||||||
|
val blocksParsed: Map[Cell, SensorCount] = if(sensor.contains("blocks")) parseBlocks(sensor("blocks").asInstanceOf[Vector[Any]]) else Map()
|
||||||
|
val cells = mergeMaps[Cell, SensorCount](blocksParsed, cellsParsed, (a: SensorCount, b: SensorCount) => a.add(b), SensorCount(0))
|
||||||
val group = Group(groupString, parentString)
|
val group = Group(groupString, parentString)
|
||||||
if(!groups.contains(groupString)) {
|
if(!groups.contains(groupString)) {
|
||||||
groups(groupString) = group
|
groups(groupString) = group
|
||||||
@@ -113,18 +115,41 @@ 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) = (inCell: Any) => inCell 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]]
|
||||||
(Cell(cellMap("x"), cellMap("y")), SensorCount(cellMap("count")))
|
(Cell(cellMap("x"), cellMap("y")), SensorCount(cellMap("count")))
|
||||||
case _ => throw new Exception("Invalid Cell: " + cell.toString)
|
case _ => throw new Exception("Invalid Cell: " + inCell.toString)
|
||||||
}
|
}
|
||||||
// traversableToMap iterates over the vector while parseCell returns a key value
|
// traversableToMap iterates over the vector while parseCell returns a key value
|
||||||
// pair for each element which than gets added to the returned map
|
// pair for each element which than gets added to the returned map
|
||||||
traversableToMap[Cell, SensorCount](cells, parseCell)
|
traversableToMap[Cell, SensorCount](cells, parseCell)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def parseBlocks(blocks: Vector[Any]): Map[Cell, SensorCount] = {
|
||||||
|
val parseBlock: Any => Map[Cell, SensorCount] = (inBlock: Any) => inBlock match {
|
||||||
|
case block: Map[_, _] => {
|
||||||
|
val blockMap = block.asInstanceOf[Map[String, Any]]
|
||||||
|
val start = blockMap("start").asInstanceOf[Vector[Int]]
|
||||||
|
val end = blockMap("end").asInstanceOf[Vector[Int]]
|
||||||
|
val count = blockMap("count").asInstanceOf[Int]
|
||||||
|
val blockCells = Cell(start(0), start(1)).block(Cell(end(0), end(1)))
|
||||||
|
val countPerCell: Int = count / blockCells.length
|
||||||
|
var countRest: Int = count % blockCells.length
|
||||||
|
|
||||||
|
val result: Vector[(Cell, SensorCount)] = blockCells.map(cell => {
|
||||||
|
val sensorCount = SensorCount(countPerCell + (if(countRest > 0) 1 else 0))
|
||||||
|
if(countRest > 0) countRest -= 1
|
||||||
|
cell -> sensorCount
|
||||||
|
})
|
||||||
|
result.toMap
|
||||||
|
}
|
||||||
|
case _ => throw new Exception("Invalid Block: " + inBlock.toString)
|
||||||
|
}
|
||||||
|
mergeMaps[Cell, SensorCount](blocks.map(parseBlock), (a: SensorCount, b: SensorCount) => a.add(b), SensorCount(0))
|
||||||
|
}
|
||||||
|
|
||||||
// don't add tickfacor here, this is done in parseTruth with config.time()
|
// don't add tickfacor here, this is done in parseTruth with config.time()
|
||||||
private def parseTimeLineElement(timeLineElement: Any): (Int, Option[Int]) = {
|
private def parseTimeLineElement(timeLineElement: Any): (Int, Option[Int]) = {
|
||||||
timeLineElement match {
|
timeLineElement match {
|
||||||
|
|||||||
@@ -126,6 +126,18 @@ case class Cell(x: Int, y: Int) {
|
|||||||
def distance(otherCell: Cell): Double = {
|
def distance(otherCell: Cell): Double = {
|
||||||
Math.sqrt(Math.pow(x - otherCell.x, 2) + Math.pow(y - otherCell.y, 2))
|
Math.sqrt(Math.pow(x - otherCell.x, 2) + Math.pow(y - otherCell.y, 2))
|
||||||
}
|
}
|
||||||
|
def block(otherCell: Cell): Vector[Cell] = {
|
||||||
|
val bottomLeft = Cell(math.min(x, otherCell.x), math.min(y, otherCell.y))
|
||||||
|
val topRight = Cell(math.max(x, otherCell.x), math.max(y, otherCell.y))
|
||||||
|
// add + 1 as topright is included in the block
|
||||||
|
val xCount = topRight.x - bottomLeft.x + 1
|
||||||
|
val yCount = topRight.y - bottomLeft.y + 1
|
||||||
|
Vector.tabulate(yCount)(yCoord => {
|
||||||
|
Vector.tabulate(xCount)(xCoord => {
|
||||||
|
Cell(xCoord + bottomLeft.x, yCoord + bottomLeft.y)
|
||||||
|
})
|
||||||
|
}).flatten
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case class Group(name: String, sensorParent: Option[String] = None){
|
case class Group(name: String, sensorParent: Option[String] = None){
|
||||||
// the sensorParent serves as indicator for the parser that a ground truth is not required
|
// the sensorParent serves as indicator for the parser that a ground truth is not required
|
||||||
|
|||||||
@@ -152,6 +152,18 @@ package object mapUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def mergeMaps[A, B](mapA: Map[A, B], mapB: Map[A, B], add: (B, B) => B, default: B): Map[A, B] = {
|
||||||
|
mapA ++ mapB.map(e => e._1 -> add(e._2, mapA.getOrElse(e._1, default)))
|
||||||
|
}
|
||||||
|
|
||||||
|
def mergeMaps[A, B](vector: Vector[Map[A, B]], add: (B, B) => B, default: B): Map[A, B] = {
|
||||||
|
if(vector.length > 1) {
|
||||||
|
mergeMaps(vector.head, mergeMaps(vector.tail, add, default), add, default)
|
||||||
|
} else {
|
||||||
|
vector.head
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def traversableToMap[A, B](traversable: Traversable[Any], getTuple: (Any) => (A, B) = (e: Any) => e.asInstanceOf[(A, B)]._1 -> e.asInstanceOf[(A, B)]._2): Map[A, B] = {
|
def traversableToMap[A, B](traversable: Traversable[Any], getTuple: (Any) => (A, B) = (e: Any) => e.asInstanceOf[(A, B)]._1 -> e.asInstanceOf[(A, B)]._2): Map[A, B] = {
|
||||||
// Traversable[Tuple[A, B]] can be converted via .map
|
// Traversable[Tuple[A, B]] can be converted via .map
|
||||||
// .foldLeft used in favor of .map().toMap as the latter needs two traversals
|
// .foldLeft used in favor of .map().toMap as the latter needs two traversals
|
||||||
|
|||||||
Reference in New Issue
Block a user