[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
|
||||
# of baseline for each into the console
|
||||
- group: baseline
|
||||
cells:
|
||||
- [0, 0, 0]
|
||||
- [1, 1, 0]
|
||||
- [2, 2, 0]
|
||||
- [3, 3, 0]
|
||||
blocks:
|
||||
- start: [0, 0]
|
||||
end: [6, 6]
|
||||
count: 0
|
||||
|
||||
groundtruths:
|
||||
- group: baseline
|
||||
|
||||
@@ -89,7 +89,9 @@ class SimulationConfigParser(input: Map[String, Any], simulationBehaviours: Simu
|
||||
private def parseSensor(sensor: Map[String, Any]): Unit = {
|
||||
val groupString = sensor("group").asInstanceOf[String]
|
||||
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)
|
||||
if(!groups.contains(groupString)) {
|
||||
groups(groupString) = group
|
||||
@@ -113,18 +115,41 @@ 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) = (inCell: Any) => inCell 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]]
|
||||
(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
|
||||
// pair for each element which than gets added to the returned map
|
||||
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()
|
||||
private def parseTimeLineElement(timeLineElement: Any): (Int, Option[Int]) = {
|
||||
timeLineElement match {
|
||||
|
||||
@@ -126,6 +126,18 @@ case class Cell(x: Int, y: Int) {
|
||||
def distance(otherCell: Cell): Double = {
|
||||
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){
|
||||
// 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] = {
|
||||
// Traversable[Tuple[A, B]] can be converted via .map
|
||||
// .foldLeft used in favor of .map().toMap as the latter needs two traversals
|
||||
|
||||
Reference in New Issue
Block a user