diff --git a/README.md b/README.md index 0967912a..f0653b89 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,19 @@ 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 (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. 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 diff --git a/cara/apps/calculator/templates/calculator.form.html.j2 b/cara/apps/calculator/templates/calculator.form.html.j2 index 063a1c46..254ea53c 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,15 @@ 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 +360,9 @@ v{{ calculator_version }} Please sen for more detailed explanations on how to use this tool.
-



+
+
+



diff --git a/cara/models.py b/cara/models.py index 5d5b7693..a55cb9d3 100644 --- a/cara/models.py +++ b/cara/models.py @@ -37,9 +37,6 @@ import typing import numpy as np from scipy.interpolate import interp1d -import scipy.stats as sct -from sklearn.neighbors import KernelDensity # type: ignore - if not typing.TYPE_CHECKING: from memoization import cached @@ -58,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 @@ -584,9 +569,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), @@ -596,29 +578,6 @@ Activity.types = { 'Heavy exercise': Activity(3.30, 3.30), } -def _generate_activity_distribution(csi: float, lamb: float, samples: int): - 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: