From 9ed65a2b044448483dfc6b3de34047705cb0e3b2 Mon Sep 17 00:00:00 2001 From: Nicolas Mounet Date: Mon, 13 Sep 2021 12:00:06 +0200 Subject: [PATCH] Model optimisation: avoid computing before first presence time --- cara/models.py | 14 +++++++++++++- cara/tests/models/test_concentration_model.py | 4 ++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/cara/models.py b/cara/models.py index 53cf52bc..86d2acb9 100644 --- a/cara/models.py +++ b/cara/models.py @@ -776,6 +776,14 @@ class ConcentrationModel: state_change_times.update(self.ventilation.transition_times()) return sorted(state_change_times) + @method_cache + def _first_presence_time(self) -> float: + """ + First presence time. Before that, the concentration is zero. + + """ + return self.infected.presence.boundaries()[0][0] + def last_state_change(self, time: float) -> float: """ Find the most recent/previous state change. @@ -823,7 +831,9 @@ class ConcentrationModel: Note that time is not vectorised. You can only pass a single float to this method. """ - if time == 0: + # The model always starts at t=0, but we avoid running concentration calculations + # before the first presence as an optimisation. + if time <= self._first_presence_time(): return 0.0 next_state_change_time = self._next_state_change(time) IVRR = self.infectious_virus_removal_rate(next_state_change_time) @@ -841,6 +851,8 @@ class ConcentrationModel: """ Get the integrated concentration dose between the times start and stop. """ + if stop <= self._first_presence_time(): + return 0.0 state_change_times = self.state_change_times() req_start, req_stop = start, stop total_concentration = 0. diff --git a/cara/tests/models/test_concentration_model.py b/cara/tests/models/test_concentration_model.py index 46e7e88e..9373d4a9 100644 --- a/cara/tests/models/test_concentration_model.py +++ b/cara/tests/models/test_concentration_model.py @@ -121,6 +121,10 @@ def test_next_state_change_time_out_of_range(simple_conc_model: models.Concentra simple_conc_model._next_state_change(3.1) +def test_first_presence_time(simple_conc_model): + assert simple_conc_model._first_presence_time() == 0.5 + + def test_integrated_concentration(simple_conc_model): c1 = simple_conc_model.integrated_concentration(0, 2) c2 = simple_conc_model.integrated_concentration(0, 1)