This repository contains the code to compute optimal testing allocations to identify asymptomatic infections for COVID-19 in Switzerland. The employed epidemiological model is coded in C++ and uses python bindings. It relies on:
- Cmake: minimum required version 3.12
- boost: https://www.boost.org/
In the following, we provide a detailed explanation on how to clone the directory, install the code and use it.
https: git clone --recurse-submodules https://github.com/cselab/optimal-testing
ssh: git clone --recurse-submodules [email protected]:cselab/optimal-testing.git
First, install Cmake and Boost. Second, install the Dynesty library by using pip3:
pip3 install dynesty
Finally, compile the epidemiological model as follows:
cd optimal-testing/covid19
mkdir -p build
cd build
cmake ..
make
The optimal test allocation is run via the script launch.sh. The script contains the following arguments
- CORES : maximum number of available cores (MPI processes)
- CASE : which case to run (1,2,3 or 4)
- SENSORS : how many surveys to allocate (one survey corresponds to testing people in one canton)
- SAMPLES : how many model parameter samples will be used for the Monte-Carlo approximation of the integral in the utility function
- NY : how many measurement samples will be used for the Monte-Carlo approximation of the integral in the utility function
- NLIVE : parameter used for nested-sampling for cases 2,3,4 (use 50 for quick results or around 500-1000 for more accurate sampling)
- DLOGZ : parameter used as termination criterion for nested-sampling (use 0.1 or smaller number)
- CORES_SAMPLES : how many cores will be used to evaluate the model using the model parameter samples. Must be less than or equal to CORES and SAMPLES must be divisible by this number.
This script will sample the model parameters first. The samples will be drawn uniformly for case 1 and with nested-sampling for the other cases. Note that nested-sampling for cases 3 and 4 takes a while. Then, the epidemiological model is evaluated using those samples. Finally, the sequential optimization will be performed, to find the optimal test allocation.
The posterior distributions the arise from nested-sampling are plotted by running
python3 plot-sampling.py --case X
where X=2,3,4. The plots are saved as .pdf files, in the directory caseX. This directory contains:
- cantons.pdf : shows the fitted model for all cantons (reported infections' data plotted against model output)
- posteriorX.pdf : shows the one-dimensional marginal posterior distributions of the model parameters, after they are updated with data for the reported infections
- result.npy : contains the utility function evaluations
- map.npy : contains the maximum a posteriori estimates of the model parameters, after the inference is completed.
- samples_X.pickle : contains the samples of the model parameters after the inference
- prediction_country.pdf : model prediction plotted against data for total reported cases in Switzerland
- day=Y.npy : epidemiological model evaluation for all cantons on day Y
- dispersion.npy : error model dispersion
- Run the plotting script
python3 plot-ots.py --case Y
where Y=1,2,3. This will create the plots for the different cases as shown in the publication. The figures are saved in figures/caseY. Plotting case Y=3 assumes that the optimal testing was run for case 3 and case 4. - The tables from the Supplementary Information are created using
python3 print-tables.py --case Y
for Y=1,2,3. The generated screen output can be copy pasted to generate the tables in latex.
To do this comparison you must first:
- Run the optimal testing for case 1, so that the utility function is computed and the optimal strategy is defined.
- Run the optimal testing for case 2 and the plot-sampling.py script afterwards, so that the maximum a posteriori estimates for the model parameters are used to generate artificial survey measurements.
Then, in the directory 'comparison':
- Execute
python3 comparison.py --surveys 2
- Plot the results by using
python3 plot.py
- Data openZH database. For the inference on the swiss data we do not use the NaN values.
- common.py : contains the dates used for test allocation for the four cases.
- nested.py : does the nested-sampling. The prior distributions for the model parameters used for each case can be found here.
- plot-ots.py: Plot the resulting optimal testing strategies
- plot-sampling.py: plots the results from nested sampling
- print-tables.py: prints the tables to be used in latex
- run-sequential.py: performs the evaluation of the utility function following sequential optimisation
- samples.py: evaluates the model at model parameter samples
- seiin.py : wrapper for the employed epidemiological model's C++ code
- swiss_cantons.py : will download data used for cases 2,3,4 as well as cantons connections matrix for epidemiological model