Merge branch 'develop/calculator_inf_vs_exp_times' into 'master'
Disentangle infected and exposed presence times in model_generator See merge request cara/cara!87
This commit is contained in:
commit
8c3bd0dad8
3 changed files with 31 additions and 11 deletions
|
|
@ -172,7 +172,7 @@ class FormData:
|
|||
coffee_times.append((start, end))
|
||||
return tuple(coffee_times)
|
||||
|
||||
def present_interval(self) -> models.Interval:
|
||||
def present_interval(self, start, finish) -> models.Interval:
|
||||
leave_times = []
|
||||
enter_times = []
|
||||
if self.lunch_option:
|
||||
|
|
@ -193,19 +193,19 @@ class FormData:
|
|||
# representing the infected person entering and leaving the room. Note that if one of the evenly spaced coffee-
|
||||
# breaks happens to coincide with the lunch-break, it is simply ignored.
|
||||
present_intervals = []
|
||||
time = self.infected_start
|
||||
time = start
|
||||
is_present = True
|
||||
while time < self.infected_finish:
|
||||
while time < finish:
|
||||
if is_present:
|
||||
if not leave_times:
|
||||
present_intervals.append((time / 60, self.infected_finish / 60))
|
||||
present_intervals.append((time / 60, finish / 60))
|
||||
break
|
||||
|
||||
if leave_times[-1] <= time:
|
||||
leave_times.pop()
|
||||
else:
|
||||
new_time = leave_times.pop()
|
||||
present_intervals.append((time / 60, min(new_time, self.infected_finish) / 60))
|
||||
present_intervals.append((time / 60, min(new_time, finish) / 60))
|
||||
is_present = False
|
||||
time = new_time
|
||||
|
||||
|
|
@ -221,6 +221,12 @@ class FormData:
|
|||
|
||||
return models.SpecificInterval(tuple(present_intervals))
|
||||
|
||||
def infected_present_interval(self) -> models.Interval:
|
||||
return self.present_interval(self.infected_start, self.infected_finish)
|
||||
|
||||
def exposed_present_interval(self) -> models.Interval:
|
||||
return self.present_interval(self.activity_start, self.activity_finish)
|
||||
|
||||
|
||||
def model_from_form(form: FormData) -> models.ExposureModel:
|
||||
# Initializes room with volume either given directly or as product of area and height
|
||||
|
|
@ -262,7 +268,7 @@ def model_from_form(form: FormData) -> models.ExposureModel:
|
|||
infected=models.InfectedPopulation(
|
||||
number=infected_occupants,
|
||||
virus=virus,
|
||||
presence=form.present_interval(),
|
||||
presence=form.infected_present_interval(),
|
||||
mask=mask,
|
||||
activity=infected_activity,
|
||||
expiration=infected_expiration
|
||||
|
|
@ -270,7 +276,7 @@ def model_from_form(form: FormData) -> models.ExposureModel:
|
|||
),
|
||||
exposed=models.Population(
|
||||
number=exposed_occupants,
|
||||
presence=form.present_interval(),
|
||||
presence=form.exposed_present_interval(),
|
||||
activity=exposed_activity,
|
||||
mask=mask,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -24,8 +24,10 @@ class RepeatEvents:
|
|||
def calculate_report_data(model: models.ExposureModel):
|
||||
resolution = 600
|
||||
|
||||
t_start = model.exposed.presence.boundaries()[0][0]
|
||||
t_end = model.exposed.presence.boundaries()[-1][1]
|
||||
t_start = min(model.exposed.presence.boundaries()[0][0],
|
||||
model.concentration_model.infected.presence.boundaries()[0][0])
|
||||
t_end = max(model.exposed.presence.boundaries()[-1][1],
|
||||
model.concentration_model.infected.presence.boundaries()[-1][1])
|
||||
|
||||
times = list(np.linspace(t_start, t_end, resolution))
|
||||
concentrations = [model.concentration_model.concentration(time) for time in times]
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ def test_ventilation_window_hepa(baseline_form):
|
|||
[baseline_form.ventilation().air_exchange(room, t) for t in ts])
|
||||
|
||||
|
||||
def test_present_intervals(baseline_form):
|
||||
def test_infected_present_intervals(baseline_form):
|
||||
baseline_form.coffee_duration = 15
|
||||
baseline_form.coffee_breaks = 2
|
||||
baseline_form.activity_start = 9 * 60
|
||||
|
|
@ -108,9 +108,21 @@ def test_present_intervals(baseline_form):
|
|||
baseline_form.infected_start = 10 * 60
|
||||
baseline_form.infected_finish = 15 * 60
|
||||
correct = ((10, 11), (11.25, 12.5), (13.5, 15.0))
|
||||
assert baseline_form.present_interval().present_times == correct
|
||||
assert baseline_form.infected_present_interval().present_times == correct
|
||||
|
||||
|
||||
def test_exposed_present_intervals(baseline_form):
|
||||
baseline_form.coffee_duration = 15
|
||||
baseline_form.coffee_breaks = 2
|
||||
baseline_form.activity_start = 9 * 60
|
||||
baseline_form.activity_finish = 17 * 60
|
||||
baseline_form.lunch_start = 12 * 60 + 30
|
||||
baseline_form.lunch_finish = 13 * 60 + 30
|
||||
baseline_form.infected_start = 10 * 60
|
||||
baseline_form.infected_finish = 15 * 60
|
||||
correct = ((9, 11), (11.25, 12.5), (13.5, 15), (15.25, 17.0))
|
||||
assert baseline_form.exposed_present_interval().present_times == correct
|
||||
|
||||
def test_key_validation(baseline_form_data):
|
||||
baseline_form_data['activity_type'] = 'invalid key'
|
||||
with pytest.raises(ValueError):
|
||||
|
|
|
|||
Loading…
Reference in a new issue