@@ -1615,9 +1615,19 @@ def __post_init__(self):
16151615 # the short range interaction is with does not have to be defined (?)
16161616 raise NotImplementedError ("Short range interactions with multiple infected populations not yet implemented." )
16171617
1618- _ = self .virus
1619- _ = self .room
1620- _ = self .ventilation
1618+ viruses = [c_model .virus for c_model in self .concentration_model_list ]
1619+ virus = viruses [0 ]
1620+ if any (v != virus for v in viruses ):
1621+ raise ValueError ("All infected must be infected with the same virus." )
1622+ rooms = [c_model .room for c_model in self .concentration_model_list ]
1623+ room = rooms [0 ]
1624+ if any (r != room for r in rooms ):
1625+ raise ValueError ("All concentration models must describe the same room." )
1626+
1627+ # TODO: test that all concentration models have overlapping ventilations
1628+ # NOTE: Different concentration models can have different occupancy times, and therefore different
1629+ # start and end times for which the ventilation is defined. Therefore, the ventilation objects
1630+ # must overlapp, but not neccecarily be identical.
16211631
16221632 for c_model in self .concentration_model_list :
16231633 # Check if the diameter is vectorised.
@@ -1644,27 +1654,11 @@ def concentration_model_list(self):
16441654
16451655 @property
16461656 def virus (self ):
1647- viruses = [c_model .virus for c_model in self .concentration_model_list ]
1648- virus = viruses [0 ]
1649- if any (v != virus for v in viruses [1 :]):
1650- raise ValueError ("All infected must be infected with the same virus." )
1651- return virus
1657+ return self .concentration_model_list [0 ].virus
16521658
16531659 @property
16541660 def room (self ):
1655- rooms = [c_model .room for c_model in self .concentration_model_list ]
1656- room = rooms [0 ]
1657- if any (r != room for r in rooms [1 :]):
1658- raise ValueError ("All concentration models must describe the same room." )
1659- return room
1660-
1661- @property
1662- def ventilation (self ):
1663- ventilations = [c_model .ventilation for c_model in self .concentration_model_list ]
1664- ventilation = ventilations [0 ]
1665- if any (v != ventilation for v in ventilations [1 :]):
1666- raise ValueError ("All concentration models must have the same ventilation." )
1667- return ventilation
1661+ return self .concentration_model_list [0 ].room
16681662
16691663 @method_cache
16701664 def population_state_change_times (self ) -> typing .List [float ]:
@@ -1709,17 +1703,19 @@ def _long_range_normed_exposure_between_bounds(self, c_model, time1: float, time
17091703
17101704 def long_range_concentration (self , time : float ) -> float :
17111705 """
1712- Integrated virus exposure concentration, as a function of time.
1706+ Total virus concentration in the room , as a function of time.
17131707
17141708 It only considers the long-range concentration without the
17151709 contribution of the short-range concentration.
17161710
1717- Since the different ConcentrationModel objects may have different diameter bases drawn
1718- from different distributions, the concentrations from different ConcentrationModel
1719- objects must be averaged over the diameter before summed together.
1711+ Since the different ConcentrationModel objects may have different infected with different expirations,
1712+ they can have different particle diameters bases drawn from different probability distributions.
1713+ To Monte Carlo integrate correctly over the particle diameter, we must therefore average the concentration
1714+ of each ConcentrationModel over the particle diameter before adding together all the contributions from all
1715+ the ConcentrationModels.
17201716 """
1721- return sum ([np .array (c_model .concentration (time )).mean () for c_model in self .concentration_model_list ])
1722-
1717+ return sum ([np .array (c_model .concentration (time )).mean () for c_model in self .concentration_model_list ]) # Average over particle diameter
1718+
17231719 def concentration (self , time : float ) -> float :
17241720 """
17251721 Integrated virus exposure concentration, as a function of time.
@@ -1770,7 +1766,7 @@ def long_range_deposited_exposure_between_bounds(self, time1: float, time2: floa
17701766
17711767 return deposited_exposure
17721768
1773- def deposited_exposure_between_bounds (self , time1 : float , time2 : float ) -> _VectorisedFloat :###
1769+ def deposited_exposure_between_bounds (self , time1 : float , time2 : float ) -> _VectorisedFloat :
17741770 """
17751771 The number of virus per m^3 deposited on the respiratory tract
17761772 between any two times.
@@ -1910,7 +1906,7 @@ def reproduction_number(self) -> _VectorisedFloat:
19101906 cases directly generated by one infected case in a population.
19111907 """
19121908 if isinstance (self .concentration_model , list ):
1913- raise NotImplementedError ("yet to implement dynamic infected for SR interactions " )
1909+ raise NotImplementedError ("yet to implement dynamic infected for the reproduction number " )
19141910 infected_population : InfectedPopulation = self .concentration_model .infected
19151911 if isinstance (infected_population .number , int ) and infected_population .number == 1 :
19161912 return self .expected_new_cases ()
0 commit comments