Merge branch 'feature/HI_data' into 'master'

Host Immunity Data

See merge request cara/caimira!401
This commit is contained in:
Andre Henriques 2022-11-23 16:54:52 +01:00
commit 20b65b6081
13 changed files with 355 additions and 18 deletions

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
*.xlsx filter=lfs diff=lfs merge=lfs -text

View file

@ -33,7 +33,7 @@ from .user import AuthenticatedUser, AnonymousUser
# calculator version. If the calculator needs to make breaking changes (e.g. change
# form attributes) then it can also increase its MAJOR version without needing to
# increase the overall CAiMIRA version (found at ``caimira.__version__``).
__version__ = "4.4"
__version__ = "4.5"
class BaseRequestHandler(RequestHandler):

View file

@ -72,6 +72,10 @@ class FormData:
room_volume: float
simulation_name: str
total_people: int
vaccine_option: bool
vaccine_booster_option: bool
vaccine_type: str
vaccine_booster_type: str
ventilation_type: str
virus_type: str
volume_type: str
@ -133,6 +137,10 @@ class FormData:
'room_volume': 0.,
'simulation_name': _NO_DEFAULT,
'total_people': _NO_DEFAULT,
'vaccine_option': False,
'vaccine_booster_option': False,
'vaccine_type': 'AZD1222_(AstraZeneca)',
'vaccine_booster_type': 'AZD1222_(AstraZeneca)',
'ventilation_type': 'no_ventilation',
'virus_type': 'SARS_CoV_2',
'volume_type': _NO_DEFAULT,
@ -270,8 +278,9 @@ class FormData:
('window_opening_regime', WINDOWS_OPENING_REGIMES),
('window_type', WINDOWS_TYPES),
('event_month', MONTH_NAMES),
('ascertainment_bias', CONFIDENCE_LEVEL_OPTIONS),]
('ascertainment_bias', CONFIDENCE_LEVEL_OPTIONS),
('vaccine_type', VACCINE_TYPE),
('vaccine_booster_type', VACCINE_BOOSTER_TYPE),]
for attr_name, valid_set in validation_tuples:
if getattr(self, attr_name) not in valid_set:
raise ValueError(f"{getattr(self, attr_name)} is not a valid value for {attr_name}")
@ -517,7 +526,7 @@ class FormData:
mask=self.mask(),
activity=activity,
expiration=expiration,
host_immunity=0.,
host_immunity=0., # Vaccination status does not affect the infected population (for now)
)
return infected
@ -545,12 +554,22 @@ class FormData:
# minus the number of infected occupants.
exposed_occupants = self.total_people - infected_occupants
if (self.vaccine_option):
if (self.vaccine_booster_option and self.vaccine_booster_type != 'Other'):
host_immunity = [vaccine['VE'] for vaccine in data.vaccine_booster_host_immunity if
vaccine['primary series vaccine'] == self.vaccine_type and
vaccine['booster vaccine'] == self.vaccine_booster_type][0]
else:
host_immunity = data.vaccine_primary_host_immunity[self.vaccine_type]
else:
host_immunity = 0.
exposed = mc.Population(
number=exposed_occupants,
presence=self.exposed_present_interval(),
activity=activity,
mask=self.mask(),
host_immunity=0.,
host_immunity=host_immunity,
)
return exposed
@ -790,6 +809,10 @@ def baseline_raw_form_data() -> typing.Dict[str, typing.Union[str, float]]:
'room_volume': '75',
'simulation_name': 'Test',
'total_people': '10',
'vaccine_option': '0',
'vaccine_booster_option': '0',
'vaccine_type': 'Ad26.COV2.S_(Janssen)',
'vaccine_booster_type': 'AZD1222_(AstraZeneca)',
'ventilation_type': 'natural_ventilation',
'virus_type': 'SARS_CoV_2',
'volume_type': 'room_volume_explicit',
@ -820,7 +843,12 @@ MONTH_NAMES = [
'January', 'February', 'March', 'April', 'May', 'June', 'July',
'August', 'September', 'October', 'November', 'December',
]
VACCINE_TYPE = ['Ad26.COV2.S_(Janssen)', 'Any_mRNA_-_heterologous', 'AZD1222_(AstraZeneca)', 'AZD1222_(AstraZeneca)_and_any_mRNA_-_heterologous', 'AZD1222_(AstraZeneca)_and_BNT162b2_(Pfizer)',
'BBIBP-CorV_(Beijing_CNBG)', 'BNT162b2_(Pfizer)', 'BNT162b2_(Pfizer)_and_mRNA-1273_(Moderna)', 'CoronaVac_(Sinovac)', 'CoronaVac_(Sinovac)_and_AZD1222_(AstraZeneca)', 'Covishield',
'mRNA-1273_(Moderna)', 'Sputnik_V_(Gamaleya)', 'CoronaVac_(Sinovac)_and_BNT162b2_(Pfizer)']
VACCINE_BOOSTER_TYPE = ['AZD1222_(AstraZeneca)', 'Ad26.COV2.S_(Janssen)', 'BNT162b2_(Pfizer)', 'BNT162b2_(Pfizer)_(4th_dose)', 'BNT162b2_(Pfizer)_and_mRNA-1273_(Moderna)',
'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)', 'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)_(4th_dose)', 'CoronaVac_(Sinovac)', 'Coronavac_(Sinovac)', 'Sinopharm',
'mRNA-1273_(Moderna)', 'mRNA-1273_(Moderna)_(4th_dose)', 'Other']
def _hours2timestring(hours: float):
# Convert times like 14.5 to strings, like "14:30"

View file

@ -214,6 +214,10 @@ def readable_minutes(minutes: int) -> str:
return time_str + unit
def percentage(absolute: float) -> float:
return absolute * 100
def non_zero_percentage(percentage: int) -> str:
if percentage < 0.01:
return "<0.01%"
@ -389,6 +393,7 @@ class ReportGenerator:
env.filters['minutes_to_time'] = minutes_to_time
env.filters['float_format'] = "{0:.2f}".format
env.filters['int_format'] = "{:0.0f}".format
env.filters['percentage'] = percentage
env.filters['JSONify'] = json.dumps
return env

View file

@ -328,6 +328,49 @@ function on_wearing_mask_change() {
})
}
function update_booster_warning() {
// Check if "Other" is selected
$("#vaccine_booster_type").find(":selected").val() == "Other" ? $("#booster_warning").show() : $("#booster_warning").hide();
}
function update_booster_dropdown(url) {
let primary_vaccine_option = $("#vaccine_type").find(":selected").val();
$("#vaccine_booster_type option").remove();
vaccine_booster_host_immunity.forEach(booster => {
if (booster['primary series vaccine'] == primary_vaccine_option)
$("#vaccine_booster_type").append(`<option data-primary-vaccine=${primary_vaccine_option} value=${booster['booster vaccine']}>${booster['booster vaccine'].replaceAll('_', ' ')}</option>`);
});
$("#vaccine_booster_type").append(`<option value='Other'>Other</option>`);
let booster_vaccine = url.searchParams.has('vaccine_booster_type') ? url.searchParams.get('vaccine_booster_type') : null;
$(`#vaccine_booster_type > option[value="${booster_vaccine}"`).attr('selected', true);
update_booster_warning();
}
function on_vaccination_change(url) {
vaccination_option = $('input[type=radio][name=vaccine_option]');
vaccination_option.each(function (index) {
if (this.checked) {
getChildElement($(this)).show();
require_fields(this);
}
else {
getChildElement($(this)).hide();
require_fields(this);
}
});
update_booster_dropdown(url);
}
function on_vaccination_booster_change() {
vaccination_booster_option = $('input[type=radio][name=vaccine_booster_option]');
vaccination_booster_option.each(function (index) {
if (this.checked) getChildElement($(this)).show();
else getChildElement($(this)).hide();
});
}
function populate_temp_hum_values(data, index) {
$("#sensor_temperature").text(Math.round(data[index].Details.T) + '°C');
$("#sensor_humidity").text(Math.round(data[index].Details.RH) + '%');
@ -818,6 +861,7 @@ window.onpagehide = function(){
$(document).ready(function () {
var url = new URL(decodeURIComponent(window.location.href));
//Pre-fill form with known values
url.searchParams.forEach((value, name) => {
//If element exists
if(document.getElementsByName(name).length > 0) {
@ -852,8 +896,8 @@ $(document).ready(function () {
$("#sr_interactions").text(index - 1);
}
else if (name == 'sensor_in_use') {
// TODO - Validate if sensor exists
else if (name == 'sensor_in_use' || name == 'vaccine_type' || name == 'vaccine_booster_type') {
// Validation after
}
//Ignore 0 (default) values from server side
@ -865,6 +909,14 @@ $(document).ready(function () {
});
// Handle default URL values if they are not explicitly defined.
// Populate primary vaccine dropdown
$("#vaccine_type option").remove();
let primary_vaccine = url.searchParams.has('vaccine_type') ? url.searchParams.get('vaccine_type') : null;
vaccine_primary_host_immunity.forEach(vaccine => $("#vaccine_type").append(`<option value=${vaccine}>${vaccine.replaceAll('_', ' ')}</option>`));
$(`#vaccine_type > option[value="${primary_vaccine}"]`).attr('selected', true);
// Handle geographic location input
if (Array.from(url.searchParams).length > 0) {
if (!url.searchParams.has('location_name')) {
$('[name="location_name"]').val('Geneva')
@ -878,7 +930,6 @@ $(document).ready(function () {
}
}
// When the document is ready, deal with the fact that we may be here
// as a result of a forward/back browser action. If that is the case, update
// the visibility of some of our inputs.
@ -931,6 +982,23 @@ $(document).ready(function () {
// Call the function now to handle forward/back button presses in the browser.
on_wearing_mask_change();
// When the vaccinated_option_option changes we want to make its respective
// children show/hide.
$("input[type=radio][name=vaccine_option]").change(() => on_vaccination_change(url));
// Call the function now to handle forward/back button presses in the browser.
on_vaccination_change(url);
// When the vaccine_type dropdown selected option changes we want to update
// the booster vaccine dropdown.
$("#vaccine_type").change(() => update_booster_dropdown(url));
$("#vaccine_booster_type").change(update_booster_warning);
// When the vaccinated_booster_option changes we want to make its respective
// children show/hide.
$("input[type=radio][name=vaccine_booster_option]").change(on_vaccination_booster_change);
// Call the function now to handle forward/back button presses in the browser.
on_vaccination_booster_change();
// When the short_range_option changes we want to make its respective
// children show/hide.
$("input[type=radio][name=short_range_option]").change(on_short_range_option_change);
@ -1216,3 +1284,47 @@ function objectifyForm(formArray) {
returnArray[formArray[i]['name']] = formArray[i]['value'];
return returnArray;
}
// ------- VACCINATION DATA -------
// From data available in Results of COVID-19 Vaccine Effectiveness
// Studies: An Ongoing Systematic Review - Updated September 8, 2022.
// https://view-hub.org/resources
vaccine_primary_host_immunity = [
'AZD1222_(AstraZeneca)',
'AZD1222_(AstraZeneca)_and_BNT162b2_(Pfizer)',
'AZD1222_(AstraZeneca)_and_any_mRNA_-_heterologous',
'Ad26.COV2.S_(Janssen)',
'Any_mRNA_-_heterologous',
'BBIBP-CorV_(Beijing_CNBG)',
'BNT162b2_(Pfizer)',
'BNT162b2_(Pfizer)_and_mRNA-1273_(Moderna)',
'CoronaVac_(Sinovac)',
'CoronaVac_(Sinovac)_and_AZD1222_(AstraZeneca)',
'CoronaVac_(Sinovac)_and_AZD1222_(AstraZeneca)_-_heterologous',
'CoronaVac_(Sinovac)_and_BNT162b2_(Pfizer)',
'Covishield',
'Sputnik_V_(Gamaleya)',
'mRNA-1273_(Moderna)',
]
vaccine_booster_host_immunity = [
{'primary series vaccine': 'AZD1222_(AstraZeneca)', 'booster vaccine': 'AZD1222_(AstraZeneca)',},
{'primary series vaccine': 'AZD1222_(AstraZeneca)', 'booster vaccine': 'BNT162b2_(Pfizer)',},
{'primary series vaccine': 'AZD1222_(AstraZeneca)', 'booster vaccine': 'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)',},
{'primary series vaccine': 'AZD1222_(AstraZeneca)', 'booster vaccine': 'mRNA-1273_(Moderna)',},
{'primary series vaccine': 'Ad26.COV2.S_(Janssen)', 'booster vaccine': 'Ad26.COV2.S_(Janssen)',},
{'primary series vaccine': 'Ad26.COV2.S_(Janssen)', 'booster vaccine': 'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)',},
{'primary series vaccine': 'BNT162b2_(Pfizer)', 'booster vaccine': 'AZD1222_(AstraZeneca)',},
{'primary series vaccine': 'BNT162b2_(Pfizer)', 'booster vaccine': 'BNT162b2_(Pfizer)',},
{'primary series vaccine': 'BNT162b2_(Pfizer)', 'booster vaccine': 'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)',},
{'primary series vaccine': 'BNT162b2_(Pfizer)', 'booster vaccine': 'mRNA-1273_(Moderna)',},
{'primary series vaccine': 'BNT162b2_(Pfizer)_and_mRNA-1273_(Moderna)', 'booster vaccine': 'BNT162b2_(Pfizer)_and_mRNA-1273_(Moderna)',},
{'primary series vaccine': 'BNT162b2_(Pfizer)_(3_doses)', 'booster vaccine': 'BNT162b2_(Pfizer)_(4th_dose)',},
{'primary series vaccine': 'CoronaVac_(Sinovac)', 'booster vaccine': 'AZD1222_(AstraZeneca)',},
{'primary series vaccine': 'CoronaVac_(Sinovac)', 'booster vaccine': 'BNT162b2_(Pfizer)',},
{'primary series vaccine': 'CoronaVac_(Sinovac)', 'booster vaccine': 'CoronaVac_(Sinovac)',},
{'primary series vaccine': 'mRNA-1273_(Moderna)', 'booster vaccine': 'BNT162b2_(Pfizer)',},
{'primary series vaccine': 'mRNA-1273_(Moderna)', 'booster vaccine': 'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)',},
{'primary series vaccine': 'mRNA-1273_(Moderna)', 'booster vaccine': 'mRNA-1273_(Moderna)',}
]

View file

@ -58,7 +58,7 @@
<b>Virus data:</b>
<div data-tooltip="Choose the SARS-CoV-2 Variant of Concern (VOC).">
<div data-tooltip="Choose the SARS-CoV-2 Variant of Concern (VOC) and select the vaccine type taken by the majority of the exposed population.">
<span class="tooltip_text">?</span>
</div><br>
@ -76,6 +76,49 @@
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">Vaccinated? 💉</div>
<div class="col-sm-6 ml-0">
<input type="radio" id="vaccinated_no" name="vaccine_option" value="0" checked="checked">
<label class="mb-0" for="vaccinated_no">No</label>
<input class="ml-2" type="radio" id="vaccinated_yes" name="vaccine_option" value="1" data-enables="#DIVvaccine_booster">
<label class="mb-0" for="vaccinated_yes">Yes</label>
</div>
</div>
<div id="DIVvaccine_booster" class="mt-3">
<div class="form-group row">
<div class="col-sm-4"><label class="col-form-label">Primary vaccine:</label></div>
<div class="col-sm-6 align-self-center">
<select id="vaccine_type" name="vaccine_type" class="form-control form-control-sm">
{# Updated with JS #}
</select>
</div>
</div>
<div class="form-group row">
<div class="d-flex flex-row col-sm-4"><div class="ml-4" style="border: 1px solid #2f4858"></div><p class="ml-2">With booster?</p></div>
<div class="col-sm-6 ml-0">
<input type="radio" id="vaccinated_booster_no" name="vaccine_booster_option" value="0" checked="checked">
<label class="mb-0" for="vaccinated_booster_no">No</label>
<input class="ml-2" type="radio" id="vaccinated_booster_yes" name="vaccine_booster_option" value="1" data-enables="#DIVvaccine_booster_yes">
<label class="mb-0" for="vaccinated_booster_yes">Yes</label>
</div>
</div>
<div id="DIVvaccine_booster_yes" class="mt-3">
<div class="form-group row">
<div class="col-sm-4"><label class="col-form-label">Booster:</label></div>
<div class="col-sm-6 align-self-center">
<select id="vaccine_booster_type" name="vaccine_booster_type" class="form-control form-control-sm">
{# Updated with JS #}
</select>
</div>
</div>
<p id="booster_warning" class="red_text" style="display: none; max-width: 85%">Due to the lack of data, only the efficiency of the primary dose(s) is considered</p>
</div>
</div>
<hr width="80%">
<b>Room data:</b>
@ -325,7 +368,7 @@
<input type="radio" id="p_deterministic_exposure" name="exposure_option" value="p_deterministic_exposure" checked="checked" data-enables="#DIVp_deterministic_exposure">
<label for="p_deterministic_exposure">Deterministic exposure</label>
</div>
<div class="form-group">
<div class="form-group mb-1">
<input type="radio" id="p_probabilistic_exposure" name="exposure_option" value="p_probabilistic_exposure" data-enables="#DIVp_probabilistic_exposure">
<label for="p_probabilistic_exposure">Probabilistic exposure (incidence rate)</label>
</div>
@ -359,6 +402,7 @@
</div>
<span id="training_limit_error" class="red_text" hidden>Conference/Training activities limited to 1 infected<br></span>
<hr width="80%">
<div class="form-group row">
@ -381,7 +425,6 @@
</div>
</div>
<div style=" margin-right:2rem;">
<div class="boxMargin pb-0">
<div class='sub_title'>Exposed person(s) presence:</div>
@ -427,7 +470,7 @@
</div>
<p id="short_range_warning" class="red_text" style="margin-right: 2rem">The use of masks mitigates exposure at short-range. The analytical model with short-range interactions does not take mask wearing into account.</p>
<div id="DIVsr_interactions" class="none">
<div id="DIVsr_interactions">
<div class="d-flex">
<button type="button" id="set_interactions_button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#short_range_dialog" data-keyboard="false" data-backdrop="static">Set interactions</button>
<p class="align-self-center pl-4"><b id="sr_interactions">0</b> short-range interactions.</p>
@ -604,8 +647,6 @@
<br style="clear:both;">
<i>Coffee breaks are spread evenly throughout the day.</i><br>
<br><br>
</div>
</div>

View file

@ -375,6 +375,24 @@
</ul>
</div>
</div>
<br>
<div class="card">
<div class="card-header"><strong>Vaccination data:</strong></div>
<div class="card-body">
{% if form.vaccine_option %}
<ul>
<li>Primary vaccine: {{ form.vaccine_type | replace("_", " ") }}
{% if form.vaccine_booster_option %}
<li>Booster vaccine: {{ form.vaccine_booster_type | replace("_", " ")}} </li>
{% endif %}
<li>Vaccine effectiveness: {{ model.exposed.host_immunity | percentage | non_zero_percentage }} </li>
</ul>
{% else %}
<p>No vaccination selected.</p>
{% endif %}
</div>
</div>
<br>
<div class="card">
<div class="card-header"><strong>Ventilation data:</strong></div>

View file

@ -51,6 +51,11 @@ The local population in Manaus had very high levels of Covid-19 antibodies (&gt;
This factor has been taken into account by the authors of the study, via statistical adjustments to the transmission value (i.e. it has been increased, to account for spread in a population with significant acquired Covid-19 immunity).
However, this value may be revised in the future as more studies of the Gamma VOC transmission in different geographical locations become available.</p>
<br>
<h4>Vaccine effectiveness</h4>
<br>
<p>The vaccination input corresponds to the vaccine type(s) administrated to the exposed population, assuming every exposed (or the occupant in question) has received the vaccine cocktail selected by the user.
The respective vaccine effectiveness values were extracted from data available in <a href="https://view-hub.org/resources">Results of COVID-19 Vaccine Effectiveness Studies: An Ongoing Systematic Review - Updated September 8, 2022</a>, using <a href="https://gitlab.cern.ch/cara/caimira/-/tree/master/caimira/scripts/data/vaccine_effectiveness.py">this script</a>.</p>
<br>
<h3>Room Data</h3>
<br>
<p>Please enter either the room volume (in m³) or both the floor area (m²) and the room height (m).

View file

@ -40,3 +40,48 @@ GenevaTemperatures = {
month: GenevaTemperatures_hourly[month].refine(refine_factor=10)
for month, temperatures in local_hourly_temperatures_celsius_per_hour.items()
}
# ------- VACCINATION DATA -------
# From data available in Results of COVID-19 Vaccine Effectiveness
# Studies: An Ongoing Systematic Review - Updated September 8, 2022.
# https://view-hub.org/resources
vaccine_primary_host_immunity = {
'AZD1222_(AstraZeneca)': 0.589293,
'AZD1222_(AstraZeneca)_and_BNT162b2_(Pfizer)': 0.7865,
'AZD1222_(AstraZeneca)_and_any_mRNA_-_heterologous': 0.81,
'Ad26.COV2.S_(Janssen)': 0.551278,
'Any_mRNA_-_heterologous': 0.93875,
'BBIBP-CorV_(Beijing_CNBG)': 0.4325,
'BNT162b2_(Pfizer)': 0.660272,
'BNT162b2_(Pfizer)_and_mRNA-1273_(Moderna)': 0.586319,
'CoronaVac_(Sinovac)': 0.317333,
'CoronaVac_(Sinovac)_and_AZD1222_(AstraZeneca)': 0.472,
'CoronaVac_(Sinovac)_and_AZD1222_(AstraZeneca)_-_heterologous': 0.74,
'CoronaVac_(Sinovac)_and_BNT162b2_(Pfizer)': 0.7965,
'Covishield': 0.98,
'Sputnik_V_(Gamaleya)': 0.696,
'mRNA-1273_(Moderna)': 0.730148,
}
vaccine_booster_host_immunity = [
{'primary series vaccine': 'AZD1222_(AstraZeneca)', 'booster vaccine': 'AZD1222_(AstraZeneca)', 'VE': 0.500429},
{'primary series vaccine': 'AZD1222_(AstraZeneca)', 'booster vaccine': 'BNT162b2_(Pfizer)', 'VE': 0.537818},
{'primary series vaccine': 'AZD1222_(AstraZeneca)', 'booster vaccine': 'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)', 'VE': 0.284},
{'primary series vaccine': 'AZD1222_(AstraZeneca)', 'booster vaccine': 'mRNA-1273_(Moderna)', 'VE': 0.709143},
{'primary series vaccine': 'Ad26.COV2.S_(Janssen)', 'booster vaccine': 'Ad26.COV2.S_(Janssen)', 'VE': 0.492667},
{'primary series vaccine': 'Ad26.COV2.S_(Janssen)', 'booster vaccine': 'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)', 'VE': 0.79},
{'primary series vaccine': 'BNT162b2_(Pfizer)', 'booster vaccine': 'AZD1222_(AstraZeneca)', 'VE': 0.801},
{'primary series vaccine': 'BNT162b2_(Pfizer)', 'booster vaccine': 'BNT162b2_(Pfizer)', 'VE': 0.60712},
{'primary series vaccine': 'BNT162b2_(Pfizer)', 'booster vaccine': 'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)', 'VE': 0.632633},
{'primary series vaccine': 'BNT162b2_(Pfizer)', 'booster vaccine': 'mRNA-1273_(Moderna)', 'VE': 0.716786},
{'primary series vaccine': 'BNT162b2_(Pfizer)_and_mRNA-1273_(Moderna)', 'booster vaccine': 'BNT162b2_(Pfizer)_and_mRNA-1273_(Moderna)', 'VE': 0.645},
{'primary series vaccine': 'BNT162b2_(Pfizer)_(3_doses)', 'booster vaccine': 'BNT162b2_(Pfizer)_(4th_dose)', 'VE': 0.962},
{'primary series vaccine': 'CoronaVac_(Sinovac)', 'booster vaccine': 'AZD1222_(AstraZeneca)', 'VE': 0.9405},
{'primary series vaccine': 'CoronaVac_(Sinovac)', 'booster vaccine': 'BNT162b2_(Pfizer)', 'VE': 0.690563},
{'primary series vaccine': 'CoronaVac_(Sinovac)', 'booster vaccine': 'CoronaVac_(Sinovac)', 'VE': 0.52225},
{'primary series vaccine': 'mRNA-1273_(Moderna)', 'booster vaccine': 'BNT162b2_(Pfizer)', 'VE': 0.842143},
{'primary series vaccine': 'mRNA-1273_(Moderna)', 'booster vaccine': 'BNT162b2_(Pfizer)_or_mRNA-1273_(Moderna)', 'VE': 0.632633},
{'primary series vaccine': 'mRNA-1273_(Moderna)', 'booster vaccine': 'mRNA-1273_(Moderna)', 'VE': 0.633238}
]

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2aef0605c3668b4884b815f71c0eae93eaaa7b88d6b6c17ff97f6a86a38674a5
size 76179581

View file

@ -0,0 +1,56 @@
import pandas as pd
from tabulate import tabulate
'''
Script file to generate the vaccine effectiveness values.
To generate the primary vaccine effectiveness values, uncoment lines 16-21.
To generate the booster effectiveness values, uncoment lines 26-56.
'''
# Data from 08 Sep. 2022
file_loc = "./WeeklySummary_COVID19_VE_Studies_08Sep2022_adapted.xlsx"
# ------- PRIMARY VACCINATION ------ #
# df = pd.read_excel(file_loc, sheet_name="Primary_filtered", usecols="A, B, E")
# calculate the VE value
# df = df.drop(df[df['VE'] < 0].index)
# ve_data = df.groupby(['vaccine'])['VE'].mean().divide(100).reset_index()
# print(tabulate(ve_data, headers='keys', tablefmt='psql'))
# ------- BOOSTER VACCINATION ------ #
# df = pd.read_excel(file_loc, sheet_name="Booster_filtered", usecols="A, B, C, F")
# # create df without the ' or ' substring in primary vaccines
# rows_with_or = df[df['primary series vaccine'].str.contains(' or ')]
# rows_indexes = list(rows_with_or.index)
# df_without_or = df.drop(labels=rows_indexes, axis=0)
# # copy of all the rows that contain ' or '
# new_rows_with_or = rows_with_or.reset_index().copy()
# # create new dataframe empty
# rows_to_add = pd.DataFrame(columns=rows_with_or.columns)
# # duplicate each row and add it into the new dataframe
# for index, row in new_rows_with_or.iterrows():
# new_rows_with_or.at[index, 'primary series vaccine'] = row['primary series vaccine'].split(' or ')[0]
# rows_to_add.loc[index] = new_rows_with_or.loc[index]
# new_rows_with_or.at[index, 'primary series vaccine'] = row['primary series vaccine'].split(' or ')[1]
# rows_to_add.loc[len(rows_indexes)+index] = new_rows_with_or.loc[index]
# # merge the dataframe without the ' or ' with the new dataframe that has the rows divided in two
# final_df = pd.concat([df_without_or, rows_to_add]).reset_index().drop(columns=['index'])
# # calculate the VE value
# final_df = final_df.drop(final_df[final_df['VE'] < 0].index)
# ve_data = final_df.groupby(['primary series vaccine', 'booster vaccine'])['VE'].mean().divide(100).reset_index()
# result = ve_data.to_dict('records')
# print(tabulate(ve_data, headers='keys', tablefmt='psql'))

View file

@ -297,13 +297,13 @@ def test_prob_meet_infected_person(pop, cases, AB, exposed, infected, prob_meet_
[30, known_concentrations(lambda t: 1.2),
100000, 68, 5, 55.93154502],
])
def test_probabilistic_exposure_probability(exposed_population, cm,
def test_probabilistic_exposure_probability(sr_model, exposed_population, cm,
pop, AB, cases, probabilistic_exposure_probability):
population = models.Population(
exposed_population, models.PeriodicInterval(120, 60), models.Mask.types['Type I'],
models.Activity.types['Standing'], host_immunity=0.,)
model = ExposureModel(cm, (), population, models.Cases(geographic_population=pop,
model = ExposureModel(cm, sr_model, population, models.Cases(geographic_population=pop,
geographic_cases=cases, ascertainment_bias=AB),)
np.testing.assert_allclose(
model.total_probability_rule(), probabilistic_exposure_probability, rtol=0.05
@ -390,4 +390,25 @@ def test_diameter_vectorisation_room(diameter_dependent_model, sr_model, cases_m
ventilation = models.HVACMechanical(active=models.SpecificInterval(((0., 24.), )), q_air_mech=100.))
with pytest.raises(ValueError, match=error_message):
models.ExposureModel(concentration, sr_model, populations[0], cases_model)
@pytest.mark.parametrize(
["cm", "host_immunity", "expected_probability"],
[
[known_concentrations(lambda t: 36.), np.array([0.25, 0.5]), np.array([57.40415859, 41.03956914])],
[known_concentrations(lambda t: 36.), np.array([0., 1.]), np.array([67.95037626, 0.])],
]
)
def test_host_immunity_vectorisation(sr_model, cases_model, cm, host_immunity, expected_probability):
population = models.Population(
10, halftime, models.Mask(np.array([0.3, 0.35])),
models.Activity.types['Standing'], host_immunity=host_immunity
)
model = ExposureModel(cm, sr_model, population, cases_model)
inf_probability = model.infection_probability()
np.testing.assert_almost_equal(
inf_probability, expected_probability, decimal=1
)
assert isinstance(inf_probability, np.ndarray)
assert inf_probability.shape == (2, )

View file

@ -29,3 +29,5 @@ ignore_missing_imports = True
[mypy-timezonefinder.*]
ignore_missing_imports = True
[mypy-pandas.*]
ignore_missing_imports = True