Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM ubuntu:latest
RUN apt update -y
RUN apt upgrade -y
RUN apt install build-essential python3 python3-pip git vim -y
RUN python3 -m pip install cmake
RUN git clone https://github.com/ScottishCovidResponse/Covid19_EERAModel.git /home/Covid19_EERAModel
RUN git clone https://github.com/ScottishCovidResponse/data_pipeline_api.git /home/Covid19_EERAModel/api
RUN python3 -m pip install -r /home/Covid19_EERAModel/api/bindings/cpp/requirements.txt
WORKDIR /home/Covid19_EERAModel
ENV DEBIAN_FRONTEND=noninteractive
RUN apt install -y libgsl-dev pkg-config
RUN cmake -H. -Bbuild -DDATA_PIPELINE=/home/Covid19_EERAModel/api -DPython3_EXECUTABLE=$(which python3)
RUN cmake --build build
ENV EERAMODEL_ROOT=/home/Covid19_EERAModel
ENTRYPOINT [ "/usr/bin/bash" ]
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ At the present time, the `-d` and `-l` options are unused by the code and can be

The command line options used on a given model run are logged in the output log file (see below) for traceability and future reference.

### Running with Docker

The model can also be run via the included Dockerfile, firstly build the image by running:

```bash
docker build --label eeramodel </path/to/Dockerfile>
```

you can then run an interactive terminal within a new container, with the additional option of mounting the repository to your local file system (important for having access to the model outputs):

```bash
docker run -ti --label eeramodel_container -v </path/on/host-file-system>:/home/Covid19_EERAModel eeramodel
```

note however that these outputs will be owned by `root` within the container, as such it is highly advised that this method not be used for development. If you do not care about having access to the files on your host file system the volume option can be dropped.

### Inputs
The model requires a number of input files to run, in addition to the command line arguments. Input files must be placed in the `data` directory, and must be named according to the table below. The required contents of each file are described in more detail underneath the table.

Expand Down
57 changes: 47 additions & 10 deletions src/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,26 +430,19 @@ void WriteOutputsToFiles(int smc, int herd_id, int Nparticle, int nPar,
output_simu << "iterID" << "," << "day" << "," << "inc_case" << "," << "inc_death_hospital" << "," << "inc_death" << std::endl;

//add the column names for each output list of the compartment values of the last day of the chosen simulations
output_ends << "iterID" << "," << "age_group" << "," << "comparts" << "," << "value" << std::endl;
WriteInferenceEndsHeader(output_ends);

// outputs the list of particles (and corresponding predictions) that were accepted at each steps of ABC-smc
for (int kk = 0; kk < Nparticle; ++kk) {
output_step << particleList[kk].iter << ", " << particleList[kk].nsse_cases << ", " << particleList[kk].nsse_deaths << ", " ;

for (int var = 0; var < nPar; ++var) {
output_step << particleList[kk].parameter_set[var] << ", ";
}
output_step << particleList[kk].weight<< '\n';
WriteInferenceParticlesRow(output_step, kk, particleList[kk]);

for (unsigned int var = 0; var < particleList[kk].simu_outs.size(); ++var) {
output_simu << particleList[kk].iter << ", " << var << ", " << particleList[kk].simu_outs[var] << ", " \
<< particleList[kk].hospital_death_outs[var] << ", " << particleList[kk].death_outs[var] << '\n';
}

for (unsigned int age = 0; age < particleList[kk].end_comps.size(); ++age) {
for (unsigned int var = 0; var < particleList[kk].end_comps[0].size(); ++var) {
output_ends << particleList[kk].iter << ", " << age << ", " << var << ", " << particleList[kk].end_comps[age][var] << '\n';
}
WriteInferenceEndsRow(output_ends, particleList[kk].iter, age, particleList[kk].end_comps[age]);
}
}

Expand Down Expand Up @@ -499,6 +492,12 @@ void WritePredictionFullHeader(std::ostream& os)
" I1, I2, I3, I4, I_s1, I_s2, I_s3, I_s4, H, R, D" << std::endl;
}

void WriteInferenceEndsHeader(std::ostream& os)
{
os << "iter, age_group, S, E, E_t, I_p, I_t,"
" I1, I2, I3, I4, I_s1, I_s2, I_s3, I_s4, H, R, D" << std::endl;
}

