From 2881b8d40ff75b36749879c516ccb055ad65ae69 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 16 Feb 2022 16:56:06 +0100 Subject: [PATCH 01/83] Rename package org.vadere.simulator.models.sir to org.vadere.simulator.models.infection --- .../Demos/TransmissionModel/scenarios/bottleneckA.scenario | 2 +- .../Demos/TransmissionModel/scenarios/bottleneckB.scenario | 2 +- .../scenarios/bottleneckB_socialDistancing.scenario | 2 +- .../Demos/TransmissionModel/scenarios/closeContact.scenario | 2 +- .../Demos/TransmissionModel/scenarios/passageway.scenario | 2 +- .../scenarios/queueScenario_publication.scenario | 2 +- .../scenarios/hamner-2020-life_postvis_template.scenario | 2 +- ...hamner-2020-life_postvis_template_seed_000_100fr.scenario | 2 +- .../validation/scenarios/hamner-2020-life_template.scenario | 2 +- .../validation/scenarios/lu-2020-life.scenario | 2 +- .../validation/scenarios/miller-2020-life_seed_000.scenario | 2 +- .../validation/scenarios/miller-2020-life_template.scenario | 2 +- .../scenarios/basic_2_density_discrete_ca_5_sources.scenario | 2 +- .../scenarios/queueScenario_modelComparison.scenario | 2 +- .../org/vadere/simulator/control/simulation/ScenarioRun.java | 2 +- .../models/{sir => infection}/AbstractSirModel.java | 2 +- .../vadere/simulator/models/{sir => infection}/SirModel.java | 2 +- .../models/{sir => infection}/TransmissionModel.java | 2 +- .../models/{sir => infection}/BaseSirModelTest.java | 2 +- .../simulator/models/{sir => infection}/SirModelTest.java | 5 +---- .../models/{sir => infection}/TransmissionModelTest.java | 4 ++-- 21 files changed, 22 insertions(+), 25 deletions(-) rename VadereSimulator/src/org/vadere/simulator/models/{sir => infection}/AbstractSirModel.java (93%) rename VadereSimulator/src/org/vadere/simulator/models/{sir => infection}/SirModel.java (83%) rename VadereSimulator/src/org/vadere/simulator/models/{sir => infection}/TransmissionModel.java (99%) rename VadereSimulator/tests/org/vadere/simulator/models/{sir => infection}/BaseSirModelTest.java (91%) rename VadereSimulator/tests/org/vadere/simulator/models/{sir => infection}/SirModelTest.java (88%) rename VadereSimulator/tests/org/vadere/simulator/models/{sir => infection}/TransmissionModelTest.java (98%) diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario index 572ec0498..4755d5ac3 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario @@ -62,7 +62,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario index 1899d272f..7faf3be5b 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario @@ -87,7 +87,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario index 2636dbfde..04c1217f6 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario @@ -87,7 +87,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario index 1ed8efbf0..25e32da2f 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario @@ -92,7 +92,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.0, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario b/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario index ebb8ecb98..c3b41bc6f 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario @@ -62,7 +62,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario index 132c22daf..67b5f6b64 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario @@ -120,7 +120,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario index beceb814d..2d84075f2 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario @@ -80,7 +80,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario index d6ff7e203..4afe86b4b 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario @@ -80,7 +80,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario index 3376514ef..da36b57d7 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario @@ -38,7 +38,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario index 0cdf52e18..8c72b4fa2 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario @@ -62,7 +62,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario index 1fde5fcdb..51bd98d38 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario @@ -45,7 +45,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario index f4d3c93cb..165b7975f 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario @@ -45,7 +45,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario index 5ceeb081d..537ffb802 100644 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario +++ b/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario @@ -101,7 +101,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario index d922e3513..d40aa4eca 100644 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario +++ b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario @@ -116,7 +116,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.sir.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, diff --git a/VadereSimulator/src/org/vadere/simulator/control/simulation/ScenarioRun.java b/VadereSimulator/src/org/vadere/simulator/control/simulation/ScenarioRun.java index 45c1ace8d..dd9ec2407 100644 --- a/VadereSimulator/src/org/vadere/simulator/control/simulation/ScenarioRun.java +++ b/VadereSimulator/src/org/vadere/simulator/control/simulation/ScenarioRun.java @@ -20,7 +20,7 @@ import org.vadere.simulator.control.scenarioelements.TargetChangerController; import org.vadere.simulator.models.MainModel; import org.vadere.simulator.models.MainModelBuilder; import org.vadere.simulator.models.potential.solver.EikonalSolverCacheProvider; -import org.vadere.simulator.models.sir.TransmissionModel; +import org.vadere.simulator.models.infection.TransmissionModel; import org.vadere.simulator.projects.Domain; import org.vadere.simulator.projects.RunnableFinishedListener; import org.vadere.simulator.projects.Scenario; diff --git a/VadereSimulator/src/org/vadere/simulator/models/sir/AbstractSirModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractSirModel.java similarity index 93% rename from VadereSimulator/src/org/vadere/simulator/models/sir/AbstractSirModel.java rename to VadereSimulator/src/org/vadere/simulator/models/infection/AbstractSirModel.java index 408f7c726..e21b094c7 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/sir/AbstractSirModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractSirModel.java @@ -1,4 +1,4 @@ -package org.vadere.simulator.models.sir; +package org.vadere.simulator.models.infection; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.scenario.AttributesAgent; diff --git a/VadereSimulator/src/org/vadere/simulator/models/sir/SirModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/SirModel.java similarity index 83% rename from VadereSimulator/src/org/vadere/simulator/models/sir/SirModel.java rename to VadereSimulator/src/org/vadere/simulator/models/infection/SirModel.java index a07ec2dfd..fa4fbb692 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/sir/SirModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/SirModel.java @@ -1,4 +1,4 @@ -package org.vadere.simulator.models.sir; +package org.vadere.simulator.models.infection; import org.vadere.simulator.models.Model; diff --git a/VadereSimulator/src/org/vadere/simulator/models/sir/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java similarity index 99% rename from VadereSimulator/src/org/vadere/simulator/models/sir/TransmissionModel.java rename to VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index ed1a31088..102a76540 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/sir/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -1,4 +1,4 @@ -package org.vadere.simulator.models.sir; +package org.vadere.simulator.models.infection; import org.vadere.annotation.factories.models.ModelClass; import org.vadere.simulator.context.VadereContext; diff --git a/VadereSimulator/tests/org/vadere/simulator/models/sir/BaseSirModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/BaseSirModelTest.java similarity index 91% rename from VadereSimulator/tests/org/vadere/simulator/models/sir/BaseSirModelTest.java rename to VadereSimulator/tests/org/vadere/simulator/models/infection/BaseSirModelTest.java index 7bd1380a6..54ca7186a 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/sir/BaseSirModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/BaseSirModelTest.java @@ -1,4 +1,4 @@ -package org.vadere.simulator.models.sir; +package org.vadere.simulator.models.infection; import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.models.AttributeSIR; diff --git a/VadereSimulator/tests/org/vadere/simulator/models/sir/SirModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/SirModelTest.java similarity index 88% rename from VadereSimulator/tests/org/vadere/simulator/models/sir/SirModelTest.java rename to VadereSimulator/tests/org/vadere/simulator/models/infection/SirModelTest.java index 5ea1748f1..e45b8d077 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/sir/SirModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/SirModelTest.java @@ -1,16 +1,13 @@ -package org.vadere.simulator.models.sir; +package org.vadere.simulator.models.infection; -import org.junit.Test; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.health.InfectionStatus; import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Topography; import org.vadere.util.geometry.shapes.VPoint; -import java.util.Collection; import java.util.LinkedList; import java.util.Random; -import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; diff --git a/VadereSimulator/tests/org/vadere/simulator/models/sir/TransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java similarity index 98% rename from VadereSimulator/tests/org/vadere/simulator/models/sir/TransmissionModelTest.java rename to VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java index 4c3c8435f..4aff1464f 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/sir/TransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java @@ -1,4 +1,4 @@ -package org.vadere.simulator.models.sir; +package org.vadere.simulator.models.infection; import org.junit.After; import org.junit.Assert; @@ -21,7 +21,7 @@ import org.vadere.util.geometry.shapes.*; import java.util.*; import static org.junit.Assert.*; -import static org.vadere.simulator.models.sir.TransmissionModel.*; +import static org.vadere.simulator.models.infection.TransmissionModel.*; import static org.vadere.state.scenario.AerosolCloud.createAerosolCloudShape; public class TransmissionModelTest { -- GitLab From fdbdd3960fc4ace55b39ad07c19635eee744048f Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 16 Feb 2022 17:35:29 +0100 Subject: [PATCH 02/83] Remove code related to SIR models; Add interface and abstract class for exposure models; Let TransmissionModel extend AbstractExposureModel; --- .../infection/AbstractExposureModel.java | 20 ++++++++++ .../models/infection/AbstractSirModel.java | 21 ----------- .../models/infection/ExposureModel.java | 8 ++++ .../simulator/models/infection/SirModel.java | 9 ----- .../models/infection/TransmissionModel.java | 7 +--- .../models/infection/BaseSirModelTest.java | 23 ------------ .../models/infection/SirModelTest.java | 29 --------------- .../state/attributes/models/AttributeSIR.java | 37 ------------------- 8 files changed, 29 insertions(+), 125 deletions(-) create mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java delete mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/AbstractSirModel.java create mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java delete mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/SirModel.java delete mode 100644 VadereSimulator/tests/org/vadere/simulator/models/infection/BaseSirModelTest.java delete mode 100644 VadereSimulator/tests/org/vadere/simulator/models/infection/SirModelTest.java delete mode 100644 VadereState/src/org/vadere/state/attributes/models/AttributeSIR.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java new file mode 100644 index 000000000..f69da1ab7 --- /dev/null +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java @@ -0,0 +1,20 @@ +package org.vadere.simulator.models.infection; + +import org.vadere.simulator.projects.Domain; +import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.util.logging.Logger; + +import java.util.Random; + +public abstract class AbstractExposureModel implements ExposureModel { + + // add default implementations and shared fields here to keep ExposureModel interface clean + + protected static Logger logger = Logger.getLogger(AbstractExposureModel.class); + + // this random provider everywhere to keep simulation reproducible + protected Random random; + protected Domain domain; + protected AttributesAgent attributesAgent; + +} diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractSirModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractSirModel.java deleted file mode 100644 index e21b094c7..000000000 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractSirModel.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.vadere.simulator.models.infection; - -import org.vadere.simulator.projects.Domain; -import org.vadere.state.attributes.scenario.AttributesAgent; -import org.vadere.util.logging.Logger; - -import java.util.Random; - -// TODO remove class AbstractSirModel if no additional models similar to TransmissionModel are implemented -public abstract class AbstractSirModel implements SirModel { - - // add default implementations and shared fields here to keep SirModel interface clean - - protected static Logger logger = Logger.getLogger(AbstractSirModel.class); - - // this random provider everywhere to keep simulation reproducible - protected Random random; - protected Domain domain; - protected AttributesAgent attributesAgent; - -} diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java new file mode 100644 index 000000000..8b9109619 --- /dev/null +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java @@ -0,0 +1,8 @@ +package org.vadere.simulator.models.infection; + +import org.vadere.simulator.models.Model; + +public interface ExposureModel extends Model { + // any methods **ALL** ExposureModel models have in common. + +} diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/SirModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/SirModel.java deleted file mode 100644 index fa4fbb692..000000000 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/SirModel.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.vadere.simulator.models.infection; - -import org.vadere.simulator.models.Model; - -// TODO remove class SirModel if no additional models similar to TransmissionModel are implemented -public interface SirModel extends Model { - // any methods **ALL** SIR models have in common. - -} diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index 102a76540..a1193ca17 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -39,15 +39,10 @@ import static org.vadere.state.scenario.Droplets.createTransformedDropletsShape; * */ @ModelClass -public class TransmissionModel implements Model { +public class TransmissionModel extends AbstractExposureModel { protected static Logger logger = Logger.getLogger(TransmissionModel.class); - // this random provider everywhere to keep simulation reproducible - protected Random random; - protected Domain domain; - protected AttributesAgent attributesAgent; - private AttributesTransmissionModel attributesTransmissionModel; double simTimeStepLength; Topography topography; diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/BaseSirModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/BaseSirModelTest.java deleted file mode 100644 index 54ca7186a..000000000 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/BaseSirModelTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.vadere.simulator.models.infection; - -import org.vadere.state.attributes.Attributes; -import org.vadere.state.attributes.models.AttributeSIR; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class BaseSirModelTest { - - public List getSimpleState() { - ArrayList attrList = new ArrayList<>(); - var att = new AttributeSIR(); - att.setInitialR(2.0); - ArrayList ids = new ArrayList<>(Arrays.asList(1, 2, 3)); - att.setInfectionZoneIds(ids); - attrList.add(att); - - return attrList; - } - -} diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/SirModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/SirModelTest.java deleted file mode 100644 index e45b8d077..000000000 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/SirModelTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.vadere.simulator.models.infection; - -import org.vadere.state.attributes.scenario.AttributesAgent; -import org.vadere.state.health.InfectionStatus; -import org.vadere.state.scenario.Pedestrian; -import org.vadere.state.scenario.Topography; -import org.vadere.util.geometry.shapes.VPoint; - -import java.util.LinkedList; -import java.util.Random; - -import static org.junit.Assert.assertEquals; - -public abstract class SirModelTest { - public abstract SirModel sirModel(); - - private void createPedestrian(Topography topography, VPoint pedPosition, int pedId, int targetId, InfectionStatus infectionStatus) { - Pedestrian pedestrian = new Pedestrian(new AttributesAgent(), new Random(1)); - pedestrian.setPosition(pedPosition); - pedestrian.setInfectionStatus(infectionStatus); - pedestrian.setId(pedId); - - LinkedList targetsPedestrian = new LinkedList<>(); - targetsPedestrian.add(targetId); - pedestrian.setTargets(targetsPedestrian); - - topography.addElement(pedestrian); - } -} \ No newline at end of file diff --git a/VadereState/src/org/vadere/state/attributes/models/AttributeSIR.java b/VadereState/src/org/vadere/state/attributes/models/AttributeSIR.java deleted file mode 100644 index f5919fbe5..000000000 --- a/VadereState/src/org/vadere/state/attributes/models/AttributeSIR.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.vadere.state.attributes.models; - -import org.vadere.annotation.factories.attributes.ModelAttributeClass; -import org.vadere.state.attributes.Attributes; - -import java.util.ArrayList; - -@ModelAttributeClass -public class AttributeSIR extends Attributes { - - // initial r-Value of SIR model - private double initialR = 0.8; - private ArrayList infectionZoneIds = new ArrayList<>(); - - - - - public double getInitialR() { - return initialR; - } - - public void setInitialR(double initialR) { - // all attribute setter must have this check to ensure they are not changed during simulation - checkSealed(); - this.initialR = initialR; - } - - public void setInfectionZoneIds(ArrayList infectionZoneIds) { - checkSealed(); - this.infectionZoneIds = infectionZoneIds; - } - - public ArrayList getInfectionZoneIds() { - return infectionZoneIds; - } -} - -- GitLab From e3c2d18aa0a6bee7ca58f839685508a068c798b7 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 16 Feb 2022 17:36:01 +0100 Subject: [PATCH 03/83] Add pseudocode for ThresholdResponseModel --- .../infection/AbstractDoseResponseModel.java | 20 +++++++ .../models/infection/DoseResponseModel.java | 8 +++ .../infection/ThresholdResponseModel.java | 55 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java create mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/DoseResponseModel.java create mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java new file mode 100644 index 000000000..041657a27 --- /dev/null +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java @@ -0,0 +1,20 @@ +package org.vadere.simulator.models.infection; + +import org.vadere.simulator.projects.Domain; +import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.util.logging.Logger; + +import java.util.Random; + +public abstract class AbstractDoseResponseModel implements DoseResponseModel { + + // add default implementations and shared fields here to keep ExposureModel interface clean + + protected static Logger logger = Logger.getLogger(AbstractDoseResponseModel.class); + + // this random provider everywhere to keep simulation reproducible + protected Random random; + protected Domain domain; + protected AttributesAgent attributesAgent; + +} diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/DoseResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/DoseResponseModel.java new file mode 100644 index 000000000..c9d699d3c --- /dev/null +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/DoseResponseModel.java @@ -0,0 +1,8 @@ +package org.vadere.simulator.models.infection; + +import org.vadere.simulator.models.Model; + +public interface DoseResponseModel extends Model { + // any methods **ALL** DoseResponseModel have in common. + +} diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java new file mode 100644 index 000000000..a4362aabd --- /dev/null +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java @@ -0,0 +1,55 @@ +package org.vadere.simulator.models.infection; + +import org.vadere.simulator.projects.Domain; +import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.scenario.Pedestrian; +import org.vadere.state.scenario.Topography; + +import java.util.Collection; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +public class ThresholdResponseModel extends AbstractDoseResponseModel { + + Topography topography; + + private double threshold; + //TODO replace threshold by private AttributesThresholdInfectionModel attributesThresholdInfectionModel; + + + @Override + public void initialize(List attributesList, Domain domain, AttributesAgent attributesPedestrian, Random random) { + this.domain = domain; + this.random = random; + this.topography = domain.getTopography(); + this.attributesAgent = attributesPedestrian; + + // this.attributesThresholdInfectionModel = Model.findAttributes(attributesList, AttributesThresholdInfectionModel.class); + this.threshold = 999; // + } + + @Override + public void preLoop(double simTimeInSec) { + + } + + @Override + public void postLoop(double simTimeInSec) { + //TODO check if this works in postLoop + Collection exposedPedestrians = topography.getPedestrianDynamicElements() + .getElements() + .stream() + .filter(pedestrian -> pedestrian.getPathogenAbsorbedLoad() > threshold).collect(Collectors.toSet()); + + for (Pedestrian pedestrian : exposedPedestrians) { + // pedestrian.setInfected(true); + } + } + + @Override + public void update(double simTimeInSec) { + + } +} -- GitLab From 8e14ef851b419ab47b7cdfe430ba8fc31be47158 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 17 Feb 2022 16:52:19 +0100 Subject: [PATCH 04/83] Add updatePedestrianDegreeOfExposure method --- .../vadere/simulator/models/infection/ExposureModel.java | 7 ++++++- .../simulator/models/infection/TransmissionModel.java | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java index 8b9109619..d3982330c 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java @@ -1,8 +1,13 @@ package org.vadere.simulator.models.infection; import org.vadere.simulator.models.Model; +import org.vadere.state.scenario.Pedestrian; public interface ExposureModel extends Model { - // any methods **ALL** ExposureModel models have in common. + + /** + * This method updates the degree of exposure of a pedestrian. + */ + void updatePedestrianDegreeOfExposure(final Pedestrian pedestrian, double degreeOfExposure); } diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index a1193ca17..4eaee2a0e 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -141,6 +141,11 @@ public class TransmissionModel extends AbstractExposureModel { } } + @Override + public void updatePedestrianDegreeOfExposure(Pedestrian pedestrian, double degreeOfExposure) { + pedestrian.absorbPathogen(degreeOfExposure); + } + public void executeAerosolCloudEmissionEvents(double simTimeInSec) { Collection infectedPedestrians = getInfectedPedestrians(topography); for (Pedestrian pedestrian : infectedPedestrians) { @@ -330,7 +335,7 @@ public class TransmissionModel extends AbstractExposureModel { .collect(Collectors.toSet()); for (Pedestrian ped : breathingInPedsInAerosolCloud) { - ped.absorbPathogen(aerosolCloud.getPathogenConcentration() * timeNormalizationConst); + updatePedestrianDegreeOfExposure(ped, aerosolCloud.getPathogenConcentration() * timeNormalizationConst); } } } @@ -349,7 +354,7 @@ public class TransmissionModel extends AbstractExposureModel { .filter(p -> droplets.getShape().contains(p.getPosition())) .collect(Collectors.toSet()); for (Pedestrian ped : breathingInPedsInDroplets) { - ped.absorbPathogen(droplets.getCurrentPathogenLoad()); + updatePedestrianDegreeOfExposure(ped, droplets.getCurrentPathogenLoad()); } } } -- GitLab From 5ae3a2a201a9d12ffc5c60c035cfc7471db934c9 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 17 Feb 2022 17:16:18 +0100 Subject: [PATCH 05/83] Add first draft of simple model that evaluates exposure based on proximity --- .../infection/ProximityExposureModel.java | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java new file mode 100644 index 000000000..0ffa25aa4 --- /dev/null +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java @@ -0,0 +1,101 @@ +package org.vadere.simulator.models.infection; + +import org.jetbrains.annotations.NotNull; +import org.vadere.annotation.factories.models.ModelClass; +import org.vadere.simulator.control.simulation.ControllerProvider; +import org.vadere.simulator.projects.Domain; +import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.InfectionStatus; +import org.vadere.state.scenario.Pedestrian; +import org.vadere.state.scenario.Topography; +import org.vadere.util.geometry.shapes.VCircle; +import org.vadere.util.geometry.shapes.VPoint; +import org.vadere.util.geometry.shapes.VShape; + +import java.util.Collection; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +/** + * Models the spread of infectious pathogen among pedestrians based a simple rule: + * Any pedestrian that approaches an infectious pedestrian so that the mutual distance falls below a defined + * threshold becomes exposed. + */ +@ModelClass +public class ProximityExposureModel extends AbstractExposureModel { + + /* + * defines the maximum possible degree of exposure a pedestrian can adopt + */ + private static final double MAX_DEG_OF_EXPOSURE = 1; + + Topography topography; + + //TODO replace radius by AttributesProximityExposureModel attributesProximityExposureModel; + private double radius; + + @Override + public void initialize(List attributesList, Domain domain, AttributesAgent attributesPedestrian, Random random) { + this.domain = domain; + this.random = random; + this.attributesAgent = attributesPedestrian; + this.radius = 0.5; + // this.attributesProximityExposureModel = Model.findAttributes(attributesList, AttributesProximityExposureModel.class); + this.topography = domain.getTopography(); + } + + @Override + public void registerToScenarioElementControllerEvents(ControllerProvider controllerProvider) { + super.registerToScenarioElementControllerEvents(controllerProvider); + } + + @Override + public void preLoop(double simTimeInSec) { + + } + + @Override + public void postLoop(double simTimeInSec) { + + } + + @Override + public void update(double simTimeInSec) { + Collection pedestrians; + pedestrians = topography.getPedestrianDynamicElements().getElements().stream().collect(Collectors.toSet()); + + Collection infectiousPedestrians = pedestrians.stream() + .filter(p -> p.getInfectionStatus().equals(InfectionStatus.INFECTIOUS)).collect(Collectors.toSet()); + + if (!infectiousPedestrians.isEmpty()) { + for (Pedestrian infectiousPedestrian : infectiousPedestrians) { + Collection exposedPedestrians = getPedestriansNearbyInfectiousPedestrian(pedestrians, infectiousPedestrian); + + for (Pedestrian pedestrian : exposedPedestrians) { + updatePedestrianDegreeOfExposure(pedestrian, MAX_DEG_OF_EXPOSURE); + } + } + } + + } + + @NotNull + private Collection getPedestriansNearbyInfectiousPedestrian(Collection pedestrians, Pedestrian infectiousPedestrian) { + VPoint position = infectiousPedestrian.getPosition(); + VShape areaOfExposure = new VCircle(position, radius); + + Collection exposedPedestrians = pedestrians + .stream() + .filter(p -> areaOfExposure.contains(p.getPosition())).collect(Collectors.toSet()); + return exposedPedestrians; + } + + @Override + public void updatePedestrianDegreeOfExposure(Pedestrian pedestrian, double degreeOfExposure) { + //TODO create method in Pedestrian + // pedestrian.incrementDegreeOfExposure(degreeOfExposure); + } + +} -- GitLab From 7eb7fddc82fff30d66331cc945c2d22843a80db4 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Fri, 18 Feb 2022 09:31:06 +0100 Subject: [PATCH 06/83] In Pedestrian add infectionStatus The right infectionStatus can be added by corresponding DoseResponseModel by calling addInfectionStatus(...). --- .../DoseResponseModelInfectionStatus.java | 9 +++++ ...ThresholdResponseModelInfectionStatus.java | 40 +++++++++++++++++++ .../org/vadere/state/scenario/Pedestrian.java | 25 +++++++++++- 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java create mode 100644 VadereState/src/org/vadere/state/health/ThresholdResponseModelInfectionStatus.java diff --git a/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java b/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java new file mode 100644 index 000000000..6c58ad860 --- /dev/null +++ b/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java @@ -0,0 +1,9 @@ +package org.vadere.state.health; + +public interface DoseResponseModelInfectionStatus { + // Getter + double getProbabilityOfInfection(); + + // Setter + void setProbabilityOfInfection(double probabilityOfInfection); +} diff --git a/VadereState/src/org/vadere/state/health/ThresholdResponseModelInfectionStatus.java b/VadereState/src/org/vadere/state/health/ThresholdResponseModelInfectionStatus.java new file mode 100644 index 000000000..6061591d9 --- /dev/null +++ b/VadereState/src/org/vadere/state/health/ThresholdResponseModelInfectionStatus.java @@ -0,0 +1,40 @@ +package org.vadere.state.health; + +/** + * Defines a pedestrian's infection status by means of a probability of infection. + */ +public class ThresholdResponseModelInfectionStatus implements DoseResponseModelInfectionStatus { + + private double probabilityOfInfection; + + /* + * default for pedestrian's probability of infection, when pedestrian has not been exposed yet + */ + private static final double DEF_PROBABILITY_OF_INFECTION = 0; + + + // Constructors + public ThresholdResponseModelInfectionStatus(double probabilityOfInfection) { + this.probabilityOfInfection = probabilityOfInfection; + } + + public ThresholdResponseModelInfectionStatus(ThresholdResponseModelInfectionStatus other) { + this.probabilityOfInfection = other.getProbabilityOfInfection(); + } + + public ThresholdResponseModelInfectionStatus() { + this(DEF_PROBABILITY_OF_INFECTION); + } + + // Getter + @Override + public double getProbabilityOfInfection() { + return probabilityOfInfection; + } + + // Setter + @Override + public void setProbabilityOfInfection(double probabilityOfInfection) { + this.probabilityOfInfection = probabilityOfInfection; + } +} diff --git a/VadereState/src/org/vadere/state/scenario/Pedestrian.java b/VadereState/src/org/vadere/state/scenario/Pedestrian.java index 499666987..1f76870c6 100644 --- a/VadereState/src/org/vadere/state/scenario/Pedestrian.java +++ b/VadereState/src/org/vadere/state/scenario/Pedestrian.java @@ -1,6 +1,7 @@ package org.vadere.state.scenario; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.DoseResponseModelInfectionStatus; import org.vadere.state.psychology.information.KnowledgeBase; import org.vadere.state.psychology.PsychologyStatus; import org.vadere.state.health.InfectionStatus; @@ -15,6 +16,7 @@ import org.vadere.state.simulation.VTrajectory; import org.vadere.state.types.ScenarioElementType; import org.vadere.util.geometry.shapes.VPoint; +import java.lang.reflect.InvocationTargetException; import java.util.*; public class Pedestrian extends Agent { @@ -34,6 +36,7 @@ public class Pedestrian extends Agent { private PsychologyStatus psychologyStatus; private HealthStatus healthStatus; + private DoseResponseModelInfectionStatus infectionStatus; private LinkedList groupIds; // TODO should actually be an attribute or a member of a subclass private LinkedList groupSizes; @@ -75,6 +78,7 @@ public class Pedestrian extends Agent { isLikelyInjured = false; psychologyStatus = new PsychologyStatus(null, new ThreatMemory(), SelfCategory.TARGET_ORIENTED, GroupMembership.OUT_GROUP, new KnowledgeBase()); healthStatus = new HealthStatus(); + infectionStatus = null; groupIds = new LinkedList<>(); groupSizes = new LinkedList<>(); modelPedestrianMap = new HashMap<>(); @@ -91,6 +95,11 @@ public class Pedestrian extends Agent { psychologyStatus = new PsychologyStatus(other.psychologyStatus); + if (other.infectionStatus != null) { + infectionStatus = other.infectionStatus; + } else { + infectionStatus = null; + } healthStatus = new HealthStatus(other.healthStatus); if (other.groupIds != null) { @@ -163,6 +172,10 @@ public class Pedestrian extends Agent { return ScenarioElementType.PEDESTRIAN; } + public double getProbabilityOfInfection() { + return infectionStatus.getProbabilityOfInfection(); + } + public InfectionStatus getInfectionStatus() { return healthStatus.getInfectionStatus(); } @@ -282,6 +295,10 @@ public class Pedestrian extends Agent { return modelPedestrianMap.put(modelPedestrian.getClass(), modelPedestrian); } + public void setProbabilityOfInfection(double probabilityOfInfection) { + infectionStatus.setProbabilityOfInfection(probabilityOfInfection); + } + public void setInfectionStatus(InfectionStatus infectionStatus) { healthStatus.setInfectionStatus(infectionStatus); } @@ -414,5 +431,11 @@ public class Pedestrian extends Agent { super.setTargets(targetIds); } - + public void addInfectionStatus(Class infectionStatusType) { + try { + infectionStatus = (DoseResponseModelInfectionStatus) infectionStatusType.getDeclaredConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + e.printStackTrace(); + } + } } -- GitLab From 934ad210f5326b47e1b6bd54e1a1bc8765a92f64 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Fri, 18 Feb 2022 11:43:21 +0100 Subject: [PATCH 07/83] [wip] replace HealthStatus by more flexible ExposureModelHealthStatus XYHealthStatus contains only the information required by XYExposureModel --- .../models/infection/TransmissionModel.java | 18 +-- .../models/AttributesTransmissionModel.java | 2 +- .../TransmissionModelSourceParameters.java | 10 +- .../health/ExposureModelHealthStatus.java | 13 +++ .../health/TransmissionModelHealthStatus.java | 103 ++++++++++++++++++ .../org/vadere/state/scenario/Pedestrian.java | 100 ++++++++++++----- 6 files changed, 202 insertions(+), 44 deletions(-) create mode 100644 VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java create mode 100644 VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index 4eaee2a0e..fae6f3d9e 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -1,5 +1,6 @@ package org.vadere.simulator.models.infection; +import org.lwjgl.system.CallbackI; import org.vadere.annotation.factories.models.ModelClass; import org.vadere.simulator.context.VadereContext; import org.vadere.simulator.control.scenarioelements.SourceController; @@ -14,6 +15,7 @@ import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesDroplets; import org.vadere.state.health.HealthStatus; import org.vadere.state.health.InfectionStatus; +import org.vadere.state.health.TransmissionModelHealthStatus; import org.vadere.state.scenario.*; import org.vadere.util.geometry.shapes.VLine; import org.vadere.util.geometry.shapes.VPoint; @@ -373,14 +375,14 @@ public class TransmissionModel extends AbstractExposureModel { TransmissionModelSourceParameters sourceParameters = defineSourceParameters(controller); Pedestrian ped = (Pedestrian) scenarioElement; - ped.setInfectionStatus(sourceParameters.getInfectionStatus()); - ped.setPathogenEmissionCapacity(attributesTransmissionModel.getPedestrianPathogenEmissionCapacity()); - ped.setPathogenAbsorptionRate(attributesTransmissionModel.getPedestrianPathogenAbsorptionRate()); - ped.setRespiratoryTimeOffset(random.nextDouble() * attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod()); - ped.setMinInfectiousDose(attributesTransmissionModel.getPedestrianMinInfectiousDose()); - ped.setExposedPeriod(attributesTransmissionModel.getExposedPeriod()); - ped.setInfectiousPeriod(attributesTransmissionModel.getInfectiousPeriod()); - ped.setRecoveredPeriod(attributesTransmissionModel.getRecoveredPeriod()); + ped.addHealthStatus(TransmissionModelHealthStatus.class); + ped.setInfectious(sourceParameters.isInfectious()); + ped.setDegreeOfExposure(0); + + //TODO cast healthStatus in method getHealthStatus() + ((TransmissionModelHealthStatus)ped.getHealthStatus()).setRespiratoryTimeOffset(random.nextDouble() * attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + ((TransmissionModelHealthStatus)ped.getHealthStatus()).setBreathingIn(false); + //TODO check exhalation start position null? logger.infof(">>>>>>>>>>>sourceControllerEvent at time: %f agentId: %d", simTimeInSec, scenarioElement.getId()); return ped; diff --git a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java index 74cc087fe..58856997a 100644 --- a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java @@ -50,7 +50,7 @@ public class AttributesTransmissionModel extends Attributes { private double dropletsPathogenLoadFactor; public AttributesTransmissionModel() { - this.transmissionModelSourceParameters = new ArrayList<>(Arrays.asList(new TransmissionModelSourceParameters(AttributesEmbedShape.ID_NOT_SET, InfectionStatus.SUSCEPTIBLE))); + this.transmissionModelSourceParameters = new ArrayList<>(Arrays.asList(new TransmissionModelSourceParameters(AttributesEmbedShape.ID_NOT_SET, false))); // Mean pedestrian healthStatus and aerosolCloud attributes, rahn-2021b-cdyn Table I; // Some of these values are defined as mean values but could/should be introduced as distributions diff --git a/VadereState/src/org/vadere/state/attributes/models/TransmissionModelSourceParameters.java b/VadereState/src/org/vadere/state/attributes/models/TransmissionModelSourceParameters.java index 9c11af875..4080c0370 100644 --- a/VadereState/src/org/vadere/state/attributes/models/TransmissionModelSourceParameters.java +++ b/VadereState/src/org/vadere/state/attributes/models/TransmissionModelSourceParameters.java @@ -6,19 +6,19 @@ import org.vadere.state.health.InfectionStatus; public class TransmissionModelSourceParameters extends Attributes { private int sourceId = -1; - private InfectionStatus infectionStatus = InfectionStatus.SUSCEPTIBLE; + private boolean infectious = false; public TransmissionModelSourceParameters() { } - public TransmissionModelSourceParameters(int sourceId, InfectionStatus infectionStatus) { + public TransmissionModelSourceParameters(int sourceId, boolean infectious) { this.sourceId = sourceId; - this.infectionStatus = infectionStatus; + this.infectious = infectious; } - public InfectionStatus getInfectionStatus() { - return infectionStatus; + public boolean isInfectious() { + return infectious; } public int getSourceId() { diff --git a/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java new file mode 100644 index 000000000..82ff63522 --- /dev/null +++ b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java @@ -0,0 +1,13 @@ +package org.vadere.state.health; + +public interface ExposureModelHealthStatus { + // Getter + boolean isInfectious(); + + double getDegreeOfExposure(); + + // Setter + void setInfectious(boolean infectious); + + void setDegreeOfExposure(double degreeOfExposure); +} diff --git a/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java b/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java new file mode 100644 index 000000000..719dbac20 --- /dev/null +++ b/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java @@ -0,0 +1,103 @@ +package org.vadere.state.health; + +import org.vadere.util.geometry.shapes.VPoint; + +public class TransmissionModelHealthStatus implements ExposureModelHealthStatus { + + // Member variables + boolean isInfectious; + double degreeOfExposure; + + boolean isBreathingIn; + double respiratoryTimeOffset; + VPoint exhalationStartPosition; + + + // Constructors + public TransmissionModelHealthStatus() { + this(false, 0, false, 0, null); + } + + public TransmissionModelHealthStatus(boolean isInfectious, double degreeOfExposure, boolean isBreathingIn, double respiratoryTimeOffset, VPoint exhalationStartPosition) { + this.isInfectious = isInfectious; + this.degreeOfExposure = degreeOfExposure; + this.isBreathingIn = isBreathingIn; + this.respiratoryTimeOffset = respiratoryTimeOffset; + this.exhalationStartPosition = exhalationStartPosition; + } + + public TransmissionModelHealthStatus(TransmissionModelHealthStatus other) { + this.isInfectious = other.isInfectious(); + this.degreeOfExposure = other.getDegreeOfExposure(); + this.isBreathingIn = other.isInfectious(); + this.respiratoryTimeOffset = other.getRespiratoryTimeOffset(); + this.exhalationStartPosition = other.getExhalationStartPosition(); + } + + + // Getter + @Override + public boolean isInfectious() { + return isInfectious; + } + + @Override + public double getDegreeOfExposure() { + return degreeOfExposure; + } + + public boolean isBreathingIn() { + return isBreathingIn; + } + + public double getRespiratoryTimeOffset() { + return respiratoryTimeOffset; + } + + public VPoint getExhalationStartPosition() { + return exhalationStartPosition; + } + + void updateRespiratoryCycle(double simTimeInSec) { + + } + + void incrementDegreeOfExposure(double deltaDegreeOfExposure) { + this.degreeOfExposure += deltaDegreeOfExposure; + } + + // Setter + @Override + public void setInfectious(boolean infectious) { + isInfectious = infectious; + } + + @Override + public void setDegreeOfExposure(double degreeOfExposure) { + this.degreeOfExposure = degreeOfExposure; + } + + public void setBreathingIn(boolean breathingIn) { + isBreathingIn = breathingIn; + } + + public void setRespiratoryTimeOffset(double respiratoryTimeOffset) { + this.respiratoryTimeOffset = respiratoryTimeOffset; + } + + public void setExhalationStartPosition(VPoint exhalationStartPosition) { + this.exhalationStartPosition = exhalationStartPosition; + } + + // Methods + + /* + * Defines whether the pedestrian inhales or exhales depending on the current simulation time, + * respiratoryTimeOffset, and periodLength. Assumes that periodLength for inhalation and exhalation are equally + * long. Pedestrian inhales when sin(time) > 0 or cos(time) == 1. + */ + public void updateRespiratoryCycle(double simTimeInSec, double periodLength) { + double b = 2.0 * Math.PI / periodLength; + setBreathingIn((Math.sin(b * (respiratoryTimeOffset + simTimeInSec)) > 0) || (Math.cos(b * (respiratoryTimeOffset + simTimeInSec)) == 1)); + } +} diff --git a/VadereState/src/org/vadere/state/scenario/Pedestrian.java b/VadereState/src/org/vadere/state/scenario/Pedestrian.java index 1f76870c6..0005dd23f 100644 --- a/VadereState/src/org/vadere/state/scenario/Pedestrian.java +++ b/VadereState/src/org/vadere/state/scenario/Pedestrian.java @@ -2,6 +2,7 @@ package org.vadere.state.scenario; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.health.DoseResponseModelInfectionStatus; +import org.vadere.state.health.ExposureModelHealthStatus; import org.vadere.state.psychology.information.KnowledgeBase; import org.vadere.state.psychology.PsychologyStatus; import org.vadere.state.health.InfectionStatus; @@ -35,7 +36,8 @@ public class Pedestrian extends Agent { private PsychologyStatus psychologyStatus; - private HealthStatus healthStatus; + private HealthStatus wrapperHealthStatus; + private ExposureModelHealthStatus healthStatus; private DoseResponseModelInfectionStatus infectionStatus; private LinkedList groupIds; // TODO should actually be an attribute or a member of a subclass @@ -77,7 +79,8 @@ public class Pedestrian extends Agent { isChild = false; isLikelyInjured = false; psychologyStatus = new PsychologyStatus(null, new ThreatMemory(), SelfCategory.TARGET_ORIENTED, GroupMembership.OUT_GROUP, new KnowledgeBase()); - healthStatus = new HealthStatus(); + wrapperHealthStatus = new HealthStatus(); + healthStatus = null; infectionStatus = null; groupIds = new LinkedList<>(); groupSizes = new LinkedList<>(); @@ -95,12 +98,19 @@ public class Pedestrian extends Agent { psychologyStatus = new PsychologyStatus(other.psychologyStatus); + if (other.healthStatus != null) { + healthStatus = other.healthStatus; + } else { + healthStatus = null; + } + if (other.infectionStatus != null) { infectionStatus = other.infectionStatus; } else { infectionStatus = null; } - healthStatus = new HealthStatus(other.healthStatus); + + wrapperHealthStatus = new HealthStatus(other.wrapperHealthStatus); if (other.groupIds != null) { groupIds = new LinkedList<>(other.groupIds); @@ -172,52 +182,66 @@ public class Pedestrian extends Agent { return ScenarioElementType.PEDESTRIAN; } + //TODO return specific healthStatusModel type + public ExposureModelHealthStatus getHealthStatus() { + return healthStatus; + } + + public boolean isInfectious() { + return healthStatus.isInfectious(); + } + + public double getDegreeOfExposure() { + return healthStatus.getDegreeOfExposure(); + } + + public double getProbabilityOfInfection() { return infectionStatus.getProbabilityOfInfection(); } public InfectionStatus getInfectionStatus() { - return healthStatus.getInfectionStatus(); + return wrapperHealthStatus.getInfectionStatus(); } public double getPathogenEmissionCapacity() { - return healthStatus.getPathogenEmissionCapacity(); + return wrapperHealthStatus.getPathogenEmissionCapacity(); } public double getPathogenAbsorptionRate() { - return healthStatus.getPathogenAbsorptionRate(); + return wrapperHealthStatus.getPathogenAbsorptionRate(); } public double getRespiratoryTimeOffset(){ - return healthStatus.getRespiratoryTimeOffset(); + return wrapperHealthStatus.getRespiratoryTimeOffset(); } public double getExposedPeriod() { - return healthStatus.getExposedPeriod(); + return wrapperHealthStatus.getExposedPeriod(); } public double getInfectiousPeriod() { - return healthStatus.getInfectiousPeriod(); + return wrapperHealthStatus.getInfectiousPeriod(); } public double getRecoveredPeriod() { - return healthStatus.getRecoveredPeriod(); + return wrapperHealthStatus.getRecoveredPeriod(); } public double getPathogenAbsorbedLoad() { - return healthStatus.getPathogenAbsorbedLoad(); + return wrapperHealthStatus.getPathogenAbsorbedLoad(); } public VPoint getStartBreatheOutPosition() { - return healthStatus.getStartBreatheOutPosition(); + return wrapperHealthStatus.getStartBreatheOutPosition(); } public boolean isBreathingIn() { - return healthStatus.isBreathingIn(); + return wrapperHealthStatus.isBreathingIn(); } public double getMinInfectiousDose() { - return healthStatus.getMinInfectiousDose(); + return wrapperHealthStatus.getMinInfectiousDose(); } @@ -295,48 +319,56 @@ public class Pedestrian extends Agent { return modelPedestrianMap.put(modelPedestrian.getClass(), modelPedestrian); } + public void setInfectious(boolean infectious) { + healthStatus.setInfectious(infectious); + } + + public void setDegreeOfExposure(double degreeOfExposure) { + healthStatus.setDegreeOfExposure(degreeOfExposure); + } + public void setProbabilityOfInfection(double probabilityOfInfection) { infectionStatus.setProbabilityOfInfection(probabilityOfInfection); } public void setInfectionStatus(InfectionStatus infectionStatus) { - healthStatus.setInfectionStatus(infectionStatus); + wrapperHealthStatus.setInfectionStatus(infectionStatus); } public void setStartBreatheOutPosition(VPoint startBreatheOutPosition) { - healthStatus.setStartBreatheOutPosition(startBreatheOutPosition); + wrapperHealthStatus.setStartBreatheOutPosition(startBreatheOutPosition); } public void setRespiratoryTimeOffset(double respiratoryTimeOffset) { - healthStatus.setRespiratoryTimeOffset(respiratoryTimeOffset); + wrapperHealthStatus.setRespiratoryTimeOffset(respiratoryTimeOffset); } public void setPathogenEmissionCapacity(double pathogenEmissionCapacity) { - healthStatus.setPathogenEmissionCapacity(pathogenEmissionCapacity); + wrapperHealthStatus.setPathogenEmissionCapacity(pathogenEmissionCapacity); } public void setPathogenAbsorptionRate(double pathogenAbsorptionRate) { - healthStatus.setPathogenAbsorptionRate(pathogenAbsorptionRate); + wrapperHealthStatus.setPathogenAbsorptionRate(pathogenAbsorptionRate); } public void setPathogenAbsorbedLoad(double absorbedLoad) { - healthStatus.setPathogenAbsorbedLoad(absorbedLoad); + wrapperHealthStatus.setPathogenAbsorbedLoad(absorbedLoad); } public void setMinInfectiousDose(double minInfectiousDose) { - healthStatus.setMinInfectiousDose(minInfectiousDose); + wrapperHealthStatus.setMinInfectiousDose(minInfectiousDose); } public void setExposedPeriod(double exposedPeriod) { - healthStatus.setExposedPeriod(exposedPeriod); + wrapperHealthStatus.setExposedPeriod(exposedPeriod); } public void setInfectiousPeriod(double infectiousPeriod) { - healthStatus.setInfectiousPeriod(infectiousPeriod); + wrapperHealthStatus.setInfectiousPeriod(infectiousPeriod); } public void setRecoveredPeriod(double recoveredPeriod) { - healthStatus.setRecoveredPeriod(recoveredPeriod); + wrapperHealthStatus.setRecoveredPeriod(recoveredPeriod); } // Methods @@ -360,26 +392,26 @@ public class Pedestrian extends Agent { } public double emitPathogen() { - return healthStatus.emitPathogen(); + return wrapperHealthStatus.emitPathogen(); } public void absorbPathogen(double pathogenConcentration) { - healthStatus.absorbPathogen(pathogenConcentration); + wrapperHealthStatus.absorbPathogen(pathogenConcentration); } public void updateInfectionStatus(double simTimeInSec) { - healthStatus.updateInfectionStatus(simTimeInSec); + wrapperHealthStatus.updateInfectionStatus(simTimeInSec); } public void updateRespiratoryCycle(double simTimeInSec, double periodLength) { - healthStatus.updateRespiratoryCycle(simTimeInSec, periodLength); + wrapperHealthStatus.updateRespiratoryCycle(simTimeInSec, periodLength); } public boolean isStartingBreatheOut() { - return healthStatus.isStartingBreatheOut(); + return wrapperHealthStatus.isStartingBreatheOut(); } public boolean isStartingBreatheIn() { - return healthStatus.isStartingBreatheIn(); + return wrapperHealthStatus.isStartingBreatheIn(); } // Overridden Methods @@ -438,4 +470,12 @@ public class Pedestrian extends Agent { e.printStackTrace(); } } + + public void addHealthStatus(Class healthStatusType) { + try { + healthStatus = (ExposureModelHealthStatus) healthStatusType.getDeclaredConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + e.printStackTrace(); + } + } } -- GitLab From 34328c64fc60ce09a4cc416d2c94883a8246e306 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Sat, 19 Feb 2022 14:45:12 +0100 Subject: [PATCH 08/83] Add helper methods --- .../health/TransmissionModelHealthStatus.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java b/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java index 719dbac20..70b8d3407 100644 --- a/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java @@ -10,12 +10,20 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus boolean isBreathingIn; double respiratoryTimeOffset; + + /* + * defines the position at which pedestrian starts current exhalation; + */ VPoint exhalationStartPosition; + /* + * reset value for simulation periods during which pedestrian inhales + */ + private final static VPoint RESET_EXHALATION_POSITION = null; // Constructors public TransmissionModelHealthStatus() { - this(false, 0, false, 0, null); + this(false, 0, false, 0, RESET_EXHALATION_POSITION); } public TransmissionModelHealthStatus(boolean isInfectious, double degreeOfExposure, boolean isBreathingIn, double respiratoryTimeOffset, VPoint exhalationStartPosition) { @@ -62,7 +70,7 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus } - void incrementDegreeOfExposure(double deltaDegreeOfExposure) { + public void incrementDegreeOfExposure(double deltaDegreeOfExposure) { this.degreeOfExposure += deltaDegreeOfExposure; } @@ -100,4 +108,17 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus double b = 2.0 * Math.PI / periodLength; setBreathingIn((Math.sin(b * (respiratoryTimeOffset + simTimeInSec)) > 0) || (Math.cos(b * (respiratoryTimeOffset + simTimeInSec)) == 1)); } + + public boolean isStartingExhalation() { + return (!isBreathingIn && exhalationStartPosition == RESET_EXHALATION_POSITION); + } + + public boolean isStartingInhalation() { + return (isBreathingIn && !(exhalationStartPosition == RESET_EXHALATION_POSITION)); + } + + public void resetStartExhalationPosition() { + exhalationStartPosition = RESET_EXHALATION_POSITION; + } + } -- GitLab From dadc31409814e8b7a87569e6f3ea7b0d221dbd52 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Sat, 19 Feb 2022 14:45:36 +0100 Subject: [PATCH 09/83] Type cast in getHealthStatus method in Pedestrian --- .../models/infection/TransmissionModel.java | 28 ++++++++----------- .../org/vadere/state/scenario/Pedestrian.java | 5 ++-- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index fae6f3d9e..218a1ce97 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -1,6 +1,5 @@ package org.vadere.simulator.models.infection; -import org.lwjgl.system.CallbackI; import org.vadere.annotation.factories.models.ModelClass; import org.vadere.simulator.context.VadereContext; import org.vadere.simulator.control.scenarioelements.SourceController; @@ -14,7 +13,6 @@ import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesDroplets; import org.vadere.state.health.HealthStatus; -import org.vadere.state.health.InfectionStatus; import org.vadere.state.health.TransmissionModelHealthStatus; import org.vadere.state.scenario.*; import org.vadere.util.geometry.shapes.VLine; @@ -145,20 +143,20 @@ public class TransmissionModel extends AbstractExposureModel { @Override public void updatePedestrianDegreeOfExposure(Pedestrian pedestrian, double degreeOfExposure) { - pedestrian.absorbPathogen(degreeOfExposure); + pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).incrementDegreeOfExposure(degreeOfExposure); } public void executeAerosolCloudEmissionEvents(double simTimeInSec) { - Collection infectedPedestrians = getInfectedPedestrians(topography); - for (Pedestrian pedestrian : infectedPedestrians) { + Collection infectiousPedestrians = getInfectiousPedestrians(topography); + for (Pedestrian pedestrian : infectiousPedestrians) { // ... for each user-defined event createAerosolClouds(simTimeInSec, pedestrian); } } public void executeDropletEmissionEvents(double simTimeInSec) { - Collection infectedPedestrians = getInfectedPedestrians(topography); - for (Pedestrian pedestrian : infectedPedestrians) { + Collection infectiousPedestrians = getInfectiousPedestrians(topography); + for (Pedestrian pedestrian : infectiousPedestrians) { // ... for each user-defined event createDroplets(simTimeInSec, pedestrian); } @@ -177,10 +175,10 @@ public class TransmissionModel extends AbstractExposureModel { public void createAerosolClouds(double simTimeInSec, Pedestrian pedestrian) { - if (pedestrian.isStartingBreatheOut()) { - pedestrian.setStartBreatheOutPosition(pedestrian.getPosition()); + if (pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).isStartingExhalation()) { + pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).setExhalationStartPosition(pedestrian.getPosition()); - } else if (pedestrian.isStartingBreatheIn()) { + } else if (pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).isStartingInhalation()) { VPoint startBreatheOutPosition = pedestrian.getStartBreatheOutPosition(); VPoint stopBreatheOutPosition = pedestrian.getPosition(); VLine distanceWalkedDuringExhalation = new VLine(startBreatheOutPosition, stopBreatheOutPosition); @@ -361,11 +359,11 @@ public class TransmissionModel extends AbstractExposureModel { } } - public Collection getInfectedPedestrians(Topography topography) { + public Collection getInfectiousPedestrians(Topography topography) { return topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(p -> p.getInfectionStatus() == InfectionStatus.INFECTIOUS) + .filter(p -> p.isInfectious()) .collect(Collectors.toSet()); } @@ -378,10 +376,8 @@ public class TransmissionModel extends AbstractExposureModel { ped.addHealthStatus(TransmissionModelHealthStatus.class); ped.setInfectious(sourceParameters.isInfectious()); ped.setDegreeOfExposure(0); - - //TODO cast healthStatus in method getHealthStatus() - ((TransmissionModelHealthStatus)ped.getHealthStatus()).setRespiratoryTimeOffset(random.nextDouble() * attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod()); - ((TransmissionModelHealthStatus)ped.getHealthStatus()).setBreathingIn(false); + ped.getHealthStatus(TransmissionModelHealthStatus.class).setRespiratoryTimeOffset(random.nextDouble() * attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + ped.getHealthStatus(TransmissionModelHealthStatus.class).setBreathingIn(false); //TODO check exhalation start position null? logger.infof(">>>>>>>>>>>sourceControllerEvent at time: %f agentId: %d", simTimeInSec, scenarioElement.getId()); diff --git a/VadereState/src/org/vadere/state/scenario/Pedestrian.java b/VadereState/src/org/vadere/state/scenario/Pedestrian.java index 0005dd23f..dffc5feeb 100644 --- a/VadereState/src/org/vadere/state/scenario/Pedestrian.java +++ b/VadereState/src/org/vadere/state/scenario/Pedestrian.java @@ -182,9 +182,8 @@ public class Pedestrian extends Agent { return ScenarioElementType.PEDESTRIAN; } - //TODO return specific healthStatusModel type - public ExposureModelHealthStatus getHealthStatus() { - return healthStatus; + public T getHealthStatus(Class modelType) { + return modelType.cast(healthStatus); } public boolean isInfectious() { -- GitLab From c796a6e1faf2a677c26ceece879f18c827935aa1 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Sat, 19 Feb 2022 15:11:06 +0100 Subject: [PATCH 10/83] replace old healthStatus methods --- .../models/infection/TransmissionModel.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index 218a1ce97..02898a274 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -142,8 +142,8 @@ public class TransmissionModel extends AbstractExposureModel { } @Override - public void updatePedestrianDegreeOfExposure(Pedestrian pedestrian, double degreeOfExposure) { - pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).incrementDegreeOfExposure(degreeOfExposure); + public void updatePedestrianDegreeOfExposure(Pedestrian pedestrian, double deltaDegreeOfExposure) { + pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).incrementDegreeOfExposure(deltaDegreeOfExposure); } public void executeAerosolCloudEmissionEvents(double simTimeInSec) { @@ -179,15 +179,14 @@ public class TransmissionModel extends AbstractExposureModel { pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).setExhalationStartPosition(pedestrian.getPosition()); } else if (pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).isStartingInhalation()) { - VPoint startBreatheOutPosition = pedestrian.getStartBreatheOutPosition(); + VPoint startBreatheOutPosition = pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).getExhalationStartPosition(); VPoint stopBreatheOutPosition = pedestrian.getPosition(); VLine distanceWalkedDuringExhalation = new VLine(startBreatheOutPosition, stopBreatheOutPosition); AerosolCloud aerosolCloud = generateAerosolCloud(simTimeInSec, pedestrian, distanceWalkedDuringExhalation); topography.addAerosolCloud(aerosolCloud); - // reset pedestrian's startBreatheOutPosition - pedestrian.setStartBreatheOutPosition(null); + pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).resetStartExhalationPosition(); } } @@ -201,8 +200,8 @@ public class TransmissionModel extends AbstractExposureModel { center, simTimeInSec, attributesTransmissionModel.getAerosolCloudHalfLife(), - pedestrian.emitPathogen(), - pedestrian.emitPathogen())); + Math.pow(10, attributesTransmissionModel.getPedestrianPathogenEmissionCapacity()), + Math.pow(10, attributesTransmissionModel.getPedestrianPathogenEmissionCapacity()))); aerosolCloudIdCounter = aerosolCloudIdCounter + 1; @@ -242,7 +241,7 @@ public class TransmissionModel extends AbstractExposureModel { attributesTransmissionModel.getDropletsDistanceOfSpread(), Math.toRadians(attributesTransmissionModel.getDropletsAngleOfSpreadInDeg())); - double emittedPathogenLoad = pedestrian.emitPathogen() * attributesTransmissionModel.getDropletsPathogenLoadFactor(); + double emittedPathogenLoad = Math.pow(10, attributesTransmissionModel.getPedestrianPathogenEmissionCapacity()) * attributesTransmissionModel.getDropletsPathogenLoadFactor(); Droplets droplets = new Droplets(new AttributesDroplets(1, shape, @@ -314,7 +313,7 @@ public class TransmissionModel extends AbstractExposureModel { Collection allPedestrians = topography.getPedestrianDynamicElements().getElements(); for (Pedestrian pedestrian : allPedestrians) { pedestrian.updateInfectionStatus(simTimeInSec); - pedestrian.updateRespiratoryCycle(simTimeInSec, attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).updateRespiratoryCycle(simTimeInSec, attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod()); } } @@ -322,7 +321,7 @@ public class TransmissionModel extends AbstractExposureModel { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(Pedestrian::isBreathingIn) + .filter(p -> p.getHealthStatus(TransmissionModelHealthStatus.class).isBreathingIn()) .collect(Collectors.toSet()); // Agents absorb pathogen continuously but simulation is discrete. Therefore, the absorption must be adapted with normalizationFactor: @@ -344,7 +343,7 @@ public class TransmissionModel extends AbstractExposureModel { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(Pedestrian::isBreathingIn) + .filter(p -> p.getHealthStatus(TransmissionModelHealthStatus.class).isBreathingIn()) .collect(Collectors.toSet()); Collection allDroplets = topography.getDroplets(); @@ -363,7 +362,7 @@ public class TransmissionModel extends AbstractExposureModel { return topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(p -> p.isInfectious()) + .filter(Pedestrian::isInfectious) .collect(Collectors.toSet()); } -- GitLab From 4ca463171a58f2d682ee1d882e23813935bd31de Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 09:40:49 +0100 Subject: [PATCH 11/83] Remove deprecated NumberOfPedPerInfectionStatusProcessor --- .../queueScenario_publication.scenario | 3 -- ...hamner-2020-life_postvis_template.scenario | 3 -- ...e_postvis_template_seed_000_100fr.scenario | 3 -- .../hamner-2020-life_template.scenario | 5 +-- .../miller-2020-life_seed_000.scenario | 3 -- .../miller-2020-life_template.scenario | 3 -- ...c_2_density_discrete_ca_5_sources.scenario | 3 -- .../queueScenario_modelComparison.scenario | 3 -- ...umberOfPedPerInfectionStatusProcessor.java | 39 ------------------- 9 files changed, 1 insertion(+), 64 deletions(-) delete mode 100644 VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/NumberOfPedPerInfectionStatusProcessor.java diff --git a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario index 67b5f6b64..6a4d9c99b 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario @@ -75,9 +75,6 @@ "gridResolution" : 0.5, "timeResolution" : 4.0 } - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOfPedPerInfectionStatusProcessor", - "id" : 8 }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudLifeTimeProcessor", "id" : 9 diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario index 2d84075f2..bc169e8df 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario @@ -26,9 +26,6 @@ "processors" : [ 7 ] } ], "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOfPedPerInfectionStatusProcessor", - "id" : 1 - }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor", "id" : 2 }, { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario index 4afe86b4b..51e323c6f 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario @@ -26,9 +26,6 @@ "processors" : [ 7 ] } ], "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOfPedPerInfectionStatusProcessor", - "id" : 1 - }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor", "id" : 2 }, { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario index da36b57d7..69eb8a588 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario @@ -9,10 +9,7 @@ "filename" : "infectionStatus.txt", "processors" : [ 1 ] } ], - "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOfPedPerInfectionStatusProcessor", - "id" : 1 - } ], + "processors" : [ ], "isTimestamped" : false, "isWriteMetaData" : false }, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario index 51bd98d38..e243f5b9b 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario @@ -14,9 +14,6 @@ "processors" : [ 2 ] } ], "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOfPedPerInfectionStatusProcessor", - "id" : 1 - }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPathogenLoadMaxProcessor", "id" : 2 } ], diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario index 165b7975f..7d50defbb 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario @@ -14,9 +14,6 @@ "processors" : [ 2 ] } ], "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOfPedPerInfectionStatusProcessor", - "id" : 1 - }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPathogenLoadMaxProcessor", "id" : 2 } ], diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario index 537ffb802..d253412e6 100644 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario +++ b/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario @@ -51,9 +51,6 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepTargetIDProcessor", "id" : 7 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOfPedPerInfectionStatusProcessor", - "id" : 8 } ], "isTimestamped" : true, "isWriteMetaData" : false diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario index d40aa4eca..d5b5d97ab 100644 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario +++ b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario @@ -78,9 +78,6 @@ "gridResolution" : 0.5, "timeResolution" : 4.0 } - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOfPedPerInfectionStatusProcessor", - "id" : 8 }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudLifeTimeProcessor", "id" : 9 diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/NumberOfPedPerInfectionStatusProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/NumberOfPedPerInfectionStatusProcessor.java deleted file mode 100644 index bebb89dd7..000000000 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/NumberOfPedPerInfectionStatusProcessor.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.vadere.simulator.projects.dataprocessing.processor; - -import org.vadere.annotation.factories.dataprocessors.DataProcessorClass; -import org.vadere.simulator.control.simulation.SimulationState; -import org.vadere.simulator.projects.dataprocessing.ProcessorManager; -import org.vadere.simulator.projects.dataprocessing.datakey.TimestepKey; -import org.vadere.state.health.InfectionStatus; -import org.vadere.state.scenario.Pedestrian; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@DataProcessorClass() -public class NumberOfPedPerInfectionStatusProcessor extends DataProcessor> { - - public NumberOfPedPerInfectionStatusProcessor(){ - super("infection statuses placeholder"); - // super("S", "E", "I", "R"); // ToDo: iterate through enum InfectionStatus - } - - @Override - public void init(final ProcessorManager manager) { - super.init(manager); - } - - @Override - protected void doUpdate(SimulationState state) { - Collection peds = state.getTopography().getElements(Pedestrian.class); - List numberOfPed = new ArrayList<>(); - for (InfectionStatus infectionStatus : InfectionStatus.values()) { - numberOfPed.add(peds.stream().filter(p -> p.getInfectionStatus() == infectionStatus).count()); - - } - putValue(new TimestepKey(state.getStep()), numberOfPed); - } - -} - -- GitLab From 15c225fb446eef603519d27d0a159faa951ab65a Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 09:43:28 +0100 Subject: [PATCH 12/83] Remove deprecated PedestrianHealthStatusProcessor --- .../queueScenario_publication.scenario | 3 -- .../queueScenario_modelComparison.scenario | 3 -- .../PedestrianHealthStatusProcessor.java | 46 ------------------- 3 files changed, 52 deletions(-) delete mode 100644 VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianHealthStatusProcessor.java diff --git a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario index 6a4d9c99b..bc530eec0 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario @@ -78,9 +78,6 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudLifeTimeProcessor", "id" : 9 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianHealthStatusProcessor", - "id" : 10 }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepHealthStatusProcessor", "id" : 11 diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario index d5b5d97ab..490e51f80 100644 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario +++ b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario @@ -81,9 +81,6 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudLifeTimeProcessor", "id" : 9 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianHealthStatusProcessor", - "id" : 10 }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudAreaProcessor", "id" : 11 diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianHealthStatusProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianHealthStatusProcessor.java deleted file mode 100644 index 2a4f3eca1..000000000 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianHealthStatusProcessor.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.vadere.simulator.projects.dataprocessing.processor; - -import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.NotNull; -import org.vadere.annotation.factories.dataprocessors.DataProcessorClass; -import org.vadere.simulator.control.simulation.SimulationState; -import org.vadere.simulator.projects.dataprocessing.datakey.TimestepPedestrianIdKey; -import org.vadere.state.health.InfectionStatus; -import org.vadere.state.scenario.Pedestrian; - -import java.util.Collection; - -/** - * This processor returns pedestrians' absorbedPathogenLoad and InfectionStatus for each timeStep and pedestrianId - */ -@DataProcessorClass() -public class PedestrianHealthStatusProcessor extends DataProcessor> { - PedestrianHealthStatusProcessor() { - super("absorbedPathogenLoad", "InfectionStatus"); - } - - @Override - public void doUpdate(final SimulationState state) { - Collection peds = state.getTopography().getElements(Pedestrian.class); - for(Pedestrian ped : peds) { - TimestepPedestrianIdKey key = new TimestepPedestrianIdKey(state.getStep(), ped.getId()); - - setAbsorbedLoad(key, ped.getPathogenAbsorbedLoad()); - setInfectionStatus(key, ped.getInfectionStatus()); - } - } - - @Override - public String[] toStrings(@NotNull final TimestepPedestrianIdKey key) { - Pair times = getValue(key); - return new String[]{Double.toString(times.getLeft()), times.getRight().toString()}; - } - - private void setAbsorbedLoad(@NotNull final TimestepPedestrianIdKey key, double time) { - putValue(key, Pair.of(time, InfectionStatus.RECOVERED)); // InfectionStatus.RECOVERED is just a place holder - } - - private void setInfectionStatus(@NotNull final TimestepPedestrianIdKey key, InfectionStatus infectionStatus) { - putValue(key, Pair.of(getValue(key).getLeft(), infectionStatus)); - } -} -- GitLab From 438defd666c23e6fccab992b514e73b61cf805f4 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 09:49:56 +0100 Subject: [PATCH 13/83] [wip] Remove unused methods related to deprecated healthStatus --- .../infection/ProximityExposureModel.java | 3 +- .../infection/ThresholdResponseModel.java | 2 +- .../org/vadere/state/scenario/Pedestrian.java | 84 ------------------- 3 files changed, 2 insertions(+), 87 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java index 0ffa25aa4..d3e8e98a6 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java @@ -6,7 +6,6 @@ import org.vadere.simulator.control.simulation.ControllerProvider; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.scenario.AttributesAgent; -import org.vadere.state.health.InfectionStatus; import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Topography; import org.vadere.util.geometry.shapes.VCircle; @@ -67,7 +66,7 @@ public class ProximityExposureModel extends AbstractExposureModel { pedestrians = topography.getPedestrianDynamicElements().getElements().stream().collect(Collectors.toSet()); Collection infectiousPedestrians = pedestrians.stream() - .filter(p -> p.getInfectionStatus().equals(InfectionStatus.INFECTIOUS)).collect(Collectors.toSet()); + .filter(Pedestrian::isInfectious).collect(Collectors.toSet()); if (!infectiousPedestrians.isEmpty()) { for (Pedestrian infectiousPedestrian : infectiousPedestrians) { diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java index a4362aabd..ae4657ac8 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java @@ -41,7 +41,7 @@ public class ThresholdResponseModel extends AbstractDoseResponseModel { Collection exposedPedestrians = topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(pedestrian -> pedestrian.getPathogenAbsorbedLoad() > threshold).collect(Collectors.toSet()); + .filter(pedestrian -> pedestrian.getDegreeOfExposure() > threshold).collect(Collectors.toSet()); for (Pedestrian pedestrian : exposedPedestrians) { // pedestrian.setInfected(true); diff --git a/VadereState/src/org/vadere/state/scenario/Pedestrian.java b/VadereState/src/org/vadere/state/scenario/Pedestrian.java index dffc5feeb..cdac9b2bc 100644 --- a/VadereState/src/org/vadere/state/scenario/Pedestrian.java +++ b/VadereState/src/org/vadere/state/scenario/Pedestrian.java @@ -203,47 +203,10 @@ public class Pedestrian extends Agent { return wrapperHealthStatus.getInfectionStatus(); } - public double getPathogenEmissionCapacity() { - return wrapperHealthStatus.getPathogenEmissionCapacity(); - } - - public double getPathogenAbsorptionRate() { - return wrapperHealthStatus.getPathogenAbsorptionRate(); - } - - public double getRespiratoryTimeOffset(){ - return wrapperHealthStatus.getRespiratoryTimeOffset(); - } - - public double getExposedPeriod() { - return wrapperHealthStatus.getExposedPeriod(); - } - - public double getInfectiousPeriod() { - return wrapperHealthStatus.getInfectiousPeriod(); - } - - public double getRecoveredPeriod() { - return wrapperHealthStatus.getRecoveredPeriod(); - } - public double getPathogenAbsorbedLoad() { return wrapperHealthStatus.getPathogenAbsorbedLoad(); } - public VPoint getStartBreatheOutPosition() { - return wrapperHealthStatus.getStartBreatheOutPosition(); - } - - public boolean isBreathingIn() { - return wrapperHealthStatus.isBreathingIn(); - } - - public double getMinInfectiousDose() { - return wrapperHealthStatus.getMinInfectiousDose(); - } - - public VTrajectory getTrajectory() { return trajectory; } @@ -334,22 +297,6 @@ public class Pedestrian extends Agent { wrapperHealthStatus.setInfectionStatus(infectionStatus); } - public void setStartBreatheOutPosition(VPoint startBreatheOutPosition) { - wrapperHealthStatus.setStartBreatheOutPosition(startBreatheOutPosition); - } - - public void setRespiratoryTimeOffset(double respiratoryTimeOffset) { - wrapperHealthStatus.setRespiratoryTimeOffset(respiratoryTimeOffset); - } - - public void setPathogenEmissionCapacity(double pathogenEmissionCapacity) { - wrapperHealthStatus.setPathogenEmissionCapacity(pathogenEmissionCapacity); - } - - public void setPathogenAbsorptionRate(double pathogenAbsorptionRate) { - wrapperHealthStatus.setPathogenAbsorptionRate(pathogenAbsorptionRate); - } - public void setPathogenAbsorbedLoad(double absorbedLoad) { wrapperHealthStatus.setPathogenAbsorbedLoad(absorbedLoad); } @@ -358,18 +305,6 @@ public class Pedestrian extends Agent { wrapperHealthStatus.setMinInfectiousDose(minInfectiousDose); } - public void setExposedPeriod(double exposedPeriod) { - wrapperHealthStatus.setExposedPeriod(exposedPeriod); - } - - public void setInfectiousPeriod(double infectiousPeriod) { - wrapperHealthStatus.setInfectiousPeriod(infectiousPeriod); - } - - public void setRecoveredPeriod(double recoveredPeriod) { - wrapperHealthStatus.setRecoveredPeriod(recoveredPeriod); - } - // Methods public boolean isTarget() { return this.idAsTarget != -1; @@ -390,29 +325,10 @@ public class Pedestrian extends Agent { } } - public double emitPathogen() { - return wrapperHealthStatus.emitPathogen(); - } - - public void absorbPathogen(double pathogenConcentration) { - wrapperHealthStatus.absorbPathogen(pathogenConcentration); - } - public void updateInfectionStatus(double simTimeInSec) { wrapperHealthStatus.updateInfectionStatus(simTimeInSec); } - public void updateRespiratoryCycle(double simTimeInSec, double periodLength) { - wrapperHealthStatus.updateRespiratoryCycle(simTimeInSec, periodLength); - } - public boolean isStartingBreatheOut() { - return wrapperHealthStatus.isStartingBreatheOut(); - } - - public boolean isStartingBreatheIn() { - return wrapperHealthStatus.isStartingBreatheIn(); - } - // Overridden Methods @Override -- GitLab From cc5207db8c21e6b7c608ab3cd33033edecd6df23 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 09:59:50 +0100 Subject: [PATCH 14/83] [wip] Remove unused methods related to deprecated healthStatus Rename PedestrianPathogenLoadMaxProcessor --- .../miller-2020-life_seed_000.scenario | 2 +- .../miller-2020-life_template.scenario | 2 +- ...destrianMaxDegreeOfExposureProcessor.java} | 22 +++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) rename VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/{PedestrianPathogenLoadMaxProcessor.java => PedestrianMaxDegreeOfExposureProcessor.java} (60%) diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario index e243f5b9b..c74ed88c3 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario @@ -14,7 +14,7 @@ "processors" : [ 2 ] } ], "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPathogenLoadMaxProcessor", + "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianMaxDegreeOfExposureProcessor", "id" : 2 } ], "isTimestamped" : false, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario index 7d50defbb..8e4c7f81d 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario @@ -14,7 +14,7 @@ "processors" : [ 2 ] } ], "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPathogenLoadMaxProcessor", + "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianMaxDegreeOfExposureProcessor", "id" : 2 } ], "isTimestamped" : false, diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianPathogenLoadMaxProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianMaxDegreeOfExposureProcessor.java similarity index 60% rename from VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianPathogenLoadMaxProcessor.java rename to VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianMaxDegreeOfExposureProcessor.java index e99da8963..5f505d70a 100644 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianPathogenLoadMaxProcessor.java +++ b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianMaxDegreeOfExposureProcessor.java @@ -9,17 +9,17 @@ import org.vadere.state.scenario.Pedestrian; import java.util.Locale; /** - * Log the absorbed pathogen load when a pedestrian reaches its final target (i.e. the maximum load). If a pedestrian - * does not reach the target before the simulation ends, log current pathogen load (i.e., we enter the post loop and the - * topography still holds pedestrians). + * Log the degree of exposure when a pedestrian reaches its final target. If a pedestrian does not reach the target + * before the simulation ends, log current degree of exposure (i.e., we enter the post loop and the topography still + * holds pedestrians). * * Use a simple map with pedestrian.getId() as key and update the value in each simulation step. * This is a naive and inefficient approach, but it works. */ @DataProcessorClass() -public class PedestrianPathogenLoadMaxProcessor extends DataProcessor { - public PedestrianPathogenLoadMaxProcessor() { - super("pathogenLoad"); +public class PedestrianMaxDegreeOfExposureProcessor extends DataProcessor { + public PedestrianMaxDegreeOfExposureProcessor() { + super("degreeOfExposure"); } @Override @@ -27,7 +27,7 @@ public class PedestrianPathogenLoadMaxProcessor extends DataProcessor { PedestrianIdKey pedId = new PedestrianIdKey(pedestrian.getId()); - this.putValue(pedId, getAbsorbedPathogenLoad(pedestrian)); + this.putValue(pedId, getDegreeOfExposure(pedestrian)); }); } @@ -36,7 +36,7 @@ public class PedestrianPathogenLoadMaxProcessor extends DataProcessor { PedestrianIdKey pedId = new PedestrianIdKey(pedestrian.getId()); - this.putValue(pedId, getAbsorbedPathogenLoad(pedestrian)); + this.putValue(pedId, getDegreeOfExposure(pedestrian)); }); } @@ -45,8 +45,8 @@ public class PedestrianPathogenLoadMaxProcessor extends DataProcessor Date: Mon, 21 Feb 2022 10:04:58 +0100 Subject: [PATCH 15/83] [wip] Remove unused methods related to deprecated healthStatus Rename PedestrianPathogenLoadProcessor --- .../TransmissionModel/scenarios/closeContact.scenario | 2 +- .../scenarios/queueScenario_publication.scenario | 2 +- .../scenarios/queueScenario_modelComparison.scenario | 2 +- ...ssor.java => PedestrianDegreeOfExposureProcessor.java} | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) rename VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/{PedestrianPathogenLoadProcessor.java => PedestrianDegreeOfExposureProcessor.java} (68%) diff --git a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario index 25e32da2f..7cd3cc147 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario @@ -46,7 +46,7 @@ "pedestrianOverlapProcessorId" : 3 } }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPathogenLoadProcessor", + "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianDegreeOfExposureProcessor", "id" : 5 }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.PathogenConcentrationProcessor", diff --git a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario index bc530eec0..a75f47060 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario @@ -62,7 +62,7 @@ "pedestrianOverlapProcessorId" : 3 } }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPathogenLoadProcessor", + "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianDegreeOfExposureProcessor", "id" : 5 }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudCountingProcessor", diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario index 490e51f80..e0b957538 100644 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario +++ b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario @@ -65,7 +65,7 @@ "pedestrianOverlapProcessorId" : 3 } }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPathogenLoadProcessor", + "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianDegreeOfExposureProcessor", "id" : 5 }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudCountingProcessor", diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianPathogenLoadProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianDegreeOfExposureProcessor.java similarity index 68% rename from VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianPathogenLoadProcessor.java rename to VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianDegreeOfExposureProcessor.java index 7bb61980e..99538b54b 100644 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianPathogenLoadProcessor.java +++ b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/PedestrianDegreeOfExposureProcessor.java @@ -8,17 +8,17 @@ import org.vadere.state.scenario.Pedestrian; import java.util.Collection; /** - * This processor returns the absorbedPathogenLoad per pedestrian id at each simulation step + * This processor returns the degree of exposure per pedestrian id at each simulation step */ @DataProcessorClass() -public class PedestrianPathogenLoadProcessor extends DataProcessor { - public PedestrianPathogenLoadProcessor() { +public class PedestrianDegreeOfExposureProcessor extends DataProcessor { + public PedestrianDegreeOfExposureProcessor() { super("absorbedPathogenLoad"); } @Override public void doUpdate(final SimulationState state) { Collection peds = state.getTopography().getElements(Pedestrian.class); - peds.forEach(p -> this.putValue(new TimestepPedestrianIdKey(state.getStep(), p.getId()), p.getPathogenAbsorbedLoad())); + peds.forEach(p -> this.putValue(new TimestepPedestrianIdKey(state.getStep(), p.getId()), p.getDegreeOfExposure())); } } -- GitLab From 80d4b29b7ae99768de9f356e3f5d1d5c87398c73 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 10:36:16 +0100 Subject: [PATCH 16/83] [wip] Remove unused methods related to deprecated healthStatus Adapt information required for postvis --- .../components/view/SimulationRenderer.java | 64 +++++++++---------- .../model/PostvisualizationModel.java | 14 ++-- .../model/TableTrajectoryFootStep.java | 10 ++- .../TopographyController.java | 9 +-- .../FootStepHealthStatusProcessor.java | 11 ++-- .../simulator/projects/io/ColumnNames.java | 32 ++++------ .../infection/TransmissionModelTest.java | 18 +++--- .../org/vadere/state/scenario/Pedestrian.java | 12 ---- 8 files changed, 66 insertions(+), 104 deletions(-) diff --git a/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java b/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java index bb28e7e31..0df2df7c2 100644 --- a/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java +++ b/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java @@ -334,7 +334,7 @@ public abstract class SimulationRenderer extends DefaultRenderer { case INFECTION_STATUS: { if (agent instanceof Pedestrian) { Pedestrian pedestrian = (Pedestrian) agent; - return getInfectionStatusColor(pedestrian.getInfectionStatus(), pedestrian.getPathogenAbsorbedLoad(), pedestrian.getMinInfectiousDose()); + return getHealthStatusColor(pedestrian.isInfectious(), pedestrian.getDegreeOfExposure()); } } default: return model.config.getPedestrianColor(); @@ -342,40 +342,36 @@ public abstract class SimulationRenderer extends DefaultRenderer { } } - public Color getInfectionStatusColor(InfectionStatus infectionStatus, double absorbedPathogenLoad, double minInfectiousDose) { - Color color = model.config.getInfectionStatusColor(infectionStatus); - boolean interpolateColors = true; // ToDo define as checkbox in settings dialog - - double minAbsorbedPathogenLoad = 0; - double maxAbsorbedPathogenLoad = minInfectiousDose; - float t = (float) ((absorbedPathogenLoad - minAbsorbedPathogenLoad) / maxAbsorbedPathogenLoad); - - // if no color defined explicitly for each status (= default pedestrian color is applied) -> use default values - for (InfectionStatus status : InfectionStatus.values()) { - if (model.config.getInfectionStatusColor(status).equals(model.config.getDefaultInfectionStatusColor(InfectionStatus.SUSCEPTIBLE))) { - model.config.setInfectionStatusColor(status, model.config.getDefaultInfectionStatusColor(status)); - } + public Color getHealthStatusColor(boolean infectious, double degreeOfExposure) { + Color color; + + double minDegreeOfExposure = 0; + double maxDegreeOfExposure = 1000; //TODO value to be defined in settings dialog + float t = (float) ((degreeOfExposure - minDegreeOfExposure) / maxDegreeOfExposure); + +// // if no color defined explicitly for each status (= default pedestrian color is applied) -> use default values +// for (InfectionStatus status : InfectionStatus.values()) { +// +// if (model.config.getHealthStatusColor(status).equals(model.config.getDefaultInfectionStatusColor(InfectionStatus.SUSCEPTIBLE))) { +// model.config.setInfectionStatusColor(status, model.config.getDefaultInfectionStatusColor(status)); +// } +// } + + //TODO adapt model.config + Color susceptibleColor = model.config.getPedestrianColor(); + Color exposedColor = model.config.getExposedColor(); + Color infectiousColor = model.config.getInfectiousColor(); + + if (degreeOfExposure <= minDegreeOfExposure) { + color = susceptibleColor; + } else if (degreeOfExposure >= maxDegreeOfExposure) { + color = exposedColor; + } else { + // color = ColorHelper.standardColorInterpolation(susceptibleColor, exposedColor, t); + color = ColorHelper.improvedColorInterpolation(susceptibleColor, exposedColor, t); } - - Color susceptibleColor = model.config.getInfectionStatusColor(InfectionStatus.SUSCEPTIBLE); - Color exposedColor = model.config.getInfectionStatusColor(InfectionStatus.EXPOSED); - - if (interpolateColors) { - switch (infectionStatus) { - case SUSCEPTIBLE: - case EXPOSED: - if (absorbedPathogenLoad <= minAbsorbedPathogenLoad) { // if (t < 0) - color = susceptibleColor; - } else if (absorbedPathogenLoad >= maxAbsorbedPathogenLoad) { // if (t > 1) - color = exposedColor; - } else { - // color = ColorHelper.standardColorInterpolation(susceptibleColor, exposedColor, t); - color = ColorHelper.improvedColorInterpolation(susceptibleColor, exposedColor, t); - } - break; - case INFECTIOUS: - case RECOVERED: - } + if (infectious) { + color = infectiousColor; } return color; } diff --git a/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java b/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java index 105a60b8a..bdfe8fb34 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java @@ -283,17 +283,13 @@ public class PostvisualizationModel extends SimulationModel newPedestrian.addFootStepToTrajectory(footStep)); - newPedestrian.setInfectionStatus(agentWrapper.getInfectionStatus()); - newPedestrian.setPathogenEmissionCapacity(agentWrapper.getPathogenEmissionCapacity()); - newPedestrian.setPathogenAbsorptionRate(agentWrapper.getPathogenAbsorptionRate()); - newPedestrian.setRespiratoryTimeOffset(agentWrapper.getRespiratoryTimeOffset()); - newPedestrian.setMinInfectiousDose(agentWrapper.getMinInfectiousDose()); - newPedestrian.setExposedPeriod(agentWrapper.getExposedPeriod()); - newPedestrian.setInfectiousPeriod(agentWrapper.getInfectiousPeriod()); - newPedestrian.setRecoveredPeriod(agentWrapper.getRecoveredPeriod()); + newPedestrian.setHealthStatus(agentWrapper.getHealthStatus()); } public void update(double simTimeInSec) { diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java index 11bc14b68..116f5a7ab 100644 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java +++ b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java @@ -11,12 +11,12 @@ import org.vadere.state.simulation.FootStep; import java.util.LinkedList; /** - * Log {@link Pedestrian}'s current {@link HealthStatus} + * Log {@link Pedestrian}'s current {@link org.vadere.state.health.ExposureModelHealthStatus} */ @DataProcessorClass() public class FootStepHealthStatusProcessor extends DataProcessor { - public static String[] HEADERS = {"infectionStatus", "absorbedPathogenLoad", "minInfectiousDose"}; + public static String[] HEADERS = {"isInfectious", "degreeOfExposure"}; public FootStepHealthStatusProcessor() { super(HEADERS); @@ -37,10 +37,9 @@ public class FootStepHealthStatusProcessor extends DataProcessor selfCategoryKeys; private Set informationStateKeys; private Set groupMembershipKeys; - private Set infectionStatusKeys; - private Set absorbedPathogenLoadKeys; - private Set minInfectiousDoseKeys; + private Set isInfectiousKeys; + private Set degreeOfExposureKeys; private Set aerosolCloudIdKeys; private Set aerosolCloudPathogenLoadKeys; private Set aerosolCloudRadiusKeys; @@ -64,9 +63,8 @@ public final class ColumnNames { selfCategoryKeys = new HashSet<>(); informationStateKeys = new HashSet<>(); groupMembershipKeys = new HashSet<>(); - infectionStatusKeys = new HashSet<>(); - absorbedPathogenLoadKeys = new HashSet<>(); - minInfectiousDoseKeys = new HashSet<>(); + isInfectiousKeys = new HashSet<>(); + degreeOfExposureKeys = new HashSet<>(); aerosolCloudIdKeys = new HashSet<>(); aerosolCloudPathogenLoadKeys = new HashSet<>(); aerosolCloudRadiusKeys = new HashSet<>(); @@ -109,9 +107,8 @@ public final class ColumnNames { informationStateKeys.add("informationState"); groupMembershipKeys.add("groupMembership"); - infectionStatusKeys.add("infectionStatus"); - absorbedPathogenLoadKeys.add("absorbedPathogenLoad"); - minInfectiousDoseKeys.add("minInfectiousDose"); + isInfectiousKeys.add("isInfectious"); + degreeOfExposureKeys.add("degreeOfExposure"); aerosolCloudIdKeys.add("id"); aerosolCloudPathogenLoadKeys.add("pathogenLoad"); @@ -134,9 +131,8 @@ public final class ColumnNames { keys.add(selfCategoryKeys); keys.add(informationStateKeys); keys.add(groupMembershipKeys); - keys.add(infectionStatusKeys); - keys.add(absorbedPathogenLoadKeys); - keys.add(minInfectiousDoseKeys); + keys.add(isInfectiousKeys); + keys.add(degreeOfExposureKeys); keys.add(aerosolCloudIdKeys); keys.add(aerosolCloudPathogenLoadKeys); keys.add(aerosolCloudRadiusKeys); @@ -164,16 +160,12 @@ public final class ColumnNames { return getColId(dataFrame, groupMembershipKeys); } - public int getInfectionStatusCol(@NotNull final Table dataFrame) { - return getColId(dataFrame, infectionStatusKeys); + public int getIsInfectiousCol(@NotNull final Table dataFrame) { + return getColId(dataFrame, isInfectiousKeys); } - public int getAbsorbedPathogenLoadCol(@NotNull final Table dataFrame) { - return getColId(dataFrame, absorbedPathogenLoadKeys); - } - - public int getMinInfectiousDoseCol(@NotNull final Table dataFrame) { - return getColId(dataFrame, minInfectiousDoseKeys); + public int getDegreeOfExposureCol(@NotNull final Table dataFrame) { + return getColId(dataFrame, degreeOfExposureKeys); } public int getAerosolCloudIdCol(@NotNull final Table dataFrame) { diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java index 4aff1464f..d78079ba2 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java @@ -79,10 +79,10 @@ public class TransmissionModelTest { return attrList; } - private void createPedestrian(Topography topography, VPoint pedPosition, int pedId, int targetId, InfectionStatus infectionStatus) { + private void createPedestrian(Topography topography, VPoint pedPosition, int pedId, int targetId, boolean isInfectious) { Pedestrian pedestrian = new Pedestrian(new AttributesAgent(), new Random(1)); pedestrian.setPosition(pedPosition); - pedestrian.setInfectionStatus(infectionStatus); + pedestrian.setInfectious(isInfectious); pedestrian.setId(pedId); LinkedList targetsPedestrian = new LinkedList<>(); @@ -105,7 +105,7 @@ public class TransmissionModelTest { transmissionModel.initialize(attributeList, new Domain(topography),null,null); - createPedestrian(topography, new VPoint(10, 10), 1, -1, InfectionStatus.INFECTIOUS); + createPedestrian(topography, new VPoint(10, 10), 1, -1, true); double simTimeInSec = 0.0; double simTimeStepLength = 0.4; @@ -125,7 +125,7 @@ public class TransmissionModelTest { @Test public void throwIfPedestrianInsideAerosolCloudNotDetected() { Topography topography = new Topography(); - createPedestrian(topography, new VPoint(10, 10), 1, -1, InfectionStatus.SUSCEPTIBLE); + createPedestrian(topography, new VPoint(10, 10), 1, -1, false); AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(new VCircle(new VPoint(10, 10), 1), 0.0)); topography.addAerosolCloud(aerosolCloud); boolean inAerosolCloud = isPedestrianInAerosolCloud(aerosolCloud, topography.getPedestrianDynamicElements().getElement(1)); @@ -136,7 +136,7 @@ public class TransmissionModelTest { @Test public void throwIfPedestrianOutsideAerosolCloudConsideredInside() { Topography topography = new Topography(); - createPedestrian(topography, new VPoint(5, 5), 1, -1, InfectionStatus.SUSCEPTIBLE); + createPedestrian(topography, new VPoint(5, 5), 1, -1, false); AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(new VCircle(new VPoint(10, 10), 1), 0.0)); topography.addAerosolCloud(aerosolCloud); boolean inAerosolCloud = isPedestrianInAerosolCloud(aerosolCloud, topography.getPedestrianDynamicElements().getElement(1)); @@ -151,11 +151,11 @@ public class TransmissionModelTest { aerosolCloud.setId(1); topography.addAerosolCloud(aerosolCloud); // pedestrians outside cloud - createPedestrian(topography, new VPoint(12, 12), 2, -1, InfectionStatus.SUSCEPTIBLE); - createPedestrian(topography, new VPoint(1, 1), 3, -1, InfectionStatus.SUSCEPTIBLE); + createPedestrian(topography, new VPoint(12, 12), 2, -1, false); + createPedestrian(topography, new VPoint(1, 1), 3, -1,false); // pedestrians inside cloud - createPedestrian(topography, new VPoint(10, 10), 4, -1, InfectionStatus.SUSCEPTIBLE); - createPedestrian(topography, new VPoint(10.5, 10.5), 5, -1, InfectionStatus.SUSCEPTIBLE); + createPedestrian(topography, new VPoint(10, 10), 4, -1, false); + createPedestrian(topography, new VPoint(10.5, 10.5), 5, -1, false); Collection expectedPedestriansInAerosolCloud = new LinkedList<>(); expectedPedestriansInAerosolCloud.add(topography.getPedestrianDynamicElements().getElement(4)); diff --git a/VadereState/src/org/vadere/state/scenario/Pedestrian.java b/VadereState/src/org/vadere/state/scenario/Pedestrian.java index cdac9b2bc..b9f2f574a 100644 --- a/VadereState/src/org/vadere/state/scenario/Pedestrian.java +++ b/VadereState/src/org/vadere/state/scenario/Pedestrian.java @@ -203,10 +203,6 @@ public class Pedestrian extends Agent { return wrapperHealthStatus.getInfectionStatus(); } - public double getPathogenAbsorbedLoad() { - return wrapperHealthStatus.getPathogenAbsorbedLoad(); - } - public VTrajectory getTrajectory() { return trajectory; } @@ -297,14 +293,6 @@ public class Pedestrian extends Agent { wrapperHealthStatus.setInfectionStatus(infectionStatus); } - public void setPathogenAbsorbedLoad(double absorbedLoad) { - wrapperHealthStatus.setPathogenAbsorbedLoad(absorbedLoad); - } - - public void setMinInfectiousDose(double minInfectiousDose) { - wrapperHealthStatus.setMinInfectiousDose(minInfectiousDose); - } - // Methods public boolean isTarget() { return this.idAsTarget != -1; -- GitLab From 2931dafdfa7b30db9da2a7748166c14ddd853703 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 10:40:17 +0100 Subject: [PATCH 17/83] [wip] Remove unused methods related to deprecated healthStatus Rename enum in AgentColoring --- .../src/org/vadere/gui/components/model/AgentColoring.java | 2 +- .../src/org/vadere/gui/components/view/SettingsDialog.java | 2 +- .../src/org/vadere/gui/components/view/SimulationRenderer.java | 2 +- .../onlinevisualization/model/OnlineVisualizationModel.java | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/VadereGui/src/org/vadere/gui/components/model/AgentColoring.java b/VadereGui/src/org/vadere/gui/components/model/AgentColoring.java index b12446c6c..442006ceb 100644 --- a/VadereGui/src/org/vadere/gui/components/model/AgentColoring.java +++ b/VadereGui/src/org/vadere/gui/components/model/AgentColoring.java @@ -1,5 +1,5 @@ package org.vadere.gui.components.model; public enum AgentColoring { - TARGET, RANDOM, GROUP, EVACUATION_TIMES, PREDICATE, SELF_CATEGORY, INFECTION_STATUS, INFORMATION_STATE; + TARGET, RANDOM, GROUP, EVACUATION_TIMES, PREDICATE, SELF_CATEGORY, HEALTH_STATUS, INFORMATION_STATE; } diff --git a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java index f63a84436..3301d92d5 100644 --- a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java +++ b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java @@ -252,7 +252,7 @@ public class SettingsDialog extends JDialog { JRadioButton rbRandomColoring = createRadioButtonWithListener(AgentColoring.RANDOM, Messages.getString("SettingsDialog.chbUseRandomColors.text")); JRadioButton rbGroupColoring = createRadioButtonWithListener(AgentColoring.GROUP, Messages.getString("SettingsDialog.chbGroupColors.text")); JRadioButton rbSelfCategoryColoring = createRadioButtonWithListener(AgentColoring.SELF_CATEGORY, Messages.getString("SettingsDialog.lblSelfCategoryColoring.text")+ ":"); - JRadioButton rbInfectionStatusColoring = createRadioButtonWithListener(AgentColoring.INFECTION_STATUS, Messages.getString("SettingsDialog.lblInfectionStatusColoring.text")+ ":"); + JRadioButton rbInfectionStatusColoring = createRadioButtonWithListener(AgentColoring.HEALTH_STATUS, Messages.getString("SettingsDialog.lblHealthStatusColoring.text")+ ":"); JRadioButton rbInformationColoring = createRadioButtonWithListener(AgentColoring.INFORMATION_STATE, Messages.getString("SettingsDialog.lblInformationColoring.text")+ ":"); diff --git a/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java b/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java index 0df2df7c2..455783b7e 100644 --- a/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java +++ b/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java @@ -331,7 +331,7 @@ public abstract class SimulationRenderer extends DefaultRenderer { return model.getGroupColor((Pedestrian)agent); } } - case INFECTION_STATUS: { + case HEALTH_STATUS: { if (agent instanceof Pedestrian) { Pedestrian pedestrian = (Pedestrian) agent; return getHealthStatusColor(pedestrian.isInfectious(), pedestrian.getDegreeOfExposure()); diff --git a/VadereGui/src/org/vadere/gui/onlinevisualization/model/OnlineVisualizationModel.java b/VadereGui/src/org/vadere/gui/onlinevisualization/model/OnlineVisualizationModel.java index 65566300e..75f2b9039 100644 --- a/VadereGui/src/org/vadere/gui/onlinevisualization/model/OnlineVisualizationModel.java +++ b/VadereGui/src/org/vadere/gui/onlinevisualization/model/OnlineVisualizationModel.java @@ -15,7 +15,6 @@ import org.vadere.gui.components.model.DefaultSimulationConfig; import org.vadere.gui.components.model.SimulationModel; import org.vadere.gui.onlinevisualization.OnlineVisualization; import org.vadere.meshing.mesh.gen.AMesh; -import org.vadere.meshing.mesh.gen.PMesh; import org.vadere.meshing.mesh.inter.IMesh; import org.vadere.simulator.models.potential.fields.IPotentialField; import org.vadere.simulator.projects.Domain; @@ -256,7 +255,7 @@ public class OnlineVisualizationModel extends SimulationModel Date: Mon, 21 Feb 2022 15:35:51 +0100 Subject: [PATCH 18/83] [gui] adapt visualization of health status to new categorization infectious, not exposed, exposed; lower and upper limit for exposure are now user defined values --- VadereGui/resources/messages.properties | 5 +- VadereGui/resources/messages_de_DE.properties | 5 +- .../ActionSetInfectionStatusColor.java | 27 ----- .../ActionSetPedestrianDefaultColor.java | 18 +++ .../ActionSetPedestrianExposedColor.java | 18 +++ .../ActionSetPedestrianInfectiousColor.java | 18 +++ .../gui/components/model/DefaultConfig.java | 32 +++-- .../model/DefaultSimulationConfig.java | 70 +++++++++-- .../gui/components/view/SettingsDialog.java | 114 ++++++++++++------ .../components/view/SimulationRenderer.java | 37 +----- 10 files changed, 214 insertions(+), 130 deletions(-) delete mode 100644 VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetInfectionStatusColor.java create mode 100644 VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianDefaultColor.java create mode 100644 VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianExposedColor.java create mode 100644 VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianInfectiousColor.java diff --git a/VadereGui/resources/messages.properties b/VadereGui/resources/messages.properties index 435b56fbb..42e37f893 100644 --- a/VadereGui/resources/messages.properties +++ b/VadereGui/resources/messages.properties @@ -331,7 +331,10 @@ SettingsDialog.lblStair.text=Stair SettingsDialog.lblPedestrianNoTarget.text=Without Target SettingsDialog.lblTargetColoring.text=Coloring by Target SettingsDialog.lblSelfCategoryColoring.text=Coloring by Self Category -SettingsDialog.lblInfectionStatusColoring.text=Coloring by Infection Status +SettingsDialog.lblHealthStatusColoring.text=Coloring by Health Status +SettingsDialog.lblPedestrianLowerExposure.text=Lower Exposure +SettingsDialog.lblPedestrianUpperExposure.text=Upper Exposure +SettingsDialog.lblPedestrianInfectious.text=Infectious SettingsDialog.lblInformationColoring.text=Coloring by Information State ProjectView.menuOpenFloorFieldFile.title=Add Floor Field File... diff --git a/VadereGui/resources/messages_de_DE.properties b/VadereGui/resources/messages_de_DE.properties index 7def6aecb..17be97049 100644 --- a/VadereGui/resources/messages_de_DE.properties +++ b/VadereGui/resources/messages_de_DE.properties @@ -321,7 +321,10 @@ SettingsDialog.lblStair.text=Treppe SettingsDialog.lblPedestrianNoTarget.text=Ohne Ziel SettingsDialog.lblTargetColoring.text=F\u00e4rbung nach Ziel SettingsDialog.lblSelfCategoryColoring.text=F\u00e4rbung nach "Self Category" -SettingsDialog.lblInfectionStatusColoring.text=F\u00e4rbung nach "Infection Status" +SettingsDialog.lblHealthStatusColoring.text=F\u00e4rbung nach "Health Status" +SettingsDialog.lblPedestrianLowerExposure.text=Unterer Expositionsgrad +SettingsDialog.lblPedestrianUpperExposure.text=Oberer Expositionsgrad +SettingsDialog.lblPedestrianInfectious.text=Infekti\u00f6s SettingsDialog.menuOpenFloorFieldFile.title=Floor Field-Datei hinzuf\u00fcgen... SettingsDialog.btnDrawVoronoiDiagram.tooltip=Voronoi-Diagramm zeichnen und anzeigen SettingsDialog.chbLogo.text=VADERE-Logo anzeigen diff --git a/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetInfectionStatusColor.java b/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetInfectionStatusColor.java deleted file mode 100644 index d0c0ecaca..000000000 --- a/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetInfectionStatusColor.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.vadere.gui.components.control.simulation; - -import org.vadere.gui.components.model.DefaultSimulationConfig; -import org.vadere.gui.components.model.SimulationModel; -import org.vadere.state.health.InfectionStatus; - -import javax.swing.*; -import java.awt.*; - -public class ActionSetInfectionStatusColor extends ActionSetColor { - private final JComboBox comboBox; - - public ActionSetInfectionStatusColor(final String name, final SimulationModel model, final JPanel coloredPanel, - final JComboBox comboBox) { - super(name, model, coloredPanel); - this.comboBox = comboBox; - } - - @Override - protected void saveColor(Color color) { - InfectionStatus infectionStatus = comboBox.getItemAt(comboBox.getSelectedIndex()); - - if (infectionStatus != null) { - model.config.setInfectionStatusColor(infectionStatus, color); - } - } -} \ No newline at end of file diff --git a/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianDefaultColor.java b/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianDefaultColor.java new file mode 100644 index 000000000..f69ba5f00 --- /dev/null +++ b/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianDefaultColor.java @@ -0,0 +1,18 @@ +package org.vadere.gui.components.control.simulation; + +import org.vadere.gui.components.model.DefaultSimulationConfig; +import org.vadere.gui.components.model.SimulationModel; + +import javax.swing.*; +import java.awt.*; + +public class ActionSetPedestrianDefaultColor extends ActionSetColor { + public ActionSetPedestrianDefaultColor(String name, SimulationModel model, JPanel coloredPanel) { + super(name, model, coloredPanel); + } + + @Override + protected void saveColor(Color color) { + model.config.setPedestrianColor(color); + } +} \ No newline at end of file diff --git a/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianExposedColor.java b/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianExposedColor.java new file mode 100644 index 000000000..5e8206a64 --- /dev/null +++ b/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianExposedColor.java @@ -0,0 +1,18 @@ +package org.vadere.gui.components.control.simulation; + +import org.vadere.gui.components.model.DefaultSimulationConfig; +import org.vadere.gui.components.model.SimulationModel; + +import javax.swing.*; +import java.awt.*; + +public class ActionSetPedestrianExposedColor extends ActionSetColor { + public ActionSetPedestrianExposedColor(String name, SimulationModel model, JPanel coloredPanel) { + super(name, model, coloredPanel); + } + + @Override + protected void saveColor(Color color) { + model.config.setExposedColor(color); + } +} \ No newline at end of file diff --git a/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianInfectiousColor.java b/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianInfectiousColor.java new file mode 100644 index 000000000..8460127c8 --- /dev/null +++ b/VadereGui/src/org/vadere/gui/components/control/simulation/ActionSetPedestrianInfectiousColor.java @@ -0,0 +1,18 @@ +package org.vadere.gui.components.control.simulation; + +import org.vadere.gui.components.model.DefaultSimulationConfig; +import org.vadere.gui.components.model.SimulationModel; + +import javax.swing.*; +import java.awt.*; + +public class ActionSetPedestrianInfectiousColor extends ActionSetColor { + public ActionSetPedestrianInfectiousColor(String name, SimulationModel model, JPanel coloredPanel) { + super(name, model, coloredPanel); + } + + @Override + protected void saveColor(Color color) { + model.config.setInfectiousColor(color); + } +} \ No newline at end of file diff --git a/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java b/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java index 494779fbd..2e6d89928 100644 --- a/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java +++ b/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java @@ -1,6 +1,5 @@ package org.vadere.gui.components.model; -import org.vadere.state.health.InfectionStatus; import org.vadere.state.psychology.cognition.GroupMembership; import java.awt.*; @@ -23,14 +22,14 @@ public class DefaultConfig { private int aerosolCloudAlphaMax = 10; private int aerosolCloudAlphaMin = 0; private Color dropletsColor = new Color(190, 210, 20); + private Color exposedColor = new Color(202, 76, 187); + private Color infectiousColor = new Color(202, 76, 76); private HashMap groupMembershipColors = new HashMap<>(); - private HashMap infectionStatusColors = new HashMap<>(); private boolean changed = false; // Constructors public DefaultConfig() { initGroupMembershipColor(); - initInfectionStatusColor(); } public DefaultConfig(final DefaultConfig config) { @@ -48,8 +47,9 @@ public class DefaultConfig { this.aerosolCloudAlphaMax = config.aerosolCloudAlphaMax; this.aerosolCloudAlphaMin = config.aerosolCloudAlphaMin; this.dropletsColor = config.dropletsColor; + this.exposedColor = config.exposedColor; + this.infectiousColor = config.infectiousColor; initGroupMembershipColor(); - initInfectionStatusColor(); this.changed = config.changed; } @@ -66,13 +66,6 @@ public class DefaultConfig { groupMembershipColors.put(GroupMembership.OUT_GROUP_HOSTILE, new Color(229,229,0)); } - private void initInfectionStatusColor() { - infectionStatusColors.put(InfectionStatus.SUSCEPTIBLE, pedestrianColor); - infectionStatusColors.put(InfectionStatus.EXPOSED, new Color(202, 76, 187)); // use this in combination with org.vadere.util.visualization.ColorHelper.improvedColorInterpolation() - infectionStatusColors.put(InfectionStatus.INFECTIOUS, new Color(202, 76, 76)); - infectionStatusColors.put(InfectionStatus.RECOVERED, new Color(153, 153, 153)); - } - // Getter public synchronized boolean hasChanged() { return changed; @@ -114,8 +107,11 @@ public class DefaultConfig { public int getAerosolCloudAlphaMax() { return aerosolCloudAlphaMax; } public int getAerosolCloudAlphaMin() { return aerosolCloudAlphaMin; } public Color getDropletsColor() {return dropletsColor;} - public Color getDefaultInfectionStatusColor(InfectionStatus infectionStatus) { - return infectionStatusColors.get(infectionStatus); + public Color getExposedColor() { + return exposedColor; + } + public Color getInfectiousColor() { + return infectiousColor; } // Setter @@ -184,4 +180,14 @@ public class DefaultConfig { public void setDropletsColor(Color dropletsColor) { this.dropletsColor = dropletsColor; } + + public void setExposedColor(Color exposedColor) { + this.exposedColor = exposedColor; + setChanged(); + } + + public void setInfectiousColor(Color infectiousColor) { + this.infectiousColor = infectiousColor; + setChanged(); + } } diff --git a/VadereGui/src/org/vadere/gui/components/model/DefaultSimulationConfig.java b/VadereGui/src/org/vadere/gui/components/model/DefaultSimulationConfig.java index cf5c509c8..7d1b464db 100644 --- a/VadereGui/src/org/vadere/gui/components/model/DefaultSimulationConfig.java +++ b/VadereGui/src/org/vadere/gui/components/model/DefaultSimulationConfig.java @@ -7,7 +7,6 @@ import java.util.Optional; import java.util.TreeMap; import org.apache.commons.configuration2.Configuration; -import org.vadere.state.health.InfectionStatus; import org.vadere.state.psychology.cognition.SelfCategory; import org.vadere.state.psychology.information.InformationState; import org.vadere.util.config.VadereConfig; @@ -52,7 +51,17 @@ public class DefaultSimulationConfig extends DefaultConfig { private Map pedestrianColors = new TreeMap<>(); private Map randomColors = new HashMap<>(); private Map selfCategoryColors = new HashMap<>(); - private Map infectionStatusColors = new HashMap<>(); + + /* + * threshold above which pedestrian's color changes gradually depending on current degree of exposure + */ + private double lowerVisualizedExposure = 0; + + /* + * threshold below which pedestrian's color changes gradually depending on current degree of exposure + */ + private double upperVisualizedExposure = 1000; + private Map informationStateColors = new HashMap<>(); private double gridWidth = CONFIG.getDouble("ProjectView.cellWidth"); private final double MIN_CELL_WIDTH = CONFIG.getDouble("ProjectView.minCellWidth"); @@ -69,7 +78,8 @@ public class DefaultSimulationConfig extends DefaultConfig { this.randomColors = new HashMap<>(); this.pedestrianColors = new HashMap<>(); this.selfCategoryColors = new HashMap<>(); - this.infectionStatusColors = new HashMap<>(); + this.lowerVisualizedExposure = config.lowerVisualizedExposure; + this.upperVisualizedExposure = config.upperVisualizedExposure; this.informationStateColors = new HashMap<>(); for (Map.Entry entry : config.pedestrianColors.entrySet()) { @@ -365,7 +375,6 @@ public class DefaultSimulationConfig extends DefaultConfig { setChanged(); } - public Color getSelfCategoryColor(SelfCategory selfCategory) { Color color = getPedestrianDefaultColor(); @@ -375,13 +384,53 @@ public class DefaultSimulationConfig extends DefaultConfig { return color; } - public Color getInfectionStatusColor(InfectionStatus infectionStatus) { - Color color = getPedestrianDefaultColor(); - if (infectionStatusColors.containsKey(infectionStatus.ordinal())) { - color = infectionStatusColors.get(infectionStatus.ordinal()); + public double getLowerVisualizedExposure() { + return lowerVisualizedExposure; + } + + public void setLowerVisualizedExposure(double lowerVisualizedExposure) { + this.lowerVisualizedExposure = lowerVisualizedExposure; + } + + public void setUpperVisualizedExposure(double upperVisualizedExposure) { + this.upperVisualizedExposure = upperVisualizedExposure; + } + + public double getUpperVisualizedExposure() { + return this.upperVisualizedExposure; + } + + public Color getHealthStatusColor(Boolean isInfectious, double degreeOfExposure) { + Color color; + + if (isInfectious) { + color = getInfectiousColor(); + } else { + color = getInterpolatedExposureColor(degreeOfExposure); } + return color; + } + + /* + * defines a truncated color transition depending on an agent's degree of exposure. + */ + private Color getInterpolatedExposureColor(double degreeOfExposure) { + Color color; + float t = (float) ((degreeOfExposure - lowerVisualizedExposure) / upperVisualizedExposure); + Color susceptibleColor = getPedestrianDefaultColor(); + Color exposedColor = getExposedColor(); + + if (degreeOfExposure <= lowerVisualizedExposure) { + color = susceptibleColor; + } else if (degreeOfExposure >= upperVisualizedExposure) { + color = exposedColor; + } else { + color = ColorHelper.improvedColorInterpolation(susceptibleColor, exposedColor, t); + // alternatively use: + // color = ColorHelper.standardColorInterpolation(susceptibleColor, exposedColor, t); + } return color; } @@ -395,11 +444,6 @@ public class DefaultSimulationConfig extends DefaultConfig { return color; } - public void setInfectionStatusColor(InfectionStatus infectionStatus, final Color color) { - this.infectionStatusColors.put(infectionStatus.ordinal(), color); - setChanged(); - } - public void setGridWidth(final double gridWidth) { this.gridWidth = gridWidth; } diff --git a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java index 3301d92d5..6a354b2e9 100644 --- a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java +++ b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java @@ -11,7 +11,6 @@ import org.vadere.gui.components.model.SimulationModel; import org.vadere.gui.components.utils.Messages; import org.vadere.gui.components.utils.SwingUtils; import org.vadere.gui.postvisualization.control.ActionCloseSettingDialog; -import org.vadere.state.health.InfectionStatus; import org.vadere.state.psychology.cognition.SelfCategory; import org.vadere.state.psychology.information.InformationState; import org.vadere.state.scenario.Target; @@ -243,7 +242,7 @@ public class SettingsDialog extends JDialog { private void initAgentColorSettingsPane(JLayeredPane colorSettingsPane){ FormLayout pedColorLayout = new FormLayout("5dlu, pref, 2dlu, pref, 2dlu, pref:grow, 2dlu, pref, 2dlu, pref, 5dlu", - createCellsWithSeparators(8)); + createCellsWithSeparators(10)); //rows colorSettingsPane.setLayout(pedColorLayout); colorSettingsPane.setBorder(BorderFactory.createTitledBorder(Messages.getString("SettingsDialog.pedcolors.border.text"))); @@ -252,7 +251,7 @@ public class SettingsDialog extends JDialog { JRadioButton rbRandomColoring = createRadioButtonWithListener(AgentColoring.RANDOM, Messages.getString("SettingsDialog.chbUseRandomColors.text")); JRadioButton rbGroupColoring = createRadioButtonWithListener(AgentColoring.GROUP, Messages.getString("SettingsDialog.chbGroupColors.text")); JRadioButton rbSelfCategoryColoring = createRadioButtonWithListener(AgentColoring.SELF_CATEGORY, Messages.getString("SettingsDialog.lblSelfCategoryColoring.text")+ ":"); - JRadioButton rbInfectionStatusColoring = createRadioButtonWithListener(AgentColoring.HEALTH_STATUS, Messages.getString("SettingsDialog.lblHealthStatusColoring.text")+ ":"); + JRadioButton rbHealthStatusColoring = createRadioButtonWithListener(AgentColoring.HEALTH_STATUS, Messages.getString("SettingsDialog.lblHealthStatusColoring.text")+ ":"); JRadioButton rbInformationColoring = createRadioButtonWithListener(AgentColoring.INFORMATION_STATE, Messages.getString("SettingsDialog.lblInformationColoring.text")+ ":"); @@ -264,7 +263,7 @@ public class SettingsDialog extends JDialog { group.add(rbRandomColoring); group.add(rbGroupColoring); group.add(rbSelfCategoryColoring); - group.add(rbInfectionStatusColoring); + group.add(rbHealthStatusColoring); group.add(rbInformationColoring); JComboBox cbTargetIds = createTargetIdsComboBoxAndAddIds(); @@ -281,11 +280,39 @@ public class SettingsDialog extends JDialog { initColoringBySelfCategory(cbSelfCategories, pSelfCategoryColor, bChangeSelfCategoryColor); - JComboBox cbInfectionStatuses = createInfectionStatusesComboBox(); - final JPanel pInfectionStatus = new JPanel(); - final JButton bChangeInfectionStatusColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); + final JPanel pPedestrianColorLowerExposure = new JPanel(); + final JButton bChangePedestrianColorLowerExposure = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); + + final JPanel pPedestrianColorUpperExposure = new JPanel(); + final JButton bChangePedestrianColorUpperExposure = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); + + + final JPanel pPedestrianColorInfectious = new JPanel(); + final JButton bChangePedestrianColorInfectious = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); + + initColoringByHealthStatus(bChangePedestrianColorLowerExposure, pPedestrianColorLowerExposure, + bChangePedestrianColorUpperExposure, pPedestrianColorUpperExposure, + bChangePedestrianColorInfectious, pPedestrianColorInfectious); + + final JSpinner spinnerLowerExposure = new JSpinner(); + spinnerLowerExposure.setPreferredSize(new Dimension(75, 20)); + final SpinnerNumberModel sModelLowerExposure = new SpinnerNumberModel(model.config.getLowerVisualizedExposure(), 0, model.config.getUpperVisualizedExposure(), 1); + spinnerLowerExposure.setModel(sModelLowerExposure); + spinnerLowerExposure.addChangeListener(e -> { + model.config.setLowerVisualizedExposure((double) sModelLowerExposure.getValue()); + model.notifyObservers(); + }); + + + final JSpinner spinnerUpperExposure = new JSpinner(); + spinnerUpperExposure.setPreferredSize(new Dimension(75, 20)); + final SpinnerNumberModel sModelUpperExposure = new SpinnerNumberModel(model.config.getUpperVisualizedExposure(), model.config.getLowerVisualizedExposure(), null, 1); + spinnerUpperExposure.setModel(sModelUpperExposure); + spinnerUpperExposure.addChangeListener(e -> { + model.config.setUpperVisualizedExposure((double) sModelUpperExposure.getValue()); + model.notifyObservers(); + }); - initColoringByInfectionStatus(cbInfectionStatuses, pInfectionStatus, bChangeInfectionStatusColor); JComboBox cbInformationStates = createInformationStateComboBox(); final JPanel pInformationStateColor = new JPanel(); @@ -299,35 +326,46 @@ public class SettingsDialog extends JDialog { int column2 = 4; int column3 = 6; int column4 = 8; + int column5 = 10; CellConstraints cc = new CellConstraints(); colorSettingsPane.add(rbTargetColoring, cc.xy(column1, row += NEXT_CELL)); colorSettingsPane.add(cbTargetIds, cc.xy(column2, row)); - colorSettingsPane.add(pTargetColor, cc.xy(column3, row)); - colorSettingsPane.add(bChangeTargetColor, cc.xy(column4, row)); + colorSettingsPane.add(pTargetColor, cc.xy(column4, row)); + colorSettingsPane.add(bChangeTargetColor, cc.xy(column5, row)); colorSettingsPane.add(new JLabel(Messages.getString("SettingsDialog.lblPedestrianNoTarget.text") + ":"), cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(pPedestrianColorNoTarget, cc.xy(column3, row)); - colorSettingsPane.add(bChangePedestrianColorNoTarget, cc.xy(column4, row)); + colorSettingsPane.add(pPedestrianColorNoTarget, cc.xy(column4, row)); + colorSettingsPane.add(bChangePedestrianColorNoTarget, cc.xy(column5, row)); colorSettingsPane.add(rbRandomColoring, cc.xyw(column1, row += NEXT_CELL, 9)); colorSettingsPane.add(rbGroupColoring, cc.xyw(column1, row += NEXT_CELL, 9)); colorSettingsPane.add(rbSelfCategoryColoring, cc.xy(column1, row += NEXT_CELL)); colorSettingsPane.add(cbSelfCategories, cc.xy(column2, row)); - colorSettingsPane.add(pSelfCategoryColor, cc.xy(column3, row)); - colorSettingsPane.add(bChangeSelfCategoryColor, cc.xy(column4, row)); + colorSettingsPane.add(pSelfCategoryColor, cc.xy(column4, row)); + colorSettingsPane.add(bChangeSelfCategoryColor, cc.xy(column5, row)); - colorSettingsPane.add(rbInfectionStatusColoring, cc.xy(column1, row += NEXT_CELL)); - colorSettingsPane.add(cbInfectionStatuses, cc.xy(column2, row)); - colorSettingsPane.add(pInfectionStatus, cc.xy(column3, row)); - colorSettingsPane.add(bChangeInfectionStatusColor, cc.xy(column4, row)); + colorSettingsPane.add(rbHealthStatusColoring, cc.xy(column1, row += NEXT_CELL)); + colorSettingsPane.add(new JLabel(Messages.getString("SettingsDialog.lblPedestrianLowerExposure.text") + ":"), cc.xy(column2, row)); + colorSettingsPane.add(spinnerLowerExposure, cc.xy(column3, row)); + colorSettingsPane.add(pPedestrianColorLowerExposure, cc.xy(column4, row)); + colorSettingsPane.add(bChangePedestrianColorLowerExposure, cc.xy(column5, row)); + + colorSettingsPane.add(new JLabel(Messages.getString("SettingsDialog.lblPedestrianUpperExposure.text") + ":"), cc.xy(column2, row += NEXT_CELL)); + colorSettingsPane.add(spinnerUpperExposure, cc.xy(column3, row)); + colorSettingsPane.add(pPedestrianColorUpperExposure, cc.xy(column4, row)); + colorSettingsPane.add(bChangePedestrianColorUpperExposure, cc.xy(column5, row)); + + colorSettingsPane.add(new JLabel(Messages.getString("SettingsDialog.lblPedestrianInfectious.text") + ":"), cc.xy(column2, row += NEXT_CELL)); + colorSettingsPane.add(pPedestrianColorInfectious, cc.xy(column4, row)); + colorSettingsPane.add(bChangePedestrianColorInfectious, cc.xy(column5, row)); colorSettingsPane.add(rbInformationColoring, cc.xy(column1, row += NEXT_CELL)); colorSettingsPane.add(cbInformationStates, cc.xy(column2, row)); - colorSettingsPane.add(pInformationStateColor, cc.xy(column3, row)); - colorSettingsPane.add(bChangeInformationStateColor, cc.xy(column4, row)); + colorSettingsPane.add(pInformationStateColor, cc.xy(column4, row)); + colorSettingsPane.add(bChangeInformationStateColor, cc.xy(column5, row)); // Evacuation time and criteria coloring comes in the next row see "postvisualization/.../SettingsDialog.java". } @@ -360,11 +398,6 @@ public class SettingsDialog extends JDialog { return comboBox; } - private JComboBox createInfectionStatusesComboBox() { - JComboBox comboBox = new JComboBox<>(InfectionStatus.values()); - return comboBox; - } - private JComboBox createInformationStateComboBox() { JComboBox comboBox = new JComboBox<>(InformationState.values()); return comboBox; @@ -424,24 +457,27 @@ public class SettingsDialog extends JDialog { }); } - private void initColoringByInfectionStatus(JComboBox cbInfectionStatuses, JPanel pInfectionStatusColor, JButton bChangeInfectionStatusColor) { - cbInfectionStatuses.setSelectedIndex(0); + private void initColoringByHealthStatus(JButton bChangePedestrianColorLowerExposure, JPanel pPedestrianColorLowerExposure, + JButton bChangePedestrianColorUpperExposure, JPanel pPedestrianColorUpperExposure, + JButton bChangePedestrianColorInfectious, JPanel pPedestrianColorInfectious) { - InfectionStatus selectedInfectionStatus = cbInfectionStatuses.getItemAt(cbInfectionStatuses.getSelectedIndex()); - Color infectionStatusColor = model.config.getInfectionStatusColor(selectedInfectionStatus); - - pInfectionStatusColor.setBackground(infectionStatusColor); - pInfectionStatusColor.setPreferredSize(new Dimension(130, 20)); + pPedestrianColorLowerExposure.setBackground(config.getPedestrianDefaultColor()); + pPedestrianColorLowerExposure.setPreferredSize(new Dimension(130, 20)); + // When user changes a color, save it in the model. + bChangePedestrianColorLowerExposure.addActionListener(new ActionSetPedestrianDefaultColor( + "Set Pedestrian Exposure Color (lower limit)", model, pPedestrianColorLowerExposure)); + pPedestrianColorUpperExposure.setBackground(config.getExposedColor()); + pPedestrianColorUpperExposure.setPreferredSize(new Dimension(130, 20)); // When user changes a color, save it in the model. - bChangeInfectionStatusColor.addActionListener(new ActionSetInfectionStatusColor("Set Infection Status Color", model, pInfectionStatusColor, - cbInfectionStatuses)); + bChangePedestrianColorUpperExposure.addActionListener(new ActionSetPedestrianExposedColor( + "Set Pedestrian Exposure Color (Upper Limit)", model, pPedestrianColorUpperExposure)); - // Retrieve configured color from "model". - cbInfectionStatuses.addActionListener(e -> { - InfectionStatus selectedInfectionStatusInner = cbInfectionStatuses.getItemAt(cbInfectionStatuses.getSelectedIndex()); - pInfectionStatusColor.setBackground(model.config.getInfectionStatusColor(selectedInfectionStatusInner)); - }); + pPedestrianColorInfectious.setBackground(config.getInfectiousColor()); + pPedestrianColorInfectious.setPreferredSize(new Dimension(130, 20)); + // When user changes a color, save it in the model. + bChangePedestrianColorInfectious.addActionListener(new ActionSetPedestrianInfectiousColor( + "Set Pedestrian Infectious Color", model, pPedestrianColorInfectious)); } private void initColoringByInformationState(JComboBox cbInformationStates, JPanel pInformationStateColor, JButton bChangeInformationStateColor) { diff --git a/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java b/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java index 455783b7e..f7a0e6bec 100644 --- a/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java +++ b/VadereGui/src/org/vadere/gui/components/view/SimulationRenderer.java @@ -5,7 +5,6 @@ import org.vadere.gui.components.model.SimulationModel; import org.vadere.gui.components.utils.CLGaussianCalculator; import org.vadere.gui.postvisualization.model.PostvisualizationModel; import org.vadere.gui.renderer.agent.AgentRender; -import org.vadere.state.health.InfectionStatus; import org.vadere.state.scenario.Agent; import org.vadere.state.scenario.Pedestrian; import org.vadere.util.geometry.shapes.VPoint; @@ -334,7 +333,7 @@ public abstract class SimulationRenderer extends DefaultRenderer { case HEALTH_STATUS: { if (agent instanceof Pedestrian) { Pedestrian pedestrian = (Pedestrian) agent; - return getHealthStatusColor(pedestrian.isInfectious(), pedestrian.getDegreeOfExposure()); + return model.config.getHealthStatusColor(pedestrian.isInfectious(), pedestrian.getDegreeOfExposure()); } } default: return model.config.getPedestrianColor(); @@ -342,38 +341,4 @@ public abstract class SimulationRenderer extends DefaultRenderer { } } - public Color getHealthStatusColor(boolean infectious, double degreeOfExposure) { - Color color; - - double minDegreeOfExposure = 0; - double maxDegreeOfExposure = 1000; //TODO value to be defined in settings dialog - float t = (float) ((degreeOfExposure - minDegreeOfExposure) / maxDegreeOfExposure); - -// // if no color defined explicitly for each status (= default pedestrian color is applied) -> use default values -// for (InfectionStatus status : InfectionStatus.values()) { -// -// if (model.config.getHealthStatusColor(status).equals(model.config.getDefaultInfectionStatusColor(InfectionStatus.SUSCEPTIBLE))) { -// model.config.setInfectionStatusColor(status, model.config.getDefaultInfectionStatusColor(status)); -// } -// } - - //TODO adapt model.config - Color susceptibleColor = model.config.getPedestrianColor(); - Color exposedColor = model.config.getExposedColor(); - Color infectiousColor = model.config.getInfectiousColor(); - - if (degreeOfExposure <= minDegreeOfExposure) { - color = susceptibleColor; - } else if (degreeOfExposure >= maxDegreeOfExposure) { - color = exposedColor; - } else { - // color = ColorHelper.standardColorInterpolation(susceptibleColor, exposedColor, t); - color = ColorHelper.improvedColorInterpolation(susceptibleColor, exposedColor, t); - } - if (infectious) { - color = infectiousColor; - } - return color; - } - } \ No newline at end of file -- GitLab From 81e92650da416247de2e381d13160b439827437f Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 15:56:50 +0100 Subject: [PATCH 19/83] Remove HealthStatus --- .../models/infection/TransmissionModel.java | 7 +- .../FootStepHealthStatusProcessor.java | 1 - .../models/AttributesTransmissionModel.java | 7 +- .../org/vadere/state/health/HealthStatus.java | 260 ------------------ .../org/vadere/state/scenario/Pedestrian.java | 17 +- .../vadere/state/health/HealthStatusTest.java | 108 -------- 6 files changed, 6 insertions(+), 394 deletions(-) delete mode 100644 VadereState/src/org/vadere/state/health/HealthStatus.java delete mode 100644 VadereState/tests/org/vadere/state/health/HealthStatusTest.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index 02898a274..f91a0ce12 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -12,7 +12,6 @@ import org.vadere.state.attributes.models.TransmissionModelSourceParameters; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesDroplets; -import org.vadere.state.health.HealthStatus; import org.vadere.state.health.TransmissionModelHealthStatus; import org.vadere.state.scenario.*; import org.vadere.util.geometry.shapes.VLine; @@ -32,8 +31,8 @@ import static org.vadere.state.scenario.Droplets.createTransformedDropletsShape; * For this purpose, the TransmissionModel controls the airborne transmission of pathogen from infectious pedestrians to * other pedestrians, i.e. it *
    - *
  • initializes each pedestrian's {@link HealthStatus} after a pedestrian is inserted into the topography,
  • - *
  • updates the pedestrian's {@link HealthStatus}
  • + *
  • initializes each pedestrian's {@link TransmissionModelHealthStatus} after a pedestrian is inserted into the topography,
  • + *
  • updates the pedestrian's {@link TransmissionModelHealthStatus}
  • *
  • creates, updates and deletes each {@link AerosolCloud}
  • *
  • creates, updates and deletes {@link Droplets}
  • *
@@ -109,7 +108,6 @@ public class TransmissionModel extends AbstractExposureModel { @Override public void update(double simTimeInSec) { //ToDo: move boolean isXyModelDefined to initialize method and distinguish between: - // * HealthStatus // * AerosolCloudModel // * AlternativeAerosolCloudModel (not yet implemented) // * DropletModel @@ -312,7 +310,6 @@ public class TransmissionModel extends AbstractExposureModel { private void updatePedsHealthStatus(double simTimeInSec) { Collection allPedestrians = topography.getPedestrianDynamicElements().getElements(); for (Pedestrian pedestrian : allPedestrians) { - pedestrian.updateInfectionStatus(simTimeInSec); pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).updateRespiratoryCycle(simTimeInSec, attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod()); } } diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java index 116f5a7ab..3ce3da9c6 100644 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java +++ b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java @@ -4,7 +4,6 @@ import org.vadere.annotation.factories.dataprocessors.DataProcessorClass; import org.vadere.simulator.control.simulation.SimulationState; import org.vadere.simulator.projects.dataprocessing.ProcessorManager; import org.vadere.simulator.projects.dataprocessing.datakey.EventtimePedestrianIdKey; -import org.vadere.state.health.HealthStatus; import org.vadere.state.scenario.Pedestrian; import org.vadere.state.simulation.FootStep; diff --git a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java index 58856997a..4ada84f22 100644 --- a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java @@ -3,22 +3,21 @@ package org.vadere.state.attributes.models; import org.vadere.annotation.factories.attributes.ModelAttributeClass; import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.AttributesEmbedShape; -import org.vadere.state.health.InfectionStatus; import java.util.ArrayList; import java.util.Arrays; +import org.vadere.state.health.TransmissionModelHealthStatus; import org.vadere.state.scenario.AerosolCloud; import org.vadere.state.scenario.Droplets; -import org.vadere.state.health.HealthStatus; import org.vadere.state.scenario.Pedestrian; /** - * This class defines the attributes of the corresponding TransmissionModel. All attributes are defined by the user and + * This class defines the attributes of the corresponding exposure model. All attributes are defined by the user and * relate to *
    *
  • the TransmissionModel: {@link #transmissionModelSourceParameters}, {@link #pedestrianRespiratoryCyclePeriod}
  • - *
  • the {@link HealthStatus} of the {@link Pedestrian}s
  • + *
  • the {@link TransmissionModelHealthStatus} of the {@link Pedestrian}s
  • *
  • the {@link AerosolCloud}s' initial attributes when they are created by the TransmissionModel
  • *
  • the {@link Droplets}s' initial attributes when they are created by the TransmissionModel
  • *
diff --git a/VadereState/src/org/vadere/state/health/HealthStatus.java b/VadereState/src/org/vadere/state/health/HealthStatus.java deleted file mode 100644 index 273fea52c..000000000 --- a/VadereState/src/org/vadere/state/health/HealthStatus.java +++ /dev/null @@ -1,260 +0,0 @@ -package org.vadere.state.health; - -import org.vadere.state.attributes.models.AttributesTransmissionModel; -import org.vadere.util.geometry.shapes.VPoint; -import org.vadere.state.scenario.Pedestrian; - -/** - * This class contains all attributes and methods that a {@link Pedestrian} needs to emit and absorb pathogen. The - * {@link HealthStatus} is initialized und updated by the InfectionModel. - * - *
    - *
  • {@link #pathogenEmissionCapacity}: potentially emitted pathogen load (pathogen particles per breath) in - * decimal log scale per update interval by infectious agent define susceptible agents
  • - *
  • {@link #pathogenAbsorptionRate}: tidal volume in m^3; one could account for protective measures such as - * masks by multiplying the tidal volume by a "mask efficiency factor [0, 1]"
  • - *
  • {@link #pathogenAbsorbedLoad}: current pathogen load that a pedestrian has accumulated
  • - *
  • {@link #minInfectiousDose}: min absorbed pathogen load that leads to change from infectionStatus susceptible - * to exposed.
  • - *
  • {@link #exposedPeriod}, {@link #infectiousPeriod}, {@link #recoveredPeriod}: time that must pass until the - * infectionStatus changes to the next status.
  • - *
- * - * - */ -public class HealthStatus { - - // Member variables - private InfectionStatus infectionStatus; - private double lastInfectionStatusUpdateTime; - private double pathogenAbsorbedLoad; - private VPoint startBreatheOutPosition; - private double respiratoryTimeOffset; - private boolean breathingIn; - - private double pathogenEmissionCapacity; - private double pathogenAbsorptionRate; - private double minInfectiousDose; - private double exposedPeriod; - private double infectiousPeriod; - private double recoveredPeriod; - - private final static double defaultPathogenLoad = 0.0; - private final static double defaultUpdateTime = -1; - private final static double defaultRespiratoryTimeOffset = 0.0; - private final static AttributesTransmissionModel meanPedHealthStatusAttributes = new AttributesTransmissionModel(); - - // Constructors - public HealthStatus(InfectionStatus infectionStatus, double lastInfectionStatusUpdateTime, double pathogenAbsorbedLoad, - VPoint startBreatheOutPosition, double respiratoryTimeOffset, boolean breathingIn, - double pathogenEmissionCapacity, double pathogenAbsorptionRate, double minInfectiousDose, - double exposedPeriod, double infectiousPeriod, double recoveredPeriod) { - this.infectionStatus = infectionStatus; - this.lastInfectionStatusUpdateTime = lastInfectionStatusUpdateTime; - this.pathogenAbsorbedLoad = pathogenAbsorbedLoad; - this.startBreatheOutPosition = startBreatheOutPosition; - this.respiratoryTimeOffset = respiratoryTimeOffset; - this.breathingIn = breathingIn; - this.pathogenEmissionCapacity = pathogenEmissionCapacity; - this.pathogenAbsorptionRate = pathogenAbsorptionRate; - this.minInfectiousDose = minInfectiousDose; - this.exposedPeriod = exposedPeriod; - this.infectiousPeriod = infectiousPeriod; - this.recoveredPeriod = recoveredPeriod; - } - - public HealthStatus() { - this(InfectionStatus.SUSCEPTIBLE, - defaultUpdateTime, - defaultPathogenLoad, - null, - defaultRespiratoryTimeOffset, - false, - meanPedHealthStatusAttributes.getPedestrianPathogenEmissionCapacity(), - meanPedHealthStatusAttributes.getPedestrianPathogenAbsorptionRate(), - meanPedHealthStatusAttributes.getPedestrianMinInfectiousDose(), - meanPedHealthStatusAttributes.getExposedPeriod(), - meanPedHealthStatusAttributes.getInfectiousPeriod(), - meanPedHealthStatusAttributes.getRecoveredPeriod()); - } - - public HealthStatus(HealthStatus other) { - this.infectionStatus = other.getInfectionStatus(); - this.lastInfectionStatusUpdateTime = other.getLastInfectionStatusUpdateTime(); - this.pathogenAbsorbedLoad = other.getPathogenAbsorbedLoad(); - this.startBreatheOutPosition = other.getStartBreatheOutPosition(); - this.respiratoryTimeOffset = other.getRespiratoryTimeOffset(); - this.pathogenEmissionCapacity = other.getPathogenEmissionCapacity(); - this.pathogenAbsorptionRate = other.getPathogenAbsorptionRate(); - this.minInfectiousDose = other.getMinInfectiousDose(); - this.exposedPeriod = other.getExposedPeriod(); - this.infectiousPeriod = other.getInfectiousPeriod(); - this.recoveredPeriod = other.getRecoveredPeriod(); - this.breathingIn = other.isBreathingIn(); - } - - - // Getter - public InfectionStatus getInfectionStatus() { - return infectionStatus; - } - - public double getLastInfectionStatusUpdateTime() { - return lastInfectionStatusUpdateTime; - } - - public double getPathogenAbsorbedLoad() { - return pathogenAbsorbedLoad; - } - - public VPoint getStartBreatheOutPosition() { - return startBreatheOutPosition; - } - - public double getRespiratoryTimeOffset() { - return respiratoryTimeOffset; - } - - public double getPathogenEmissionCapacity() { - return pathogenEmissionCapacity; - } - - public double getPathogenAbsorptionRate() { - return pathogenAbsorptionRate; - } - - public double getMinInfectiousDose() { - return minInfectiousDose; - } - - public double getExposedPeriod() { - return exposedPeriod; - } - - public double getInfectiousPeriod() { - return infectiousPeriod; - } - - public double getRecoveredPeriod() { - return recoveredPeriod; - } - - public boolean isBreathingIn() { - return breathingIn; - } - - // Setter - public void setInfectionStatus(InfectionStatus infectionStatus) { - this.infectionStatus = infectionStatus; - } - - public void setLastInfectionStatusUpdateTime(double lastInfectionStatusUpdateTime) { - this.lastInfectionStatusUpdateTime = lastInfectionStatusUpdateTime; - } - - public void setPathogenAbsorbedLoad(double pathogenAbsorbedLoad) { - this.pathogenAbsorbedLoad = pathogenAbsorbedLoad; - } - - public void setStartBreatheOutPosition(VPoint startBreatheOutPosition) { - this.startBreatheOutPosition = startBreatheOutPosition; - } - - public void setRespiratoryTimeOffset(double respiratoryTimeOffset) { - this.respiratoryTimeOffset = respiratoryTimeOffset; - } - - public void setPathogenEmissionCapacity(double pathogenEmissionCapacity) { - this.pathogenEmissionCapacity = pathogenEmissionCapacity; - } - - public void setPathogenAbsorptionRate(double pathogenAbsorptionRate) { - this.pathogenAbsorptionRate = pathogenAbsorptionRate; - } - - public void setMinInfectiousDose(double minInfectiousDose) { - this.minInfectiousDose = minInfectiousDose; - } - - public void setExposedPeriod(double exposedPeriod) { - this.exposedPeriod = exposedPeriod; - } - - public void setInfectiousPeriod(double infectiousPeriod) { - this.infectiousPeriod = infectiousPeriod; - } - - public void setRecoveredPeriod(double recoveredPeriod) { - this.recoveredPeriod = recoveredPeriod; - } - - public void setBreathingIn(boolean breathingIn) { - this.breathingIn = breathingIn; - } - - // other methods - public double emitPathogen() { - return Math.pow(10, this.getPathogenEmissionCapacity()); - } - - public void updateRespiratoryCycle(double simTimeInSec, double periodLength) { - // Assumption: phases when breathing in and out are equally long - // Breathing in phase condition: sin(time) > 0 or cos(time) == 1 - double b = 2.0 * Math.PI / periodLength; - setBreathingIn((Math.sin(b * (respiratoryTimeOffset + simTimeInSec)) > 0) || (Math.cos(b * (respiratoryTimeOffset + simTimeInSec)) == 1)); - } - - public boolean isStartingBreatheOut() { - return (!breathingIn && startBreatheOutPosition == null); - } - - public boolean isStartingBreatheIn() { - return (breathingIn && !(startBreatheOutPosition == null)); - } - - public void absorbPathogen(double pathogenConcentration) { - double accumulatedAbsorbedPathogenLoad = pathogenAbsorbedLoad + pathogenAbsorptionRate * pathogenConcentration; - - switch (infectionStatus) { - case SUSCEPTIBLE: - case EXPOSED: - setPathogenAbsorbedLoad(accumulatedAbsorbedPathogenLoad); - break; - case INFECTIOUS: - case RECOVERED: - break; // do not absorb - default: - throw new IllegalStateException("Unexpected value: " + infectionStatus); - } - } - - public void updateInfectionStatus(double simTimeInSec) { - switch (infectionStatus) { - case SUSCEPTIBLE: - if (pathogenAbsorbedLoad >= minInfectiousDose) { - setInfectionStatus(InfectionStatus.EXPOSED); - setLastInfectionStatusUpdateTime(simTimeInSec); - } - break; - case EXPOSED: - if (simTimeInSec >= lastInfectionStatusUpdateTime + exposedPeriod) { - setInfectionStatus(InfectionStatus.INFECTIOUS); - setLastInfectionStatusUpdateTime(simTimeInSec); - } - break; - case INFECTIOUS: - if (simTimeInSec >= lastInfectionStatusUpdateTime + infectiousPeriod) { - setInfectionStatus(InfectionStatus.RECOVERED); - setLastInfectionStatusUpdateTime(simTimeInSec); - setPathogenAbsorbedLoad(defaultPathogenLoad); // reset pathogen load to 0 - } - break; - case RECOVERED: - if (simTimeInSec >= lastInfectionStatusUpdateTime + recoveredPeriod) { - setInfectionStatus(InfectionStatus.SUSCEPTIBLE); - setLastInfectionStatusUpdateTime(defaultUpdateTime); // reset lastInfectionStatusUpdateTime - } - break; - } - } -} diff --git a/VadereState/src/org/vadere/state/scenario/Pedestrian.java b/VadereState/src/org/vadere/state/scenario/Pedestrian.java index b9f2f574a..14803c69e 100644 --- a/VadereState/src/org/vadere/state/scenario/Pedestrian.java +++ b/VadereState/src/org/vadere/state/scenario/Pedestrian.java @@ -5,8 +5,6 @@ import org.vadere.state.health.DoseResponseModelInfectionStatus; import org.vadere.state.health.ExposureModelHealthStatus; import org.vadere.state.psychology.information.KnowledgeBase; import org.vadere.state.psychology.PsychologyStatus; -import org.vadere.state.health.InfectionStatus; -import org.vadere.state.health.HealthStatus; import org.vadere.state.psychology.cognition.GroupMembership; import org.vadere.state.psychology.cognition.SelfCategory; import org.vadere.state.psychology.perception.ThreatMemory; @@ -36,7 +34,6 @@ public class Pedestrian extends Agent { private PsychologyStatus psychologyStatus; - private HealthStatus wrapperHealthStatus; private ExposureModelHealthStatus healthStatus; private DoseResponseModelInfectionStatus infectionStatus; @@ -79,7 +76,6 @@ public class Pedestrian extends Agent { isChild = false; isLikelyInjured = false; psychologyStatus = new PsychologyStatus(null, new ThreatMemory(), SelfCategory.TARGET_ORIENTED, GroupMembership.OUT_GROUP, new KnowledgeBase()); - wrapperHealthStatus = new HealthStatus(); healthStatus = null; infectionStatus = null; groupIds = new LinkedList<>(); @@ -110,8 +106,6 @@ public class Pedestrian extends Agent { infectionStatus = null; } - wrapperHealthStatus = new HealthStatus(other.wrapperHealthStatus); - if (other.groupIds != null) { groupIds = new LinkedList<>(other.groupIds); groupSizes = new LinkedList<>(other.groupSizes); @@ -199,9 +193,6 @@ public class Pedestrian extends Agent { return infectionStatus.getProbabilityOfInfection(); } - public InfectionStatus getInfectionStatus() { - return wrapperHealthStatus.getInfectionStatus(); - } public VTrajectory getTrajectory() { return trajectory; @@ -289,9 +280,7 @@ public class Pedestrian extends Agent { infectionStatus.setProbabilityOfInfection(probabilityOfInfection); } - public void setInfectionStatus(InfectionStatus infectionStatus) { - wrapperHealthStatus.setInfectionStatus(infectionStatus); - } + // Methods public boolean isTarget() { @@ -313,10 +302,6 @@ public class Pedestrian extends Agent { } } - public void updateInfectionStatus(double simTimeInSec) { - wrapperHealthStatus.updateInfectionStatus(simTimeInSec); - } - // Overridden Methods @Override diff --git a/VadereState/tests/org/vadere/state/health/HealthStatusTest.java b/VadereState/tests/org/vadere/state/health/HealthStatusTest.java deleted file mode 100644 index ffec507ca..000000000 --- a/VadereState/tests/org/vadere/state/health/HealthStatusTest.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.vadere.state.health; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; - -import static org.junit.Assert.*; - -public class HealthStatusTest { - - public static double ALLOWED_DOUBLE_TOLERANCE = 10e-3; - private HealthStatus healthStatus; - private final static double infectionStatusInterval = 60.0; - private final static double exposedPathogenLoadThreshold = 1000; - - @Before - public void setUp() { - healthStatus = new HealthStatus(InfectionStatus.SUSCEPTIBLE, 0, 0, - null, 0, true, 1e4, 5e-4, - exposedPathogenLoadThreshold, infectionStatusInterval, infectionStatusInterval, infectionStatusInterval); - } - - @Test - public void testEmitPathogen() { - double logExpectedEmittedPathogen = 7; - double expectedEmittedPathogen = Math.pow(10, logExpectedEmittedPathogen); - HealthStatus healthStatus = new HealthStatus(); - - healthStatus.setPathogenEmissionCapacity(7); - - double emittedPathogen = healthStatus.emitPathogen(); - - assertEquals(logExpectedEmittedPathogen, healthStatus.getPathogenEmissionCapacity(), ALLOWED_DOUBLE_TOLERANCE); - assertEquals(expectedEmittedPathogen, emittedPathogen, ALLOWED_DOUBLE_TOLERANCE); - } - - @Test - public void throwIfHealthStatusExposedNotReached() { - healthStatus.setInfectionStatus(InfectionStatus.SUSCEPTIBLE); - healthStatus.setPathogenAbsorbedLoad(exposedPathogenLoadThreshold); - - healthStatus.updateInfectionStatus(1); - Assert.assertEquals(InfectionStatus.EXPOSED, healthStatus.getInfectionStatus()); - } - - @Test - public void throwIfHealthStatusInfectiousNotReached() { - healthStatus.setInfectionStatus(InfectionStatus.EXPOSED); - healthStatus.updateInfectionStatus(infectionStatusInterval); - Assert.assertEquals(InfectionStatus.INFECTIOUS, healthStatus.getInfectionStatus()); - } - - @Test - public void throwIfHealthStatusRecoveredNotReached() { - healthStatus.setInfectionStatus(InfectionStatus.INFECTIOUS); - healthStatus.updateInfectionStatus(infectionStatusInterval); - Assert.assertEquals(InfectionStatus.RECOVERED, healthStatus.getInfectionStatus()); - } - - @Test - public void throwIfHealthStatusSusceptibleNotReached() { - healthStatus.setInfectionStatus(InfectionStatus.RECOVERED); - healthStatus.updateInfectionStatus(infectionStatusInterval); - Assert.assertEquals(InfectionStatus.SUSCEPTIBLE, healthStatus.getInfectionStatus()); - } - - @Test - public void throwIfHealthStatusIsBreatheIn() { - double periodLength = 4; - double simTimeInSec = healthStatus.getRespiratoryTimeOffset() + periodLength / 2.0 + 1e-3; - healthStatus.updateRespiratoryCycle(simTimeInSec, periodLength); - - assertFalse(healthStatus.isBreathingIn()); - } - - @Test - public void throwIfHealthStatusAbsorbsWrongAmountOfPathogen() { - double pathogenConcentration = 1; - double rate = 1; - healthStatus.setPathogenAbsorptionRate(rate); - ArrayList statuses = new ArrayList<>(Arrays.asList(InfectionStatus.SUSCEPTIBLE, InfectionStatus.EXPOSED)); - for (InfectionStatus status : statuses) { - healthStatus.setInfectionStatus(status); - double expectedAbsorbedLoad = healthStatus.getPathogenAbsorbedLoad() + rate * pathogenConcentration; - - healthStatus.absorbPathogen(pathogenConcentration); - Assert.assertEquals(expectedAbsorbedLoad, healthStatus.getPathogenAbsorbedLoad(), ALLOWED_DOUBLE_TOLERANCE); - } - } - - @Test - public void throwIfHealthStatusAbsorbsPathogenAlthoughInNotAbsorbingState() { - double pathogenConcentration = 1; - double rate = 1; - healthStatus.setPathogenAbsorptionRate(rate); - ArrayList statuses = new ArrayList<>(Arrays.asList(InfectionStatus.INFECTIOUS, InfectionStatus.RECOVERED)); - for (InfectionStatus status : statuses) { - healthStatus.setInfectionStatus(status); - double expectedAbsorbedLoad = healthStatus.getPathogenAbsorbedLoad(); - - healthStatus.absorbPathogen(pathogenConcentration); - Assert.assertEquals(expectedAbsorbedLoad, healthStatus.getPathogenAbsorbedLoad(), ALLOWED_DOUBLE_TOLERANCE); - } - } -} -- GitLab From 79cbff2d72c1d87a96e2c9e67202f2a22fc1df15 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 16:03:28 +0100 Subject: [PATCH 20/83] Complete commit 934ad210: Adapt TransmissionModelSourceParameters also in scenario files; --- .../Demos/TransmissionModel/scenarios/bottleneckA.scenario | 4 ++-- .../Demos/TransmissionModel/scenarios/bottleneckB.scenario | 4 ++-- .../scenarios/bottleneckB_socialDistancing.scenario | 4 ++-- .../Demos/TransmissionModel/scenarios/closeContact.scenario | 4 ++-- .../Demos/TransmissionModel/scenarios/passageway.scenario | 4 ++-- .../scenarios/queueScenario_publication.scenario | 4 ++-- .../scenarios/hamner-2020-life_postvis_template.scenario | 4 ++-- .../hamner-2020-life_postvis_template_seed_000_100fr.scenario | 4 ++-- .../validation/scenarios/hamner-2020-life_template.scenario | 4 ++-- .../validation/scenarios/lu-2020-life.scenario | 4 ++-- .../validation/scenarios/miller-2020-life_seed_000.scenario | 4 ++-- .../validation/scenarios/miller-2020-life_template.scenario | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario index 4755d5ac3..fe84bab0a 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario @@ -98,10 +98,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : 3, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 5, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario index 7faf3be5b..f77ff1273 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario @@ -123,10 +123,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : 3, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 5, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario index 04c1217f6..0cc510ddb 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario @@ -123,10 +123,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : 3, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 5, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario index 7cd3cc147..c670c4930 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario @@ -128,10 +128,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : 15, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 16, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario b/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario index c3b41bc6f..4576b7475 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario @@ -98,10 +98,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : -1, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 2, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario index a75f47060..42420c5b9 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario @@ -150,10 +150,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : 1, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 2, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario index bc169e8df..38058dc51 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario @@ -113,10 +113,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : -1, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 1, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario index 51e323c6f..af9652393 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario @@ -113,10 +113,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : -1, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 1, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario index 69eb8a588..d51d81217 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario @@ -71,10 +71,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : -1, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 1, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario index 8c72b4fa2..51f6583ea 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario @@ -98,10 +98,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : -1, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 11, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario index c74ed88c3..0799b5406 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario @@ -78,10 +78,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : -1, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 1, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario index 8e4c7f81d..c38f8bff4 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario @@ -78,10 +78,10 @@ "org.vadere.state.attributes.models.AttributesTransmissionModel" : { "transmissionModelSourceParameters" : [ { "sourceId" : -1, - "infectionStatus" : "SUSCEPTIBLE" + "infectious" : false }, { "sourceId" : 1, - "infectionStatus" : "INFECTIOUS" + "infectious" : true } ], "pedestrianRespiratoryCyclePeriod" : 4.0, "pedestrianPathogenEmissionCapacity" : 4.0, -- GitLab From bf38cee9fe5cb66cc4122fa39ce783ddb243b950 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 16:17:23 +0100 Subject: [PATCH 21/83] Complete commit 934ad210: Adapt TransmissionModelSourceParameters also in scenario files; --- .../scenarios/queueScenario_publication.scenario | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario index 42420c5b9..486a1af1d 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario @@ -28,10 +28,6 @@ "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimeGridOutputFile", "filename" : "pathogenConcentration.txt", "processors" : [ 7 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile", - "filename" : "infectionStatusPerPedestrian.txt", - "processors" : [ 8 ] }, { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile", "filename" : "pedestrianHealthStatus.txt", -- GitLab From 9b3cca5cd8b822ca8a107e08f0c666d16efefc1d Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 21 Feb 2022 17:37:02 +0100 Subject: [PATCH 22/83] Remove deprecated InfectionStatus --- .../model/PostvisualizationModel.java | 1 - .../infection/TransmissionModelTest.java | 1 - .../vadere/state/health/InfectionStatus.java | 28 ------------------- 3 files changed, 30 deletions(-) delete mode 100644 VadereState/src/org/vadere/state/health/InfectionStatus.java diff --git a/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java b/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java index bdfe8fb34..9f95cd190 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java @@ -7,7 +7,6 @@ import org.vadere.gui.postvisualization.utils.PotentialFieldContainer; import org.vadere.simulator.projects.Scenario; import org.vadere.state.attributes.AttributesSimulation; import org.vadere.state.attributes.scenario.AttributesAgent; -import org.vadere.state.health.InfectionStatus; import org.vadere.state.psychology.cognition.GroupMembership; import org.vadere.state.psychology.cognition.SelfCategory; import org.vadere.state.psychology.information.InformationState; diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java index d78079ba2..3222acf13 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java @@ -11,7 +11,6 @@ import org.vadere.state.attributes.models.AttributesTransmissionModel; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesTarget; -import org.vadere.state.health.InfectionStatus; import org.vadere.state.scenario.AerosolCloud; import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Target; diff --git a/VadereState/src/org/vadere/state/health/InfectionStatus.java b/VadereState/src/org/vadere/state/health/InfectionStatus.java deleted file mode 100644 index 093267fe6..000000000 --- a/VadereState/src/org/vadere/state/health/InfectionStatus.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.vadere.state.health; - -/** - * Infection status defined similarly to compartmental S(E)IR models (Kermack–McKendrick theory, "kermack-1927"): - * - * Simplifications and assumptions: - *
    - *
  • {@link #SUSCEPTIBLE}: absorbs and accumulates pathogens, does not emit pathogens, becomes {@link #EXPOSED} if - * susceptibility exceeded
  • - *
  • {@link #EXPOSED}: absorbs and accumulates pathogens, does not emit pathogens, becomes {@link #INFECTIOUS} - * after exposed period
  • - *
  • {@link #INFECTIOUS}: does not absorb and accumulate pathogens, emits pathogens, becomes {@link #RECOVERED} - * after infectious period
  • - *
  • {@link #RECOVERED}: does not absorb and accumulate pathogens, does not emit pathogens, becomes - * {@link #SUSCEPTIBLE} after recovered period; {@link #RECOVERED} can be interpreted as immune. An alternative - * definition of R is removed (e.g. deceased, isolated, ...)
  • - *
- * - * Extending the infection status: - * Infection statuses SYMPTOMATIC_INFECTIOUS and ASYMPTOMATIC_INFECTIOUS could be considered to account for adaptation - * to the pedestrians' behavior (e.g. keeping greater distance from symptomatic pedestrians). Note the difference - * between latent period and incubation period. - * - */ - -public enum InfectionStatus { - SUSCEPTIBLE, EXPOSED, INFECTIOUS, RECOVERED -} -- GitLab From dbd65bf750f4caf5474d9b58dce6c5cf3700eaaa Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 22 Feb 2022 14:34:34 +0100 Subject: [PATCH 23/83] Introduce AttributesTransmissionModelAerosolCloud and AttributesTransmissionModelDroplets These attributes are user-defined, do not change during the simulation and are shared by all AerosolCloud and Droplets, respectively. --- .../models/infection/TransmissionModel.java | 206 +++++++++--------- .../models/AttributesTransmissionModel.java | 162 ++++++++------ .../TransmissionModelSourceParameters.java | 27 --- ...tributesExposureModelSourceParameters.java | 36 +++ ...tributesTransmissionModelAerosolCloud.java | 127 +++++++++++ .../AttributesTransmissionModelDroplets.java | 100 +++++++++ .../scenario/AttributesAerosolCloud.java | 12 +- .../scenario/AttributesDroplets.java | 8 +- .../vadere/state/scenario/AerosolCloud.java | 6 - .../org/vadere/state/scenario/Droplets.java | 6 - .../state/scenario/AerosolCloudTest.java | 6 +- 11 files changed, 466 insertions(+), 230 deletions(-) delete mode 100644 VadereState/src/org/vadere/state/attributes/models/TransmissionModelSourceParameters.java create mode 100644 VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModelSourceParameters.java create mode 100644 VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelAerosolCloud.java create mode 100644 VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelDroplets.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index f91a0ce12..ec0f93919 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -8,7 +8,7 @@ import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.models.AttributesTransmissionModel; -import org.vadere.state.attributes.models.TransmissionModelSourceParameters; +import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesDroplets; @@ -42,48 +42,39 @@ public class TransmissionModel extends AbstractExposureModel { protected static Logger logger = Logger.getLogger(TransmissionModel.class); - private AttributesTransmissionModel attributesTransmissionModel; + private AttributesTransmissionModel attrTransmissionModel; double simTimeStepLength; Topography topography; int aerosolCloudIdCounter; private Map lastPedestrianPositions; private Map viewingDirections; - private static final double MIN_STEP_LENGTH = 0.1; + private static final double MIN_PED_STEP_LENGTH = 0.1; /** * Key that is used for initializeVadereContext in ScenarioRun */ public static final String simStepLength = "simTimeStepLength"; - /* + /** * constant that results from exponential decay of pathogen concentration: C(t) = C_init * exp(-lambda * t), * lambda = exponentialDecayFactor / halfLife */ private static final double exponentialDecayFactor = Math.log(2.0); - /* minimumPercentage defines a percentage of the initial pathogen concentration + /** + * minimumPercentage defines a percentage of the initial pathogen concentration * (pathogenLoad / aerosolCloud.volume); As soon as an aerosolCloud has reached the minimum concentration, the * aerosolCloud is considered negligible and therefore deleted */ private static final double minimumPercentage = 0.01; - /* rateOfSpread describes how fast the aerosolCloud spreads due to diffusion; unit: m/s; and - * could be implemented as user-defined parameter in AttributesTransmissionModel - */ - private static final double rateOfSpread = 0.001; - - /* each pedestrian with velocity v causes an increase of the cloud's radius by factor - * weight * v * simTimeStepLength; could be implemented as user-defined parameter in AttributesTransmissionModel - */ - private static final double weight = 0.0125; - @Override public void initialize(List attributesList, Domain domain, AttributesAgent attributesPedestrian, Random random) { this.domain = domain; this.random = random; this.attributesAgent = attributesPedestrian; - this.attributesTransmissionModel = Model.findAttributes(attributesList, AttributesTransmissionModel.class); + this.attrTransmissionModel = Model.findAttributes(attributesList, AttributesTransmissionModel.class); this.topography = domain.getTopography(); this.simTimeStepLength = VadereContext.get(this.topography).getDouble(simStepLength); this.aerosolCloudIdCounter = 1; @@ -107,34 +98,20 @@ public class TransmissionModel extends AbstractExposureModel { @Override public void update(double simTimeInSec) { - //ToDo: move boolean isXyModelDefined to initialize method and distinguish between: - // * AerosolCloudModel - // * AlternativeAerosolCloudModel (not yet implemented) - // * DropletModel - // * ... (any other transmission route) - // Consider this also in AttributesTransmissionModel - //ToDo: alternatively, introduce sub-submodels and iterate through sub-submodels, similarly to loop over all - // models in class Simulation - - boolean isAerosolCloudModelDefined = attributesTransmissionModel.getAerosolCloudHalfLife() > 0; - boolean isDropletModelDefined = attributesTransmissionModel.getDropletsExhalationFrequency() > 0; - - // this model for transmission via aerosol clouds is enabled by default - if (isAerosolCloudModelDefined) { + if (attrTransmissionModel.isAerosolCloudsActive()) { executeAerosolCloudEmissionEvents(simTimeInSec); updateAerosolClouds(simTimeInSec); - updatePedsPathogenLoadFromAerosolClouds(); + updatePedestriansExposureToAerosolClouds(); } - // this model for transmission via droplets is disabled by default - if (isDropletModelDefined) { + if (attrTransmissionModel.isDropletsActive()) { executeDropletEmissionEvents(simTimeInSec); updateDroplets(simTimeInSec); - updatePedsPathogenLoadFromDroplets(); + updatePedestriansExposureToDroplets(); } - if (isAerosolCloudModelDefined || isDropletModelDefined) { + if (attrTransmissionModel.isAerosolCloudsActive() || attrTransmissionModel.isDropletsActive()) { updatePedsHealthStatus(simTimeInSec); } } @@ -147,7 +124,6 @@ public class TransmissionModel extends AbstractExposureModel { public void executeAerosolCloudEmissionEvents(double simTimeInSec) { Collection infectiousPedestrians = getInfectiousPedestrians(topography); for (Pedestrian pedestrian : infectiousPedestrians) { - // ... for each user-defined event createAerosolClouds(simTimeInSec, pedestrian); } } @@ -155,7 +131,6 @@ public class TransmissionModel extends AbstractExposureModel { public void executeDropletEmissionEvents(double simTimeInSec) { Collection infectiousPedestrians = getInfectiousPedestrians(topography); for (Pedestrian pedestrian : infectiousPedestrians) { - // ... for each user-defined event createDroplets(simTimeInSec, pedestrian); } } @@ -181,25 +156,22 @@ public class TransmissionModel extends AbstractExposureModel { VPoint stopBreatheOutPosition = pedestrian.getPosition(); VLine distanceWalkedDuringExhalation = new VLine(startBreatheOutPosition, stopBreatheOutPosition); - AerosolCloud aerosolCloud = generateAerosolCloud(simTimeInSec, pedestrian, distanceWalkedDuringExhalation); + AerosolCloud aerosolCloud = generateAerosolCloud(simTimeInSec, distanceWalkedDuringExhalation); topography.addAerosolCloud(aerosolCloud); pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).resetStartExhalationPosition(); } } - private AerosolCloud generateAerosolCloud(double simTimeInSec, Pedestrian pedestrian, VLine distanceWalkedDuringExhalation) { + private AerosolCloud generateAerosolCloud(double simTimeInSec, VLine distanceWalkedDuringExhalation) { VPoint center = distanceWalkedDuringExhalation.midPoint(); - double radius = attributesTransmissionModel.getAerosolCloudInitialRadius(); - AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(aerosolCloudIdCounter, - radius, + attrTransmissionModel.getAerosolCloudInitialRadius(), center, simTimeInSec, - attributesTransmissionModel.getAerosolCloudHalfLife(), - Math.pow(10, attributesTransmissionModel.getPedestrianPathogenEmissionCapacity()), - Math.pow(10, attributesTransmissionModel.getPedestrianPathogenEmissionCapacity()))); + attrTransmissionModel.getAerosolCloudInitialPathogenLoad(), + attrTransmissionModel.getAerosolCloudInitialPathogenLoad())); aerosolCloudIdCounter = aerosolCloudIdCounter + 1; @@ -207,56 +179,51 @@ public class TransmissionModel extends AbstractExposureModel { } private void createDroplets(double simTimeInSec, Pedestrian pedestrian) { - - if (attributesTransmissionModel.getDropletsExhalationFrequency() > 0) { - - // ToDo: remove this quick solution; it would be better to have the walking directions stored in pedestrian - int pedestrianId = pedestrian.getId(); - Vector2D viewingDirection; - VPoint currentPosition = pedestrian.getPosition(); - VPoint lastPosition = lastPedestrianPositions.get(pedestrianId); - if (lastPedestrianPositions.get(pedestrianId) == null) { - viewingDirection = new Vector2D(Math.random(), Math.random()); + // ToDo: refactor: it could be better to have the walking directions stored in pedestrian + int pedestrianId = pedestrian.getId(); + Vector2D viewingDirection; + VPoint currentPosition = pedestrian.getPosition(); + VPoint lastPosition = lastPedestrianPositions.get(pedestrianId); + if (lastPedestrianPositions.get(pedestrianId) == null) { + viewingDirection = new Vector2D(Math.random(), Math.random()); + } else { + if (lastPosition.distance(currentPosition) < MIN_PED_STEP_LENGTH) { + viewingDirection = viewingDirections.get(pedestrianId); } else { - if (lastPosition.distance(currentPosition) < MIN_STEP_LENGTH) { - viewingDirection = viewingDirections.get(pedestrianId); - } else { - viewingDirection = new Vector2D(currentPosition.getX() - lastPosition.getX(), - currentPosition.getY() - lastPosition.getY()); - } + viewingDirection = new Vector2D(currentPosition.getX() - lastPosition.getX(), + currentPosition.getY() - lastPosition.getY()); } - viewingDirection.normalize(1); - viewingDirections.put(pedestrianId, viewingDirection); - lastPedestrianPositions.put(pedestrianId, currentPosition); - - // period between two droplet generating respiratory events - double dropletExhalationPeriod = 1 / attributesTransmissionModel.getDropletsExhalationFrequency(); + } + viewingDirection.normalize(1); + viewingDirections.put(pedestrianId, viewingDirection); + lastPedestrianPositions.put(pedestrianId, currentPosition); - if (simTimeInSec % dropletExhalationPeriod < simTimeStepLength) { + // period between two droplet generating respiratory events + double dropletExhalationPeriod = 1 / attrTransmissionModel.getDropletsEmissionFrequency(); - VShape shape = createTransformedDropletsShape(pedestrian.getPosition(), - viewingDirection, - attributesTransmissionModel.getDropletsDistanceOfSpread(), - Math.toRadians(attributesTransmissionModel.getDropletsAngleOfSpreadInDeg())); + if (simTimeInSec % dropletExhalationPeriod < simTimeStepLength) { - double emittedPathogenLoad = Math.pow(10, attributesTransmissionModel.getPedestrianPathogenEmissionCapacity()) * attributesTransmissionModel.getDropletsPathogenLoadFactor(); + VShape shape = createTransformedDropletsShape(pedestrian.getPosition(), + viewingDirection, + attrTransmissionModel.getDropletsDistanceOfSpread(), + Math.toRadians(attrTransmissionModel.getDropletsAngleOfSpreadInDeg())); - Droplets droplets = new Droplets(new AttributesDroplets(1, - shape, - simTimeInSec, - attributesTransmissionModel.getDropletsLifeTime(), - emittedPathogenLoad)); + Droplets droplets = new Droplets(new AttributesDroplets(1, + shape, + simTimeInSec, + attrTransmissionModel.getDropletsPathogenLoad())); - topography.addDroplets(droplets); - } + topography.addDroplets(droplets); } } + //TODO define recursive; then, if possible, remove property initialPathogenLoad from AerosolCloud public void updateAerosolCloudsPathogenLoad(double simTimeInSec) { + double lambda = exponentialDecayFactor / attrTransmissionModel.getAerosolCloudHalfLife(); + Collection allAerosolClouds = topography.getAerosolClouds(); for (AerosolCloud aerosolCloud : allAerosolClouds) { double t = simTimeInSec - aerosolCloud.getCreationTime(); - double lambda = exponentialDecayFactor / aerosolCloud.getHalfLife(); aerosolCloud.setCurrentPathogenLoad(aerosolCloud.getInitialPathogenLoad() * Math.exp(-lambda * t)); } } @@ -264,33 +231,38 @@ public class TransmissionModel extends AbstractExposureModel { public void updateAerosolCloudsExtent() { Collection allAerosolClouds = topography.getAerosolClouds(); for (AerosolCloud aerosolCloud : allAerosolClouds) { + double deltaRadius = 0.0; - // Increasing extent due to diffusion - // aerosolCloud.increaseShape(rateOfSpread * simTimeStepLength); + // Increasing extent due to dispersion, multiplication with simTimeStepLength keeps deltaRadius independent of simulation step width + if (attrTransmissionModel.getAerosolCloudAirDispersionFactor() > 0) { + deltaRadius = attrTransmissionModel.getAerosolCloudAirDispersionFactor() * simTimeStepLength; + } - // Increasing extent due to moving air caused by agents - // Increase aerosolCloudRadius about deltaRadius due to moving agents within the cloud - // ToDo: to be discussed if it makes sense to use the agent's velocity at each simStep (shouldn't it be the - // mean velocity within each simStep? or is that too detailed?) - Collection pedestriansInsideCloud = getPedestriansInsideAerosolCloud(topography, aerosolCloud); - double deltaRadius = 0.0; + // Increasing extent due to moving air caused by agents, multiplication with simTimeStepLength keeps deltaRadius independent of simulation step width + if (attrTransmissionModel.getAerosolCloudPedestrianDispersionWeight() > 0) { + Collection pedestriansInsideCloud = getPedestriansInsideAerosolCloud(topography, aerosolCloud); for (Pedestrian pedestrian : pedestriansInsideCloud) { - deltaRadius = deltaRadius + pedestrian.getVelocity().getLength() * weight * simTimeStepLength; + deltaRadius += pedestrian.getVelocity().getLength() * attrTransmissionModel.getAerosolCloudPedestrianDispersionWeight() * simTimeStepLength; } + } + aerosolCloud.increaseShape(deltaRadius); } } - /* - * Deletes aerosolClouds with negligible pathogenConcentration, that is if current pathogen concentration is smaller + /** + * Deletes aerosol clouds with negligible pathogen concentration, i.e. if current pathogen concentration is smaller * than a threshold (minimumPercentage * initial pathogen concentration) */ public void deleteExpiredAerosolClouds() { - double initialRadius = attributesTransmissionModel.getAerosolCloudInitialRadius(); + + double initialCloudVolume = AerosolCloud.radiusToVolume(attrTransmissionModel.getAerosolCloudInitialRadius()); + double initialPathogenConcentration = attrTransmissionModel.getAerosolCloudInitialPathogenLoad() / initialCloudVolume; + double minimumConcentration = minimumPercentage * initialPathogenConcentration; Collection aerosolCloudsToBeDeleted = topography.getAerosolClouds() .stream() - .filter(a -> a.getPathogenConcentration() < minimumPercentage * a.getInitialPathogenLoad() / AerosolCloud.radiusToVolume(initialRadius)) + .filter(a -> a.getPathogenConcentration() < minimumConcentration) .collect(Collectors.toSet()); for (AerosolCloud aerosolCloud : aerosolCloudsToBeDeleted) { topography.getAerosolClouds().remove(aerosolCloud); @@ -300,7 +272,7 @@ public class TransmissionModel extends AbstractExposureModel { public void deleteExpiredDroplets(double simTimeInSec) { Collection dropletsToBeDeleted = topography.getDroplets() .stream() - .filter(d -> d.getLifeTime() + d.getCreationTime() < simTimeInSec) + .filter(d -> attrTransmissionModel.getDropletsLifeTime() + d.getCreationTime() < simTimeInSec) .collect(Collectors.toSet()); for (Droplets droplets : dropletsToBeDeleted) { topography.getDroplets().remove(droplets); @@ -310,19 +282,22 @@ public class TransmissionModel extends AbstractExposureModel { private void updatePedsHealthStatus(double simTimeInSec) { Collection allPedestrians = topography.getPedestrianDynamicElements().getElements(); for (Pedestrian pedestrian : allPedestrians) { - pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).updateRespiratoryCycle(simTimeInSec, attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).updateRespiratoryCycle(simTimeInSec, attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); } } - private void updatePedsPathogenLoadFromAerosolClouds() { + private void updatePedestriansExposureToAerosolClouds() { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() .filter(p -> p.getHealthStatus(TransmissionModelHealthStatus.class).isBreathingIn()) .collect(Collectors.toSet()); - // Agents absorb pathogen continuously but simulation is discrete. Therefore, the absorption must be adapted with normalizationFactor: - double timeNormalizationConst = simTimeStepLength / (attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod() / 2.0); + // Agents absorb pathogen continuously but simulation is discrete. Therefore, the absorption during inhalation + // must be divided into absorption for each sim step: + double inhalationPeriodLength = attrTransmissionModel.getPedestrianRespiratoryCyclePeriod() / 2.0; + double aerosolAbsorptionRatePerSimStep = attrTransmissionModel.getAerosolCloudAbsorptionRate() * (simTimeStepLength / inhalationPeriodLength); + Collection allAerosolClouds = topography.getAerosolClouds(); for (AerosolCloud aerosolCloud : allAerosolClouds) { Collection breathingInPedsInAerosolCloud = breathingInPeds @@ -331,26 +306,41 @@ public class TransmissionModel extends AbstractExposureModel { .collect(Collectors.toSet()); for (Pedestrian ped : breathingInPedsInAerosolCloud) { - updatePedestrianDegreeOfExposure(ped, aerosolCloud.getPathogenConcentration() * timeNormalizationConst); + double deltaDegreeOfExposure = aerosolCloud.getPathogenConcentration() * aerosolAbsorptionRatePerSimStep; + updatePedestrianDegreeOfExposure(ped, deltaDegreeOfExposure); } } } - private void updatePedsPathogenLoadFromDroplets() { + private void updatePedestriansExposureToDroplets() { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() .filter(p -> p.getHealthStatus(TransmissionModelHealthStatus.class).isBreathingIn()) .collect(Collectors.toSet()); + /* + * Agents absorb pathogen continuously but simulation is discrete. Therefore, the absorption during inhalation + * must be divided into absorption for each sim step: + */ + double inhalationPeriodLength = attrTransmissionModel.getPedestrianRespiratoryCyclePeriod() / 2.0; + double dropletsAbsorptionRatePerSimStep = attrTransmissionModel.getDropletsAbsorptionRate() * (simTimeStepLength / inhalationPeriodLength); + + /* + * Intake of droplets: Inhaling agents simply absorb a fraction of the pathogen from droplets they are exposed + * to. In contrast to intake of pathogen from aerosol clouds, we do not consider concentrations (for simplicity + * or to avoid further assumptions on pathogen distribution within droplets). + */ Collection allDroplets = topography.getDroplets(); for (Droplets droplets : allDroplets) { Collection breathingInPedsInDroplets = breathingInPeds .stream() .filter(p -> droplets.getShape().contains(p.getPosition())) .collect(Collectors.toSet()); + for (Pedestrian ped : breathingInPedsInDroplets) { - updatePedestrianDegreeOfExposure(ped, droplets.getCurrentPathogenLoad()); + double deltaDegreeOfExposure = attrTransmissionModel.getDropletsPathogenLoad() * dropletsAbsorptionRatePerSimStep; + updatePedestrianDegreeOfExposure(ped, deltaDegreeOfExposure); } } } @@ -366,13 +356,13 @@ public class TransmissionModel extends AbstractExposureModel { public Agent sourceControllerEvent(SourceController controller, double simTimeInSec, Agent scenarioElement) { // SourceControllerListener. This will be called *after* a pedestrian is inserted into the // topography by the given SourceController. Change model state on Agent here - TransmissionModelSourceParameters sourceParameters = defineSourceParameters(controller); + AttributesExposureModelSourceParameters sourceParameters = defineSourceParameters(controller); Pedestrian ped = (Pedestrian) scenarioElement; ped.addHealthStatus(TransmissionModelHealthStatus.class); ped.setInfectious(sourceParameters.isInfectious()); ped.setDegreeOfExposure(0); - ped.getHealthStatus(TransmissionModelHealthStatus.class).setRespiratoryTimeOffset(random.nextDouble() * attributesTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + ped.getHealthStatus(TransmissionModelHealthStatus.class).setRespiratoryTimeOffset(random.nextDouble() * attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); ped.getHealthStatus(TransmissionModelHealthStatus.class).setBreathingIn(false); //TODO check exhalation start position null? @@ -380,15 +370,15 @@ public class TransmissionModel extends AbstractExposureModel { return ped; } - private TransmissionModelSourceParameters defineSourceParameters(SourceController controller) { + private AttributesExposureModelSourceParameters defineSourceParameters(SourceController controller) { int sourceId = controller.getSourceId(); int defaultSourceId = -1; - Optional sourceParameters = attributesTransmissionModel + Optional sourceParameters = attrTransmissionModel .getTransmissionModelSourceParameters().stream().filter(s -> s.getSourceId() == sourceId).findFirst(); // if sourceId not set by user, check if the user has defined default attributes by setting sourceId = -1 if (sourceParameters.isEmpty()) { - sourceParameters = attributesTransmissionModel.getTransmissionModelSourceParameters().stream().filter(s -> s.getSourceId() == defaultSourceId).findFirst(); + sourceParameters = attrTransmissionModel.getTransmissionModelSourceParameters().stream().filter(s -> s.getSourceId() == defaultSourceId).findFirst(); // if no user defined default values: use attributesTransmissionModel default values if (sourceParameters.isPresent()) { @@ -401,7 +391,7 @@ public class TransmissionModel extends AbstractExposureModel { } public AttributesTransmissionModel getAttributesTransmissionModel() { - return attributesTransmissionModel; + return attrTransmissionModel; } public static Collection getDynamicElementsNearAerosolCloud(Topography topography, AerosolCloud aerosolCloud) { diff --git a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java index 4ada84f22..a8fb0d05d 100644 --- a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java @@ -7,6 +7,9 @@ import org.vadere.state.attributes.AttributesEmbedShape; import java.util.ArrayList; import java.util.Arrays; +import org.vadere.state.attributes.models.infection.AttributesTransmissionModelAerosolCloud; +import org.vadere.state.attributes.models.infection.AttributesTransmissionModelDroplets; +import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.health.TransmissionModelHealthStatus; import org.vadere.state.scenario.AerosolCloud; import org.vadere.state.scenario.Droplets; @@ -25,108 +28,137 @@ import org.vadere.state.scenario.Pedestrian; @ModelAttributeClass public class AttributesTransmissionModel extends Attributes { - // Attributes that are required by the TransmissionModel - private ArrayList transmissionModelSourceParameters; - private double pedestrianRespiratoryCyclePeriod; // equals 1/(pedestrians' average breathing rate) in seconds - - // Pedestrians' healthStatus related attributes - private double pedestrianPathogenEmissionCapacity; - private double pedestrianPathogenAbsorptionRate; - private double pedestrianMinInfectiousDose; - private double exposedPeriod; - private double infectiousPeriod; - private double recoveredPeriod; - - // AerosolCloud related attributes - private double aerosolCloudHalfLife; - private double aerosolCloudInitialRadius; - - // Droplet related attributes - private double dropletsExhalationFrequency; - private double dropletsDistanceOfSpread; - private double dropletsAngleOfSpreadInDeg; - private double dropletsLifeTime; - private double dropletsPathogenLoadFactor; + private ArrayList transmissionModelSourceParameters; + + /** + * Attribute related to the pedestrians' health state that is shared among all pedestrians. It is not defined + * for each instance of TransmissionModelHealthStatus separately to keep the TransmissionModelHealthStatus lean. + * pedestrianRespiratoryCyclePeriod equals 1/(pedestrians' average breathing rate) in seconds. + */ + private double pedestrianRespiratoryCyclePeriod; + + /** + * Defines whether aerosol clouds are considered in the exposure model (true) or not (false). + */ + private boolean aerosolCloudsActive; + private AttributesTransmissionModelAerosolCloud aerosolCloudParameters; + + /** + * Defines whether droplets are considered in the exposure model (true) or not (false). + */ + private boolean dropletsActive; + private AttributesTransmissionModelDroplets dropletParameters; + public AttributesTransmissionModel() { - this.transmissionModelSourceParameters = new ArrayList<>(Arrays.asList(new TransmissionModelSourceParameters(AttributesEmbedShape.ID_NOT_SET, false))); - - // Mean pedestrian healthStatus and aerosolCloud attributes, rahn-2021b-cdyn Table I; - // Some of these values are defined as mean values but could/should be introduced as distributions - this.pedestrianRespiratoryCyclePeriod = 4; // in seconds - this.pedestrianPathogenEmissionCapacity = 4; // pathogen particles per exhalation, logarithmized to base 10 - this.pedestrianPathogenAbsorptionRate = 0.0005; // tidal volume in m^3 per inhalation - this.pedestrianMinInfectiousDose = 3200; // in particles - this.exposedPeriod = 2.59E5; // in seconds - this.infectiousPeriod = 3.46E5; // in seconds - this.recoveredPeriod = 1.56E7; // in seconds - this.aerosolCloudHalfLife = 600; // in seconds - this.aerosolCloudInitialRadius = 1.5; // in m - - this.dropletsExhalationFrequency = 0; // 0 -> no droplets are exhaled - this.dropletsDistanceOfSpread = 1.5; - this.dropletsAngleOfSpreadInDeg = 30; - this.dropletsLifeTime = 1.0 + 1.0E-3; // make sure that lifeTime is not a multiple of simTimeStepLength - this.dropletsPathogenLoadFactor = 200; // pathogen load of droplets is dropletsPathogenLoadFactor times greater than + this.transmissionModelSourceParameters = new ArrayList<>(Arrays.asList(new AttributesExposureModelSourceParameters(AttributesEmbedShape.ID_NOT_SET, false))); + + this.pedestrianRespiratoryCyclePeriod = 4; + + this.aerosolCloudsActive = false; + this.aerosolCloudParameters = new AttributesTransmissionModelAerosolCloud(); + + this.dropletsActive = false; + this.dropletParameters = new AttributesTransmissionModelDroplets(); } + // Getter + public double getPedestrianRespiratoryCyclePeriod() { return pedestrianRespiratoryCyclePeriod; } - public ArrayList getTransmissionModelSourceParameters() { + public ArrayList getTransmissionModelSourceParameters() { return transmissionModelSourceParameters; } - public double getPedestrianPathogenEmissionCapacity() { - return pedestrianPathogenEmissionCapacity; + public boolean isAerosolCloudsActive() { + return aerosolCloudsActive; } - public double getPedestrianPathogenAbsorptionRate() { - return pedestrianPathogenAbsorptionRate; + public double getAerosolCloudInitialPathogenLoad() { + return aerosolCloudParameters.getInitialPathogenLoad(); } - public double getPedestrianMinInfectiousDose() { - return pedestrianMinInfectiousDose; + public double getAerosolCloudHalfLife() { + return aerosolCloudParameters.getHalfLife(); } - public double getExposedPeriod() { - return exposedPeriod; + public double getAerosolCloudInitialRadius() { + return aerosolCloudParameters.getInitialRadius(); } - public double getInfectiousPeriod() { - return infectiousPeriod; + public double getAerosolCloudAirDispersionFactor() { + return aerosolCloudParameters.getAirDispersionFactor(); } - public double getRecoveredPeriod() { - return recoveredPeriod; + public double getAerosolCloudPedestrianDispersionWeight() { + return aerosolCloudParameters.getPedestrianDispersionWeight(); } - public double getAerosolCloudHalfLife() { - return aerosolCloudHalfLife; + public double getAerosolCloudAbsorptionRate() { + return aerosolCloudParameters.getAbsorptionRate(); } - public double getAerosolCloudInitialRadius() { - return aerosolCloudInitialRadius; + public boolean isDropletsActive() { + return dropletsActive; } - public double getDropletsExhalationFrequency() { - return dropletsExhalationFrequency; + public double getDropletsEmissionFrequency() { + return dropletParameters.getEmissionFrequency(); } public double getDropletsDistanceOfSpread() { - return dropletsDistanceOfSpread; + return dropletParameters.getDistanceOfSpread(); } public double getDropletsAngleOfSpreadInDeg() { - return dropletsAngleOfSpreadInDeg; + return dropletParameters.getAngleOfSpreadInDeg(); } public double getDropletsLifeTime() { - return dropletsLifeTime; + return dropletParameters.getLifeTime(); + } + + public double getDropletsPathogenLoad() { + return dropletParameters.getPathogenLoad(); + } + + public double getDropletsAbsorptionRate() { + return dropletParameters.getAbsorptionRate(); + } + + // Setter + + public void setAerosolCloudsActive(boolean aerosolCloudsActive) { + this.aerosolCloudsActive = aerosolCloudsActive; + } + + public void setAerosolCloudHalfLife(double aerosolCloudHalfLife) { + this.aerosolCloudParameters.setHalfLife(aerosolCloudHalfLife); + } + + public void setAerosolCloudInitialRadius(double aerosolCloudInitialRadius) { + this.aerosolCloudParameters.setInitialRadius(aerosolCloudInitialRadius); + } + + public void setAerosolCloudInitialPathogenLoad(double aerosolCloudInitialPathogenLoad) { + this.aerosolCloudParameters.setInitialPathogenLoad(aerosolCloudInitialPathogenLoad); + } + + public void setAerosolCloudAirDispersionFactor(double aerosolCloudAirDispersionFactor) { + this.aerosolCloudParameters.setAirDispersionFactor(aerosolCloudAirDispersionFactor); + } + + public void setAerosolCloudPedestrianDispersionWeight(double aerosolCloudPedestrianDispersionWeight) { + this.aerosolCloudParameters.setPedestrianDispersionWeight(aerosolCloudPedestrianDispersionWeight); + } + + public void setAerosolCloudAbsorptionRate(double aerosolCloudAbsorptionRate) { + this.aerosolCloudParameters.setAbsorptionRate(aerosolCloudAbsorptionRate); } - public double getDropletsPathogenLoadFactor() { - return dropletsPathogenLoadFactor; + public void setDropletsActive(boolean dropletsActive) { + this.dropletsActive = dropletsActive; } } diff --git a/VadereState/src/org/vadere/state/attributes/models/TransmissionModelSourceParameters.java b/VadereState/src/org/vadere/state/attributes/models/TransmissionModelSourceParameters.java deleted file mode 100644 index 4080c0370..000000000 --- a/VadereState/src/org/vadere/state/attributes/models/TransmissionModelSourceParameters.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.vadere.state.attributes.models; - -import org.vadere.state.attributes.Attributes; -import org.vadere.state.health.InfectionStatus; - -public class TransmissionModelSourceParameters extends Attributes { - - private int sourceId = -1; - private boolean infectious = false; - - public TransmissionModelSourceParameters() { - } - - public TransmissionModelSourceParameters(int sourceId, boolean infectious) { - this.sourceId = sourceId; - this.infectious = infectious; - } - - - public boolean isInfectious() { - return infectious; - } - - public int getSourceId() { - return sourceId; - } -} diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModelSourceParameters.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModelSourceParameters.java new file mode 100644 index 000000000..1991f8845 --- /dev/null +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModelSourceParameters.java @@ -0,0 +1,36 @@ +package org.vadere.state.attributes.models.infection; + +import org.vadere.state.attributes.Attributes; +/** + * Attributes required by an exposure model to define which source (defined by {@link #sourceId}) spawns + * {@link #infectious} agents. + */ +public class AttributesExposureModelSourceParameters extends Attributes { + + /** + * Default value -1 refers to any source that has not referenced explicitly by another sourceId. + */ + private int sourceId = -1; + + /** + * Describes whether agents from this source are infectious or not. + */ + private boolean infectious = false; + + public AttributesExposureModelSourceParameters() { + } + + public AttributesExposureModelSourceParameters(int sourceId, boolean infectious) { + this.sourceId = sourceId; + this.infectious = infectious; + } + + + public boolean isInfectious() { + return infectious; + } + + public int getSourceId() { + return sourceId; + } +} diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelAerosolCloud.java new file mode 100644 index 000000000..b33a5ffe1 --- /dev/null +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelAerosolCloud.java @@ -0,0 +1,127 @@ +package org.vadere.state.attributes.models.infection; + +import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.models.AttributesTransmissionModel; + +/** + * Attributes related to aerosol clouds that are shared among all aerosol clouds. These are not defined for each + * instance of AerosolCloud separately to keep the AerosolCloud lean. + * The frequency of occurrence is not defined here because aerosolClouds (if considered in the model) are directly + * linked to the respiratory cycle defined in {@link AttributesTransmissionModel}. + */ +public class AttributesTransmissionModelAerosolCloud extends Attributes { + + /** + * Describes exponential decay of pathogen load within an aerosol cloud; + * Unit: seconds + */ + private double halfLife; + + /** + * Describes initial spatial extent of aerosol clouds. The aerosol clouds have all the same initial + * circular extent (in the two-dimensional model). In 3D, we actually imagine them as spheres. + * Unit: meter + */ + private double initialRadius; + + /** + * Describes the amount of pathogen in an aerosol cloud immediately after exhalation. + * Indirectly describes the infectious pedestrian's infectiousness; is to be reduced if aerosol emission + * is mitigated, e.g. by masks. + * Unit: particles / exhalation + */ + private double initialPathogenLoad; + + /** + * Describes constant dispersion (over time), i.e. the spatial spread over time due to local air movement. + * This increases the radius of aerosol clouds equally in all directions (three-dimensional). + * Unit: meter / simulation step + */ + private double airDispersionFactor; + + /** + * Describes dispersion depending on agents, i.e. the spatial spread of aerosol clouds caused by moving agents + * (which results temporally in local air movement). Each agent that passes a cloud with speed > 0 m / s contributes + * to the dispersion of the cloud: deltaRadius = pedestrianSpeed * pedestrianDispersionWeight + * This increases the radius of aerosol clouds equally in all directions (three-dimensional). + * Unit: 1 / simulation step + */ + private double pedestrianDispersionWeight; + + /** + * Describes how much pathogen carried by aerosols is absorbed per inhalation; is to be reduced if aerosol + * inhalation is mitigated, e.g. by masks. + * Unit: 1 / inhalation (can also be interpreted as m^3 / inhalation) + */ + private double absorptionRate; + + public AttributesTransmissionModelAerosolCloud() { + this.halfLife = 600; + this.initialRadius = 1.5; + this.initialPathogenLoad = 10000; + this.airDispersionFactor = 0; + this.pedestrianDispersionWeight = 0.0125; + this.absorptionRate = 0.0005; + } + + public AttributesTransmissionModelAerosolCloud(double aerosolCloudHalfLife, double aerosolCloudInitialRadius, double initialPathogenLoad, double airDispersionFactor, double pedestrianDispersionWeight, double absorptionRate) { + this.halfLife = aerosolCloudHalfLife; + this.initialRadius = aerosolCloudInitialRadius; + this.initialPathogenLoad = initialPathogenLoad; + this.airDispersionFactor = airDispersionFactor; + this.pedestrianDispersionWeight = pedestrianDispersionWeight; + this.absorptionRate = absorptionRate; + } + + // Getter + + public double getHalfLife() { + return halfLife; + } + + public double getInitialRadius() { + return initialRadius; + } + + public double getInitialPathogenLoad() { + return initialPathogenLoad; + } + + public double getAirDispersionFactor() { + return airDispersionFactor; + } + + public double getPedestrianDispersionWeight() { + return pedestrianDispersionWeight; + } + + public double getAbsorptionRate() { + return absorptionRate; + } + + // Setter + + public void setHalfLife(double halfLife) { + this.halfLife = halfLife; + } + + public void setInitialRadius(double initialRadius) { + this.initialRadius = initialRadius; + } + + public void setInitialPathogenLoad(double initialPathogenLoad) { + this.initialPathogenLoad = initialPathogenLoad; + } + + public void setAirDispersionFactor(double airDispersionFactor) { + this.airDispersionFactor = airDispersionFactor; + } + + public void setPedestrianDispersionWeight(double pedestrianDispersionWeight) { + this.pedestrianDispersionWeight = pedestrianDispersionWeight; + } + + public void setAbsorptionRate(double absorptionRate) { + this.absorptionRate = absorptionRate; + } +} diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelDroplets.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelDroplets.java new file mode 100644 index 000000000..ee1edebd3 --- /dev/null +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelDroplets.java @@ -0,0 +1,100 @@ +package org.vadere.state.attributes.models.infection; + +import org.vadere.state.attributes.Attributes; + +/** + * Attributes related to droplets that are shared among all droplets. These are not defined for each + * instance of Droplets separately to keep Droplets lean. + */ +public class AttributesTransmissionModelDroplets extends Attributes { + + /** + * Unit: 1/second + */ + private double emissionFrequency; + + /** + * Unit: meter + */ + private double distanceOfSpread; + + /** + * Unit: degree + */ + private double angleOfSpreadInDeg; + + /** + * Unit: second + */ + private double lifeTime; + + /** + * Unit: particles + */ + private double pathogenLoad; + + /** + * Describes the fraction infectious particles inhaled from droplets if the inhaling agent is located within + * droplets. + * Unit: 1 / inhalation + */ + private double absorptionRate; + + public AttributesTransmissionModelDroplets() { + this.emissionFrequency = 1.0 / 60.0; + this.distanceOfSpread = 1.5; + this.angleOfSpreadInDeg = 30; + this.lifeTime = 1.5; + this.pathogenLoad = 10000; + this.absorptionRate = 0.1; + } + + public double getEmissionFrequency() { + return emissionFrequency; + } + + public double getDistanceOfSpread() { + return distanceOfSpread; + } + + public double getAngleOfSpreadInDeg() { + return angleOfSpreadInDeg; + } + + public double getLifeTime() { + return lifeTime; + } + + public double getPathogenLoad() { + return pathogenLoad; + } + + public double getAbsorptionRate() { + return absorptionRate; + } + + public void setEmissionFrequency(double emissionFrequency) { + this.emissionFrequency = emissionFrequency; + } + + public void setDistanceOfSpread(double distanceOfSpread) { + this.distanceOfSpread = distanceOfSpread; + } + + public void setAngleOfSpreadInDeg(double angleOfSpreadInDeg) { + this.angleOfSpreadInDeg = angleOfSpreadInDeg; + } + + public void setLifeTime(double lifeTime) { + this.lifeTime = lifeTime; + } + + public void setPathogenLoad(double pathogenLoad) { + this.pathogenLoad = pathogenLoad; + } + + public void setAbsorptionRate(double absorptionRate) { + this.absorptionRate = absorptionRate; + } + +} diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java index 3f71be3c3..c85eb8478 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java @@ -1,5 +1,6 @@ package org.vadere.state.attributes.scenario; +import org.vadere.state.attributes.models.AttributesTransmissionModel; import org.vadere.state.scenario.AerosolCloud; import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VShape; @@ -11,14 +12,12 @@ public class AttributesAerosolCloud extends AttributesParticleDispersion { private double radius; private VPoint center; - private double halfLife; // Constructors public AttributesAerosolCloud() { super(); - this.radius = 1.5; - this.center = new VPoint(0, 0); - this.halfLife = 600; + this.radius = new AttributesTransmissionModel().getAerosolCloudInitialRadius(); + this.center = new VPoint(); } public AttributesAerosolCloud(VShape shape, double creationTime){ @@ -29,11 +28,10 @@ public class AttributesAerosolCloud extends AttributesParticleDispersion { super(id, AerosolCloud.createAerosolCloudShape(center, radius), currentPathogenLoad); } - public AttributesAerosolCloud(int id, double radius, VPoint center, double creationTime, double halfLife, double initialPathogenLoad, double currentPathogenLoad) { + public AttributesAerosolCloud(int id, double radius, VPoint center, double creationTime, double initialPathogenLoad, double currentPathogenLoad) { super(id, creationTime, initialPathogenLoad, currentPathogenLoad, AerosolCloud.createAerosolCloudShape(center, radius)); this.radius = radius; this.center = center; - this.halfLife = halfLife; } // Getter @@ -45,8 +43,6 @@ public class AttributesAerosolCloud extends AttributesParticleDispersion { return center; } - public double getHalfLife() { return halfLife; } - public double getArea() { return radius * radius * Math.PI; } diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java index 8c4eb4dee..561dd760e 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java @@ -1,5 +1,6 @@ package org.vadere.state.attributes.scenario; +import org.vadere.state.attributes.models.infection.AttributesTransmissionModelDroplets; import org.vadere.state.scenario.Droplets; import org.vadere.util.geometry.shapes.VShape; @@ -9,7 +10,6 @@ import org.vadere.util.geometry.shapes.VShape; public class AttributesDroplets extends AttributesParticleDispersion { //private VShape shape; - private double lifeTime; // Constructors public AttributesDroplets() { @@ -18,11 +18,7 @@ public class AttributesDroplets extends AttributesParticleDispersion { } - public AttributesDroplets(int id, VShape shape, double creationTime, double lifeTime, double initialPathogenLoad) { + public AttributesDroplets(int id, VShape shape, double creationTime, double initialPathogenLoad) { super(id, creationTime, initialPathogenLoad, initialPathogenLoad, shape); - this.lifeTime = lifeTime; } - - // Getter - public double getLifeTime() { return lifeTime; } } diff --git a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java index f34f411eb..47e153784 100644 --- a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java +++ b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java @@ -23,8 +23,6 @@ public class AerosolCloud extends InfectiousParticleDispersion { private AttributesAerosolCloud attributes; - final static int numberOfNodesAlongShapeBound = 20; - // ToDo: implement AerosolCloudListener (or remove commented code) // private final Collection aerosolCloudListeners = new LinkedList<>(); @@ -83,10 +81,6 @@ public class AerosolCloud extends InfectiousParticleDispersion { return attributes.getCenter(); } - public double getHalfLife() { - return attributes.getHalfLife(); - } - public double getCreationTime() { return attributes.getCreationTime(); } diff --git a/VadereState/src/org/vadere/state/scenario/Droplets.java b/VadereState/src/org/vadere/state/scenario/Droplets.java index c816c3200..7a5ecb08f 100644 --- a/VadereState/src/org/vadere/state/scenario/Droplets.java +++ b/VadereState/src/org/vadere/state/scenario/Droplets.java @@ -47,14 +47,8 @@ public class Droplets extends InfectiousParticleDispersion { return attributes; } - public double getLifeTime() { return attributes.getLifeTime(); } - public double getCreationTime() { return attributes.getCreationTime(); } - public double getCurrentPathogenLoad() { - return attributes.getCurrentPathogenLoad(); - } - // Setter @Override public void setShape(VShape newShape) { diff --git a/VadereState/tests/org/vadere/state/scenario/AerosolCloudTest.java b/VadereState/tests/org/vadere/state/scenario/AerosolCloudTest.java index 9d3b40992..15b5ae6db 100644 --- a/VadereState/tests/org/vadere/state/scenario/AerosolCloudTest.java +++ b/VadereState/tests/org/vadere/state/scenario/AerosolCloudTest.java @@ -28,10 +28,9 @@ public class AerosolCloudTest { double radius = 1; VPoint center = new VPoint(10, 10); double creationTime = 0; - double halfLife = 60; double initialPathogenLoad = 10e4; - AttributesAerosolCloud attributesCirc = new AttributesAerosolCloud(id, radius, center, creationTime, halfLife, initialPathogenLoad, initialPathogenLoad); + AttributesAerosolCloud attributesCirc = new AttributesAerosolCloud(id, radius, center, creationTime, initialPathogenLoad, initialPathogenLoad); aerosolCloudCirc = new AerosolCloud(attributesCirc); } @@ -64,13 +63,12 @@ public class AerosolCloudTest { double pathogenLoad = 10e9; double lifeTime = 60*60*3; - AerosolCloud aerosolCloudOriginal = new AerosolCloud(new AttributesAerosolCloud(id, radius, center, creationTime, pathogenLoad, pathogenLoad, lifeTime)); + AerosolCloud aerosolCloudOriginal = new AerosolCloud(new AttributesAerosolCloud(id, radius, center, creationTime, pathogenLoad, pathogenLoad)); AerosolCloud aerosolCloudClone = aerosolCloudOriginal.clone(); Assert.assertEquals(aerosolCloudOriginal.getId(), aerosolCloudClone.getId()); Assert.assertEquals(aerosolCloudOriginal.getShape(), aerosolCloudClone.getShape()); Assert.assertEquals(aerosolCloudOriginal.getCreationTime(), aerosolCloudClone.getCreationTime(), ALLOWED_DOUBLE_TOLERANCE); - Assert.assertEquals(aerosolCloudOriginal.getHalfLife(), aerosolCloudClone.getHalfLife(), ALLOWED_DOUBLE_TOLERANCE); // check that original is not affected by setters/changes to the clone aerosolCloudClone.setId(2); -- GitLab From 80665b8e2dd389fd8f5c71c157f078c9968c370b Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 22 Feb 2022 17:01:27 +0100 Subject: [PATCH 24/83] [gui] increase opacity of aerosol clouds --- .../src/org/vadere/gui/components/view/DefaultRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java b/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java index 1596eed2b..c5749f96c 100644 --- a/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java +++ b/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java @@ -297,7 +297,7 @@ public abstract class DefaultRenderer { float maxAlpha = defaultModel.getConfig().getAerosolCloudAlphaMax(); float minAlpha = defaultModel.getConfig().getAerosolCloudAlphaMin(); //ToDo this is hard coded! - double maxPathogensPerArea = 10000; + double maxPathogensPerArea = 1400; // results from 10000 / (1.5^2 * PI) double pathogensPerArea = cloud.getCurrentPathogenLoad() / cloud.getArea(); pathogensPerArea = Math.min(pathogensPerArea, maxPathogensPerArea); // make sure that maxPathogensPerArea is not exceeded int currentAlpha = (int) ((pathogensPerArea / maxPathogensPerArea) * (maxAlpha - minAlpha) + minAlpha); -- GitLab From f6d400b9237ada8a79fd64e51c5895c6c872e064 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 23 Feb 2022 14:39:36 +0100 Subject: [PATCH 25/83] [wip] Refactoring Make ExposureModelHealthStatus abstract class instead of interface; include attributes from TransmissionModelHealthStatus --- .../health/ExposureModelHealthStatus.java | 31 +++++++++-- .../health/TransmissionModelHealthStatus.java | 54 +++++++++---------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java index 82ff63522..0f9af6805 100644 --- a/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java @@ -1,13 +1,34 @@ package org.vadere.state.health; -public interface ExposureModelHealthStatus { +public abstract class ExposureModelHealthStatus { + + boolean infectious; + double degreeOfExposure; + + ExposureModelHealthStatus() { + this(false, 0); + } + + ExposureModelHealthStatus(boolean infectious, double degreeOfExposure) { + this.infectious = infectious; + this.degreeOfExposure = degreeOfExposure; + } + // Getter - boolean isInfectious(); + public boolean isInfectious() { + return infectious; + } - double getDegreeOfExposure(); + public double getDegreeOfExposure() { + return degreeOfExposure; + } // Setter - void setInfectious(boolean infectious); + public void setInfectious(boolean infectious) { + this.infectious = infectious; + } - void setDegreeOfExposure(double degreeOfExposure); + public void setDegreeOfExposure(double degreeOfExposure) { + this.degreeOfExposure = degreeOfExposure; + } } diff --git a/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java b/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java index 70b8d3407..67c806f3e 100644 --- a/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java @@ -2,19 +2,20 @@ package org.vadere.state.health; import org.vadere.util.geometry.shapes.VPoint; -public class TransmissionModelHealthStatus implements ExposureModelHealthStatus { +public class TransmissionModelHealthStatus extends ExposureModelHealthStatus { - // Member variables - boolean isInfectious; - double degreeOfExposure; + private boolean breathingIn; - boolean isBreathingIn; - double respiratoryTimeOffset; + /* + * Defines the start of each pedestrian's respiratory cycle. This allows to have individual respiratory cycles for + * all pedestrians, i.e. they in- or exhale all at different times. + */ + private double respiratoryTimeOffset; /* * defines the position at which pedestrian starts current exhalation; */ - VPoint exhalationStartPosition; + private VPoint exhalationStartPosition; /* * reset value for simulation periods during which pedestrian inhales @@ -23,21 +24,19 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus // Constructors public TransmissionModelHealthStatus() { - this(false, 0, false, 0, RESET_EXHALATION_POSITION); + this(false, 0, RESET_EXHALATION_POSITION); } - public TransmissionModelHealthStatus(boolean isInfectious, double degreeOfExposure, boolean isBreathingIn, double respiratoryTimeOffset, VPoint exhalationStartPosition) { - this.isInfectious = isInfectious; - this.degreeOfExposure = degreeOfExposure; - this.isBreathingIn = isBreathingIn; + public TransmissionModelHealthStatus(boolean breathingIn, double respiratoryTimeOffset, VPoint exhalationStartPosition) { + super(); + this.breathingIn = breathingIn; this.respiratoryTimeOffset = respiratoryTimeOffset; this.exhalationStartPosition = exhalationStartPosition; } public TransmissionModelHealthStatus(TransmissionModelHealthStatus other) { - this.isInfectious = other.isInfectious(); - this.degreeOfExposure = other.getDegreeOfExposure(); - this.isBreathingIn = other.isInfectious(); + super(other.isInfectious(), other.getDegreeOfExposure()); + this.breathingIn = other.isBreathingIn(); this.respiratoryTimeOffset = other.getRespiratoryTimeOffset(); this.exhalationStartPosition = other.getExhalationStartPosition(); } @@ -46,7 +45,7 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus // Getter @Override public boolean isInfectious() { - return isInfectious; + return infectious; } @Override @@ -55,7 +54,7 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus } public boolean isBreathingIn() { - return isBreathingIn; + return breathingIn; } public double getRespiratoryTimeOffset() { @@ -66,18 +65,10 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus return exhalationStartPosition; } - void updateRespiratoryCycle(double simTimeInSec) { - - } - - public void incrementDegreeOfExposure(double deltaDegreeOfExposure) { - this.degreeOfExposure += deltaDegreeOfExposure; - } - // Setter @Override public void setInfectious(boolean infectious) { - isInfectious = infectious; + this.infectious = infectious; } @Override @@ -86,7 +77,7 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus } public void setBreathingIn(boolean breathingIn) { - isBreathingIn = breathingIn; + this.breathingIn = breathingIn; } public void setRespiratoryTimeOffset(double respiratoryTimeOffset) { @@ -99,6 +90,10 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus // Methods + public void incrementDegreeOfExposure(double deltaDegreeOfExposure) { + this.degreeOfExposure += deltaDegreeOfExposure; + } + /* * Defines whether the pedestrian inhales or exhales depending on the current simulation time, * respiratoryTimeOffset, and periodLength. Assumes that periodLength for inhalation and exhalation are equally @@ -110,15 +105,14 @@ public class TransmissionModelHealthStatus implements ExposureModelHealthStatus } public boolean isStartingExhalation() { - return (!isBreathingIn && exhalationStartPosition == RESET_EXHALATION_POSITION); + return (!breathingIn && exhalationStartPosition == RESET_EXHALATION_POSITION); } public boolean isStartingInhalation() { - return (isBreathingIn && !(exhalationStartPosition == RESET_EXHALATION_POSITION)); + return (breathingIn && !(exhalationStartPosition == RESET_EXHALATION_POSITION)); } public void resetStartExhalationPosition() { exhalationStartPosition = RESET_EXHALATION_POSITION; } - } -- GitLab From 1e8b32849ef5b33459dcc18ef61ab8e11fccdf32 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 23 Feb 2022 15:05:51 +0100 Subject: [PATCH 26/83] [wip] Refactoring Change getHealthStatus and setHealthStatus methods in Pedestrian and TransmissionModel --- .../models/infection/TransmissionModel.java | 36 +++++++++++-------- .../org/vadere/state/scenario/Pedestrian.java | 29 ++++++--------- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index ec0f93919..88dcb1375 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -118,7 +118,7 @@ public class TransmissionModel extends AbstractExposureModel { @Override public void updatePedestrianDegreeOfExposure(Pedestrian pedestrian, double deltaDegreeOfExposure) { - pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).incrementDegreeOfExposure(deltaDegreeOfExposure); + pedestrian.getHealthStatus().incrementDegreeOfExposure(deltaDegreeOfExposure); } public void executeAerosolCloudEmissionEvents(double simTimeInSec) { @@ -148,18 +148,18 @@ public class TransmissionModel extends AbstractExposureModel { public void createAerosolClouds(double simTimeInSec, Pedestrian pedestrian) { - if (pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).isStartingExhalation()) { - pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).setExhalationStartPosition(pedestrian.getPosition()); + if (pedestrian.getHealthStatus().isStartingExhalation()) { + pedestrian.getHealthStatus().setExhalationStartPosition(pedestrian.getPosition()); - } else if (pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).isStartingInhalation()) { - VPoint startBreatheOutPosition = pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).getExhalationStartPosition(); + } else if (pedestrian.getHealthStatus().isStartingInhalation()) { + VPoint startBreatheOutPosition = pedestrian.getHealthStatus().getExhalationStartPosition(); VPoint stopBreatheOutPosition = pedestrian.getPosition(); VLine distanceWalkedDuringExhalation = new VLine(startBreatheOutPosition, stopBreatheOutPosition); AerosolCloud aerosolCloud = generateAerosolCloud(simTimeInSec, distanceWalkedDuringExhalation); topography.addAerosolCloud(aerosolCloud); - pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).resetStartExhalationPosition(); + pedestrian.getHealthStatus().resetStartExhalationPosition(); } } @@ -233,12 +233,18 @@ public class TransmissionModel extends AbstractExposureModel { for (AerosolCloud aerosolCloud : allAerosolClouds) { double deltaRadius = 0.0; - // Increasing extent due to dispersion, multiplication with simTimeStepLength keeps deltaRadius independent of simulation step width + /* + * Increasing extent due to dispersion, multiplication with simTimeStepLength keeps deltaRadius independent + * of simulation step width + */ if (attrTransmissionModel.getAerosolCloudAirDispersionFactor() > 0) { deltaRadius = attrTransmissionModel.getAerosolCloudAirDispersionFactor() * simTimeStepLength; } - // Increasing extent due to moving air caused by agents, multiplication with simTimeStepLength keeps deltaRadius independent of simulation step width + /* + * Increasing extent due to moving air caused by agents, multiplication with simTimeStepLength keeps + * deltaRadius independent of simulation step width + */ if (attrTransmissionModel.getAerosolCloudPedestrianDispersionWeight() > 0) { Collection pedestriansInsideCloud = getPedestriansInsideAerosolCloud(topography, aerosolCloud); for (Pedestrian pedestrian : pedestriansInsideCloud) { @@ -282,7 +288,8 @@ public class TransmissionModel extends AbstractExposureModel { private void updatePedsHealthStatus(double simTimeInSec) { Collection allPedestrians = topography.getPedestrianDynamicElements().getElements(); for (Pedestrian pedestrian : allPedestrians) { - pedestrian.getHealthStatus(TransmissionModelHealthStatus.class).updateRespiratoryCycle(simTimeInSec, attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + pedestrian.getHealthStatus() + .updateRespiratoryCycle(simTimeInSec, attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); } } @@ -290,7 +297,7 @@ public class TransmissionModel extends AbstractExposureModel { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(p -> p.getHealthStatus(TransmissionModelHealthStatus.class).isBreathingIn()) + .filter(p -> p.getHealthStatus().isBreathingIn()) .collect(Collectors.toSet()); // Agents absorb pathogen continuously but simulation is discrete. Therefore, the absorption during inhalation @@ -316,7 +323,7 @@ public class TransmissionModel extends AbstractExposureModel { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(p -> p.getHealthStatus(TransmissionModelHealthStatus.class).isBreathingIn()) + .filter(p -> p.getHealthStatus().isBreathingIn()) .collect(Collectors.toSet()); /* @@ -359,11 +366,10 @@ public class TransmissionModel extends AbstractExposureModel { AttributesExposureModelSourceParameters sourceParameters = defineSourceParameters(controller); Pedestrian ped = (Pedestrian) scenarioElement; - ped.addHealthStatus(TransmissionModelHealthStatus.class); + ped.setHealthStatus(new TransmissionModelHealthStatus()); ped.setInfectious(sourceParameters.isInfectious()); - ped.setDegreeOfExposure(0); - ped.getHealthStatus(TransmissionModelHealthStatus.class).setRespiratoryTimeOffset(random.nextDouble() * attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); - ped.getHealthStatus(TransmissionModelHealthStatus.class).setBreathingIn(false); + ped.getHealthStatus().setRespiratoryTimeOffset(random.nextDouble() * attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + ped.getHealthStatus().setBreathingIn(false); //TODO check exhalation start position null? logger.infof(">>>>>>>>>>>sourceControllerEvent at time: %f agentId: %d", simTimeInSec, scenarioElement.getId()); diff --git a/VadereState/src/org/vadere/state/scenario/Pedestrian.java b/VadereState/src/org/vadere/state/scenario/Pedestrian.java index 14803c69e..5958407ac 100644 --- a/VadereState/src/org/vadere/state/scenario/Pedestrian.java +++ b/VadereState/src/org/vadere/state/scenario/Pedestrian.java @@ -15,7 +15,6 @@ import org.vadere.state.simulation.VTrajectory; import org.vadere.state.types.ScenarioElementType; import org.vadere.util.geometry.shapes.VPoint; -import java.lang.reflect.InvocationTargetException; import java.util.*; public class Pedestrian extends Agent { @@ -176,8 +175,8 @@ public class Pedestrian extends Agent { return ScenarioElementType.PEDESTRIAN; } - public T getHealthStatus(Class modelType) { - return modelType.cast(healthStatus); + public T getHealthStatus() { + return (T) healthStatus; } public boolean isInfectious() { @@ -268,6 +267,14 @@ public class Pedestrian extends Agent { return modelPedestrianMap.put(modelPedestrian.getClass(), modelPedestrian); } + public void setHealthStatus(ExposureModelHealthStatus healthStatus) { + this.healthStatus = healthStatus; + } + + public void setInfectionStatus(DoseResponseModelInfectionStatus infectionStatus) { + this.infectionStatus = infectionStatus; + } + public void setInfectious(boolean infectious) { healthStatus.setInfectious(infectious); } @@ -350,20 +357,4 @@ public class Pedestrian extends Agent { protected void setTargetsOther(LinkedList targetIds) { super.setTargets(targetIds); } - - public void addInfectionStatus(Class infectionStatusType) { - try { - infectionStatus = (DoseResponseModelInfectionStatus) infectionStatusType.getDeclaredConstructor().newInstance(); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - e.printStackTrace(); - } - } - - public void addHealthStatus(Class healthStatusType) { - try { - healthStatus = (ExposureModelHealthStatus) healthStatusType.getDeclaredConstructor().newInstance(); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - e.printStackTrace(); - } - } } -- GitLab From 79b2547c054783b44238c88e558ff53ce5909e46 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 23 Feb 2022 15:11:51 +0100 Subject: [PATCH 27/83] Define HealthStatus for pedestrians that are directly put into the topography; Previously, pedestrians that are not spawned by sources could not be accessed / manipulated by the TransmissionModel, i.e. one could not define a health status. This is now handled by the TopographyController. --- .../TopographyController.java | 29 +++++++++++++++++-- .../models/infection/TransmissionModel.java | 24 +++++++++++++-- .../models/AttributesTransmissionModel.java | 14 +++++++-- ...tributesExposureModelSourceParameters.java | 12 +++++--- 4 files changed, 68 insertions(+), 11 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/control/scenarioelements/TopographyController.java b/VadereSimulator/src/org/vadere/simulator/control/scenarioelements/TopographyController.java index 4407c303b..333999ee3 100644 --- a/VadereSimulator/src/org/vadere/simulator/control/scenarioelements/TopographyController.java +++ b/VadereSimulator/src/org/vadere/simulator/control/scenarioelements/TopographyController.java @@ -1,24 +1,30 @@ package org.vadere.simulator.control.scenarioelements; +import org.vadere.simulator.control.scenarioelements.listener.ControllerEventListener; +import org.vadere.simulator.control.scenarioelements.listener.ControllerEventProvider; import org.vadere.simulator.models.DynamicElementFactory; import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.exceptions.AttributesNotFoundException; import org.vadere.state.attributes.models.AttributesFloorField; +import org.vadere.state.scenario.Agent; import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Topography; import org.vadere.util.logging.Logger; +import java.util.ArrayList; import java.util.List; import java.util.Random; -public class TopographyController extends OfflineTopographyController { +public class TopographyController extends OfflineTopographyController implements ControllerEventProvider { private static Logger logger = Logger.getLogger(TopographyController.class); private final Domain domain; private final DynamicElementFactory dynamicElementFactory; + protected ArrayList> eventListeners = new ArrayList<>(); + public TopographyController(Domain domain, DynamicElementFactory dynamicElementFactory, final Random random) { super(domain, random); this.domain = domain; @@ -40,10 +46,10 @@ public class TopographyController extends OfflineTopographyController { attributesFloorField = new AttributesFloorField(); } prepareTopography(attributesFloorField); - createAgentWrapperPedestrians(); + createAgentWrapperPedestrians(simTimeInSec); } - private void createAgentWrapperPedestrians() { + private void createAgentWrapperPedestrians(double simTimeInSec) { for (Pedestrian agentWrapper : domain.getTopography().getInitialElements(Pedestrian.class)) { // Maybe, pass "attributesAgent" to "createElement()" so that attributes, // which are configure in GUI, are not overwritten by "createElement()" method @@ -51,6 +57,11 @@ public class TopographyController extends OfflineTopographyController { agentWrapper.getId(), Pedestrian.class); applyAttributesFromAgentWrapper(agentWrapper, createdPedestrian); + + for (ControllerEventListener listener : eventListeners) { + createdPedestrian = (Pedestrian) listener.notify(this, simTimeInSec, createdPedestrian); + } + domain.getTopography().addElement(createdPedestrian); } domain.getTopography().initializePedestrianCount(); @@ -94,4 +105,16 @@ public class TopographyController extends OfflineTopographyController { public void postLoop(double simTimeInSec) { domain.getTopography().reset(); } + + @Override + public void register(ControllerEventListener listener) { + if (! eventListeners.contains(listener)){ + eventListeners.add(listener); + } + } + + @Override + public void unregister(ControllerEventListener listener) { + eventListeners.remove(listener); + } } diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java index 88dcb1375..eab4105b4 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java @@ -3,6 +3,7 @@ package org.vadere.simulator.models.infection; import org.vadere.annotation.factories.models.ModelClass; import org.vadere.simulator.context.VadereContext; import org.vadere.simulator.control.scenarioelements.SourceController; +import org.vadere.simulator.control.scenarioelements.TopographyController; import org.vadere.simulator.control.simulation.ControllerProvider; import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; @@ -84,10 +85,11 @@ public class TransmissionModel extends AbstractExposureModel { @Override public void registerToScenarioElementControllerEvents(ControllerProvider controllerProvider) { - // ToDo: controllerProvider should be handled by initialize method (this requires changes in all models) + // ToDo: controllerProvider could be handled by initialize method (this requires changes in all models) for (var controller : controllerProvider.getSourceControllers()){ controller.register(this::sourceControllerEvent); } + controllerProvider.getTopographyController().register(this::topographyControllerEvent); } @Override @@ -179,7 +181,6 @@ public class TransmissionModel extends AbstractExposureModel { } private void createDroplets(double simTimeInSec, Pedestrian pedestrian) { - // ToDo: refactor: it could be better to have the walking directions stored in pedestrian int pedestrianId = pedestrian.getId(); Vector2D viewingDirection; VPoint currentPosition = pedestrian.getPosition(); @@ -376,6 +377,25 @@ public class TransmissionModel extends AbstractExposureModel { return ped; } + /* + * The TopographyController assures that each pedestrian that is directly set into the topography obtains a health + * status. + */ + private Pedestrian topographyControllerEvent(TopographyController topographyController, double simtimeInSec, Agent agent) { + Pedestrian pedestrian = (Pedestrian) agent; + TransmissionModelHealthStatus defaultHealthStatus = new TransmissionModelHealthStatus(); + + pedestrian.setHealthStatus(defaultHealthStatus); + pedestrian.getHealthStatus() + .setRespiratoryTimeOffset(random.nextDouble() * attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + + if (attrTransmissionModel.getInfectiousPedestrianIdsNoSource().contains(agent.getId())) { + pedestrian.setInfectious(true); + } + + return pedestrian; + } + private AttributesExposureModelSourceParameters defineSourceParameters(SourceController controller) { int sourceId = controller.getSourceId(); int defaultSourceId = -1; diff --git a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java index a8fb0d05d..ae6f7473e 100644 --- a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java @@ -2,7 +2,6 @@ package org.vadere.state.attributes.models; import org.vadere.annotation.factories.attributes.ModelAttributeClass; import org.vadere.state.attributes.Attributes; -import org.vadere.state.attributes.AttributesEmbedShape; import java.util.ArrayList; import java.util.Arrays; @@ -30,6 +29,12 @@ public class AttributesTransmissionModel extends Attributes { private ArrayList transmissionModelSourceParameters; + /** + * Contains the Ids of pedestrians that are directly set into the topography (and not spawned by sources). + * Any agent contained in the list is infectious. All others (not spawned by sources) are not infectious. + */ + private ArrayList infectiousPedestrianIdsNoSource; + /** * Attribute related to the pedestrians' health state that is shared among all pedestrians. It is not defined * for each instance of TransmissionModelHealthStatus separately to keep the TransmissionModelHealthStatus lean. @@ -51,7 +56,8 @@ public class AttributesTransmissionModel extends Attributes { public AttributesTransmissionModel() { - this.transmissionModelSourceParameters = new ArrayList<>(Arrays.asList(new AttributesExposureModelSourceParameters(AttributesEmbedShape.ID_NOT_SET, false))); + this.transmissionModelSourceParameters = new ArrayList<>(Arrays.asList(new AttributesExposureModelSourceParameters())); + this.infectiousPedestrianIdsNoSource = new ArrayList<>(); this.pedestrianRespiratoryCyclePeriod = 4; @@ -72,6 +78,10 @@ public class AttributesTransmissionModel extends Attributes { return transmissionModelSourceParameters; } + public ArrayList getInfectiousPedestrianIdsNoSource() { + return infectiousPedestrianIdsNoSource; + } + public boolean isAerosolCloudsActive() { return aerosolCloudsActive; } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModelSourceParameters.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModelSourceParameters.java index 1991f8845..fc1002587 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModelSourceParameters.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModelSourceParameters.java @@ -1,6 +1,8 @@ package org.vadere.state.attributes.models.infection; import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.AttributesEmbedShape; + /** * Attributes required by an exposure model to define which source (defined by {@link #sourceId}) spawns * {@link #infectious} agents. @@ -10,21 +12,23 @@ public class AttributesExposureModelSourceParameters extends Attributes { /** * Default value -1 refers to any source that has not referenced explicitly by another sourceId. */ - private int sourceId = -1; + private int sourceId; /** * Describes whether agents from this source are infectious or not. */ - private boolean infectious = false; + private boolean infectious; + - public AttributesExposureModelSourceParameters() { - } public AttributesExposureModelSourceParameters(int sourceId, boolean infectious) { this.sourceId = sourceId; this.infectious = infectious; } + public AttributesExposureModelSourceParameters() { + this(AttributesEmbedShape.ID_NOT_SET, false); + } public boolean isInfectious() { return infectious; -- GitLab From 0ded980fc25c466e7836c1a8276e7b2060211826 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 23 Feb 2022 15:49:28 +0100 Subject: [PATCH 28/83] Rename TransmissionModel to AirTransmissionModel; TransmissionModel could also refer to transmission in the context of communication; Here, transmission relates to transmission of pathogens carried by (airborne) particles through the air. Further, rename TransmissionModelHealthStatus, TransmissionModelTest, AttributesTransmissionModel, AttributesTransmissionModelAerosolCloud, AttributesTransmissionModelDroplets --- .../scenarios/bottleneckA.scenario | 6 +- .../scenarios/bottleneckB.scenario | 6 +- .../bottleneckB_socialDistancing.scenario | 6 +- .../scenarios/closeContact.scenario | 6 +- .../scenarios/passageway.scenario | 6 +- .../queueScenario_publication.scenario | 6 +- ...hamner-2020-life_postvis_template.scenario | 6 +- ...e_postvis_template_seed_000_100fr.scenario | 6 +- .../hamner-2020-life_template.scenario | 6 +- .../scenarios/lu-2020-life.scenario | 6 +- .../miller-2020-life_seed_000.scenario | 6 +- .../miller-2020-life_template.scenario | 6 +- ...c_2_density_discrete_ca_5_sources.scenario | 6 +- .../queueScenario_modelComparison.scenario | 6 +- .../control/simulation/ScenarioRun.java | 4 +- ...onModel.java => AirTransmissionModel.java} | 114 +++++++++--------- ...est.java => AirTransmissionModelTest.java} | 26 ++-- ...va => AttributesAirTransmissionModel.java} | 36 +++--- ...utesAirTransmissionModelAerosolCloud.java} | 10 +- ...tributesAirTransmissionModelDroplets.java} | 4 +- .../scenario/AttributesAerosolCloud.java | 4 +- .../scenario/AttributesDroplets.java | 1 - ... => AirTransmissionModelHealthStatus.java} | 8 +- 23 files changed, 145 insertions(+), 146 deletions(-) rename VadereSimulator/src/org/vadere/simulator/models/infection/{TransmissionModel.java => AirTransmissionModel.java} (73%) rename VadereSimulator/tests/org/vadere/simulator/models/infection/{TransmissionModelTest.java => AirTransmissionModelTest.java} (85%) rename VadereState/src/org/vadere/state/attributes/models/{AttributesTransmissionModel.java => AttributesAirTransmissionModel.java} (76%) rename VadereState/src/org/vadere/state/attributes/models/infection/{AttributesTransmissionModelAerosolCloud.java => AttributesAirTransmissionModelAerosolCloud.java} (88%) rename VadereState/src/org/vadere/state/attributes/models/infection/{AttributesTransmissionModelDroplets.java => AttributesAirTransmissionModelDroplets.java} (94%) rename VadereState/src/org/vadere/state/health/{TransmissionModelHealthStatus.java => AirTransmissionModelHealthStatus.java} (90%) diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario index fe84bab0a..b50d26801 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario @@ -62,7 +62,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -95,8 +95,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : 3, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario index f77ff1273..dce63baa5 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario @@ -87,7 +87,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -120,8 +120,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : 3, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario index 0cc510ddb..12a3ee5bb 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario @@ -87,7 +87,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -120,8 +120,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : 3, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario index c670c4930..306de97ce 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario @@ -92,7 +92,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.0, @@ -125,8 +125,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : 15, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario b/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario index 4576b7475..dab03c7d2 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario @@ -62,7 +62,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -95,8 +95,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario index 486a1af1d..716f339c2 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario @@ -110,7 +110,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -143,8 +143,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : 1, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario index 38058dc51..368ff1612 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario @@ -77,7 +77,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -110,8 +110,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario index af9652393..29683ee8b 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario @@ -77,7 +77,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -110,8 +110,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario index d51d81217..cf180a967 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario @@ -35,7 +35,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -68,8 +68,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario index 51f6583ea..9b7673f5b 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario @@ -62,7 +62,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -95,8 +95,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario index 0799b5406..a7bc460b1 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario @@ -42,7 +42,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -75,8 +75,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false }, { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario index c38f8bff4..96520ad8d 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario @@ -42,7 +42,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -75,8 +75,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false }, { diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario index d253412e6..0a90589a1 100644 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario +++ b/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario @@ -98,7 +98,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -110,8 +110,8 @@ "personalSpacePower" : 1, "intimateSpacePower" : 1 }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectionStatus" : "SUSCEPTIBLE" }, { diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario index e0b957538..bb404c2d3 100644 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario +++ b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario @@ -110,7 +110,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.TransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -143,8 +143,8 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesTransmissionModel" : { - "transmissionModelSourceParameters" : [ { + "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "exposureModelSourceParameters" : [ { "sourceId" : 2, "infectionStatus" : "SUSCEPTIBLE" }, { diff --git a/VadereSimulator/src/org/vadere/simulator/control/simulation/ScenarioRun.java b/VadereSimulator/src/org/vadere/simulator/control/simulation/ScenarioRun.java index dd9ec2407..05f816370 100644 --- a/VadereSimulator/src/org/vadere/simulator/control/simulation/ScenarioRun.java +++ b/VadereSimulator/src/org/vadere/simulator/control/simulation/ScenarioRun.java @@ -19,8 +19,8 @@ import org.vadere.simulator.control.psychology.perception.StimulusController; import org.vadere.simulator.control.scenarioelements.TargetChangerController; import org.vadere.simulator.models.MainModel; import org.vadere.simulator.models.MainModelBuilder; +import org.vadere.simulator.models.infection.AirTransmissionModel; import org.vadere.simulator.models.potential.solver.EikonalSolverCacheProvider; -import org.vadere.simulator.models.infection.TransmissionModel; import org.vadere.simulator.projects.Domain; import org.vadere.simulator.projects.RunnableFinishedListener; import org.vadere.simulator.projects.Scenario; @@ -122,7 +122,7 @@ public class ScenarioRun implements Runnable { ctx.setEikonalSolverProvider(new EikonalSolverCacheProvider(scenarioCache)); // cache found use CacheProvider if possible ctx.put("cache", scenarioCache); - ctx.put(TransmissionModel.simStepLength, scenario.getAttributesSimulation().getSimTimeStepLength()); + ctx.put(AirTransmissionModel.simStepLength, scenario.getAttributesSimulation().getSimTimeStepLength()); VadereContext.add(scenarioName, ctx); logger.info("scenario context initialized."); diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java similarity index 73% rename from VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java rename to VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index eab4105b4..b88d9943c 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/TransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -8,12 +8,12 @@ import org.vadere.simulator.control.simulation.ControllerProvider; import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; -import org.vadere.state.attributes.models.AttributesTransmissionModel; +import org.vadere.state.attributes.models.AttributesAirTransmissionModel; import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesDroplets; -import org.vadere.state.health.TransmissionModelHealthStatus; +import org.vadere.state.health.AirTransmissionModelHealthStatus; import org.vadere.state.scenario.*; import org.vadere.util.geometry.shapes.VLine; import org.vadere.util.geometry.shapes.VPoint; @@ -29,21 +29,21 @@ import static org.vadere.state.scenario.Droplets.createTransformedDropletsShape; /** * This class models the spread of infectious pathogen among pedestrians. - * For this purpose, the TransmissionModel controls the airborne transmission of pathogen from infectious pedestrians to + * For this purpose, the AirTransmissionModel controls the airborne transmission of pathogen from infectious pedestrians to * other pedestrians, i.e. it *
    - *
  • initializes each pedestrian's {@link TransmissionModelHealthStatus} after a pedestrian is inserted into the topography,
  • - *
  • updates the pedestrian's {@link TransmissionModelHealthStatus}
  • + *
  • initializes each pedestrian's {@link AirTransmissionModelHealthStatus} after a pedestrian is inserted into the topography,
  • + *
  • updates the pedestrian's {@link AirTransmissionModelHealthStatus}
  • *
  • creates, updates and deletes each {@link AerosolCloud}
  • *
  • creates, updates and deletes {@link Droplets}
  • *
*/ @ModelClass -public class TransmissionModel extends AbstractExposureModel { +public class AirTransmissionModel extends AbstractExposureModel { - protected static Logger logger = Logger.getLogger(TransmissionModel.class); + protected static Logger logger = Logger.getLogger(AirTransmissionModel.class); - private AttributesTransmissionModel attrTransmissionModel; + private AttributesAirTransmissionModel attrAirTransmissionModel; double simTimeStepLength; Topography topography; int aerosolCloudIdCounter; @@ -75,7 +75,7 @@ public class TransmissionModel extends AbstractExposureModel { this.domain = domain; this.random = random; this.attributesAgent = attributesPedestrian; - this.attrTransmissionModel = Model.findAttributes(attributesList, AttributesTransmissionModel.class); + this.attrAirTransmissionModel = Model.findAttributes(attributesList, AttributesAirTransmissionModel.class); this.topography = domain.getTopography(); this.simTimeStepLength = VadereContext.get(this.topography).getDouble(simStepLength); this.aerosolCloudIdCounter = 1; @@ -101,26 +101,26 @@ public class TransmissionModel extends AbstractExposureModel { @Override public void update(double simTimeInSec) { - if (attrTransmissionModel.isAerosolCloudsActive()) { + if (attrAirTransmissionModel.isAerosolCloudsActive()) { executeAerosolCloudEmissionEvents(simTimeInSec); updateAerosolClouds(simTimeInSec); updatePedestriansExposureToAerosolClouds(); } - if (attrTransmissionModel.isDropletsActive()) { + if (attrAirTransmissionModel.isDropletsActive()) { executeDropletEmissionEvents(simTimeInSec); updateDroplets(simTimeInSec); updatePedestriansExposureToDroplets(); } - if (attrTransmissionModel.isAerosolCloudsActive() || attrTransmissionModel.isDropletsActive()) { + if (attrAirTransmissionModel.isAerosolCloudsActive() || attrAirTransmissionModel.isDropletsActive()) { updatePedsHealthStatus(simTimeInSec); } } @Override public void updatePedestrianDegreeOfExposure(Pedestrian pedestrian, double deltaDegreeOfExposure) { - pedestrian.getHealthStatus().incrementDegreeOfExposure(deltaDegreeOfExposure); + pedestrian.getHealthStatus().incrementDegreeOfExposure(deltaDegreeOfExposure); } public void executeAerosolCloudEmissionEvents(double simTimeInSec) { @@ -150,18 +150,18 @@ public class TransmissionModel extends AbstractExposureModel { public void createAerosolClouds(double simTimeInSec, Pedestrian pedestrian) { - if (pedestrian.getHealthStatus().isStartingExhalation()) { - pedestrian.getHealthStatus().setExhalationStartPosition(pedestrian.getPosition()); + if (pedestrian.getHealthStatus().isStartingExhalation()) { + pedestrian.getHealthStatus().setExhalationStartPosition(pedestrian.getPosition()); - } else if (pedestrian.getHealthStatus().isStartingInhalation()) { - VPoint startBreatheOutPosition = pedestrian.getHealthStatus().getExhalationStartPosition(); + } else if (pedestrian.getHealthStatus().isStartingInhalation()) { + VPoint startBreatheOutPosition = pedestrian.getHealthStatus().getExhalationStartPosition(); VPoint stopBreatheOutPosition = pedestrian.getPosition(); VLine distanceWalkedDuringExhalation = new VLine(startBreatheOutPosition, stopBreatheOutPosition); AerosolCloud aerosolCloud = generateAerosolCloud(simTimeInSec, distanceWalkedDuringExhalation); topography.addAerosolCloud(aerosolCloud); - pedestrian.getHealthStatus().resetStartExhalationPosition(); + pedestrian.getHealthStatus().resetStartExhalationPosition(); } } @@ -169,11 +169,11 @@ public class TransmissionModel extends AbstractExposureModel { VPoint center = distanceWalkedDuringExhalation.midPoint(); AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(aerosolCloudIdCounter, - attrTransmissionModel.getAerosolCloudInitialRadius(), + attrAirTransmissionModel.getAerosolCloudInitialRadius(), center, simTimeInSec, - attrTransmissionModel.getAerosolCloudInitialPathogenLoad(), - attrTransmissionModel.getAerosolCloudInitialPathogenLoad())); + attrAirTransmissionModel.getAerosolCloudInitialPathogenLoad(), + attrAirTransmissionModel.getAerosolCloudInitialPathogenLoad())); aerosolCloudIdCounter = aerosolCloudIdCounter + 1; @@ -200,19 +200,19 @@ public class TransmissionModel extends AbstractExposureModel { lastPedestrianPositions.put(pedestrianId, currentPosition); // period between two droplet generating respiratory events - double dropletExhalationPeriod = 1 / attrTransmissionModel.getDropletsEmissionFrequency(); + double dropletExhalationPeriod = 1 / attrAirTransmissionModel.getDropletsEmissionFrequency(); if (simTimeInSec % dropletExhalationPeriod < simTimeStepLength) { VShape shape = createTransformedDropletsShape(pedestrian.getPosition(), viewingDirection, - attrTransmissionModel.getDropletsDistanceOfSpread(), - Math.toRadians(attrTransmissionModel.getDropletsAngleOfSpreadInDeg())); + attrAirTransmissionModel.getDropletsDistanceOfSpread(), + Math.toRadians(attrAirTransmissionModel.getDropletsAngleOfSpreadInDeg())); Droplets droplets = new Droplets(new AttributesDroplets(1, shape, simTimeInSec, - attrTransmissionModel.getDropletsPathogenLoad())); + attrAirTransmissionModel.getDropletsPathogenLoad())); topography.addDroplets(droplets); } @@ -220,7 +220,7 @@ public class TransmissionModel extends AbstractExposureModel { //TODO define recursive; then, if possible, remove property initialPathogenLoad from AerosolCloud public void updateAerosolCloudsPathogenLoad(double simTimeInSec) { - double lambda = exponentialDecayFactor / attrTransmissionModel.getAerosolCloudHalfLife(); + double lambda = exponentialDecayFactor / attrAirTransmissionModel.getAerosolCloudHalfLife(); Collection allAerosolClouds = topography.getAerosolClouds(); for (AerosolCloud aerosolCloud : allAerosolClouds) { @@ -238,18 +238,18 @@ public class TransmissionModel extends AbstractExposureModel { * Increasing extent due to dispersion, multiplication with simTimeStepLength keeps deltaRadius independent * of simulation step width */ - if (attrTransmissionModel.getAerosolCloudAirDispersionFactor() > 0) { - deltaRadius = attrTransmissionModel.getAerosolCloudAirDispersionFactor() * simTimeStepLength; + if (attrAirTransmissionModel.getAerosolCloudAirDispersionFactor() > 0) { + deltaRadius = attrAirTransmissionModel.getAerosolCloudAirDispersionFactor() * simTimeStepLength; } /* * Increasing extent due to moving air caused by agents, multiplication with simTimeStepLength keeps * deltaRadius independent of simulation step width */ - if (attrTransmissionModel.getAerosolCloudPedestrianDispersionWeight() > 0) { + if (attrAirTransmissionModel.getAerosolCloudPedestrianDispersionWeight() > 0) { Collection pedestriansInsideCloud = getPedestriansInsideAerosolCloud(topography, aerosolCloud); for (Pedestrian pedestrian : pedestriansInsideCloud) { - deltaRadius += pedestrian.getVelocity().getLength() * attrTransmissionModel.getAerosolCloudPedestrianDispersionWeight() * simTimeStepLength; + deltaRadius += pedestrian.getVelocity().getLength() * attrAirTransmissionModel.getAerosolCloudPedestrianDispersionWeight() * simTimeStepLength; } } @@ -263,8 +263,8 @@ public class TransmissionModel extends AbstractExposureModel { */ public void deleteExpiredAerosolClouds() { - double initialCloudVolume = AerosolCloud.radiusToVolume(attrTransmissionModel.getAerosolCloudInitialRadius()); - double initialPathogenConcentration = attrTransmissionModel.getAerosolCloudInitialPathogenLoad() / initialCloudVolume; + double initialCloudVolume = AerosolCloud.radiusToVolume(attrAirTransmissionModel.getAerosolCloudInitialRadius()); + double initialPathogenConcentration = attrAirTransmissionModel.getAerosolCloudInitialPathogenLoad() / initialCloudVolume; double minimumConcentration = minimumPercentage * initialPathogenConcentration; Collection aerosolCloudsToBeDeleted = topography.getAerosolClouds() @@ -279,7 +279,7 @@ public class TransmissionModel extends AbstractExposureModel { public void deleteExpiredDroplets(double simTimeInSec) { Collection dropletsToBeDeleted = topography.getDroplets() .stream() - .filter(d -> attrTransmissionModel.getDropletsLifeTime() + d.getCreationTime() < simTimeInSec) + .filter(d -> attrAirTransmissionModel.getDropletsLifeTime() + d.getCreationTime() < simTimeInSec) .collect(Collectors.toSet()); for (Droplets droplets : dropletsToBeDeleted) { topography.getDroplets().remove(droplets); @@ -289,8 +289,8 @@ public class TransmissionModel extends AbstractExposureModel { private void updatePedsHealthStatus(double simTimeInSec) { Collection allPedestrians = topography.getPedestrianDynamicElements().getElements(); for (Pedestrian pedestrian : allPedestrians) { - pedestrian.getHealthStatus() - .updateRespiratoryCycle(simTimeInSec, attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + pedestrian.getHealthStatus() + .updateRespiratoryCycle(simTimeInSec, attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod()); } } @@ -298,13 +298,13 @@ public class TransmissionModel extends AbstractExposureModel { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(p -> p.getHealthStatus().isBreathingIn()) + .filter(p -> p.getHealthStatus().isBreathingIn()) .collect(Collectors.toSet()); // Agents absorb pathogen continuously but simulation is discrete. Therefore, the absorption during inhalation // must be divided into absorption for each sim step: - double inhalationPeriodLength = attrTransmissionModel.getPedestrianRespiratoryCyclePeriod() / 2.0; - double aerosolAbsorptionRatePerSimStep = attrTransmissionModel.getAerosolCloudAbsorptionRate() * (simTimeStepLength / inhalationPeriodLength); + double inhalationPeriodLength = attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod() / 2.0; + double aerosolAbsorptionRatePerSimStep = attrAirTransmissionModel.getAerosolCloudAbsorptionRate() * (simTimeStepLength / inhalationPeriodLength); Collection allAerosolClouds = topography.getAerosolClouds(); for (AerosolCloud aerosolCloud : allAerosolClouds) { @@ -324,15 +324,15 @@ public class TransmissionModel extends AbstractExposureModel { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(p -> p.getHealthStatus().isBreathingIn()) + .filter(p -> p.getHealthStatus().isBreathingIn()) .collect(Collectors.toSet()); /* * Agents absorb pathogen continuously but simulation is discrete. Therefore, the absorption during inhalation * must be divided into absorption for each sim step: */ - double inhalationPeriodLength = attrTransmissionModel.getPedestrianRespiratoryCyclePeriod() / 2.0; - double dropletsAbsorptionRatePerSimStep = attrTransmissionModel.getDropletsAbsorptionRate() * (simTimeStepLength / inhalationPeriodLength); + double inhalationPeriodLength = attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod() / 2.0; + double dropletsAbsorptionRatePerSimStep = attrAirTransmissionModel.getDropletsAbsorptionRate() * (simTimeStepLength / inhalationPeriodLength); /* * Intake of droplets: Inhaling agents simply absorb a fraction of the pathogen from droplets they are exposed @@ -347,7 +347,7 @@ public class TransmissionModel extends AbstractExposureModel { .collect(Collectors.toSet()); for (Pedestrian ped : breathingInPedsInDroplets) { - double deltaDegreeOfExposure = attrTransmissionModel.getDropletsPathogenLoad() * dropletsAbsorptionRatePerSimStep; + double deltaDegreeOfExposure = attrAirTransmissionModel.getDropletsPathogenLoad() * dropletsAbsorptionRatePerSimStep; updatePedestrianDegreeOfExposure(ped, deltaDegreeOfExposure); } } @@ -367,10 +367,10 @@ public class TransmissionModel extends AbstractExposureModel { AttributesExposureModelSourceParameters sourceParameters = defineSourceParameters(controller); Pedestrian ped = (Pedestrian) scenarioElement; - ped.setHealthStatus(new TransmissionModelHealthStatus()); + ped.setHealthStatus(new AirTransmissionModelHealthStatus()); ped.setInfectious(sourceParameters.isInfectious()); - ped.getHealthStatus().setRespiratoryTimeOffset(random.nextDouble() * attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); - ped.getHealthStatus().setBreathingIn(false); + ped.getHealthStatus().setRespiratoryTimeOffset(random.nextDouble() * attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + ped.getHealthStatus().setBreathingIn(false); //TODO check exhalation start position null? logger.infof(">>>>>>>>>>>sourceControllerEvent at time: %f agentId: %d", simTimeInSec, scenarioElement.getId()); @@ -383,13 +383,13 @@ public class TransmissionModel extends AbstractExposureModel { */ private Pedestrian topographyControllerEvent(TopographyController topographyController, double simtimeInSec, Agent agent) { Pedestrian pedestrian = (Pedestrian) agent; - TransmissionModelHealthStatus defaultHealthStatus = new TransmissionModelHealthStatus(); + AirTransmissionModelHealthStatus defaultHealthStatus = new AirTransmissionModelHealthStatus(); pedestrian.setHealthStatus(defaultHealthStatus); - pedestrian.getHealthStatus() - .setRespiratoryTimeOffset(random.nextDouble() * attrTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + pedestrian.getHealthStatus() + .setRespiratoryTimeOffset(random.nextDouble() * attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod()); - if (attrTransmissionModel.getInfectiousPedestrianIdsNoSource().contains(agent.getId())) { + if (attrAirTransmissionModel.getInfectiousPedestrianIdsNoSource().contains(agent.getId())) { pedestrian.setInfectious(true); } @@ -399,25 +399,25 @@ public class TransmissionModel extends AbstractExposureModel { private AttributesExposureModelSourceParameters defineSourceParameters(SourceController controller) { int sourceId = controller.getSourceId(); int defaultSourceId = -1; - Optional sourceParameters = attrTransmissionModel - .getTransmissionModelSourceParameters().stream().filter(s -> s.getSourceId() == sourceId).findFirst(); + Optional sourceParameters = attrAirTransmissionModel + .getExposureModelSourceParameters().stream().filter(s -> s.getSourceId() == sourceId).findFirst(); // if sourceId not set by user, check if the user has defined default attributes by setting sourceId = -1 if (sourceParameters.isEmpty()) { - sourceParameters = attrTransmissionModel.getTransmissionModelSourceParameters().stream().filter(s -> s.getSourceId() == defaultSourceId).findFirst(); + sourceParameters = attrAirTransmissionModel.getExposureModelSourceParameters().stream().filter(s -> s.getSourceId() == defaultSourceId).findFirst(); - // if no user defined default values: use attributesTransmissionModel default values + // if no user defined default values: use attributesAirTransmissionModel default values if (sourceParameters.isPresent()) { - logger.infof(">>>>>>>>>>>defineSourceParameters: sourceId %d not set explicitly transmissionModelSourceParameters. Source uses default transmissionModelSourceParameters defined for sourceId: %d", sourceId, defaultSourceId); + logger.infof(">>>>>>>>>>>defineSourceParameters: sourceId %d not set explicitly exposureModelSourceParameters. Source uses default exposureModelSourceParameters defined for sourceId: %d", sourceId, defaultSourceId); } else { - logger.errorf(">>>>>>>>>>>defineSourceParameters: sourceId %d is not set in transmissionModelSourceParameters", sourceId); + logger.errorf(">>>>>>>>>>>defineSourceParameters: sourceId %d is not set in exposureModelSourceParameters", sourceId); } } return sourceParameters.get(); } - public AttributesTransmissionModel getAttributesTransmissionModel() { - return attrTransmissionModel; + public AttributesAirTransmissionModel getAttributesAirTransmissionModel() { + return attrAirTransmissionModel; } public static Collection getDynamicElementsNearAerosolCloud(Topography topography, AerosolCloud aerosolCloud) { diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java similarity index 85% rename from VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java rename to VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java index 3222acf13..b6098162a 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/TransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import org.vadere.simulator.context.VadereContext; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; -import org.vadere.state.attributes.models.AttributesTransmissionModel; +import org.vadere.state.attributes.models.AttributesAirTransmissionModel; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesTarget; @@ -20,15 +20,15 @@ import org.vadere.util.geometry.shapes.*; import java.util.*; import static org.junit.Assert.*; -import static org.vadere.simulator.models.infection.TransmissionModel.*; +import static org.vadere.simulator.models.infection.AirTransmissionModel.*; import static org.vadere.state.scenario.AerosolCloud.createAerosolCloudShape; -public class TransmissionModelTest { +public class AirTransmissionModelTest { public static double ALLOWED_DOUBLE_TOLERANCE = 10e-3; static final double simTimeStepLength = 0.4; List attributeList; - TransmissionModel transmissionModel; + AirTransmissionModel airTransmissionModel; Topography topography; VadereContext ctx; @@ -42,12 +42,12 @@ public class TransmissionModelTest { @Before public void setUp() { attributeList = getAttributeList(); - transmissionModel = new TransmissionModel(); + airTransmissionModel = new AirTransmissionModel(); topography = new Topography(); topography.setContextId("testId"); ctx = new VadereContext(); - ctx.put(TransmissionModel.simStepLength, simTimeStepLength); + ctx.put(AirTransmissionModel.simStepLength, simTimeStepLength); VadereContext.add(topography.getContextId(), ctx); circle = createAerosolCloudShape(center, radius); @@ -62,16 +62,16 @@ public class TransmissionModelTest { @Test public void testInitializeOk() { // initialize must find the AttributesInfectionModel from the attributeList - transmissionModel.initialize(attributeList, new Domain(topography),null,null); + airTransmissionModel.initialize(attributeList, new Domain(topography),null,null); - AttributesTransmissionModel attributesTransmissionModel = transmissionModel.getAttributesTransmissionModel(); + AttributesAirTransmissionModel attributesAirTransmissionModel = airTransmissionModel.getAttributesAirTransmissionModel(); - Assert.assertEquals(attributeList.get(0), attributesTransmissionModel); + Assert.assertEquals(attributeList.get(0), attributesAirTransmissionModel); } public List getAttributeList() { ArrayList attrList = new ArrayList<>(); - var att = new AttributesTransmissionModel(); + var att = new AttributesAirTransmissionModel(); attrList.add(att); @@ -102,7 +102,7 @@ public class TransmissionModelTest { @Test public void testUpdateNumberOfGeneratedAerosolClouds() { - transmissionModel.initialize(attributeList, new Domain(topography),null,null); + airTransmissionModel.initialize(attributeList, new Domain(topography),null,null); createPedestrian(topography, new VPoint(10, 10), 1, -1, true); @@ -111,11 +111,11 @@ public class TransmissionModelTest { double simEndTime = 100; while(simTimeInSec <= simEndTime) { - transmissionModel.update(simTimeInSec); + airTransmissionModel.update(simTimeInSec); simTimeInSec += simTimeStepLength; } - int expectedNumberOfAerosolClouds = (int) Math.floor(simEndTime / transmissionModel.getAttributesTransmissionModel().getPedestrianRespiratoryCyclePeriod()); + int expectedNumberOfAerosolClouds = (int) Math.floor(simEndTime / airTransmissionModel.getAttributesAirTransmissionModel().getPedestrianRespiratoryCyclePeriod()); int actualNumberOfAerosolClouds = topography.getAerosolClouds().size(); assertEquals(actualNumberOfAerosolClouds, expectedNumberOfAerosolClouds); diff --git a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java similarity index 76% rename from VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java rename to VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java index ae6f7473e..958d7a0f5 100644 --- a/VadereState/src/org/vadere/state/attributes/models/AttributesTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java @@ -6,10 +6,10 @@ import org.vadere.state.attributes.Attributes; import java.util.ArrayList; import java.util.Arrays; -import org.vadere.state.attributes.models.infection.AttributesTransmissionModelAerosolCloud; -import org.vadere.state.attributes.models.infection.AttributesTransmissionModelDroplets; +import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModelAerosolCloud; +import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModelDroplets; import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; -import org.vadere.state.health.TransmissionModelHealthStatus; +import org.vadere.state.health.AirTransmissionModelHealthStatus; import org.vadere.state.scenario.AerosolCloud; import org.vadere.state.scenario.Droplets; import org.vadere.state.scenario.Pedestrian; @@ -18,16 +18,16 @@ import org.vadere.state.scenario.Pedestrian; * This class defines the attributes of the corresponding exposure model. All attributes are defined by the user and * relate to *
    - *
  • the TransmissionModel: {@link #transmissionModelSourceParameters}, {@link #pedestrianRespiratoryCyclePeriod}
  • - *
  • the {@link TransmissionModelHealthStatus} of the {@link Pedestrian}s
  • - *
  • the {@link AerosolCloud}s' initial attributes when they are created by the TransmissionModel
  • - *
  • the {@link Droplets}s' initial attributes when they are created by the TransmissionModel
  • + *
  • the AirTransmissionModel: {@link #exposureModelSourceParameters}, {@link #pedestrianRespiratoryCyclePeriod}
  • + *
  • the {@link AirTransmissionModelHealthStatus} of the {@link Pedestrian}s
  • + *
  • the {@link AerosolCloud}s' initial attributes when they are created by the AirTransmissionModel
  • + *
  • the {@link Droplets}s' initial attributes when they are created by the AirTransmissionModel
  • *
*/ @ModelAttributeClass -public class AttributesTransmissionModel extends Attributes { +public class AttributesAirTransmissionModel extends Attributes { - private ArrayList transmissionModelSourceParameters; + private ArrayList exposureModelSourceParameters; /** * Contains the Ids of pedestrians that are directly set into the topography (and not spawned by sources). @@ -37,7 +37,7 @@ public class AttributesTransmissionModel extends Attributes { /** * Attribute related to the pedestrians' health state that is shared among all pedestrians. It is not defined - * for each instance of TransmissionModelHealthStatus separately to keep the TransmissionModelHealthStatus lean. + * for each instance of AirTransmissionModelHealthStatus separately to keep the AirTransmissionModelHealthStatus lean. * pedestrianRespiratoryCyclePeriod equals 1/(pedestrians' average breathing rate) in seconds. */ private double pedestrianRespiratoryCyclePeriod; @@ -46,26 +46,26 @@ public class AttributesTransmissionModel extends Attributes { * Defines whether aerosol clouds are considered in the exposure model (true) or not (false). */ private boolean aerosolCloudsActive; - private AttributesTransmissionModelAerosolCloud aerosolCloudParameters; + private AttributesAirTransmissionModelAerosolCloud aerosolCloudParameters; /** * Defines whether droplets are considered in the exposure model (true) or not (false). */ private boolean dropletsActive; - private AttributesTransmissionModelDroplets dropletParameters; + private AttributesAirTransmissionModelDroplets dropletParameters; - public AttributesTransmissionModel() { - this.transmissionModelSourceParameters = new ArrayList<>(Arrays.asList(new AttributesExposureModelSourceParameters())); + public AttributesAirTransmissionModel() { + this.exposureModelSourceParameters = new ArrayList<>(Arrays.asList(new AttributesExposureModelSourceParameters())); this.infectiousPedestrianIdsNoSource = new ArrayList<>(); this.pedestrianRespiratoryCyclePeriod = 4; this.aerosolCloudsActive = false; - this.aerosolCloudParameters = new AttributesTransmissionModelAerosolCloud(); + this.aerosolCloudParameters = new AttributesAirTransmissionModelAerosolCloud(); this.dropletsActive = false; - this.dropletParameters = new AttributesTransmissionModelDroplets(); + this.dropletParameters = new AttributesAirTransmissionModelDroplets(); } // Getter @@ -74,8 +74,8 @@ public class AttributesTransmissionModel extends Attributes { return pedestrianRespiratoryCyclePeriod; } - public ArrayList getTransmissionModelSourceParameters() { - return transmissionModelSourceParameters; + public ArrayList getExposureModelSourceParameters() { + return exposureModelSourceParameters; } public ArrayList getInfectiousPedestrianIdsNoSource() { diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java similarity index 88% rename from VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelAerosolCloud.java rename to VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java index b33a5ffe1..3617ecc5b 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java @@ -1,15 +1,15 @@ package org.vadere.state.attributes.models.infection; import org.vadere.state.attributes.Attributes; -import org.vadere.state.attributes.models.AttributesTransmissionModel; +import org.vadere.state.attributes.models.AttributesAirTransmissionModel; /** * Attributes related to aerosol clouds that are shared among all aerosol clouds. These are not defined for each * instance of AerosolCloud separately to keep the AerosolCloud lean. * The frequency of occurrence is not defined here because aerosolClouds (if considered in the model) are directly - * linked to the respiratory cycle defined in {@link AttributesTransmissionModel}. + * linked to the respiratory cycle defined in {@link AttributesAirTransmissionModel}. */ -public class AttributesTransmissionModelAerosolCloud extends Attributes { +public class AttributesAirTransmissionModelAerosolCloud extends Attributes { /** * Describes exponential decay of pathogen load within an aerosol cloud; @@ -55,7 +55,7 @@ public class AttributesTransmissionModelAerosolCloud extends Attributes { */ private double absorptionRate; - public AttributesTransmissionModelAerosolCloud() { + public AttributesAirTransmissionModelAerosolCloud() { this.halfLife = 600; this.initialRadius = 1.5; this.initialPathogenLoad = 10000; @@ -64,7 +64,7 @@ public class AttributesTransmissionModelAerosolCloud extends Attributes { this.absorptionRate = 0.0005; } - public AttributesTransmissionModelAerosolCloud(double aerosolCloudHalfLife, double aerosolCloudInitialRadius, double initialPathogenLoad, double airDispersionFactor, double pedestrianDispersionWeight, double absorptionRate) { + public AttributesAirTransmissionModelAerosolCloud(double aerosolCloudHalfLife, double aerosolCloudInitialRadius, double initialPathogenLoad, double airDispersionFactor, double pedestrianDispersionWeight, double absorptionRate) { this.halfLife = aerosolCloudHalfLife; this.initialRadius = aerosolCloudInitialRadius; this.initialPathogenLoad = initialPathogenLoad; diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelDroplets.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java similarity index 94% rename from VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelDroplets.java rename to VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java index ee1edebd3..8f4d447de 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesTransmissionModelDroplets.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java @@ -6,7 +6,7 @@ import org.vadere.state.attributes.Attributes; * Attributes related to droplets that are shared among all droplets. These are not defined for each * instance of Droplets separately to keep Droplets lean. */ -public class AttributesTransmissionModelDroplets extends Attributes { +public class AttributesAirTransmissionModelDroplets extends Attributes { /** * Unit: 1/second @@ -40,7 +40,7 @@ public class AttributesTransmissionModelDroplets extends Attributes { */ private double absorptionRate; - public AttributesTransmissionModelDroplets() { + public AttributesAirTransmissionModelDroplets() { this.emissionFrequency = 1.0 / 60.0; this.distanceOfSpread = 1.5; this.angleOfSpreadInDeg = 30; diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java index c85eb8478..97270269f 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java @@ -1,6 +1,6 @@ package org.vadere.state.attributes.scenario; -import org.vadere.state.attributes.models.AttributesTransmissionModel; +import org.vadere.state.attributes.models.AttributesAirTransmissionModel; import org.vadere.state.scenario.AerosolCloud; import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VShape; @@ -16,7 +16,7 @@ public class AttributesAerosolCloud extends AttributesParticleDispersion { // Constructors public AttributesAerosolCloud() { super(); - this.radius = new AttributesTransmissionModel().getAerosolCloudInitialRadius(); + this.radius = new AttributesAirTransmissionModel().getAerosolCloudInitialRadius(); this.center = new VPoint(); } diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java index 561dd760e..d095e4adc 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java @@ -1,6 +1,5 @@ package org.vadere.state.attributes.scenario; -import org.vadere.state.attributes.models.infection.AttributesTransmissionModelDroplets; import org.vadere.state.scenario.Droplets; import org.vadere.util.geometry.shapes.VShape; diff --git a/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java b/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java similarity index 90% rename from VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java rename to VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java index 67c806f3e..d8cfa52a8 100644 --- a/VadereState/src/org/vadere/state/health/TransmissionModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java @@ -2,7 +2,7 @@ package org.vadere.state.health; import org.vadere.util.geometry.shapes.VPoint; -public class TransmissionModelHealthStatus extends ExposureModelHealthStatus { +public class AirTransmissionModelHealthStatus extends ExposureModelHealthStatus { private boolean breathingIn; @@ -23,18 +23,18 @@ public class TransmissionModelHealthStatus extends ExposureModelHealthStatus { private final static VPoint RESET_EXHALATION_POSITION = null; // Constructors - public TransmissionModelHealthStatus() { + public AirTransmissionModelHealthStatus() { this(false, 0, RESET_EXHALATION_POSITION); } - public TransmissionModelHealthStatus(boolean breathingIn, double respiratoryTimeOffset, VPoint exhalationStartPosition) { + public AirTransmissionModelHealthStatus(boolean breathingIn, double respiratoryTimeOffset, VPoint exhalationStartPosition) { super(); this.breathingIn = breathingIn; this.respiratoryTimeOffset = respiratoryTimeOffset; this.exhalationStartPosition = exhalationStartPosition; } - public TransmissionModelHealthStatus(TransmissionModelHealthStatus other) { + public AirTransmissionModelHealthStatus(AirTransmissionModelHealthStatus other) { super(other.isInfectious(), other.getDegreeOfExposure()); this.breathingIn = other.isBreathingIn(); this.respiratoryTimeOffset = other.getRespiratoryTimeOffset(); -- GitLab From a9c93e9b2e66e7924feb79827c6f069dd17b54a0 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 23 Feb 2022 16:13:10 +0100 Subject: [PATCH 29/83] Minor changes --- .../vadere/simulator/models/infection/AirTransmissionModel.java | 1 - 1 file changed, 1 deletion(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index b88d9943c..fc5955912 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -371,7 +371,6 @@ public class AirTransmissionModel extends AbstractExposureModel { ped.setInfectious(sourceParameters.isInfectious()); ped.getHealthStatus().setRespiratoryTimeOffset(random.nextDouble() * attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod()); ped.getHealthStatus().setBreathingIn(false); - //TODO check exhalation start position null? logger.infof(">>>>>>>>>>>sourceControllerEvent at time: %f agentId: %d", simTimeInSec, scenarioElement.getId()); return ped; -- GitLab From c90ea0c4039dd4c6a6ccd01d41f474e87843500b Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 23 Feb 2022 16:27:00 +0100 Subject: [PATCH 30/83] Adapt JSON files to renamed AirTransmissionModel, update AttributesAirTransmissionModel in JSON files --- .../scenarios/bottleneckA.scenario | 32 +- .../scenarios/bottleneckB.scenario | 32 +- .../bottleneckB_socialDistancing.scenario | 32 +- .../scenarios/closeContact.scenario | 32 +- .../scenarios/passageway.scenario | 32 +- .../queueScenario_publication.scenario | 32 +- ...hamner-2020-life_postvis_template.scenario | 32 +- ...e_postvis_template_seed_000_100fr.scenario | 32 +- .../hamner-2020-life_template.scenario | 32 +- .../scenarios/lu-2020-life.scenario | 32 +- .../miller-2020-life_seed_000.scenario | 32 +- .../miller-2020-life_template.scenario | 32 +- ...c_2_density_discrete_ca_5_sources.scenario | 370 ----------------- .../queueScenario_modelComparison.scenario | 377 ------------------ 14 files changed, 228 insertions(+), 903 deletions(-) delete mode 100644 Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario delete mode 100644 Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario index b50d26801..83312fb05 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario @@ -103,20 +103,26 @@ "sourceId" : 5, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 1.0E-4, - "pedestrianMinInfectiousDose" : 1000.0, - "exposedPeriod" : 432000.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 1.296E7, - "aerosolCloudHalfLife" : 120.0, - "aerosolCloudInitialRadius" : 1, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario index dce63baa5..76b766fbf 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario @@ -128,20 +128,26 @@ "sourceId" : 5, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 1000.0, - "exposedPeriod" : 432000.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 1.296E7, - "aerosolCloudHalfLife" : 120.0, - "aerosolCloudInitialRadius" : 1, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario index 12a3ee5bb..60ed1565c 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario @@ -128,20 +128,26 @@ "sourceId" : 5, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 1000.0, - "exposedPeriod" : 432000.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 1.296E7, - "aerosolCloudHalfLife" : 120.0, - "aerosolCloudInitialRadius" : 1, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario index 306de97ce..431590cba 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario @@ -133,20 +133,26 @@ "sourceId" : 16, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 3200.0, - "exposedPeriod" : 432000.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 1.296E7, - "aerosolCloudHalfLife" : 600.0, - "aerosolCloudInitialRadius" : 1.5, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario b/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario index dab03c7d2..fdcaaf436 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario @@ -103,20 +103,26 @@ "sourceId" : 2, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 1000.0, - "exposedPeriod" : 432000.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 1.296E7, - "aerosolCloudHalfLife" : 120.0, - "aerosolCloudInitialRadius" : 1, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario index 716f339c2..3d9be7fc9 100644 --- a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario +++ b/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario @@ -151,20 +151,26 @@ "sourceId" : 2, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 3200.0, - "exposedPeriod" : 432000.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 1.296E7, - "aerosolCloudHalfLife" : 600.0, - "aerosolCloudInitialRadius" : 1.5, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario index 368ff1612..0b50acccd 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario @@ -118,20 +118,26 @@ "sourceId" : 1, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 3200.0, - "exposedPeriod" : 172800.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 3.1536E7, - "aerosolCloudHalfLife" : 600.0, - "aerosolCloudInitialRadius" : 1.5, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario index 29683ee8b..14fdea5c5 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario @@ -118,20 +118,26 @@ "sourceId" : 1, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 3200.0, - "exposedPeriod" : 172800.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 3.1536E7, - "aerosolCloudHalfLife" : 600.0, - "aerosolCloudInitialRadius" : 1.5, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario index cf180a967..6b0e49da8 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario @@ -76,20 +76,26 @@ "sourceId" : 1, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 3200.0, - "exposedPeriod" : 172800.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 3.1536E7, - "aerosolCloudHalfLife" : 600.0, - "aerosolCloudInitialRadius" : 1.5, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario index 9b7673f5b..0ac2504a5 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario @@ -103,20 +103,26 @@ "sourceId" : 11, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 3200.0, - "exposedPeriod" : 432000.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 1.296E7, - "aerosolCloudHalfLife" : 600.0, - "aerosolCloudInitialRadius" : 1.5, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario index a7bc460b1..72e21348b 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario @@ -83,20 +83,26 @@ "sourceId" : 1, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 3200.0, - "exposedPeriod" : 172800.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 3.1536E7, - "aerosolCloudHalfLife" : 600.0, - "aerosolCloudInitialRadius" : 1.5, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario index 96520ad8d..0c3a4245c 100644 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario +++ b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario @@ -83,20 +83,26 @@ "sourceId" : 1, "infectious" : true } ], + "infectiousPedestrianIdsNoSource" : [ ], "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 3200.0, - "exposedPeriod" : 172800.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 3.1536E7, - "aerosolCloudHalfLife" : 600.0, - "aerosolCloudInitialRadius" : 1.5, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 + "aerosolCloudsActive" : true, + "aerosolCloudParameters" : { + "halfLife" : 600.0, + "initialRadius" : 1.5, + "initialPathogenLoad" : 10000.0, + "airDispersionFactor" : 0.0, + "pedestrianDispersionWeight" : 0.0125, + "absorptionRate" : 5.0E-4 + }, + "dropletsActive" : false, + "dropletParameters" : { + "emissionFrequency" : 0.016666666666666666, + "distanceOfSpread" : 1.5, + "angleOfSpreadInDeg" : 30.0, + "lifeTime" : 1.5, + "pathogenLoad" : 10000.0, + "absorptionRate" : 0.1 + } } }, "attributesSimulation" : { diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario deleted file mode 100644 index 0a90589a1..000000000 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/basic_2_density_discrete_ca_5_sources.scenario +++ /dev/null @@ -1,370 +0,0 @@ -{ - "name" : "basic_2_density_discrete_ca_5_sources", - "description" : "", - "release" : "2.0", - "processWriters" : { - "files" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile", - "filename" : "density.txt", - "processors" : [ 1 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOverlapOutputFile", - "filename" : "out.txt", - "processors" : [ 3 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", - "filename" : "postvis.traj", - "processors" : [ 6, 7 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile", - "filename" : "seir.txt", - "processors" : [ 8 ] - } ], - "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianDensityCountingProcessor", - "id" : 1, - "attributesType" : "org.vadere.state.attributes.processor.AttributesPedestrianDensityCountingProcessor", - "attributes" : { - "pedestrianPositionProcessorId" : 2, - "radius" : 1.5 - } - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPositionProcessor", - "id" : 2, - "attributesType" : "org.vadere.state.attributes.processor.AttributesPedestrianPositionProcessor", - "attributes" : { - "interpolate" : true - } - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianOverlapProcessor", - "id" : 3 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOverlapsProcessor", - "id" : 4, - "attributesType" : "org.vadere.state.attributes.processor.AttributesNumberOverlapsProcessor", - "attributes" : { - "pedestrianOverlapProcessorId" : 3 - } - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor", - "id" : 6 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepTargetIDProcessor", - "id" : 7 - } ], - "isTimestamped" : true, - "isWriteMetaData" : false - }, - "scenario" : { - "mainModel" : "org.vadere.simulator.models.osm.OptimalStepsModel", - "attributesModel" : { - "org.vadere.state.attributes.models.AttributesFloorField" : { - "createMethod" : "HIGH_ACCURACY_FAST_MARCHING", - "potentialFieldResolution" : 0.1, - "obstacleGridPenalty" : 0.1, - "targetAttractionStrength" : 1.0, - "cacheType" : "NO_CACHE", - "cacheDir" : "", - "timeCostAttributes" : { - "standardDeviation" : 0.7, - "type" : "UNIT", - "obstacleDensityWeight" : 3.5, - "pedestrianSameTargetDensityWeight" : 3.5, - "pedestrianOtherTargetDensityWeight" : 3.5, - "pedestrianWeight" : 3.5, - "queueWidthLoading" : 1.0, - "pedestrianDynamicWeight" : 6.0, - "loadingType" : "CONSTANT", - "width" : 0.2, - "height" : 1.0 - } - }, - "org.vadere.state.attributes.models.AttributesOSM" : { - "stepCircleResolution" : 18, - "numberOfCircles" : 1, - "optimizationType" : "DISCRETE", - "varyStepDirection" : false, - "movementType" : "ARBITRARY", - "stepLengthIntercept" : 0.4625, - "stepLengthSlopeSpeed" : 0.2345, - "stepLengthSD" : 0.036, - "movementThreshold" : 0.0, - "minStepLength" : 0.4625, - "minimumStepLength" : false, - "maxStepDuration" : 1.7976931348623157E308, - "dynamicStepLength" : false, - "updateType" : "EVENT_DRIVEN", - "seeSmallWalls" : false, - "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", - "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", - "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] - }, - "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { - "pedPotentialIntimateSpaceWidth" : 0.45, - "pedPotentialPersonalSpaceWidth" : 1.2, - "pedPotentialHeight" : 50.0, - "obstPotentialWidth" : 0.8, - "obstPotentialHeight" : 6.0, - "intimateSpaceFactor" : 1.2, - "personalSpacePower" : 1, - "intimateSpacePower" : 1 - }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { - "exposureModelSourceParameters" : [ { - "sourceId" : -1, - "infectionStatus" : "SUSCEPTIBLE" - }, { - "sourceId" : 7, - "infectionStatus" : "INFECTIOUS" - } ], - "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 1.0, - "pedestrianPathogenAbsorptionRate" : 0.4, - "pedestrianMinInfectiousDose" : 1.0, - "exposedPeriod" : 2.0, - "infectiousPeriod" : 20.0, - "recoveredPeriod" : 20.0, - "aerosolCloudHalfLife" : 120.0, - "aerosolCloudInitialRadius" : 1, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 - } - }, - "attributesSimulation" : { - "finishTime" : 200.0, - "simTimeStepLength" : 0.4, - "realTimeSimTimeRatio" : 0.0, - "writeSimulationData" : true, - "visualizationEnabled" : true, - "printFPS" : false, - "digitsPerCoordinate" : 2, - "useFixedSeed" : true, - "fixedSeed" : 1, - "simulationSeed" : 1 - }, - "attributesPsychology" : { - "usePsychologyLayer" : false, - "psychologyLayer" : { - "perception" : "SimplePerceptionModel", - "cognition" : "CooperativeCognitionModel" - } - }, - "topography" : { - "attributes" : { - "bounds" : { - "x" : 0.0, - "y" : 0.0, - "width" : 38.0, - "height" : 12.0 - }, - "boundingBoxWidth" : 0.5, - "bounded" : true, - "referenceCoordinateSystem" : null - }, - "obstacles" : [ { - "shape" : { - "type" : "POLYGON", - "points" : [ { - "x" : 9.0, - "y" : 12.0 - }, { - "x" : 9.0, - "y" : 10.0 - }, { - "x" : 30.0, - "y" : 7.0 - }, { - "x" : 30.0, - "y" : 12.0 - } ] - }, - "id" : 3 - }, { - "shape" : { - "type" : "POLYGON", - "points" : [ { - "x" : 9.0, - "y" : 0.0 - }, { - "x" : 9.0, - "y" : 2.0 - }, { - "x" : 30.0, - "y" : 5.0 - }, { - "x" : 30.0, - "y" : 0.0 - } ] - }, - "id" : 4 - } ], - "measurementAreas" : [ ], - "stairs" : [ ], - "targets" : [ { - "id" : 1, - "absorbing" : true, - "shape" : { - "x" : 35.0, - "y" : 5.0, - "width" : 2.0, - "height" : 2.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 0.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - } ], - "targetChangers" : [ ], - "absorbingAreas" : [ ], - "aerosolClouds" : [ ], - "droplets" : [ ], - "sources" : [ { - "id" : 5, - "shape" : { - "x" : 1.0, - "y" : 1.1, - "width" : 5.0, - "height" : 1.8, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 50, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : true, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 6, - "shape" : { - "x" : 1.0, - "y" : 3.1, - "width" : 5.0, - "height" : 1.8, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 50, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : true, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 7, - "shape" : { - "x" : 1.0, - "y" : 5.1, - "width" : 5.0, - "height" : 1.8, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : true, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 8, - "shape" : { - "x" : 1.0, - "y" : 7.1, - "width" : 5.0, - "height" : 1.8, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 50, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : true, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 9, - "shape" : { - "x" : 1.0, - "y" : 9.1, - "width" : 5.0, - "height" : 1.8, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 50, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : true, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - } ], - "dynamicElements" : [ ], - "attributesPedestrian" : { - "radius" : 0.195, - "densityDependentSpeed" : false, - "speedDistributionMean" : 1.34, - "speedDistributionStandardDeviation" : 0.26, - "minimumSpeed" : 0.5, - "maximumSpeed" : 2.2, - "acceleration" : 2.0, - "footstepHistorySize" : 4, - "searchRadius" : 1.0, - "walkingDirectionCalculation" : "BY_TARGET_CENTER", - "walkingDirectionSameIfAngleLessOrEqual" : 45.0 - }, - "teleporter" : null, - "attributesCar" : null - }, - "stimulusInfos" : [ ], - "reactionProbabilities" : [ ] - } -} diff --git a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario b/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario deleted file mode 100644 index bb404c2d3..000000000 --- a/Scenarios/ModelTests/TestTransmissionModel/scenarios/queueScenario_modelComparison.scenario +++ /dev/null @@ -1,377 +0,0 @@ -{ - "name" : "queueScenario_modelComparison", - "description" : "This scenario is used for comparing the simulation output between the implementations of the infection model in crowd:it and vadere.", - "release" : "2.0", - "processWriters" : { - "files" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", - "filename" : "postvis.traj", - "processors" : [ 1, 2 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOverlapOutputFile", - "filename" : "overlaps.csv", - "processors" : [ 3 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile", - "filename" : "overlapCount.txt", - "processors" : [ 4 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile", - "filename" : "pathogenLoad.txt", - "processors" : [ 5 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile", - "filename" : "numberOfAerosolClouds.txt", - "processors" : [ 6 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimeGridOutputFile", - "filename" : "pathogenConcentration.txt", - "processors" : [ 7 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile", - "filename" : "infectionStatusPerPedestrian.txt", - "processors" : [ 8 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.IdOutputFile", - "filename" : "aerosolCloudLifeTime.txt", - "processors" : [ 9 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile", - "filename" : "pedestrianHealthStatust.txt", - "processors" : [ 10 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", - "filename" : "aerosolCloudArea.txt", - "processors" : [ 11 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", - "filename" : "aerosolCloudData.txt", - "processors" : [ 12 ] - } ], - "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor", - "id" : 1 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepTargetIDProcessor", - "id" : 2 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianOverlapProcessor", - "id" : 3 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOverlapsProcessor", - "id" : 4, - "attributesType" : "org.vadere.state.attributes.processor.AttributesNumberOverlapsProcessor", - "attributes" : { - "pedestrianOverlapProcessorId" : 3 - } - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianDegreeOfExposureProcessor", - "id" : 5 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudCountingProcessor", - "id" : 6 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PathogenConcentrationProcessor", - "id" : 7, - "attributesType" : "org.vadere.state.attributes.processor.AttributesPathogenConcentrationProcessor", - "attributes" : { - "gridResolution" : 0.5, - "timeResolution" : 4.0 - } - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudLifeTimeProcessor", - "id" : 9 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudAreaProcessor", - "id" : 11 - } ], - "isTimestamped" : true, - "isWriteMetaData" : false - }, - "scenario" : { - "mainModel" : "org.vadere.simulator.models.osm.OptimalStepsModel", - "attributesModel" : { - "org.vadere.state.attributes.models.AttributesOSM" : { - "stepCircleResolution" : 4, - "numberOfCircles" : 1, - "optimizationType" : "NELDER_MEAD", - "varyStepDirection" : true, - "movementType" : "ARBITRARY", - "stepLengthIntercept" : 0.4625, - "stepLengthSlopeSpeed" : 0.2345, - "stepLengthSD" : 0.036, - "movementThreshold" : 0.0, - "minStepLength" : 0.1, - "minimumStepLength" : true, - "maxStepDuration" : 1.7976931348623157E308, - "dynamicStepLength" : true, - "updateType" : "EVENT_DRIVEN", - "seeSmallWalls" : true, - "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", - "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", - "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] - }, - "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { - "pedPotentialIntimateSpaceWidth" : 0.45, - "pedPotentialPersonalSpaceWidth" : 1.2, - "pedPotentialHeight" : 50.0, - "obstPotentialWidth" : 0.8, - "obstPotentialHeight" : 6.0, - "intimateSpaceFactor" : 1.2, - "personalSpacePower" : 1, - "intimateSpacePower" : 1 - }, - "org.vadere.state.attributes.models.AttributesFloorField" : { - "createMethod" : "HIGH_ACCURACY_FAST_MARCHING", - "potentialFieldResolution" : 0.1, - "obstacleGridPenalty" : 0.1, - "targetAttractionStrength" : 0.4, - "cacheType" : "NO_CACHE", - "cacheDir" : "", - "timeCostAttributes" : { - "standardDeviation" : 0.7, - "type" : "UNIT", - "obstacleDensityWeight" : 3.5, - "pedestrianSameTargetDensityWeight" : 3.5, - "pedestrianOtherTargetDensityWeight" : 3.5, - "pedestrianWeight" : 3.5, - "queueWidthLoading" : 1.0, - "pedestrianDynamicWeight" : 6.0, - "loadingType" : "CONSTANT", - "width" : 0.2, - "height" : 1.0 - } - }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { - "exposureModelSourceParameters" : [ { - "sourceId" : 2, - "infectionStatus" : "SUSCEPTIBLE" - }, { - "sourceId" : 1, - "infectionStatus" : "INFECTIOUS" - } ], - "pedestrianRespiratoryCyclePeriod" : 4.0, - "pedestrianPathogenEmissionCapacity" : 4.0, - "pedestrianPathogenAbsorptionRate" : 5.0E-4, - "pedestrianMinInfectiousDose" : 1000.0, - "exposedPeriod" : 432000.0, - "infectiousPeriod" : 1209600.0, - "recoveredPeriod" : 1.296E7, - "aerosolCloudHalfLife" : 120.0, - "aerosolCloudInitialRadius" : 1, - "dropletsExhalationFrequency" : 0.0, - "dropletsDistanceOfSpread" : 1.5, - "dropletsAngleOfSpreadInDeg" : 30.0, - "dropletsLifeTime" : 1.001, - "dropletsPathogenLoadFactor" : 200.0 - } - }, - "attributesSimulation" : { - "finishTime" : 1200.0, - "simTimeStepLength" : 0.5, - "realTimeSimTimeRatio" : 0.1, - "writeSimulationData" : true, - "visualizationEnabled" : true, - "printFPS" : false, - "digitsPerCoordinate" : 2, - "useFixedSeed" : true, - "fixedSeed" : 1436250873317888407, - "simulationSeed" : 1436250873317888407 - }, - "attributesPsychology" : { - "usePsychologyLayer" : false, - "psychologyLayer" : { - "perception" : "SimplePerceptionModel", - "cognition" : "SimpleCognitionModel" - } - }, - "topography" : { - "attributes" : { - "bounds" : { - "x" : 0.0, - "y" : 0.0, - "width" : 5.8, - "height" : 11.0 - }, - "boundingBoxWidth" : 0.5, - "bounded" : true, - "referenceCoordinateSystem" : null - }, - "obstacles" : [ { - "shape" : { - "x" : 0.5, - "y" : 10.0, - "width" : 4.8, - "height" : 0.5, - "type" : "RECTANGLE" - }, - "id" : 2 - }, { - "shape" : { - "x" : 4.8, - "y" : 1.0, - "width" : 0.5, - "height" : 9.0, - "type" : "RECTANGLE" - }, - "id" : 3 - }, { - "shape" : { - "x" : 0.5, - "y" : 0.5, - "width" : 4.8, - "height" : 0.5, - "type" : "RECTANGLE" - }, - "id" : 4 - }, { - "shape" : { - "x" : 1.8, - "y" : 1.8, - "width" : 0.2, - "height" : 8.2, - "type" : "RECTANGLE" - }, - "id" : 5 - }, { - "shape" : { - "x" : 3.8, - "y" : 1.8, - "width" : 0.2, - "height" : 8.2, - "type" : "RECTANGLE" - }, - "id" : 8 - }, { - "shape" : { - "x" : 2.8, - "y" : 1.0, - "width" : 0.2, - "height" : 8.2, - "type" : "RECTANGLE" - }, - "id" : 15 - }, { - "shape" : { - "x" : 0.5, - "y" : 1.0, - "width" : 0.5, - "height" : 9.0, - "type" : "RECTANGLE" - }, - "id" : 7 - } ], - "measurementAreas" : [ ], - "stairs" : [ ], - "targets" : [ { - "id" : 3, - "absorbing" : true, - "shape" : { - "x" : 4.15, - "y" : 8.9, - "width" : 0.5, - "height" : 1.05, - "type" : "RECTANGLE" - }, - "waitingTime" : 90.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - } ], - "targetChangers" : [ ], - "absorbingAreas" : [ ], - "aerosolClouds" : [ ], - "droplets" : [ ], - "sources" : [ { - "id" : 1, - "shape" : { - "x" : 1.2, - "y" : 9.45, - "width" : 0.5, - "height" : 0.5, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : 1, - "startTime" : 7.0, - "endTime" : 20.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 3 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 2, - "shape" : { - "x" : 1.2, - "y" : 8.9, - "width" : 0.5, - "height" : 0.5, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 2.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : 10, - "startTime" : 0.0, - "endTime" : 50.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 3 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - } ], - "dynamicElements" : [ ], - "attributesPedestrian" : { - "radius" : 0.2, - "densityDependentSpeed" : false, - "speedDistributionMean" : 1.34, - "speedDistributionStandardDeviation" : 0.26, - "minimumSpeed" : 0.5, - "maximumSpeed" : 2.2, - "acceleration" : 2.0, - "footstepHistorySize" : 4, - "searchRadius" : 1.0, - "walkingDirectionCalculation" : "BY_TARGET_CENTER", - "walkingDirectionSameIfAngleLessOrEqual" : 45.0 - }, - "teleporter" : null, - "attributesCar" : { - "id" : -1, - "radius" : 0.2, - "densityDependentSpeed" : false, - "speedDistributionMean" : 1.0, - "speedDistributionStandardDeviation" : 0.0, - "minimumSpeed" : 0.5, - "maximumSpeed" : 2.2, - "acceleration" : 2.0, - "footstepHistorySize" : 4, - "searchRadius" : 1.0, - "walkingDirectionCalculation" : "BY_TARGET_CENTER", - "walkingDirectionSameIfAngleLessOrEqual" : 45.0, - "length" : 4.5, - "width" : 1.7, - "direction" : { - "x" : 1.0, - "y" : 0.0 - } - } - }, - "stimulusInfos" : [ ], - "reactionProbabilities" : [ ] - } -} -- GitLab From b304a1afb46c47f800f79600ab8f48f60ca33ac9 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 23 Feb 2022 16:29:49 +0100 Subject: [PATCH 31/83] Rearrange folder structure; create new sub folder for example scenarios --- .../{ => examples}/scenarios/bottleneckA.scenario | 0 .../{ => examples}/scenarios/bottleneckB.scenario | 0 .../scenarios/bottleneckB_socialDistancing.scenario | 0 .../{ => examples}/scenarios/closeContact.scenario | 0 .../{ => examples}/scenarios/passageway.scenario | 0 .../{ => examples}/scenarios/queueScenario_publication.scenario | 0 Scenarios/Demos/TransmissionModel/{ => examples}/vadere.project | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename Scenarios/Demos/TransmissionModel/{ => examples}/scenarios/bottleneckA.scenario (100%) rename Scenarios/Demos/TransmissionModel/{ => examples}/scenarios/bottleneckB.scenario (100%) rename Scenarios/Demos/TransmissionModel/{ => examples}/scenarios/bottleneckB_socialDistancing.scenario (100%) rename Scenarios/Demos/TransmissionModel/{ => examples}/scenarios/closeContact.scenario (100%) rename Scenarios/Demos/TransmissionModel/{ => examples}/scenarios/passageway.scenario (100%) rename Scenarios/Demos/TransmissionModel/{ => examples}/scenarios/queueScenario_publication.scenario (100%) rename Scenarios/Demos/TransmissionModel/{ => examples}/vadere.project (100%) diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario b/Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckA.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/scenarios/bottleneckA.scenario rename to Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckA.scenario diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario b/Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckB.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/scenarios/bottleneckB.scenario rename to Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckB.scenario diff --git a/Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario b/Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/scenarios/bottleneckB_socialDistancing.scenario rename to Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario diff --git a/Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario b/Scenarios/Demos/TransmissionModel/examples/scenarios/closeContact.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/scenarios/closeContact.scenario rename to Scenarios/Demos/TransmissionModel/examples/scenarios/closeContact.scenario diff --git a/Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario b/Scenarios/Demos/TransmissionModel/examples/scenarios/passageway.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/scenarios/passageway.scenario rename to Scenarios/Demos/TransmissionModel/examples/scenarios/passageway.scenario diff --git a/Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/TransmissionModel/examples/scenarios/queueScenario_publication.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/scenarios/queueScenario_publication.scenario rename to Scenarios/Demos/TransmissionModel/examples/scenarios/queueScenario_publication.scenario diff --git a/Scenarios/Demos/TransmissionModel/vadere.project b/Scenarios/Demos/TransmissionModel/examples/vadere.project similarity index 100% rename from Scenarios/Demos/TransmissionModel/vadere.project rename to Scenarios/Demos/TransmissionModel/examples/vadere.project -- GitLab From 61ac7c2638660171065d36728d6f0bd15d76775f Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 23 Feb 2022 16:32:29 +0100 Subject: [PATCH 32/83] Rename directory name TransmissionModel to AirTransmissionModel --- .../.gitignore | 0 .../examples/scenarios/bottleneckA.scenario | 0 .../examples/scenarios/bottleneckB.scenario | 0 .../bottleneckB_socialDistancing.scenario | 0 .../examples/scenarios/closeContact.scenario | 0 .../examples/scenarios/passageway.scenario | 0 .../queueScenario_publication.scenario | 0 .../examples/vadere.project | 0 ...hamner-2020-life_postvis_template.scenario | 0 .../hamner-2020-life_template.scenario | 0 .../scenarios/lu-2020-life.scenario | 0 .../scenarios/miller-2020-life_targetList.csv | 0 .../miller-2020-life_template.scenario | 0 .../validation/vadere.project | 0 ...e_postvis_template_seed_000_100fr.scenario | 4519 ---------------- .../miller-2020-life_seed_000.scenario | 4561 ----------------- 16 files changed, 9080 deletions(-) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/.gitignore (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/examples/scenarios/bottleneckA.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/examples/scenarios/bottleneckB.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/examples/scenarios/bottleneckB_socialDistancing.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/examples/scenarios/closeContact.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/examples/scenarios/passageway.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/examples/scenarios/queueScenario_publication.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/examples/vadere.project (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/validation/scenarios/hamner-2020-life_postvis_template.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/validation/scenarios/hamner-2020-life_template.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/validation/scenarios/lu-2020-life.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/validation/scenarios/miller-2020-life_targetList.csv (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/validation/scenarios/miller-2020-life_template.scenario (100%) rename Scenarios/Demos/{TransmissionModel => AirTransmissionModel}/validation/vadere.project (100%) delete mode 100644 Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario delete mode 100644 Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario diff --git a/Scenarios/Demos/TransmissionModel/.gitignore b/Scenarios/Demos/AirTransmissionModel/.gitignore similarity index 100% rename from Scenarios/Demos/TransmissionModel/.gitignore rename to Scenarios/Demos/AirTransmissionModel/.gitignore diff --git a/Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckA.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckA.scenario rename to Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario diff --git a/Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckB.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckB.scenario rename to Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario diff --git a/Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario rename to Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario diff --git a/Scenarios/Demos/TransmissionModel/examples/scenarios/closeContact.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/examples/scenarios/closeContact.scenario rename to Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario diff --git a/Scenarios/Demos/TransmissionModel/examples/scenarios/passageway.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/examples/scenarios/passageway.scenario rename to Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario diff --git a/Scenarios/Demos/TransmissionModel/examples/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queueScenario_publication.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/examples/scenarios/queueScenario_publication.scenario rename to Scenarios/Demos/AirTransmissionModel/examples/scenarios/queueScenario_publication.scenario diff --git a/Scenarios/Demos/TransmissionModel/examples/vadere.project b/Scenarios/Demos/AirTransmissionModel/examples/vadere.project similarity index 100% rename from Scenarios/Demos/TransmissionModel/examples/vadere.project rename to Scenarios/Demos/AirTransmissionModel/examples/vadere.project diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario rename to Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_template.scenario rename to Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/lu-2020-life.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/validation/scenarios/lu-2020-life.scenario rename to Scenarios/Demos/AirTransmissionModel/validation/scenarios/lu-2020-life.scenario diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_targetList.csv b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_targetList.csv similarity index 100% rename from Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_targetList.csv rename to Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_targetList.csv diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario similarity index 100% rename from Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_template.scenario rename to Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario diff --git a/Scenarios/Demos/TransmissionModel/validation/vadere.project b/Scenarios/Demos/AirTransmissionModel/validation/vadere.project similarity index 100% rename from Scenarios/Demos/TransmissionModel/validation/vadere.project rename to Scenarios/Demos/AirTransmissionModel/validation/vadere.project diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario deleted file mode 100644 index 14fdea5c5..000000000 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/hamner-2020-life_postvis_template_seed_000_100fr.scenario +++ /dev/null @@ -1,4519 +0,0 @@ -{ - "name" : "hamner-2020-life_postvis_template_seed_000_100fr", - "description" : "", - "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", - "processWriters" : { - "files" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile", - "filename" : "infectionStatus.txt", - "processors" : [ 1 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", - "filename" : "postvis.traj", - "processors" : [ 2, 3, 6 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOverlapOutputFile", - "filename" : "overlaps.csv", - "processors" : [ 4 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile", - "filename" : "overlapCount.txt", - "processors" : [ 5 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", - "filename" : "aerosolCloudShapes.txt", - "processors" : [ 7 ] - } ], - "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor", - "id" : 2 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepTargetIDProcessor", - "id" : 3 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianOverlapProcessor", - "id" : 4 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOverlapsProcessor", - "id" : 5, - "attributesType" : "org.vadere.state.attributes.processor.AttributesNumberOverlapsProcessor", - "attributes" : { - "pedestrianOverlapProcessorId" : 4 - } - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepHealthStatusProcessor", - "id" : 6 - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudShapeProcessor", - "id" : 7, - "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", - "attributes" : { - "sampleEveryNthSimStep" : 100 - } - } ], - "isTimestamped" : false, - "isWriteMetaData" : false - }, - "scenario" : { - "mainModel" : "org.vadere.simulator.models.osm.OptimalStepsModel", - "attributesModel" : { - "org.vadere.state.attributes.models.AttributesOSM" : { - "stepCircleResolution" : 4, - "numberOfCircles" : 1, - "optimizationType" : "NELDER_MEAD", - "varyStepDirection" : true, - "movementType" : "ARBITRARY", - "stepLengthIntercept" : 0.4625, - "stepLengthSlopeSpeed" : 0.2345, - "stepLengthSD" : 0.036, - "movementThreshold" : 0.0, - "minStepLength" : 0.1, - "minimumStepLength" : true, - "maxStepDuration" : 1.7976931348623157E308, - "dynamicStepLength" : true, - "updateType" : "EVENT_DRIVEN", - "seeSmallWalls" : false, - "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", - "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", - "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] - }, - "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { - "pedPotentialIntimateSpaceWidth" : 0.45, - "pedPotentialPersonalSpaceWidth" : 1.2, - "pedPotentialHeight" : 5.0, - "obstPotentialWidth" : 0.8, - "obstPotentialHeight" : 6.0, - "intimateSpaceFactor" : 1.2, - "personalSpacePower" : 1, - "intimateSpacePower" : 1 - }, - "org.vadere.state.attributes.models.AttributesFloorField" : { - "createMethod" : "HIGH_ACCURACY_FAST_MARCHING", - "potentialFieldResolution" : 0.1, - "obstacleGridPenalty" : 0.1, - "targetAttractionStrength" : 1.0, - "cacheType" : "NO_CACHE", - "cacheDir" : "", - "timeCostAttributes" : { - "standardDeviation" : 0.7, - "type" : "UNIT", - "obstacleDensityWeight" : 3.5, - "pedestrianSameTargetDensityWeight" : 3.5, - "pedestrianOtherTargetDensityWeight" : 3.5, - "pedestrianWeight" : 3.5, - "queueWidthLoading" : 1.0, - "pedestrianDynamicWeight" : 6.0, - "loadingType" : "CONSTANT", - "width" : 0.2, - "height" : 1.0 - } - }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { - "exposureModelSourceParameters" : [ { - "sourceId" : -1, - "infectious" : false - }, { - "sourceId" : 1, - "infectious" : true - } ], - "infectiousPedestrianIdsNoSource" : [ ], - "pedestrianRespiratoryCyclePeriod" : 4.0, - "aerosolCloudsActive" : true, - "aerosolCloudParameters" : { - "halfLife" : 600.0, - "initialRadius" : 1.5, - "initialPathogenLoad" : 10000.0, - "airDispersionFactor" : 0.0, - "pedestrianDispersionWeight" : 0.0125, - "absorptionRate" : 5.0E-4 - }, - "dropletsActive" : false, - "dropletParameters" : { - "emissionFrequency" : 0.016666666666666666, - "distanceOfSpread" : 1.5, - "angleOfSpreadInDeg" : 30.0, - "lifeTime" : 1.5, - "pathogenLoad" : 10000.0, - "absorptionRate" : 0.1 - } - } - }, - "attributesSimulation" : { - "finishTime" : 9300.0, - "simTimeStepLength" : 0.4, - "realTimeSimTimeRatio" : 0.0, - "writeSimulationData" : true, - "visualizationEnabled" : true, - "printFPS" : false, - "digitsPerCoordinate" : 2, - "useFixedSeed" : true, - "fixedSeed" : -2054058476485033808, - "simulationSeed" : 0 - }, - "attributesPsychology" : { - "usePsychologyLayer" : false, - "psychologyLayer" : { - "perception" : "SimplePerceptionModel", - "cognition" : "SimpleCognitionModel" - } - }, - "topography" : { - "attributes" : { - "bounds" : { - "x" : 0.0, - "y" : 0.0, - "width" : 39.05, - "height" : 19.4 - }, - "boundingBoxWidth" : 0.5, - "bounded" : true, - "referenceCoordinateSystem" : null - }, - "obstacles" : [ { - "shape" : { - "x" : 6.15, - "y" : 0.5, - "width" : 32.400000000000006, - "height" : 0.5, - "type" : "RECTANGLE" - }, - "id" : 2001 - }, { - "shape" : { - "x" : 6.15, - "y" : 3.0, - "width" : 0.5, - "height" : 15.899999999999999, - "type" : "RECTANGLE" - }, - "id" : 2002 - }, { - "shape" : { - "x" : 6.65, - "y" : 18.4, - "width" : 31.400000000000002, - "height" : 0.5, - "type" : "RECTANGLE" - }, - "id" : 2003 - }, { - "shape" : { - "x" : 25.75, - "y" : 3.0, - "width" : 0.5, - "height" : 15.399999999999999, - "type" : "RECTANGLE" - }, - "id" : 2004 - }, { - "shape" : { - "x" : 38.05, - "y" : 1.0, - "width" : 0.5, - "height" : 17.9, - "type" : "RECTANGLE" - }, - "id" : 2005 - } ], - "measurementAreas" : [ ], - "stairs" : [ ], - "targets" : [ { - "id" : 1001, - "absorbing" : false, - "shape" : { - "x" : 9.65, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1002, - "absorbing" : false, - "shape" : { - "x" : 10.25, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1003, - "absorbing" : false, - "shape" : { - "x" : 10.85, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1004, - "absorbing" : false, - "shape" : { - "x" : 11.45, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1005, - "absorbing" : false, - "shape" : { - "x" : 12.049999999999999, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1006, - "absorbing" : false, - "shape" : { - "x" : 12.649999999999999, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1007, - "absorbing" : false, - "shape" : { - "x" : 13.249999999999998, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1008, - "absorbing" : false, - "shape" : { - "x" : 13.849999999999998, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1009, - "absorbing" : false, - "shape" : { - "x" : 14.449999999999998, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1010, - "absorbing" : false, - "shape" : { - "x" : 15.049999999999997, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1011, - "absorbing" : false, - "shape" : { - "x" : 9.65, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1012, - "absorbing" : false, - "shape" : { - "x" : 10.25, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1013, - "absorbing" : false, - "shape" : { - "x" : 10.85, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1014, - "absorbing" : false, - "shape" : { - "x" : 11.45, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1015, - "absorbing" : false, - "shape" : { - "x" : 12.049999999999999, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1016, - "absorbing" : false, - "shape" : { - "x" : 12.649999999999999, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1017, - "absorbing" : false, - "shape" : { - "x" : 13.249999999999998, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1018, - "absorbing" : false, - "shape" : { - "x" : 13.849999999999998, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1019, - "absorbing" : false, - "shape" : { - "x" : 14.449999999999998, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1020, - "absorbing" : false, - "shape" : { - "x" : 15.049999999999997, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1021, - "absorbing" : false, - "shape" : { - "x" : 9.65, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1022, - "absorbing" : false, - "shape" : { - "x" : 10.25, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1023, - "absorbing" : false, - "shape" : { - "x" : 10.85, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1024, - "absorbing" : false, - "shape" : { - "x" : 11.45, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1025, - "absorbing" : false, - "shape" : { - "x" : 12.049999999999999, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1026, - "absorbing" : false, - "shape" : { - "x" : 12.649999999999999, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1027, - "absorbing" : false, - "shape" : { - "x" : 13.249999999999998, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1028, - "absorbing" : false, - "shape" : { - "x" : 13.849999999999998, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1029, - "absorbing" : false, - "shape" : { - "x" : 14.449999999999998, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1030, - "absorbing" : false, - "shape" : { - "x" : 15.049999999999997, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1031, - "absorbing" : false, - "shape" : { - "x" : 9.65, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1032, - "absorbing" : false, - "shape" : { - "x" : 10.25, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1033, - "absorbing" : false, - "shape" : { - "x" : 10.85, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1034, - "absorbing" : false, - "shape" : { - "x" : 11.45, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1035, - "absorbing" : false, - "shape" : { - "x" : 12.049999999999999, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1036, - "absorbing" : false, - "shape" : { - "x" : 12.649999999999999, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1037, - "absorbing" : false, - "shape" : { - "x" : 13.249999999999998, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1038, - "absorbing" : false, - "shape" : { - "x" : 13.849999999999998, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1039, - "absorbing" : false, - "shape" : { - "x" : 14.449999999999998, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1040, - "absorbing" : false, - "shape" : { - "x" : 15.049999999999997, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1041, - "absorbing" : false, - "shape" : { - "x" : 9.65, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1042, - "absorbing" : false, - "shape" : { - "x" : 10.25, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1043, - "absorbing" : false, - "shape" : { - "x" : 10.85, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1044, - "absorbing" : false, - "shape" : { - "x" : 11.45, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1045, - "absorbing" : false, - "shape" : { - "x" : 12.049999999999999, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1046, - "absorbing" : false, - "shape" : { - "x" : 12.649999999999999, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1047, - "absorbing" : false, - "shape" : { - "x" : 13.249999999999998, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1048, - "absorbing" : false, - "shape" : { - "x" : 13.849999999999998, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1049, - "absorbing" : false, - "shape" : { - "x" : 14.449999999999998, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1050, - "absorbing" : false, - "shape" : { - "x" : 15.049999999999997, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1051, - "absorbing" : false, - "shape" : { - "x" : 9.65, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1052, - "absorbing" : false, - "shape" : { - "x" : 10.25, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1053, - "absorbing" : false, - "shape" : { - "x" : 10.85, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1054, - "absorbing" : false, - "shape" : { - "x" : 11.45, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1055, - "absorbing" : false, - "shape" : { - "x" : 12.049999999999999, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1056, - "absorbing" : false, - "shape" : { - "x" : 12.649999999999999, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1057, - "absorbing" : false, - "shape" : { - "x" : 13.249999999999998, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1058, - "absorbing" : false, - "shape" : { - "x" : 13.849999999999998, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1059, - "absorbing" : false, - "shape" : { - "x" : 14.449999999999998, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1060, - "absorbing" : false, - "shape" : { - "x" : 15.049999999999997, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1061, - "absorbing" : false, - "shape" : { - "x" : 16.95, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1062, - "absorbing" : false, - "shape" : { - "x" : 17.55, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1063, - "absorbing" : false, - "shape" : { - "x" : 18.150000000000002, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1064, - "absorbing" : false, - "shape" : { - "x" : 18.750000000000004, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1065, - "absorbing" : false, - "shape" : { - "x" : 19.350000000000005, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1066, - "absorbing" : false, - "shape" : { - "x" : 19.950000000000006, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1067, - "absorbing" : false, - "shape" : { - "x" : 20.550000000000008, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1068, - "absorbing" : false, - "shape" : { - "x" : 21.15000000000001, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1069, - "absorbing" : false, - "shape" : { - "x" : 21.75000000000001, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1070, - "absorbing" : false, - "shape" : { - "x" : 22.350000000000012, - "y" : 12.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1071, - "absorbing" : false, - "shape" : { - "x" : 16.95, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1072, - "absorbing" : false, - "shape" : { - "x" : 17.55, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1073, - "absorbing" : false, - "shape" : { - "x" : 18.150000000000002, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1074, - "absorbing" : false, - "shape" : { - "x" : 18.750000000000004, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1075, - "absorbing" : false, - "shape" : { - "x" : 19.350000000000005, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1076, - "absorbing" : false, - "shape" : { - "x" : 19.950000000000006, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1077, - "absorbing" : false, - "shape" : { - "x" : 20.550000000000008, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1078, - "absorbing" : false, - "shape" : { - "x" : 21.15000000000001, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1079, - "absorbing" : false, - "shape" : { - "x" : 21.75000000000001, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1080, - "absorbing" : false, - "shape" : { - "x" : 22.350000000000012, - "y" : 11.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1081, - "absorbing" : false, - "shape" : { - "x" : 16.95, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1082, - "absorbing" : false, - "shape" : { - "x" : 17.55, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1083, - "absorbing" : false, - "shape" : { - "x" : 18.150000000000002, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1084, - "absorbing" : false, - "shape" : { - "x" : 18.750000000000004, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1085, - "absorbing" : false, - "shape" : { - "x" : 19.350000000000005, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1086, - "absorbing" : false, - "shape" : { - "x" : 19.950000000000006, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1087, - "absorbing" : false, - "shape" : { - "x" : 20.550000000000008, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1088, - "absorbing" : false, - "shape" : { - "x" : 21.15000000000001, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1089, - "absorbing" : false, - "shape" : { - "x" : 21.75000000000001, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1090, - "absorbing" : false, - "shape" : { - "x" : 22.350000000000012, - "y" : 10.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1091, - "absorbing" : false, - "shape" : { - "x" : 16.95, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1092, - "absorbing" : false, - "shape" : { - "x" : 17.55, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1093, - "absorbing" : false, - "shape" : { - "x" : 18.150000000000002, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1094, - "absorbing" : false, - "shape" : { - "x" : 18.750000000000004, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1095, - "absorbing" : false, - "shape" : { - "x" : 19.350000000000005, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1096, - "absorbing" : false, - "shape" : { - "x" : 19.950000000000006, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1097, - "absorbing" : false, - "shape" : { - "x" : 20.550000000000008, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1098, - "absorbing" : false, - "shape" : { - "x" : 21.15000000000001, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1099, - "absorbing" : false, - "shape" : { - "x" : 21.75000000000001, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1100, - "absorbing" : false, - "shape" : { - "x" : 22.350000000000012, - "y" : 9.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1101, - "absorbing" : false, - "shape" : { - "x" : 16.95, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1102, - "absorbing" : false, - "shape" : { - "x" : 17.55, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1103, - "absorbing" : false, - "shape" : { - "x" : 18.150000000000002, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1104, - "absorbing" : false, - "shape" : { - "x" : 18.750000000000004, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1105, - "absorbing" : false, - "shape" : { - "x" : 19.350000000000005, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1106, - "absorbing" : false, - "shape" : { - "x" : 19.950000000000006, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1107, - "absorbing" : false, - "shape" : { - "x" : 20.550000000000008, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1108, - "absorbing" : false, - "shape" : { - "x" : 21.15000000000001, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1109, - "absorbing" : false, - "shape" : { - "x" : 21.75000000000001, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1110, - "absorbing" : false, - "shape" : { - "x" : 22.350000000000012, - "y" : 8.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1111, - "absorbing" : false, - "shape" : { - "x" : 16.95, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1112, - "absorbing" : false, - "shape" : { - "x" : 17.55, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1113, - "absorbing" : false, - "shape" : { - "x" : 18.150000000000002, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1114, - "absorbing" : false, - "shape" : { - "x" : 18.750000000000004, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1115, - "absorbing" : false, - "shape" : { - "x" : 19.350000000000005, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1116, - "absorbing" : false, - "shape" : { - "x" : 19.950000000000006, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1117, - "absorbing" : false, - "shape" : { - "x" : 20.550000000000008, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1118, - "absorbing" : false, - "shape" : { - "x" : 21.15000000000001, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1119, - "absorbing" : false, - "shape" : { - "x" : 21.75000000000001, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1120, - "absorbing" : false, - "shape" : { - "x" : 22.350000000000012, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1121, - "absorbing" : false, - "shape" : { - "x" : 29.25, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1122, - "absorbing" : false, - "shape" : { - "x" : 29.85, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1123, - "absorbing" : false, - "shape" : { - "x" : 30.450000000000003, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1124, - "absorbing" : false, - "shape" : { - "x" : 31.050000000000004, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1125, - "absorbing" : false, - "shape" : { - "x" : 31.650000000000006, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1126, - "absorbing" : false, - "shape" : { - "x" : 32.25000000000001, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1127, - "absorbing" : false, - "shape" : { - "x" : 32.85000000000001, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1128, - "absorbing" : false, - "shape" : { - "x" : 33.45000000000001, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1129, - "absorbing" : false, - "shape" : { - "x" : 34.05000000000001, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1130, - "absorbing" : false, - "shape" : { - "x" : 34.65000000000001, - "y" : 7.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1131, - "absorbing" : false, - "shape" : { - "x" : 29.25, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1132, - "absorbing" : false, - "shape" : { - "x" : 29.85, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1133, - "absorbing" : false, - "shape" : { - "x" : 30.450000000000003, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1134, - "absorbing" : false, - "shape" : { - "x" : 31.050000000000004, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1135, - "absorbing" : false, - "shape" : { - "x" : 31.650000000000006, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1136, - "absorbing" : false, - "shape" : { - "x" : 32.25000000000001, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1137, - "absorbing" : false, - "shape" : { - "x" : 32.85000000000001, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1138, - "absorbing" : false, - "shape" : { - "x" : 33.45000000000001, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1139, - "absorbing" : false, - "shape" : { - "x" : 34.05000000000001, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1140, - "absorbing" : false, - "shape" : { - "x" : 34.65000000000001, - "y" : 6.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1141, - "absorbing" : false, - "shape" : { - "x" : 29.25, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1142, - "absorbing" : false, - "shape" : { - "x" : 29.85, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1143, - "absorbing" : false, - "shape" : { - "x" : 30.450000000000003, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1144, - "absorbing" : false, - "shape" : { - "x" : 31.050000000000004, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1145, - "absorbing" : false, - "shape" : { - "x" : 31.650000000000006, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1146, - "absorbing" : false, - "shape" : { - "x" : 32.25000000000001, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1147, - "absorbing" : false, - "shape" : { - "x" : 32.85000000000001, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1148, - "absorbing" : false, - "shape" : { - "x" : 33.45000000000001, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1149, - "absorbing" : false, - "shape" : { - "x" : 34.05000000000001, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1150, - "absorbing" : false, - "shape" : { - "x" : 34.65000000000001, - "y" : 5.0, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1151, - "absorbing" : false, - "shape" : { - "x" : 8.521428571428572, - "y" : 15.9, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1152, - "absorbing" : false, - "shape" : { - "x" : 11.392857142857144, - "y" : 15.9, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1153, - "absorbing" : false, - "shape" : { - "x" : 14.264285714285716, - "y" : 15.9, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1154, - "absorbing" : false, - "shape" : { - "x" : 17.135714285714286, - "y" : 15.9, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1155, - "absorbing" : false, - "shape" : { - "x" : 20.00714285714286, - "y" : 15.9, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1156, - "absorbing" : false, - "shape" : { - "x" : 22.878571428571433, - "y" : 15.9, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1157, - "absorbing" : false, - "shape" : { - "x" : 8.521428571428572, - "y" : 13.028571428571428, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1158, - "absorbing" : false, - "shape" : { - "x" : 11.392857142857144, - "y" : 13.028571428571428, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1159, - "absorbing" : false, - "shape" : { - "x" : 14.264285714285716, - "y" : 13.028571428571428, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1160, - "absorbing" : false, - "shape" : { - "x" : 17.135714285714286, - "y" : 13.028571428571428, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1161, - "absorbing" : false, - "shape" : { - "x" : 20.00714285714286, - "y" : 13.028571428571428, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1162, - "absorbing" : false, - "shape" : { - "x" : 22.878571428571433, - "y" : 13.028571428571428, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 900.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1163, - "absorbing" : false, - "shape" : { - "x" : 6.65, - "y" : 17.4, - "width" : 4.775, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 0.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1164, - "absorbing" : true, - "shape" : { - "x" : 1.0, - "y" : 1.0, - "width" : 0.5, - "height" : 2.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 0.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - } ], - "targetChangers" : [ ], - "absorbingAreas" : [ ], - "aerosolClouds" : [ ], - "droplets" : [ ], - "sources" : [ { - "id" : 1, - "shape" : { - "x" : 1.5, - "y" : 17.49, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1058, 1094, 1152, 1058, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 2, - "shape" : { - "x" : 2.31, - "y" : 17.49, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1104, 1115, 1152, 1104, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 3, - "shape" : { - "x" : 3.12, - "y" : 17.49, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1100, 1147, 1160, 1100, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 4, - "shape" : { - "x" : 3.93, - "y" : 17.49, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1004, 1106, 1153, 1004, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 5, - "shape" : { - "x" : 4.74, - "y" : 17.49, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1112, 1098, 1161, 1112, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 6, - "shape" : { - "x" : 1.5, - "y" : 16.68, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1060, 1128, 1154, 1060, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 7, - "shape" : { - "x" : 2.31, - "y" : 16.68, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1074, 1122, 1155, 1074, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 8, - "shape" : { - "x" : 3.12, - "y" : 16.68, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1023, 1146, 1162, 1023, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 9, - "shape" : { - "x" : 3.93, - "y" : 16.68, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1031, 1126, 1156, 1031, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 10, - "shape" : { - "x" : 4.74, - "y" : 16.68, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1026, 1101, 1154, 1026, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 11, - "shape" : { - "x" : 1.5, - "y" : 15.87, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1048, 1123, 1158, 1048, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 12, - "shape" : { - "x" : 2.31, - "y" : 15.87, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1070, 1141, 1151, 1070, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 13, - "shape" : { - "x" : 3.12, - "y" : 15.87, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1024, 1133, 1152, 1024, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 14, - "shape" : { - "x" : 3.93, - "y" : 15.87, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1068, 1103, 1162, 1068, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 15, - "shape" : { - "x" : 4.74, - "y" : 15.87, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1076, 1143, 1156, 1076, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 16, - "shape" : { - "x" : 1.5, - "y" : 15.059999999999999, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1017, 1114, 1159, 1017, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 17, - "shape" : { - "x" : 2.31, - "y" : 15.059999999999999, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1086, 1135, 1153, 1086, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 18, - "shape" : { - "x" : 3.12, - "y" : 15.059999999999999, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1030, 1144, 1161, 1030, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 19, - "shape" : { - "x" : 3.93, - "y" : 15.059999999999999, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1003, 1119, 1156, 1003, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 20, - "shape" : { - "x" : 4.74, - "y" : 15.059999999999999, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1077, 1120, 1155, 1077, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 21, - "shape" : { - "x" : 1.5, - "y" : 14.249999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1009, 1124, 1157, 1009, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 22, - "shape" : { - "x" : 2.31, - "y" : 14.249999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1108, 1150, 1158, 1108, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 23, - "shape" : { - "x" : 3.12, - "y" : 14.249999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1044, 1125, 1154, 1044, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 24, - "shape" : { - "x" : 3.93, - "y" : 14.249999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1085, 1090, 1152, 1085, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 25, - "shape" : { - "x" : 4.74, - "y" : 14.249999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1099, 1139, 1159, 1099, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 26, - "shape" : { - "x" : 1.5, - "y" : 13.439999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1045, 1138, 1155, 1045, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 27, - "shape" : { - "x" : 2.31, - "y" : 13.439999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1047, 1109, 1151, 1047, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 28, - "shape" : { - "x" : 3.12, - "y" : 13.439999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1116, 1148, 1157, 1116, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 29, - "shape" : { - "x" : 3.93, - "y" : 13.439999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1081, 1142, 1161, 1081, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 30, - "shape" : { - "x" : 4.74, - "y" : 13.439999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1038, 1108, 1157, 1038, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 31, - "shape" : { - "x" : 1.5, - "y" : 12.629999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1011, 1116, 1158, 1011, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 32, - "shape" : { - "x" : 2.31, - "y" : 12.629999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1025, 1092, 1162, 1025, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 33, - "shape" : { - "x" : 3.12, - "y" : 12.629999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1049, 1137, 1151, 1049, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 34, - "shape" : { - "x" : 3.93, - "y" : 12.629999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1051, 1099, 1151, 1051, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 35, - "shape" : { - "x" : 4.74, - "y" : 12.629999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1105, 1096, 1156, 1105, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 36, - "shape" : { - "x" : 1.5, - "y" : 11.819999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1094, 1093, 1158, 1094, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 37, - "shape" : { - "x" : 2.31, - "y" : 11.819999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1014, 1117, 1153, 1014, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 38, - "shape" : { - "x" : 3.12, - "y" : 11.819999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1053, 1136, 1158, 1053, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 39, - "shape" : { - "x" : 3.93, - "y" : 11.819999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1022, 1100, 1160, 1022, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 40, - "shape" : { - "x" : 4.74, - "y" : 11.819999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1113, 1113, 1155, 1113, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 41, - "shape" : { - "x" : 1.5, - "y" : 11.009999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1073, 1104, 1160, 1073, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 42, - "shape" : { - "x" : 2.31, - "y" : 11.009999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1092, 1145, 1162, 1092, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 43, - "shape" : { - "x" : 3.12, - "y" : 11.009999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1036, 1107, 1152, 1036, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 44, - "shape" : { - "x" : 3.93, - "y" : 11.009999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1020, 1091, 1158, 1020, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 45, - "shape" : { - "x" : 4.74, - "y" : 11.009999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1007, 1105, 1156, 1007, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 46, - "shape" : { - "x" : 1.5, - "y" : 10.199999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1103, 1102, 1161, 1103, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 47, - "shape" : { - "x" : 2.31, - "y" : 10.199999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1096, 1111, 1151, 1096, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 48, - "shape" : { - "x" : 3.12, - "y" : 10.199999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1021, 1130, 1157, 1021, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 49, - "shape" : { - "x" : 3.93, - "y" : 10.199999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1119, 1127, 1161, 1119, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 50, - "shape" : { - "x" : 4.74, - "y" : 10.199999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1115, 1149, 1153, 1115, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 51, - "shape" : { - "x" : 1.5, - "y" : 9.389999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1029, 1097, 1155, 1029, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 52, - "shape" : { - "x" : 2.31, - "y" : 9.389999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1035, 1129, 1159, 1035, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 53, - "shape" : { - "x" : 3.12, - "y" : 9.389999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1055, 1110, 1152, 1055, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 54, - "shape" : { - "x" : 3.93, - "y" : 9.389999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1089, 1095, 1159, 1089, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 55, - "shape" : { - "x" : 4.74, - "y" : 9.389999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1095, 1112, 1157, 1095, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 56, - "shape" : { - "x" : 1.5, - "y" : 8.579999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1016, 1140, 1154, 1016, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 57, - "shape" : { - "x" : 2.31, - "y" : 8.579999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1015, 1134, 1162, 1015, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 58, - "shape" : { - "x" : 3.12, - "y" : 8.579999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1110, 1131, 1156, 1110, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 59, - "shape" : { - "x" : 3.93, - "y" : 8.579999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1059, 1132, 1159, 1059, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 60, - "shape" : { - "x" : 4.74, - "y" : 8.579999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1084, 1121, 1154, 1084, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 61, - "shape" : { - "x" : 1.5, - "y" : 7.769999999999994, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1005, 1118, 1162, 1005, 1163, 1164 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - } ], - "dynamicElements" : [ ], - "attributesPedestrian" : { - "radius" : 0.2, - "densityDependentSpeed" : false, - "speedDistributionMean" : 1.34, - "speedDistributionStandardDeviation" : 0.26, - "minimumSpeed" : 0.5, - "maximumSpeed" : 2.2, - "acceleration" : 2.0, - "footstepHistorySize" : 4, - "searchRadius" : 1.0, - "walkingDirectionCalculation" : "BY_TARGET_CENTER", - "walkingDirectionSameIfAngleLessOrEqual" : 45.0 - }, - "teleporter" : null, - "attributesCar" : { - "id" : -1, - "radius" : 0.2, - "densityDependentSpeed" : false, - "speedDistributionMean" : 1.34, - "speedDistributionStandardDeviation" : 0.26, - "minimumSpeed" : 0.5, - "maximumSpeed" : 2.2, - "acceleration" : 2.0, - "footstepHistorySize" : 4, - "searchRadius" : 1.0, - "walkingDirectionCalculation" : "BY_TARGET_CENTER", - "walkingDirectionSameIfAngleLessOrEqual" : 45.0, - "length" : 4.5, - "width" : 1.7, - "direction" : { - "x" : 1.0, - "y" : 0.0 - } - } - }, - "stimulusInfos" : [ ], - "reactionProbabilities" : [ ] - } -} \ No newline at end of file diff --git a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario b/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario deleted file mode 100644 index 72e21348b..000000000 --- a/Scenarios/Demos/TransmissionModel/validation/scenarios/miller-2020-life_seed_000.scenario +++ /dev/null @@ -1,4561 +0,0 @@ -{ - "name" : "miller-2020-life_seed_000", - "description" : "Superspreading event during a choir rehearsal following miller-2020-life;\n\nS. L. Miller, W. W. Nazaroff, J. L. Jimenez, A. Boerstra, G. Buonanno, S. J. Dancer, J. Kurnitski, L. C. Marr, L. Morawska, and C. Noakes. Transmission of SARSCoV-2 by inhalation of respiratory aerosol in the skagit valley chorale superspreading event. Indoor Air, 31(2): 314–323, 2020. doi:10.1111/ina.12751.", - "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", - "processWriters" : { - "files" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile", - "filename" : "infectionStatus.txt", - "processors" : [ 1 ] - }, { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.PedestrianIdOutputFile", - "filename" : "pathogenLoad.txt", - "processors" : [ 2 ] - } ], - "processors" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianMaxDegreeOfExposureProcessor", - "id" : 2 - } ], - "isTimestamped" : false, - "isWriteMetaData" : false - }, - "scenario" : { - "mainModel" : "org.vadere.simulator.models.osm.OptimalStepsModel", - "attributesModel" : { - "org.vadere.state.attributes.models.AttributesOSM" : { - "stepCircleResolution" : 4, - "numberOfCircles" : 1, - "optimizationType" : "NELDER_MEAD", - "varyStepDirection" : true, - "movementType" : "ARBITRARY", - "stepLengthIntercept" : 0.4625, - "stepLengthSlopeSpeed" : 0.2345, - "stepLengthSD" : 0.036, - "movementThreshold" : 0.0, - "minStepLength" : 0.1, - "minimumStepLength" : true, - "maxStepDuration" : 1.7976931348623157E308, - "dynamicStepLength" : true, - "updateType" : "EVENT_DRIVEN", - "seeSmallWalls" : false, - "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", - "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", - "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] - }, - "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { - "pedPotentialIntimateSpaceWidth" : 0.45, - "pedPotentialPersonalSpaceWidth" : 1.2, - "pedPotentialHeight" : 5.0, - "obstPotentialWidth" : 0.8, - "obstPotentialHeight" : 6.0, - "intimateSpaceFactor" : 1.2, - "personalSpacePower" : 1, - "intimateSpacePower" : 1 - }, - "org.vadere.state.attributes.models.AttributesFloorField" : { - "createMethod" : "HIGH_ACCURACY_FAST_MARCHING", - "potentialFieldResolution" : 0.1, - "obstacleGridPenalty" : 0.1, - "targetAttractionStrength" : 1.0, - "cacheType" : "NO_CACHE", - "cacheDir" : "", - "timeCostAttributes" : { - "standardDeviation" : 0.7, - "type" : "UNIT", - "obstacleDensityWeight" : 3.5, - "pedestrianSameTargetDensityWeight" : 3.5, - "pedestrianOtherTargetDensityWeight" : 3.5, - "pedestrianWeight" : 3.5, - "queueWidthLoading" : 1.0, - "pedestrianDynamicWeight" : 6.0, - "loadingType" : "CONSTANT", - "width" : 0.2, - "height" : 1.0 - } - }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { - "exposureModelSourceParameters" : [ { - "sourceId" : -1, - "infectious" : false - }, { - "sourceId" : 1, - "infectious" : true - } ], - "infectiousPedestrianIdsNoSource" : [ ], - "pedestrianRespiratoryCyclePeriod" : 4.0, - "aerosolCloudsActive" : true, - "aerosolCloudParameters" : { - "halfLife" : 600.0, - "initialRadius" : 1.5, - "initialPathogenLoad" : 10000.0, - "airDispersionFactor" : 0.0, - "pedestrianDispersionWeight" : 0.0125, - "absorptionRate" : 5.0E-4 - }, - "dropletsActive" : false, - "dropletParameters" : { - "emissionFrequency" : 0.016666666666666666, - "distanceOfSpread" : 1.5, - "angleOfSpreadInDeg" : 30.0, - "lifeTime" : 1.5, - "pathogenLoad" : 10000.0, - "absorptionRate" : 0.1 - } - } - }, - "attributesSimulation" : { - "finishTime" : 9300.0, - "simTimeStepLength" : 0.4, - "realTimeSimTimeRatio" : 0.0, - "writeSimulationData" : true, - "visualizationEnabled" : true, - "printFPS" : false, - "digitsPerCoordinate" : 2, - "useFixedSeed" : true, - "fixedSeed" : -2054058476485033808, - "simulationSeed" : 0 - }, - "attributesPsychology" : { - "usePsychologyLayer" : false, - "psychologyLayer" : { - "perception" : "SimplePerceptionModel", - "cognition" : "SimpleCognitionModel" - } - }, - "topography" : { - "attributes" : { - "bounds" : { - "x" : 0.0, - "y" : 0.0, - "width" : 36.41, - "height" : 12.899999999999999 - }, - "boundingBoxWidth" : 0.5, - "bounded" : true, - "referenceCoordinateSystem" : null - }, - "obstacles" : [ { - "shape" : { - "x" : 6.96, - "y" : 0.5, - "width" : 28.95, - "height" : 0.5, - "type" : "RECTANGLE" - }, - "id" : 2001 - }, { - "shape" : { - "x" : 6.96, - "y" : 3.0, - "width" : 0.5, - "height" : 9.399999999999999, - "type" : "RECTANGLE" - }, - "id" : 2002 - }, { - "shape" : { - "x" : 7.46, - "y" : 11.899999999999999, - "width" : 27.95, - "height" : 0.5, - "type" : "RECTANGLE" - }, - "id" : 2003 - }, { - "shape" : { - "x" : 25.36, - "y" : 3.0, - "width" : 0.5, - "height" : 6.899999999999999, - "type" : "RECTANGLE" - }, - "id" : 2004 - }, { - "shape" : { - "x" : 35.41, - "y" : 1.0, - "width" : 0.5, - "height" : 11.399999999999999, - "type" : "RECTANGLE" - }, - "id" : 2005 - }, { - "shape" : { - "x" : 25.86, - "y" : 7.7, - "width" : 9.55, - "height" : 0.5, - "type" : "RECTANGLE" - }, - "id" : 2006 - } ], - "measurementAreas" : [ ], - "stairs" : [ ], - "targets" : [ { - "id" : 1001, - "absorbing" : false, - "shape" : { - "x" : 8.66, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1002, - "absorbing" : false, - "shape" : { - "x" : 9.41, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1003, - "absorbing" : false, - "shape" : { - "x" : 10.16, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1004, - "absorbing" : false, - "shape" : { - "x" : 10.91, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1005, - "absorbing" : false, - "shape" : { - "x" : 11.66, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1006, - "absorbing" : false, - "shape" : { - "x" : 12.41, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1007, - "absorbing" : false, - "shape" : { - "x" : 13.16, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1008, - "absorbing" : false, - "shape" : { - "x" : 13.91, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1009, - "absorbing" : false, - "shape" : { - "x" : 14.66, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1010, - "absorbing" : false, - "shape" : { - "x" : 15.41, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1011, - "absorbing" : false, - "shape" : { - "x" : 8.66, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1012, - "absorbing" : false, - "shape" : { - "x" : 9.41, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1013, - "absorbing" : false, - "shape" : { - "x" : 10.16, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1014, - "absorbing" : false, - "shape" : { - "x" : 10.91, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1015, - "absorbing" : false, - "shape" : { - "x" : 11.66, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1016, - "absorbing" : false, - "shape" : { - "x" : 12.41, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1017, - "absorbing" : false, - "shape" : { - "x" : 13.16, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1018, - "absorbing" : false, - "shape" : { - "x" : 13.91, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1019, - "absorbing" : false, - "shape" : { - "x" : 14.66, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1020, - "absorbing" : false, - "shape" : { - "x" : 15.41, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1021, - "absorbing" : false, - "shape" : { - "x" : 8.66, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1022, - "absorbing" : false, - "shape" : { - "x" : 9.41, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1023, - "absorbing" : false, - "shape" : { - "x" : 10.16, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1024, - "absorbing" : false, - "shape" : { - "x" : 10.91, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1025, - "absorbing" : false, - "shape" : { - "x" : 11.66, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1026, - "absorbing" : false, - "shape" : { - "x" : 12.41, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1027, - "absorbing" : false, - "shape" : { - "x" : 13.16, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1028, - "absorbing" : false, - "shape" : { - "x" : 13.91, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1029, - "absorbing" : false, - "shape" : { - "x" : 14.66, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1030, - "absorbing" : false, - "shape" : { - "x" : 15.41, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1031, - "absorbing" : false, - "shape" : { - "x" : 8.66, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1032, - "absorbing" : false, - "shape" : { - "x" : 9.41, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1033, - "absorbing" : false, - "shape" : { - "x" : 10.16, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1034, - "absorbing" : false, - "shape" : { - "x" : 10.91, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1035, - "absorbing" : false, - "shape" : { - "x" : 11.66, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1036, - "absorbing" : false, - "shape" : { - "x" : 12.41, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1037, - "absorbing" : false, - "shape" : { - "x" : 13.16, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1038, - "absorbing" : false, - "shape" : { - "x" : 13.91, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1039, - "absorbing" : false, - "shape" : { - "x" : 14.66, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1040, - "absorbing" : false, - "shape" : { - "x" : 15.41, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1041, - "absorbing" : false, - "shape" : { - "x" : 8.66, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1042, - "absorbing" : false, - "shape" : { - "x" : 9.41, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1043, - "absorbing" : false, - "shape" : { - "x" : 10.16, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1044, - "absorbing" : false, - "shape" : { - "x" : 10.91, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1045, - "absorbing" : false, - "shape" : { - "x" : 11.66, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1046, - "absorbing" : false, - "shape" : { - "x" : 12.41, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1047, - "absorbing" : false, - "shape" : { - "x" : 13.16, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1048, - "absorbing" : false, - "shape" : { - "x" : 13.91, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1049, - "absorbing" : false, - "shape" : { - "x" : 14.66, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1050, - "absorbing" : false, - "shape" : { - "x" : 15.41, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1051, - "absorbing" : false, - "shape" : { - "x" : 8.66, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1052, - "absorbing" : false, - "shape" : { - "x" : 9.41, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1053, - "absorbing" : false, - "shape" : { - "x" : 10.16, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1054, - "absorbing" : false, - "shape" : { - "x" : 10.91, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1055, - "absorbing" : false, - "shape" : { - "x" : 11.66, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1056, - "absorbing" : false, - "shape" : { - "x" : 12.41, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1057, - "absorbing" : false, - "shape" : { - "x" : 13.16, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1058, - "absorbing" : false, - "shape" : { - "x" : 13.91, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1059, - "absorbing" : false, - "shape" : { - "x" : 14.66, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1060, - "absorbing" : false, - "shape" : { - "x" : 15.41, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1061, - "absorbing" : false, - "shape" : { - "x" : 17.01, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1062, - "absorbing" : false, - "shape" : { - "x" : 17.76, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1063, - "absorbing" : false, - "shape" : { - "x" : 18.51, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1064, - "absorbing" : false, - "shape" : { - "x" : 19.26, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1065, - "absorbing" : false, - "shape" : { - "x" : 20.01, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1066, - "absorbing" : false, - "shape" : { - "x" : 20.76, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1067, - "absorbing" : false, - "shape" : { - "x" : 21.51, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1068, - "absorbing" : false, - "shape" : { - "x" : 22.26, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1069, - "absorbing" : false, - "shape" : { - "x" : 23.01, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1070, - "absorbing" : false, - "shape" : { - "x" : 23.76, - "y" : 10.499999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1071, - "absorbing" : false, - "shape" : { - "x" : 17.01, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1072, - "absorbing" : false, - "shape" : { - "x" : 17.76, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1073, - "absorbing" : false, - "shape" : { - "x" : 18.51, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1074, - "absorbing" : false, - "shape" : { - "x" : 19.26, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1075, - "absorbing" : false, - "shape" : { - "x" : 20.01, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1076, - "absorbing" : false, - "shape" : { - "x" : 20.76, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1077, - "absorbing" : false, - "shape" : { - "x" : 21.51, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1078, - "absorbing" : false, - "shape" : { - "x" : 22.26, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1079, - "absorbing" : false, - "shape" : { - "x" : 23.01, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1080, - "absorbing" : false, - "shape" : { - "x" : 23.76, - "y" : 9.099999999999998, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1081, - "absorbing" : false, - "shape" : { - "x" : 17.01, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1082, - "absorbing" : false, - "shape" : { - "x" : 17.76, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1083, - "absorbing" : false, - "shape" : { - "x" : 18.51, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1084, - "absorbing" : false, - "shape" : { - "x" : 19.26, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1085, - "absorbing" : false, - "shape" : { - "x" : 20.01, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1086, - "absorbing" : false, - "shape" : { - "x" : 20.76, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1087, - "absorbing" : false, - "shape" : { - "x" : 21.51, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1088, - "absorbing" : false, - "shape" : { - "x" : 22.26, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1089, - "absorbing" : false, - "shape" : { - "x" : 23.01, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1090, - "absorbing" : false, - "shape" : { - "x" : 23.76, - "y" : 7.6999999999999975, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1091, - "absorbing" : false, - "shape" : { - "x" : 17.01, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1092, - "absorbing" : false, - "shape" : { - "x" : 17.76, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1093, - "absorbing" : false, - "shape" : { - "x" : 18.51, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1094, - "absorbing" : false, - "shape" : { - "x" : 19.26, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1095, - "absorbing" : false, - "shape" : { - "x" : 20.01, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1096, - "absorbing" : false, - "shape" : { - "x" : 20.76, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1097, - "absorbing" : false, - "shape" : { - "x" : 21.51, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1098, - "absorbing" : false, - "shape" : { - "x" : 22.26, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1099, - "absorbing" : false, - "shape" : { - "x" : 23.01, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1100, - "absorbing" : false, - "shape" : { - "x" : 23.76, - "y" : 6.299999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1101, - "absorbing" : false, - "shape" : { - "x" : 17.01, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1102, - "absorbing" : false, - "shape" : { - "x" : 17.76, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1103, - "absorbing" : false, - "shape" : { - "x" : 18.51, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1104, - "absorbing" : false, - "shape" : { - "x" : 19.26, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1105, - "absorbing" : false, - "shape" : { - "x" : 20.01, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1106, - "absorbing" : false, - "shape" : { - "x" : 20.76, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1107, - "absorbing" : false, - "shape" : { - "x" : 21.51, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1108, - "absorbing" : false, - "shape" : { - "x" : 22.26, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1109, - "absorbing" : false, - "shape" : { - "x" : 23.01, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1110, - "absorbing" : false, - "shape" : { - "x" : 23.76, - "y" : 4.899999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1111, - "absorbing" : false, - "shape" : { - "x" : 17.01, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1112, - "absorbing" : false, - "shape" : { - "x" : 17.76, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1113, - "absorbing" : false, - "shape" : { - "x" : 18.51, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1114, - "absorbing" : false, - "shape" : { - "x" : 19.26, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1115, - "absorbing" : false, - "shape" : { - "x" : 20.01, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1116, - "absorbing" : false, - "shape" : { - "x" : 20.76, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1117, - "absorbing" : false, - "shape" : { - "x" : 21.51, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1118, - "absorbing" : false, - "shape" : { - "x" : 22.26, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1119, - "absorbing" : false, - "shape" : { - "x" : 23.01, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1120, - "absorbing" : false, - "shape" : { - "x" : 23.76, - "y" : 3.499999999999997, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1121, - "absorbing" : false, - "shape" : { - "x" : 27.060000000000002, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1122, - "absorbing" : false, - "shape" : { - "x" : 27.810000000000002, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1123, - "absorbing" : false, - "shape" : { - "x" : 28.560000000000002, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1124, - "absorbing" : false, - "shape" : { - "x" : 29.310000000000002, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1125, - "absorbing" : false, - "shape" : { - "x" : 30.060000000000002, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1126, - "absorbing" : false, - "shape" : { - "x" : 30.810000000000002, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1127, - "absorbing" : false, - "shape" : { - "x" : 31.560000000000002, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1128, - "absorbing" : false, - "shape" : { - "x" : 32.31, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1129, - "absorbing" : false, - "shape" : { - "x" : 33.06, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1130, - "absorbing" : false, - "shape" : { - "x" : 33.81, - "y" : 6.299999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1131, - "absorbing" : false, - "shape" : { - "x" : 27.060000000000002, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1132, - "absorbing" : false, - "shape" : { - "x" : 27.810000000000002, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1133, - "absorbing" : false, - "shape" : { - "x" : 28.560000000000002, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1134, - "absorbing" : false, - "shape" : { - "x" : 29.310000000000002, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1135, - "absorbing" : false, - "shape" : { - "x" : 30.060000000000002, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1136, - "absorbing" : false, - "shape" : { - "x" : 30.810000000000002, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1137, - "absorbing" : false, - "shape" : { - "x" : 31.560000000000002, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1138, - "absorbing" : false, - "shape" : { - "x" : 32.31, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1139, - "absorbing" : false, - "shape" : { - "x" : 33.06, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1140, - "absorbing" : false, - "shape" : { - "x" : 33.81, - "y" : 4.899999999999999, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1141, - "absorbing" : false, - "shape" : { - "x" : 27.060000000000002, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1142, - "absorbing" : false, - "shape" : { - "x" : 27.810000000000002, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1143, - "absorbing" : false, - "shape" : { - "x" : 28.560000000000002, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1144, - "absorbing" : false, - "shape" : { - "x" : 29.310000000000002, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1145, - "absorbing" : false, - "shape" : { - "x" : 30.060000000000002, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1146, - "absorbing" : false, - "shape" : { - "x" : 30.810000000000002, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1147, - "absorbing" : false, - "shape" : { - "x" : 31.560000000000002, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1148, - "absorbing" : false, - "shape" : { - "x" : 32.31, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1149, - "absorbing" : false, - "shape" : { - "x" : 33.06, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1150, - "absorbing" : false, - "shape" : { - "x" : 33.81, - "y" : 3.4999999999999987, - "width" : 0.4, - "height" : 0.4, - "type" : "RECTANGLE" - }, - "waitingTime" : 2700.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1151, - "absorbing" : false, - "shape" : { - "x" : 9.61, - "y" : 9.499999999999996, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1152, - "absorbing" : false, - "shape" : { - "x" : 12.76, - "y" : 9.499999999999996, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1153, - "absorbing" : false, - "shape" : { - "x" : 15.91, - "y" : 9.499999999999996, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1154, - "absorbing" : false, - "shape" : { - "x" : 19.06, - "y" : 9.499999999999996, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1155, - "absorbing" : false, - "shape" : { - "x" : 22.209999999999997, - "y" : 9.499999999999996, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1156, - "absorbing" : false, - "shape" : { - "x" : 9.61, - "y" : 6.699999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1157, - "absorbing" : false, - "shape" : { - "x" : 12.76, - "y" : 6.699999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1158, - "absorbing" : false, - "shape" : { - "x" : 15.91, - "y" : 6.699999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1159, - "absorbing" : false, - "shape" : { - "x" : 19.06, - "y" : 6.699999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1160, - "absorbing" : false, - "shape" : { - "x" : 22.209999999999997, - "y" : 6.699999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1161, - "absorbing" : false, - "shape" : { - "x" : 9.61, - "y" : 3.899999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1162, - "absorbing" : false, - "shape" : { - "x" : 12.76, - "y" : 3.899999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1163, - "absorbing" : false, - "shape" : { - "x" : 15.91, - "y" : 3.899999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1164, - "absorbing" : false, - "shape" : { - "x" : 19.06, - "y" : 3.899999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1165, - "absorbing" : false, - "shape" : { - "x" : 22.209999999999997, - "y" : 3.899999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1166, - "absorbing" : false, - "shape" : { - "x" : 9.61, - "y" : 1.099999999999997, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1167, - "absorbing" : false, - "shape" : { - "x" : 30.134999999999998, - "y" : 9.499999999999996, - "width" : 1.0, - "height" : 1.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 600.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - }, { - "id" : 1168, - "absorbing" : true, - "shape" : { - "x" : 6.96, - "y" : 1.0, - "width" : 0.5, - "height" : 2.0, - "type" : "RECTANGLE" - }, - "waitingTime" : 0.0, - "waitingTimeYellowPhase" : 0.0, - "parallelWaiters" : 0, - "individualWaiting" : true, - "deletionDistance" : 0.1, - "startingWithRedLight" : false, - "nextSpeed" : -1.0 - } ], - "targetChangers" : [ ], - "absorbingAreas" : [ ], - "aerosolClouds" : [ ], - "droplets" : [ ], - "sources" : [ { - "id" : 1, - "shape" : { - "x" : 1.5, - "y" : 10.989999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1058, 1103, 1167, 1058, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 2, - "shape" : { - "x" : 2.31, - "y" : 10.989999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1104, 1138, 1166, 1104, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 3, - "shape" : { - "x" : 3.12, - "y" : 10.989999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1100, 1094, 1155, 1100, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 4, - "shape" : { - "x" : 3.93, - "y" : 10.989999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1004, 1076, 1165, 1004, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 5, - "shape" : { - "x" : 4.74, - "y" : 10.989999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1112, 1116, 1153, 1112, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 6, - "shape" : { - "x" : 5.550000000000001, - "y" : 10.989999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1060, 1078, 1157, 1060, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 7, - "shape" : { - "x" : 1.5, - "y" : 10.179999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1074, 1080, 1154, 1074, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 8, - "shape" : { - "x" : 2.31, - "y" : 10.179999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1023, 1131, 1152, 1023, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 9, - "shape" : { - "x" : 3.12, - "y" : 10.179999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1031, 1148, 1167, 1031, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 10, - "shape" : { - "x" : 3.93, - "y" : 10.179999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1026, 1061, 1151, 1026, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 11, - "shape" : { - "x" : 4.74, - "y" : 10.179999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1048, 1126, 1162, 1048, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 12, - "shape" : { - "x" : 5.550000000000001, - "y" : 10.179999999999998, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1070, 1125, 1155, 1070, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 13, - "shape" : { - "x" : 1.5, - "y" : 9.369999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1024, 1087, 1167, 1024, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 14, - "shape" : { - "x" : 2.31, - "y" : 9.369999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1068, 1090, 1160, 1068, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 15, - "shape" : { - "x" : 3.12, - "y" : 9.369999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1076, 1132, 1167, 1076, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 16, - "shape" : { - "x" : 3.93, - "y" : 9.369999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1017, 1146, 1163, 1017, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 17, - "shape" : { - "x" : 4.74, - "y" : 9.369999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1086, 1069, 1165, 1086, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 18, - "shape" : { - "x" : 5.550000000000001, - "y" : 9.369999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1030, 1093, 1152, 1030, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 19, - "shape" : { - "x" : 1.5, - "y" : 8.559999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1003, 1141, 1158, 1003, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 20, - "shape" : { - "x" : 2.31, - "y" : 8.559999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1077, 1096, 1152, 1077, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 21, - "shape" : { - "x" : 3.12, - "y" : 8.559999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1009, 1083, 1161, 1009, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 22, - "shape" : { - "x" : 3.93, - "y" : 8.559999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1108, 1134, 1157, 1108, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 23, - "shape" : { - "x" : 4.74, - "y" : 8.559999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1044, 1137, 1156, 1044, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 24, - "shape" : { - "x" : 5.550000000000001, - "y" : 8.559999999999997, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1085, 1120, 1164, 1085, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 25, - "shape" : { - "x" : 1.5, - "y" : 7.7499999999999964, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1099, 1107, 1159, 1099, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 26, - "shape" : { - "x" : 2.31, - "y" : 7.7499999999999964, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1045, 1110, 1155, 1045, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 27, - "shape" : { - "x" : 3.12, - "y" : 7.7499999999999964, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1047, 1100, 1164, 1047, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 28, - "shape" : { - "x" : 3.93, - "y" : 7.7499999999999964, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1116, 1070, 1158, 1116, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 29, - "shape" : { - "x" : 4.74, - "y" : 7.7499999999999964, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1081, 1081, 1163, 1081, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 30, - "shape" : { - "x" : 5.550000000000001, - "y" : 7.7499999999999964, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1038, 1098, 1166, 1038, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 31, - "shape" : { - "x" : 1.5, - "y" : 6.939999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1011, 1130, 1157, 1011, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 32, - "shape" : { - "x" : 2.31, - "y" : 6.939999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1025, 1117, 1156, 1025, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 33, - "shape" : { - "x" : 3.12, - "y" : 6.939999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1049, 1077, 1158, 1049, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 34, - "shape" : { - "x" : 3.93, - "y" : 6.939999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1051, 1067, 1153, 1051, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 35, - "shape" : { - "x" : 4.74, - "y" : 6.939999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1105, 1088, 1154, 1105, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 36, - "shape" : { - "x" : 5.550000000000001, - "y" : 6.939999999999996, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1094, 1144, 1167, 1094, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 37, - "shape" : { - "x" : 1.5, - "y" : 6.1299999999999955, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1014, 1064, 1166, 1014, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 38, - "shape" : { - "x" : 2.31, - "y" : 6.1299999999999955, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1053, 1074, 1159, 1053, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 39, - "shape" : { - "x" : 3.12, - "y" : 6.1299999999999955, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1022, 1091, 1152, 1022, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 40, - "shape" : { - "x" : 3.93, - "y" : 6.1299999999999955, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1113, 1105, 1153, 1113, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 41, - "shape" : { - "x" : 4.74, - "y" : 6.1299999999999955, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1073, 1072, 1153, 1073, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 42, - "shape" : { - "x" : 5.550000000000001, - "y" : 6.1299999999999955, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1092, 1112, 1156, 1092, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 43, - "shape" : { - "x" : 1.5, - "y" : 5.319999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1036, 1129, 1156, 1036, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 44, - "shape" : { - "x" : 2.31, - "y" : 5.319999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1020, 1111, 1164, 1020, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 45, - "shape" : { - "x" : 3.12, - "y" : 5.319999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1007, 1140, 1167, 1007, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 46, - "shape" : { - "x" : 3.93, - "y" : 5.319999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1103, 1109, 1163, 1103, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 47, - "shape" : { - "x" : 4.74, - "y" : 5.319999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1096, 1084, 1154, 1096, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 48, - "shape" : { - "x" : 5.550000000000001, - "y" : 5.319999999999995, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1021, 1149, 1160, 1021, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 49, - "shape" : { - "x" : 1.5, - "y" : 4.5099999999999945, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1119, 1086, 1151, 1119, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 50, - "shape" : { - "x" : 2.31, - "y" : 4.5099999999999945, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1115, 1114, 1161, 1115, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 51, - "shape" : { - "x" : 3.12, - "y" : 4.5099999999999945, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1029, 1122, 1159, 1029, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 52, - "shape" : { - "x" : 3.93, - "y" : 4.5099999999999945, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1035, 1150, 1157, 1035, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 53, - "shape" : { - "x" : 4.74, - "y" : 4.5099999999999945, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1055, 1127, 1160, 1055, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 54, - "shape" : { - "x" : 5.550000000000001, - "y" : 4.5099999999999945, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1089, 1121, 1154, 1089, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 55, - "shape" : { - "x" : 1.5, - "y" : 3.6999999999999944, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1095, 1128, 1151, 1095, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 56, - "shape" : { - "x" : 2.31, - "y" : 3.6999999999999944, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1016, 1062, 1155, 1016, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 57, - "shape" : { - "x" : 3.12, - "y" : 3.6999999999999944, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1015, 1065, 1161, 1015, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 58, - "shape" : { - "x" : 3.93, - "y" : 3.6999999999999944, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1110, 1104, 1162, 1110, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 59, - "shape" : { - "x" : 4.74, - "y" : 3.6999999999999944, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1059, 1099, 1165, 1059, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 60, - "shape" : { - "x" : 5.550000000000001, - "y" : 3.6999999999999944, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1084, 1135, 1151, 1084, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - }, { - "id" : 61, - "shape" : { - "x" : 1.5, - "y" : 2.8899999999999944, - "width" : 0.41, - "height" : 0.41, - "type" : "RECTANGLE" - }, - "interSpawnTimeDistribution" : "constant", - "distributionParameters" : { - "updateFrequency" : 1.0 - }, - "spawnNumber" : 1, - "maxSpawnNumberTotal" : -1, - "startTime" : 0.0, - "endTime" : 0.0, - "spawnAtRandomPositions" : false, - "spawnAtGridPositionsCA" : false, - "useFreeSpaceOnly" : true, - "targetIds" : [ 1005, 1119, 1162, 1005, 1168 ], - "groupSizeDistribution" : [ 1.0 ], - "dynamicElementType" : "PEDESTRIAN", - "attributesPedestrian" : null - } ], - "dynamicElements" : [ ], - "attributesPedestrian" : { - "radius" : 0.2, - "densityDependentSpeed" : false, - "speedDistributionMean" : 1.34, - "speedDistributionStandardDeviation" : 0.26, - "minimumSpeed" : 0.5, - "maximumSpeed" : 2.2, - "acceleration" : 2.0, - "footstepHistorySize" : 4, - "searchRadius" : 1.0, - "walkingDirectionCalculation" : "BY_TARGET_CENTER", - "walkingDirectionSameIfAngleLessOrEqual" : 45.0 - }, - "teleporter" : null, - "attributesCar" : { - "id" : -1, - "radius" : 0.2, - "densityDependentSpeed" : false, - "speedDistributionMean" : 1.34, - "speedDistributionStandardDeviation" : 0.26, - "minimumSpeed" : 0.5, - "maximumSpeed" : 2.2, - "acceleration" : 2.0, - "footstepHistorySize" : 4, - "searchRadius" : 1.0, - "walkingDirectionCalculation" : "BY_TARGET_CENTER", - "walkingDirectionSameIfAngleLessOrEqual" : 45.0, - "length" : 4.5, - "width" : 1.7, - "direction" : { - "x" : 1.0, - "y" : 0.0 - } - } - }, - "stimulusInfos" : [ ], - "reactionProbabilities" : [ ] - } -} \ No newline at end of file -- GitLab From df9bd5b53148387a380752d114d02c4016a3aca6 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 23 Feb 2022 16:32:58 +0100 Subject: [PATCH 33/83] Rename directory name TestTransmissionModel to TestAirTransmissionModel --- .../vadere.project | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Scenarios/ModelTests/{TestTransmissionModel => TestAirTransmissionModel}/vadere.project (100%) diff --git a/Scenarios/ModelTests/TestTransmissionModel/vadere.project b/Scenarios/ModelTests/TestAirTransmissionModel/vadere.project similarity index 100% rename from Scenarios/ModelTests/TestTransmissionModel/vadere.project rename to Scenarios/ModelTests/TestAirTransmissionModel/vadere.project -- GitLab From d4d640cd0a2c8d925a7c785a7a74e1b85c57bd3a Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 09:37:12 +0100 Subject: [PATCH 34/83] Move method incrementDegreeOfExposure to abstract class ExposureModelHealthStatus. --- .../simulator/models/infection/AirTransmissionModel.java | 2 +- .../state/health/AirTransmissionModelHealthStatus.java | 4 ---- .../org/vadere/state/health/ExposureModelHealthStatus.java | 5 +++++ VadereState/src/org/vadere/state/scenario/Pedestrian.java | 4 ++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index fc5955912..7df66d9e0 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -120,7 +120,7 @@ public class AirTransmissionModel extends AbstractExposureModel { @Override public void updatePedestrianDegreeOfExposure(Pedestrian pedestrian, double deltaDegreeOfExposure) { - pedestrian.getHealthStatus().incrementDegreeOfExposure(deltaDegreeOfExposure); + pedestrian.incrementDegreeOfExposure(deltaDegreeOfExposure); } public void executeAerosolCloudEmissionEvents(double simTimeInSec) { diff --git a/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java b/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java index d8cfa52a8..5c7487dd8 100644 --- a/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java @@ -90,10 +90,6 @@ public class AirTransmissionModelHealthStatus extends ExposureModelHealthStatus // Methods - public void incrementDegreeOfExposure(double deltaDegreeOfExposure) { - this.degreeOfExposure += deltaDegreeOfExposure; - } - /* * Defines whether the pedestrian inhales or exhales depending on the current simulation time, * respiratoryTimeOffset, and periodLength. Assumes that periodLength for inhalation and exhalation are equally diff --git a/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java index 0f9af6805..08b484488 100644 --- a/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java @@ -31,4 +31,9 @@ public abstract class ExposureModelHealthStatus { public void setDegreeOfExposure(double degreeOfExposure) { this.degreeOfExposure = degreeOfExposure; } + + // Methods + public void incrementDegreeOfExposure(double deltaDegreeOfExposure) { + this.degreeOfExposure += deltaDegreeOfExposure; + } } diff --git a/VadereState/src/org/vadere/state/scenario/Pedestrian.java b/VadereState/src/org/vadere/state/scenario/Pedestrian.java index 5958407ac..bc269d0b5 100644 --- a/VadereState/src/org/vadere/state/scenario/Pedestrian.java +++ b/VadereState/src/org/vadere/state/scenario/Pedestrian.java @@ -283,6 +283,10 @@ public class Pedestrian extends Agent { healthStatus.setDegreeOfExposure(degreeOfExposure); } + public void incrementDegreeOfExposure(double deltaDegreeOfExposure) { + healthStatus.incrementDegreeOfExposure(deltaDegreeOfExposure); + } + public void setProbabilityOfInfection(double probabilityOfInfection) { infectionStatus.setProbabilityOfInfection(probabilityOfInfection); } -- GitLab From d936a5a9bbf3501b1e370357efd4316e039f47aa Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 09:49:38 +0100 Subject: [PATCH 35/83] Move method defineSourceParameters to abstract class AbstractExposureModel. --- .../infection/AbstractExposureModel.java | 24 +++++++++++++++++++ .../infection/AirTransmissionModel.java | 22 +---------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java index f69da1ab7..8631202c4 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java @@ -1,9 +1,13 @@ package org.vadere.simulator.models.infection; +import org.vadere.simulator.control.scenarioelements.SourceController; import org.vadere.simulator.projects.Domain; +import org.vadere.state.attributes.models.infection.AttributesExposureModel; +import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.util.logging.Logger; +import java.util.Optional; import java.util.Random; public abstract class AbstractExposureModel implements ExposureModel { @@ -17,4 +21,24 @@ public abstract class AbstractExposureModel implements ExposureModel { protected Domain domain; protected AttributesAgent attributesAgent; + public AttributesExposureModelSourceParameters defineSourceParameters(SourceController controller, AttributesExposureModel attributes) { + int sourceId = controller.getSourceId(); + int defaultSourceId = -1; + Optional sourceParameters = attributes + .getExposureModelSourceParameters().stream().filter(s -> s.getSourceId() == sourceId).findFirst(); + + // if sourceId not set by user, check if the user has defined default attributes by setting sourceId = -1 + if (sourceParameters.isEmpty()) { + sourceParameters = attributes.getExposureModelSourceParameters().stream().filter(s -> s.getSourceId() == defaultSourceId).findFirst(); + + // if no user defined default values: use attributesAirTransmissionModel default values + if (sourceParameters.isPresent()) { + logger.infof(">>>>>>>>>>>defineSourceParameters: sourceId %d not set explicitly exposureModelSourceParameters. Source uses default exposureModelSourceParameters defined for sourceId: %d", sourceId, defaultSourceId); + } else { + logger.errorf(">>>>>>>>>>>defineSourceParameters: sourceId %d is not set in exposureModelSourceParameters", sourceId); + } + } + return sourceParameters.get(); + } + } diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index 7df66d9e0..e811ff6bc 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -364,7 +364,7 @@ public class AirTransmissionModel extends AbstractExposureModel { public Agent sourceControllerEvent(SourceController controller, double simTimeInSec, Agent scenarioElement) { // SourceControllerListener. This will be called *after* a pedestrian is inserted into the // topography by the given SourceController. Change model state on Agent here - AttributesExposureModelSourceParameters sourceParameters = defineSourceParameters(controller); + AttributesExposureModelSourceParameters sourceParameters = defineSourceParameters(controller, attrAirTransmissionModel); Pedestrian ped = (Pedestrian) scenarioElement; ped.setHealthStatus(new AirTransmissionModelHealthStatus()); @@ -395,26 +395,6 @@ public class AirTransmissionModel extends AbstractExposureModel { return pedestrian; } - private AttributesExposureModelSourceParameters defineSourceParameters(SourceController controller) { - int sourceId = controller.getSourceId(); - int defaultSourceId = -1; - Optional sourceParameters = attrAirTransmissionModel - .getExposureModelSourceParameters().stream().filter(s -> s.getSourceId() == sourceId).findFirst(); - - // if sourceId not set by user, check if the user has defined default attributes by setting sourceId = -1 - if (sourceParameters.isEmpty()) { - sourceParameters = attrAirTransmissionModel.getExposureModelSourceParameters().stream().filter(s -> s.getSourceId() == defaultSourceId).findFirst(); - - // if no user defined default values: use attributesAirTransmissionModel default values - if (sourceParameters.isPresent()) { - logger.infof(">>>>>>>>>>>defineSourceParameters: sourceId %d not set explicitly exposureModelSourceParameters. Source uses default exposureModelSourceParameters defined for sourceId: %d", sourceId, defaultSourceId); - } else { - logger.errorf(">>>>>>>>>>>defineSourceParameters: sourceId %d is not set in exposureModelSourceParameters", sourceId); - } - } - return sourceParameters.get(); - } - public AttributesAirTransmissionModel getAttributesAirTransmissionModel() { return attrAirTransmissionModel; } -- GitLab From fac16e4c9ae0bb867e673a4a27ea642bcc470f01 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 10:28:15 +0100 Subject: [PATCH 36/83] Create abstract class AttributesExposureModel: Move properties from AttributesAirTransmissionModel to AttributesExposureModel --- .../AttributesAirTransmissionModel.java | 34 ++++--------------- .../infection/AttributesExposureModel.java | 30 ++++++++++++++++ 2 files changed, 36 insertions(+), 28 deletions(-) create mode 100644 VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java diff --git a/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java index 958d7a0f5..863852949 100644 --- a/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java @@ -1,18 +1,11 @@ package org.vadere.state.attributes.models; import org.vadere.annotation.factories.attributes.ModelAttributeClass; -import org.vadere.state.attributes.Attributes; - -import java.util.ArrayList; -import java.util.Arrays; import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModelAerosolCloud; import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModelDroplets; -import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; -import org.vadere.state.health.AirTransmissionModelHealthStatus; -import org.vadere.state.scenario.AerosolCloud; -import org.vadere.state.scenario.Droplets; -import org.vadere.state.scenario.Pedestrian; +import org.vadere.state.attributes.models.infection.AttributesExposureModel; +import org.vadere.state.scenario.*; /** * This class defines the attributes of the corresponding exposure model. All attributes are defined by the user and @@ -25,15 +18,7 @@ import org.vadere.state.scenario.Pedestrian; * */ @ModelAttributeClass -public class AttributesAirTransmissionModel extends Attributes { - - private ArrayList exposureModelSourceParameters; - - /** - * Contains the Ids of pedestrians that are directly set into the topography (and not spawned by sources). - * Any agent contained in the list is infectious. All others (not spawned by sources) are not infectious. - */ - private ArrayList infectiousPedestrianIdsNoSource; +public class AttributesAirTransmissionModel extends AttributesExposureModel { /** * Attribute related to the pedestrians' health state that is shared among all pedestrians. It is not defined @@ -46,6 +31,8 @@ public class AttributesAirTransmissionModel extends Attributes { * Defines whether aerosol clouds are considered in the exposure model (true) or not (false). */ private boolean aerosolCloudsActive; + + private AttributesAirTransmissionModelAerosolCloud aerosolCloudParameters; /** @@ -56,8 +43,7 @@ public class AttributesAirTransmissionModel extends Attributes { public AttributesAirTransmissionModel() { - this.exposureModelSourceParameters = new ArrayList<>(Arrays.asList(new AttributesExposureModelSourceParameters())); - this.infectiousPedestrianIdsNoSource = new ArrayList<>(); + super(); this.pedestrianRespiratoryCyclePeriod = 4; @@ -74,14 +60,6 @@ public class AttributesAirTransmissionModel extends Attributes { return pedestrianRespiratoryCyclePeriod; } - public ArrayList getExposureModelSourceParameters() { - return exposureModelSourceParameters; - } - - public ArrayList getInfectiousPedestrianIdsNoSource() { - return infectiousPedestrianIdsNoSource; - } - public boolean isAerosolCloudsActive() { return aerosolCloudsActive; } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java new file mode 100644 index 000000000..346d193eb --- /dev/null +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java @@ -0,0 +1,30 @@ +package org.vadere.state.attributes.models.infection; + +import org.vadere.state.attributes.Attributes; + +import java.util.ArrayList; +import java.util.Arrays; + +public abstract class AttributesExposureModel extends Attributes { + + private ArrayList exposureModelSourceParameters; + + /** + * Contains the Ids of pedestrians that are directly set into the topography (and not spawned by sources). + * Any agent contained in the list is infectious. All others (not spawned by sources) are not infectious. + */ + private ArrayList infectiousPedestrianIdsNoSource; + + public AttributesExposureModel() { + this.exposureModelSourceParameters = new ArrayList<>(Arrays.asList(new AttributesExposureModelSourceParameters())); + this.infectiousPedestrianIdsNoSource = new ArrayList<>(); + } + + public ArrayList getExposureModelSourceParameters() { + return exposureModelSourceParameters; + } + + public ArrayList getInfectiousPedestrianIdsNoSource() { + return infectiousPedestrianIdsNoSource; + } +} -- GitLab From 9d0fc8b34cc51cd7724fdc52b3673423e4b08886 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 10:29:42 +0100 Subject: [PATCH 37/83] Minor changes; add comments --- .../AttributesAirTransmissionModel.java | 49 ++----------------- ...butesAirTransmissionModelAerosolCloud.java | 33 ++----------- ...ttributesAirTransmissionModelDroplets.java | 37 ++++---------- 3 files changed, 18 insertions(+), 101 deletions(-) diff --git a/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java index 863852949..bc4e41e54 100644 --- a/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java @@ -8,22 +8,15 @@ import org.vadere.state.attributes.models.infection.AttributesExposureModel; import org.vadere.state.scenario.*; /** - * This class defines the attributes of the corresponding exposure model. All attributes are defined by the user and - * relate to - *
    - *
  • the AirTransmissionModel: {@link #exposureModelSourceParameters}, {@link #pedestrianRespiratoryCyclePeriod}
  • - *
  • the {@link AirTransmissionModelHealthStatus} of the {@link Pedestrian}s
  • - *
  • the {@link AerosolCloud}s' initial attributes when they are created by the AirTransmissionModel
  • - *
  • the {@link Droplets}s' initial attributes when they are created by the AirTransmissionModel
  • - *
+ * Attributes related to the corresponding exposure model. They define properties of {@link Pedestrian}s, + * {@link AerosolCloud}s, and {@link Droplets} that are equal for all instances of each class. */ @ModelAttributeClass public class AttributesAirTransmissionModel extends AttributesExposureModel { /** - * Attribute related to the pedestrians' health state that is shared among all pedestrians. It is not defined - * for each instance of AirTransmissionModelHealthStatus separately to keep the AirTransmissionModelHealthStatus lean. - * pedestrianRespiratoryCyclePeriod equals 1/(pedestrians' average breathing rate) in seconds. + * Equals 1/(pedestrians' average breathing rate). + * Unit: seconds */ private double pedestrianRespiratoryCyclePeriod; @@ -115,38 +108,4 @@ public class AttributesAirTransmissionModel extends AttributesExposureModel { public double getDropletsAbsorptionRate() { return dropletParameters.getAbsorptionRate(); } - - // Setter - - public void setAerosolCloudsActive(boolean aerosolCloudsActive) { - this.aerosolCloudsActive = aerosolCloudsActive; - } - - public void setAerosolCloudHalfLife(double aerosolCloudHalfLife) { - this.aerosolCloudParameters.setHalfLife(aerosolCloudHalfLife); - } - - public void setAerosolCloudInitialRadius(double aerosolCloudInitialRadius) { - this.aerosolCloudParameters.setInitialRadius(aerosolCloudInitialRadius); - } - - public void setAerosolCloudInitialPathogenLoad(double aerosolCloudInitialPathogenLoad) { - this.aerosolCloudParameters.setInitialPathogenLoad(aerosolCloudInitialPathogenLoad); - } - - public void setAerosolCloudAirDispersionFactor(double aerosolCloudAirDispersionFactor) { - this.aerosolCloudParameters.setAirDispersionFactor(aerosolCloudAirDispersionFactor); - } - - public void setAerosolCloudPedestrianDispersionWeight(double aerosolCloudPedestrianDispersionWeight) { - this.aerosolCloudParameters.setPedestrianDispersionWeight(aerosolCloudPedestrianDispersionWeight); - } - - public void setAerosolCloudAbsorptionRate(double aerosolCloudAbsorptionRate) { - this.aerosolCloudParameters.setAbsorptionRate(aerosolCloudAbsorptionRate); - } - - public void setDropletsActive(boolean dropletsActive) { - this.dropletsActive = dropletsActive; - } } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java index 3617ecc5b..82bce7afb 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java @@ -2,12 +2,13 @@ package org.vadere.state.attributes.models.infection; import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.models.AttributesAirTransmissionModel; +import org.vadere.state.scenario.AerosolCloud; /** * Attributes related to aerosol clouds that are shared among all aerosol clouds. These are not defined for each - * instance of AerosolCloud separately to keep the AerosolCloud lean. - * The frequency of occurrence is not defined here because aerosolClouds (if considered in the model) are directly - * linked to the respiratory cycle defined in {@link AttributesAirTransmissionModel}. + * instance of {@link AerosolCloud} separately to keep the class lean. + * The frequency of occurrence is not defined here because {@link AerosolCloud}s (if considered in the exposure model) + * are directly linked to the respiratory cycle defined in {@link AttributesAirTransmissionModel}. */ public class AttributesAirTransmissionModelAerosolCloud extends Attributes { @@ -98,30 +99,4 @@ public class AttributesAirTransmissionModelAerosolCloud extends Attributes { public double getAbsorptionRate() { return absorptionRate; } - - // Setter - - public void setHalfLife(double halfLife) { - this.halfLife = halfLife; - } - - public void setInitialRadius(double initialRadius) { - this.initialRadius = initialRadius; - } - - public void setInitialPathogenLoad(double initialPathogenLoad) { - this.initialPathogenLoad = initialPathogenLoad; - } - - public void setAirDispersionFactor(double airDispersionFactor) { - this.airDispersionFactor = airDispersionFactor; - } - - public void setPedestrianDispersionWeight(double pedestrianDispersionWeight) { - this.pedestrianDispersionWeight = pedestrianDispersionWeight; - } - - public void setAbsorptionRate(double absorptionRate) { - this.absorptionRate = absorptionRate; - } } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java index 8f4d447de..9c8dad1fa 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java @@ -1,34 +1,42 @@ package org.vadere.state.attributes.models.infection; import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.scenario.AttributesDroplets; +import org.vadere.state.scenario.Droplets; /** * Attributes related to droplets that are shared among all droplets. These are not defined for each - * instance of Droplets separately to keep Droplets lean. + * instance of {@link Droplets} separately to keep the class lean. */ public class AttributesAirTransmissionModelDroplets extends Attributes { /** - * Unit: 1/second + * Describes how often {@link Droplets} are emitted by an infectious pedestrian. + * Unit: 1 / second */ private double emissionFrequency; /** + * Describes the shape of {@link AttributesDroplets}: Radius of the circular segment. * Unit: meter */ private double distanceOfSpread; /** + * Describes the shape of {@link AttributesDroplets}: Angle of the circular segment. * Unit: degree */ private double angleOfSpreadInDeg; /** + * Describes the persistence of {@link Droplets}. * Unit: second */ private double lifeTime; /** + * Describes the pathogen load within {@link Droplets}. It remains constant over + * {@link #lifeTime}. * Unit: particles */ private double pathogenLoad; @@ -72,29 +80,4 @@ public class AttributesAirTransmissionModelDroplets extends Attributes { public double getAbsorptionRate() { return absorptionRate; } - - public void setEmissionFrequency(double emissionFrequency) { - this.emissionFrequency = emissionFrequency; - } - - public void setDistanceOfSpread(double distanceOfSpread) { - this.distanceOfSpread = distanceOfSpread; - } - - public void setAngleOfSpreadInDeg(double angleOfSpreadInDeg) { - this.angleOfSpreadInDeg = angleOfSpreadInDeg; - } - - public void setLifeTime(double lifeTime) { - this.lifeTime = lifeTime; - } - - public void setPathogenLoad(double pathogenLoad) { - this.pathogenLoad = pathogenLoad; - } - - public void setAbsorptionRate(double absorptionRate) { - this.absorptionRate = absorptionRate; - } - } -- GitLab From a0e52e8c7fc8b06b5ce82d1339b33121cc37e479 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 13:02:40 +0100 Subject: [PATCH 38/83] Rename scenario --- .../{queueScenario_publication.scenario => queue.scenario} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename Scenarios/Demos/AirTransmissionModel/examples/scenarios/{queueScenario_publication.scenario => queue.scenario} (98%) diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queueScenario_publication.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario similarity index 98% rename from Scenarios/Demos/AirTransmissionModel/examples/scenarios/queueScenario_publication.scenario rename to Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario index 3d9be7fc9..6bddb3b0d 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queueScenario_publication.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario @@ -1,8 +1,8 @@ { - "name" : "queueScenario_publication", + "name" : "queue", "description" : "", "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", + "commithash" : "9d0fc8b34cc51cd7724fdc52b3673423e4b08886", "processWriters" : { "files" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", @@ -143,7 +143,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : 1, "infectious" : false -- GitLab From e2a85a2de744c6e9dbdce7e48a1b8514318232a6 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 13:06:20 +0100 Subject: [PATCH 39/83] Move AttributesAirTransmissionModel to org.vadere.state.attributes.models.infection --- .../examples/scenarios/bottleneckA.scenario | 2 +- .../examples/scenarios/bottleneckB.scenario | 2 +- .../examples/scenarios/bottleneckB_socialDistancing.scenario | 2 +- .../examples/scenarios/closeContact.scenario | 2 +- .../AirTransmissionModel/examples/scenarios/passageway.scenario | 2 +- .../scenarios/hamner-2020-life_postvis_template.scenario | 2 +- .../validation/scenarios/hamner-2020-life_template.scenario | 2 +- .../validation/scenarios/lu-2020-life.scenario | 2 +- .../validation/scenarios/miller-2020-life_template.scenario | 2 +- .../vadere/simulator/models/infection/AirTransmissionModel.java | 2 +- .../simulator/models/infection/AirTransmissionModelTest.java | 2 +- .../models/{ => infection}/AttributesAirTransmissionModel.java | 2 +- .../infection/AttributesAirTransmissionModelAerosolCloud.java | 1 - .../state/attributes/scenario/AttributesAerosolCloud.java | 2 +- 14 files changed, 13 insertions(+), 14 deletions(-) rename VadereState/src/org/vadere/state/attributes/models/{ => infection}/AttributesAirTransmissionModel.java (98%) diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario index 83312fb05..fa6ede277 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario @@ -95,7 +95,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : 3, "infectious" : false diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario index 76b766fbf..278974950 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario @@ -120,7 +120,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : 3, "infectious" : false diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario index 60ed1565c..16df1682d 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario @@ -120,7 +120,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : 3, "infectious" : false diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario index 431590cba..85f044820 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario @@ -125,7 +125,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : 15, "infectious" : false diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario index fdcaaf436..0b1676efc 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario @@ -95,7 +95,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false diff --git a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario index 0b50acccd..a0cb08f3a 100644 --- a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario +++ b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario @@ -110,7 +110,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false diff --git a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario index 6b0e49da8..71f71849c 100644 --- a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario +++ b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario @@ -68,7 +68,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false diff --git a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/lu-2020-life.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/lu-2020-life.scenario index 0ac2504a5..42299f75d 100644 --- a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/lu-2020-life.scenario +++ b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/lu-2020-life.scenario @@ -95,7 +95,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false diff --git a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario index 0c3a4245c..25734cead 100644 --- a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario +++ b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario @@ -75,7 +75,7 @@ "height" : 1.0 } }, - "org.vadere.state.attributes.models.AttributesAirTransmissionModel" : { + "org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel" : { "exposureModelSourceParameters" : [ { "sourceId" : -1, "infectious" : false diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index e811ff6bc..d5294cb64 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -8,7 +8,7 @@ import org.vadere.simulator.control.simulation.ControllerProvider; import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; -import org.vadere.state.attributes.models.AttributesAirTransmissionModel; +import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel; import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java index b6098162a..015f6b1a0 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import org.vadere.simulator.context.VadereContext; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; -import org.vadere.state.attributes.models.AttributesAirTransmissionModel; +import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesTarget; diff --git a/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java similarity index 98% rename from VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java rename to VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java index bc4e41e54..ec10d84f7 100644 --- a/VadereState/src/org/vadere/state/attributes/models/AttributesAirTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java @@ -1,4 +1,4 @@ -package org.vadere.state.attributes.models; +package org.vadere.state.attributes.models.infection; import org.vadere.annotation.factories.attributes.ModelAttributeClass; diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java index 82bce7afb..6494703fc 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java @@ -1,7 +1,6 @@ package org.vadere.state.attributes.models.infection; import org.vadere.state.attributes.Attributes; -import org.vadere.state.attributes.models.AttributesAirTransmissionModel; import org.vadere.state.scenario.AerosolCloud; /** diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java index 97270269f..a6e609aea 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java @@ -1,6 +1,6 @@ package org.vadere.state.attributes.scenario; -import org.vadere.state.attributes.models.AttributesAirTransmissionModel; +import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel; import org.vadere.state.scenario.AerosolCloud; import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VShape; -- GitLab From f7ec0b9e854e9fd67cf1e5ad8c87511b6a129a45 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 13:07:16 +0100 Subject: [PATCH 40/83] Add ProximityExposureModel --- .../infection/ProximityExposureModel.java | 58 ++++++++++++++++--- .../AttributesProximityExposureModel.java | 23 ++++++++ .../ProximityExposureModelHealthStatus.java | 8 +++ 3 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 VadereState/src/org/vadere/state/attributes/models/infection/AttributesProximityExposureModel.java create mode 100644 VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java index d3e8e98a6..eda2592e8 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java @@ -2,10 +2,17 @@ package org.vadere.simulator.models.infection; import org.jetbrains.annotations.NotNull; import org.vadere.annotation.factories.models.ModelClass; +import org.vadere.simulator.control.scenarioelements.SourceController; +import org.vadere.simulator.control.scenarioelements.TopographyController; import org.vadere.simulator.control.simulation.ControllerProvider; +import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; +import org.vadere.state.attributes.models.infection.AttributesProximityExposureModel; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.ProximityExposureModelHealthStatus; +import org.vadere.state.scenario.Agent; import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Topography; import org.vadere.util.geometry.shapes.VCircle; @@ -32,22 +39,23 @@ public class ProximityExposureModel extends AbstractExposureModel { Topography topography; - //TODO replace radius by AttributesProximityExposureModel attributesProximityExposureModel; - private double radius; + AttributesProximityExposureModel attributesProximityExposureModel; @Override public void initialize(List attributesList, Domain domain, AttributesAgent attributesPedestrian, Random random) { this.domain = domain; this.random = random; this.attributesAgent = attributesPedestrian; - this.radius = 0.5; - // this.attributesProximityExposureModel = Model.findAttributes(attributesList, AttributesProximityExposureModel.class); + this.attributesProximityExposureModel = Model.findAttributes(attributesList, AttributesProximityExposureModel.class); this.topography = domain.getTopography(); } @Override public void registerToScenarioElementControllerEvents(ControllerProvider controllerProvider) { - super.registerToScenarioElementControllerEvents(controllerProvider); + for (var controller : controllerProvider.getSourceControllers()){ + controller.register(this::sourceControllerEvent); + } + controllerProvider.getTopographyController().register(this::topographyControllerEvent); } @Override @@ -83,18 +91,50 @@ public class ProximityExposureModel extends AbstractExposureModel { @NotNull private Collection getPedestriansNearbyInfectiousPedestrian(Collection pedestrians, Pedestrian infectiousPedestrian) { VPoint position = infectiousPedestrian.getPosition(); - VShape areaOfExposure = new VCircle(position, radius); + VShape areaOfExposure = new VCircle(position, attributesProximityExposureModel.getExposureRadius()); Collection exposedPedestrians = pedestrians .stream() - .filter(p -> areaOfExposure.contains(p.getPosition())).collect(Collectors.toSet()); + .filter(p -> (areaOfExposure.contains(p.getPosition())) && p.getDegreeOfExposure() < MAX_DEG_OF_EXPOSURE).collect(Collectors.toSet()); return exposedPedestrians; } + /** + * This simple approach allows only 0 or {@link #MAX_DEG_OF_EXPOSURE}. The degree of exposure is increased only + * once. + */ @Override public void updatePedestrianDegreeOfExposure(Pedestrian pedestrian, double degreeOfExposure) { - //TODO create method in Pedestrian - // pedestrian.incrementDegreeOfExposure(degreeOfExposure); + pedestrian.setDegreeOfExposure(degreeOfExposure); + } + + public Agent sourceControllerEvent(SourceController controller, double simTimeInSec, Agent scenarioElement) { + // SourceControllerListener. This will be called *after* a pedestrian is inserted into the + // topography by the given SourceController. Change model state on Agent here + AttributesExposureModelSourceParameters sourceParameters = defineSourceParameters(controller, attributesProximityExposureModel); + + Pedestrian ped = (Pedestrian) scenarioElement; + ped.setHealthStatus(new ProximityExposureModelHealthStatus()); + ped.setInfectious(sourceParameters.isInfectious()); + + logger.infof(">>>>>>>>>>>sourceControllerEvent at time: %f agentId: %d", simTimeInSec, scenarioElement.getId()); + return ped; + } + + /* + * The TopographyController assures that each pedestrian that is directly set into the topography obtains a health + * status. + */ + private Pedestrian topographyControllerEvent(TopographyController topographyController, double simTimeInSec, Agent agent) { + Pedestrian pedestrian = (Pedestrian) agent; + + pedestrian.setHealthStatus(new ProximityExposureModelHealthStatus()); + + if (attributesProximityExposureModel.getInfectiousPedestrianIdsNoSource().contains(agent.getId())) { + pedestrian.setInfectious(true); + } + + return pedestrian; } } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesProximityExposureModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesProximityExposureModel.java new file mode 100644 index 000000000..f1f2c1660 --- /dev/null +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesProximityExposureModel.java @@ -0,0 +1,23 @@ +package org.vadere.state.attributes.models.infection; + + +import org.vadere.annotation.factories.attributes.ModelAttributeClass; + +@ModelAttributeClass +public class AttributesProximityExposureModel extends AttributesExposureModel { + + /** + * Within this radius around an infectious agent all other agents become exposed. + */ + private double exposureRadius; + + public AttributesProximityExposureModel() { + super(); + this.exposureRadius = 1; + } + + // Getter + public double getExposureRadius() { + return exposureRadius; + } +} diff --git a/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java new file mode 100644 index 000000000..4f51d27aa --- /dev/null +++ b/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java @@ -0,0 +1,8 @@ +package org.vadere.state.health; + +public class ProximityExposureModelHealthStatus extends ExposureModelHealthStatus { + + public ProximityExposureModelHealthStatus() { + super(); + } +} -- GitLab From 590466aa95fb8f298cfdde84ed8e78d8b97eab0b Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 16:05:20 +0100 Subject: [PATCH 41/83] Replace Interface DoseResponseModel by class AbstractDoseResponseModel --- .../infection/AbstractDoseResponseModel.java | 32 ++++++++++++++++++- .../models/infection/DoseResponseModel.java | 8 ----- 2 files changed, 31 insertions(+), 9 deletions(-) delete mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/DoseResponseModel.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java index 041657a27..089bf33e7 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java @@ -1,12 +1,19 @@ package org.vadere.simulator.models.infection; +import org.vadere.simulator.control.scenarioelements.SourceController; +import org.vadere.simulator.control.scenarioelements.TopographyController; +import org.vadere.simulator.control.simulation.ControllerProvider; +import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; +import org.vadere.state.attributes.models.infection.AttributesDoseResponseModel; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.scenario.Agent; +import org.vadere.state.scenario.Pedestrian; import org.vadere.util.logging.Logger; import java.util.Random; -public abstract class AbstractDoseResponseModel implements DoseResponseModel { +public abstract class AbstractDoseResponseModel implements Model { // add default implementations and shared fields here to keep ExposureModel interface clean @@ -17,4 +24,27 @@ public abstract class AbstractDoseResponseModel implements DoseResponseModel { protected Domain domain; protected AttributesAgent attributesAgent; + /* + * This will be called *after* a pedestrian is inserted into the topography by the given SourceController. + * Change model state on Agent here + */ + @Override + public void registerToScenarioElementControllerEvents(ControllerProvider controllerProvider) { + for (var controller : controllerProvider.getSourceControllers()){ + controller.register(this::sourceControllerEvent); + } + controllerProvider.getTopographyController().register(this::topographyControllerEvent); + } + + /** + * Assures that each pedestrian that is spawned by sources obtains properties related to + * {@link AttributesDoseResponseModel} when pedestrian is added to topography. + */ + protected abstract Agent sourceControllerEvent(SourceController controller, double simTimeInSec, Agent scenarioElement); + + /** + * Assures that each pedestrian that is directly set into the topography obtains properties + * related to {@link AttributesDoseResponseModel}. + */ + protected abstract Pedestrian topographyControllerEvent(TopographyController topographyController, double simTimeInSec, Agent agent); } diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/DoseResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/DoseResponseModel.java deleted file mode 100644 index c9d699d3c..000000000 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/DoseResponseModel.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.vadere.simulator.models.infection; - -import org.vadere.simulator.models.Model; - -public interface DoseResponseModel extends Model { - // any methods **ALL** DoseResponseModel have in common. - -} -- GitLab From ce256064b5fc1bf7d24eb44e6710e8a9d8417aa1 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 16:11:11 +0100 Subject: [PATCH 42/83] Add infection status to Pedestrian: The infection status is defined in ThresholdResponseModelInfectionStatus and DoseResponseModelInfectionStatus. --- .../DoseResponseModelInfectionStatus.java | 31 ++++++++++++++-- ...ThresholdResponseModelInfectionStatus.java | 35 ++----------------- .../org/vadere/state/scenario/Pedestrian.java | 8 ++++- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java b/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java index 6c58ad860..26da44025 100644 --- a/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java +++ b/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java @@ -1,9 +1,34 @@ package org.vadere.state.health; -public interface DoseResponseModelInfectionStatus { +public abstract class DoseResponseModelInfectionStatus { + + /* + * Probability of infection; depending on the dose response model, it ranges in [0, 1] or {0, 1}. + */ + private double probabilityOfInfection; + + private static final double MIN_PROBABILITY_INFECTION = 0; + private static final double MAX_PROBABILITY_INFECTION = 1; + + DoseResponseModelInfectionStatus() { + this.probabilityOfInfection = MIN_PROBABILITY_INFECTION; + } + // Getter - double getProbabilityOfInfection(); + public double getProbabilityOfInfection() { + return probabilityOfInfection; + } // Setter - void setProbabilityOfInfection(double probabilityOfInfection); + public void setProbabilityOfInfection(double probabilityOfInfection) { + if(probabilityOfInfection < MIN_PROBABILITY_INFECTION || probabilityOfInfection > MAX_PROBABILITY_INFECTION) { + throw new IllegalArgumentException(); + } else { + this.probabilityOfInfection = probabilityOfInfection; + } + } + + public void setProbabilityOfInfectionToMax() { + this.probabilityOfInfection = MAX_PROBABILITY_INFECTION; + } } diff --git a/VadereState/src/org/vadere/state/health/ThresholdResponseModelInfectionStatus.java b/VadereState/src/org/vadere/state/health/ThresholdResponseModelInfectionStatus.java index 6061591d9..dfa83a9a1 100644 --- a/VadereState/src/org/vadere/state/health/ThresholdResponseModelInfectionStatus.java +++ b/VadereState/src/org/vadere/state/health/ThresholdResponseModelInfectionStatus.java @@ -1,40 +1,9 @@ package org.vadere.state.health; -/** - * Defines a pedestrian's infection status by means of a probability of infection. - */ -public class ThresholdResponseModelInfectionStatus implements DoseResponseModelInfectionStatus { - - private double probabilityOfInfection; - - /* - * default for pedestrian's probability of infection, when pedestrian has not been exposed yet - */ - private static final double DEF_PROBABILITY_OF_INFECTION = 0; - +public class ThresholdResponseModelInfectionStatus extends DoseResponseModelInfectionStatus { // Constructors - public ThresholdResponseModelInfectionStatus(double probabilityOfInfection) { - this.probabilityOfInfection = probabilityOfInfection; - } - - public ThresholdResponseModelInfectionStatus(ThresholdResponseModelInfectionStatus other) { - this.probabilityOfInfection = other.getProbabilityOfInfection(); - } - public ThresholdResponseModelInfectionStatus() { - this(DEF_PROBABILITY_OF_INFECTION); - } - - // Getter - @Override - public double getProbabilityOfInfection() { - return probabilityOfInfection; - } - - // Setter - @Override - public void setProbabilityOfInfection(double probabilityOfInfection) { - this.probabilityOfInfection = probabilityOfInfection; + super(); } } diff --git a/VadereState/src/org/vadere/state/scenario/Pedestrian.java b/VadereState/src/org/vadere/state/scenario/Pedestrian.java index bc269d0b5..fbe3bb064 100644 --- a/VadereState/src/org/vadere/state/scenario/Pedestrian.java +++ b/VadereState/src/org/vadere/state/scenario/Pedestrian.java @@ -179,6 +179,10 @@ public class Pedestrian extends Agent { return (T) healthStatus; } + public T getInfectionStatus() { + return (T) infectionStatus; + } + public boolean isInfectious() { return healthStatus.isInfectious(); } @@ -291,7 +295,9 @@ public class Pedestrian extends Agent { infectionStatus.setProbabilityOfInfection(probabilityOfInfection); } - + public void setProbabilityOfInfectionToMax() { + infectionStatus.setProbabilityOfInfectionToMax(); + } // Methods public boolean isTarget() { -- GitLab From 793b00159b5cc27de10d369c8dd49912c68bac64 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 16:20:55 +0100 Subject: [PATCH 43/83] Add ThresholdResponseModel --- .../infection/AbstractDoseResponseModel.java | 2 - .../infection/ThresholdResponseModel.java | 56 +++++++++++++++---- .../AttributesDoseResponseModel.java | 8 +++ .../AttributesThresholdResponseModel.java | 22 ++++++++ 4 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 VadereState/src/org/vadere/state/attributes/models/infection/AttributesDoseResponseModel.java create mode 100644 VadereState/src/org/vadere/state/attributes/models/infection/AttributesThresholdResponseModel.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java index 089bf33e7..de21eb6c0 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java @@ -15,8 +15,6 @@ import java.util.Random; public abstract class AbstractDoseResponseModel implements Model { - // add default implementations and shared fields here to keep ExposureModel interface clean - protected static Logger logger = Logger.getLogger(AbstractDoseResponseModel.class); // this random provider everywhere to keep simulation reproducible diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java index ae4657ac8..7b0ae2391 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java @@ -1,22 +1,33 @@ package org.vadere.simulator.models.infection; +import org.vadere.annotation.factories.models.ModelClass; +import org.vadere.simulator.control.scenarioelements.SourceController; +import org.vadere.simulator.control.scenarioelements.TopographyController; +import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.exceptions.AttributesNotFoundException; +import org.vadere.state.attributes.models.infection.AttributesExposureModel; +import org.vadere.state.attributes.models.infection.AttributesThresholdResponseModel; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.ThresholdResponseModelInfectionStatus; +import org.vadere.state.scenario.Agent; import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Topography; import java.util.Collection; import java.util.List; import java.util.Random; +import java.util.Set; import java.util.stream.Collectors; + +@ModelClass public class ThresholdResponseModel extends AbstractDoseResponseModel { Topography topography; - private double threshold; - //TODO replace threshold by private AttributesThresholdInfectionModel attributesThresholdInfectionModel; + private AttributesThresholdResponseModel attributesThresholdResponseModel; @Override @@ -25,31 +36,56 @@ public class ThresholdResponseModel extends AbstractDoseResponseModel { this.random = random; this.topography = domain.getTopography(); this.attributesAgent = attributesPedestrian; + this.attributesThresholdResponseModel = Model.findAttributes(attributesList, AttributesThresholdResponseModel.class); + + checkIfExposureModelDefined(attributesList); + } - // this.attributesThresholdInfectionModel = Model.findAttributes(attributesList, AttributesThresholdInfectionModel.class); - this.threshold = 999; // + /* + * Check prerequisite for dose response model: Is exposure model defined? Throw error otherwise. + */ + private void checkIfExposureModelDefined(List attributesList) throws AttributesNotFoundException { + Set result = attributesList.stream().filter(a -> AttributesExposureModel.class.isAssignableFrom(a.getClass())).collect(Collectors.toSet()); + if (result.size() < 1) { + throw new RuntimeException(this.getClass() + " requires any exposure model defined by " + AttributesExposureModel.class); + } } @Override public void preLoop(double simTimeInSec) { - } @Override public void postLoop(double simTimeInSec) { - //TODO check if this works in postLoop + } + + @Override + public void update(double simTimeInSec) { + + /* + * Here we update the infection status at each simulation step. This could also be done once at the end of the + * simulation. However, this solution is useful if one wants to know when/where the threshold is exceeded. + */ Collection exposedPedestrians = topography.getPedestrianDynamicElements() .getElements() .stream() - .filter(pedestrian -> pedestrian.getDegreeOfExposure() > threshold).collect(Collectors.toSet()); - + .filter(pedestrian -> pedestrian.getDegreeOfExposure() >= attributesThresholdResponseModel.getExposureToInfectedThreshold()).collect(Collectors.toSet()); for (Pedestrian pedestrian : exposedPedestrians) { - // pedestrian.setInfected(true); + pedestrian.setProbabilityOfInfectionToMax(); } } @Override - public void update(double simTimeInSec) { + public Agent sourceControllerEvent(SourceController controller, double simTimeInSec, Agent scenarioElement) { + Pedestrian ped = (Pedestrian) scenarioElement; + ped.setInfectionStatus(new ThresholdResponseModelInfectionStatus()); + return ped; + } + @Override + protected Pedestrian topographyControllerEvent(TopographyController topographyController, double simTimeInSec, Agent agent) { + Pedestrian pedestrian = (Pedestrian) agent; + pedestrian.setInfectionStatus(new ThresholdResponseModelInfectionStatus()); + return pedestrian; } } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesDoseResponseModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesDoseResponseModel.java new file mode 100644 index 000000000..7deab65b5 --- /dev/null +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesDoseResponseModel.java @@ -0,0 +1,8 @@ +package org.vadere.state.attributes.models.infection; + +import org.vadere.state.attributes.Attributes; + +public abstract class AttributesDoseResponseModel extends Attributes { + + +} diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesThresholdResponseModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesThresholdResponseModel.java new file mode 100644 index 000000000..c5d73951b --- /dev/null +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesThresholdResponseModel.java @@ -0,0 +1,22 @@ +package org.vadere.state.attributes.models.infection; + +import org.vadere.annotation.factories.attributes.ModelAttributeClass; + + + +@ModelAttributeClass +public class AttributesThresholdResponseModel extends AttributesDoseResponseModel { + + /** + * Degree of exposure at which a pedestrian's probability of infection changes from 0 to 1. + */ + private double exposureToInfectedThreshold; + + public AttributesThresholdResponseModel() { + this.exposureToInfectedThreshold = 1; + } + + public double getExposureToInfectedThreshold() { + return exposureToInfectedThreshold; + } +} -- GitLab From 31a2135d9cf2e5c9febb991c756eb78b12840948 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 16:40:26 +0100 Subject: [PATCH 44/83] Minor changes, extract abstract methods. --- .../infection/AbstractDoseResponseModel.java | 12 +++--- .../infection/AbstractExposureModel.java | 39 +++++++++++++++++-- .../infection/AirTransmissionModel.java | 21 ++-------- .../infection/ProximityExposureModel.java | 21 ++-------- .../infection/ThresholdResponseModel.java | 2 +- 5 files changed, 50 insertions(+), 45 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java index de21eb6c0..d387e641c 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java @@ -22,15 +22,17 @@ public abstract class AbstractDoseResponseModel implements Model { protected Domain domain; protected AttributesAgent attributesAgent; - /* - * This will be called *after* a pedestrian is inserted into the topography by the given SourceController. - * Change model state on Agent here - */ - @Override + @Override public void registerToScenarioElementControllerEvents(ControllerProvider controllerProvider) { + /* + * This will be called *after* a pedestrian is inserted into the topography by the given SourceController. + * Change model state on Agent here. + * ControllerProvider could also be handled by initialize method (this requires changes in all models) + */ for (var controller : controllerProvider.getSourceControllers()){ controller.register(this::sourceControllerEvent); } + controllerProvider.getTopographyController().register(this::topographyControllerEvent); } diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java index 8631202c4..bd5bade63 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java @@ -1,18 +1,21 @@ package org.vadere.simulator.models.infection; import org.vadere.simulator.control.scenarioelements.SourceController; +import org.vadere.simulator.control.scenarioelements.TopographyController; +import org.vadere.simulator.control.simulation.ControllerProvider; +import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.models.infection.AttributesExposureModel; import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.scenario.Agent; +import org.vadere.state.scenario.Pedestrian; import org.vadere.util.logging.Logger; import java.util.Optional; import java.util.Random; -public abstract class AbstractExposureModel implements ExposureModel { - - // add default implementations and shared fields here to keep ExposureModel interface clean +public abstract class AbstractExposureModel implements Model { protected static Logger logger = Logger.getLogger(AbstractExposureModel.class); @@ -21,6 +24,24 @@ public abstract class AbstractExposureModel implements ExposureModel { protected Domain domain; protected AttributesAgent attributesAgent; + + abstract void updatePedestrianDegreeOfExposure(final Pedestrian pedestrian, double degreeOfExposure); + + @Override + public void registerToScenarioElementControllerEvents(ControllerProvider controllerProvider) { + /* + * This will be called *after* a pedestrian is inserted into the topography by the given SourceController. + * Change model state on Agent here. + * ControllerProvider could also be handled by initialize method (this requires changes in all models) + */ + for (var controller : controllerProvider.getSourceControllers()){ + controller.register(this::sourceControllerEvent); + } + + controllerProvider.getTopographyController().register(this::topographyControllerEvent); + } + + public AttributesExposureModelSourceParameters defineSourceParameters(SourceController controller, AttributesExposureModel attributes) { int sourceId = controller.getSourceId(); int defaultSourceId = -1; @@ -41,4 +62,16 @@ public abstract class AbstractExposureModel implements ExposureModel { return sourceParameters.get(); } + /** + * Assures that each pedestrian that is spawned by sources obtains properties related to + * {@link AttributesExposureModel} when pedestrian is added to topography. + */ + protected abstract Agent sourceControllerEvent(SourceController controller, double simTimeInSec, Agent scenarioElement); + + + /** + * Assures that each pedestrian that is directly set into the topography obtains properties + * related to {@link AttributesExposureModel}. + */ + protected abstract Pedestrian topographyControllerEvent(TopographyController topographyController, double simtimeInSec, Agent agent); } diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index d5294cb64..15f8fdc1e 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -83,15 +83,6 @@ public class AirTransmissionModel extends AbstractExposureModel { this.lastPedestrianPositions = new HashMap<>(); } - @Override - public void registerToScenarioElementControllerEvents(ControllerProvider controllerProvider) { - // ToDo: controllerProvider could be handled by initialize method (this requires changes in all models) - for (var controller : controllerProvider.getSourceControllers()){ - controller.register(this::sourceControllerEvent); - } - controllerProvider.getTopographyController().register(this::topographyControllerEvent); - } - @Override public void preLoop(double simTimeInSec) {} @@ -361,9 +352,8 @@ public class AirTransmissionModel extends AbstractExposureModel { .collect(Collectors.toSet()); } + @Override public Agent sourceControllerEvent(SourceController controller, double simTimeInSec, Agent scenarioElement) { - // SourceControllerListener. This will be called *after* a pedestrian is inserted into the - // topography by the given SourceController. Change model state on Agent here AttributesExposureModelSourceParameters sourceParameters = defineSourceParameters(controller, attrAirTransmissionModel); Pedestrian ped = (Pedestrian) scenarioElement; @@ -371,16 +361,11 @@ public class AirTransmissionModel extends AbstractExposureModel { ped.setInfectious(sourceParameters.isInfectious()); ped.getHealthStatus().setRespiratoryTimeOffset(random.nextDouble() * attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod()); ped.getHealthStatus().setBreathingIn(false); - - logger.infof(">>>>>>>>>>>sourceControllerEvent at time: %f agentId: %d", simTimeInSec, scenarioElement.getId()); return ped; } - /* - * The TopographyController assures that each pedestrian that is directly set into the topography obtains a health - * status. - */ - private Pedestrian topographyControllerEvent(TopographyController topographyController, double simtimeInSec, Agent agent) { + @Override + public Pedestrian topographyControllerEvent(TopographyController topographyController, double simtimeInSec, Agent agent) { Pedestrian pedestrian = (Pedestrian) agent; AirTransmissionModelHealthStatus defaultHealthStatus = new AirTransmissionModelHealthStatus(); diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java index eda2592e8..620a23d44 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java @@ -4,7 +4,6 @@ import org.jetbrains.annotations.NotNull; import org.vadere.annotation.factories.models.ModelClass; import org.vadere.simulator.control.scenarioelements.SourceController; import org.vadere.simulator.control.scenarioelements.TopographyController; -import org.vadere.simulator.control.simulation.ControllerProvider; import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; @@ -50,14 +49,6 @@ public class ProximityExposureModel extends AbstractExposureModel { this.topography = domain.getTopography(); } - @Override - public void registerToScenarioElementControllerEvents(ControllerProvider controllerProvider) { - for (var controller : controllerProvider.getSourceControllers()){ - controller.register(this::sourceControllerEvent); - } - controllerProvider.getTopographyController().register(this::topographyControllerEvent); - } - @Override public void preLoop(double simTimeInSec) { @@ -108,24 +99,18 @@ public class ProximityExposureModel extends AbstractExposureModel { pedestrian.setDegreeOfExposure(degreeOfExposure); } + @Override public Agent sourceControllerEvent(SourceController controller, double simTimeInSec, Agent scenarioElement) { - // SourceControllerListener. This will be called *after* a pedestrian is inserted into the - // topography by the given SourceController. Change model state on Agent here AttributesExposureModelSourceParameters sourceParameters = defineSourceParameters(controller, attributesProximityExposureModel); Pedestrian ped = (Pedestrian) scenarioElement; ped.setHealthStatus(new ProximityExposureModelHealthStatus()); ped.setInfectious(sourceParameters.isInfectious()); - - logger.infof(">>>>>>>>>>>sourceControllerEvent at time: %f agentId: %d", simTimeInSec, scenarioElement.getId()); return ped; } - /* - * The TopographyController assures that each pedestrian that is directly set into the topography obtains a health - * status. - */ - private Pedestrian topographyControllerEvent(TopographyController topographyController, double simTimeInSec, Agent agent) { + @Override + public Pedestrian topographyControllerEvent(TopographyController topographyController, double simTimeInSec, Agent agent) { Pedestrian pedestrian = (Pedestrian) agent; pedestrian.setHealthStatus(new ProximityExposureModelHealthStatus()); diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java index 7b0ae2391..cae3255de 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java @@ -63,7 +63,7 @@ public class ThresholdResponseModel extends AbstractDoseResponseModel { public void update(double simTimeInSec) { /* - * Here we update the infection status at each simulation step. This could also be done once at the end of the + * Here, we update the infection status at each simulation step. This could also be done once at the end of the * simulation. However, this solution is useful if one wants to know when/where the threshold is exceeded. */ Collection exposedPedestrians = topography.getPedestrianDynamicElements() -- GitLab From 40d400b9fd9735ff90bd2288c73bfae8c0df7229 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 24 Feb 2022 16:40:50 +0100 Subject: [PATCH 45/83] Remove unnecessary interface ExposureModel --- .../simulator/models/infection/ExposureModel.java | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java deleted file mode 100644 index d3982330c..000000000 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ExposureModel.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.vadere.simulator.models.infection; - -import org.vadere.simulator.models.Model; -import org.vadere.state.scenario.Pedestrian; - -public interface ExposureModel extends Model { - - - /** - * This method updates the degree of exposure of a pedestrian. - */ - void updatePedestrianDegreeOfExposure(final Pedestrian pedestrian, double degreeOfExposure); -} -- GitLab From 3957ec7613276e2b0309cc8af952c7a50e51a8da Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 1 Mar 2022 10:37:50 +0100 Subject: [PATCH 46/83] Remove initialPathogenLoad from AttributesAerosolCloud initialPathogenLoad is already defined in AttributesAirTransmissionModelAerosolCloud --- .../infection/AirTransmissionModel.java | 6 ++---- .../infection/AirTransmissionModelTest.java | 6 +++--- .../scenario/AttributesAerosolCloud.java | 14 ++++++------- .../scenario/AttributesDroplets.java | 2 +- .../AttributesParticleDispersion.java | 21 +++---------------- .../vadere/state/scenario/AerosolCloud.java | 4 ---- .../state/scenario/AerosolCloudTest.java | 4 ++-- 7 files changed, 17 insertions(+), 40 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index 15f8fdc1e..7a81556e4 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -4,7 +4,6 @@ import org.vadere.annotation.factories.models.ModelClass; import org.vadere.simulator.context.VadereContext; import org.vadere.simulator.control.scenarioelements.SourceController; import org.vadere.simulator.control.scenarioelements.TopographyController; -import org.vadere.simulator.control.simulation.ControllerProvider; import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; @@ -64,7 +63,7 @@ public class AirTransmissionModel extends AbstractExposureModel { private static final double exponentialDecayFactor = Math.log(2.0); /** - * minimumPercentage defines a percentage of the initial pathogen concentration + * Defines a percentage of the initial pathogen concentration * (pathogenLoad / aerosolCloud.volume); As soon as an aerosolCloud has reached the minimum concentration, the * aerosolCloud is considered negligible and therefore deleted */ @@ -163,7 +162,6 @@ public class AirTransmissionModel extends AbstractExposureModel { attrAirTransmissionModel.getAerosolCloudInitialRadius(), center, simTimeInSec, - attrAirTransmissionModel.getAerosolCloudInitialPathogenLoad(), attrAirTransmissionModel.getAerosolCloudInitialPathogenLoad())); aerosolCloudIdCounter = aerosolCloudIdCounter + 1; @@ -216,7 +214,7 @@ public class AirTransmissionModel extends AbstractExposureModel { Collection allAerosolClouds = topography.getAerosolClouds(); for (AerosolCloud aerosolCloud : allAerosolClouds) { double t = simTimeInSec - aerosolCloud.getCreationTime(); - aerosolCloud.setCurrentPathogenLoad(aerosolCloud.getInitialPathogenLoad() * Math.exp(-lambda * t)); + aerosolCloud.setCurrentPathogenLoad(attrAirTransmissionModel.getAerosolCloudInitialPathogenLoad() * Math.exp(-lambda * t)); } } diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java index 015f6b1a0..a22d0d682 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java @@ -125,7 +125,7 @@ public class AirTransmissionModelTest { public void throwIfPedestrianInsideAerosolCloudNotDetected() { Topography topography = new Topography(); createPedestrian(topography, new VPoint(10, 10), 1, -1, false); - AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(new VCircle(new VPoint(10, 10), 1), 0.0)); + AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(Attributes.ID_NOT_SET, 1, new VPoint(10, 10), 0.0, 0)); topography.addAerosolCloud(aerosolCloud); boolean inAerosolCloud = isPedestrianInAerosolCloud(aerosolCloud, topography.getPedestrianDynamicElements().getElement(1)); @@ -136,7 +136,7 @@ public class AirTransmissionModelTest { public void throwIfPedestrianOutsideAerosolCloudConsideredInside() { Topography topography = new Topography(); createPedestrian(topography, new VPoint(5, 5), 1, -1, false); - AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(new VCircle(new VPoint(10, 10), 1), 0.0)); + AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(Attributes.ID_NOT_SET, 1, new VPoint(10, 10), 0.0, 0)); topography.addAerosolCloud(aerosolCloud); boolean inAerosolCloud = isPedestrianInAerosolCloud(aerosolCloud, topography.getPedestrianDynamicElements().getElement(1)); @@ -146,7 +146,7 @@ public class AirTransmissionModelTest { @Test public void testGetPedestriansInsideAerosolCloud() { Topography topography = new Topography(); - AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(new VCircle(new VPoint(10, 10), 1), 0.0)); + AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(Attributes.ID_NOT_SET, 1, new VPoint(10, 10), 0.0, 0)); aerosolCloud.setId(1); topography.addAerosolCloud(aerosolCloud); // pedestrians outside cloud diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java index a6e609aea..e5c47c079 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java @@ -20,16 +20,14 @@ public class AttributesAerosolCloud extends AttributesParticleDispersion { this.center = new VPoint(); } - public AttributesAerosolCloud(VShape shape, double creationTime){ - super(creationTime, shape); - } - - public AttributesAerosolCloud(int id, double radius, VPoint center, double currentPathogenLoad){ - super(id, AerosolCloud.createAerosolCloudShape(center, radius), currentPathogenLoad); + public AttributesAerosolCloud(int id, double radius, VPoint center, double currentPathogenLoad) { + super(id, currentPathogenLoad, AerosolCloud.createAerosolCloudShape(center, radius)); + this.radius = radius; + this.center = center; } - public AttributesAerosolCloud(int id, double radius, VPoint center, double creationTime, double initialPathogenLoad, double currentPathogenLoad) { - super(id, creationTime, initialPathogenLoad, currentPathogenLoad, AerosolCloud.createAerosolCloudShape(center, radius)); + public AttributesAerosolCloud(int id, double radius, VPoint center, double creationTime, double currentPathogenLoad) { + super(id, creationTime, currentPathogenLoad, AerosolCloud.createAerosolCloudShape(center, radius)); this.radius = radius; this.center = center; } diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java index d095e4adc..9dafecb87 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java @@ -18,6 +18,6 @@ public class AttributesDroplets extends AttributesParticleDispersion { public AttributesDroplets(int id, VShape shape, double creationTime, double initialPathogenLoad) { - super(id, creationTime, initialPathogenLoad, initialPathogenLoad, shape); + super(id, creationTime, initialPathogenLoad, shape); } } diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesParticleDispersion.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesParticleDispersion.java index 9f2076fb8..005c45a11 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesParticleDispersion.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesParticleDispersion.java @@ -11,14 +11,12 @@ public abstract class AttributesParticleDispersion extends AttributesEmbedShape private int id; private double creationTime; - private double initialPathogenLoad; private double currentPathogenLoad; private VShape shape; public AttributesParticleDispersion() { this.id = AttributesEmbedShape.ID_NOT_SET; this.creationTime = -1; - this.initialPathogenLoad = -1; this.currentPathogenLoad = -1; Path2D path = new Path2D.Double(); @@ -26,24 +24,16 @@ public abstract class AttributesParticleDispersion extends AttributesEmbedShape this.shape = new VPolygon(path); } - public AttributesParticleDispersion(double creationTime, VShape shape){ - this(); - this.creationTime = creationTime; - this.shape = shape; - } - - public AttributesParticleDispersion(int id, VShape shape, double currentPathogenLoad){ + public AttributesParticleDispersion(int id, double currentPathogenLoad, VShape shape) { this(); this.id = id; - this.shape = shape; this.currentPathogenLoad = currentPathogenLoad; + this.shape = shape; } - public AttributesParticleDispersion(int id, double creationTime, double initialPathogenLoad, double currentPathogenLoad, VShape shape) { + public AttributesParticleDispersion(int id, double creationTime, double currentPathogenLoad, VShape shape) { this.id = id; - this.creationTime = creationTime; - this.initialPathogenLoad = initialPathogenLoad; this.currentPathogenLoad = currentPathogenLoad; this.shape = shape; } @@ -54,11 +44,6 @@ public abstract class AttributesParticleDispersion extends AttributesEmbedShape return creationTime; } - - public double getInitialPathogenLoad() { - return initialPathogenLoad; - } - public double getCurrentPathogenLoad() { return currentPathogenLoad; } diff --git a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java index 47e153784..a327e5285 100644 --- a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java +++ b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java @@ -85,10 +85,6 @@ public class AerosolCloud extends InfectiousParticleDispersion { return attributes.getCreationTime(); } - public double getInitialPathogenLoad() { - return attributes.getInitialPathogenLoad(); - } - public double getCurrentPathogenLoad() { return attributes.getCurrentPathogenLoad(); } diff --git a/VadereState/tests/org/vadere/state/scenario/AerosolCloudTest.java b/VadereState/tests/org/vadere/state/scenario/AerosolCloudTest.java index 15b5ae6db..d446c08b4 100644 --- a/VadereState/tests/org/vadere/state/scenario/AerosolCloudTest.java +++ b/VadereState/tests/org/vadere/state/scenario/AerosolCloudTest.java @@ -30,7 +30,7 @@ public class AerosolCloudTest { double creationTime = 0; double initialPathogenLoad = 10e4; - AttributesAerosolCloud attributesCirc = new AttributesAerosolCloud(id, radius, center, creationTime, initialPathogenLoad, initialPathogenLoad); + AttributesAerosolCloud attributesCirc = new AttributesAerosolCloud(id, radius, center, creationTime, initialPathogenLoad); aerosolCloudCirc = new AerosolCloud(attributesCirc); } @@ -63,7 +63,7 @@ public class AerosolCloudTest { double pathogenLoad = 10e9; double lifeTime = 60*60*3; - AerosolCloud aerosolCloudOriginal = new AerosolCloud(new AttributesAerosolCloud(id, radius, center, creationTime, pathogenLoad, pathogenLoad)); + AerosolCloud aerosolCloudOriginal = new AerosolCloud(new AttributesAerosolCloud(id, radius, center, creationTime, pathogenLoad)); AerosolCloud aerosolCloudClone = aerosolCloudOriginal.clone(); Assert.assertEquals(aerosolCloudOriginal.getId(), aerosolCloudClone.getId()); -- GitLab From 24fc644484b248dae16d12eb2b33cb7f583afe4c Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 1 Mar 2022 10:47:46 +0100 Subject: [PATCH 47/83] Rename InfectiousParticleDispersion to ParticleDispersion --- VadereState/src/org/vadere/state/scenario/AerosolCloud.java | 2 +- VadereState/src/org/vadere/state/scenario/Droplets.java | 2 +- ...nfectiousParticleDispersion.java => ParticleDispersion.java} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename VadereState/src/org/vadere/state/scenario/{InfectiousParticleDispersion.java => ParticleDispersion.java} (68%) diff --git a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java index a327e5285..275a5da52 100644 --- a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java +++ b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java @@ -19,7 +19,7 @@ import org.vadere.util.geometry.shapes.*; * concentration * */ -public class AerosolCloud extends InfectiousParticleDispersion { +public class AerosolCloud extends ParticleDispersion { private AttributesAerosolCloud attributes; diff --git a/VadereState/src/org/vadere/state/scenario/Droplets.java b/VadereState/src/org/vadere/state/scenario/Droplets.java index 7a5ecb08f..8c43e01fc 100644 --- a/VadereState/src/org/vadere/state/scenario/Droplets.java +++ b/VadereState/src/org/vadere/state/scenario/Droplets.java @@ -12,7 +12,7 @@ import org.vadere.util.geometry.shapes.Vector2D; import java.awt.geom.AffineTransform; import java.awt.geom.Path2D; -public class Droplets extends InfectiousParticleDispersion { +public class Droplets extends ParticleDispersion { private AttributesDroplets attributes; final static int numberOfCircularSections = 5; diff --git a/VadereState/src/org/vadere/state/scenario/InfectiousParticleDispersion.java b/VadereState/src/org/vadere/state/scenario/ParticleDispersion.java similarity index 68% rename from VadereState/src/org/vadere/state/scenario/InfectiousParticleDispersion.java rename to VadereState/src/org/vadere/state/scenario/ParticleDispersion.java index 6527cbd4c..13c708e2d 100644 --- a/VadereState/src/org/vadere/state/scenario/InfectiousParticleDispersion.java +++ b/VadereState/src/org/vadere/state/scenario/ParticleDispersion.java @@ -2,7 +2,7 @@ package org.vadere.state.scenario; import org.vadere.state.attributes.scenario.AttributesParticleDispersion; -public abstract class InfectiousParticleDispersion extends ScenarioElement { +public abstract class ParticleDispersion extends ScenarioElement { private AttributesParticleDispersion attributes; } -- GitLab From 60f7673027374c20b58c9387ccedf8d7187d0300 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 1 Mar 2022 14:57:56 +0100 Subject: [PATCH 48/83] Refactor and add comments / javadoc --- .../infection/AbstractDoseResponseModel.java | 35 ++++++++++++++++++- .../infection/AbstractExposureModel.java | 10 ++++++ .../infection/AirTransmissionModel.java | 25 +++++++++---- .../infection/ProximityExposureModel.java | 17 +++++++-- .../infection/ThresholdResponseModel.java | 30 +++++++++------- .../AttributesAirTransmissionModel.java | 17 ++++----- .../infection/AttributesExposureModel.java | 4 +++ .../AttributesProximityExposureModel.java | 6 +++- .../AirTransmissionModelHealthStatus.java | 6 +++- .../DoseResponseModelInfectionStatus.java | 11 ++++++ .../health/ExposureModelHealthStatus.java | 10 ++++++ .../ProximityExposureModelHealthStatus.java | 4 +++ .../vadere/state/scenario/AerosolCloud.java | 13 ++----- 13 files changed, 143 insertions(+), 45 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java index d387e641c..3fd74e3e6 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractDoseResponseModel.java @@ -5,14 +5,35 @@ import org.vadere.simulator.control.scenarioelements.TopographyController; import org.vadere.simulator.control.simulation.ControllerProvider; import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; +import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.exceptions.AttributesNotFoundException; import org.vadere.state.attributes.models.infection.AttributesDoseResponseModel; +import org.vadere.state.attributes.models.infection.AttributesExposureModel; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.DoseResponseModelInfectionStatus; import org.vadere.state.scenario.Agent; import org.vadere.state.scenario.Pedestrian; import org.vadere.util.logging.Logger; +import java.util.List; import java.util.Random; +import java.util.Set; +import java.util.stream.Collectors; +/** + * AbstractDoseResponseModel is the abstract base class for all dose response + * models which allow to describe a Pedestrian's probability of + * infection, more precisely its {@link DoseResponseModelInfectionStatus}. + *

+ * A dose response model can be included in the simulation by defining the + * desired model in the scenario file in the list of submodels. + *

+ *

+ * Any dose response model requires that an exposure model is defined. + *

+ * + * @see AbstractExposureModel + */ public abstract class AbstractDoseResponseModel implements Model { protected static Logger logger = Logger.getLogger(AbstractDoseResponseModel.class); @@ -22,7 +43,7 @@ public abstract class AbstractDoseResponseModel implements Model { protected Domain domain; protected AttributesAgent attributesAgent; - @Override + @Override public void registerToScenarioElementControllerEvents(ControllerProvider controllerProvider) { /* * This will be called *after* a pedestrian is inserted into the topography by the given SourceController. @@ -36,6 +57,18 @@ public abstract class AbstractDoseResponseModel implements Model { controllerProvider.getTopographyController().register(this::topographyControllerEvent); } + /** + * Checks prerequisite for dose response model. + * + * @throws AttributesNotFoundException if no exposure model defined. + */ + protected void checkIfExposureModelDefined(List attributesList) throws AttributesNotFoundException { + Set result = attributesList.stream().filter(a -> AttributesExposureModel.class.isAssignableFrom(a.getClass())).collect(Collectors.toSet()); + if (result.size() < 1) { + throw new RuntimeException(this.getClass() + " requires any exposure model defined by " + AttributesExposureModel.class); + } + } + /** * Assures that each pedestrian that is spawned by sources obtains properties related to * {@link AttributesDoseResponseModel} when pedestrian is added to topography. diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java index bd5bade63..a7f2b6b1b 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AbstractExposureModel.java @@ -8,6 +8,7 @@ import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.models.infection.AttributesExposureModel; import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.ExposureModelHealthStatus; import org.vadere.state.scenario.Agent; import org.vadere.state.scenario.Pedestrian; import org.vadere.util.logging.Logger; @@ -15,6 +16,15 @@ import org.vadere.util.logging.Logger; import java.util.Optional; import java.util.Random; +/** + * AbstractExposureModel is the abstract base class for all exposure models which + * allow to describe a Pedestrian's degree of exposure, more + * precisely, its {@link ExposureModelHealthStatus health status}. + *

+ * An exposure model can be included in the simulation by defining the + * desired model in the scenario file in the list of submodels. + *

+ */ public abstract class AbstractExposureModel implements Model { protected static Logger logger = Logger.getLogger(AbstractExposureModel.class); diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index 7a81556e4..e0d73955e 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -27,14 +27,25 @@ import java.util.stream.Collectors; import static org.vadere.state.scenario.Droplets.createTransformedDropletsShape; /** - * This class models the spread of infectious pathogen among pedestrians. - * For this purpose, the AirTransmissionModel controls the airborne transmission of pathogen from infectious pedestrians to - * other pedestrians, i.e. it + * AirTransmissionModel describes the transmission of pathogen from one + * Pedestrian to another via ParticleDispersion that + * move through the air. + *

+ * This particle dispersion can either be described as {@link AerosolCloud + * AerosolClouds}, which are carried by air for a longer period, or by {@link + * Droplets}, which remain in the air only for short. + * Whether aerosol clouds and/or droplets are considered, is defined in + * {@link AttributesAirTransmissionModel}. + *

+ *

AirTransmissionModel contains the logic, that is: *

    - *
  • initializes each pedestrian's {@link AirTransmissionModelHealthStatus} after a pedestrian is inserted into the topography,
  • - *
  • updates the pedestrian's {@link AirTransmissionModelHealthStatus}
  • - *
  • creates, updates and deletes each {@link AerosolCloud}
  • - *
  • creates, updates and deletes {@link Droplets}
  • + *
  • Each pedestrian obtains a {@link AirTransmissionModelHealthStatus health + * status} after being inserted into the topography.
  • + *
  • Infectious pedestrians emit pathogen contained in aerosol + * clouds or droplets.
  • + *
  • Pedestrians health status, aerosol clouds, droplets
  • + *
  • The AirTransmissionModel deletes aerosol clouds and + * droplets once they have reached a minimum pathogen concentration.
  • *
*/ @ModelClass diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java index 620a23d44..af1ebd0b6 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java @@ -24,9 +24,20 @@ import java.util.Random; import java.util.stream.Collectors; /** - * Models the spread of infectious pathogen among pedestrians based a simple rule: - * Any pedestrian that approaches an infectious pedestrian so that the mutual distance falls below a defined - * threshold becomes exposed. + * ProximityExposureModel describes the degree of exposure of + * Pedestrians to another infectious one simply by their mutual + * distance. + *

+ *

+ *

ProximityExposureModel contains the logic, that is: + *

    + *
  • Each pedestrian obtains a {@link ProximityExposureModelHealthStatus + * health status} + * after being inserted into the topography.
  • + *
  • Any pedestrian that approaches an infectious pedestrian so that the + * mutual distance falls below a defined threshold becomes exposed. The + * threshold is defined in {@link AttributesProximityExposureModel}.
  • + *
*/ @ModelClass public class ProximityExposureModel extends AbstractExposureModel { diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java index cae3255de..0f3c22be8 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java @@ -6,10 +6,9 @@ import org.vadere.simulator.control.scenarioelements.TopographyController; import org.vadere.simulator.models.Model; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; -import org.vadere.state.attributes.exceptions.AttributesNotFoundException; -import org.vadere.state.attributes.models.infection.AttributesExposureModel; import org.vadere.state.attributes.models.infection.AttributesThresholdResponseModel; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.ExposureModelHealthStatus; import org.vadere.state.health.ThresholdResponseModelInfectionStatus; import org.vadere.state.scenario.Agent; import org.vadere.state.scenario.Pedestrian; @@ -18,10 +17,25 @@ import org.vadere.state.scenario.Topography; import java.util.Collection; import java.util.List; import java.util.Random; -import java.util.Set; import java.util.stream.Collectors; +/** + * ThresholdResponseModel describes a Pedestrian's probability of + * infection, more precisely its {@link ThresholdResponseModelInfectionStatus}. + *

+ * It can be included in the simulation by adding it to the list of + * submodels in the scenario file. This requires that an + * exposure model is defined. + *

+ *

+ * The probability of infection is 0 by default but set to 1 if the + * Pedestrian's degree of exposure + * {@link ExposureModelHealthStatus} reaches or exceeds a user-defined + * threshold. The threshold is defined by + * {@link AttributesThresholdResponseModel}. + *

+ */ @ModelClass public class ThresholdResponseModel extends AbstractDoseResponseModel { @@ -41,16 +55,6 @@ public class ThresholdResponseModel extends AbstractDoseResponseModel { checkIfExposureModelDefined(attributesList); } - /* - * Check prerequisite for dose response model: Is exposure model defined? Throw error otherwise. - */ - private void checkIfExposureModelDefined(List attributesList) throws AttributesNotFoundException { - Set result = attributesList.stream().filter(a -> AttributesExposureModel.class.isAssignableFrom(a.getClass())).collect(Collectors.toSet()); - if (result.size() < 1) { - throw new RuntimeException(this.getClass() + " requires any exposure model defined by " + AttributesExposureModel.class); - } - } - @Override public void preLoop(double simTimeInSec) { } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java index ec10d84f7..b5b001b2d 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java @@ -2,14 +2,16 @@ package org.vadere.state.attributes.models.infection; import org.vadere.annotation.factories.attributes.ModelAttributeClass; -import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModelAerosolCloud; -import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModelDroplets; -import org.vadere.state.attributes.models.infection.AttributesExposureModel; -import org.vadere.state.scenario.*; - /** - * Attributes related to the corresponding exposure model. They define properties of {@link Pedestrian}s, - * {@link AerosolCloud}s, and {@link Droplets} that are equal for all instances of each class. + * AttributesAirTransmissionModel contains user-defined properties related to the + * AirTransmissionModel. + * They define properties that are shared by all instances of + *
    + *
  • Pedestrian
  • + *
  • AerosolCloud
  • + *
  • Droplets
  • + *
+ * */ @ModelAttributeClass public class AttributesAirTransmissionModel extends AttributesExposureModel { @@ -25,7 +27,6 @@ public class AttributesAirTransmissionModel extends AttributesExposureModel { */ private boolean aerosolCloudsActive; - private AttributesAirTransmissionModelAerosolCloud aerosolCloudParameters; /** diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java index 346d193eb..112be302a 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java @@ -5,6 +5,10 @@ import org.vadere.state.attributes.Attributes; import java.util.ArrayList; import java.util.Arrays; +/** + * AttributesExposureModel contains user-defined properties describing the + * AbstractExposureModel. + */ public abstract class AttributesExposureModel extends Attributes { private ArrayList exposureModelSourceParameters; diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesProximityExposureModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesProximityExposureModel.java index f1f2c1660..be03bae1c 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesProximityExposureModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesProximityExposureModel.java @@ -1,8 +1,12 @@ package org.vadere.state.attributes.models.infection; - import org.vadere.annotation.factories.attributes.ModelAttributeClass; + +/** + * AttributesProximityExposureModel contains user-defined properties related to + * the ProximityExposureModel. + */ @ModelAttributeClass public class AttributesProximityExposureModel extends AttributesExposureModel { diff --git a/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java b/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java index 5c7487dd8..ae2ed11bd 100644 --- a/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java @@ -2,6 +2,10 @@ package org.vadere.state.health; import org.vadere.util.geometry.shapes.VPoint; +/** + * AirTransmissionModelHealthStatus that is used in combination with the + * AirTransmissionModel. + */ public class AirTransmissionModelHealthStatus extends ExposureModelHealthStatus { private boolean breathingIn; @@ -90,7 +94,7 @@ public class AirTransmissionModelHealthStatus extends ExposureModelHealthStatus // Methods - /* + /** * Defines whether the pedestrian inhales or exhales depending on the current simulation time, * respiratoryTimeOffset, and periodLength. Assumes that periodLength for inhalation and exhalation are equally * long. Pedestrian inhales when sin(time) > 0 or cos(time) == 1. diff --git a/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java b/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java index 26da44025..7feddc5b5 100644 --- a/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java +++ b/VadereState/src/org/vadere/state/health/DoseResponseModelInfectionStatus.java @@ -1,5 +1,16 @@ package org.vadere.state.health; +/** + * DoseResponseModelInfectionStatus is the abstract base class for all infection + * statuses a Pedestrian can adopt. + *

+ * It describes whether a Pedestrian is infected or not by a + * probability of infection. The probability of infection ranges in [0, 1]. + * It is calculated based on the degree of exposure + * ({@link ExposureModelHealthStatus}), by the underlying + * AbstractDoseResponseModel. + *

+ */ public abstract class DoseResponseModelInfectionStatus { /* diff --git a/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java index 08b484488..f9022d994 100644 --- a/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java @@ -1,5 +1,15 @@ package org.vadere.state.health; +/** + * ExposureModelHealthStatus is the abstract base class for all types of exposure + * a Pedestrian can adopt. + *

+ * It describes the degree to which a Pedestrian is exposed to + * infectious pathogens, or in a more abstract sense, to other (infectious) + * agents. The degree of exposure is defined by the underlying + * AbstractExposureModel. + *

+ */ public abstract class ExposureModelHealthStatus { boolean infectious; diff --git a/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java index 4f51d27aa..e7b94cf6e 100644 --- a/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java @@ -1,5 +1,9 @@ package org.vadere.state.health; +/** + * ProximityExposureModelHealthStatus that is used in combination with the + * ProximityExposureModel. + */ public class ProximityExposureModelHealthStatus extends ExposureModelHealthStatus { public ProximityExposureModelHealthStatus() { diff --git a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java index 275a5da52..6f35fa197 100644 --- a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java +++ b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java @@ -7,17 +7,8 @@ import org.vadere.state.types.ScenarioElementType; import org.vadere.util.geometry.shapes.*; /** - * This class models aerosolClouds. AerosolClouds represent one mode of transmission how pathogen can spread among - * pedestrians. They are created, updated and deleted in the InfectionModel: - * - *
    - *
  • Creation: infectious pedestrians emit pathogen, i.e. an aerosolCloud is created. Its position - * depends on the pedestrian's trajectory and respiratory cycle. The shape is circular.
  • - *
  • Update: An aerosolCloud can change its extent and pathogenLoad. The corresponding methods are defined - * in this class. The pathogen concentration equals pathogenLoad / volume.
  • - *
  • Deletion: The TransmissionModel deletes an aerosolCloud once it has reached a minimum pathogen - * concentration
  • - *
+ * AerosolCloud represents one medium of transmission how pathogen can spread among + * pedestrians. */ public class AerosolCloud extends ParticleDispersion { -- GitLab From 2f0bfe8475a106468566bd11887e09ec34a588f6 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 1 Mar 2022 15:02:30 +0100 Subject: [PATCH 49/83] Add ThresholdResponseModel to simulation --- .../AirTransmissionModel/examples/scenarios/queue.scenario | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario index 6bddb3b0d..9d4e4da07 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario @@ -2,7 +2,7 @@ "name" : "queue", "description" : "", "release" : "2.0", - "commithash" : "9d0fc8b34cc51cd7724fdc52b3673423e4b08886", + "commithash" : "f7ec0b9e854e9fd67cf1e5ad8c87511b6a129a45", "processWriters" : { "files" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", @@ -110,7 +110,7 @@ "targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid", "pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell", "obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell", - "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel" ] + "submodels" : [ "org.vadere.simulator.models.infection.AirTransmissionModel", "org.vadere.simulator.models.infection.ThresholdResponseModel" ] }, "org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : { "pedPotentialIntimateSpaceWidth" : 0.45, @@ -171,6 +171,9 @@ "pathogenLoad" : 10000.0, "absorptionRate" : 0.1 } + }, + "org.vadere.state.attributes.models.infection.AttributesThresholdResponseModel" : { + "exposureToInfectedThreshold" : 1000.0 } }, "attributesSimulation" : { -- GitLab From 41ab050a2f56f6725ba200ec914ee6369bd01418 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 2 Mar 2022 11:56:42 +0100 Subject: [PATCH 50/83] Reduce color JPanel width; introduce variable --- .../gui/components/view/SettingsDialog.java | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java index 6a354b2e9..45af7dfc4 100644 --- a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java +++ b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java @@ -30,6 +30,8 @@ public class SettingsDialog extends JDialog { */ public final int NEXT_CELL = 2; + public final int COLOR_JPANEL_WIDTH = 60; + private DefaultSimulationConfig config; private final SimulationModel model; @@ -170,7 +172,7 @@ public class SettingsDialog extends JDialog { final JButton bObstColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pObstacleColor = new JPanel(); pObstacleColor.setBackground(model.config.getObstacleColor()); - pObstacleColor.setPreferredSize(new Dimension(130, 20)); + pObstacleColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bObstColor.addActionListener(new ActionSetObstacleColor("Set Obstacle Color", model, pObstacleColor)); colorSettingsPane.add(pObstacleColor, cc.xy(column2, row += NEXT_CELL)); colorSettingsPane.add(bObstColor, cc.xy(column3, row)); @@ -178,7 +180,7 @@ public class SettingsDialog extends JDialog { final JButton bTarColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pTargetColor = new JPanel(); pTargetColor.setBackground(model.config.getTargetColor()); - pTargetColor.setPreferredSize(new Dimension(130, 20)); + pTargetColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bTarColor.addActionListener(new ActionSetTargetColor("Set Target Color", model, pTargetColor)); colorSettingsPane.add(pTargetColor, cc.xy(column2, row += NEXT_CELL)); colorSettingsPane.add(bTarColor, cc.xy(column3, row)); @@ -186,7 +188,7 @@ public class SettingsDialog extends JDialog { final JButton bSrcColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pSourceColor = new JPanel(); pSourceColor.setBackground(model.config.getSourceColor()); - pSourceColor.setPreferredSize(new Dimension(130, 20)); + pSourceColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bSrcColor.addActionListener(new ActionSetSourceColor("Set Source Color", model, pSourceColor)); colorSettingsPane.add(pSourceColor, cc.xy(column2, row += NEXT_CELL)); colorSettingsPane.add(bSrcColor, cc.xy(column3, row)); @@ -194,7 +196,7 @@ public class SettingsDialog extends JDialog { final JButton bStairsColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pStairsColor = new JPanel(); pStairsColor.setBackground(model.config.getStairColor()); - pStairsColor.setPreferredSize(new Dimension(130, 20)); + pStairsColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bStairsColor.addActionListener(new ActionSetStairsColor("Set Stairs Color", model, pStairsColor)); colorSettingsPane.add(pStairsColor, cc.xy(column2, row += NEXT_CELL)); colorSettingsPane.add(bStairsColor, cc.xy(column3, row)); @@ -202,7 +204,7 @@ public class SettingsDialog extends JDialog { final JButton bDensityColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pDensityColor = new JPanel(); pDensityColor.setBackground(model.config.getDensityColor()); - pDensityColor.setPreferredSize(new Dimension(130, 20)); + pDensityColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bDensityColor.addActionListener(new ActionSetDensityColor("Set Density Color", model, pDensityColor)); colorSettingsPane.add(pDensityColor, cc.xy(column2, row += NEXT_CELL)); colorSettingsPane.add(bDensityColor, cc.xy(column3, row)); @@ -210,7 +212,7 @@ public class SettingsDialog extends JDialog { final JButton bAbsorbingAreaColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pAbsorbingAreaColor = new JPanel(); pAbsorbingAreaColor.setBackground(model.config.getAbsorbingAreaColor()); - pAbsorbingAreaColor.setPreferredSize(new Dimension(130, 20)); + pAbsorbingAreaColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bAbsorbingAreaColor.addActionListener(new ActionSetAbsorbingAreaColor("Set Absorbing Area Color", model, pAbsorbingAreaColor)); colorSettingsPane.add(pAbsorbingAreaColor, cc.xy(column2, row += NEXT_CELL)); colorSettingsPane.add(bAbsorbingAreaColor, cc.xy(column3, row)); @@ -218,7 +220,7 @@ public class SettingsDialog extends JDialog { final JButton bTargetChangerColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pTargetChangerColor = new JPanel(); pTargetChangerColor.setBackground(model.config.getTargetChangerColor()); - pTargetChangerColor.setPreferredSize(new Dimension(130, 20)); + pTargetChangerColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bTargetChangerColor.addActionListener(new ActionSetTargetChangerColor("Set Target Changer Color", model, pTargetChangerColor)); colorSettingsPane.add(pTargetChangerColor, cc.xy(column2, row += NEXT_CELL)); colorSettingsPane.add(bTargetChangerColor, cc.xy(column3, row)); @@ -226,7 +228,7 @@ public class SettingsDialog extends JDialog { final JButton bAerosolCloudColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pAerosolCloudColor = new JPanel(); pAerosolCloudColor.setBackground(model.config.getAerosolCloudColor()); - pAerosolCloudColor.setPreferredSize(new Dimension(130, 20)); + pAerosolCloudColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bAerosolCloudColor.addActionListener(new ActionSetAerosolCloudColor("Set Aerosol Cloud Color", model, pAerosolCloudColor)); colorSettingsPane.add(pAerosolCloudColor, cc.xy(column2, row += NEXT_CELL)); colorSettingsPane.add(bAerosolCloudColor, cc.xy(column3, row)); @@ -234,7 +236,7 @@ public class SettingsDialog extends JDialog { final JButton bDropletCloudColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pDropletCloudColor = new JPanel(); pDropletCloudColor.setBackground(model.config.getDropletsColor()); - pDropletCloudColor.setPreferredSize(new Dimension(130, 20)); + pDropletCloudColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bDropletCloudColor.addActionListener(new ActionSetDropletsColor("Set Droplet Cloud Color", model, pDropletCloudColor)); colorSettingsPane.add(pDropletCloudColor, cc.xy(column2, row += NEXT_CELL)); colorSettingsPane.add(bDropletCloudColor, cc.xy(column3, row)); @@ -413,7 +415,7 @@ public class SettingsDialog extends JDialog { Optional colorByTargetId = model.config.getColorByTargetId(selectedTargetIdOuter); pTargetColor.setBackground(colorByTargetId.orElseGet(() -> model.config.getPedestrianDefaultColor())); - pTargetColor.setPreferredSize(new Dimension(130, 20)); + pTargetColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); // When user changes a color, save it in the model. bChangeTargetColor.addActionListener(new ActionSetPedestrianColor("Set Pedestrian Color", model, pTargetColor, @@ -432,7 +434,7 @@ public class SettingsDialog extends JDialog { Optional notTargetPedCol = config.getColorByTargetId((-1)); pPedestrianColorNoTarget.setBackground(notTargetPedCol.orElseGet(() -> model.config.getPedestrianDefaultColor())); - pPedestrianColorNoTarget.setPreferredSize(new Dimension(130, 20)); + pPedestrianColorNoTarget.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bChangePedestrianColorNoTarget.addActionListener(new ActionSetPedestrianWithoutTargetColor( "Set Pedestrian without Target Color", model, pPedestrianColorNoTarget)); } @@ -444,7 +446,7 @@ public class SettingsDialog extends JDialog { Color selfCategoryColor = model.config.getSelfCategoryColor(selectedSelfCategory); pSelfCategoryColor.setBackground(selfCategoryColor); - pSelfCategoryColor.setPreferredSize(new Dimension(130, 20)); + pSelfCategoryColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); // When user changes a color, save it in the model. bChangeSelfCategoryColor.addActionListener(new ActionSetSelfCategoryColor("Set Self Category Color", model, pSelfCategoryColor, @@ -462,19 +464,19 @@ public class SettingsDialog extends JDialog { JButton bChangePedestrianColorInfectious, JPanel pPedestrianColorInfectious) { pPedestrianColorLowerExposure.setBackground(config.getPedestrianDefaultColor()); - pPedestrianColorLowerExposure.setPreferredSize(new Dimension(130, 20)); + pPedestrianColorLowerExposure.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); // When user changes a color, save it in the model. bChangePedestrianColorLowerExposure.addActionListener(new ActionSetPedestrianDefaultColor( "Set Pedestrian Exposure Color (lower limit)", model, pPedestrianColorLowerExposure)); pPedestrianColorUpperExposure.setBackground(config.getExposedColor()); - pPedestrianColorUpperExposure.setPreferredSize(new Dimension(130, 20)); + pPedestrianColorUpperExposure.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); // When user changes a color, save it in the model. bChangePedestrianColorUpperExposure.addActionListener(new ActionSetPedestrianExposedColor( "Set Pedestrian Exposure Color (Upper Limit)", model, pPedestrianColorUpperExposure)); pPedestrianColorInfectious.setBackground(config.getInfectiousColor()); - pPedestrianColorInfectious.setPreferredSize(new Dimension(130, 20)); + pPedestrianColorInfectious.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); // When user changes a color, save it in the model. bChangePedestrianColorInfectious.addActionListener(new ActionSetPedestrianInfectiousColor( "Set Pedestrian Infectious Color", model, pPedestrianColorInfectious)); @@ -488,7 +490,7 @@ public class SettingsDialog extends JDialog { Color informationStateColor = model.config.getInformationStateColor(selectedInformationState); pInformationStateColor.setBackground(informationStateColor); - pInformationStateColor.setPreferredSize(new Dimension(130, 20)); + pInformationStateColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); // When user changes a color, save it in the model. bChangeInformationStateColor.addActionListener(new ActionSetInformationStateColor("Set Information State Color", model, pInformationStateColor, -- GitLab From b25ad66d09de22f49063d3fe80f92bda17fa1f2b Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 2 Mar 2022 12:00:10 +0100 Subject: [PATCH 51/83] Add JSpinner to set opacity of aerosol clouds in SettingsDialog Users can now flexibly adapt the opacity of aerosol clouds --- VadereGui/resources/messages.properties | 5 +- VadereGui/resources/messages_de_DE.properties | 5 +- .../gui/components/model/DefaultConfig.java | 6 +- .../gui/components/view/DefaultRenderer.java | 6 +- .../gui/components/view/SettingsDialog.java | 55 ++++++++++++------- 5 files changed, 46 insertions(+), 31 deletions(-) diff --git a/VadereGui/resources/messages.properties b/VadereGui/resources/messages.properties index 42e37f893..e8fbd46bf 100644 --- a/VadereGui/resources/messages.properties +++ b/VadereGui/resources/messages.properties @@ -326,14 +326,15 @@ SettingsDialog.lblDensityColor.text=Density SettingsDialog.lblAbsorbingAreaColor.text=Absorbing Area SettingsDialog.lblTargetChanger.text=Target Changer SettingsDialog.lblAerosolCloudColor.text=Aerosol Cloud +SettingsDialog.lblAerosolCloudAlpha.text=Opacity SettingsDialog.lblDropletCloudColor.text=Droplet Cloud SettingsDialog.lblStair.text=Stair SettingsDialog.lblPedestrianNoTarget.text=Without Target SettingsDialog.lblTargetColoring.text=Coloring by Target SettingsDialog.lblSelfCategoryColoring.text=Coloring by Self Category SettingsDialog.lblHealthStatusColoring.text=Coloring by Health Status -SettingsDialog.lblPedestrianLowerExposure.text=Lower Exposure -SettingsDialog.lblPedestrianUpperExposure.text=Upper Exposure +SettingsDialog.lblPedestrianLowerExposure.text=Lower degree of exposure color transition +SettingsDialog.lblPedestrianUpperExposure.text=Upper degree of exposure color transition SettingsDialog.lblPedestrianInfectious.text=Infectious SettingsDialog.lblInformationColoring.text=Coloring by Information State ProjectView.menuOpenFloorFieldFile.title=Add Floor Field File... diff --git a/VadereGui/resources/messages_de_DE.properties b/VadereGui/resources/messages_de_DE.properties index 17be97049..d4e239670 100644 --- a/VadereGui/resources/messages_de_DE.properties +++ b/VadereGui/resources/messages_de_DE.properties @@ -315,6 +315,7 @@ SettingsDialog.btnClose.text=Schlie\u00dfen SettingsDialog.lblDensityColor.text=Dichte SettingsDialog.lblAbsorbingAreaColor.text=Absorbierender Bereich SettingsDialog.lblAerosolCloudColor.text=Aerosolwolke +SettingsDialog.lblAerosolCloudAlpha.text=Deckkraft SettingsDialog.lblDropletCloudColor.text=Tr\u00F6pfchenwolke SettingsDialog.lblTargetChanger.text=Ziel\u00e4nderung SettingsDialog.lblStair.text=Treppe @@ -322,8 +323,8 @@ SettingsDialog.lblPedestrianNoTarget.text=Ohne Ziel SettingsDialog.lblTargetColoring.text=F\u00e4rbung nach Ziel SettingsDialog.lblSelfCategoryColoring.text=F\u00e4rbung nach "Self Category" SettingsDialog.lblHealthStatusColoring.text=F\u00e4rbung nach "Health Status" -SettingsDialog.lblPedestrianLowerExposure.text=Unterer Expositionsgrad -SettingsDialog.lblPedestrianUpperExposure.text=Oberer Expositionsgrad +SettingsDialog.lblPedestrianLowerExposure.text=Unterer Expositionsgrad Farbverlauf +SettingsDialog.lblPedestrianUpperExposure.text=Oberer Expositionsgrad Farbverlauf SettingsDialog.lblPedestrianInfectious.text=Infekti\u00f6s SettingsDialog.menuOpenFloorFieldFile.title=Floor Field-Datei hinzuf\u00fcgen... SettingsDialog.btnDrawVoronoiDiagram.tooltip=Voronoi-Diagramm zeichnen und anzeigen diff --git a/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java b/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java index 2e6d89928..7dc228e37 100644 --- a/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java +++ b/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java @@ -20,7 +20,7 @@ public class DefaultConfig { private int measurementAreaAlpha = 140; private Color aerosolCloudColor = new Color(202, 156, 76); // Color(0.60f, 0.52f, 0.00f); private int aerosolCloudAlphaMax = 10; - private int aerosolCloudAlphaMin = 0; + private int aerosolCloudAlphaPathLoad = 1400; // pathogen load per area corresponding to aerosolCloudAlphaMax; 1400 results from init pathogen load 10000 / init area (1.5^2 * PI) private Color dropletsColor = new Color(190, 210, 20); private Color exposedColor = new Color(202, 76, 187); private Color infectiousColor = new Color(202, 76, 76); @@ -45,7 +45,7 @@ public class DefaultConfig { this.measurementAreaAlpha = config.measurementAreaAlpha; this.aerosolCloudColor = config.aerosolCloudColor; this.aerosolCloudAlphaMax = config.aerosolCloudAlphaMax; - this.aerosolCloudAlphaMin = config.aerosolCloudAlphaMin; + this.aerosolCloudAlphaPathLoad = config.aerosolCloudAlphaPathLoad; this.dropletsColor = config.dropletsColor; this.exposedColor = config.exposedColor; this.infectiousColor = config.infectiousColor; @@ -105,7 +105,7 @@ public class DefaultConfig { } public Color getAerosolCloudColor() {return aerosolCloudColor;} public int getAerosolCloudAlphaMax() { return aerosolCloudAlphaMax; } - public int getAerosolCloudAlphaMin() { return aerosolCloudAlphaMin; } + public int getAerosolCloudAlphaPathLoad() { return aerosolCloudAlphaPathLoad; } public Color getDropletsColor() {return dropletsColor;} public Color getExposedColor() { return exposedColor; diff --git a/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java b/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java index c5749f96c..90eb6cb21 100644 --- a/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java +++ b/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java @@ -295,9 +295,9 @@ public abstract class DefaultRenderer { final Color tmpColor = graphics.getColor(); AerosolCloud cloud = (AerosolCloud) element; float maxAlpha = defaultModel.getConfig().getAerosolCloudAlphaMax(); - float minAlpha = defaultModel.getConfig().getAerosolCloudAlphaMin(); - //ToDo this is hard coded! - double maxPathogensPerArea = 1400; // results from 10000 / (1.5^2 * PI) + float minAlpha = 0; // no lower threshold + + double maxPathogensPerArea = defaultModel.getConfig().getAerosolCloudAlphaPathLoad(); double pathogensPerArea = cloud.getCurrentPathogenLoad() / cloud.getArea(); pathogensPerArea = Math.min(pathogensPerArea, maxPathogensPerArea); // make sure that maxPathogensPerArea is not exceeded int currentAlpha = (int) ((pathogensPerArea / maxPathogensPerArea) * (maxAlpha - minAlpha) + minAlpha); diff --git a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java index 45af7dfc4..e1ec10337 100644 --- a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java +++ b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java @@ -141,7 +141,7 @@ public class SettingsDialog extends JDialog { colorSettingsPane .setBorder(BorderFactory.createTitledBorder(Messages.getString("SettingsDialog.colors.border.text"))); - FormLayout colorSettingsLayout = new FormLayout("5dlu, pref, 2dlu, pref:grow, 2dlu, pref, 2dlu, pref, 5dlu", // col + FormLayout colorSettingsLayout = new FormLayout("5dlu, pref:grow, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 5dlu", // col createCellsWithSeparators(9)); // rows colorSettingsPane.setLayout(colorSettingsLayout); @@ -167,6 +167,8 @@ public class SettingsDialog extends JDialog { int row = 0; int column2 = 4; int column3 = 6; + int column4 = 8; + int column5 = 10; CellConstraints cc = new CellConstraints(); final JButton bObstColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); @@ -174,72 +176,83 @@ public class SettingsDialog extends JDialog { pObstacleColor.setBackground(model.config.getObstacleColor()); pObstacleColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bObstColor.addActionListener(new ActionSetObstacleColor("Set Obstacle Color", model, pObstacleColor)); - colorSettingsPane.add(pObstacleColor, cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(bObstColor, cc.xy(column3, row)); + colorSettingsPane.add(pObstacleColor, cc.xy(column4, row += NEXT_CELL)); + colorSettingsPane.add(bObstColor, cc.xy(column5, row)); final JButton bTarColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pTargetColor = new JPanel(); pTargetColor.setBackground(model.config.getTargetColor()); pTargetColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bTarColor.addActionListener(new ActionSetTargetColor("Set Target Color", model, pTargetColor)); - colorSettingsPane.add(pTargetColor, cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(bTarColor, cc.xy(column3, row)); + colorSettingsPane.add(pTargetColor, cc.xy(column4, row += NEXT_CELL)); + colorSettingsPane.add(bTarColor, cc.xy(column5, row)); final JButton bSrcColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pSourceColor = new JPanel(); pSourceColor.setBackground(model.config.getSourceColor()); pSourceColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bSrcColor.addActionListener(new ActionSetSourceColor("Set Source Color", model, pSourceColor)); - colorSettingsPane.add(pSourceColor, cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(bSrcColor, cc.xy(column3, row)); + colorSettingsPane.add(pSourceColor, cc.xy(column4, row += NEXT_CELL)); + colorSettingsPane.add(bSrcColor, cc.xy(column5, row)); final JButton bStairsColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pStairsColor = new JPanel(); pStairsColor.setBackground(model.config.getStairColor()); pStairsColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bStairsColor.addActionListener(new ActionSetStairsColor("Set Stairs Color", model, pStairsColor)); - colorSettingsPane.add(pStairsColor, cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(bStairsColor, cc.xy(column3, row)); + colorSettingsPane.add(pStairsColor, cc.xy(column4, row += NEXT_CELL)); + colorSettingsPane.add(bStairsColor, cc.xy(column5, row)); final JButton bDensityColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pDensityColor = new JPanel(); pDensityColor.setBackground(model.config.getDensityColor()); pDensityColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bDensityColor.addActionListener(new ActionSetDensityColor("Set Density Color", model, pDensityColor)); - colorSettingsPane.add(pDensityColor, cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(bDensityColor, cc.xy(column3, row)); + colorSettingsPane.add(pDensityColor, cc.xy(column4, row += NEXT_CELL)); + colorSettingsPane.add(bDensityColor, cc.xy(column5, row)); final JButton bAbsorbingAreaColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pAbsorbingAreaColor = new JPanel(); pAbsorbingAreaColor.setBackground(model.config.getAbsorbingAreaColor()); pAbsorbingAreaColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bAbsorbingAreaColor.addActionListener(new ActionSetAbsorbingAreaColor("Set Absorbing Area Color", model, pAbsorbingAreaColor)); - colorSettingsPane.add(pAbsorbingAreaColor, cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(bAbsorbingAreaColor, cc.xy(column3, row)); + colorSettingsPane.add(pAbsorbingAreaColor, cc.xy(column4, row += NEXT_CELL)); + colorSettingsPane.add(bAbsorbingAreaColor, cc.xy(column5, row)); final JButton bTargetChangerColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pTargetChangerColor = new JPanel(); pTargetChangerColor.setBackground(model.config.getTargetChangerColor()); pTargetChangerColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bTargetChangerColor.addActionListener(new ActionSetTargetChangerColor("Set Target Changer Color", model, pTargetChangerColor)); - colorSettingsPane.add(pTargetChangerColor, cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(bTargetChangerColor, cc.xy(column3, row)); + colorSettingsPane.add(pTargetChangerColor, cc.xy(column4, row += NEXT_CELL)); + colorSettingsPane.add(bTargetChangerColor, cc.xy(column5, row)); final JButton bAerosolCloudColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pAerosolCloudColor = new JPanel(); pAerosolCloudColor.setBackground(model.config.getAerosolCloudColor()); pAerosolCloudColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bAerosolCloudColor.addActionListener(new ActionSetAerosolCloudColor("Set Aerosol Cloud Color", model, pAerosolCloudColor)); - colorSettingsPane.add(pAerosolCloudColor, cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(bAerosolCloudColor, cc.xy(column3, row)); + colorSettingsPane.add(pAerosolCloudColor, cc.xy(column4, row += NEXT_CELL)); + colorSettingsPane.add(bAerosolCloudColor, cc.xy(column5, row)); + final JSpinner spinnerAerosolCloudAlpha = new JSpinner(); + spinnerAerosolCloudAlpha.setPreferredSize(new Dimension(60, 20)); + final SpinnerNumberModel sModelAerosolCloudAlpha = new SpinnerNumberModel(model.config.getAerosolCloudAlphaMax(), + 0, 255, 1); + spinnerAerosolCloudAlpha.setModel(sModelAerosolCloudAlpha); + spinnerAerosolCloudAlpha.addChangeListener(e -> { + model.config.setAerosolCloudAlphaMax((int) sModelAerosolCloudAlpha.getValue()); + model.notifyObservers(); + }); + colorSettingsPane.add(new JLabel(Messages.getString("SettingsDialog.lblAerosolCloudAlpha.text") + ":"), cc.xy(column2, row)); + colorSettingsPane.add(spinnerAerosolCloudAlpha, cc.xy(column3, row)); final JButton bDropletCloudColor = new JButton(Messages.getString("SettingsDialog.btnEditColor.text")); final JPanel pDropletCloudColor = new JPanel(); pDropletCloudColor.setBackground(model.config.getDropletsColor()); pDropletCloudColor.setPreferredSize(new Dimension(COLOR_JPANEL_WIDTH, 20)); bDropletCloudColor.addActionListener(new ActionSetDropletsColor("Set Droplet Cloud Color", model, pDropletCloudColor)); - colorSettingsPane.add(pDropletCloudColor, cc.xy(column2, row += NEXT_CELL)); - colorSettingsPane.add(bDropletCloudColor, cc.xy(column3, row)); + colorSettingsPane.add(pDropletCloudColor, cc.xy(column4, row += NEXT_CELL)); + colorSettingsPane.add(bDropletCloudColor, cc.xy(column5, row)); } private void initAgentColorSettingsPane(JLayeredPane colorSettingsPane){ @@ -297,7 +310,7 @@ public class SettingsDialog extends JDialog { bChangePedestrianColorInfectious, pPedestrianColorInfectious); final JSpinner spinnerLowerExposure = new JSpinner(); - spinnerLowerExposure.setPreferredSize(new Dimension(75, 20)); + spinnerLowerExposure.setPreferredSize(new Dimension(60, 20)); final SpinnerNumberModel sModelLowerExposure = new SpinnerNumberModel(model.config.getLowerVisualizedExposure(), 0, model.config.getUpperVisualizedExposure(), 1); spinnerLowerExposure.setModel(sModelLowerExposure); spinnerLowerExposure.addChangeListener(e -> { @@ -307,7 +320,7 @@ public class SettingsDialog extends JDialog { final JSpinner spinnerUpperExposure = new JSpinner(); - spinnerUpperExposure.setPreferredSize(new Dimension(75, 20)); + spinnerUpperExposure.setPreferredSize(new Dimension(60, 20)); final SpinnerNumberModel sModelUpperExposure = new SpinnerNumberModel(model.config.getUpperVisualizedExposure(), model.config.getLowerVisualizedExposure(), null, 1); spinnerUpperExposure.setModel(sModelUpperExposure); spinnerUpperExposure.addChangeListener(e -> { -- GitLab From bda809004f2d8775619eac8452092158e33105e9 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 2 Mar 2022 13:30:39 +0100 Subject: [PATCH 52/83] Correct TikzGenerator Let opacity of aerosol clouds in tex file depend on the cloud's pathogen load per area (this concentration) --- .../org/vadere/gui/postvisualization/utils/TikzGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VadereGui/src/org/vadere/gui/postvisualization/utils/TikzGenerator.java b/VadereGui/src/org/vadere/gui/postvisualization/utils/TikzGenerator.java index 4af375d42..731d20828 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/utils/TikzGenerator.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/utils/TikzGenerator.java @@ -156,8 +156,8 @@ public class TikzGenerator { for (AerosolCloud aerosolCloud : topography.getAerosolClouds()) { VPoint centroid = aerosolCloud.getShape().getCentroid(); generatedCode += String.format(Locale.US, "\\coordinate (AerosolCloud%d) at (%f,%f); %% Centroid: AerosolCloud %d\n", aerosolCloud.getId(), centroid.x, centroid.y, aerosolCloud.getId()); - generatedCode += String.format(Locale.US, "\\fill[AerosolCloudColor,opacity=\\AerosolCloudOpacity] %s;\n", generatePathForScenarioElement(aerosolCloud)); - + double normalizedPathogenLoadPerArea = (aerosolCloud.getCurrentPathogenLoad() / aerosolCloud.getArea()) / (model.getConfig().getAerosolCloudAlphaPathLoad()); + generatedCode += String.format(Locale.US, "\\fill[AerosolCloudColor,opacity=\\AerosolCloudOpacity*%f] %s;\n", normalizedPathogenLoadPerArea, generatePathForScenarioElement(aerosolCloud)); } } else { generatedCode += "% Aerosol clouds (not enabled in config)\n"; -- GitLab From 1900e28190a71e6fd1f08812a33da4242bdc15e3 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 2 Mar 2022 14:34:50 +0100 Subject: [PATCH 53/83] [gui] set aerosol cloud opacity according to pathogen concentration --- .../gui/components/model/DefaultConfig.java | 16 +++++++++++++--- .../gui/components/view/DefaultRenderer.java | 8 ++++---- .../postvisualization/utils/TikzGenerator.java | 4 ++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java b/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java index 7dc228e37..8e9b1b426 100644 --- a/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java +++ b/VadereGui/src/org/vadere/gui/components/model/DefaultConfig.java @@ -1,6 +1,8 @@ package org.vadere.gui.components.model; +import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel; import org.vadere.state.psychology.cognition.GroupMembership; +import org.vadere.state.scenario.AerosolCloud; import java.awt.*; import java.util.HashMap; @@ -20,7 +22,7 @@ public class DefaultConfig { private int measurementAreaAlpha = 140; private Color aerosolCloudColor = new Color(202, 156, 76); // Color(0.60f, 0.52f, 0.00f); private int aerosolCloudAlphaMax = 10; - private int aerosolCloudAlphaPathLoad = 1400; // pathogen load per area corresponding to aerosolCloudAlphaMax; 1400 results from init pathogen load 10000 / init area (1.5^2 * PI) + private double aerosolCloudMaxPathogenConcentration; // pathogen concentration that corresponds to aerosolCloudAlphaMax private Color dropletsColor = new Color(190, 210, 20); private Color exposedColor = new Color(202, 76, 187); private Color infectiousColor = new Color(202, 76, 76); @@ -29,6 +31,7 @@ public class DefaultConfig { // Constructors public DefaultConfig() { + initPathogenConcentration(); initGroupMembershipColor(); } @@ -45,7 +48,7 @@ public class DefaultConfig { this.measurementAreaAlpha = config.measurementAreaAlpha; this.aerosolCloudColor = config.aerosolCloudColor; this.aerosolCloudAlphaMax = config.aerosolCloudAlphaMax; - this.aerosolCloudAlphaPathLoad = config.aerosolCloudAlphaPathLoad; + initPathogenConcentration(); this.dropletsColor = config.dropletsColor; this.exposedColor = config.exposedColor; this.infectiousColor = config.infectiousColor; @@ -66,6 +69,13 @@ public class DefaultConfig { groupMembershipColors.put(GroupMembership.OUT_GROUP_HOSTILE, new Color(229,229,0)); } + private void initPathogenConcentration() { + AttributesAirTransmissionModel attributes = new AttributesAirTransmissionModel(); + double volume = AerosolCloud.radiusToVolume(attributes.getAerosolCloudInitialRadius()); + double pathogenLoad = attributes.getAerosolCloudInitialPathogenLoad(); + aerosolCloudMaxPathogenConcentration = (pathogenLoad / volume); + } + // Getter public synchronized boolean hasChanged() { return changed; @@ -105,7 +115,7 @@ public class DefaultConfig { } public Color getAerosolCloudColor() {return aerosolCloudColor;} public int getAerosolCloudAlphaMax() { return aerosolCloudAlphaMax; } - public int getAerosolCloudAlphaPathLoad() { return aerosolCloudAlphaPathLoad; } + public double getAerosolCloudMaxPathogenConcentration() { return aerosolCloudMaxPathogenConcentration; } public Color getDropletsColor() {return dropletsColor;} public Color getExposedColor() { return exposedColor; diff --git a/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java b/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java index 90eb6cb21..a52ecdc48 100644 --- a/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java +++ b/VadereGui/src/org/vadere/gui/components/view/DefaultRenderer.java @@ -297,10 +297,10 @@ public abstract class DefaultRenderer { float maxAlpha = defaultModel.getConfig().getAerosolCloudAlphaMax(); float minAlpha = 0; // no lower threshold - double maxPathogensPerArea = defaultModel.getConfig().getAerosolCloudAlphaPathLoad(); - double pathogensPerArea = cloud.getCurrentPathogenLoad() / cloud.getArea(); - pathogensPerArea = Math.min(pathogensPerArea, maxPathogensPerArea); // make sure that maxPathogensPerArea is not exceeded - int currentAlpha = (int) ((pathogensPerArea / maxPathogensPerArea) * (maxAlpha - minAlpha) + minAlpha); + double maxPathogenConcentration = defaultModel.getConfig().getAerosolCloudMaxPathogenConcentration(); + double pathogenConcentration = cloud.getPathogenConcentration(); + pathogenConcentration = Math.min(pathogenConcentration, maxPathogenConcentration); // make sure that pathogenConcentration is not exceeded + int currentAlpha = (int) ((pathogenConcentration / maxPathogenConcentration) * (maxAlpha - minAlpha) + minAlpha); graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), currentAlpha)); if (cloud.getShape() instanceof VPolygon){ diff --git a/VadereGui/src/org/vadere/gui/postvisualization/utils/TikzGenerator.java b/VadereGui/src/org/vadere/gui/postvisualization/utils/TikzGenerator.java index 731d20828..80ce0cd1b 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/utils/TikzGenerator.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/utils/TikzGenerator.java @@ -156,8 +156,8 @@ public class TikzGenerator { for (AerosolCloud aerosolCloud : topography.getAerosolClouds()) { VPoint centroid = aerosolCloud.getShape().getCentroid(); generatedCode += String.format(Locale.US, "\\coordinate (AerosolCloud%d) at (%f,%f); %% Centroid: AerosolCloud %d\n", aerosolCloud.getId(), centroid.x, centroid.y, aerosolCloud.getId()); - double normalizedPathogenLoadPerArea = (aerosolCloud.getCurrentPathogenLoad() / aerosolCloud.getArea()) / (model.getConfig().getAerosolCloudAlphaPathLoad()); - generatedCode += String.format(Locale.US, "\\fill[AerosolCloudColor,opacity=\\AerosolCloudOpacity*%f] %s;\n", normalizedPathogenLoadPerArea, generatePathForScenarioElement(aerosolCloud)); + double normalizedPathogenConcentration = aerosolCloud.getPathogenConcentration() / model.getConfig().getAerosolCloudMaxPathogenConcentration(); + generatedCode += String.format(Locale.US, "\\fill[AerosolCloudColor,opacity=\\AerosolCloudOpacity*%f] %s;\n", normalizedPathogenConcentration, generatePathForScenarioElement(aerosolCloud)); } } else { generatedCode += "% Aerosol clouds (not enabled in config)\n"; -- GitLab From 2d2edad52b374210008bc3646df2fa1a62d63d92 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 2 Mar 2022 16:44:06 +0100 Subject: [PATCH 54/83] [gui] Change color of settings icon Users complained about contrast between background and settings icon. Now, the icon is highly visible. --- VadereGui/resources/icons/setting32x32.png | Bin 2622 -> 2029 bytes VadereGui/resources/icons/settings.png | Bin 12121 -> 14237 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/VadereGui/resources/icons/setting32x32.png b/VadereGui/resources/icons/setting32x32.png index a2b11698c15b0e88a278ae5cf1332502683ec6fa..5431c6f0478d770aab033f4d8af73c2632f7f220 100644 GIT binary patch delta 2000 zcmV;>2QT=(6zva?Bnkm@Qb$4nuFf3kks%X*32;bRa{vGi!vFvd!vV){sAK>D03mcm zSad^jWnpw_Z*Cw|X>DZyGB7eRIxsdmF)$!8GCDFeIy5j~=c|nX00&h`L_t(oN4-~j zXw_95Klk;!&t2zU>U?au&E0KkDQStpa`{N445DF7NRY6CD2fOQjKIGnNDTTTqKF`W znq+A9_@fjH!C@-0tw>XG)4lG!d))25fA`*BpU=6!b9b*c6@otFd(Ziu$M=1{=gcDh z8yp~4zAK_2Bj3G$+_wTtmMn4Kx^*jIeoCxcx9*U~<9W?uv51k8k=2(kU+y!f?i*IK zof8{3ZhUOZmMtgRT3ZL!tXb1y4ii>?m&^5}-EJ2)n@v1osR9tQ)bz#dNdX;Sdf@vpe8+65X%n zNKU77vCr#$0~YU)b0FX^2oFkT|ALYbR99E~+S}VdY^blVb-CS%=H}*xnwpv~!N@O= zXtXpMjfttqw1`a4h?$wFh{oc7BA!T!46KFKQXvJd&*=KML&L-0n?rY?Bm~>GZ97n2 zUjDAK2=30Im0qI2iHS*AZWEg3fIb%KcEnz`8H7jIGvH_yUXM%8XQ5OonfxOd4nKb7 z%9XGbavO?0U5?1>CK7nME%x?#+M?#{16(W(;xlI~@ z46Q+E)>c(j#TPAF^lWui)n0h(R3ec`abHOYkU+<4Yil>*crB&^N;vCFna`Vd7slAq zy@aYfs-lDUXUH^WU^J1&y%i{ z3@C_9I8T9cAwZ#KOC|V4K{muAlg-Vp1N2nt^Zx$+edcE&1QryJg&iFo&-wlS*CEiw z?6!b`%jGnegt&SeBcprLqdfYtV5S5cs*X>v0|pyJ4u$8BsZ_*PHP*`?R7UtK&oJ#&UO0t;iWPA>)r~Dg-Lhr9t5&W0t*NQ$O?+Byu~nB-)0v%kT0>c0N%;BAbI(qbvm`D1A&%{ zi0Mf%2^6n?A;~a+Y^bUfPC#%1H|B8|_v%b6)=n`6Wm{WYeXCcm{tkElCR(A2h#y6W znV)67*LB&N*K+=J;F}4{te1U|wA7r_TyBwwMdf9cNG89)DcEC*l#m{v@ReGm=S*Q&-)-RzaYmI_T!f-eoZE9$kkA(p|xqby* z!h@p?yX0RE6RZhTssyIO3Y_H#J>d3u#msa>x}H^&;lloAT=$iDpZp{@0L2_M5P8t= z_Rh|K&L0qxtrWtXpgWxo4LL9yf0Y9&M;Lc2vfhR_!{o$-Og<{0@`oWsH5?il9Sz_J z@)=)p9cMwR5+SFIAMv1k8LmVi4Y`?#mVYbE>diw(_d5_Sx*XmUQ&W>tFcm_P`wZ9o zrx>?mtQPfPH=g%@n%he}Py)R9+nO31`^lVt9-#YaE&C35LOogx#7ED-vP1$|o+x;O z-kF}BKG4(C^B&kK!@QtazMDr$9ViB>*E6(Qx)97@K}xwh5s!&TWJ*kohedciBqk>( zU};Rwag8MGLDruHtD5rW`b7nE(wksBm9>q9x!tDrwB&^AQ z#^dp;pz~^sHzvZue@yO*IYR(g@n6v^V6yD=>C^AvTixN7?c29s!1x+kjQEb?j&FgI z5zJ}W(~a=#q=HbW`{KomyYk!q9VKtV+hE+hdGp+j8#jJNzu1jp>C&YEe{ty-0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}m;000JJOGiWi{{a60|De66lK=n!2XskIMF-*s5D*Il zjou{$000R>Nkl3&275?tMZ=Ls;@xBnd#vuX6IDd6QQxzk!5Kx8C@wt~;AI zZ@#K?l>fHj(0`#rXm4*f=FgvBFfuYS9*f1q`1m;Pz3)Es_Vhdx3ti1ebN@>mK=gxh9Nkc>DJMX*$Aw=Pd6)Rdz(`@3L zV>}%G!L7I5wzZ+50Y7bSMm!!bw`_aSXPc||{TE&!vWqX2;7l9JWI zU~s(^2;5RxS^08rZ|}0jix;o_@{KosPuH|1kP?It7^Zp0YumO}9y@jnQ`6IB3l}c@ z<${`;cW=JwreCRwQt{>+Z(Lmp48wqv$smm5+MWt zz_zS!EPrciYTLhm|GycfwU%YA1waFVz&*OIzoM$@*i`|jtE+=<7?4t?0B`_|5JELw zE9E|i=lSrt4=E%-079u|nr5S>s*OTQNFgAEfbaXK&zw1PhR`dMJp-Vts|)dXyt<~Q zW)t`Qvy)R(ANTb1lvY$!Y^IblAp{)9#nf~Z@qa`Dp6h`NfqV*7RfQEWVVXJ!0GT`2 z^Sq#-HIQ*@B;1Y@BdkGaq;s)2`U~VsZ+M z66l%=Mk%Be;6i}=9IofVaeXkx5DMBbbPYlXq*AHw!J(mzU#hM?wQBWh7`je;&L!s@ zzJKp$0kpKVAQp`V)~#FD5-KS8j+7EY2uLB|dLGW68$~ALAQZH~D1{ILTyO}UrI~XM zk)zykJ-8l+Z3SQj3Oo27lz~&2cPeQOYQR!YDGX2Y^6P7*s`BWLef) z!!YhN4C8B*kh2eL*zn=-@Nl*b_w3n&($Z3_Sg~R-91gc|&RqbQnvQ}CfzskaD2#y; z0!rze46k@bK^-8KpF81_JN7uG=PrP)*ZpB!ocMwVAe? ztz1ILgy*?$m6erFT)$`$IDhwVDhP$X%_zM@+9d!@QxOc#Ln@U5075CXRaL!?Qo1mm zPVbx<$MIMUgF{0PR99E;0HAoj4^348DZz6hBRJ10ALlZWOuZe6od1ocYN1dl^c*4h zD(C(s;>3l3rfJYL9ntA2IX8UY2c_(SK;=@vm;%>zkrTG*WHR}$bUNKRIXT(U+uIva z0ATR+X$%YuR5vsSh8fv_TapE_sgtcfO8JV^>+fqDNKQ;=}0Ex@H}s3ud1r`wrv}S4;}j8{8r%s*vcx-I!FD)%Ce^wObpCu(F*K3-#B&Xq7x){rfioDc){u`kbs;Yr0 z42gIgj^jW|DSt(FKLJ36lq?#H{X^HZL|a?im2br#9XyE0#KevD_4Tc~rd9JC07X%u zstU4dDIo>Ve&z~KN{LJ+jYK>fx$paKEEfAyI-Ndh7{*FU>Eg-B$rr!1e*N3))~&;? zUAwM)Cp1hGmSqJQWAo&U_y{;o2ChTE7z1V5@hgRd&wn{w*MXC9;CgPp*ZrxfsjYqe z{Xeg|=9+j%XXkILs;WvRB9ZZ9$B$#zu3g!nW;=iCsi#n1Uyl1;ipomj^#~F@uua=0U!h5>}-FRT~*7=%RvaC z08A-_FMoyL(O7K9@ngsC9vvNhG#ZP&#W_!2lz-uQ-e@YF?oK6>okB_<04Sw~Wm%2O znwqd`)v7rQ_A&rNLqj-nkFTU#H`q|*oU z#p7f$11C?Oynp}x{de{B^sJA^Vt`au@J(Xn3#Cs znt%E8+v;w(0RXV=)mL$1U_hOSL^uc$J9g~&!t<^gKy!05q?C%Ps=?yoVoeA!MJaXi z+J3e6AD`3KR_eKejsO4vC3HntbYx+4WjbSWWnpw>05UK!I4v+YEipG#F)=zYH##se zD=;!TFfd(UAqM~e03~!qSaf7zbY(hiZ!TnMW_bWIFflkSFgGnRHdHY*Ix#UiFf=PL XGCD9Y0n$4e00000NkvXXu0mjf4r9$@ diff --git a/VadereGui/resources/icons/settings.png b/VadereGui/resources/icons/settings.png index cfba0c687c33fedc66064e49593ff17bcedd7a8c..9718670ed459d099e6cb48cc92f765b4952f668b 100644 GIT binary patch literal 14237 zcmV;OH)6<%P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D03mcmSad^jWnpw_ zZ*Cw|X>DZyGB7eRIxsdmF)$!8GCDFeIy5j~=c|nX05=6mL_t(|UhRDecwEk?0GPotm;w6#=iYPY&ch5a07;OQ^^^CV zbI(0@J?Gu!&6`2!O}vRW@h0BH4=ai+{b55GVO1m&Sq7SS42p`1rmCx}&kha_j#$wf z4nLF*(9qCOQ(s^I)fH`R_rc1UK>)8H7mh?i2M!!~YkkH_1Z znwoZypP8AFpz!&0Ivs+eymkHh^${z2!{Pr62Y^wE7;N;iaNm9RMJg&P?nbD_6whfs zZy?|RcMS{-luP6di0j$`ZomEZ5*VPiq@-jg*5Z3`CzjcyMdQ?|Q)N|EReN}M!^*Ra z9t_JG8@D79iB_Ba4TtN|0g6|yTv-9Sx}&4xCtF)vpWd@)&-d=QvkscmU#xmyifTwE*^7fJWyq-AAg)#c^o+mOVK;~NgwO{X?*-dvhYCTlS0cSNJn zU)i>8+wX3=`R1Rhsja;cUK%MaDTziaD|a6}c<}2`k0E3h>%vi7Sy}m(n>K9t4_s1; ztdxrj+nwoEqjEtmg^5uXx9V=Q)`>!}MJ-$YuAz+kd+-2`sv0}yh z*REN!69Zp@(a((1^mHf;n6glYDzd-v}B z6Bz$)+>IqPKrqnwG}z5I-Snf_7d*La*|I8IM8SX|E3o^&pXSvvb5RW%Z)|Mbgri`a zDP_@!VitL9(V|}SqY9^NfG^i|% z*c9t$9+bhF;hj5o{vPh=T?Gsr z`xt3!YpcK=xEr%gg_h&jF-vCh3Xk@MkoUgVUw?fuMvB(e)jbYle>NP6R27HAu1+{Z z-3>R~@EaS}umAeVlP4eLi3j>iYLn|?6Nmw(fj)o*vdZ6(G2mj1VX4Y7nB|z7?>T(< z@HcRz}VH>j7oC+zh(9G}tr+ z9HRuMkiUVWj#*J5sKiqB#HNiKKZ81=Rwj`82rO%8Tl4be%YO`QUOzcG`N}=_+%tIo z{P`u>8)SNT4T0&g@zz^!{SKzZZDIrpeIwXSAO}mfX_j&jaaZnp>7|!Gh-et=>Nea( zcOz`aUALjCva$tEP|7S^Ixy9kd+;JBJFC0$);->)e+ zSh$=2e)FbHd-FMf+zuF^X#`RobxzqAFJ3%aS6jQPx~8UaYHCUbR-pM5%**mLzZaLN zTrE5urP#TL#wR9Xy}i9h5xx#*_!gY*?7DU9#tt1iG(|PS8viG7w59ROr3?hNT@9Vf z0T{p3)%Cwn&%eWLGj5B!s<xjP}1V1NC9U z_X(6!s(JNJH(4NKV4tjbpql_2e9J8vs8o1`C00JAJX>__n?tB{l3IvvQ zIpqbBOGg8ZS5aQR0!!F0Z{51}w~?D0QAr~>)37aspD!5VV`J?&4xb0VB*rJM3kP`i z*=N%@qjzEyW(^7hE?M+?4SIL`GUtToCn@2l`(bo+^ca?wQBhhVTo(?2&d=a@)t64C z+_M0M#;-;QB9~6SpvaXrUkK(S`0`02kvP!S)#WymOM&ac0SGJs!?**6Y&7p+i7XJm zQeh#;m46`t7ej4Xm^!A%$H!lI5&HlUE)lM|17ON5!V$0T(l8%#<;fZB zz94_dk!Oj*#Kgn}gtOq6Z2cz|=Jq+j=i~8sya?yvnf?3sFVuUBk*~3-sp(_8ckliM z?2OAW8g2)!6kcL>;-Dt#jgd|BsQ~3*NeN9RrzE7Nrb1JQ^Fq~j&jI8Fz+m}{mo9w``=IwO)dL{KWjO$k zZyg;SkJi=I?M34cVhTT6R#tWa=j5@juC63Hm(J(WbR0O$>h0UN|BtP=-uk1#;~%LE zET|sAI9P;I0eHrkhv)S1iHT4mJ{B6EoD8L>QfAQcZy_Dk(s^e_;1s20rJ-_!($W$s z$JK7@7HZq%;vm#@&V%4PfE)usnMRyAdGgnBBmDl!lP8lRSRyQBT(W>pV0?;J-+lMp z-(IC;SdV711jf{*O#LRFA)7rV_=H?ijB6a4>8E$Z<={ToPpWbrU zU3Yzc&6+jaI3OHs9b9Qtp$>qQI1D~K5)VyIPRJe35`rDeDo<;#|>5d+&iY>W;Z$n9X>%wx48xCNdQXYE-yJQJ>$nE_(>k$ z?g&*>VAZ0OLP?c~P|AZ2V3HAM`Lv8Ki8R?*Nnu zWv~uFB&VighYlTj->Oxs_F;ZQJ&vjQa*x>Kk8pP#F|< zo^ntmNE!!3bge8%IatKd@JMK2U??=rX`bl>^WrY2gH^x?+`Nfct^m^2aB2jBCsUd? zO|JZ&z;q~yjpTHS4oRtP19&<@Wo3oz6|^j-=5qkbWCpNtO#i({jvjsAjW^!-f0uF} zu;34a_yWez(9pZ>)DOFPPrK#`xMUnbWtPuJ$xSAc*d_PKUC-Q_&gnfGEf3XHSBA=A zeED$4!g00?!)DScHzb=1d>+skstc81c8Oq?p$-j4Rn5!O2JYriDV$N;!oCI}`quE| zse@UovT@n6hmIdV{wy}eeONY^WG`S^Ss>70w6|#0U3cF3?bU17ZlH`E&>0}t5}=fv z7#`{DnTvA(AS0a2qnz#s28W=N$;I-cn07h!iiCp+3dWVCa50;v=~;56xzenRP(4GK zZwAZ5bZBbI*vjbAsGJSTL*=EVIcEUT_3nNrM;MLAPaQsd_%VpiAY64PFqSG1YuBzV zYiViu`Smy5lx2J|unm5kd@x<}`IPW^f&+5#Qg^6-z`TgdL8VGXc|~YhLmdV7oKskb|Tdn|QN`q-YuwB$Mg!!=aU`D7Yi?|IY+eswi|7zA;eB2a;OY_PTDp$b96-+NH z35Uu`!ZzfDf!{$HS+AbW2d%qMaL=%M>(;GLA>1pwa5S36A(T?4LBTuPGUo1N z+@@<9V_fe$FLYtU#iJdUhY&VaW!QLDNxJ4WIRLLbEr(QP8h3Ts4W(-j;5g><^7wK? zER`$Z=_?pdVw0#le1iR`idM)8#g$=~0O7rI)LD=xb@b@bpTW`jAWm9M;c$3eO-;?F z($dn6F!~J`lNE3Pe!V@+x@Zf~@#7~>+z)4Xkwr;C^B`lP!a*lkgA)Lq;2u_9kOQ#8 z!r)3dJ1r?0OiWCKE?lJXGi|TN9bbj>Ho?IWCkW=%I4Oc*XUkZx@SYAKQ$J1;V(=L4(4Y_aytnKNGk>poeX3yX08f_07JsPZhF z;P$q*w$=1N-vJ2c?F7;#jl5EebSfR{=)8o%vc^Yftgpl7sx+fZ!&sh`2g`7APp<7C zly{OGdRlG}lt>yNx_(*8=gJ2W$H2@mCO$Ql#xXIHX@>>#2g?@D##ui(p;nd)kw~O+ zY;5e}s#U8F4Gs>@`=b_%bpV2G8M$=n(mqT%J24ZircgT)4EaFE>AY|W8$UkP!z=>b zM(pzWKm{4C7C_!Qfkdq=f5{oR`u*~VK-|TGdLDA7Sp8i6q=-)=&8lY7`D9T)SkgRx zUh*!@lLwJ2h2x2vvK2Qc-%p(Plf}z%079JL;>C;mF!k)j5plKd38WKV5RmsM`f`;?P^xP`so`YPyc|pP;oZA;pPKLO;>&daV&?J3 zA0K(Kwm6hF&BaF-hL{`IXLmiMd7#j%<#bR>TQ?s_ZO3wF8)0{$WIgUqJ%4bmv zr)Qzw(|MzW!GKhC-i7s4;v5_4x$ZsGB{(#N?E_ zYp*mK>g(@|$K$d=p9@#S0bqclzP`TY+qZB30M?zH1LcG1U0pq5IP!e+rm?YJ(%cilp)AnVBJZ{A8W{IvxQLD`Cs4+G&^oi~1{=ZDum5=LO{FvY8p7ub zh3mug^w{fX&;C+6o&LQ-e&6tlH~`j~+6@~v{NyBzIv+Ts{r#Bw@sFsih`N_5I69;{ z3&=nq$m3O;Ce-p-)K4e1&@z2v~h4&gyuUb!0hvjBs2olH3%DB)uQ z!}F1`Ij#A+x$@12bSl;V%BfR79gD@DqVZ9NHX|>tgadFRxf`><789Kte2XVNZ66_r z!=Z)-ekC5AMO?Z}IfE_*fDF1}osI;{`!eN8{X5wo37ZpYmQ$+GvaH;tQU;Q%EW+&v zEL4x>xVkLD@BrETBCvHl8U`_|{yBin-gy}RJxxtb{87t-zrudm4uD;M`P#K>-;28+ z?KK_JhWk)iYBNyCEpm{xgKcBD?aGAk=!21kDF=stU!}x#W#EBE{ z*|lreiN(B0bXg97^M4q}zg?}Zt^8DKPH<30vH6qr9H_>5UwPL_QVg05Ab9P1R=N}8nuj+%RokVJ}@_S`cHLt zck{Yc~@6gSDCv#I4Bx7LZOtq zhT3#Z%c34H15c_l3+DvZFzOh-p$M19maFjPhU7>KLfZml>4TSj8bti?ixE1Z5SLArHLP%|h||_3KOe`ud`{d)L<2 z*WZh&e(%PO8}HzhKR!M#gCPTmz(<>;D)TA5y8V2oeA>tO^2U03r(Rl)I4R`}M&wbO zPAbpRQIB(Xl?8Pe5Ad2U)PkM&>vB4tOeg~TGAoTT6EQl%X7V_A`6Q3(I9-gB-59fs zk_dQDhk<=jo`I#jc<9jEVViG4ZP7D;?STObF5-KC*h$t_R#t9lY;4?vss61n`nIa7 zs`6wqX)0$UJR_^2Z5b}EbbNdwbg`@3tas?>iWM!Qi$p^hU|6A$X<1Ac4paw#ptBJY z56FFeO;edth2vDurp=;q4Hy_y`X?~}aVHDp6WDYpWXCOLio&LRgb0>{jGEC4Ish)A zS6_SW6U&w@`>&Vt8hMrj)YQ~8!04aCoxcZ0zX25$^O-#>WXII-K?fj|&ovYD4Ge}x zar|TV%5dj5FK>XsQHIIr25K%R&@_#Uv3(s4Hcj;;pVi|aj*X3nCMT0w=Wc#nTUJ&o zfg4lR*YeabgyWfpAbn(!22)f z3#GwN16N>O|5L2>E$LJWcFq`>R5*`nx*A$_2|wT9K+N5>wK)2fl$5w~M9=c1C`h{Q z%Cc#0&@99WEk6rL)3Ow?kvPI=Xo6oFMO(B!Itb%@BWVJT!J}9izxQWhTj40-WZK3Y z$eCtkxpGn8yisg*0!q313Wq6z@xQRZ-!9C8aXAYZF~UOG7(F zz^%m8c~M?g)(Yb{*yy4#%K>nAX328F@BDn=%aNS!*)1B3-`8`Ux718|h9?ak4=t0S zR*!Iv_4I`UeoQ{ zabHgOd@f8T^;5qh`Esb--F8r9aBN&`G!*mONL}^pnS5eixR%^DH5eFfZ0>JG1I1a>#|ZaYum+2L$C_+(=B& zaut4E1je2}%&`Kpd2iZ$a2Z(`NSMFas74M3AGu_?z)hs-Pm%dfJz2SAcgD$-auyKQ z=wwk}4W3ggMlQyhxDa`O03ty{P5`T1UzW;*pwo;?23xD8?~i{JHQovy7u zPmuRzIwq7UwP~7*G^-3kbv*ri2&Chnwo-l$cQMHF92hi=fiI?Eb(ifMIvDqnOGc#l zQ70V~ZRR_0G%P#IE=bT0TUl0GzzGz78uba?4^Wp);fAglGfw-tvwwu6(hG$im8eJk z^X=#Us5l&f1DM}FAf&CJjQK56Ui;$GJYM_2tB#Z}Gr&ffG7T20=YulZ2yJ~F`vbtx`m5* zX{5^Ma{^KmR5AyUx3QsN$Htp){`B_SZhO9|sp+5ji>v&rXjmGS@%w_%%Cd0~S&1-Y z7@=q`!}|!vgJ9=G$99rawRBF6N+Hse3T)g@qkg`Vf#gHbbUMLQYFaj%1O5F6air}* zp1B(u0QH$~V5t8f%h4{dZmrX`L&w0Axik;HOxvoB%F+jKmw>Yz0EHye>2#{RyxiUW`J7=PU?Ul1 zttL+yoxt)==ErStY1RpxT=j&QxbVW!+4#eY@slv*qMnj5-*_T%lI5@-Em`U}jNvs- z*tlVhTy+g`n)#goggi#s#0!MfC;3q3^mIvOG`gj=we`ar*02Akn{U4PAkzM-va<5W z_#vLjVcfddEr;q}*FKRGZkFoCal{MwFa3kLW`p+M379OK2LY?|535>PxzC<||lC@9pjWm-_np1B>~w zg}%Pk#nsjE+nbtN9^yOwe1pgJ%eE&cn5KF@yu1q0L(nn65*&iT_@`}U!#pxF?8?gY zJOdpMN9CG{gAqPlTwFtksH(2MlMjykFN|c(0DPpFOeT+F?f5gSB|r7eZ+`Qx&wu{& z5C7vo{nKwAK74rp@aSj^Q%a}^cd}o(&j$g&ky(VnYzDFiPu6WKV`r6$OeqyXsmq{) zl0~f^d85P1itC4mhqL-vDAuoMzT*1g;_$3Gg(LL?MK(QGnm~C_h34VNk>?}f>FL?; z2ohOk+JK7*9z<@b(*t0Gu|y(~Wu)w!xgnnl4h{~MAvD+2)NIFQ!s-5msYJ=`v@O9(?qOO+RS<^)jq2X0z*BSqjCiTa)Ml0X=$i!)oMAujwRxu zzTO^_20iJUSLhg=f{&JOl#rX8zy?g&2 z{Kt+SJ^D1KtodLXX@WF{cRU~iM=CKxg@-&BmF`=9zLP;DQXC2wg+nV=th#G-baW*; zZTdv@ zz9bo$s970*CXVkMMysmovFZ6a>|+-6s~Oa9Lq6t@@MNs_uB}_B)|pEtS0JD#)I>}W zHY4Y_hyx(-S56B>unvVUw>>@-ISo2L4N>pasC_|S>&uS032oK|J8Wrb7gsD`*N2Kz)s^=!~yp2-#;CX$2-FX zECH-u*CKv0#|ou^mg17(0p0~F3#LiFKpOS^bj!%Doj?3sQc@ay=%I%{*WKOyHXQA$ z@+}9HGo5-5Jow<}kgt+u@GT~-%YkvPPT{OfgNWn`_%c$xVXRES4X2D1>f|GI&65jr zr75W62lO$1MH~R&pLpp_PE7Czp+%rH2v*Ej!5QQw483b1CnUxO3bC>|oPcpZO_l~> zO}ejFjM=B8BoeBrty%t#cRcpDI1>JLX=&*#ptXET#=D)Aams6JYk!-1H8r(OH2zf5 zJW=%Pav*QxtW$Lqu03)EsN<(IFs^!_T(;-{TrTCuF!R7KCkQPwsKYpHkU&4PrnLMe z&5srDc=XX1o3UWhU~~Yb!O9b3W6nY9YHLN09d)4Bg9M#Pbigx4nFf_9rJjE>aC(eG zURqv`Hu1ND!=Z_Z@zFDtI)QdtVD%zcu6WEUD(2@A)7T@Fh(pleTyHsFq(H~V$K<7uVEI|b zw^aHW)bqf&uP^ZQoIc8lpgmR9HI(w__(E~}5J<|78Cvy|y=8L1H<)xv9x>~kU8Y(Se z2ZVS7qcV2VlZg}9G^azVdX~<10`U0Hzs50(boYA8qIQOQ(x=0De!Pv$ONxKJmm8f5F$S2;TwNAdPeFA00JMANd7{mZs&x zivu7Cpzk_pc_*_SbiC>jln2vTuF8EqA!rvVbtJ*U>SXP_`IN0b6fG;0mibPgx<1_h*2h zzMn?@taPO|-BH$0N(9q<>hb89#9g|AG7DcntA0|s0yd2gfH(sX)9IN|A~7Oqgp{Mf zi=%(jr%s*vRZQ>S!c2U=p`jsh{``3wJpb-72Nrw^K;>e5c-SW%e)!=J@wie5_;k+N z5VJv?8wQc{D!YC_9Y5KL1ltl`}QC?j;~ z0>mW<>y_cjvS8y}|9SS8^Zyj~XB?yef)dQS=llBlzKAKG>-&KHR`7z1Pk6nbA2dGy zRsf9un~yy5$VUqKK?nu^qzp%deNOU^IKgqms0eICmJ?W+4v-Ft=rdOU|CWQ<3=GS(%IuiLjZ$Ba|1aX{0uAea$kW%1I$pXJL>RRwR2ymIcZz6=Hdo z;o=s)9^uLYRVig9Jetauy&P0|)hE;-L48fn41Zh)0seE z2TbDN{X33E)pVZ#VK17#2{S&UAL1432vwZpT-+%DI2Y)6w?fV@ef{o1uU#G03 z#ElidtSR5yQ-fP7L!K;z}IzS6WKF8pcr+--Z846wUett(iJ!uo(mE%WDSHPA{s9ul?QQp%R1obWa{t;U5EPX2v%8Zm> z=Ps9zrYYcOBBR5xIY0OJp|!Ie2w~Xd{(*skV{6y0ZKthl@`52VYCde*1wPnkezi4l7 zznve%hZz4aab zo4urLgbo^cz9wE)RyKnvX@F1F;H6ofsd)wLkj*QQC=ulHUoW4&eY#pH%XAdRf#&vYdc2P1m@i7JLzR%?s=Un&AN7-gwhZw{R-vWXNv^@zHKFmEvac zLU(uf2{hsd{r&wfVDIocP7v>Z^wCHE3qLd9An{Q!2M4Wo#+lVprXxiMm47;h%a42% z3eZ_!4;?y`Mx$on^~<+z-THqvZQ68? z6vBpEs*Yd`PS(yOlwmJGsW=U2X&I)^iV8CT2r~4f%4@kc&a#{gaK?hnoI1>)Ivw&P z4A2$IG%NS@G>vfO5}v-~#Xp>)LuKU^l1A`}=b##&GD|fOCa;0qFo5d&#um!B%B(K` zW+3(zzcw^9WPcZDei#cB0RH#@3V#cYjk~g^rlw~6#v5;(diL38`6tA+-9EyY!nZ&6 z*kk{KbL*`AgQGMwIzgz6AK-{Xh|GLQ6OCrR)G8fDV7GJR}vr8@8etIu{uDr>vL$N`E>|16r+@(KD;#kItO>@3LY8x zCuHSECeUH_jvZ$ZAP*ZRam&vo}!mfignGr4k3o$;y?-U}>KkVDL z@4vb45!wzIHk)bdzVNm&7e&dr#=@}c&qnUp^3T^gz7Q82F{@-?(jWp$0b^I+N>hT&tO*pM-Pu#b%U{SO9QX32uV&r4jq zbm{kTTI1&g1sR{1_Y`osz%i2h#G{~V+S=M~L2J$3L+IdIFvc_|g)Scu@yVGPbfiGW zr-sy1!x~jctYIi~<=FI~%ujQ1BA5nf9lk!>K{awH$M!TV1R4Vl{sgjimvU!Ipvz6_@m zKGuyy%nKdbhD2i2toPXTX&yC_PyL{nN+x@;|KU^_*6CeCa0y_*MJR5t!E^2HKaHvX zEb?XwEC5U5000{m#|h%Oit_S1mo+r3QlSqSE<0#Ssl&lYrKjv{z$w;j60MocV0fj; zz%!i#WXn-wkWy1(!88-eq%p7zi5dr_;rSyOe38>FEm-S$+~r-*Z$Sx|7cgy`O{H8L zh@n{Q$kC%m-_z02@z;q&;yesqg7f_{)KQvm7Qlt|%ye{iejKN;ZwwC)FZgqTrE&mb zrn$K}IXN+Lc!?$D-+D?Rdz;UnP!k6 zGa5n>&nh1feNq!KrNO}5*zs8e4PRDKE|09Gtq8>tzQ&cr9X}Wv86KAQF|QBS6NEFM zMQnKZ*vXS8e`43JU8l~TJ=^)zQ%^mQ8T0A$=g&Vq8jl}G9n)ncB@H-MRR(7U9M8W3 z=lfJ|Z|{PC1cS(K?NtU}E!(zj+qc%NS+m^@v^QWXL(fbaq8ujaG^rglQsz_Rl$P2* zF`ozK4ziz@z((A=OIZjg2|_cN#;|;XN#pYCcD^pUVZh|pSk<)yU*tOvoH7EcV7g~Q4YQ3=<8eR>+2t>udBNkv%_lC-SztG zukV3_yb4uQ$pVoX{i_Ugya-e0o$r44yPrd}M2)QuAcGIeLD4iBSkPP!;DdSj+Id-7 zxqRqyr4X!#uWcm~ae0A-4|cS@Y^UnVF^+MSlZXRao)m$3J1<=LM;QM~WtGOo)!a>|pqvQn(u3;&>ur(Lt$OkpQK5gMPE2w~|mKigvK6M&amNi_uI&LJ#M zirnebXU=@4zrX)eSnvCxxtP1xtaT~Ad5Y^Q<4JZ>h96~pa3_P>*oUUL|)aAZ{f7*t74Bp+`#mkdBTemCU z2QvEx7Lk=J4LU$_aCd@etUTmes>MLjsjWSXDf>biE5LdMzY@R1`Q zhv-kSrpKvzt&zDEt|E5s+!?8@t$k~GX=#)L!C*FKhMzC^$R{Uq$$W^j(Xo^op-`30 z1;6fmbp_LXJsxALtE#qOzq05zc&;>-!~xpd+sknTd}I=9>Ou@ZS0ENETWnC|O3N2~ zeJ%lYb#=GmyuP4cExVdn5(mIq*RpEWs<-$9BLf0wD8wOxI=E!TMFs@pgwN-LpYL*m zB3BwiWmVM%oZHP0BwPo$>JGqjEWCbKLtS0H8Zu~5b%b1jdxh6dpZ@Oo^XCs?cMtXK z0c9ZOieFEmthBTWo6$}D>#NexYmBSjh>3}b3atMhYiMZL%s5wBF%buZbPg1U!!tj4 z;f2p0KYsj|hlYl}aO%{lA3$8&(Ac;#TvQa%9k#%h=gKFT1_$E6Yh1Vh)pVctby$xY z(4`ZME46YzE^VyDdc7*l{p zIeH4srmJ&Os)pCl)6?^982{bZ!%0BK{Az;V zV8N94OFMV$_;|Raq>5_}9Y8A1;{a31Wb9uL9QY;V`*N;9!XV0DIK|$g8t3U-T3TA( zjfj&~g*bpei}0#O@^#oIewj0wOpf&r3>+UC7&v;vjW@m*N7`B`pE^PU zOrjI&|o6Bwa8X*A7?R0np*1wzjqk+_iVDU%&pp!*E-99P%B&IRV1( z$jF5Q2M&A?27S){?8$u4zj0iFfn9m~?YDms_1(sV`5YkYF1LZ-+k?Sok`oi-aTp5i z?!d17r9>j}15Dk=F{53CV@{(Fdr{ZtaJH}3{8E&bCouy$0A;$A;4=Nos6K*8yI|Ni}LD^{#{a>tGxKZn7WZ-}b#`HzL@9R z{OLNB_lLLd*zsYRiaF>uE$9GQQ?y+I($mwEM~)o%2#o$3_AdOb_So{}%M;kcOr1G% zCWSJlJ%d%$*VjLG+ikb~C3;|A`bSxo63!{?44@9c8wnfF(Hw z68xkKo$tiJe*C-N{q9c=3=VeE_`1`7_0?Cue(3Pwf3s`Xu9p`3;Ra@mDcr5k@h;{- z=L`OntUM{!=A&remvLwE11o;Q*25);ueN~?zWh3ljp{{R-B=hfkb1@%Q|i^x-2%{<5Q^$#GcZa#VCcCph7IaJ96fgI!??@Gv<}|!ex11jW|eJd z>y`WHa*|neVevupvd~0Zo282*4EZLUVU4DKM?WkO~Y}tD^Z{GZAlvTk&l>%sN5_Ja3z)z*q!=0U-pF`|7FzYP( zFMnSNEa?moz%-`oA>0M~K`;B~&J=ZZb>o<}UnI{#_wVw2l%cz)=Qw7gR~OliM1Oz( zm#}pGBFdW3GFiR`BArSNpKWjdvt!4O-BVIh^6TB*-HZOK-&YFP(g74##PAB;2f&bS z@YNVT^#g=l|DS1UYPy`eF@e*;-<~>k>OY~(Nv(%vW6d8u*WUi;M~)u74|*TP(e(uX zOzo9&`pd!f-~d+|+y`(om!JW1If2iUV)viM67+TZ+q#Per*oWUzIgJLSAGRiz79{r z|4(cb??qkzIhjnpWT$*RoLqBU%RRtV1NH%R>(;INPD@kM4vsX9OvvU8yubD{VETR; zGslDcVx=fvJ}R-x-vb9|Z)j-X_bA7%hr2x&-iR{*|LQ0A0WYZW8T>on1;mNo-rnyt zHa0Hmt=c?DU^DquO!dcj$6v3;C*F__z=t-to1ZHQn?Gn|Kp%;!V7XH}S)SQ0V^wlXmEBNQT+300000NkvXXu0mjfN=C-T literal 12121 zcmW++byQP-8^5EwTe=$*=^9V(jh6`Azg}ecOxZT@BO`;Gx%dW zyW{TpKA()#P*cFhpuhkC09#2>Rtx+K`|p8<0{-rmcsl|BJhV!(QaWA>$JwY*!t3iU zp2X1V@Q96`_Qt>p<3l|n4*I|1AE(8o$~V4a;vrw_Ep7CO9GEphAcd^<^R#@SjL+BH zAuw`JC1`o)>;{wP(DvVZiB-XlL$aUGTg4>(jUBM(p~mEA$Z6t;I(kYtAT@-ug2;jP+l@w3yZa)h=_<=Iy$-@ zXa8j;x@UCY;qiftKqI2KxOnQ9+gO%x;v@4b*SQ85%rx)8Px=LLgCXG?IKI@poS&EX zs>5A4Db#Nk;56^Za{D)k|K}(xi$cTU*0j~bA1GRcXY4Ih<-$$xuY$O_xv8}xWm$lY z;NVdKr^NAj0?o0Z0V} z8^g=>D%gKrKfGc7L7Da}Dj*<`OsqVE0)&q-_s7skmgtu2b#v%fKCExRPEY`SeSL1( zMFcOyz`b}n>dMFa>xRZ3Zo{OJNf=*zpCxJ);;8+*h}(>7EW<+oIv>rqXEuNQQ#8Ii zp3{!BYpn$VFzud$5FvP|4*?rLBTZyZ+|nBbc?TI&I8BxB?^L8agaPBm57tMkovYvM zr^^uKV<`BWKIY4hF%qDo`gfECD_TP}JU07d@T!6Q-SO6SM* z_W#?z_-XM}3cwcA8l7{yPTa9^an<>^%(AnyRkMdvPcY`ghQhB;czQ4W=IgvK1d-P> z5!ZHi2e7cQ-BHnSw%^&3YBsfSMfK4?G&n7i`8_m|P7S{i>C|oYa4L5{oG~pkEuVQN zmgH%sn?eMtw>}-sojnr}5}NP(<^oOc`!I;_K7d0a3eW=a6P2c|S8>d$8L}{k5k7fX zd7Pgc0KRMg>E-3IANcV(dfLQ3a|14zco8f?Fg9_Q^DQN1o7=$zhUoWyil#d~umAdc zjT9pS4XAH&#Jm{|ibEV`DhsIs;pgA3o*Qf~?E}3WKJPQ-=<8_2Q`foeruh3_|4kG6 zXt}X7mMK?g`m{<3Bw-MvM6FH&-TP{K- zXp9O_y8H5?Kpg-YCM8gNzg@1c9UKz!z7L|?eWYKd+3Qpv7blsusBlK%AcRJcRZfeCaqrp84_`&nAQ--i+dOUz76ebPaf!5NP>Y)HDN z0~mpi8DsBinu^tP1%6alvubw+JhE3;X#B7lJ6~>fKh!LB-9|YWFV=__0bK4Sxc^RP zHM@y+c%9LwANWgEkWQ6q5BP6?AvV^$)k>tA8U?1)x&s#cG)X4Po|i3m2j1@Ljf8A@&s^npTJAmlJc0g zcpWd)Yhb!vc>3R8ju^K4)K6khmuSjpfCqqX#mp>|E^{5fkEjA2NWvuLp>FfPziI+c zFIkqWR>BDaASftkmMP%$AdZ4fQON!H2L(26C65HX{IO>9D{m`I+~4O}*5x!|M8DGH z?@GI`w5*p0TXxx5Q!d78Diwiv=9b)ztm_S1|v>##`oK@bN%Y1h9CSj?DddS8vwxZYclb=0K{l z(Tynp2#yAvop1j#74`h9SNHIk3TVXa{f;9Ae%g2DBf<){w$dd0@9Kh1Sd#SS14#i& ziBAzV9?LCi`cksbZ-J@5`j4?VK;>%F$Bmf^t|B{W@&3X3urZk;~}O! zL<1I>yX-W%hThH1#uM3+=JwdqtJr`Tb=71!DbHV-bF(X3Bme;#c@LMOvUz;EKRzR5 zPBQv&Du`;ay3!ua?=YJoEF|=ArQJavh8}0DsRi&Rweqv+Vz6yBLTLH;F8qtfvjc-> zX;gkZV53;9w0S!Y_L753Be~L~`K#W+D~B0Q=B?HSaAmvMj;6iT<#&381k7i@bm2u! zU>Rkpb#sku6QgS*As~DA1@q_WOQm&%bgYQ2`FE?Gk?7%TuFaur6QOG^!er@$ecFHM zl{qWlaLpEA!|tz7!cEY@1@>&tjt#|li3aP7B6T}iYX0+rXzsW_=EXI&gx}3~$NAbb zKn7a+qNQUJP@6naSCRY=$BU zISEQzJ3G>{+$k5(N4@0t4&P)7SK79AJ<~ zGlrC~9U|m+!)pc30WpoZ&!_33p;C$!B-zuRKuaqt8Zp0{hpXeo>l~P@tn5!5@>h(e z^a(^=dPq=3y(+V@%gf6OUl6dC`R%9d3<|bmxq;II6&rzs__Q|#MMa7Hl*y(K{RMK* zn&wz?f^r=kOvVWFKrs1R2PdT-3r;|YGWJt^xI!v8ex@|yHg8H}aeuw|?+E+>(cNbv zS28e`Y;i8C(f+MUx(>VAn>P<+BqUb{;NryX8WjgT@sag<_LrL7?vIa;*fp`+zHm@~ zQ+lIJClR1V>)Q2mgxzcXcug1|Ngz`$%|)o-{4}o5lEj|)Ie~rfT(EG09~#{ zab&`iz0=c|A_fCmQ~{Nwz~#a853`-)_D+@A%JxreX2q^-2(YhN8S+1$E`qR*h$Ku? zWcZXMovh!=r$N{B9X7c<@uj6rN=tT7upE?|KUscf}Dx&%tH{ocH8GcTo#j_8j zPYaCe;O1_eb)M6({|Gn%ZEbBrYuC#mAtBdaTr8|#GEuw$h~5TB;9m&DDymMf=6P{X zdA#7j>>(hUfMswe4-m8vsSzVgn~6+c?*+Ja({BM-mXX7@Ym$805}G7X=qy7a1i)wt zj_Xy3b_s*uk^fXIoFtRQ1SBOT`;X>-aD<9`yVkcQYF}<3zjFjmH-1eF{OliU^-^+H zX(4>wTCh>ds=J+5xtRgez(jipucQ-YF;8J1o*uE_?WUN++gbYz?(47dX=Ld0+N*D6 z!uxOTZj-&BikL7E<g)5*Vz>x2_uf)%IWUs#%O~CSJ^itq{9ELIa zH;(Mex|GEbi0<|0#iJ#^N%j&Vv~-b;`T$*dBcO{GF?fdq| zE^dm7gO-CCwGF69y!5MWZ-Z;sU%&B~$`o9}Jv-Y;NlCFj1d*4xwv3|Qe&%~(cJ|}` zT#c2=N?*U$hc|i1u;OACht&>$;)yKbAI07mJIB0_d;-AUiTP&*{M*~xVXK)G5?Mo3 z(Pl(ePBACEU%F)-Byb@l3RTO5ah zSgK^TT#5E#!yh(IO!f#o{*b|u5eBoM^C2lZSE;^510%oV5&mrLIN+BCrUoU#x!F0L z;wZ-_bUO$y_nL)^A_Ne_Q67WU4(?vuHW*w+VR>r1soHVHQAz$KCC7icJGniQ^f_ri z8D%_EFpd}x50+x#{HI7&2@MMwaCj=8bynQA>cun)C_c9yDrsrz(Y3Uroo1InyL_n^O;0Rgem;5@;KL{Kc z-HtjHRQ?ecBbv;f#IU%|KkXBPr=iPeYWJ@WX)YszTk0cH@`;75+=`VF0NY({djDtX z==*mrI#TXEN1azCe0KfO*XL-yxji6y zoR;u+=s0LD>Bk`AL)7gi`RUj!+Lb>S@YdGqHu-A|1Q^~8eD<&ZH1yS+fu6w~hl{UC z)a&n3^Y`P$Mh?1P@6e|pFoGAP>Wt9JDm%-Hy{(eh_g@h59Uw#lQ*2{o`*gZwI>=m7 zu^QBiU2nBJ(BHoQU_=j8&pWaq1%A@5XsbF;jx< zVUd)_%;eE+vmfHT+A-Zy8~Ixv37h=Y&+jJ9u9&HuhP6=B6N`@kZ=OH8RIX))z*SkY z=O0jP&)45+TT>)BuBqjUSe? zQmf3U$oTDbb_l4(dgLKMFt+a?N~N%<=Y{Z*4iXH_ z7OG;%Lzh#xoPXsJT3=siV{IP-lQ)5n`G9-nTlcpzsEuMo;dzeQoB^7bGEj;DBi?@u z$5k&@%@i0eRL_m*g3}s>C}E*=jgEe|*U_2sKT7-M(_P&Mp?Yq6E}<;fSH-`1uTA-_ zL%^Qz(g!t~D7mZ(`DPfS%RDGlDpn+^9@_;CCrXJN;2cnhqcH~o;5U({=k;|^P*9yM z(F>%mg?a}=LFW}pKTvx4m$iFlaNnr@6Ls~I_}ja#EpWb2rJY`eY=?yj#YeE}%G*zq zX0(7XhJH`QTa-ZpAjAOlcJkM+U+oI9)TVRaWWtdo#Zlw-kh{*UM+`K7|6XEHh@C@1 zMt1UWcYjpX#~vITW6+j-kYf%hIw{V3gPr@^gIig-5aV->6kP`aA?LQQHX+XZ`vOcD zsEbcB5-d<4O}?X{j+bRPxn7?HL)Xo0Aw9@mqeLtfe-j~05fAu0`p?Y(%TT#w z(^q(YKG*l^@3IyvQOB(QtCZbmB zWToRk3XX^lD93tYPs|n1-NkG8BdiP~4*>4` z9WPk4B}vMwr{juN1@vs-Z8l2`TsmKLqJr!H=EME6rRWmNv-G>H_>!}&GCJb^{#jjJ zeZgKlaT|}<9-cr7fq&fW7s!{7F`EBjJHbuNq4%9WK{2iD_%4Ge4->{X_((`-EgrD5 zWAo~ws(f8Rfvb30o>ua+)s@TmTIwjLtD~fcxz$=2p(4@6^Ox&Csh?a*mV%Kjc&%#y z%q74W6<}@ruqxquI8)IL((^yQ((myB5d5@{!6mL9#LZ_7DSIlR2H+2br0V0p`uykC zt!!+Jyd+vkU}Ze|;-nA$YKqJRiP}RoZWt<|^@=ZZa3n+ST~=}}8LQ}|=!myT=Lamh zpKF!4gwiAP)4GcaO%k=W@@yt@mhZ+g1(RmEr!Zjo`BoKaX=wu*Py{OoERjEN8RM)0M@=R>=-0~ea-2}ck;msTL$R3>!1j8_DyX45)*iyj(;t3o!Cj&B`uPnVfqOvSDNVPeDgy7FO9K$Ytc_fKc7z} zDsPo@>+eTLM>*aK^5g8zdGV9?UB)KsNG*9YXC)+3EE=Mb#+6-3_|N8$E2`)&D(`5%?CeaBb1xL zPcYT55@T+btACe$m##0C%lM3_`8+7E`!5f<8gHCLd*9W5=cF^!RJ)lX{-jk;ltJ$+ zK>E;0PepWy1X!iHgK7?FtiPSw|Kn4^S%$QBbG8``@;ZKG;O`d<455AmTJ)sclmsP` zs@cm2UsJO+YRAu%Jw* z*MsrVl}hn$wwZADR+;jnQ)Bw+-F-4}#XQF45=3MziJiA=3!^SuJ@QlLQqiyezkVfbSI-rZYc2e)e{K z6#qNZl|MPKMrS>eN$p!tC#aoKLZ>6%{euGEyCq}9+uz?mQ_m4=_C3D4B(xwOH*NRP z-N%V~2LY{N($KK5X**C6EP~dUyB+v&Q&1Qap)VBWf88(`O!f)F`b5F$yHvoYZ6w?7omfHwB(?iqzZ%aH?)@y5=DTxb zSpMH_>yM=c@=Oz%RVgwuGmY7p*|eI;3MlB}j}tZYn#{<9A4JL1h2QmRLt)Pg1wTUz zS=5mJn0XHL6;>%VpR0|4uql?>9Z%rM90RDopf&1<0)+I-)rzXopi7c96eIdH0Q{Bg zKR0(L+!mEdH0VbViC$lTzAoj8X6jiKbd1maqqx- z-q~s7+0(suLnpf4-q|MX2}amh$zCLtk*R7zrIA!S+_z+Xylc+5-kZO$E1z-l;r*SB zPq3Nh&$Ww(h9n!NoNP@(%Mu>(tTFe;0Sf?qmfl!u(V5$xFwFfV2rD-pYi%sGIQ!mQ zO+IPclj&@MhU>m=GkNdts_2bGdKFsgF6$MS{gem4w?+dv$41VVmr;}=?|8R4Efg&9 zto~-r^E)rKxu=fs*Dx2nnw7KDfY)q5+%PeFYD~P(-SzaC6Hae`XhOW69&VRG`tsLy zB3oMztz90exwX}elaq4?v|IP%5N=HZVgMMM-uK*IOPQpRcLy|E?*Ta~MIl5~u8Av{ zQ{d+;$ws1J<6&`|di!aDe;+>@3cTIeG9+-6A1Af1lkky&?_B83%!F1{P~G0C$fG2D z)tVcy!UA%{0|T&uJ>S1e!q$2PqyQ!fr^P^DUknZg))Mz51h}nczWvHJS2>=r`)7C} z2`UCNHYo}dlT~y>X~w0TYIN@8h$7*dBFFUd_RchE^7=ONJAWY7qS!zxK*E4XGZLFo zbJ^CxR^14qqhe(L3O(p01O`Yl{yWgUj*rK)w*G|)>kY@{qq9Epcz$}sl>Vl1CJZ&QjQGX!X;HHgk5i%KqTl);WEy7Ty%cybVVJAL*;90OTpme z;u1ZXZ*@k^bvBZxXQMrLb$eG+NJj$e*?n2!!Fs5ecIs6y@<#b46>n!-Q;S;{fSM~* zJzdW3fsQXLOU#})dy{f9yQ+D+pEs$!kp80FTFm+y=J~){zsp*fRK4l)ORm4cee3MX z^n$#+yo0k7g4N$cdhdNM4;h+or25PCc~qZN6-)Mn``jo84VpA0iz6|vU$96oGaCCtx@tQKC|VAm+I_XVFj!e)_ppJ?F>V?{s>iv7{-W=d zQJQr~d228Y)gbtS+ulBk4j0P6&rruGC?-_k8l+W+Ag68< zM)KR)0`OfN=J7%kN-IBK1R_%>XH@xATILQM{_u3s(98H4D56e%KZSWv_z+8(PAt61TE0?H;_Q=txgB`6Utb&VmiiDJ?k+p31R{5h( zRxSq8!Ik0sT!K1xxAZU!3##uEL+|{SI3OY}4x#Gv$eDQ{h;)gstcM?r!K2yscey3f zW;CnReXz+4$P#hKpts@41ocW~+Uxg|vg{*2t^J0y1ZWoL42VA>qTB{J4U`z+I}J~v z!0AY!+hi>)LFvfeSc|HYf3&{YxSwOr+;=@w2Q&Y z!v?0j`oW~nu?yL2BJE|bHfiY>E|lQr=Gr8D(vWI40gklFyn6qfugLJcH&n{gf_$t5 zMAC(8n4SXft0o3* zoXi3P>`)9~PB?@kgf+$AgVpMOdI@Tj9@GHWz?Cb<a9oEGZGS%2U9VA8|0)-j%A4ZDlUt- z$4>I!`aoPZexiSFY-~J^z-Q1?0|UY~gC|E5&`2c7Z3?OckR2pr@flxV;vHzE;dEB$ zV}Y)ylhii>gT0@~=LEyB%G9fv27*MkDZWw)xPX*I zvdYyc&3qg=#>PfZ3YYl`mzbEz$t^4ixTy#X z9I0GxaYE^olukGx#{@>v&d)LV(EP4&Q3T|jQGb2Yv1&@K>Vo4DSvnMSjb`~pVJIU0 z;n6a*RCob2I@1>vPt|z=)E8GH`2T zO<>teWO8Mqa3?57Z2b(a%0bBE!0h_?jF+hz^CfnLhLBL(^%yYWZd?MzZKdvagPNim zNEesKPofA+8sU(U{&+%#k~<@c>OJcN{;opJTaod;O{wvTU5*h>ekO7R$#wnh5=`J$ zz+va46W3{_?Uo6o%I&!VWyC-u1hL74F!2n``<9fAAPk5wV@hsjP4An$Qno5ZF(^N4 z0Ya1+37ib+?i~u62od93cDzA9)FdB08|JfZ75N0VH82Vp8XHlexoE>lR}kXr&F$@PHB5JeU!8%0+(^_6V8f%+RM_+lB5-c4 zUjPzcHfCn#qSJ*W4B%BC$)l;ZwuHBYKNn>ApN6@hw#j?Bai-+!f9M#=agQuRLy@)o zU!ws)d33SydO$sGt)qW{CEzZayiN}*e~M@cE`=B_?t5iYq1o;uzTLO(S_P+#*usOXGcedcHlqnQ=MOTyeF4F7#rEgU&UUEpKE}wi`8bgUB-g&#Qs?F#Mi##S(ej7P=JKXWDq+p zg3J|6=}gnp(+z8CYJP*pkM9{6F02Or+tW1g^Ly|Gt0J5=2Auy+Px11J4Qk&-K7!gb z~%xIYUZ3ju$NT^=GRh zjBCAKI;=iD#&olrtXrRYA_IPXNw~9G8Zg0uWJ!_^uk{yP;!|)Przf-J-LsZk zyrXa1S`n-?qXAm<-?HR%5db)}FY!BAp|J93YrE0q`{|a}YZChI@K~ zSHaxP{J#ZK4~kq>A;$)&`%QL618Heo+(g|{TN`{Nl}9^3PooqOhQO8ww+zErx!9S= zt)MiKCWrNKvBNNnQv2S$zhT1uQj|`Pcg`O+gu*RnlShHT_YPZhZ`ZB%M-+Q1J>WGC z#$OX)oFwXXQ~kE7HudJH*)3~t&o02n$0rOV?hVLfKCeGal@vm0t9c|yF2$yd8h{&P7lL4q|EPbahDwA^x8Zu|5mQzV({ z;)?48go3NF4F3C0@MB)x6zZ0H{HG})@e>~qQ9a1_cCKtd7Fu{cNanxwU%N;yilpA_ z=5(FwG%krGZ>l*tkTgV!`{teM-)@88dT|z(7Y}{{w=EH+JZ7y?PP!+Fqb_S1&Y*&~ z`P=5r_Zf%k?k#vjMEtLH)YbJqy}`OZm@e1TNI&T1M>DQ>^yabKRofKffiw1vjm0=v zS@GG{$4z{p=ZMAs4AEFhpfv<2uk`DMsm%j^2hBI=hh;@KO$$V%xNaS zzyCAyX%bonlwht6W@?{p){e82+-el{j7nV@y0VeggqmO@J#u>Zy=|aR7F;fy@d&2< zhXQ3KV&-|?jJsX?5vQK>n#~OiA5hqSX|NFkAoUqe6L2zW2NnBDc->gtYe0iq`;jWL zVDO|=_iN<^1ppx2416KJFl+N#ry(a-^1Yn=8V}aoMkT`sHdW8T8}_5bAhq_$dLMww zmFiT=of)w3KR|8risp3Dc|ZiLlbLGMD%i0$(SVJ?QPja} zy3<1h657Jo!)B@AD@jO5rsdqsR{}!{>nasx%KwTVKXN7f zMYaaldwoNNuCkedJwfN?4*#*qo}OB%-p{JCx3^fz%DQb&<3QIZ_kU?GAL#%wQOhmG z5ZfyA||AM@~-8X29)s>J{Fb z^DqC{9u$DC*V7Xd&hD0$dDr`Vw*RQd95~rN0td5ICul+HY0c?|hE6fUp~Diad2=1#>U4hg$I|HD{{*nCfJiXW>N6c4t&T}Fo3=V z>AMC*&`~lK4}5AnEd5j5>CLRM0sK2&oNWVT?jKSfqu02~RCgHY<*>;7voNN&fN7EnjF?WtQ18;Gtp|0jkCQ)p4{+D)*U`Ar~SdqTo!4W`2-? zii(AikIw^0927)FMOTA$lx$B(vU1VuBN2CZS(uoFsU$wx1zu9{Q?QLIU;?F%XUHYX zlWkd9OFB&{o}i}~cy}}(1%?*l(P+4V)=pLz_!8_O6z`K%J1weJ>+F1jbbT{MTwY!T zn=8-b;57ptKGPDNZXSW_I@uVkQ$2unsyJd&A{QM9bd`)8|I9Bwd|(g1H@wqmdsC*> z-?s|}X*1$?_&_EZ@bIoMvd9(^%2%X*{cy9dO#~#zXJ%%ufC}7Eh`UU$-A4+Z&^R-NP7@ER=GeKDtS^sW-vJ{zKv+FiK9%18!a_JSyhFc_9+;Kud zp6#8O^=!{>_eXv`YiCvk_Od>Lb*G#}7WIIW&CPuMZ=+yC>vC&|uo1L&smJx-QN9Ku zBBK4OExLnqR7iN#5b@k+-c)N9o$j{0-|Rm=72WzN&kn40;*nCdd7i8YRmZN@NtNh8 zG|No)Q#Al_;Kt8yAf0h? zSg3nHT9qxj`zYZsGl7qklERrLnR^ND7}|m_;Y1G4V5!1kdxy(dFU0T)1$lp2NW0!% zS87u}=CiN2w-b_zMV^LOfp7Yn9u6`XDLSm=$-RlA7I!UvlWrMb&X@Aw0>I}M7G?s# zD3hT{7z`&}VDjLoih6UI`Yc+VT7(cG;-!Ii(s2vSeg(HM!+QSMj#Gx=4d7nMfnSJt z`1sF^$#@z9;PhE9ARr)6x7?^6o%lbcWd?RCE8IZZr8%=4)TN5ZEsT=9^!$ua{<+i*YjeoTZ8Cd@Wl&CAiyF`12U51m)KY{XyJNf8Pu^C=?06s zR(JAT27%XihI8hEln3Q_`Nu9G;V1P1pu|yFYE{quz-K$&h7+{uxt^+`9iRwkI668x zh+|^<_E`QHLXP~Hm7CYA=x#UnU&n#(ZBM9&#nXG$(mTzqaAZJB&#KgofnfY20K~UGCu&v!)>`nw;RL(ooNpb?L|J9nS)83#Y z_F0C8hVlwI3J6mgaFX!R@iXMIq3S_Doo&dq4@^JLZil0+1?Cw)p?0ZrKO?TOq&}lo XU%wy{?H&cu1^|@g)MP8AErS0CSO^gJ -- GitLab From d2283cc93c1da72d03340153024e8d1032d5a452 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 2 Mar 2022 16:49:38 +0100 Subject: [PATCH 55/83] rename ProximityExposureModelHealthStatus to BasicExposureModelHealthStatus --- .../models/infection/ProximityExposureModel.java | 8 ++++---- .../health/BasicExposureModelHealthStatus.java | 15 +++++++++++++++ .../ProximityExposureModelHealthStatus.java | 12 ------------ 3 files changed, 19 insertions(+), 16 deletions(-) create mode 100644 VadereState/src/org/vadere/state/health/BasicExposureModelHealthStatus.java delete mode 100644 VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java index af1ebd0b6..9467a5952 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java @@ -10,7 +10,7 @@ import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.attributes.models.infection.AttributesProximityExposureModel; import org.vadere.state.attributes.scenario.AttributesAgent; -import org.vadere.state.health.ProximityExposureModelHealthStatus; +import org.vadere.state.health.BasicExposureModelHealthStatus; import org.vadere.state.scenario.Agent; import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Topography; @@ -31,7 +31,7 @@ import java.util.stream.Collectors; *

*

ProximityExposureModel contains the logic, that is: *

    - *
  • Each pedestrian obtains a {@link ProximityExposureModelHealthStatus + *
  • Each pedestrian obtains a {@link BasicExposureModelHealthStatus * health status} * after being inserted into the topography.
  • *
  • Any pedestrian that approaches an infectious pedestrian so that the @@ -115,7 +115,7 @@ public class ProximityExposureModel extends AbstractExposureModel { AttributesExposureModelSourceParameters sourceParameters = defineSourceParameters(controller, attributesProximityExposureModel); Pedestrian ped = (Pedestrian) scenarioElement; - ped.setHealthStatus(new ProximityExposureModelHealthStatus()); + ped.setHealthStatus(new BasicExposureModelHealthStatus()); ped.setInfectious(sourceParameters.isInfectious()); return ped; } @@ -124,7 +124,7 @@ public class ProximityExposureModel extends AbstractExposureModel { public Pedestrian topographyControllerEvent(TopographyController topographyController, double simTimeInSec, Agent agent) { Pedestrian pedestrian = (Pedestrian) agent; - pedestrian.setHealthStatus(new ProximityExposureModelHealthStatus()); + pedestrian.setHealthStatus(new BasicExposureModelHealthStatus()); if (attributesProximityExposureModel.getInfectiousPedestrianIdsNoSource().contains(agent.getId())) { pedestrian.setInfectious(true); diff --git a/VadereState/src/org/vadere/state/health/BasicExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/BasicExposureModelHealthStatus.java new file mode 100644 index 000000000..78c578bfe --- /dev/null +++ b/VadereState/src/org/vadere/state/health/BasicExposureModelHealthStatus.java @@ -0,0 +1,15 @@ +package org.vadere.state.health; + +/** + * BasicExposureModelHealthStatus that is used in combination with: + * + *
  • ProximityExposureModel
  • + *
  • PostvisualizationModel
  • + * + */ +public class BasicExposureModelHealthStatus extends ExposureModelHealthStatus { + + public BasicExposureModelHealthStatus() { + super(); + } +} diff --git a/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java deleted file mode 100644 index e7b94cf6e..000000000 --- a/VadereState/src/org/vadere/state/health/ProximityExposureModelHealthStatus.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.vadere.state.health; - -/** - * ProximityExposureModelHealthStatus that is used in combination with the - * ProximityExposureModel. - */ -public class ProximityExposureModelHealthStatus extends ExposureModelHealthStatus { - - public ProximityExposureModelHealthStatus() { - super(); - } -} -- GitLab From de5568c81779c99a2a8ae8f2515de01f50b3fecc Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Wed, 2 Mar 2022 16:50:12 +0100 Subject: [PATCH 56/83] [gui] add pedestrian health status in PostvisualizationModel --- .../model/PostvisualizationModel.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java b/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java index 9f95cd190..5bde6fb55 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java @@ -7,6 +7,7 @@ import org.vadere.gui.postvisualization.utils.PotentialFieldContainer; import org.vadere.simulator.projects.Scenario; import org.vadere.state.attributes.AttributesSimulation; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.BasicExposureModelHealthStatus; import org.vadere.state.psychology.cognition.GroupMembership; import org.vadere.state.psychology.cognition.SelfCategory; import org.vadere.state.psychology.information.InformationState; @@ -283,11 +284,17 @@ public class PostvisualizationModel extends SimulationModel Date: Wed, 2 Mar 2022 17:28:36 +0100 Subject: [PATCH 57/83] [gui] remove overlapping elements in postvis SettingsDialog --- .../src/org/vadere/gui/components/view/SettingsDialog.java | 4 +++- .../vadere/gui/postvisualization/view/SettingsDialog.java | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java index e1ec10337..524052dcb 100644 --- a/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java +++ b/VadereGui/src/org/vadere/gui/components/view/SettingsDialog.java @@ -256,8 +256,10 @@ public class SettingsDialog extends JDialog { } private void initAgentColorSettingsPane(JLayeredPane colorSettingsPane){ + int nOnlineVisualizationCells = 9; + int nPostVisualizationCells = 6; // org.vadere.gui.postvisualization.view.SettingsDialog adds n cells (rows) to settingsPane FormLayout pedColorLayout = new FormLayout("5dlu, pref, 2dlu, pref, 2dlu, pref:grow, 2dlu, pref, 2dlu, pref, 5dlu", - createCellsWithSeparators(10)); //rows + createCellsWithSeparators(nOnlineVisualizationCells + nPostVisualizationCells)); colorSettingsPane.setLayout(pedColorLayout); colorSettingsPane.setBorder(BorderFactory.createTitledBorder(Messages.getString("SettingsDialog.pedcolors.border.text"))); diff --git a/VadereGui/src/org/vadere/gui/postvisualization/view/SettingsDialog.java b/VadereGui/src/org/vadere/gui/postvisualization/view/SettingsDialog.java index 6fd4739ee..7bc0f5712 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/view/SettingsDialog.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/view/SettingsDialog.java @@ -22,9 +22,10 @@ public class SettingsDialog extends org.vadere.gui.components.view.SettingsDialo @Override public void initComponents() { super.initComponents(); + int row = 18; //TODO this is hard coded; must be adapted when further elements are inserted above CellConstraints cc = new CellConstraints(); JRadioButton chShowEvacTimeColor = new JRadioButton(Messages.getString("PostVis.chShowEvacTimeColor.text")); - agentColorSettingsPane.add(chShowEvacTimeColor, cc.xyw(2, 14, 9)); + agentColorSettingsPane.add(chShowEvacTimeColor, cc.xyw(2, row += NEXT_CELL, 9)); chShowEvacTimeColor.addItemListener(e -> { model.setAgentColoring(AgentColoring.EVACUATION_TIMES); model.notifyObservers(); @@ -33,8 +34,8 @@ public class SettingsDialog extends org.vadere.gui.components.view.SettingsDialo JRadioButton chShowCriteriaColor = new JRadioButton(Messages.getString("PostVis.chShowCriteriaColor.text") + ":"); PedestrianColorPanel pedestrianColorPanel = new PedestrianColorPanel(model); - agentColorSettingsPane.add(chShowCriteriaColor, cc.xy(2, 16, CellConstraints.LEFT, CellConstraints.TOP)); - agentColorSettingsPane.add(pedestrianColorPanel, cc.xyw(4, 16, 7)); + agentColorSettingsPane.add(chShowCriteriaColor, cc.xy(2, row += NEXT_CELL, CellConstraints.LEFT, CellConstraints.TOP)); + agentColorSettingsPane.add(pedestrianColorPanel, cc.xyw(4, row, 7)); chShowCriteriaColor.addItemListener(e -> { model.setAgentColoring(AgentColoring.PREDICATE); model.notifyObservers(); -- GitLab From a0f6869d168c65e28ac4b03cb14f2d5e4998b0d1 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 3 Mar 2022 16:06:28 +0100 Subject: [PATCH 58/83] [wip] Rename AerosolCloudShapeProcessor to AerosolCloudDataProcessor --- .../examples/scenarios/closeContact.scenario | 2 +- .../AirTransmissionModel/examples/scenarios/queue.scenario | 2 +- .../scenarios/hamner-2020-life_postvis_template.scenario | 2 +- ...loudShapeProcessor.java => AerosolCloudDataProcessor.java} | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) rename VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/{AerosolCloudShapeProcessor.java => AerosolCloudDataProcessor.java} (94%) diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario index 85f044820..561a372ac 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario @@ -60,7 +60,7 @@ "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepHealthStatusProcessor", "id" : 7 }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudShapeProcessor", + "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 8, "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", "attributes" : { diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario index 9d4e4da07..6ac16a23e 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario @@ -78,7 +78,7 @@ "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepHealthStatusProcessor", "id" : 11 }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudShapeProcessor", + "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 12, "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", "attributes" : { diff --git a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario index a0cb08f3a..e0f78af07 100644 --- a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario +++ b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario @@ -45,7 +45,7 @@ "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepHealthStatusProcessor", "id" : 6 }, { - "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudShapeProcessor", + "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 7, "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", "attributes" : { diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudShapeProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java similarity index 94% rename from VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudShapeProcessor.java rename to VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java index 22e4249e0..202dc3b6a 100644 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudShapeProcessor.java +++ b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java @@ -23,11 +23,11 @@ import java.util.Collection; */ @DataProcessorClass() -public class AerosolCloudShapeProcessor extends DataProcessor { +public class AerosolCloudDataProcessor extends DataProcessor { private int sampleEveryNthSimStep; - public AerosolCloudShapeProcessor() { + public AerosolCloudDataProcessor() { super("pathogenLoad", "radius", "centerX", "centerY"); setAttributes(new AttributesAerosolCloudShapeProcessor()); } -- GitLab From 10cc53fc845ac81897bcec61d2dc71b5baaa9368 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 3 Mar 2022 16:12:11 +0100 Subject: [PATCH 59/83] [gui] Make error message independent of AerosolCloudDataProcessor name and output filename. --- VadereGui/resources/messages.properties | 2 +- VadereGui/resources/messages_de_DE.properties | 2 +- .../gui/postvisualization/view/PostvisualizationWindow.java | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/VadereGui/resources/messages.properties b/VadereGui/resources/messages.properties index e8fbd46bf..1e938d8f7 100644 --- a/VadereGui/resources/messages.properties +++ b/VadereGui/resources/messages.properties @@ -246,7 +246,7 @@ SettingsDialog.chbShowPedestrianInOutGroup.text=Show Pedestrian In/Outgroup PostVis.chShowEvacTimeColor.text=Coloring by Evacuation Times PostVis.chShowCriteriaColor.text=Coloring by Predicate PostVis.ShowContactsErrorMessage.text=Contacts were not processed for this scenario. To process contacts for scenarios add PedestriansNearbyProcessor and a corresponding file contacts.txt to data output. -PostVis.ShowAerosolCloudsErrorMessage.text=Aerosol clouds were not processed for this scenario. To process aerosol clouds for scenarios add AerosolCloudShapeProcessor and a corresponding file aerosolCloudShapes.txt to data output. +PostVis.ShowAerosolCloudsErrorMessage.text=Aerosol clouds were not processed for this scenario. To process aerosol clouds for scenarios add the following data processor and the corresponding output file:\n PostVis.additional.border.text=PostVis diff --git a/VadereGui/resources/messages_de_DE.properties b/VadereGui/resources/messages_de_DE.properties index d4e239670..59667888a 100644 --- a/VadereGui/resources/messages_de_DE.properties +++ b/VadereGui/resources/messages_de_DE.properties @@ -254,7 +254,7 @@ PostVis.chbHidePedAtTarget.text=Verschwundene Fu\u00dfg\u00E4nger im Ziel nicht PostVis.chbHideTrajAtTarget.text=Verschwundene Trajektorien am Ziel nicht anzeigen PostVis.chbCleanSnapshot.text=Trajektorien auf Snapshots nicht anzeigen PostVis.chShowAllTrajOnSnapshot.text=Alle Trajektorien auf Snapshot anzeigen -PostVis.ShowAerosolCloudsErrorMessage.text=Aerosolwolken wurden f\u00FCr dieses Szenario nicht aufgezeichnet. F\u00FCgen Sie den AerosolCloudShapeProcessor und eine entsprechende Output Datei aerosolCloudShapes.txt hinzu. +PostVis.ShowAerosolCloudsErrorMessage.text=Aerosolwolken wurden f\u00FCr dieses Szenario nicht aufgezeichnet. F\u00FCgen Sie folgenden Datenprozessor und die entsprechende Output Datei hinzu:\n SettingsDialog.chbUseRandomColors.text=Zuf\u00E4llige Farben SettingsDialog.chbGroupColors.text=F\u00E4rbung nach Gruppe diff --git a/VadereGui/src/org/vadere/gui/postvisualization/view/PostvisualizationWindow.java b/VadereGui/src/org/vadere/gui/postvisualization/view/PostvisualizationWindow.java index 8191e5817..b4e746b59 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/view/PostvisualizationWindow.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/view/PostvisualizationWindow.java @@ -31,13 +31,17 @@ import org.vadere.gui.postvisualization.control.ActionShowPotentialField; import org.vadere.gui.postvisualization.control.ActionStop; import org.vadere.gui.postvisualization.control.ActionVisualizationMenu; import org.vadere.gui.postvisualization.control.Player; +import org.vadere.gui.postvisualization.model.ContactData; import org.vadere.gui.postvisualization.model.PostvisualizationModel; +import org.vadere.gui.postvisualization.model.TableAerosolCloudData; import org.vadere.gui.projectview.control.ActionDeselect; import org.vadere.gui.projectview.view.ProjectView; import org.vadere.simulator.projects.Scenario; +import org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor; import org.vadere.simulator.projects.io.IOOutput; import org.vadere.util.config.VadereConfig; import org.vadere.util.io.IOUtils; +import tech.tablesaw.api.Table; import java.awt.*; import java.awt.datatransfer.DataFlavor; @@ -238,7 +242,7 @@ public class PostvisualizationWindow extends JPanel implements Observer, DropTar public void actionPerformed(ActionEvent e) { if (!model.config.isAerosolCloudsRecorded()) { JOptionPane.showMessageDialog(ProjectView.getMainWindow(), - Messages.getString("PostVis.ShowAerosolCloudsErrorMessage.text")); + Messages.getString("PostVis.ShowAerosolCloudsErrorMessage.text") + "\n" + AerosolCloudDataProcessor.class.getName() + "\n" + TableAerosolCloudData.TABLE_NAME + ".txt"); } else { model.config.setShowAerosolClouds(!model.config.isShowAerosolClouds()); model.notifyObservers(); -- GitLab From e6553692a1e5dc71387bb611be82ad1c615fc672 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 3 Mar 2022 16:19:58 +0100 Subject: [PATCH 60/83] [gui] Fix bug that led to visualization of aerosol clouds and contacts although no data is available: PostvisualizationModel initialized / did not clear old tableAerosolCloudData and contactData that was used in previous postvisualizations in case for the new scenario was no aerosolCloudData / contactData available. --- .../postvisualization/model/ContactData.java | 16 ++++-- .../model/PostvisualizationModel.java | 49 ++++++++++--------- .../model/TableAerosolCloudData.java | 14 +++++- .../view/PostvisualizationRenderer.java | 4 +- .../view/PostvisualizationWindow.java | 32 ++++++------ .../gui/projectview/view/ProjectView.java | 37 ++++++-------- .../gui/projectview/view/ScenarioPanel.java | 14 +++--- .../projects/io/ContactDataReader.java | 1 - 8 files changed, 92 insertions(+), 75 deletions(-) diff --git a/VadereGui/src/org/vadere/gui/postvisualization/model/ContactData.java b/VadereGui/src/org/vadere/gui/postvisualization/model/ContactData.java index 0db94756b..16975b1c2 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/model/ContactData.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/model/ContactData.java @@ -16,6 +16,8 @@ public class ContactData { private final List rowsWithPedIds; private static final double SIM_STEP_LENGTH = 0.4; + public static final String TABLE_NAME = "contacts"; + // columns, TODO: this is hard coded! public final int startTimeStepCol; public final int firstPedIdCol; @@ -41,15 +43,21 @@ public class ContactData { yPathCol = columnNames.getStartYCol(dataFrame); this.contactsDataFrame = dataFrame; - StringColumn startTimes = getStartTimeStep(contactsDataFrame); rowsWithPedIds = new ArrayList<>(); - for (int i = 0; i < startTimes.size(); i++) { - if (!startTimes.get(i).equals("-")) { - rowsWithPedIds.add(i); + if (!isEmpty()) { + StringColumn startTimes = getStartTimeStep(contactsDataFrame); + for (int i = 0; i < startTimes.size(); i++) { + if (!startTimes.get(i).equals("-")) { + rowsWithPedIds.add(i); + } } } } + public boolean isEmpty() { + return contactsDataFrame.isEmpty(); + } + public List getRowsWithPedIds() { return rowsWithPedIds; } diff --git a/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java b/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java index 5bde6fb55..df72dda91 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/model/PostvisualizationModel.java @@ -22,12 +22,7 @@ import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.logging.Logger; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.Random; +import java.util.*; import java.util.function.Function; import java.util.stream.Stream; @@ -74,45 +69,48 @@ public class PostvisualizationModel extends SimulationModel additionalTables, final Scenario scenario, final String projectPath) { + init(trajectories, additionalTables, scenario, projectPath, new AttributesAgent()); } + public synchronized void init(final Table trajectories, final Scenario scenario, final String projectPath) { - init(trajectories, null, null, scenario, projectPath, new AttributesAgent()); + init(trajectories, new HashMap<>(), scenario, projectPath, new AttributesAgent()); } /** * Initialize the {@link PostvisualizationModel}. * @param trajectories + * @param additionalTables tables containing additional data that is not stored in trajectories but should be + * postvisualized as well, for example contacts and aerosol clouds * @param scenario the scenario which was used to produce the output the PostVis will display. * This scenario will not contain any agents. * @param projectPath the path to the project. */ - public synchronized void init(final Table trajectories, final Table contactTrajectories, final Table aerosolCloudData, final Scenario scenario, final String projectPath, final AttributesAgent attributesAgent) { + public synchronized void init(final Table trajectories, final HashMap additionalTables, final Scenario scenario, final String projectPath, final AttributesAgent attributesAgent) { this.scenario = scenario; this.simTimeStepLength = scenario.getAttributesSimulation().getSimTimeStepLength(); this.trajectories = new TableTrajectoryFootStep(trajectories); - if (contactTrajectories != null) { - this.config.setContactsRecorded(true); - this.contactData = new ContactData(contactTrajectories); - } - if (aerosolCloudData != null) { - this.config.setAerosolCloudsRecorded(true); - this.tableAerosolCloudData = new TableAerosolCloudData(aerosolCloudData); + clearAdditionalTables(); + for (HashMap.Entry entry : additionalTables.entrySet()) { + switch (entry.getKey()) { + case ContactData.TABLE_NAME: + this.config.setContactsRecorded(true); + this.contactData = new ContactData(entry.getValue()); + case TableAerosolCloudData.TABLE_NAME: + this.config.setAerosolCloudsRecorded(true); + this.tableAerosolCloudData = new TableAerosolCloudData(entry.getValue()); + } } this.visTime = 0; this.attributesAgent = attributesAgent; @@ -230,6 +228,13 @@ public class PostvisualizationModel extends SimulationModel aerosolClouds = model.getTableAerosolCloudData().toAerosolCloudCollection(getModel().getStep()); diff --git a/VadereGui/src/org/vadere/gui/postvisualization/view/PostvisualizationWindow.java b/VadereGui/src/org/vadere/gui/postvisualization/view/PostvisualizationWindow.java index b4e746b59..de5992807 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/view/PostvisualizationWindow.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/view/PostvisualizationWindow.java @@ -54,10 +54,8 @@ import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; -import java.util.ArrayList; +import java.util.*; import java.util.List; -import java.util.Observer; -import java.util.Optional; import javax.swing.*; @@ -401,19 +399,19 @@ public class PostvisualizationWindow extends JPanel implements Observer, DropTar return menuBar; } - public void loadOutputFile(final File trajectoryFile, final File contactsTrajectoryFile, final File aerosolCloudShapeFile, final Scenario scenario) throws IOException { + public void loadOutputFile(final File trajectoryFile, final HashMap additionalFiles, final Scenario scenario) throws IOException { Player.getInstance(model).stop(); - try { - if (contactsTrajectoryFile != null && aerosolCloudShapeFile != null) { - model.init(IOOutput.readTrajectories(trajectoryFile.toPath()), IOOutput.readContactData(contactsTrajectoryFile.toPath()), IOOutput.readAerosolCloudData(aerosolCloudShapeFile.toPath()), scenario, contactsTrajectoryFile.getParent()); - } else if(contactsTrajectoryFile != null && aerosolCloudShapeFile == null) { - model.init(IOOutput.readTrajectories(trajectoryFile.toPath()), IOOutput.readContactData(contactsTrajectoryFile.toPath()), scenario, contactsTrajectoryFile.getParent()); - } else if(contactsTrajectoryFile == null && aerosolCloudShapeFile != null) { - model.init(IOOutput.readTrajectories(trajectoryFile.toPath()), null, IOOutput.readAerosolCloudData(aerosolCloudShapeFile.toPath()), scenario, aerosolCloudShapeFile.getParent()); - } else { - model.init(IOOutput.readTrajectories(trajectoryFile.toPath()), scenario, trajectoryFile.getParent()); + HashMap additionalTables = new HashMap<>(); + for (HashMap.Entry entry : additionalFiles.entrySet()) { + switch (entry.getKey()) { + case ContactData.TABLE_NAME: + additionalTables.put(entry.getKey(), IOOutput.readContactData(entry.getValue().toPath())); + case TableAerosolCloudData.TABLE_NAME: + additionalTables.put(entry.getKey(), IOOutput.readAerosolCloudData(entry.getValue().toPath())); + } } + model.init(IOOutput.readTrajectories(trajectoryFile.toPath()), additionalTables, scenario, trajectoryFile.getParent()); model.notifyObservers(); } catch (Exception ex) { JOptionPane.showMessageDialog(this, ex.getMessage(), Messages.getString("Error.text"), JOptionPane.ERROR_MESSAGE); @@ -421,7 +419,13 @@ public class PostvisualizationWindow extends JPanel implements Observer, DropTar } public void loadOutputFile(final File trajectoryFile, final Scenario scenario) throws IOException { - loadOutputFile(trajectoryFile, null, null, scenario); + Player.getInstance(model).stop(); + try { + model.init(IOOutput.readTrajectories(trajectoryFile.toPath()), scenario, trajectoryFile.getParent()); + model.notifyObservers(); + } catch (Exception ex) { + JOptionPane.showMessageDialog(this, ex.getMessage(), Messages.getString("Error.text"), JOptionPane.ERROR_MESSAGE); + } } public void loadOutputFile(final Scenario scenario) { diff --git a/VadereGui/src/org/vadere/gui/projectview/view/ProjectView.java b/VadereGui/src/org/vadere/gui/projectview/view/ProjectView.java index 942af5747..bd448cd8c 100644 --- a/VadereGui/src/org/vadere/gui/projectview/view/ProjectView.java +++ b/VadereGui/src/org/vadere/gui/projectview/view/ProjectView.java @@ -4,6 +4,8 @@ package org.vadere.gui.projectview.view; import org.jetbrains.annotations.NotNull; import org.vadere.gui.components.utils.Messages; import org.vadere.gui.postvisualization.control.Player; +import org.vadere.gui.postvisualization.model.ContactData; +import org.vadere.gui.postvisualization.model.TableAerosolCloudData; import org.vadere.gui.projectview.control.*; import org.vadere.gui.projectview.model.ProjectViewModel; import org.vadere.gui.projectview.model.ProjectViewModel.OutputBundle; @@ -30,11 +32,8 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.Collections; -import java.util.HashSet; -import java.util.Locale; -import java.util.Optional; -import java.util.Set; +import java.util.*; +import java.util.List; import javax.swing.*; import javax.swing.border.EmptyBorder; @@ -621,29 +620,23 @@ public class ProjectView extends JFrame implements ProjectFinishedListener, Sing Scenario scenarioRM = bundle.getScenarioRM(); Optional trajectoryFile = IOUtils .getFirstFile(bundle.getDirectory(), IOUtils.TRAJECTORY_FILE_EXTENSION); + File[] txtFiles = IOUtils.getFileList(bundle.getDirectory(), ".txt"); - Optional contactsTrajectoryFile = Optional.empty(); - for (File f :txtFiles) { - if (f.getName().contains("contacts")) { - contactsTrajectoryFile = Optional.of(f); - } - } - Optional aerosolCloudShapeFile = Optional.empty(); - for (File f :txtFiles) { - if (f.getName().contains("aerosolCloudShapes")) { - aerosolCloudShapeFile = Optional.of(f); + List tableNames = new ArrayList<>(Arrays.asList(ContactData.TABLE_NAME, TableAerosolCloudData.TABLE_NAME)); + HashMap optionalPostVisFiles = new HashMap<>(); + for (String name : tableNames) { + for (File f : txtFiles) { + if (f.getName().contains(name)) { + optionalPostVisFiles.put(name, f); + } } } if (trajectoryFile.isPresent()) { - if (contactsTrajectoryFile.isPresent() && aerosolCloudShapeFile.isPresent()) { - scenarioJPanel.loadOutputFileForPostVis(trajectoryFile.get(), contactsTrajectoryFile.get(), aerosolCloudShapeFile.get(), scenarioRM); - } else if (contactsTrajectoryFile.isPresent() && !aerosolCloudShapeFile.isPresent()) { - scenarioJPanel.loadOutputFileForPostVis(trajectoryFile.get(), contactsTrajectoryFile.get(), scenarioRM); - } else if (!contactsTrajectoryFile.isPresent() && aerosolCloudShapeFile.isPresent()) { - scenarioJPanel.loadOutputFileForPostVis(trajectoryFile.get(), null, aerosolCloudShapeFile.get(), scenarioRM); + if (optionalPostVisFiles.size() > 0) { + scenarioJPanel.loadOutputFileForPostVis(trajectoryFile.get(), optionalPostVisFiles, scenarioRM); } else { - scenarioJPanel.loadOutputFileForPostVis(trajectoryFile.get(), scenarioRM); + scenarioJPanel.loadOutputFileForPostVis(trajectoryFile.get(), scenarioRM); } } else { scenarioJPanel.loadOutputFileForPostVis(scenarioRM); diff --git a/VadereGui/src/org/vadere/gui/projectview/view/ScenarioPanel.java b/VadereGui/src/org/vadere/gui/projectview/view/ScenarioPanel.java index a466ec4ac..347e2d548 100644 --- a/VadereGui/src/org/vadere/gui/projectview/view/ScenarioPanel.java +++ b/VadereGui/src/org/vadere/gui/projectview/view/ScenarioPanel.java @@ -22,7 +22,9 @@ import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Optional; import javax.swing.*; import javax.swing.border.EmptyBorder; @@ -363,15 +365,11 @@ public class ScenarioPanel extends JPanel implements IProjectChangeListener, Pro public void loadOutputFileForPostVis(Scenario scenarioRM) throws IOException { postVisualizationView.loadOutputFile(scenarioRM); } - - public void loadOutputFileForPostVis(File trajectoryFile, Scenario scenarioRM) throws IOException { - postVisualizationView.loadOutputFile(trajectoryFile, null, null, scenarioRM); + public void loadOutputFileForPostVis(File trajectoryFile, HashMap additionalPostVisFiles, Scenario scenarioRM) throws IOException { + postVisualizationView.loadOutputFile(trajectoryFile, additionalPostVisFiles, scenarioRM); } - public void loadOutputFileForPostVis(File trajectoryFile, File contactsTrajectoryFile, Scenario scenarioRM) throws IOException { - postVisualizationView.loadOutputFile(trajectoryFile, contactsTrajectoryFile, null, scenarioRM); - } - public void loadOutputFileForPostVis(File trajectoryFile, File contactsTrajectoryFile, File aerosolCloudDataFile, Scenario scenarioRM) throws IOException { - postVisualizationView.loadOutputFile(trajectoryFile, contactsTrajectoryFile, aerosolCloudDataFile, scenarioRM); + public void loadOutputFileForPostVis(File trajectoryFile, Scenario scenarioRM) throws IOException { + postVisualizationView.loadOutputFile(trajectoryFile, scenarioRM); } public static void setActiveTopographyErrorMsg(JEditorPane msg){ diff --git a/VadereSimulator/src/org/vadere/simulator/projects/io/ContactDataReader.java b/VadereSimulator/src/org/vadere/simulator/projects/io/ContactDataReader.java index 982d34b9c..c1cf5ea5a 100644 --- a/VadereSimulator/src/org/vadere/simulator/projects/io/ContactDataReader.java +++ b/VadereSimulator/src/org/vadere/simulator/projects/io/ContactDataReader.java @@ -1,7 +1,6 @@ package org.vadere.simulator.projects.io; import org.vadere.simulator.projects.dataprocessing.outputfile.OutputFile; -import org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor; import tech.tablesaw.api.Table; import tech.tablesaw.io.csv.CsvReadOptions; -- GitLab From 3f3ee220e1af8f15090e99a05468f55af50cc810 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 3 Mar 2022 16:23:06 +0100 Subject: [PATCH 61/83] Refactoring: In AerosolCloudDataProcessor, correct javadoc and add number format for data output --- .../processor/AerosolCloudDataProcessor.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java index 202dc3b6a..8754a6d5f 100644 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java +++ b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java @@ -8,20 +8,20 @@ import org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcesso import org.vadere.state.scenario.AerosolCloud; import java.util.Collection; +import java.util.Locale; /** - *

    This processor writes out the shape and the pathogen load of all {@link AerosolCloud}s. Each row corresponds to - * one aerosol cloud at a given simulation time. The shape of an aerosol cloud is described by the vertices - * ([x, y]-coordinates) and the area. + *

    This processor writes out the shape and the pathogen load of all {@link AerosolCloud}s. + * Each row corresponds to one aerosol cloud at a given simulation time. The shape of an + * aerosol cloud is described by the radius and its center ([x, y]-coordinates). *

    * - *

    To reduce the size of the output file, one can reduce the sample frequency, i.e. the processor writes out only - * every {@param sampleEveryNthSimStep}. + *

    To reduce the size of the output file, one can reduce the sample frequency, that is + * the processor writes out only every {@param sampleEveryNthSimStep}. *

    * * @author Simon Rahn */ - @DataProcessorClass() public class AerosolCloudDataProcessor extends DataProcessor { @@ -52,7 +52,7 @@ public class AerosolCloudDataProcessor extends DataProcessor Date: Thu, 3 Mar 2022 16:53:11 +0100 Subject: [PATCH 62/83] Refactoring: Adapt and add AerosolCloudDataProcessor data processors In TableAerosolCloudData, correct table name that is linked to AerosolCloudDataProcessor --- .../examples/scenarios/bottleneckA.scenario | 15 +++++++++++++-- .../examples/scenarios/bottleneckB.scenario | 15 +++++++++++++-- .../bottleneckB_socialDistancing.scenario | 15 +++++++++++++-- .../examples/scenarios/closeContact.scenario | 4 ++-- .../examples/scenarios/passageway.scenario | 15 +++++++++++++-- .../examples/scenarios/queue.scenario | 4 ++-- .../hamner-2020-life_postvis_template.scenario | 8 ++------ .../scenarios/hamner-2020-life_template.scenario | 8 ++------ .../scenarios/miller-2020-life_template.scenario | 6 +----- .../model/TableAerosolCloudData.java | 2 +- 10 files changed, 62 insertions(+), 30 deletions(-) diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario index fa6ede277..f435cc9a1 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario @@ -2,7 +2,7 @@ "name" : "bottleneckA", "description" : "", "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", + "commithash" : "3f3ee220e1af8f15090e99a05468f55af50cc810", "processWriters" : { "files" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", @@ -16,6 +16,10 @@ "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile", "filename" : "overlapCount.txt", "processors" : [ 4 ] + }, { + "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", + "filename" : "aerosolCloudData.txt", + "processors" : [ 6 ] } ], "processors" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor", @@ -36,8 +40,15 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepHealthStatusProcessor", "id" : 5 + }, { + "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", + "id" : 6, + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributes" : { + "sampleEveryNthSimStep" : 1 + } } ], - "isTimestamped" : true, + "isTimestamped" : false, "isWriteMetaData" : false }, "scenario" : { diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario index 278974950..966882c52 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario @@ -2,7 +2,7 @@ "name" : "bottleneckB", "description" : "", "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", + "commithash" : "3f3ee220e1af8f15090e99a05468f55af50cc810", "processWriters" : { "files" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", @@ -20,6 +20,10 @@ "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile", "filename" : "flow.txt", "processors" : [ 6 ] + }, { + "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", + "filename" : "aerosolCloudData.txt", + "processors" : [ 9 ] } ], "processors" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor", @@ -61,8 +65,15 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepHealthStatusProcessor", "id" : 8 + }, { + "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", + "id" : 9, + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributes" : { + "sampleEveryNthSimStep" : 1 + } } ], - "isTimestamped" : true, + "isTimestamped" : false, "isWriteMetaData" : false }, "scenario" : { diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario index 16df1682d..2e72b0fb1 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario @@ -2,7 +2,7 @@ "name" : "bottleneckB_socialDistancing", "description" : "", "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", + "commithash" : "3f3ee220e1af8f15090e99a05468f55af50cc810", "processWriters" : { "files" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", @@ -20,6 +20,10 @@ "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile", "filename" : "flow.txt", "processors" : [ 6 ] + }, { + "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", + "filename" : "aerosolCloudData.txt", + "processors" : [ 9 ] } ], "processors" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor", @@ -61,8 +65,15 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepHealthStatusProcessor", "id" : 8 + }, { + "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", + "id" : 9, + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributes" : { + "sampleEveryNthSimStep" : 1 + } } ], - "isTimestamped" : true, + "isTimestamped" : false, "isWriteMetaData" : false }, "scenario" : { diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario index 561a372ac..c059a1f11 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario @@ -2,7 +2,7 @@ "name" : "closeContact", "description" : "", "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", + "commithash" : "3f3ee220e1af8f15090e99a05468f55af50cc810", "processWriters" : { "files" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", @@ -26,7 +26,7 @@ "processors" : [ 6 ] }, { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", - "filename" : "aerosolCloudShapes.txt", + "filename" : "aerosolCloudData.txt", "processors" : [ 8 ] } ], "processors" : [ { diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario index 0b1676efc..801f8e859 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario @@ -2,7 +2,7 @@ "name" : "passageway", "description" : "", "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", + "commithash" : "3f3ee220e1af8f15090e99a05468f55af50cc810", "processWriters" : { "files" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", @@ -16,6 +16,10 @@ "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile", "filename" : "overlapCount.txt", "processors" : [ 4 ] + }, { + "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", + "filename" : "aerosolCloudData.txt", + "processors" : [ 6 ] } ], "processors" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepProcessor", @@ -36,8 +40,15 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.FootStepHealthStatusProcessor", "id" : 5 + }, { + "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", + "id" : 6, + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributes" : { + "sampleEveryNthSimStep" : 1 + } } ], - "isTimestamped" : true, + "isTimestamped" : false, "isWriteMetaData" : false }, "scenario" : { diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario index 6ac16a23e..3289b394b 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario @@ -2,7 +2,7 @@ "name" : "queue", "description" : "", "release" : "2.0", - "commithash" : "f7ec0b9e854e9fd67cf1e5ad8c87511b6a129a45", + "commithash" : "3f3ee220e1af8f15090e99a05468f55af50cc810", "processWriters" : { "files" : [ { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", @@ -38,7 +38,7 @@ "processors" : [ 9 ] }, { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", - "filename" : "aerosolCloudShapes.txt", + "filename" : "aerosolCloudData.txt", "processors" : [ 12 ] } ], "processors" : [ { diff --git a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario index e0f78af07..653270a74 100644 --- a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario +++ b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario @@ -2,13 +2,9 @@ "name" : "hamner-2020-life_postvis_template", "description" : "", "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", + "commithash" : "3f3ee220e1af8f15090e99a05468f55af50cc810", "processWriters" : { "files" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile", - "filename" : "infectionStatus.txt", - "processors" : [ 1 ] - }, { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.EventtimePedestrianIdOutputFile", "filename" : "postvis.traj", "processors" : [ 2, 3, 6 ] @@ -22,7 +18,7 @@ "processors" : [ 5 ] }, { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepIdDataOutputFile", - "filename" : "aerosolCloudShapes.txt", + "filename" : "aerosolCloudData.txt", "processors" : [ 7 ] } ], "processors" : [ { diff --git a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario index 71f71849c..ec2e0040f 100644 --- a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario +++ b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_template.scenario @@ -2,13 +2,9 @@ "name" : "hamner-2020-life_template", "description" : "Superspreading event during a choir rehearsal following hamner-2020-life;\n\nL. Hamner, P. Dubbel, I. Capron, A. Ross, A. Jordan,\nJ. Lee, J. Lynn, A. Ball, S. Narwal, S. Russell, et al.\nHigh SARS-CoV-2 attack rate following exposure at a\nchoir practice — skagit county, washington, march 2020.\nMMWR. Morbidity and Mortality Weekly Report, 69\n(19):606–610, 2020. doi:10.15585/mmwr.mm6919e6.", "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", + "commithash" : "3f3ee220e1af8f15090e99a05468f55af50cc810", "processWriters" : { - "files" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile", - "filename" : "infectionStatus.txt", - "processors" : [ 1 ] - } ], + "files" : [ ], "processors" : [ ], "isTimestamped" : false, "isWriteMetaData" : false diff --git a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario index 25734cead..2dcd4fb7e 100644 --- a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario +++ b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/miller-2020-life_template.scenario @@ -2,13 +2,9 @@ "name" : "miller-2020-life_template", "description" : "Superspreading event during a choir rehearsal following miller-2020-life;\n\nS. L. Miller, W. W. Nazaroff, J. L. Jimenez, A. Boerstra, G. Buonanno, S. J. Dancer, J. Kurnitski, L. C. Marr, L. Morawska, and C. Noakes. Transmission of SARSCoV-2 by inhalation of respiratory aerosol in the skagit valley chorale superspreading event. Indoor Air, 31(2): 314–323, 2020. doi:10.1111/ina.12751.", "release" : "2.0", - "commithash" : "a45e488c23340a40f8809fb9abb820a7037f1d56", + "commithash" : "3f3ee220e1af8f15090e99a05468f55af50cc810", "processWriters" : { "files" : [ { - "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepOutputFile", - "filename" : "infectionStatus.txt", - "processors" : [ 1 ] - }, { "type" : "org.vadere.simulator.projects.dataprocessing.outputfile.PedestrianIdOutputFile", "filename" : "pathogenLoad.txt", "processors" : [ 2 ] diff --git a/VadereGui/src/org/vadere/gui/postvisualization/model/TableAerosolCloudData.java b/VadereGui/src/org/vadere/gui/postvisualization/model/TableAerosolCloudData.java index 561fbd8fd..326d55009 100644 --- a/VadereGui/src/org/vadere/gui/postvisualization/model/TableAerosolCloudData.java +++ b/VadereGui/src/org/vadere/gui/postvisualization/model/TableAerosolCloudData.java @@ -26,7 +26,7 @@ public class TableAerosolCloudData { private Table currentSlice; - public static final String TABLE_NAME = "aerosolCloudShapes"; + public static final String TABLE_NAME = "aerosolCloudData"; // columns, TODO: this is hard coded! public final int timeStepCol; -- GitLab From 9bb9f98df90d0570201a9ae93c5862c76320c6c7 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Thu, 3 Mar 2022 16:55:06 +0100 Subject: [PATCH 63/83] Refactoring: add string format locale US to avoid commas as decimal separator --- .../processor/FootStepHealthStatusProcessor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java index 3ce3da9c6..76a94eb5a 100644 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java +++ b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/FootStepHealthStatusProcessor.java @@ -8,6 +8,7 @@ import org.vadere.state.scenario.Pedestrian; import org.vadere.state.simulation.FootStep; import java.util.LinkedList; +import java.util.Locale; /** * Log {@link Pedestrian}'s current {@link org.vadere.state.health.ExposureModelHealthStatus} @@ -36,7 +37,7 @@ public class FootStepHealthStatusProcessor extends DataProcessor Date: Thu, 3 Mar 2022 18:03:01 +0100 Subject: [PATCH 64/83] Add changelog entry --- CHANGELOG.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63266a034..47ceb47f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,16 +6,60 @@ ### Added +### Removed + +### Changed + +### Fixed + +### Performance + +### Security + +### Deprecated + +### Other + + +## v2.1 (2022-03-XX) + +### Added + - Added new output processor "PedestrianTargetReachTimeProcessor" to log the time when an agent reaches its target. +- Added settings in `SettingsDialog` that allow to define opacity of aerosol clouds and agent coloring depending on their degree of exposure (`GUI`) +- Added `AbstractExposureModel` describing the exposure of healthy agents to infectious agents (`Simulator`) +* `AirTransmissionModel` as a new version of the previous `TransmisisonModel` (see section `changed`) +* `ProximityExposureModel`: Agents become exposed depending on the distance to infectious agents. +- Added `AbstractDoseResponseModel` describing the probability of infection depending on a pedestrian's individual exposure. (`Simulator`) +- `Pedestrian`: added new properties (`State`) +* Added attribute healthStatus of type T extends `ExposureModelHealthStatus` (corresponding to the new exposure model) +* Added attribute infectionStatus of type T extends `DoseResponseModelInfectionStatus` (corresponding to the new dose response model) ### Changed - In `postLoop()` of `Simulation.java`, clear the topography as very last step so that models and output processors can use it before. -- `TransmissionModel`: Reduce complexity of the transmission model (: `Simulator`, `GUI`, `State`) -* In AttributesTransmissionModel change parameter aerosolCloudInitialArea to aerosolCloudInitialRadius -* In `AttributesAerosolCloud` reduce number of parameters that describe the shape of an `AerosolCloud`. Instead of `VPolygon`, we now use `VCircle`, which can defined by a radius and a center. -* Adapt all methods and classes that were designed for both elliptical and circular clouds. -- Fix bug in `TikzGenerator`: Now, the tex file (generated with tikz snapshot) also contains aerosol clouds (29e9c937: `GUI`) +- Refactoring of the software architecture of `TransmissionModel` (`Simulator`, `GUI`, `State`): +* Renamed `TransmissionModel` to `AirTransmissionModel` to avoid confusion with transmission in the sense of communication or others. +* The previous concept of the TransmissionModel is now divided into exposure (`AbstractExposureModel`) and dose response (`AbstractDoseResponseModel`). The abstract classes allow for model enhancements or implementing alternative models. +* Adapted the model attributes so that they fit to the new exposure models and dose response models. +* Minor improvements / simplifications of the aerosol cloud model; Reduced complexity of the transmission model; Now, the model creates only circular but no elliptical clouds; +* Moved some hidden parameters to scenario file to make the model more flexible +* Move attributes that are equal for all instances of classes AerosolCloud, Droplets, and Pedestrian to the general model attributes (`AttributesAirTransmissionModel`). This is not strictly object-oriented but pragmatic and avoids redundancy. +- `TikzGenerator`: Make the transparency of aerosol clouds in the tex file depend on the pathogen concentration. (`GUI`) +- `SettingsDialog`: +* increase contrast between color of settings wheel and vadere GUI background color (2d2edad5: `GUI`) +* reduce width of color panels (`GUI`) +- Renamed + +### Fixed +- `TikzGenerator`: Now, the tex file (generated with tikz snapshot during onlinevisualization) also contains aerosol clouds (29e9c937: `GUI`) +- `SettingsDialog`: Fixed overlapping elements in postvis settings dialog. (`GUI`) +- `TopographyController`: Previously, pedestrians that were directly put into the topography (not spawned by sources) could not be accessed / manipulated by the TransmissionModel, that is one could not define a health status. These pedestrians are now handled by the TopographyController. (`Simulator`) + +## Removed +- Due to refactored architecture of the transmission model, removed... +* classes `HealthStatus`, `NumberOfPedPerInfectionStatusProcessor`, `PedestrianHealthStatusProcessor` (`State`, `Simulator`) +* enum `InfectionStatus` (`State`) ## v2.0 -- GitLab From 312ac39a845d29e27fb4a6c18186c7a42d16d940 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Fri, 4 Mar 2022 17:43:10 +0100 Subject: [PATCH 65/83] Minor changes --- .../models/infection/AirTransmissionModel.java | 12 ++++-------- .../AttributesAirTransmissionModel.java | 16 ++++++++++++++++ ...tributesAirTransmissionModelAerosolCloud.java | 12 ++++++++++-- .../scenario/AttributesAerosolCloud.java | 11 +++++++++-- .../org/vadere/state/scenario/AerosolCloud.java | 2 +- 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index e0d73955e..a51610c17 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -53,8 +53,8 @@ public class AirTransmissionModel extends AbstractExposureModel { protected static Logger logger = Logger.getLogger(AirTransmissionModel.class); - private AttributesAirTransmissionModel attrAirTransmissionModel; - double simTimeStepLength; + protected AttributesAirTransmissionModel attrAirTransmissionModel; + protected double simTimeStepLength; Topography topography; int aerosolCloudIdCounter; @@ -78,7 +78,7 @@ public class AirTransmissionModel extends AbstractExposureModel { * (pathogenLoad / aerosolCloud.volume); As soon as an aerosolCloud has reached the minimum concentration, the * aerosolCloud is considered negligible and therefore deleted */ - private static final double minimumPercentage = 0.01; + protected static final double minimumPercentage = 0.01; @Override public void initialize(List attributesList, Domain domain, AttributesAgent attributesPedestrian, Random random) { @@ -286,7 +286,7 @@ public class AirTransmissionModel extends AbstractExposureModel { } } - private void updatePedsHealthStatus(double simTimeInSec) { + protected void updatePedsHealthStatus(double simTimeInSec) { Collection allPedestrians = topography.getPedestrianDynamicElements().getElements(); for (Pedestrian pedestrian : allPedestrians) { pedestrian.getHealthStatus() @@ -389,10 +389,6 @@ public class AirTransmissionModel extends AbstractExposureModel { return pedestrian; } - public AttributesAirTransmissionModel getAttributesAirTransmissionModel() { - return attrAirTransmissionModel; - } - public static Collection getDynamicElementsNearAerosolCloud(Topography topography, AerosolCloud aerosolCloud) { final Rectangle2D aerosolCloudBounds = aerosolCloud.getShape().getBounds2D(); final VPoint centerOfAerosolCloud = new VPoint(aerosolCloudBounds.getCenterX(), aerosolCloudBounds.getCenterY()); diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java index b5b001b2d..67d83a62d 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java @@ -109,4 +109,20 @@ public class AttributesAirTransmissionModel extends AttributesExposureModel { public double getDropletsAbsorptionRate() { return dropletParameters.getAbsorptionRate(); } + + public void setAerosolCloudsActive(boolean aerosolCloudsActive) { + this.aerosolCloudsActive = aerosolCloudsActive; + } + + public void setAirDispersionFactor(double airDispersionFactor) { + this.aerosolCloudParameters.setAirDispersionFactor(airDispersionFactor); + } + + public void setPedestrianDispersionWeight(double pedestrianDispersionWeight) { + this.aerosolCloudParameters.setPedestrianDispersionWeight(pedestrianDispersionWeight); + } + + public void setDropletsActive(boolean dropletsActive) { + this.dropletsActive = dropletsActive; + } } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java index 6494703fc..32485157a 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java @@ -35,7 +35,7 @@ public class AttributesAirTransmissionModelAerosolCloud extends Attributes { /** * Describes constant dispersion (over time), i.e. the spatial spread over time due to local air movement. * This increases the radius of aerosol clouds equally in all directions (three-dimensional). - * Unit: meter / simulation step + * Unit: meter / second */ private double airDispersionFactor; @@ -44,7 +44,7 @@ public class AttributesAirTransmissionModelAerosolCloud extends Attributes { * (which results temporally in local air movement). Each agent that passes a cloud with speed > 0 m / s contributes * to the dispersion of the cloud: deltaRadius = pedestrianSpeed * pedestrianDispersionWeight * This increases the radius of aerosol clouds equally in all directions (three-dimensional). - * Unit: 1 / simulation step + * Unit: 1 */ private double pedestrianDispersionWeight; @@ -98,4 +98,12 @@ public class AttributesAirTransmissionModelAerosolCloud extends Attributes { public double getAbsorptionRate() { return absorptionRate; } + + protected void setAirDispersionFactor(double airDispersionFactor) { + this.airDispersionFactor = airDispersionFactor; + } + + protected void setPedestrianDispersionWeight(double pedestrianDispersionWeight) { + this.pedestrianDispersionWeight = pedestrianDispersionWeight; + } } diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java index e5c47c079..d6eecf4d2 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java @@ -2,6 +2,7 @@ package org.vadere.state.attributes.scenario; import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel; import org.vadere.state.scenario.AerosolCloud; +import org.vadere.util.geometry.shapes.VCircle; import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VShape; @@ -62,10 +63,16 @@ public class AttributesAerosolCloud extends AttributesParticleDispersion { // Setter public void setRadius(double radius) { - this.radius = radius; + this.setShape(new VCircle(this.center, radius)); } public void setCenter(VPoint center) { - this.center = center; + this.setShape(new VCircle(center, this.radius)); + } + + public void setShape(VCircle circle) { + this.setShape((VShape) circle); + this.radius = circle.getRadius(); + this.center = circle.getCenter(); } } \ No newline at end of file diff --git a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java index 6f35fa197..aa4a4df49 100644 --- a/VadereState/src/org/vadere/state/scenario/AerosolCloud.java +++ b/VadereState/src/org/vadere/state/scenario/AerosolCloud.java @@ -163,7 +163,7 @@ public class AerosolCloud extends ParticleDispersion { attributes.setRadius(newRadius); // define shape - VShape newShape = createAerosolCloudShape(center, newRadius); + VCircle newShape = createAerosolCloudShape(center, newRadius); attributes.setShape(newShape); } } -- GitLab From 1a1c40d1d72900042a15891b75da912380209246 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Fri, 4 Mar 2022 17:43:45 +0100 Subject: [PATCH 66/83] [wip] add tests --- .../infection/AirTransmissionModelTest.java | 284 ++++++++++++------ 1 file changed, 193 insertions(+), 91 deletions(-) diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java index a22d0d682..be9f4f25c 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java @@ -10,157 +10,259 @@ import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; -import org.vadere.state.attributes.scenario.AttributesTarget; +import org.vadere.state.health.AirTransmissionModelHealthStatus; import org.vadere.state.scenario.AerosolCloud; import org.vadere.state.scenario.Pedestrian; -import org.vadere.state.scenario.Target; import org.vadere.state.scenario.Topography; -import org.vadere.util.geometry.shapes.*; +import org.vadere.util.geometry.shapes.VPoint; +import org.vadere.util.geometry.shapes.Vector2D; -import java.util.*; - -import static org.junit.Assert.*; -import static org.vadere.simulator.models.infection.AirTransmissionModel.*; -import static org.vadere.state.scenario.AerosolCloud.createAerosolCloudShape; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; public class AirTransmissionModelTest { - public static double ALLOWED_DOUBLE_TOLERANCE = 10e-3; - static final double simTimeStepLength = 0.4; + private static final double ALLOWED_DOUBLE_TOLERANCE = 10e-3; + private static final double SIM_TIME_STEP_LENGTH = 0.4; - List attributeList; + List attributesList; AirTransmissionModel airTransmissionModel; Topography topography; VadereContext ctx; + Random rdm; + double simStartTime; - // member variables defining aerosol cloud shapes - double radius = 1; - VPoint center = new VPoint(0, 0); - VShape circle; - - - // will run before each test to setup test environment @Before public void setUp() { - attributeList = getAttributeList(); + attributesList = new ArrayList<>(); + attributesList.add(new AttributesAirTransmissionModel()); airTransmissionModel = new AirTransmissionModel(); topography = new Topography(); topography.setContextId("testId"); - + rdm = new Random(0); ctx = new VadereContext(); - ctx.put(AirTransmissionModel.simStepLength, simTimeStepLength); + ctx.put(AirTransmissionModel.simStepLength, SIM_TIME_STEP_LENGTH); VadereContext.add(topography.getContextId(), ctx); + simStartTime = 0.0; - circle = createAerosolCloudShape(center, radius); + initializeTransmissionModel(); } - // cleanup test environment @After public void after() { - attributeList.clear(); + attributesList.clear(); } @Test - public void testInitializeOk() { - // initialize must find the AttributesInfectionModel from the attributeList - airTransmissionModel.initialize(attributeList, new Domain(topography),null,null); + public void testInitializeFindsAttributesList() { + Assert.assertEquals(attributesList.get(0), airTransmissionModel.attrAirTransmissionModel); + } - AttributesAirTransmissionModel attributesAirTransmissionModel = airTransmissionModel.getAttributesAirTransmissionModel(); + @Test + public void testInitializeGetsSimTimeStepLength() { + Assert.assertEquals(ctx.get(AirTransmissionModel.simStepLength), airTransmissionModel.simTimeStepLength); + } - Assert.assertEquals(attributeList.get(0), attributesAirTransmissionModel); + @Test + public void testRegisterToScenarioElementControllerEvents() { + // TODO ... } - public List getAttributeList() { - ArrayList attrList = new ArrayList<>(); - var att = new AttributesAirTransmissionModel(); + @Test + public void testUpdate() { + // TODO ... + } - attrList.add(att); + @Test + public void testUpdateExecuteAerosolCloudEmissionEvents() { + setAerosolCloudsActive(); + Pedestrian pedestrian = createPedestrian(); + pedestrian.setInfectious(true); + topography.addElement(pedestrian); - return attrList; - } + double simEndTime = airTransmissionModel.attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod(); + for (double simTimeInSec = simStartTime; simTimeInSec <= simEndTime; simTimeInSec += airTransmissionModel.simTimeStepLength) { + airTransmissionModel.executeAerosolCloudEmissionEvents(simTimeInSec); - private void createPedestrian(Topography topography, VPoint pedPosition, int pedId, int targetId, boolean isInfectious) { - Pedestrian pedestrian = new Pedestrian(new AttributesAgent(), new Random(1)); - pedestrian.setPosition(pedPosition); - pedestrian.setInfectious(isInfectious); - pedestrian.setId(pedId); + // the tested method requires that the pedestrian's health status is updated as well + airTransmissionModel.updatePedsHealthStatus(simTimeInSec); + } - LinkedList targetsPedestrian = new LinkedList<>(); - targetsPedestrian.add(targetId); - pedestrian.setTargets(targetsPedestrian); + Assert.assertTrue(topography.getAerosolClouds().size()>0); + } - topography.addElement(pedestrian); + @Test + public void testUpdateAerosolClouds() { + // maybe not necessary } - private void createTarget(Topography topography, VPoint targetCenter, int id) { - Target target = new Target(new AttributesTarget()); - target.setShape(new VCircle(targetCenter, 0.5)); - target.getAttributes().setId(id); + @Test + public void testUpdateAerosolCloudsPathogenLoad() { + setAerosolCloudsActive(); + + double expectedPathogenLoad = airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialPathogenLoad(); + double simStepWidth = airTransmissionModel.attrAirTransmissionModel.getAerosolCloudHalfLife(); + double simTimeInSec = simStartTime; + int nSimSteps = 10; + + createAerosolCloud(airTransmissionModel); + + double[] modelPathogenLoads = new double[nSimSteps]; + double[] expectedPathogenLoads = new double[nSimSteps]; + for (int i = 0; i < nSimSteps; i++) { + airTransmissionModel.updateAerosolCloudsPathogenLoad(simTimeInSec); + + modelPathogenLoads[i] = (topography.getAerosolClouds().stream().filter(a -> a.getId() == 1).findFirst().get().getCurrentPathogenLoad()); + expectedPathogenLoads[i] = (expectedPathogenLoad); - topography.addTarget(target); + simTimeInSec += simStepWidth; + expectedPathogenLoad /= 2; + } + + Assert.assertArrayEquals(expectedPathogenLoads, modelPathogenLoads, ALLOWED_DOUBLE_TOLERANCE); } @Test - public void testUpdateNumberOfGeneratedAerosolClouds() { + public void testUpdateAerosolCloudsExtentDueToDispersion() { + setAerosolCloudsActive(); + double dispersionFactor = 0.001; // dispersion in meter / simStep + airTransmissionModel.attrAirTransmissionModel.setAirDispersionFactor(dispersionFactor); // defines time-dependent dispersion + airTransmissionModel.attrAirTransmissionModel.setPedestrianDispersionWeight(0.0); // ped movement has no effect - airTransmissionModel.initialize(attributeList, new Domain(topography),null,null); + int nSimSteps = 100; + double simEndTime = nSimSteps * airTransmissionModel.simTimeStepLength; - createPedestrian(topography, new VPoint(10, 10), 1, -1, true); + createAerosolCloud(airTransmissionModel); - double simTimeInSec = 0.0; - double simTimeStepLength = 0.4; - double simEndTime = 100; + double radius = calculateAerosolCloudRadius(airTransmissionModel, nSimSteps); + double expectedRadius = airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialRadius() + simEndTime * dispersionFactor; + + Assert.assertEquals(expectedRadius, radius, ALLOWED_DOUBLE_TOLERANCE); + } + + @Test + public void testUpdateAerosolCloudsExtentDueToDispersionIndependentFromSimStepLength() { + setAerosolCloudsActive(); + double dispersionFactor = 0.001; + airTransmissionModel.attrAirTransmissionModel.setAirDispersionFactor(dispersionFactor); // defines time-dependent dispersion + airTransmissionModel.attrAirTransmissionModel.setPedestrianDispersionWeight(0.0); // ped movement has no effect + createAerosolCloud(airTransmissionModel); + double simTimeStepLength = airTransmissionModel.simTimeStepLength; + int nSimSteps = 2500; + + double simEndTime = nSimSteps * simTimeStepLength; + + int nSimSteps2 = 2000; + double simTimeStepLength2 = simEndTime / nSimSteps2; + + // second AirTransmissionModel with different simTimeStepLength + AirTransmissionModel airTransmissionModel2 = new AirTransmissionModel(); + Topography topography2 = new Topography(); + topography2.setContextId("testId2"); + rdm = new Random(0); + VadereContext ctx2 = new VadereContext(); + ctx2.put(AirTransmissionModel.simStepLength, simTimeStepLength2); // chosen arbitrarily, not too high + VadereContext.add(topography2.getContextId(), ctx2); + airTransmissionModel2.initialize(attributesList, new Domain(topography2), null, rdm); + airTransmissionModel2.attrAirTransmissionModel.setAerosolCloudsActive(true); + createAerosolCloud(airTransmissionModel2); + + double radius = calculateAerosolCloudRadius(airTransmissionModel, nSimSteps); + double radius2 = calculateAerosolCloudRadius(airTransmissionModel2, nSimSteps2); + + Assert.assertEquals(radius, radius2, ALLOWED_DOUBLE_TOLERANCE); + } - while(simTimeInSec <= simEndTime) { - airTransmissionModel.update(simTimeInSec); - simTimeInSec += simTimeStepLength; + private double calculateAerosolCloudRadius(AirTransmissionModel airTransmissionModel, int nSimSteps) { + for (int i = 1; i <= nSimSteps; i++) { + airTransmissionModel.updateAerosolCloudsExtent(); } + return airTransmissionModel.topography.getAerosolClouds().stream().findFirst().get().getRadius(); + } + + + @Test + public void testUpdateAerosolCloudsExtentAgentMovement() { + createAerosolCloud(airTransmissionModel); - int expectedNumberOfAerosolClouds = (int) Math.floor(simEndTime / airTransmissionModel.getAttributesAirTransmissionModel().getPedestrianRespiratoryCyclePeriod()); - int actualNumberOfAerosolClouds = topography.getAerosolClouds().size(); + double simTimeStepLength = airTransmissionModel.simTimeStepLength; + int nSimSteps = 2; // arbitrarily chosen - assertEquals(actualNumberOfAerosolClouds, expectedNumberOfAerosolClouds); + Pedestrian pedestrian = createPedestrian(); + VPoint positionWithinCloud = airTransmissionModel.topography.getAerosolClouds().stream().findFirst().get().getCenter(); + pedestrian.setPosition(positionWithinCloud); + Vector2D velocity = new Vector2D (10, 10); + pedestrian.setVelocity(velocity); + topography.addElement(pedestrian); + + double radius = calculateAerosolCloudRadius(airTransmissionModel, nSimSteps); + double expectedRadius = airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialRadius() + nSimSteps * velocity.getLength() * simTimeStepLength * airTransmissionModel.attrAirTransmissionModel.getAerosolCloudPedestrianDispersionWeight(); + + Assert.assertEquals(expectedRadius, radius, ALLOWED_DOUBLE_TOLERANCE); } @Test - public void throwIfPedestrianInsideAerosolCloudNotDetected() { - Topography topography = new Topography(); - createPedestrian(topography, new VPoint(10, 10), 1, -1, false); - AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(Attributes.ID_NOT_SET, 1, new VPoint(10, 10), 0.0, 0)); - topography.addAerosolCloud(aerosolCloud); - boolean inAerosolCloud = isPedestrianInAerosolCloud(aerosolCloud, topography.getPedestrianDynamicElements().getElement(1)); + public void testDeleteExpiredAerosolClouds() { + createAerosolCloud(airTransmissionModel); + AerosolCloud aerosolCloud = topography.getAerosolClouds().stream().findFirst().get(); + double negligiblePathogenConcentr = (AirTransmissionModel.minimumPercentage * 0.9) * aerosolCloud.getPathogenConcentration(); + aerosolCloud.setCurrentPathogenLoad(negligiblePathogenConcentr); + + airTransmissionModel.deleteExpiredAerosolClouds(); - assertTrue(inAerosolCloud); + Assert.assertTrue(topography.getAerosolClouds().stream().collect(Collectors.toSet()).isEmpty()); } @Test - public void throwIfPedestrianOutsideAerosolCloudConsideredInside() { - Topography topography = new Topography(); - createPedestrian(topography, new VPoint(5, 5), 1, -1, false); - AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(Attributes.ID_NOT_SET, 1, new VPoint(10, 10), 0.0, 0)); - topography.addAerosolCloud(aerosolCloud); - boolean inAerosolCloud = isPedestrianInAerosolCloud(aerosolCloud, topography.getPedestrianDynamicElements().getElement(1)); + public void testUpdatePedestriansExposureToAerosolClouds() { - assertFalse(inAerosolCloud); } @Test - public void testGetPedestriansInsideAerosolCloud() { - Topography topography = new Topography(); - AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(Attributes.ID_NOT_SET, 1, new VPoint(10, 10), 0.0, 0)); - aerosolCloud.setId(1); - topography.addAerosolCloud(aerosolCloud); - // pedestrians outside cloud - createPedestrian(topography, new VPoint(12, 12), 2, -1, false); - createPedestrian(topography, new VPoint(1, 1), 3, -1,false); - // pedestrians inside cloud - createPedestrian(topography, new VPoint(10, 10), 4, -1, false); - createPedestrian(topography, new VPoint(10.5, 10.5), 5, -1, false); + public void testExecuteDropletEmissionEvents() { - Collection expectedPedestriansInAerosolCloud = new LinkedList<>(); - expectedPedestriansInAerosolCloud.add(topography.getPedestrianDynamicElements().getElement(4)); - expectedPedestriansInAerosolCloud.add(topography.getPedestrianDynamicElements().getElement(5)); + } + + @Test + public void testUpdateDroplets() { + + } + + @Test + public void testUpdatePedestriansExposureToDroplets() { + + } + + @Test + public void testUpdatePedsHealthStatus() { + + } + + private void initializeTransmissionModel() { + airTransmissionModel.initialize(attributesList, new Domain(topography), null, rdm); + } + + private Pedestrian createPedestrian() { + Pedestrian pedestrian = new Pedestrian(new AttributesAgent(), rdm); + pedestrian.setHealthStatus(new AirTransmissionModelHealthStatus()); + return pedestrian; + } + + private void createAerosolCloud(AirTransmissionModel airTransmissionModel) { + AerosolCloud aerosolCloud = new AerosolCloud(new AttributesAerosolCloud(1, + airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialRadius(), + new VPoint(5, 5), // position is not important for only a few tests + simStartTime, + airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialPathogenLoad())); + airTransmissionModel.topography.addAerosolCloud(aerosolCloud); + } + + private void setAerosolCloudsActive() { + airTransmissionModel.attrAirTransmissionModel.setAerosolCloudsActive(true); + } - Collection actualPedestriansInAerosolCloud = getPedestriansInsideAerosolCloud(topography, aerosolCloud); - assertEquals(actualPedestriansInAerosolCloud, expectedPedestriansInAerosolCloud); + private void setDropletsActive() { + airTransmissionModel.attrAirTransmissionModel.setDropletsActive(true); } } \ No newline at end of file -- GitLab From 1d89c68e4a4481af103c8e6d9b51222cc9404b52 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 14 Mar 2022 18:26:45 +0100 Subject: [PATCH 67/83] Add clone, equals and hashCode methods --- .../AirTransmissionModelHealthStatus.java | 20 +++++++++++++++++++ .../BasicExposureModelHealthStatus.java | 9 +++++++++ .../health/ExposureModelHealthStatus.java | 18 +++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java b/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java index ae2ed11bd..4568857cd 100644 --- a/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/AirTransmissionModelHealthStatus.java @@ -2,6 +2,8 @@ package org.vadere.state.health; import org.vadere.util.geometry.shapes.VPoint; +import java.util.Objects; + /** * AirTransmissionModelHealthStatus that is used in combination with the * AirTransmissionModel. @@ -93,6 +95,24 @@ public class AirTransmissionModelHealthStatus extends ExposureModelHealthStatus } // Methods + @Override + public AirTransmissionModelHealthStatus clone() { + return new AirTransmissionModelHealthStatus(this); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof AirTransmissionModelHealthStatus)) return false; + if (!super.equals(obj)) return false; + AirTransmissionModelHealthStatus other = (AirTransmissionModelHealthStatus) obj; + return breathingIn == other.breathingIn && Double.compare(other.respiratoryTimeOffset, respiratoryTimeOffset) == 0 && Objects.equals(exhalationStartPosition, other.exhalationStartPosition); + } + + @Override + public int hashCode() { + return Objects.hash(breathingIn, respiratoryTimeOffset, exhalationStartPosition); + } /** * Defines whether the pedestrian inhales or exhales depending on the current simulation time, diff --git a/VadereState/src/org/vadere/state/health/BasicExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/BasicExposureModelHealthStatus.java index 78c578bfe..7f24d2e2c 100644 --- a/VadereState/src/org/vadere/state/health/BasicExposureModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/BasicExposureModelHealthStatus.java @@ -12,4 +12,13 @@ public class BasicExposureModelHealthStatus extends ExposureModelHealthStatus { public BasicExposureModelHealthStatus() { super(); } + + public BasicExposureModelHealthStatus(BasicExposureModelHealthStatus other) { + super(other.isInfectious(), other.getDegreeOfExposure()); + } + + @Override + public BasicExposureModelHealthStatus clone() { + return new BasicExposureModelHealthStatus(this); + } } diff --git a/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java index f9022d994..d4fa68f0c 100644 --- a/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java +++ b/VadereState/src/org/vadere/state/health/ExposureModelHealthStatus.java @@ -1,5 +1,7 @@ package org.vadere.state.health; +import java.util.Objects; + /** * ExposureModelHealthStatus is the abstract base class for all types of exposure * a Pedestrian can adopt. @@ -46,4 +48,20 @@ public abstract class ExposureModelHealthStatus { public void incrementDegreeOfExposure(double deltaDegreeOfExposure) { this.degreeOfExposure += deltaDegreeOfExposure; } + + @Override + public abstract ExposureModelHealthStatus clone(); + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof ExposureModelHealthStatus)) return false; + ExposureModelHealthStatus other = (ExposureModelHealthStatus) obj; + return infectious == other.infectious && Double.compare(other.degreeOfExposure, degreeOfExposure) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(infectious, degreeOfExposure); + } } -- GitLab From 57645995c037746d9a9379e4b44b73d444456cd7 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 14 Mar 2022 18:32:46 +0100 Subject: [PATCH 68/83] Minor changes; add setter --- .../models/infection/AirTransmissionModel.java | 2 +- .../infection/AttributesAirTransmissionModel.java | 12 ++++++++++++ .../AttributesAirTransmissionModelAerosolCloud.java | 4 ++++ .../AttributesAirTransmissionModelDroplets.java | 8 ++++++++ .../src/org/vadere/state/scenario/Droplets.java | 2 +- 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index a51610c17..d950026f8 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -294,7 +294,7 @@ public class AirTransmissionModel extends AbstractExposureModel { } } - private void updatePedestriansExposureToAerosolClouds() { + protected void updatePedestriansExposureToAerosolClouds() { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java index 67d83a62d..e2283d117 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModel.java @@ -114,6 +114,10 @@ public class AttributesAirTransmissionModel extends AttributesExposureModel { this.aerosolCloudsActive = aerosolCloudsActive; } + public void setAerosolCloudHalfLife(double halfLife) { + this.aerosolCloudParameters.setHalfLife(halfLife); + } + public void setAirDispersionFactor(double airDispersionFactor) { this.aerosolCloudParameters.setAirDispersionFactor(airDispersionFactor); } @@ -125,4 +129,12 @@ public class AttributesAirTransmissionModel extends AttributesExposureModel { public void setDropletsActive(boolean dropletsActive) { this.dropletsActive = dropletsActive; } + + public void setDropletsLifeTime(double lifeTime) { + this.dropletParameters.setLifeTime(lifeTime); + } + + public void setDropletsAngleOfSpreadInDeg(double angleOfSpreadInDeg) { + this.dropletParameters.setAngleOfSpreadInDeg(angleOfSpreadInDeg); + } } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java index 32485157a..9e91d0f34 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelAerosolCloud.java @@ -99,6 +99,10 @@ public class AttributesAirTransmissionModelAerosolCloud extends Attributes { return absorptionRate; } + protected void setHalfLife(double halfLife) { + this.halfLife = halfLife; + } + protected void setAirDispersionFactor(double airDispersionFactor) { this.airDispersionFactor = airDispersionFactor; } diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java index 9c8dad1fa..52ff7c66e 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesAirTransmissionModelDroplets.java @@ -80,4 +80,12 @@ public class AttributesAirTransmissionModelDroplets extends Attributes { public double getAbsorptionRate() { return absorptionRate; } + + protected void setLifeTime(double lifeTime) { + this.lifeTime = lifeTime; + } + + protected void setAngleOfSpreadInDeg(double angleOfSpreadInDeg) { + this.angleOfSpreadInDeg = angleOfSpreadInDeg; + } } diff --git a/VadereState/src/org/vadere/state/scenario/Droplets.java b/VadereState/src/org/vadere/state/scenario/Droplets.java index 8c43e01fc..b53af94ab 100644 --- a/VadereState/src/org/vadere/state/scenario/Droplets.java +++ b/VadereState/src/org/vadere/state/scenario/Droplets.java @@ -15,7 +15,7 @@ import java.awt.geom.Path2D; public class Droplets extends ParticleDispersion { private AttributesDroplets attributes; - final static int numberOfCircularSections = 5; + final static int numberOfCircularSections = 10; // should not be lower; lower values cause edges when approximating a circular segment if angleOfSpreadInDeg in AttributesAirTransmissionModelDroplets is large // Constructors public Droplets() { -- GitLab From 17ce9617b9836c8c28331bec13ffc5e8c61f9002 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Mon, 14 Mar 2022 18:35:26 +0100 Subject: [PATCH 69/83] [wip] Update AirTransmissionModelTest to new software architecture and new functionality --- .../infection/AirTransmissionModelTest.java | 176 ++++++++++++++++-- 1 file changed, 165 insertions(+), 11 deletions(-) diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java index be9f4f25c..b09097c23 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java @@ -70,13 +70,135 @@ public class AirTransmissionModelTest { } @Test - public void testUpdate() { - // TODO ... + public void testUpdateCreatesAerosolCloudsAlthoughNotActive() { + setAerosolCloudsActive(false); + double simTime = getUpdateSimTime(); + initUpdate(simTime); + runUpdate(simTime); + Assert.assertEquals(0, topography.getAerosolClouds().size()); + } + + @Test + public void testUpdateCreatesDropletsAlthoughNotActive() { + setDropletsActive(false); + double simTime = getUpdateSimTime(); + initUpdate(simTime); + runUpdate(simTime); + Assert.assertEquals(0, topography.getDroplets().size()); + } + + @Test + public void testUpdateWhenAerosolCloudsActive() { + setAerosolCloudsActive(true); + double simTime = getUpdateSimTime(); + initUpdate(simTime); + runUpdate(simTime); + + Assert.assertTrue(topography.getAerosolClouds().size() > 0); + } + + @Test + public void testUpdateWhenDropletsActive() { + setDropletsActive(true); + double simTime = getUpdateSimTime(); + initUpdate(simTime); + runUpdate(simTime); + + Assert.assertTrue(topography.getDroplets().size() > 0); + } + + @Test + public void testUpdateHealthStatusWhenAerosolCloudsAndDropletsNotActive() { + setAerosolCloudsActive(false); + setDropletsActive(false); + double simTime = getUpdateSimTime(); + initUpdate(simTime); + + Pedestrian pedestrian = topography.getPedestrianDynamicElements().getElements().stream().filter(p -> !p.isInfectious()).findFirst().get(); + AirTransmissionModelHealthStatus actualStatus = pedestrian.getHealthStatus(); + AirTransmissionModelHealthStatus expectedStatus = actualStatus.clone(); + + runUpdate(simTime); + + Assert.assertEquals(expectedStatus, actualStatus); + } + + @Test + public void testUpdateHealthStatusWhenAerosolCloudsActive() { + setAerosolCloudsActive(true); + setDropletsActive(false); + double simTime = getUpdateSimTime(); + initUpdate(simTime); + + Pedestrian pedestrian = topography.getPedestrianDynamicElements().getElements().stream().filter(p -> !p.isInfectious()).findFirst().get(); + AirTransmissionModelHealthStatus actualStatus = pedestrian.getHealthStatus(); + AirTransmissionModelHealthStatus unexpectedStatus = actualStatus.clone(); + + runUpdate(simTime); + + Assert.assertNotEquals(unexpectedStatus, actualStatus); + } + + @Test + public void testUpdateHealthStatusWhenDropletsActive() { + setAerosolCloudsActive(false); + setDropletsActive(true); + airTransmissionModel.attrAirTransmissionModel.setDropletsAngleOfSpreadInDeg(359.999); // make sure that non-infectious pedestrian is really caught by droplets + double simTime = getUpdateSimTime(); + initUpdate(simTime); + + Pedestrian pedestrian = topography.getPedestrianDynamicElements().getElements().stream().filter(p -> !p.isInfectious()).findFirst().get(); + AirTransmissionModelHealthStatus actualStatus = pedestrian.getHealthStatus(); + AirTransmissionModelHealthStatus unexpectedStatus = actualStatus.clone(); + + runUpdate(simTime); + + Assert.assertNotEquals(unexpectedStatus, actualStatus); + } + + private double getUpdateSimTime() { + double bufferTime = 2 * airTransmissionModel.attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod(); + double simDuration = bufferTime + Math.max(1 / airTransmissionModel.attrAirTransmissionModel.getDropletsEmissionFrequency(), airTransmissionModel.attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod()); + + return simDuration; + } + + private void initUpdate(double simTime) { + + // this is only necessary to assure that aerosol clouds or droplets remain until the simEndTime once they are inserted into the topography + airTransmissionModel.attrAirTransmissionModel.setAerosolCloudHalfLife(simTime + 1); + airTransmissionModel.attrAirTransmissionModel.setDropletsLifeTime(simTime + 1); + + Pedestrian pedestrian1 = createPedestrian(); + pedestrian1.setInfectious(true); + VPoint pos1 = new VPoint(2,2); + pedestrian1.setPosition(pos1); + pedestrian1.setId(1); + topography.addElement(pedestrian1); + + double distance = 0.5 * Math.min(airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialRadius(), airTransmissionModel.attrAirTransmissionModel.getDropletsDistanceOfSpread()); + Vector2D spacingBetweenPeds = new Vector2D(1, 1); + spacingBetweenPeds.normalize(distance); + + Pedestrian pedestrian2 = createPedestrian(); + VPoint pos2 = pos1.add(spacingBetweenPeds); + pedestrian2.setPosition(pos2); + pedestrian2.setId(2); + topography.addElement(pedestrian2); + } + + private void runUpdate(double simEndTime) { + double simTimeInSec; + double simTimeStepLength = airTransmissionModel.simTimeStepLength; + + for (simTimeInSec = simStartTime; simTimeInSec < simEndTime; simTimeInSec += simTimeStepLength) { + airTransmissionModel.update(simTimeInSec); + } } @Test public void testUpdateExecuteAerosolCloudEmissionEvents() { - setAerosolCloudsActive(); + setAerosolCloudsActive(true); Pedestrian pedestrian = createPedestrian(); pedestrian.setInfectious(true); topography.addElement(pedestrian); @@ -99,7 +221,7 @@ public class AirTransmissionModelTest { @Test public void testUpdateAerosolCloudsPathogenLoad() { - setAerosolCloudsActive(); + setAerosolCloudsActive(true); double expectedPathogenLoad = airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialPathogenLoad(); double simStepWidth = airTransmissionModel.attrAirTransmissionModel.getAerosolCloudHalfLife(); @@ -125,7 +247,7 @@ public class AirTransmissionModelTest { @Test public void testUpdateAerosolCloudsExtentDueToDispersion() { - setAerosolCloudsActive(); + setAerosolCloudsActive(true); double dispersionFactor = 0.001; // dispersion in meter / simStep airTransmissionModel.attrAirTransmissionModel.setAirDispersionFactor(dispersionFactor); // defines time-dependent dispersion airTransmissionModel.attrAirTransmissionModel.setPedestrianDispersionWeight(0.0); // ped movement has no effect @@ -143,7 +265,7 @@ public class AirTransmissionModelTest { @Test public void testUpdateAerosolCloudsExtentDueToDispersionIndependentFromSimStepLength() { - setAerosolCloudsActive(); + setAerosolCloudsActive(true); double dispersionFactor = 0.001; airTransmissionModel.attrAirTransmissionModel.setAirDispersionFactor(dispersionFactor); // defines time-dependent dispersion airTransmissionModel.attrAirTransmissionModel.setPedestrianDispersionWeight(0.0); // ped movement has no effect @@ -214,9 +336,41 @@ public class AirTransmissionModelTest { Assert.assertTrue(topography.getAerosolClouds().stream().collect(Collectors.toSet()).isEmpty()); } + private Pedestrian testUpdatePedestriansExposureToAerosolClouds(boolean pedestrianOutsideCloud) { + createAerosolCloud(airTransmissionModel); + + double simTimeStepLength = airTransmissionModel.simTimeStepLength; + int nInhalations = 2; + double simEndTime = nInhalations * airTransmissionModel.attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod(); + + Pedestrian pedestrian = createPedestrian(); + VPoint position = airTransmissionModel.topography.getAerosolClouds().stream().findFirst().get().getCenter(); + if (pedestrianOutsideCloud) { + position = position.add(new VPoint(airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialRadius(), airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialRadius())); + } + pedestrian.setPosition(position); + topography.addElement(pedestrian); + + for (double simTimeInSec = simStartTime; simTimeInSec < simEndTime; simTimeInSec += simTimeStepLength) { + airTransmissionModel.updatePedestriansExposureToAerosolClouds(); + airTransmissionModel.updatePedsHealthStatus(simTimeInSec); + } + + return pedestrian; + } + + @Test + public void testUpdatePedestriansExposureWithinAerosolClouds() { + Pedestrian pedestrian = testUpdatePedestriansExposureToAerosolClouds(false); + + Assert.assertTrue(pedestrian.getDegreeOfExposure() > 0); + } + @Test - public void testUpdatePedestriansExposureToAerosolClouds() { + public void testUpdatePedestriansExposureOutsideAerosolClouds() { + Pedestrian pedestrian = testUpdatePedestriansExposureToAerosolClouds(true); + Assert.assertEquals(0, pedestrian.getDegreeOfExposure(), ALLOWED_DOUBLE_TOLERANCE); } @Test @@ -258,11 +412,11 @@ public class AirTransmissionModelTest { airTransmissionModel.topography.addAerosolCloud(aerosolCloud); } - private void setAerosolCloudsActive() { - airTransmissionModel.attrAirTransmissionModel.setAerosolCloudsActive(true); + private void setAerosolCloudsActive(boolean active) { + airTransmissionModel.attrAirTransmissionModel.setAerosolCloudsActive(active); } - private void setDropletsActive() { - airTransmissionModel.attrAirTransmissionModel.setDropletsActive(true); + private void setDropletsActive(boolean active) { + airTransmissionModel.attrAirTransmissionModel.setDropletsActive(active); } } \ No newline at end of file -- GitLab From e000369b2c147e24c40aae71764c873a5d870508 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 15 Mar 2022 14:20:04 +0100 Subject: [PATCH 70/83] Refactoring Minor changes; Make code more readable; --- .../infection/AirTransmissionModel.java | 51 ++++++++++--------- .../infection/AttributesExposureModel.java | 4 ++ .../scenario/AttributesAerosolCloud.java | 4 +- .../scenario/AttributesDroplets.java | 31 +++++++++-- .../org/vadere/state/scenario/Droplets.java | 12 ++++- 5 files changed, 69 insertions(+), 33 deletions(-) diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java index d950026f8..04e80e981 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/AirTransmissionModel.java @@ -24,8 +24,6 @@ import java.awt.geom.Rectangle2D; import java.util.*; import java.util.stream.Collectors; -import static org.vadere.state.scenario.Droplets.createTransformedDropletsShape; - /** * AirTransmissionModel describes the transmission of pathogen from one * Pedestrian to another via ParticleDispersion that @@ -60,7 +58,8 @@ public class AirTransmissionModel extends AbstractExposureModel { private Map lastPedestrianPositions; private Map viewingDirections; - private static final double MIN_PED_STEP_LENGTH = 0.1; + private Map nextDropletsExhalationTime; + protected static final double MIN_PED_STEP_LENGTH = 0.1; /** * Key that is used for initializeVadereContext in ScenarioRun @@ -82,15 +81,16 @@ public class AirTransmissionModel extends AbstractExposureModel { @Override public void initialize(List attributesList, Domain domain, AttributesAgent attributesPedestrian, Random random) { - this.domain = domain; - this.random = random; - this.attributesAgent = attributesPedestrian; - this.attrAirTransmissionModel = Model.findAttributes(attributesList, AttributesAirTransmissionModel.class); - this.topography = domain.getTopography(); - this.simTimeStepLength = VadereContext.get(this.topography).getDouble(simStepLength); - this.aerosolCloudIdCounter = 1; - this.viewingDirections = new HashMap<>(); - this.lastPedestrianPositions = new HashMap<>(); + this.domain = domain; + this.random = random; + this.attributesAgent = attributesPedestrian; + this.attrAirTransmissionModel = Model.findAttributes(attributesList, AttributesAirTransmissionModel.class); + this.topography = domain.getTopography(); + this.simTimeStepLength = VadereContext.get(this.topography).getDouble(simStepLength); + this.aerosolCloudIdCounter = 1; + this.viewingDirections = new HashMap<>(); + this.lastPedestrianPositions = new HashMap<>(); + this.nextDropletsExhalationTime = new HashMap<>(); } @Override @@ -115,7 +115,7 @@ public class AirTransmissionModel extends AbstractExposureModel { } if (attrAirTransmissionModel.isAerosolCloudsActive() || attrAirTransmissionModel.isDropletsActive()) { - updatePedsHealthStatus(simTimeInSec); + updatePedestriansHealthStatus(simTimeInSec); } } @@ -202,19 +202,20 @@ public class AirTransmissionModel extends AbstractExposureModel { // period between two droplet generating respiratory events double dropletExhalationPeriod = 1 / attrAirTransmissionModel.getDropletsEmissionFrequency(); - if (simTimeInSec % dropletExhalationPeriod < simTimeStepLength) { - - VShape shape = createTransformedDropletsShape(pedestrian.getPosition(), - viewingDirection, - attrAirTransmissionModel.getDropletsDistanceOfSpread(), - Math.toRadians(attrAirTransmissionModel.getDropletsAngleOfSpreadInDeg())); - + if (nextDropletsExhalationTime.get(pedestrianId) == null) { + nextDropletsExhalationTime.put(pedestrianId, simTimeInSec + dropletExhalationPeriod); + } else if (simTimeInSec >= nextDropletsExhalationTime.get(pedestrianId) && !pedestrian.getHealthStatus().isBreathingIn()) { Droplets droplets = new Droplets(new AttributesDroplets(1, - shape, simTimeInSec, - attrAirTransmissionModel.getDropletsPathogenLoad())); + attrAirTransmissionModel.getDropletsPathogenLoad(), + pedestrian.getPosition(), + viewingDirection, + attrAirTransmissionModel.getDropletsDistanceOfSpread(), + attrAirTransmissionModel.getDropletsAngleOfSpreadInDeg())); topography.addDroplets(droplets); + + nextDropletsExhalationTime.put(pedestrianId, simTimeInSec + dropletExhalationPeriod); } } @@ -286,7 +287,7 @@ public class AirTransmissionModel extends AbstractExposureModel { } } - protected void updatePedsHealthStatus(double simTimeInSec) { + protected void updatePedestriansHealthStatus(double simTimeInSec) { Collection allPedestrians = topography.getPedestrianDynamicElements().getElements(); for (Pedestrian pedestrian : allPedestrians) { pedestrian.getHealthStatus() @@ -320,7 +321,7 @@ public class AirTransmissionModel extends AbstractExposureModel { } } - private void updatePedestriansExposureToDroplets() { + protected void updatePedestriansExposureToDroplets() { Collection breathingInPeds = topography.getPedestrianDynamicElements() .getElements() .stream() @@ -374,7 +375,7 @@ public class AirTransmissionModel extends AbstractExposureModel { } @Override - public Pedestrian topographyControllerEvent(TopographyController topographyController, double simtimeInSec, Agent agent) { + public Pedestrian topographyControllerEvent(TopographyController topographyController, double simTimeInSec, Agent agent) { Pedestrian pedestrian = (Pedestrian) agent; AirTransmissionModelHealthStatus defaultHealthStatus = new AirTransmissionModelHealthStatus(); diff --git a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java index 112be302a..1c50b2264 100644 --- a/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java +++ b/VadereState/src/org/vadere/state/attributes/models/infection/AttributesExposureModel.java @@ -31,4 +31,8 @@ public abstract class AttributesExposureModel extends Attributes { public ArrayList getInfectiousPedestrianIdsNoSource() { return infectiousPedestrianIdsNoSource; } + + public void addInfectiousPedestrianIdsNoSource(int pedestrianId) { + infectiousPedestrianIdsNoSource.add(pedestrianId); + } } diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java index d6eecf4d2..f3c74577d 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAerosolCloud.java @@ -63,11 +63,11 @@ public class AttributesAerosolCloud extends AttributesParticleDispersion { // Setter public void setRadius(double radius) { - this.setShape(new VCircle(this.center, radius)); + this.setShape(AerosolCloud.createAerosolCloudShape(this.center, radius)); } public void setCenter(VPoint center) { - this.setShape(new VCircle(center, this.radius)); + this.setShape(AerosolCloud.createAerosolCloudShape(center, this.radius)); } public void setShape(VCircle circle) { diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java index 9dafecb87..daf252707 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesDroplets.java @@ -1,23 +1,44 @@ package org.vadere.state.attributes.scenario; +import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModelDroplets; import org.vadere.state.scenario.Droplets; -import org.vadere.util.geometry.shapes.VShape; +import org.vadere.util.geometry.shapes.VPoint; +import org.vadere.util.geometry.shapes.Vector2D; /** * This class defines the attributes of a {@link Droplets}. */ public class AttributesDroplets extends AttributesParticleDispersion { - //private VShape shape; + private VPoint origin; + private Vector2D direction; // Constructors public AttributesDroplets() { super(); - // ToDo this.shape = some circularSector ... + this.setShape(new VPoint(), new Vector2D(), new AttributesAirTransmissionModelDroplets().getDistanceOfSpread(), new AttributesAirTransmissionModelDroplets().getAngleOfSpreadInDeg()); } + public AttributesDroplets(int id, double creationTime, double pathogenLoad, VPoint origin, Vector2D direction, double distanceOfSpread, double angleOfSpreadInDeg) { + super(id, creationTime, pathogenLoad, Droplets.createTransformedDropletsShape(origin, + direction, + distanceOfSpread, + angleOfSpreadInDeg)); + this.origin = origin; + this.direction = direction; + } + + public VPoint getOrigin() { + return origin; + } + + public Vector2D getDirection() { + return direction; + } - public AttributesDroplets(int id, VShape shape, double creationTime, double initialPathogenLoad) { - super(id, creationTime, initialPathogenLoad, shape); + public void setShape(VPoint origin, Vector2D direction, double distanceOfSpread, double angleOfSpreadInDeg) { + this.setShape(Droplets.createTransformedDropletsShape(origin, direction, distanceOfSpread, angleOfSpreadInDeg)); + this.origin = origin; + this.direction = direction; } } diff --git a/VadereState/src/org/vadere/state/scenario/Droplets.java b/VadereState/src/org/vadere/state/scenario/Droplets.java index b53af94ab..26890a990 100644 --- a/VadereState/src/org/vadere/state/scenario/Droplets.java +++ b/VadereState/src/org/vadere/state/scenario/Droplets.java @@ -47,6 +47,14 @@ public class Droplets extends ParticleDispersion { return attributes; } + public VPoint getOrigin() { + return attributes.getOrigin(); + } + + public Vector2D getDirection() { + return attributes.getDirection(); + } + public double getCreationTime() { return attributes.getCreationTime(); } // Setter @@ -95,9 +103,11 @@ public class Droplets extends ParticleDispersion { } else return attributes.equals(other.attributes); } - public static VShape createTransformedDropletsShape(VPoint origin, Vector2D direction, double radius, double centralAngleInRad) { + public static VShape createTransformedDropletsShape(VPoint origin, Vector2D direction, double radius, double centralAngleInDeg) { VPolygon shape; + double centralAngleInRad = Math.toRadians(centralAngleInDeg); + Path2D path = new Path2D.Double(); path.moveTo(0, 0); // define stating point for (double angle = 0.0; angle <= centralAngleInRad; angle += centralAngleInRad / numberOfCircularSections) { -- GitLab From 841424fb0d71d3846cdfcfa32f277eaa94b2ab30 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 15 Mar 2022 14:21:40 +0100 Subject: [PATCH 71/83] Add tests in AirTransmissionModelTest --- .../infection/AirTransmissionModelTest.java | 165 ++++++++++++++++-- 1 file changed, 149 insertions(+), 16 deletions(-) diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java index b09097c23..9419a98fc 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java @@ -5,16 +5,22 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.vadere.simulator.context.VadereContext; +import org.vadere.simulator.control.scenarioelements.TopographyController; +import org.vadere.simulator.models.MainModel; +import org.vadere.simulator.models.osm.OptimalStepsModel; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel; +import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.attributes.scenario.AttributesDroplets; +import org.vadere.state.attributes.scenario.AttributesSource; import org.vadere.state.health.AirTransmissionModelHealthStatus; -import org.vadere.state.scenario.AerosolCloud; -import org.vadere.state.scenario.Pedestrian; -import org.vadere.state.scenario.Topography; +import org.vadere.state.health.ExposureModelHealthStatus; +import org.vadere.state.scenario.*; import org.vadere.util.geometry.shapes.VPoint; +import org.vadere.util.geometry.shapes.VRectangle; import org.vadere.util.geometry.shapes.Vector2D; import java.util.ArrayList; @@ -23,7 +29,7 @@ import java.util.Random; import java.util.stream.Collectors; public class AirTransmissionModelTest { - private static final double ALLOWED_DOUBLE_TOLERANCE = 10e-3; + private static final double ALLOWED_DOUBLE_TOLERANCE = 10e-6; private static final double SIM_TIME_STEP_LENGTH = 0.4; List attributesList; @@ -64,9 +70,50 @@ public class AirTransmissionModelTest { Assert.assertEquals(ctx.get(AirTransmissionModel.simStepLength), airTransmissionModel.simTimeStepLength); } + @Test + public void testTopographyControllerEventDefinesInfectiousPedestrian() { + int pedestrianId = 1; + airTransmissionModel.attrAirTransmissionModel.addInfectiousPedestrianIdsNoSource(pedestrianId); + Agent agent = new Pedestrian(new AttributesAgent(pedestrianId), rdm); + + Pedestrian pedestrian = airTransmissionModel.topographyControllerEvent(getTopographyController(new OptimalStepsModel()), simStartTime, agent); + + Assert.assertTrue(pedestrian.isInfectious()); + } + + @Test + public void testTopographyControllerEventInstantiatesHealthStatus() { + int pedestrianId = 1; + airTransmissionModel.attrAirTransmissionModel.addInfectiousPedestrianIdsNoSource(pedestrianId); + Pedestrian pedestrian = new Pedestrian(new AttributesAgent(pedestrianId), rdm); + Pedestrian defaultPedestrian = pedestrian.clone(); + ExposureModelHealthStatus defaultHealthState = defaultPedestrian.getHealthStatus(); + + pedestrian = airTransmissionModel.topographyControllerEvent(getTopographyController(new OptimalStepsModel()), simStartTime, pedestrian); + ExposureModelHealthStatus instantiatedHealthStatus = pedestrian.getHealthStatus(); + + Assert.assertNotEquals(defaultHealthState, instantiatedHealthStatus); + Assert.assertSame(instantiatedHealthStatus.getClass(), AirTransmissionModelHealthStatus.class); + } + + private TopographyController getTopographyController(MainModel mainModel) { + return new TopographyController(new Domain(topography), mainModel, rdm); + } + @Test public void testRegisterToScenarioElementControllerEvents() { - // TODO ... + + int sourceId = 1; + Source source = new Source(new AttributesSource(sourceId, new VRectangle(1,1,1,1))); + topography.addSource(source); + + airTransmissionModel.attrAirTransmissionModel.getExposureModelSourceParameters().add(new AttributesExposureModelSourceParameters(sourceId, true)); + + double simEndTime = 100; + + for (double simTimeInSec = simStartTime; simTimeInSec < simEndTime; simTimeInSec += airTransmissionModel.simTimeStepLength) { + airTransmissionModel.update(simTimeInSec); + } } @Test @@ -208,17 +255,12 @@ public class AirTransmissionModelTest { airTransmissionModel.executeAerosolCloudEmissionEvents(simTimeInSec); // the tested method requires that the pedestrian's health status is updated as well - airTransmissionModel.updatePedsHealthStatus(simTimeInSec); + airTransmissionModel.updatePedestriansHealthStatus(simTimeInSec); } Assert.assertTrue(topography.getAerosolClouds().size()>0); } - @Test - public void testUpdateAerosolClouds() { - // maybe not necessary - } - @Test public void testUpdateAerosolCloudsPathogenLoad() { setAerosolCloudsActive(true); @@ -303,7 +345,6 @@ public class AirTransmissionModelTest { return airTransmissionModel.topography.getAerosolClouds().stream().findFirst().get().getRadius(); } - @Test public void testUpdateAerosolCloudsExtentAgentMovement() { createAerosolCloud(airTransmissionModel); @@ -353,7 +394,7 @@ public class AirTransmissionModelTest { for (double simTimeInSec = simStartTime; simTimeInSec < simEndTime; simTimeInSec += simTimeStepLength) { airTransmissionModel.updatePedestriansExposureToAerosolClouds(); - airTransmissionModel.updatePedsHealthStatus(simTimeInSec); + airTransmissionModel.updatePedestriansHealthStatus(simTimeInSec); } return pedestrian; @@ -375,21 +416,102 @@ public class AirTransmissionModelTest { @Test public void testExecuteDropletEmissionEvents() { + double simEndTime = airTransmissionModel.attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod() + 1 / airTransmissionModel.attrAirTransmissionModel.getDropletsEmissionFrequency(); + + airTransmissionModel.attrAirTransmissionModel.setDropletsLifeTime(simEndTime); + + Pedestrian pedestrian = createPedestrian(); + pedestrian.setId(1); + pedestrian.setInfectious(true); + VPoint position = new VPoint(1, 1); + pedestrian.setPosition(position); + topography.addElement(pedestrian); + + Vector2D walkingDirection = new Vector2D(Math.random(), Math.random()); + walkingDirection.normalize(AirTransmissionModel.MIN_PED_STEP_LENGTH); + + for (double simTimeInSec = simStartTime; simTimeInSec < simEndTime; simTimeInSec += airTransmissionModel.simTimeStepLength) { + position = position.add(walkingDirection); + pedestrian.setPosition(position); + airTransmissionModel.executeDropletEmissionEvents(simTimeInSec); + } + + Vector2D normDropletsDirection = topography.getDroplets().stream().findFirst().get().getDirection().normalize(1); + Vector2D normExpectedDirection = walkingDirection.normalize(1); + Assert.assertEquals(normExpectedDirection.x, normDropletsDirection.x, ALLOWED_DOUBLE_TOLERANCE); + Assert.assertEquals(normExpectedDirection.y, normDropletsDirection.y, ALLOWED_DOUBLE_TOLERANCE); } @Test - public void testUpdateDroplets() { + public void testDeleteExpiredDropletsBeforeLifeTimeReached() { + double lifeTime = 3; + double simTimeInSec = simStartTime + lifeTime * 0.9; // any value < simStartTime + lifeTime + initTestDeleteExpiredDroplets(lifeTime); + airTransmissionModel.deleteExpiredDroplets(simTimeInSec); + + Assert.assertTrue(topography.getDroplets().size() > 0); + } + + @Test + public void testDeleteExpiredDropletsAfterLifeTimeReached() { + double lifeTime = 3; + double simTimeInSec = simStartTime + lifeTime * 1.1; // any value > simStartTime + lifeTime + initTestDeleteExpiredDroplets(lifeTime); + + airTransmissionModel.deleteExpiredDroplets(simTimeInSec); + + Assert.assertTrue(topography.getDroplets().size() == 0); + } + + public void initTestDeleteExpiredDroplets(double lifeTime) { + setDropletsActive(true); + airTransmissionModel.attrAirTransmissionModel.setDropletsLifeTime(lifeTime); + createDroplets(airTransmissionModel); } @Test - public void testUpdatePedestriansExposureToDroplets() { + public void testUpdatePedestriansExposureWithinDroplets() { + Pedestrian pedestrian = testUpdatePedestriansExposureToDroplets(false); + Assert.assertTrue(pedestrian.getDegreeOfExposure() > 0); } @Test - public void testUpdatePedsHealthStatus() { + public void testUpdatePedestriansExposureOutsideDroplets() { + Pedestrian pedestrian = testUpdatePedestriansExposureToDroplets(true); + + Assert.assertTrue(pedestrian.getDegreeOfExposure() == 0); + } + + private Pedestrian testUpdatePedestriansExposureToDroplets(boolean pedestrianOutsideDroplets) { + createDroplets(airTransmissionModel); + Droplets droplets = airTransmissionModel.topography.getDroplets().stream().findFirst().get(); + Vector2D dropletsDirection = droplets.getDirection(); + VPoint dropletsOrigin = droplets.getOrigin(); + + double simTimeStepLength = airTransmissionModel.simTimeStepLength; + double simEndTime = 1 / airTransmissionModel.attrAirTransmissionModel.getDropletsEmissionFrequency() + 2 * airTransmissionModel.attrAirTransmissionModel.getPedestrianRespiratoryCyclePeriod(); + + Pedestrian pedestrian = createPedestrian(); + VPoint position = dropletsOrigin.add(dropletsDirection.normalize(airTransmissionModel.attrAirTransmissionModel.getDropletsDistanceOfSpread() * 0.5)); + if (pedestrianOutsideDroplets) { + position = dropletsOrigin.add(dropletsDirection.normalize(airTransmissionModel.attrAirTransmissionModel.getDropletsDistanceOfSpread() * 1.5)); + } + pedestrian.setPosition(position); + topography.addElement(pedestrian); + + for (double simTimeInSec = simStartTime; simTimeInSec < simEndTime; simTimeInSec += simTimeStepLength) { + airTransmissionModel.updatePedestriansExposureToDroplets(); + airTransmissionModel.updatePedestriansHealthStatus(simTimeInSec); + } + + return pedestrian; + } + + @Test + public void testUpdatePedestriansHealthStatus() { } @@ -412,6 +534,17 @@ public class AirTransmissionModelTest { airTransmissionModel.topography.addAerosolCloud(aerosolCloud); } + private void createDroplets(AirTransmissionModel airTransmissionModel) { + Droplets droplets = new Droplets(new AttributesDroplets(1, + simStartTime, + airTransmissionModel.attrAirTransmissionModel.getDropletsPathogenLoad(), + new VPoint(5, 5), + new Vector2D(1, 1), + airTransmissionModel.attrAirTransmissionModel.getDropletsDistanceOfSpread(), + airTransmissionModel.attrAirTransmissionModel.getDropletsAngleOfSpreadInDeg())); + airTransmissionModel.topography.addDroplets(droplets); + } + private void setAerosolCloudsActive(boolean active) { airTransmissionModel.attrAirTransmissionModel.setAerosolCloudsActive(active); } -- GitLab From 570fd8e715db9e51ecc00e77afac63ce64db2462 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 15 Mar 2022 15:57:05 +0100 Subject: [PATCH 72/83] Add ProximityExposureModelTest --- .../infection/ProximityExposureModel.java | 4 +- .../infection/ProximityExposureModelTest.java | 173 ++++++++++++++++++ 2 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 VadereSimulator/tests/org/vadere/simulator/models/infection/ProximityExposureModelTest.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java index 9467a5952..da119ded6 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ProximityExposureModel.java @@ -45,7 +45,7 @@ public class ProximityExposureModel extends AbstractExposureModel { /* * defines the maximum possible degree of exposure a pedestrian can adopt */ - private static final double MAX_DEG_OF_EXPOSURE = 1; + protected static final double MAX_DEG_OF_EXPOSURE = 1; Topography topography; @@ -97,7 +97,7 @@ public class ProximityExposureModel extends AbstractExposureModel { Collection exposedPedestrians = pedestrians .stream() - .filter(p -> (areaOfExposure.contains(p.getPosition())) && p.getDegreeOfExposure() < MAX_DEG_OF_EXPOSURE).collect(Collectors.toSet()); + .filter(p -> (areaOfExposure.contains(p.getPosition())) && p.getId() != infectiousPedestrian.getId()).collect(Collectors.toSet()); return exposedPedestrians; } diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/ProximityExposureModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/ProximityExposureModelTest.java new file mode 100644 index 000000000..d3251eda5 --- /dev/null +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/ProximityExposureModelTest.java @@ -0,0 +1,173 @@ +package org.vadere.simulator.models.infection; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.vadere.simulator.control.scenarioelements.TopographyController; +import org.vadere.simulator.models.MainModel; +import org.vadere.simulator.models.osm.OptimalStepsModel; +import org.vadere.simulator.projects.Domain; +import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.models.infection.AttributesProximityExposureModel; +import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.BasicExposureModelHealthStatus; +import org.vadere.state.health.ExposureModelHealthStatus; +import org.vadere.state.scenario.Agent; +import org.vadere.state.scenario.Pedestrian; +import org.vadere.state.scenario.Topography; +import org.vadere.util.geometry.shapes.VPoint; +import org.vadere.util.geometry.shapes.Vector2D; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class ProximityExposureModelTest { + private static final double ALLOWED_DOUBLE_TOLERANCE = 10e-6; + private List attributesList; + private ProximityExposureModel proximityExposureModel; + private Topography topography; + private Random rdm; + private double simStartTime; + + @Before + public void setUp() { + attributesList = new ArrayList<>(); + attributesList.add(new AttributesProximityExposureModel()); + proximityExposureModel = new ProximityExposureModel(); + topography = new Topography(); + rdm = new Random(0); + simStartTime = 0.0; + + proximityExposureModel.initialize(attributesList, new Domain(topography), null, rdm); + } + + @After + public void after() { + attributesList.clear(); + } + + //TODO test not complete yet +// public void testRegisterToScenarioElementControllerEvents() { +// int sourceId = 1; +// Source source = new Source(new AttributesSource(sourceId, new VRectangle(1, 1, 1, 1))); +// topography.addSource(source); +// +// proximityExposureModel.attributesProximityExposureModel +// .getExposureModelSourceParameters() +// .add(new AttributesExposureModelSourceParameters(sourceId, true)); +// +// Simulation controllerProvider = new Simulation(); +// +// proximityExposureModel.registerToScenarioElementControllerEvents(controllerProvider); +// } + + @Test + public void testInitialize() { + Assert.assertEquals(attributesList.get(0), proximityExposureModel.attributesProximityExposureModel); + } + + @Test + public void testUpdateNoInfectiousAgentsPresent() { + double expectedDegreeOfExposure = new BasicExposureModelHealthStatus().getDegreeOfExposure(); + double actualDegreeOfExposure = testUpdate(false); + + Assert.assertEquals(expectedDegreeOfExposure, actualDegreeOfExposure, ALLOWED_DOUBLE_TOLERANCE); + } + + @Test + public void testUpdateAgentWithinRangeOfInfectiousAgent() { + double expectedDegreeOfExposure = proximityExposureModel.MAX_DEG_OF_EXPOSURE; + double actualDegreeOfExposure = testUpdate(true); + + Assert.assertEquals(expectedDegreeOfExposure, actualDegreeOfExposure, ALLOWED_DOUBLE_TOLERANCE); + } + + public double testUpdate(boolean infectiousAgentPresent) { + double maxExposureRadius = proximityExposureModel.attributesProximityExposureModel.getExposureRadius(); + VPoint pos1 = new VPoint(1, 1); + Vector2D distance = new Vector2D(1, 0); + distance = distance.normalize(maxExposureRadius * 0.5); + VPoint pos2 = pos1.add(distance); + + int notInfectiousId = 2; + + createPedestrian(1, pos1, infectiousAgentPresent); + createPedestrian(notInfectiousId, pos2, false); + + proximityExposureModel.update(simStartTime); + + return topography.getPedestrianDynamicElements().getElement(notInfectiousId).getDegreeOfExposure(); + } + + @Test + public void testUpdatePedestrianDegreeOfExposure() { + Pedestrian pedestrian = createPedestrian(); + double expectedDegreeOfExposure = 1; + proximityExposureModel.updatePedestrianDegreeOfExposure(pedestrian, expectedDegreeOfExposure); + + Assert.assertEquals(expectedDegreeOfExposure, pedestrian.getDegreeOfExposure(), ALLOWED_DOUBLE_TOLERANCE); + } + + public void testSourceControllerEvent() { + } + + @Test + public void testTopographyControllerEventDefinesInfectiousPedestrian() { + int pedestrianId = 1; + proximityExposureModel.attributesProximityExposureModel.addInfectiousPedestrianIdsNoSource(pedestrianId); + Agent agent = new Pedestrian(new AttributesAgent(pedestrianId), rdm); + + Pedestrian pedestrian = proximityExposureModel.topographyControllerEvent(getTopographyController(new OptimalStepsModel()), simStartTime, agent); + + Assert.assertTrue(pedestrian.isInfectious()); + } + + @Test + public void testTopographyControllerEventInstantiatesHealthStatus() { + int pedestrianId = 1; + proximityExposureModel.attributesProximityExposureModel.addInfectiousPedestrianIdsNoSource(pedestrianId); + Pedestrian pedestrian = new Pedestrian(new AttributesAgent(pedestrianId), rdm); + Pedestrian defaultPedestrian = pedestrian.clone(); + ExposureModelHealthStatus defaultHealthState = defaultPedestrian.getHealthStatus(); + + pedestrian = proximityExposureModel.topographyControllerEvent(getTopographyController(new OptimalStepsModel()), simStartTime, pedestrian); + ExposureModelHealthStatus instantiatedHealthStatus = pedestrian.getHealthStatus(); + + Assert.assertNotEquals(defaultHealthState, instantiatedHealthStatus); + Assert.assertSame(instantiatedHealthStatus.getClass(), BasicExposureModelHealthStatus.class); + } + + private TopographyController getTopographyController(MainModel mainModel) { + return new TopographyController(new Domain(topography), mainModel, rdm); + } + + private Pedestrian createPedestrian() { + Pedestrian pedestrian = new Pedestrian(new AttributesAgent(), rdm); + pedestrian.setHealthStatus(new BasicExposureModelHealthStatus()); + return pedestrian; + } + + private void createPedestrian(int id, VPoint position, boolean infectious) { + Pedestrian pedestrian = createPedestrian(); + + pedestrian.setId(id); + + double maxExposureRadius = proximityExposureModel.attributesProximityExposureModel.getExposureRadius(); + VPoint pos1 = new VPoint(1, 1); + Vector2D distance = new Vector2D(Math.random(), Math.random()); + distance.normalize(maxExposureRadius * 0.5); + VPoint pos2 = pos1.add(distance); + + pedestrian.setPosition(position); + + if (infectious) { + pedestrian.setInfectious(true); + } else { + pedestrian.setInfectious(false); + } + + topography.addElement(pedestrian); + } +} \ No newline at end of file -- GitLab From a560cc270968c850878a67b36912179f24d86ff1 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 15 Mar 2022 15:57:17 +0100 Subject: [PATCH 73/83] Minor changes --- .../infection/AirTransmissionModelTest.java | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java index 9419a98fc..8a0815b5e 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/AirTransmissionModelTest.java @@ -11,16 +11,13 @@ import org.vadere.simulator.models.osm.OptimalStepsModel; import org.vadere.simulator.projects.Domain; import org.vadere.state.attributes.Attributes; import org.vadere.state.attributes.models.infection.AttributesAirTransmissionModel; -import org.vadere.state.attributes.models.infection.AttributesExposureModelSourceParameters; import org.vadere.state.attributes.scenario.AttributesAerosolCloud; import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesDroplets; -import org.vadere.state.attributes.scenario.AttributesSource; import org.vadere.state.health.AirTransmissionModelHealthStatus; import org.vadere.state.health.ExposureModelHealthStatus; import org.vadere.state.scenario.*; import org.vadere.util.geometry.shapes.VPoint; -import org.vadere.util.geometry.shapes.VRectangle; import org.vadere.util.geometry.shapes.Vector2D; import java.util.ArrayList; @@ -70,6 +67,25 @@ public class AirTransmissionModelTest { Assert.assertEquals(ctx.get(AirTransmissionModel.simStepLength), airTransmissionModel.simTimeStepLength); } + // TODO test not completed yet +// @Test +// public void testSourceControllerEvent() { +// int pedestrianId = 1; +// int sourceId = 1; +// Source source = new Source(new AttributesSource(sourceId, new VRectangle(1, 1, 1, 1))); +// topography.addSource(source); +// +// MainModel mainModel = new OptimalStepsModel(); +// SourceControllerFactory sourceControllerFactory = mainModel.getSourceControllerFactory(); +// SourceController sourceController = sourceControllerFactory +// .create(topography, source, mainModel, new AttributesAgent(pedestrianId), rdm); +// +// double simTimeInSec = simStartTime; +// Agent agent = new Pedestrian(new AttributesAgent(), rdm); +// +// airTransmissionModel.sourceControllerEvent(sourceController, simTimeInSec, agent); +// } + @Test public void testTopographyControllerEventDefinesInfectiousPedestrian() { int pedestrianId = 1; @@ -100,21 +116,22 @@ public class AirTransmissionModelTest { return new TopographyController(new Domain(topography), mainModel, rdm); } - @Test - public void testRegisterToScenarioElementControllerEvents() { - - int sourceId = 1; - Source source = new Source(new AttributesSource(sourceId, new VRectangle(1,1,1,1))); - topography.addSource(source); - - airTransmissionModel.attrAirTransmissionModel.getExposureModelSourceParameters().add(new AttributesExposureModelSourceParameters(sourceId, true)); - - double simEndTime = 100; - - for (double simTimeInSec = simStartTime; simTimeInSec < simEndTime; simTimeInSec += airTransmissionModel.simTimeStepLength) { - airTransmissionModel.update(simTimeInSec); - } - } +// TODO test not completed yet +// @Test +// public void testRegisterToScenarioElementControllerEvents() { +// +// int sourceId = 1; +// Source source = new Source(new AttributesSource(sourceId, new VRectangle(1,1,1,1))); +// topography.addSource(source); +// +// airTransmissionModel.attrAirTransmissionModel.getExposureModelSourceParameters().add(new AttributesExposureModelSourceParameters(sourceId, true)); +// +// double simEndTime = 100; +// +// for (double simTimeInSec = simStartTime; simTimeInSec < simEndTime; simTimeInSec += airTransmissionModel.simTimeStepLength) { +// airTransmissionModel.update(simTimeInSec); +// } +// } @Test public void testUpdateCreatesAerosolCloudsAlthoughNotActive() { @@ -225,7 +242,7 @@ public class AirTransmissionModelTest { double distance = 0.5 * Math.min(airTransmissionModel.attrAirTransmissionModel.getAerosolCloudInitialRadius(), airTransmissionModel.attrAirTransmissionModel.getDropletsDistanceOfSpread()); Vector2D spacingBetweenPeds = new Vector2D(1, 1); - spacingBetweenPeds.normalize(distance); + spacingBetweenPeds = spacingBetweenPeds.normalize(distance); Pedestrian pedestrian2 = createPedestrian(); VPoint pos2 = pos1.add(spacingBetweenPeds); @@ -428,7 +445,7 @@ public class AirTransmissionModelTest { topography.addElement(pedestrian); Vector2D walkingDirection = new Vector2D(Math.random(), Math.random()); - walkingDirection.normalize(AirTransmissionModel.MIN_PED_STEP_LENGTH); + walkingDirection = walkingDirection.normalize(AirTransmissionModel.MIN_PED_STEP_LENGTH); for (double simTimeInSec = simStartTime; simTimeInSec < simEndTime; simTimeInSec += airTransmissionModel.simTimeStepLength) { position = position.add(walkingDirection); -- GitLab From ace7afcb64534ca73320c1c95af545c468d29c87 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 15 Mar 2022 17:08:03 +0100 Subject: [PATCH 74/83] Add ThresholdResponseModelTest --- .../infection/ThresholdResponseModel.java | 2 +- .../infection/ThresholdResponseModelTest.java | 124 ++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 VadereSimulator/tests/org/vadere/simulator/models/infection/ThresholdResponseModelTest.java diff --git a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java index 0f3c22be8..4ba2ebddb 100644 --- a/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java +++ b/VadereSimulator/src/org/vadere/simulator/models/infection/ThresholdResponseModel.java @@ -41,7 +41,7 @@ public class ThresholdResponseModel extends AbstractDoseResponseModel { Topography topography; - private AttributesThresholdResponseModel attributesThresholdResponseModel; + protected AttributesThresholdResponseModel attributesThresholdResponseModel; @Override diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/ThresholdResponseModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/ThresholdResponseModelTest.java new file mode 100644 index 000000000..df37bd539 --- /dev/null +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/ThresholdResponseModelTest.java @@ -0,0 +1,124 @@ +package org.vadere.simulator.models.infection; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.vadere.simulator.control.scenarioelements.TopographyController; +import org.vadere.simulator.models.osm.OptimalStepsModel; +import org.vadere.simulator.projects.Domain; +import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.models.infection.AttributesProximityExposureModel; +import org.vadere.state.attributes.models.infection.AttributesThresholdResponseModel; +import org.vadere.state.attributes.scenario.AttributesAgent; +import org.vadere.state.health.BasicExposureModelHealthStatus; +import org.vadere.state.health.DoseResponseModelInfectionStatus; +import org.vadere.state.health.ThresholdResponseModelInfectionStatus; +import org.vadere.state.scenario.Pedestrian; +import org.vadere.state.scenario.Topography; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class ThresholdResponseModelTest { + private List attributesList; + private ThresholdResponseModel thresholdResponseModel; + private Topography topography; + private Random rdm; + private double simStartTime; + + @Before + public void setUp() { + attributesList = new ArrayList<>(); + attributesList.add(new AttributesProximityExposureModel()); // alternatively use any other class extending AbstractExposureModel + attributesList.add(new AttributesThresholdResponseModel()); + thresholdResponseModel = new ThresholdResponseModel(); + topography = new Topography(); + rdm = new Random(0); + simStartTime = 0.0; + + thresholdResponseModel.initialize(attributesList, new Domain(topography), null, rdm); + } + + @After + public void tearDown(){ + attributesList.clear(); + } + + @Test + public void registerToScenarioElementControllerEvents() { + } + + @Test(expected = RuntimeException.class) + public void testInitializeThrowsErrorIfNoExposureModelDefined() { + attributesList.clear(); + attributesList = new ArrayList<>(); + attributesList.add(new AttributesThresholdResponseModel()); + + thresholdResponseModel.initialize(attributesList, new Domain(topography), null, rdm); + } + + @Test + public void testInitializeFindsAttributes() { + Assert.assertTrue(attributesList.contains(thresholdResponseModel.attributesThresholdResponseModel)); + } + + @Test + public void testRegisterToScenarioElementControllerEvents() { + } + + @Test + public void sourceControllerEvent() { + } + + @Test + public void testUpdateMinProbabilityOfInfection() { + double probabilityOfInfection = testUpdate(0.9); + + Assert.assertEquals(0, probabilityOfInfection, 0.0); + } + + @Test + public void testUpdateMaxProbabilityOfInfection() { + double probabilityOfInfection = testUpdate(1); // argument >= 1 + + Assert.assertEquals(1, probabilityOfInfection, 0.0); + } + + private double testUpdate(double percentageOfInfectionThreshold) { + int pedId = 1; + double exposureBelowThreshold = thresholdResponseModel.attributesThresholdResponseModel.getExposureToInfectedThreshold() * percentageOfInfectionThreshold; + createPedestrian(pedId, exposureBelowThreshold); + + thresholdResponseModel.update(simStartTime); + + return topography.getPedestrianDynamicElements().getElement(pedId).getProbabilityOfInfection(); + } + + @Test + public void topographyControllerEventDefinesInfectionStatus() { + Pedestrian pedestrian = new Pedestrian(new AttributesAgent(), rdm); + Pedestrian defaultPedestrian = pedestrian.clone(); + DoseResponseModelInfectionStatus defaultInfectionStatus = defaultPedestrian.getInfectionStatus(); + + TopographyController controller = new TopographyController(new Domain(topography), new OptimalStepsModel(), rdm); + + pedestrian = thresholdResponseModel.topographyControllerEvent(controller, simStartTime, pedestrian); + DoseResponseModelInfectionStatus instantiatedInfectionStatus = pedestrian.getInfectionStatus(); + + Assert.assertNotEquals(defaultInfectionStatus, instantiatedInfectionStatus); + Assert.assertSame(instantiatedInfectionStatus.getClass(), ThresholdResponseModelInfectionStatus.class); + } + + private void createPedestrian(int id, double degreeOfExposure) { + Pedestrian pedestrian = new Pedestrian(new AttributesAgent(id), rdm); + + pedestrian.setHealthStatus(new BasicExposureModelHealthStatus()); + pedestrian.setDegreeOfExposure(degreeOfExposure); + + pedestrian.setInfectionStatus(new ThresholdResponseModelInfectionStatus()); + + topography.addElement(pedestrian); + } +} \ No newline at end of file -- GitLab From 18aac2d825cb6ffa6dfcb437cba4204aae0c2746 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Tue, 15 Mar 2022 17:08:44 +0100 Subject: [PATCH 75/83] Minor changes --- .../models/infection/ProximityExposureModelTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VadereSimulator/tests/org/vadere/simulator/models/infection/ProximityExposureModelTest.java b/VadereSimulator/tests/org/vadere/simulator/models/infection/ProximityExposureModelTest.java index d3251eda5..64175137d 100644 --- a/VadereSimulator/tests/org/vadere/simulator/models/infection/ProximityExposureModelTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/models/infection/ProximityExposureModelTest.java @@ -130,12 +130,12 @@ public class ProximityExposureModelTest { proximityExposureModel.attributesProximityExposureModel.addInfectiousPedestrianIdsNoSource(pedestrianId); Pedestrian pedestrian = new Pedestrian(new AttributesAgent(pedestrianId), rdm); Pedestrian defaultPedestrian = pedestrian.clone(); - ExposureModelHealthStatus defaultHealthState = defaultPedestrian.getHealthStatus(); + ExposureModelHealthStatus defaultHealthStatus = defaultPedestrian.getHealthStatus(); pedestrian = proximityExposureModel.topographyControllerEvent(getTopographyController(new OptimalStepsModel()), simStartTime, pedestrian); ExposureModelHealthStatus instantiatedHealthStatus = pedestrian.getHealthStatus(); - Assert.assertNotEquals(defaultHealthState, instantiatedHealthStatus); + Assert.assertNotEquals(defaultHealthStatus, instantiatedHealthStatus); Assert.assertSame(instantiatedHealthStatus.getClass(), BasicExposureModelHealthStatus.class); } -- GitLab From 7e5e6b9889d6cd311bb8122069933b980053f350 Mon Sep 17 00:00:00 2001 From: Simon Rahn Date: Fri, 18 Mar 2022 12:33:03 +0100 Subject: [PATCH 76/83] Refactoring Rename AttributesAerosolCloudShapeProcessor to AttributesAerosolCloudDataProcessor --- .../examples/scenarios/bottleneckA.scenario | 2 +- .../examples/scenarios/bottleneckB.scenario | 2 +- .../scenarios/bottleneckB_socialDistancing.scenario | 2 +- .../examples/scenarios/closeContact.scenario | 2 +- .../examples/scenarios/passageway.scenario | 2 +- .../AirTransmissionModel/examples/scenarios/queue.scenario | 2 +- .../scenarios/hamner-2020-life_postvis_template.scenario | 2 +- .../dataprocessing/processor/AerosolCloudDataProcessor.java | 6 +++--- ...cessor.java => AttributesAerosolCloudDataProcessor.java} | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) rename VadereState/src/org/vadere/state/attributes/processor/{AttributesAerosolCloudShapeProcessor.java => AttributesAerosolCloudDataProcessor.java} (68%) diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario index f435cc9a1..fd3a9ddf0 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckA.scenario @@ -43,7 +43,7 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 6, - "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudDataProcessor", "attributes" : { "sampleEveryNthSimStep" : 1 } diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario index 966882c52..88016957b 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB.scenario @@ -68,7 +68,7 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 9, - "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudDataProcessor", "attributes" : { "sampleEveryNthSimStep" : 1 } diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario index 2e72b0fb1..68dce79d3 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/bottleneckB_socialDistancing.scenario @@ -68,7 +68,7 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 9, - "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudDataProcessor", "attributes" : { "sampleEveryNthSimStep" : 1 } diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario index c059a1f11..ac670c8c4 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/closeContact.scenario @@ -62,7 +62,7 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 8, - "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudDataProcessor", "attributes" : { "sampleEveryNthSimStep" : 1 } diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario index 801f8e859..abce04aa6 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/passageway.scenario @@ -43,7 +43,7 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 6, - "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudDataProcessor", "attributes" : { "sampleEveryNthSimStep" : 1 } diff --git a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario index 3289b394b..7843e41e9 100644 --- a/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario +++ b/Scenarios/Demos/AirTransmissionModel/examples/scenarios/queue.scenario @@ -80,7 +80,7 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 12, - "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudDataProcessor", "attributes" : { "sampleEveryNthSimStep" : 1 } diff --git a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario index 653270a74..6fb10a693 100644 --- a/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario +++ b/Scenarios/Demos/AirTransmissionModel/validation/scenarios/hamner-2020-life_postvis_template.scenario @@ -43,7 +43,7 @@ }, { "type" : "org.vadere.simulator.projects.dataprocessing.processor.AerosolCloudDataProcessor", "id" : 7, - "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor", + "attributesType" : "org.vadere.state.attributes.processor.AttributesAerosolCloudDataProcessor", "attributes" : { "sampleEveryNthSimStep" : 100 } diff --git a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java index 8754a6d5f..98cb79302 100644 --- a/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java +++ b/VadereSimulator/src/org/vadere/simulator/projects/dataprocessing/processor/AerosolCloudDataProcessor.java @@ -4,7 +4,7 @@ import org.vadere.annotation.factories.dataprocessors.DataProcessorClass; import org.vadere.simulator.control.simulation.SimulationState; import org.vadere.simulator.projects.dataprocessing.ProcessorManager; import org.vadere.simulator.projects.dataprocessing.datakey.TimestepIdDataKey; -import org.vadere.state.attributes.processor.AttributesAerosolCloudShapeProcessor; +import org.vadere.state.attributes.processor.AttributesAerosolCloudDataProcessor; import org.vadere.state.scenario.AerosolCloud; import java.util.Collection; @@ -29,7 +29,7 @@ public class AerosolCloudDataProcessor extends DataProcessor