From a1000eb3ec09c1725af2eb66435d87ae1260098c Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Sat, 17 Apr 2021 22:10:19 +0200 Subject: [PATCH 1/7] First steps towards making the form reponsive to screensize. --- .../templates/calculator.form.html.j2 | 91 ++++++++++++++----- 1 file changed, 67 insertions(+), 24 deletions(-) diff --git a/cara/apps/calculator/templates/calculator.form.html.j2 b/cara/apps/calculator/templates/calculator.form.html.j2 index 063a1c46..14df152e 100644 --- a/cara/apps/calculator/templates/calculator.form.html.j2 +++ b/cara/apps/calculator/templates/calculator.form.html.j2 @@ -26,7 +26,7 @@ v{{ calculator_version }} Please sen {% if DEBUG %} -
+ {% else %} {% endif %} @@ -34,37 +34,67 @@ v{{ calculator_version }} Please sen -
+
+
+
- Simulation name:
- Room number:
-
+
+ + +
+ +
+ + +
+ +
Virus data: +
?

- Variant: -
+ +
+ + +
+
Room data:
?

- -    -
- -    -
-          -
+
+ +
+ + +
+ +
+ +
+
+ +    +
+ +
+
+
+          +
+ +
+
@@ -134,15 +164,24 @@ v{{ calculator_version }} Please sen
-
+
Event data:
?

- Total number of occupants:
- Number of infected people:
+ +
+ + +
+ +
+ +
+
+
@@ -265,9 +304,11 @@ v{{ calculator_version }} Please sen
Coffee breaks are spread evenly throughout the day.

+ +
-
+
Quick Guide:
This tool simulates the long range airborne spread SARS-CoV-2 virus in a finite volume and estimates the risk of COVID-19 infection. It is based on current scientific data and can be used to compare the effectiveness of different mitigation measures.
@@ -315,7 +356,9 @@ v{{ calculator_version }} Please sen for more detailed explanations on how to use this tool.
-



+
+
+



From ea5ca699f87041172a87d500492bf31697dd3b21 Mon Sep 17 00:00:00 2001 From: James Devine Date: Thu, 6 May 2021 18:09:00 +0000 Subject: [PATCH 2/7] Update README.md with link to climatology tools repo --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 0967912a..c5b172b4 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,13 @@ CARA has not undergone review, approval or certification by competent authoritie The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and non-infringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software. +## Adapting CARA to your location + +The default weather data (hourly outdoor temperature) used in CARA is for Geneva, Switzerland. +In order for the natural ventilation option to work correctly for other geographic locations, the outdoor temperatures must be updated. +There are some scripts to help download and process the temperature data from your nearest weather station in the https://gitlab.cern.ch/cara/climatology-data repository. +Once you have used the scripts, the hourly temperature data for your location should be added to the file `data.py` in place of the default values for Geneva. +CARA currently supports only one geographic location for weather data per instance. ## Running CARA locally From 9d89ba725e8411e2d8e7c4587a57188ccb917503 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Mon, 10 May 2021 07:21:42 +0200 Subject: [PATCH 3/7] Spacing between the generate button and the userguide. --- cara/apps/calculator/templates/calculator.form.html.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/cara/apps/calculator/templates/calculator.form.html.j2 b/cara/apps/calculator/templates/calculator.form.html.j2 index 14df152e..b4b4c62e 100644 --- a/cara/apps/calculator/templates/calculator.form.html.j2 +++ b/cara/apps/calculator/templates/calculator.form.html.j2 @@ -306,6 +306,7 @@ v{{ calculator_version }} Please sen
+

From d082156d46b62134b1d9c371c0fcf4e63c7aa269 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Wed, 12 May 2021 20:08:38 +0200 Subject: [PATCH 4/7] Follow-up from Andre's review. --- .../apps/calculator/templates/calculator.form.html.j2 | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cara/apps/calculator/templates/calculator.form.html.j2 b/cara/apps/calculator/templates/calculator.form.html.j2 index b4b4c62e..254ea53c 100644 --- a/cara/apps/calculator/templates/calculator.form.html.j2 +++ b/cara/apps/calculator/templates/calculator.form.html.j2 @@ -174,12 +174,12 @@ v{{ calculator_version }} Please sen
- +
-
+
@@ -304,8 +304,11 @@ v{{ calculator_version }} Please sen
Coffee breaks are spread evenly throughout the day.

- - +
+
+ +
+


