Dynamic Occupancy Groups
The dynamic occupancy introduces the capability to handle multiple exposure groups within an event. Instead of having one single set of parameters for all the exposed (susceptible) occupants, this feature enables the model to have n groups, each with a specific occupancy profile and set of short-range interactions. This will facilitate more accurate risk assessments in a more heterogenous environment. This can also be used to define dynamic groups for the CO2 fitting algorithm.
Note
When in development mode, this feature enables the model to have n groups, each with their specific characteristics, e.g. masks, physical activity or host immunities.
This page covers the description, input structure, and results structure of this feature.
Feature Description
The feature revolves around the concept of a new ExposureModelGroup
class, which encapsulates a set of ExposureModel
instances. Each ExposureModel
represents a distinct group of exposed occupants.
Input Structure
The modelling of dynamic groups is controlled by the occupancy_format
input, set as static
by default. To enable it, the corresponding value should be set to dynamic
:
occupancy_format = "dynamic"
Definition: Exposed occupants
The dynamic_exposed_occupancy
object defines the presence of exposed population groups over time. Each group should be identified by a unique key (group_1
, group_2
, etc.), mapping to an object that specifies:
total_people
: The total number of exposed individuals in the group.presence
: A list of time intervals (start_time
andfinish_time
) during which the group was present, formatted asHH:MM
.
Example
dynamic_exposed_occupancy = {
"group_1": {
"total_people": 5,
"presence": [
{"start_time": "09:00", "finish_time": "12:00"},
{"start_time": "13:00", "finish_time": "17:00"}
]
},
"group_2": {
"total_people": 10,
"presence": [
{"start_time": "10:00", "finish_time": "11:00"}
]
}
}
group_1
consists of 5 individuals present in two time intervals:09:00
to12:00
.13:00
to17:00
.
group_2
consists of 10 individuals, present from:10:00
to11:00
.
Definition: Infected occupants
Unlike the dynamic_exposed_occupancy
, the dynamic_infected_occupancy
represents a single group of infected occupants that contributes to all exposure groups. It should be defined as a list where each entry defines a time interval during which infected individuals were present. Each entry includes:
total_people
: the total number of infected individuals in the group,start_time
andfinish_time
: the time boundaries at which the occupants were present, formatted asHH:MM
.
Example
dynamic_infected_occupancy = [
{"total_people": 2, "start_time": "10:00", "finish_time": "12:00"},
{"total_people": 3, "start_time": "13:00", "finish_time": "17:00"}
]
The infected group consists of:
2
present from10:00
to12:00
,3
people present from13:00
to17:00
.
Info
While the dynamic_exposed_occupancy
results in the creation of multiple ExposureModel
objects, the dynamic_infected_occupancy
leads to a single InfectedPopulation
object that is replicated across all ExposureModel
.
This means that the infected population contributes uniformly to the concentration in each exposure model.
Short-range interactions
The short_range_interactions
object defines the number of short-range interactions per exposure group. Each set of interactions is identified by its corresponding exposure group key (group_1
, group_2
, etc.), mapping to an object that specifies:
expiration
: expiration type of that short-range interaction (Breathing
,Speaking
, orShouting
).start_time
: when the interaction starts, formatted asHH:MM
.duration
: duration of the interaction (in minutes).
Example
short_range_interactions = {
"group_1": [
{"expiration": "Shouting", "start_time": "10:00", "duration": 30},
{"expiration": "Speaking", "start_time": "11:15", "duration": 15}
],
"group_2": [
{"expiration": "Shouting", "start_time": "10:15", "duration": 30}
]
}
group_1
has 2 interactions in two time intervals:Shouting
, from10:00
for30
minutes,Speaking
, from11:15
for15
minutes.
group_2
has 1 interaction, in a single time interval:Shouting
from10:15
for30
minutes.
Note
Extensive validation is conducted in the algorithm to guarantee that the interactions are related to an existing exposure group, and that the times are within the concerned exposure group simulation time.
Warning
Short-range interactions cannot overlap within the same group, i.e. only one short-range interaction per group is allowed for any given time.
Model generator
Following the previous JSON examples of dynamic_exposed_occupancy
, dynamic_infected_occupancy
, and short_range_interactions
, the ExposureModelGroups
object that would be generated would have the following structure:
Structure
ExposureModelGroup(
ExposureModel(
data_registry=...,
concentration_model=concentration_model_infected,
short_range=(
ShortRangeModel(
data_registry=...,
expiration="Shouting",
activity=...,
presence=SpecificInterval(((10., 11.5),)),
distance=...,
),
ShortRangeModel(
data_registry=...,
expiration="Shouting",
activity=...,
presence=SpecificInterval(((11.25, 11.5),)),
distance=...,
),
),
exposed=Population(
number=5,
presence=SpecificInterval(((9., 12.), (13., 17.))),
activity=...,
mask=...,
host_immunity=...,
),
geographical_data=...,
exposed_to_short_range=...,
identifier="group_1',
),
ExposureModel(
data_registry=...,
concentration_model=concentration_model_infected,
short_range=(
ShortRangeModel(
data_registry=...,
expiration="Shouting",
activity=...,
presence=SpecificInterval(((10.25, 10.75),)),
distance=...,
),
),
exposed=Population(
number=5,
presence=SpecificInterval(((10., 11.),)),
activity=...,
mask=...,
host_immunity=...,
),
geographical_data=...,
exposed_to_short_range=...,
identifier="group_2",
)
)
Note
Each exposure group (group_1
and group_2
) originates one ExposureModel
, and the ConcentrationModel
, originated with the dynamic_infected_occupancy
is the same for both exposure groups.
Results structure (model output)
After the defining the simulation and when making a request to the API, the response is structured as a JSON object that consists of a status
field indicating success or failure, along with a message
providing additional details. If successful, the report_data
object contains the computed exposure results per group and model configuration.
Example
{
"status": "success",
"message": "Results generated successfully",
"report_data": {
"model": ...,
"times": ...,
"CO2_concentrations": ...,
"groups": {
"group_1": {
"prob_inf": ...,
"prob_inf_sd": ...,
"prob_dist": ...,
"prob_hist_count": ...,
"prob_hist_bins": ...,
"expected_new_cases": ...,
"exposed_presence_intervals": ...,
"concentrations": ...,
"cumulative_doses": ...,
"long_range_prob": ...,
"long_range_R0": ...,
"short_range_interactions": ...,
"concentrations_zoomed": ...,
"long_range_cumulative_doses": ...
},
"group_2": ...
}
}
}
The output response is structured as follows:
-
Top-Level Fields:
status
(string) – Indicates whether the request was successful ("success"
) or if an error occurred ("error"
).message
(string) – Provides a brief description of the response outcome.
-
report_data
Object:model
(object) – Representation of the exposure model used.times
(array) – Full simulation timestamps.CO2_concentrations
(array) – CO2 concentration levels over time.groups
(object) – Contains the exposure results for each group.
-
groups
Object:Each key inside groups corresponds to a specific group (e.g.,
"group_1"
,"group_2"
) and contains the following fields:prob_inf
(float) – Mean probability of infection. For occupant groups with short-range interactions, this includes both short- and long-range exposures.prob_inf_sd
(float) – Standard deviation of the probability of infection.prob_dist
(array) – Probability distribution values.prob_hist_count
(array) – Histogram counts for probability distribution.prob_hist_bins
(array) – Histogram bin edges for probability distribution.expected_new_cases
(float) – Expected number of new cases within the group.exposed_presence_intervals
(array) – Time intervals when group members were exposed.concentrations
(array) – Viral concentration levels over time.cumulative_doses
(array) – Accumulated viral doses over time.
If short-range interactions are considered, additional fields will be included:
long_range_prob
(float) – Mean probability of infection of occupant groups without short-range interactions.long_range_expected_new_cases
(float) – Expected number of new cases of occupant groups without short-range interactions.short_range_interactions
(object) – Contains expiration times and short-range exposure data.concentrations_zoomed
(array) – Higher-resolution long-range concentration data.long_range_cumulative_doses
(array) – Accumulated viral doses from long-range interactions.
Note
Regardless of whether the occupancy_format
is static
or dynamic
, the output format will always follow the described structure.
When using a static
structure, a group object with a predefined identifier is created.
Conclusion
The dynamic occupancy feature enhances CAiMIRA's flexibility to apply different groups to the occupants in the event, allowing for a more detailed and accurate assessment of risk.
The occupancy_format
entry must be set to dynamic
and the dynamic_exposed_occupancy
, dynamic_infected_occupancy
, and short_range_interactions
correctly defined, as detailed above, for the feature to work properly.
For examples on how to extend and use the REST API, see REST API.