void WritePredictionFullRow(std::ostream& os, int iter, int day, int age_group, const Compartments& comp)
{
os << iter << ", ";
Expand All @@ -522,6 +521,44 @@ void WritePredictionFullRow(std::ostream& os, int iter, int day, int age_group,
os << comp.D << std::endl;
}

void WriteInferenceEndsRow(std::ostream& os, int iter, int age_group, const Compartments& comp)
{
os << iter << ", ";
os << age_group << ", ";
os << comp.S << ", ";
os << comp.E << ", ";
os << comp.E_t << ", ";
os << comp.I_p << ", ";
os << comp.I_t << ", ";
os << comp.I1 << ", ";
os << comp.I2 << ", ";
os << comp.I3 << ", ";
os << comp.I4 << ", ";
os << comp.I_s1 << ", ";
os << comp.I_s2 << ", ";
os << comp.I_s3 << ", ";
os << comp.I_s4 << ", ";
os << comp.H << ", ";
os << comp.R << ", ";
os << comp.D << std::endl;
}

void WriteInferenceParticlesRow(std::ostream& os, int iter, const particle particle)
{
os << iter << ", ";
os << particle.nsse_cases << ", ";
os << particle.nsse_deaths << ", ";
os << particle.parameter_set[Model::ModelParameters::PINF] << ", ";
os << particle.parameter_set[Model::ModelParameters::PHCW] << ", ";
os << particle.parameter_set[Model::ModelParameters::CHCW] << ", ";
os << particle.parameter_set[Model::ModelParameters::D] << ", ";
os << particle.parameter_set[Model::ModelParameters::Q] << ", ";
os << particle.parameter_set[Model::ModelParameters::PS] << ", ";
os << particle.parameter_set[Model::ModelParameters::RRD] << ", ";
os << particle.parameter_set[Model::ModelParameters::LAMBDA] << ", ";
os << particle.weight << std::endl;
}

void WritePredictionSimuHeader(std::ostream& os)
{
os << "iter, day, " << "inc_case, " << "inc_death_hospital, " << "inc_death" << std::endl;
Expand Down
36 changes: 35 additions & 1 deletion src/IO.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "ModelTypes.h"
#include "ModelCommon.h"
#include "IniFile.h"
#include "Utilities.h"
#include <sstream>
Expand Down Expand Up @@ -185,10 +186,19 @@ void WritePredictionsToFiles(std::vector<Status> statuses, const std::string& ou
*/
void WritePredictionFullHeader(std::ostream& os);

/**
* @brief Write header row for inference end outputs
*
* Writes inference end state file header, followed by a newline
*
* @param os Stream to write the header to
*/
void WriteInferenceEndsHeader(std::ostream& os);

/**
* @brief Write data row for prediction full outputs
*
* Writes @p iter, @p daya, @p age_group, followed by the contents of @p comp, followed by a newline
* Writes @p iter, @p day, @p age_group, followed by the contents of @p comp, followed by a newline
*
* @param os Stream to write the row to
* @param iter Iteration number
Expand All @@ -198,6 +208,30 @@ void WritePredictionFullHeader(std::ostream& os);
*/
void WritePredictionFullRow(std::ostream& os, int iter, int day, int age_group, const Compartments& comp);

/**
* @brief Write data row for inference ends outputs
*
* Writes @p iter, @p age_group, followed by the contents of @p comp, followed by a newline
*
* @param os Stream to write the row to
* @param iter Iteration number
* @param day Day number
* @param age_group Age group number
* @param comp Epidemiological compartments for @p age_group
*/
void WriteInferenceEndsRow(std::ostream& os, int iter, int age_group, const Compartments& comp);

/**
* @brief Write data row for inference ends outputs
*
* Writes @p iter, @p age_group, followed by the contents of @p comp, followed by a newline
*
* @param os Stream to write the row to
* @param iter Iteration number
* @param particle A particle representing a set of parameters
*/
void WriteInferenceParticlesRow(std::ostream& os, int iter, const particle particle);

/**
* @brief Write header row for prediction simulation outputs
*
Expand Down
2 changes: 1 addition & 1 deletion src/InferenceFramework.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ void InferenceFramework::ModelSelect(EERAModel::particle& outvec, int n_sim_step
outvec.simu_outs = status.simulation;
outvec.hospital_death_outs = status.hospital_deaths;
outvec.death_outs = status.deaths;
outvec.end_comps = Model::compartments_to_vector(status.ends);
outvec.end_comps = status.ends;
}

double InferenceFramework::ComputeParticleWeight(int smc, const std::vector<EERAModel::particle>& previousParticles,
Expand Down
15 changes: 0 additions & 15 deletions src/ModelCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,5 @@ int accumulate_compartments(const Compartments& comp)
return _total;
}

std::vector<std::vector<int>> compartments_to_vector(const std::vector<Compartments>& cmps_vec)
{
std::vector<std::vector<int>> _temp;

for(auto cmps : cmps_vec)
{
_temp.push_back({cmps.S, cmps.E, cmps.E_t, cmps.I_p,
cmps.I_t, cmps.I1, cmps.I2, cmps.I3,
cmps.I4, cmps.I_s1, cmps.I_s2, cmps.I_s3,
cmps.I_s4, cmps.H, cmps.R, cmps.D});
}

return _temp;
}

} // namespace Model
} // namespace EERAModel
12 changes: 0 additions & 12 deletions src/ModelCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,5 @@ std::vector<int> ComputeAgeNums(int shb_id, int Npop, int N_hcw, const Observati
*/
std::vector<params> BuildFixedParameters(unsigned int size, params parameters);

/**
* @brief Convert Vector of Compartments struct to a vector of integers
*
* NOTE: This is a temporary function to allow compatibility
* converts the Compartments struct to a vector of integers
*
* @param cmps_vec Vector of compartments struct containing population per category
*
* @return Vector of population counters
*/
std::vector<std::vector<int>> compartments_to_vector(const std::vector<Compartments>& cmps_vec);

} // namespace Model
} // namespace EERAModel
52 changes: 26 additions & 26 deletions src/ModelTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@

namespace EERAModel {

/**
* @brief Structure containing counters for different population categories
*
* Integers to count the number of people within the different compartments within the model
*/
struct Compartments
{
int S = 0; /*!< Number of susceptible individuals (not infected). */
int E = 0; /*!< Number of infected individuals but not yet infectious (exposed). */
int E_t = 0; /*!< Number of exposed individuals and tested positive. */
int I_p = 0; /*!< Number of infected and infectious symptomatic individuals but at pre-clinical stage (show yet no symptoms). */
int I_t = 0; /*!< Number of tested positive individuals that infectious. */
int I1 = 0; /*!< Number of infected and infectious asymptomatic individuals: first stage. */
int I2 = 0; /*!< Number of infected and infectious asymptomatic individuals: second stage. */
int I3 = 0; /*!< Number of infected and infectious asymptomatic individuals: third stage. */
int I4 = 0; /*!< Number of infected and infectious asymptomatic individuals: last stage. */
int I_s1 = 0; /*!< Number of infected and infectious symptomatic individuals: first stage. */
int I_s2 = 0; /*!< Number of infected and infectious symptomatic individuals: second stage. */
int I_s3 = 0; /*!< Number of infected and infectious symptomatic individuals: thrid stage. */
int I_s4 = 0; /*!< Number of infected and infectious symptomatic individuals: last stage. */
int H = 0; /*!< Number of infected individuals that are hospitalised. */
int R = 0; /*!< Number of infected individuals that are recovered from infection. */
int D = 0; /*!< Number of dead individuals due to disease. */
};

/**
* @brief Structure for particles generated during inference
*/
Expand All @@ -17,7 +42,7 @@ struct particle {
std::vector<int> simu_outs;
std::vector<int> hospital_death_outs;
std::vector<int> death_outs;
std::vector< std::vector<int> > end_comps;
std::vector< Compartments > end_comps;
};

/**
Expand Down Expand Up @@ -114,31 +139,6 @@ struct AgeGroupData
std::vector<double> pf_byage; /*!< Frailty Probability by age. */
};

/**
* @brief Structure containing counters for different population categories
*
* Integers to count the number of people within the different compartments within the model
*/
struct Compartments
{
int S = 0; /*!< Number of susceptible individuals (not infected). */
int E = 0; /*!< Number of infected individuals but not yet infectious (exposed). */
int E_t = 0; /*!< Number of exposed individuals and tested positive. */
int I_p = 0; /*!< Number of infected and infectious symptomatic individuals but at pre-clinical stage (show yet no symptoms). */
int I_t = 0; /*!< Number of tested positive individuals that infectious. */
int I1 = 0; /*!< Number of infected and infectious asymptomatic individuals: first stage. */
int I2 = 0; /*!< Number of infected and infectious asymptomatic individuals: second stage. */
int I3 = 0; /*!< Number of infected and infectious asymptomatic individuals: third stage. */
int I4 = 0; /*!< Number of infected and infectious asymptomatic individuals: last stage. */
int I_s1 = 0; /*!< Number of infected and infectious symptomatic individuals: first stage. */
int I_s2 = 0; /*!< Number of infected and infectious symptomatic individuals: second stage. */
int I_s3 = 0; /*!< Number of infected and infectious symptomatic individuals: thrid stage. */
int I_s4 = 0; /*!< Number of infected and infectious symptomatic individuals: last stage. */
int H = 0; /*!< Number of infected individuals that are hospitalised. */
int R = 0; /*!< Number of infected individuals that are recovered from infection. */
int D = 0; /*!< Number of dead individuals due to disease. */
};

/**
* @brief Structure to hold status objects
*
Expand Down