The simulation was created by researchers at Imperial and is one source used by the UK government to guide policy. It was open-sourced at https://github.com/mrc-ide/covid-sim relatively recently. It is relatively untested, has code translated from Pascal to C and people are whingeing hard that any political decisions have been made off the back of it.
It's a huge project, and this is definitely not going to fully reimplement it, but I thought I'd do a bit of porting to see if it turned up any odd behaviour, so I can raise it as an issue. This is also an opportunity for bit of Rust (always welcome!).
- Read the project documentation ✓
- Write a high-level overview of function calls within CovidSim.cpp ✓
- Build list of outstanding queries related to docs/CovidSim.cpp ✓
- Summarise contents of code files ✓
- Jot down initial architecture ideas for new implementation ✓
- Code to set up a micro-cell based population grid. ✓
- Code to run a single proximity-transmission update step.
- Code to run a configurable number of steps.
- Code to run a number of realisations each of n steps.
Ongoing
- Build summary of types and their uses (WIP)
- Revisit outstanding queries
- Entrypoint: main
- Parses command line parameters (and referenced files) into a global parameters object, P
- Calculates further reference values in ReadParams() and reads parameters from param files
- Configure data to output
- Configure kernel resolution
- Include transmission within houses modelling (or not)
- Include transmission via shared administrative units (or not)
- Include age-specific factors
- Include house-proximity-based transmission
- Include Airport/hotel modelling (calls ReadAirTravel)
- Include place-based transmission
- Model seasonality
- Configure initial infections
- Model disease progression and infectiousness profile (optionally including age-specific symptoms and severity)
- Configure interventions (Treatment, vaccination, social distancing, restricted movement, household quarantine, contact tracing, place closure, admin unit closure, airport closure)
- Calls into readInterventions which parses XML files and stores various data
- Model impact of public (or school?) holidays
- Vary efficacy of interventions over time
- Model Key worker households
- Model sensible age makeup of households
- Initialises the model SetupModel. Optionally setup Interventions, AirTravel
- Initial values for State, AdUnits, StateT (thread State?), Hosts, Cells, Households, MCells, Places, InfEventLog
- Initial state for various variables in params object P (for variables that vary over time)
- Calls SeedInfection,
- Models initial infection either all in one location, in random locations or some other criteria around adUnits and population density
- A variable m is used as some kind of sanity check for all methods
- which calls out to DoInfect (Update.cpp) which transitions people from susceptible to infected
- In turn may call out to doIncub, doCase, doRecover, but not at this point since time = 0
- For each realisation, sets data seeds and calls RunModel a number of times
- Option to interrupt at any point. Option to run until a number of infections is reached, option to regenerate random number seeds
- Model infected airport arrivals (uses SeedInfection)
- Model false Positives
- Call InfectSweep, IncubRecoverySweep, DigitalContactTracingSweep, TreatSweep, TravelReturnSweep (Sweep.cpp)
- Call SaveSnapshot (optionally) - a load of lines written to a file with format ##
- Call UpdateProbs - updates lots of data via CellLookup
- For each realisation, optionally calls SaveResults, always calls SaveEvents
- For overall run, optionally outputs origin/destination matrix. Calls RecordSample now if not called for every run.
- calls SaveSummaryResults
- Performs a number of 'realisations' of the model
- Uses an InterruptRun boolean for early exit
- setall uses two longs to seed all random number generators (Rand.cpp from Pascal)
- origin destination matrix; is this to show where spread is predicted from/to?
- option for coordinates to be UTM (Universal Transverse Mercator = longitude/latitude)
- Seems to allow predefined data generation seeds?
- Seems to allow snapshotting and loading model state?
- Why is NumRealisations used so oddly (adding/subtracting 1)?
- RunModel() returns true once according to comments, to reset holiday time. HOw does this work?
- Rand.cpp mltmod mentions running on a 32bit machine in a comment. Is 64bit handled?
- What do 'holidays' cover? public/school?
- What is the third initial seeding mode modelling?
- What does CellLookup reference?
- Why is DAYS_PER_YEAR defined to 364 (Constants.h)?
- NUM_PLACE_TYPES (Country.h) is 4, and the places are: primary/secondary schools, universities and offices. Shouldn't there be other places too? Supermarkets?!
- Is it a problem that the cached values for trig functions are integer-degrees only? Limited resolution?
- Are the kernels square? Shouldn't they be circular?
- Kernel resolution - high-res option 1600 times higher - when does it get used (and why ever use the low-res one)?
- What is Kernel 'shape'? e.g. P.AirportKernelShape. Seems like a scale factor with different meanings for different kernel types.
- CACHE_LINE_SIZE 64 - how important is this? Presumably it varies between machines
- DoInitUpdateProbs - set in SetupModel, triggers UpdateProbs. What does the criterion for doing this again mean?
(lcI - cI) > 0.2
(CovidSim.cpp) - Comment in Update.cpp starting "currently commenting this out" relating to household digital contact tracting. Is this fine?
- P.NC (int) is initialised to -1 in CovidSim.cpp but SetupModel runs P.ncw = P.nch = (int)sqrt((double)P.NC); P.NC = P.ncw * P.nch; if !P.DoHeteroDensity.
- what is the significance of size of P.InvLifeExpecDist[MAX_ADUNITS][1001]
- there is something like a TODO in Model.h which states DONE by only some points - see
above quantities need to be amended in following parts of code:
. - what are the queues in the State (struct PopVar) used for?
- InitKernel (Kernels.cpp): DoPlaces parameter is unreferenced, and norm parameter is always 1.0 (no effect)
- SetupModel.cpp "Binary densi\zty file should contain %i cells." remove \z
- SetupModel.cpp reads into P.BinFileLen to inspect a magic number in first 4 bytes of density file. Use a different variable.
- InitProbs() declaration in SetupModel.h, but implementation in CovidSim.cpp
- input-params.txt has a leftover merge conflict marker
- SetupModel.cpp "Cell %i has adunits < 0 (indexing AdUnits)\n" logging should refer to microcells
- SetupModel.cpp "Unable to allocate cell storage\n" logging should refer to microcells
- remove obstructive mcl variable in SetupPopulation (SetupModel.cpp) *** resolved to here
- Inconsistent use of brackets to assign default value to P.LongitudeCutLine
- Simpler to always compare <= maximum of the SpatialBoundingBox and not add the fudge factor?
- Remove GotNR CLI arg - read directly to P.NumRealisations
- unpack complex conditional in CovidSim.cpp
if(((!P.DoAlertTriggerAfterInterv) && (trigAlert >= P.PreControlClusterIdCaseThreshold))
- error on more than MAXINTFILE /I: options supplied (overflows array)
- assert no spaces when reading SaveSnapshot parameter?
- log warning (or panic?) if max num threads CLI arg supplied but _OPENMP not set
- use local variable for number of people in cell?
- SetupModel typo infectionz
- lot of renaming around nested loops at l = ((j / P.get_number_of_micro_cells_high()) / P.NMCL) * P.nch + ((j % P.get_number_of_micro_cells_high()) / P.NMCL)
- RunModel rename continueEvents
- Pull GetInputParameter function declarations out into a CovidSim header file