From 57c7c78117ff96f85564f1062418af1197ea16f1 Mon Sep 17 00:00:00 2001 From: Nicolas Mounet Date: Fri, 14 May 2021 12:38:35 +0200 Subject: [PATCH 5/7] caching _generate_activity_distribution (for Activity models) --- cara/models.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/cara/models.py b/cara/models.py index 1fa3fbe7..9b1185ad 100644 --- a/cara/models.py +++ b/cara/models.py @@ -557,27 +557,29 @@ Activity.types = { 'Heavy exercise': Activity(3.30, 3.30), } -def _generate_activity_distribution(csi: float, lamb: float, samples: int): +@cached +def _generate_activity_distribution(params: typing.Tuple[float, float, int]) -> Activity: + csi, lamb, samples = params return Activity( _lognormal_distribution(csi, lamb, samples), _lognormal_distribution(csi, lamb, samples), ) Activity.distributions = { - 'Seated': lambda n: _generate_activity_distribution( - 0.10498338229297108, -0.6872121723362303, n), + 'Seated': lambda n: _generate_activity_distribution(( + 0.10498338229297108, -0.6872121723362303, n)), - 'Standing': lambda n: _generate_activity_distribution( - 0.09373162411398223, -0.5742377578494785, n), + 'Standing': lambda n: _generate_activity_distribution(( + 0.09373162411398223, -0.5742377578494785, n)), - 'Light activity': lambda n: _generate_activity_distribution( - 0.09435378091059601, 0.21380242785625422, n), + 'Light activity': lambda n: _generate_activity_distribution(( + 0.09435378091059601, 0.21380242785625422, n)), - 'Moderate activity': lambda n: _generate_activity_distribution( - 0.1894616357138137, 0.551771330362601, n), + 'Moderate activity': lambda n: _generate_activity_distribution(( + 0.1894616357138137, 0.551771330362601, n)), - 'Heavy exercise': lambda n: _generate_activity_distribution( - 0.21744554768657565, 1.1644665696723049, n), + 'Heavy exercise': lambda n: _generate_activity_distribution(( + 0.21744554768657565, 1.1644665696723049, n)), } From 0d71a5a46d6d4ee8c762f3018ee04c195ff92b05 Mon Sep 17 00:00:00 2001 From: James Devine Date: Mon, 17 May 2021 15:13:14 +0000 Subject: [PATCH 6/7] Added comments from MR!175, resolves thread. --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c5b172b4..f0653b89 100644 --- a/README.md +++ b/README.md @@ -60,11 +60,17 @@ In no event shall the authors or copyright holders be liable for any claim, dama ## Adapting CARA to your location -The default weather data (hourly outdoor temperature) used in CARA is for Geneva, Switzerland. +The default weather data (average hourly outdoor temperature in Celcius for each month of the year) used in CARA is for Geneva, Switzerland. In order for the natural ventilation option to work correctly for other geographic locations, the outdoor temperatures must be updated. There are some scripts to help download and process the temperature data from your nearest weather station in the https://gitlab.cern.ch/cara/climatology-data repository. -Once you have used the scripts, the hourly temperature data for your location should be added to the file `data.py` in place of the default values for Geneva. -CARA currently supports only one geographic location for weather data per instance. +Once you have used the scripts, the hourly temperature data for your location should be added to the file `data.py` in place of the default values for Geneva. The temperature values for your locations should be pasted into the `Geneva_hourly_temperatures_celsius_per_hour` variable, **without changing the variable name** in the following format: + + `'Jan': [0.2, -0.3, -0.5, -0.9, -1.1, -1.4, -1.5, -1.5, -1.1, 0.1, 1.5, + 2.8, 3.8, 4.4, 4.5, 4.4, 4.4, 3.9, 3.1, 2.7, 2.2, 1.7, 1.5, 1.1], + 'Feb': [0.9, 0.3, 0.0, -0.5, -0.7, -1.1, -1.2, -1.1, -0.7, 0.8, 2.5, + 4.2, 5.4, 6.2, 6.3, 6.2, 6.1, 5.5, 4.5, 4.1, 3.5, 2.8, 2.5, 2.0],...` + +CARA currently supports **only one geographic location for weather data per instance**. ## Running CARA locally From d76e7a98d50846038d7cff72264f9a2b00a0f05f Mon Sep 17 00:00:00 2001 From: Nicolas Mounet Date: Fri, 21 May 2021 11:03:53 +0200 Subject: [PATCH 7/7] Removing pre-defined distributions for Activity --- cara/models.py | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/cara/models.py b/cara/models.py index 9b1185ad..291dcfc1 100644 --- a/cara/models.py +++ b/cara/models.py @@ -37,7 +37,6 @@ import typing import numpy as np from scipy.interpolate import interp1d -import scipy.stats as sct if not typing.TYPE_CHECKING: from memoization import cached @@ -56,18 +55,6 @@ _VectorisedFloat = typing.Union[float, np.ndarray] _VectorisedInt = typing.Union[int, np.ndarray] -def _lognormal_distribution(csi: float, lamb: float, samples: int) -> np.ndarray: - """ - Generates a number of samples from a specified lognormal distribution - :param csi: parameter used to specify the lognormal distribution - :param lamb: parameter used to specify the lognormal distribution - :param samples: number of samples to be generated - :return: numpy-array containing the samples - """ - sf_norm = sct.norm.sf(np.random.normal(size=samples)) - return sct.lognorm.isf(sf_norm, csi, loc=0, scale=np.exp(lamb)) - - @dataclass(frozen=True) class Room: #: The total volume of the room @@ -545,9 +532,6 @@ class Activity: #: Pre-populated examples of activities. types: typing.ClassVar[typing.Dict[str, "Activity"]] - #: Pre-defined examples of activity distributions. - distributions: typing.ClassVar[typing.Dict[str, typing.Callable[[int], "Activity"]]] - Activity.types = { 'Seated': Activity(0.51, 0.51), @@ -557,31 +541,6 @@ Activity.types = { 'Heavy exercise': Activity(3.30, 3.30), } -@cached -def _generate_activity_distribution(params: typing.Tuple[float, float, int]) -> Activity: - csi, lamb, samples = params - return Activity( - _lognormal_distribution(csi, lamb, samples), - _lognormal_distribution(csi, lamb, samples), - ) - -Activity.distributions = { - 'Seated': lambda n: _generate_activity_distribution(( - 0.10498338229297108, -0.6872121723362303, n)), - - 'Standing': lambda n: _generate_activity_distribution(( - 0.09373162411398223, -0.5742377578494785, n)), - - 'Light activity': lambda n: _generate_activity_distribution(( - 0.09435378091059601, 0.21380242785625422, n)), - - 'Moderate activity': lambda n: _generate_activity_distribution(( - 0.1894616357138137, 0.551771330362601, n)), - - 'Heavy exercise': lambda n: _generate_activity_distribution(( - 0.21744554768657565, 1.1644665696723049, n)), -} - @dataclass(frozen=True) class Population: