generate initial CO2 plot
This commit is contained in:
parent
2faeabf05c
commit
e75846a3b2
5 changed files with 35 additions and 40 deletions
|
|
@ -325,11 +325,8 @@ class FormData:
|
|||
humidity = float(self.humidity)
|
||||
inside_temp = self.inside_temp
|
||||
|
||||
return models.Room(volume=volume, inside_temp=models.PiecewiseConstant((0, 24), (inside_temp,)), humidity=humidity)
|
||||
|
||||
def build_mc_model(self) -> mc.ExposureModel:
|
||||
room = self.initialize_room()
|
||||
|
||||
room = models.Room(volume=volume, inside_temp=models.PiecewiseConstant((0, 24), (inside_temp,)), humidity=humidity)
|
||||
ventilation: models._VentilationBase = self.ventilation()
|
||||
infected_population = self.infected_population()
|
||||
|
||||
short_range = []
|
||||
|
|
@ -342,11 +339,10 @@ class FormData:
|
|||
distance=short_range_distances,
|
||||
))
|
||||
|
||||
# Initializes and returns a model with the attributes defined above
|
||||
return mc.ExposureModel(
|
||||
concentration_model=mc.ConcentrationModel(
|
||||
room=room,
|
||||
ventilation=self.ventilation(),
|
||||
ventilation=ventilation,
|
||||
infected=infected_population,
|
||||
evaporation_factor=0.3,
|
||||
),
|
||||
|
|
@ -357,6 +353,14 @@ class FormData:
|
|||
geographic_cases=self.geographic_cases,
|
||||
ascertainment_bias=CONFIDENCE_LEVEL_OPTIONS[self.ascertainment_bias],
|
||||
),
|
||||
CO2_profile=models.CO2Data(
|
||||
room_volume=self.room_volume,
|
||||
number=self.total_people,
|
||||
presence=self.population_present_interval(),
|
||||
ventilation_transition_times=tuple(ventilation.transition_times(room=room)),
|
||||
times=self.CO2_data['times'],
|
||||
CO2_concentrations=self.CO2_data['CO2']
|
||||
) if self.CO2_data_option else (),
|
||||
)
|
||||
|
||||
def build_model(self, sample_size=DEFAULT_MC_SAMPLE_SIZE) -> models.ExposureModel:
|
||||
|
|
@ -754,6 +758,12 @@ class FormData:
|
|||
self.infected_start, self.infected_finish,
|
||||
breaks=breaks,
|
||||
)
|
||||
|
||||
def population_present_interval(self) -> models.Interval:
|
||||
state_change_times = set(self.infected_present_interval().transition_times())
|
||||
state_change_times.update(self.exposed_present_interval().transition_times())
|
||||
all_state_changes = sorted(state_change_times)
|
||||
return models.SpecificInterval(tuple(zip(all_state_changes[:-1], all_state_changes[1:])))
|
||||
|
||||
def short_range_interval(self, interaction) -> models.SpecificInterval:
|
||||
start_time = time_string_to_minutes(interaction['start_time'])
|
||||
|
|
|
|||
|
|
@ -150,6 +150,11 @@ def calculate_report_data(form: FormData, model: models.ExposureModel) -> typing
|
|||
zip(('viral_loads', 'pi_means', 'lower_percentiles', 'upper_percentiles'),
|
||||
manufacture_conditional_probability_data(model, prob))}
|
||||
|
||||
CO2_times = list(form.CO2_data['times']) if form.CO2_data_option else []
|
||||
CO2_values = list(form.CO2_data['CO2']) if form.CO2_data_option else []
|
||||
ex, airs = model.CO2_profile.CO2_fit_params()
|
||||
co2_plot = img2base64(_figure2bytes(CO2_plot(CO2_times, CO2_values))) if form.CO2_data_option else None
|
||||
|
||||
return {
|
||||
"model_repr": repr(model),
|
||||
"times": list(times),
|
||||
|
|
|
|||
|
|
@ -181,6 +181,9 @@
|
|||
let short_range_expirations = {{ short_range_expirations | JSONify }};
|
||||
draw_plot("concentration_plot");
|
||||
</script>
|
||||
<img src= "{{ CO2_plot }}" />
|
||||
<p>Emission rate = {{ ex }}</p>
|
||||
<p>Ventilation = {{ airs }}</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1584,6 +1584,9 @@ class ExposureModel:
|
|||
c_model.ventilation.air_exchange(c_model.room, time)) for time in c_model.state_change_times()))):
|
||||
raise ValueError("If the diameter is an array, none of the ventilation parameters "
|
||||
"or virus decay constant can be arrays at the same time.")
|
||||
if not isinstance(self.exposed.number, int):
|
||||
raise NotImplementedError("Cannot use dynamic occupancy for"
|
||||
" the exposed population")
|
||||
|
||||
@method_cache
|
||||
def population_state_change_times(self) -> typing.List[float]:
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ def full_exposure_model():
|
|||
short_range=(),
|
||||
exposed=models.Population(
|
||||
number=10,
|
||||
presence=models.SpecificInterval(((8, 12), (13, 17), )),
|
||||
presence=models.SpecificInterval(((8, 12), (13, 17), )),
|
||||
mask=models.Mask.types['No mask'],
|
||||
activity=models.Activity.types['Seated'],
|
||||
host_immunity=0.
|
||||
|
|
@ -51,37 +51,11 @@ def baseline_infected_population_number():
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def baseline_exposed_population_number():
|
||||
return models.Population(
|
||||
number=models.IntPiecewiseConstant(
|
||||
(8, 12, 13, 17), (10, 0, 10)),
|
||||
presence=None,
|
||||
mask=models.Mask.types['No mask'],
|
||||
activity=models.Activity.types['Seated'],
|
||||
host_immunity=0.,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def dynamic_infected_single_exposure_model(full_exposure_model, baseline_infected_population_number):
|
||||
def dynamic_single_exposure_model(full_exposure_model, baseline_infected_population_number):
|
||||
return dc_utils.nested_replace(full_exposure_model,
|
||||
{'concentration_model.infected': baseline_infected_population_number, })
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def dynamic_exposed_single_exposure_model(full_exposure_model, baseline_exposed_population_number):
|
||||
return dc_utils.nested_replace(full_exposure_model,
|
||||
{'exposed': baseline_exposed_population_number, })
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def dynamic_population_exposure_model(full_exposure_model, baseline_infected_population_number ,baseline_exposed_population_number):
|
||||
return dc_utils.nested_replace(full_exposure_model, {
|
||||
'concentration_model.infected': baseline_infected_population_number,
|
||||
'exposed': baseline_exposed_population_number,
|
||||
})
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"time",
|
||||
[4., 8., 10., 12., 13., 14., 16., 20., 24.],
|
||||
|
|
@ -117,16 +91,16 @@ def test_population_number(full_exposure_model: models.ExposureModel,
|
|||
[4., 8., 10., 12., 13., 14., 16., 20., 24.],
|
||||
)
|
||||
def test_concentration_model_dynamic_population(full_exposure_model: models.ExposureModel,
|
||||
dynamic_infected_single_exposure_model: models.ExposureModel,
|
||||
dynamic_single_exposure_model: models.ExposureModel,
|
||||
time: float):
|
||||
|
||||
assert full_exposure_model.concentration(time) == dynamic_infected_single_exposure_model.concentration(time)
|
||||
assert full_exposure_model.concentration(time) == dynamic_single_exposure_model.concentration(time)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("number_of_infected",[1, 2, 3, 4, 5])
|
||||
@pytest.mark.parametrize("time",[9., 12.5, 16.])
|
||||
def test_linearity_with_number_of_infected(full_exposure_model: models.ExposureModel,
|
||||
dynamic_infected_single_exposure_model: models.ExposureModel,
|
||||
dynamic_single_exposure_model: models.ExposureModel,
|
||||
time: float,
|
||||
number_of_infected: int):
|
||||
|
||||
|
|
@ -138,8 +112,8 @@ def test_linearity_with_number_of_infected(full_exposure_model: models.ExposureM
|
|||
}
|
||||
)
|
||||
|
||||
npt.assert_almost_equal(static_multiple_exposure_model.concentration(time), dynamic_infected_single_exposure_model.concentration(time) * number_of_infected)
|
||||
npt.assert_almost_equal(static_multiple_exposure_model.deposited_exposure(), dynamic_infected_single_exposure_model.deposited_exposure() * number_of_infected)
|
||||
npt.assert_almost_equal(static_multiple_exposure_model.concentration(time), dynamic_single_exposure_model.concentration(time) * number_of_infected)
|
||||
npt.assert_almost_equal(static_multiple_exposure_model.deposited_exposure(), dynamic_single_exposure_model.deposited_exposure() * number_of_infected)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
|||
Loading…
Reference in a new issue