covid-sim
CovidSim.cpp
1 /*
2 (c) 2004-20 Neil Ferguson, Imperial College London (neil.ferguson@imperial.ac.uk)
3 */
4 
5 #include <errno.h>
6 #include <stddef.h>
7 
8 #include "CovidSim.h"
9 #include "BinIO.h"
10 #include "Rand.h"
11 #include "Error.h"
12 #include "Dist.h"
13 #include "Kernels.h"
14 #include "Bitmap.h"
15 #include "Model.h"
16 #include "Param.h"
17 #include "SetupModel.h"
18 #include "ModelMacros.h"
19 #include "InfStat.h"
20 #include "CalcInfSusc.h"
21 #include "Update.h"
22 #include "Sweep.h"
23 
24 #ifdef _OPENMP
25 #include <omp.h>
26 #endif // _OPENMP
27 
28 // Use the POSIX name for case-insensitive string comparison: strcasecmp.
29 #ifdef _WIN32
30 // Windows calls it _stricmp so make strcasecmp an alias.
31 #include <string.h>
32 #define strcasecmp _stricmp
33 #else
34 #include <strings.h>
35 #endif
36 
37 void ReadParams(char*, char*);
38 void ReadInterventions(char*);
39 int GetXMLNode(FILE*, const char*, const char*, char*, int);
40 void ReadAirTravel(char*);
41 void InitModel(int); //adding run number as a parameter for event log: ggilani - 15/10/2014
42 void SeedInfection(double, int*, int, int); //adding run number as a parameter for event log: ggilani - 15/10/2014
43 int RunModel(int); //adding run number as a parameter for event log: ggilani - 15/10/2014
44 
45 void SaveDistribs(void);
46 void SaveOriginDestMatrix(void); //added function to save origin destination matrix so it can be done separately to the main results: ggilani - 13/02/15
47 void SaveResults(void);
48 void SaveSummaryResults(void);
49 void SaveRandomSeeds(void); //added this function to save random seeds for each run: ggilani - 09/03/17
50 void SaveEvents(void); //added this function to save infection events from all realisations: ggilani - 15/10/14
51 void LoadSnapshot(void);
52 void SaveSnapshot(void);
53 void RecordInfTypes(void);
54 void RecordSample(double, int);
55 
56 void CalcOriginDestMatrix_adunit(void); //added function to calculate origin destination matrix: ggilani 28/01/15
57 
58 int GetInputParameter(FILE*, FILE*, const char*, const char*, void*, int, int, int);
59 int GetInputParameter2(FILE*, FILE*, const char*, const char*, void*, int, int, int);
60 int GetInputParameter3(FILE*, const char*, const char*, void*, int, int, int);
61 
62 void SetICDF(double* icdf, double startValue);
63 
64 
68 
69 Param P;
70 Person* Hosts;
71 Household* Households;
72 PopVar State, StateT[MAX_NUM_THREADS];
73 Cell* Cells; // Cells[i] is the i'th cell
74 Cell ** CellLookup; // CellLookup[i] is a pointer to the i'th populated cell
75 Microcell* Mcells, ** McellLookup;
76 Place** Places;
77 AdminUnit AdUnits[MAX_ADUNITS];
81 Results* TimeSeries, * TSMean, * TSVar, * TSMeanNE, * TSVarNE, * TSMeanE, * TSVarE;
82 Airport* Airports;
83 BitmapHeader* bmh;
84 //added declaration of pointer to events log: ggilani - 10/10/2014
85 Events* InfEventLog;
86 int nEvents;
87 
88 double inftype[INFECT_TYPE_MASK], inftype_av[INFECT_TYPE_MASK], infcountry[MAX_COUNTRIES], infcountry_av[MAX_COUNTRIES], infcountry_num[MAX_COUNTRIES];
89 double indivR0[MAX_SEC_REC][MAX_GEN_REC], indivR0_av[MAX_SEC_REC][MAX_GEN_REC];
90 double inf_household[MAX_HOUSEHOLD_SIZE + 1][MAX_HOUSEHOLD_SIZE + 1], denom_household[MAX_HOUSEHOLD_SIZE + 1];
91 double inf_household_av[MAX_HOUSEHOLD_SIZE + 1][MAX_HOUSEHOLD_SIZE + 1], AgeDist[NUM_AGE_GROUPS], AgeDist2[NUM_AGE_GROUPS];
92 double case_household[MAX_HOUSEHOLD_SIZE + 1][MAX_HOUSEHOLD_SIZE + 1], case_household_av[MAX_HOUSEHOLD_SIZE + 1][MAX_HOUSEHOLD_SIZE + 1];
93 double PropPlaces[NUM_AGE_GROUPS * AGE_GROUP_WIDTH][NUM_PLACE_TYPES];
94 double PropPlacesC[NUM_AGE_GROUPS * AGE_GROUP_WIDTH][NUM_PLACE_TYPES], AirTravelDist[MAX_DIST];
95 double PeakHeightSum, PeakHeightSS, PeakTimeSum, PeakTimeSS;
96 
97 // These allow up to about 2 billion people per pixel, which should be ample.
98 int32_t *bmPopulation; // The population in each bitmap pixel. Special value -1 means "country boundary"
99 int32_t *bmInfected; // The number of infected people in each bitmap pixel.
100 int32_t *bmRecovered; // The number of recovered people in each bitmap pixel.
101 int32_t *bmTreated; // The number of treated people in each bitmap pixel.
102 
103 char OutFile[1024], OutFileBase[1024], OutDensFile[1024], SnapshotLoadFile[1024], SnapshotSaveFile[1024], AdunitFile[1024];
104 
105 int ns, DoInitUpdateProbs, InterruptRun = 0;
106 int PlaceDistDistrib[NUM_PLACE_TYPES][MAX_DIST], PlaceSizeDistrib[NUM_PLACE_TYPES][MAX_PLACE_SIZE];
107 
108 
109 /* int NumPC,NumPCD; */
110 const int MAXINTFILE = 10;
111 
112 /* default start value for icdf arrays */
113 const int ICDF_START = 100;
114 
115 int main(int argc, char* argv[])
116 {
117  char ParamFile[1024]{}, DensityFile[1024]{}, NetworkFile[1024]{}, AirTravelFile[1024]{}, SchoolFile[1024]{}, RegDemogFile[1024]{}, InterventionFile[MAXINTFILE][1024]{}, PreParamFile[1024]{}, buf[2048]{}, * sep;
118  int i, GotP, GotPP, GotO, GotL, GotS, GotAP, GotScF, GotNR, Perr, cl;
119 
121  GotP = GotO = GotL = GotS = GotAP = GotScF = GotPP = GotNR = 0;
122 
123  Perr = 0;
124  fprintf(stderr, "sizeof(int)=%i sizeof(long)=%i sizeof(float)=%i sizeof(double)=%i sizeof(unsigned short int)=%i sizeof(int *)=%i\n", (int)sizeof(int), (int)sizeof(long), (int)sizeof(float), (int)sizeof(double), (int)sizeof(unsigned short int), (int)sizeof(int*));
125  cl = clock();
126 
127  // Default bitmap format is platform dependent.
128 #if defined(IMAGE_MAGICK) || defined(_WIN32)
129  P.BitmapFormat = BF_PNG;
130 #else
131  P.BitmapFormat = BF_BMP;
132 #endif
133 
135 
136  if (argc < 7) Perr = 1;
137  else
138  {
140  i = argc - 4;
141  sscanf(argv[i], "%i", &P.setupSeed1);
142  sscanf(argv[i + 1], "%i", &P.setupSeed2);
143  sscanf(argv[i + 2], "%i", &P.runSeed1);
144  sscanf(argv[i + 3], "%i", &P.runSeed2);
145 
147  P.PlaceCloseIndepThresh = P.LoadSaveNetwork = P.DoHeteroDensity = P.DoPeriodicBoundaries = P.DoSchoolFile = P.DoAdunitDemog = P.OutputDensFile = P.MaxNumThreads = P.DoInterventionFile = 0;
148  P.PreControlClusterIdCaseThreshold = 0;
149  P.R0scale = 1.0;
150  P.KernelOffsetScale = P.KernelPowerScale = 1.0; //added this so that kernel parameters are only changed if input from the command line: ggilani - 15/10/2014
151  P.DoSaveSnapshot = P.DoLoadSnapshot = 0;
152 
154  for (i = 1; i < argc - 4; i++)
155  {
156  if ((argv[i][0] != '/') && ((argv[i][2] != ':') && (argv[i][3] != ':'))) Perr = 1;
157  if (argv[i][1] == 'P' && argv[i][2] == ':')
158  {
159  GotP = 1;
160  sscanf(&argv[i][3], "%s", ParamFile);
161  }
162  else if (argv[i][1] == 'O' && argv[i][2] == ':')
163  {
164  GotO = 1;
165  sscanf(&argv[i][3], "%s", OutFileBase);
166  }
167  else if (argv[i][1] == 'D' && argv[i][2] == ':')
168  {
169  sscanf(&argv[i][3], "%s", DensityFile);
170  P.DoHeteroDensity = 1;
171  P.DoPeriodicBoundaries = 0;
172  }
173  else if (argv[i][1] == 'A' && argv[i][2] == ':')
174  {
175  sscanf(&argv[i][3], "%s", AdunitFile);
176  }
177  else if (argv[i][1] == 'L' && argv[i][2] == ':')
178  {
179  GotL = 1;
180  P.LoadSaveNetwork = 1;
181  sscanf(&argv[i][3], "%s", NetworkFile);
182  }
183  else if (argv[i][1] == 'S' && argv[i][2] == ':')
184  {
185  P.LoadSaveNetwork = 2;
186  GotS = 1;
187  sscanf(&argv[i][3], "%s", NetworkFile);
188  }
189  else if (argv[i][1] == 'R' && argv[i][2] == ':')
190  {
191  sscanf(&argv[i][3], "%lf", &P.R0scale);
192  }
193  else if (argv[i][1] == 'N' && argv[i][2] == 'R' && argv[i][3] == ':')
194  {
195  sscanf(&argv[i][4], "%i", &GotNR);
196  }
197  else if (argv[i][1] == 'K' && argv[i][2] == 'P' && argv[i][3] == ':') //added Kernel Power and Offset scaling so that it can easily be altered from the command line in order to vary the kernel quickly: ggilani - 15/10/14
198  {
199  sscanf(&argv[i][4], "%lf", &P.KernelPowerScale);
200  }
201  else if (argv[i][1] == 'K' && argv[i][2] == 'O' && argv[i][3] == ':')
202  {
203  sscanf(&argv[i][4], "%lf", &P.KernelOffsetScale);
204  }
205  else if (argv[i][1] == 'C' && argv[i][2] == 'L' && argv[i][3] == 'P' && argv[i][4] == '1' && argv[i][5] == ':') // generic command line specified param - matched to #1 in param file
206  {
207  sscanf(&argv[i][6], "%lf", &P.clP1);
208  }
209  else if (argv[i][1] == 'C' && argv[i][2] == 'L' && argv[i][3] == 'P' && argv[i][4] == '2' && argv[i][5] == ':') // generic command line specified param - matched to #2 in param file
210  {
211  sscanf(&argv[i][6], "%lf", &P.clP2);
212  }
213  else if(argv[i][1] == 'C' && argv[i][2] == 'L' && argv[i][3] == 'P' && argv[i][4] == '3' && argv[i][5] == ':') // generic command line specified param - matched to #3 in param file
214  {
215  sscanf(&argv[i][6], "%lf", &P.clP3);
216  }
217  else if(argv[i][1] == 'C' && argv[i][2] == 'L' && argv[i][3] == 'P' && argv[i][4] == '4' && argv[i][5] == ':') // generic command line specified param - matched to #4 in param file
218  {
219  sscanf(&argv[i][6], "%lf", &P.clP4);
220  }
221  else if(argv[i][1] == 'C' && argv[i][2] == 'L' && argv[i][3] == 'P' && argv[i][4] == '5' && argv[i][5] == ':') // generic command line specified param - matched to #5 in param file
222  {
223  sscanf(&argv[i][6], "%lf", &P.clP5);
224  }
225  else if(argv[i][1] == 'C' && argv[i][2] == 'L' && argv[i][3] == 'P' && argv[i][4] == '6' && argv[i][5] == ':') // generic command line specified param - matched to #6 in param file
226  {
227  sscanf(&argv[i][6], "%lf", &P.clP6);
228  }
229  else if (argv[i][1] == 'A' && argv[i][2] == 'P' && argv[i][3] == ':')
230  {
231  GotAP = 1;
232  sscanf(&argv[i][3], "%s", AirTravelFile);
233  }
234  else if (argv[i][1] == 's' && argv[i][2] == ':')
235  {
236  GotScF = 1;
237  sscanf(&argv[i][3], "%s", SchoolFile);
238  }
239  else if (argv[i][1] == 'T' && argv[i][2] == ':')
240  {
241  sscanf(&argv[i][3], "%i", &P.PreControlClusterIdCaseThreshold);
242  }
243  else if (argv[i][1] == 'C' && argv[i][2] == ':')
244  {
245  sscanf(&argv[i][3], "%i", &P.PlaceCloseIndepThresh);
246  }
247  else if (argv[i][1] == 'd' && argv[i][2] == ':')
248  {
249  P.DoAdunitDemog = 1;
250  sscanf(&argv[i][3], "%s", RegDemogFile);
251  }
252  else if (argv[i][1] == 'c' && argv[i][2] == ':')
253  {
254  sscanf(&argv[i][3], "%i", &P.MaxNumThreads);
255  }
256  else if (argv[i][1] == 'M' && argv[i][2] == ':')
257  {
258  P.OutputDensFile = 1;
259  sscanf(&argv[i][3], "%s", OutDensFile);
260  }
261  else if (argv[i][1] == 'I' && argv[i][2] == ':')
262  {
263  sscanf(&argv[i][3], "%s", InterventionFile[P.DoInterventionFile]);
264  P.DoInterventionFile++;
265  }
266  else if (argv[i][1] == 'L' && argv[i][2] == 'S' && argv[i][3] == ':')
267  {
268  sscanf(&argv[i][4], "%s", SnapshotLoadFile);
269  P.DoLoadSnapshot = 1;
270  }
271  else if (argv[i][1] == 'P' && argv[i][2] == 'P' && argv[i][3] == ':')
272  {
273  sscanf(&argv[i][4], "%s", PreParamFile);
274  GotPP = 1;
275  }
276  else if (argv[i][1] == 'S' && argv[i][2] == 'S' && argv[i][3] == ':')
277  {
278  sscanf(&argv[i][4], "%s", buf);
279  fprintf(stderr, "### %s\n", buf);
280  sep = strchr(buf, ',');
281  if (!sep)
282  Perr = 1;
283  else
284  {
285  P.DoSaveSnapshot = 1;
286  *sep = ' ';
287  sscanf(buf, "%lf %s", &(P.SnapshotSaveTime), SnapshotSaveFile);
288  }
289  }
290  else if (argv[i][1] == 'B' && argv[i][2] == 'M' && argv[i][3] == ':')
291  {
292  sscanf(&argv[i][4], "%s", buf);
293  if (strcasecmp(buf, "png") == 0)
294  {
295 #if defined(IMAGE_MAGICK) || defined(_WIN32)
296  P.BitmapFormat = BF_PNG;
297 #else
298  fprintf(stderr, "PNG Bitmaps not supported - please build with Image Magic or WIN32 support\n");
299  Perr = 1;
300 #endif
301  }
302  else if (strcasecmp(buf, "bmp") == 0)
303  {
304  P.BitmapFormat = BF_BMP;
305  }
306  else
307  {
308  fprintf(stderr, "Unrecognised bitmap format: %s\n", buf);
309  Perr = 1;
310  }
311  }
312  }
313  if (((GotS) && (GotL)) || (!GotP) || (!GotO)) Perr = 1;
314  }
315 
317 
318  sprintf(OutFile, "%s", OutFileBase);
319 
320  fprintf(stderr, "Param=%s\nOut=%s\nDens=%s\n", ParamFile, OutFile, DensityFile);
321  fprintf(stderr, "Bitmap Format = *.%s\n", P.BitmapFormat == BF_PNG ? "png" : "bmp");
322  if (Perr) ERR_CRITICAL_FMT("Syntax:\n%s /P:ParamFile /O:OutputFile [/AP:AirTravelFile] [/s:SchoolFile] [/D:DensityFile] [/L:NetworkFileToLoad | /S:NetworkFileToSave] [/R:R0scaling] SetupSeed1 SetupSeed2 RunSeed1 RunSeed2\n", argv[0]);
323 
327 
328 #ifdef _OPENMP
329  P.NumThreads = omp_get_max_threads();
330  if ((P.MaxNumThreads > 0) && (P.MaxNumThreads < P.NumThreads)) P.NumThreads = P.MaxNumThreads;
331  if (P.NumThreads > MAX_NUM_THREADS)
332  {
333  fprintf(stderr, "Assigned number of threads (%d) > MAX_NUM_THREADS (%d)\n", P.NumThreads, MAX_NUM_THREADS);
334  P.NumThreads = MAX_NUM_THREADS;
335  }
336  fprintf(stderr, "Using %d threads\n", P.NumThreads);
337  omp_set_num_threads(P.NumThreads);
338 
339 #pragma omp parallel default(shared)
340  {
341  fprintf(stderr, "Thread %i initialised\n", omp_get_thread_num());
342  }
343  /* fprintf(stderr,"int=%i\tfloat=%i\tdouble=%i\tint *=%i\n",(int) sizeof(int),(int) sizeof(float),(int) sizeof(double),(int) sizeof(int *)); */
344 #else
345  P.NumThreads = 1;
346 #endif
347  if (!GotPP)
348  {
349  sprintf(PreParamFile, ".." DIRECTORY_SEPARATOR "Pre_%s", ParamFile);
350  }
351 
355 
356 
357  P.NumRealisations = GotNR;
358  ReadParams(ParamFile, PreParamFile);
359  if (GotScF) P.DoSchoolFile = 1;
360  if (P.DoAirports)
361  {
362  if (!GotAP) ERR_CRITICAL_FMT("Syntax:\n%s /P:ParamFile /O:OutputFile /AP:AirTravelFile [/s:SchoolFile] [/D:DensityFile] [/L:NetworkFileToLoad | /S:NetworkFileToSave] [/R:R0scaling] SetupSeed1 SetupSeed2 RunSeed1 RunSeed2\n", argv[0]);
363  ReadAirTravel(AirTravelFile);
364  }
365 
369 
371  SetupModel(DensityFile, NetworkFile, SchoolFile, RegDemogFile);
372 
373  for (i = 0; i < MAX_ADUNITS; i++) AdUnits[i].NI = 0;
374  if (P.DoInterventionFile > 0)
375  for (i = 0; i < P.DoInterventionFile; i++)
376  ReadInterventions(InterventionFile[i]);
377 
378  fprintf(stderr, "Model setup in %lf seconds\n", ((double)(clock() - cl)) / CLOCKS_PER_SEC);
379 
380  //print out number of calls to random number generator
381 
385 
386 
387  P.NRactE = P.NRactNE = 0;
388  for (i = 0; (i < P.NumRealisations) && (P.NRactNE < P.NumNonExtinctRealisations) ; i++)
389  {
390  if (P.NumRealisations > 1)
391  {
392  sprintf(OutFile, "%s.%i", OutFileBase, i);
393  fprintf(stderr, "Realisation %i of %i (time=%lf nr_ne=%i)\n", i + 1, P.NumRealisations,((double)(clock() - cl)) / CLOCKS_PER_SEC, P.NRactNE);
394  }
395  P.StopCalibration = P.ModelCalibIteration = 0; // needed for calibration to work for multiple realisations
396  P.PreControlClusterIdHolOffset = 0; // needed for calibration to work for multiple realisations
397  P.PreControlClusterIdCaseThreshold = P.PreControlClusterIdCaseThreshold2; // needed for calibration to work for multiple realisations
398  P.SeedingScaling = 1.0; // needed for calibration to work for multiple realisations
400  if (i == 0 || (P.ResetSeeds && P.KeepSameSeeds))
401  {
402  P.nextRunSeed1 = P.runSeed1;
403  P.nextRunSeed2 = P.runSeed2;
404  }
405  if (P.ResetSeeds) {
406  //save these seeds to file
407  SaveRandomSeeds();
408  }
409  // Now that we have set P.nextRunSeed* ready for the run, we need to save the values in case
410  // we need to reinitialise the RNG after the run is interrupted.
411  int32_t thisRunSeed1 = P.nextRunSeed1;
412  int32_t thisRunSeed2 = P.nextRunSeed2;
413 // if (i == 0 || P.ResetSeeds)
414  setall(&P.nextRunSeed1, &P.nextRunSeed2);
415 
417  InitModel(i); //passing run number into RunModel so we can save run number in the infection event log: ggilani - 15/10/2014
418  if (P.DoLoadSnapshot) LoadSnapshot();
419  while (RunModel(i))
420  { // has been interrupted to reset holiday time. Note that this currently only happens in the first run, regardless of how many realisations are being run.
421  int32_t tmp1 = thisRunSeed1;
422  int32_t tmp2 = thisRunSeed2;
423  setall(&tmp1, &tmp2); // reset random number seeds to generate same run again after calibration.
424  InitModel(i);
425  }
426  if (P.OutputNonSummaryResults)
427  {
428  if (((!TimeSeries[P.NumSamples - 1].extinct) || (!P.OutputOnlyNonExtinct)) && (P.OutputEveryRealisation))
429  {
430  SaveResults();
431  }
432  }
433  if ((P.DoRecordInfEvents) && (P.RecordInfEventsPerRun == 1))
434  {
435  SaveEvents();
436  }
437  }
438  sprintf(OutFile, "%s", OutFileBase);
439 
440  //Calculate origin destination matrix if needed
441  if ((P.DoAdUnits) && (P.DoOriginDestinationMatrix))
442  {
443  CalcOriginDestMatrix_adunit();
444  SaveOriginDestMatrix();
445  }
446 
447  P.NRactual = P.NRactNE;
448  TSMean = TSMeanNE; TSVar = TSVarNE;
449  if ((P.DoRecordInfEvents) && (P.RecordInfEventsPerRun == 0))
450  {
451  SaveEvents();
452  }
453  sprintf(OutFile, "%s.avNE", OutFileBase);
454  SaveSummaryResults();
455  P.NRactual = P.NRactE;
456  TSMean = TSMeanE; TSVar = TSVarE;
457  sprintf(OutFile, "%s.avE", OutFileBase);
458  //SaveSummaryResults();
459 
460  Bitmap_Finalise();
461 
462  fprintf(stderr, "Extinction in %i out of %i runs\n", P.NRactE, P.NRactNE + P.NRactE);
463  fprintf(stderr, "Model ran in %lf seconds\n", ((double)(clock() - cl)) / CLOCKS_PER_SEC);
464  fprintf(stderr, "Model finished\n");
465 }
466 
467 
468 void ReadParams(char* ParamFile, char* PreParamFile)
469 {
470  FILE* ParamFile_dat, * PreParamFile_dat, * AdminFile_dat;
471  double s, t, AgeSuscScale;
472  int i, j, k, f, nc, na;
473  char CountryNameBuf[128 * MAX_COUNTRIES], AdunitListNamesBuf[128 * MAX_ADUNITS];
474 
475  char* CountryNames[MAX_COUNTRIES];
476  for (i = 0; i < MAX_COUNTRIES; i++) { CountryNames[i] = CountryNameBuf + 128 * i; CountryNames[i][0] = 0; }
477  char* AdunitListNames[MAX_ADUNITS];
478  for (i = 0; i < MAX_ADUNITS; i++) { AdunitListNames[i] = AdunitListNamesBuf + 128 * i; AdunitListNames[i][0] = 0; }
479  if (!(ParamFile_dat = fopen(ParamFile, "rb"))) ERR_CRITICAL("Unable to open parameter file\n");
480  PreParamFile_dat = fopen(PreParamFile, "rb");
481  if (!(AdminFile_dat = fopen(AdunitFile, "rb"))) AdminFile_dat = ParamFile_dat;
482  if (!GetInputParameter2(ParamFile_dat, AdminFile_dat, "Longitude cut line", "%lf", (void*)&(P.LongitudeCutLine), 1, 1, 0)) {
483  P.LongitudeCutLine = -360.0;
484  }
485  AgeSuscScale = 1.0;
486  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Update timestep", "%lf", (void*)&(P.TimeStep), 1, 1, 0);
487  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Sampling timestep", "%lf", (void*)&(P.SampleStep), 1, 1, 0);
488  if (P.TimeStep > P.SampleStep) ERR_CRITICAL("Update step must be smaller than sampling step\n");
489  t = ceil(P.SampleStep / P.TimeStep - 1e-6);
490  P.UpdatesPerSample = (int)t;
491  P.TimeStep = P.SampleStep / t;
492  P.TimeStepsPerDay = ceil(1.0 / P.TimeStep - 1e-6);
493  fprintf(stderr, "Update step = %lf\nSampling step = %lf\nUpdates per sample=%i\nTimeStepsPerDay=%lf\n", P.TimeStep, P.SampleStep, P.UpdatesPerSample, P.TimeStepsPerDay);
494  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Sampling time", "%lf", (void*)&(P.SampleTime), 1, 1, 0);
495  P.NumSamples = 1 + (int)ceil(P.SampleTime / P.SampleStep);
496  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Population size", "%i", (void*)&(P.PopSize), 1, 1, 0);
497  if (P.NumRealisations == 0)
498  {
499  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Number of realisations", "%i", (void*)&(P.NumRealisations), 1, 1, 0);
500  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of non-extinct realisations", "%i", (void*)&(P.NumNonExtinctRealisations), 1, 1, 0)) P.NumNonExtinctRealisations = P.NumRealisations;
501  }
502  else
504  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Maximum number of cases defining small outbreak", "%i", (void*) & (P.SmallEpidemicCases), 1, 1, 0)) P.SmallEpidemicCases = -1;
505 
506  P.NC = -1;
507  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Number of micro-cells per spatial cell width", "%i", (void*) & (P.NMCL), 1, 1, 0);
508  //added parameter to reset seeds after every run
509  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Reset seeds for every run", "%i", (void*) & (P.ResetSeeds), 1, 1, 0)) P.ResetSeeds = 0;
510  if (P.ResetSeeds)
511  {
512  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Keep same seeds for every run", "%i", (void*) & (P.KeepSameSeeds), 1, 1, 0)) P.KeepSameSeeds = 0; //added this to control which seeds are used: ggilani 27/11/19
513  }
514  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Reset seeds after intervention", "%i", (void*) & (P.ResetSeedsPostIntervention), 1, 1, 0)) P.ResetSeedsPostIntervention = 0;
515  if (P.ResetSeedsPostIntervention)
516  {
517  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Time to reset seeds after intervention", "%i", (void*) & (P.TimeToResetSeeds), 1, 1, 0)) P.TimeToResetSeeds = 1000000;
518  }
519  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Include households", "%i", (void*) & (P.DoHouseholds), 1, 1, 0)) P.DoHouseholds = 1;
520 
521  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputAge" , "%i", (void*) & (P.OutputAge) , 1, 1, 0)) P.OutputAge = 1;
522  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputSeverityAdminUnit" , "%i", (void*) & (P.OutputSeverityAdminUnit) , 1, 1, 0)) P.OutputSeverityAdminUnit = 1;
523  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputSeverityAge" , "%i", (void*) & (P.OutputSeverityAge) , 1, 1, 0)) P.OutputSeverityAge = 1;
524  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputR0" , "%i", (void*) & (P.OutputR0) , 1, 1, 0)) P.OutputR0 = 0;
525  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputControls" , "%i", (void*) & (P.OutputControls) , 1, 1, 0)) P.OutputControls = 0;
526  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputCountry" , "%i", (void*) & (P.OutputCountry) , 1, 1, 0)) P.OutputCountry = 0;
527  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputAdUnitVar" , "%i", (void*) & (P.OutputAdUnitVar) , 1, 1, 0)) P.OutputAdUnitVar = 0;
528  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputHousehold" , "%i", (void*) & (P.OutputHousehold) , 1, 1, 0)) P.OutputHousehold = 0;
529  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputInfType" , "%i", (void*) & (P.OutputInfType) , 1, 1, 0)) P.OutputInfType = 0;
530  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputNonSeverity" , "%i", (void*) & (P.OutputNonSeverity) , 1, 1, 0)) P.OutputNonSeverity = 0;
531  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "OutputNonSummaryResults" , "%i", (void*) & (P.OutputNonSummaryResults) , 1, 1, 0)) P.OutputNonSummaryResults = 0;
532 
533  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Kernel resolution", "%i", (void*)&P.NKR, 1, 1, 0)) P.NKR = 4000000;
534  if (P.NKR < 2000000)
535  {
536  ERR_CRITICAL_FMT("[Kernel resolution] needs to be at least 2000000 - not %d", P.NKR);
537  }
538  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Kernel higher resolution factor", "%i", (void*)&P.NK_HR, 1, 1, 0)) P.NK_HR = P.NKR / 1600;
539  if (P.NK_HR < 1 || P.NK_HR >= P.NKR)
540  {
541  ERR_CRITICAL_FMT("[Kernel higher resolution factor] needs to be in range [1, P.NKR = %d) - not %d", P.NKR, P.NK_HR);
542  }
543 
544  if (P.DoHouseholds)
545  {
546  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Household size distribution", "%lf", (void*)P.HouseholdSizeDistrib[0], MAX_HOUSEHOLD_SIZE, 1, 0);
547  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Household attack rate", "%lf", (void*) & (P.HouseholdTrans), 1, 1, 0);
548  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Household transmission denominator power", "%lf", (void*) & (P.HouseholdTransPow), 1, 1, 0);
549  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Correct age distribution after household allocation to exactly match specified demography", "%i", (void*)&(P.DoCorrectAgeDist), 1, 1, 0)) P.DoCorrectAgeDist = 0;
550  }
551  else
552  {
553  P.HouseholdTrans = 0.0;
554  P.HouseholdTransPow = 1.0;
555  P.HouseholdSizeDistrib[0][0] = 1.0;
556  for (i = 1; i < MAX_HOUSEHOLD_SIZE; i++)
557  P.HouseholdSizeDistrib[0][i] = 0;
558  }
559  for (i = 1; i < MAX_HOUSEHOLD_SIZE; i++)
560  P.HouseholdSizeDistrib[0][i] = P.HouseholdSizeDistrib[0][i] + P.HouseholdSizeDistrib[0][i - 1];
561  for (i = 0; i < MAX_HOUSEHOLD_SIZE; i++)
562  P.HouseholdDenomLookup[i] = 1 / pow(((double)(i + 1)), P.HouseholdTransPow);
563  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Include administrative units within countries", "%i", (void*) & (P.DoAdUnits), 1, 1, 0)) P.DoAdUnits = 1;
564  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Divisor for countries", "%i", (void*) & (P.CountryDivisor), 1, 1, 0)) P.CountryDivisor = 1;
565  if (P.DoAdUnits)
566  {
567  char** AdunitNames, * AdunitNamesBuf;
568  if (!(AdunitNames = (char**)malloc(3 * ADUNIT_LOOKUP_SIZE * sizeof(char*)))) ERR_CRITICAL("Unable to allocate temp storage\n");
569  if (!(AdunitNamesBuf = (char*)malloc(3 * ADUNIT_LOOKUP_SIZE * 360 * sizeof(char)))) ERR_CRITICAL("Unable to allocate temp storage\n");
570 
571  for (i = 0; i < ADUNIT_LOOKUP_SIZE; i++)
572  {
573  P.AdunitLevel1Lookup[i] = -1;
574  AdunitNames[3 * i] = AdunitNamesBuf + 3 * i * 360;
575  AdunitNames[3 * i + 1] = AdunitNamesBuf + 3 * i * 360 + 60;
576  AdunitNames[3 * i + 2] = AdunitNamesBuf + 3 * i * 360 + 160;
577  }
578  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Divisor for level 1 administrative units", "%i", (void*)&(P.AdunitLevel1Divisor), 1, 1, 0)) P.AdunitLevel1Divisor = 1;
579  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Mask for level 1 administrative units", "%i", (void*)&(P.AdunitLevel1Mask), 1, 1, 0)) P.AdunitLevel1Mask = 1000000000;
580  na = (GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Codes and country/province names for admin units", "%s", (void*)AdunitNames, 3 * ADUNIT_LOOKUP_SIZE, 1, 0)) / 3;
581  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Number of countries to include", "%i", (void*)&nc, 1, 1, 0)) nc = 0;
582  if ((na > 0) && (nc>0))
583  {
584  P.DoAdunitBoundaries = (nc > 0);
585  nc = abs(nc);
586  GetInputParameter(PreParamFile_dat, AdminFile_dat, "List of names of countries to include", "%s", (nc > 1) ? ((void*)CountryNames) : ((void*)CountryNames[0]), nc, 1, 0);
587  P.NumAdunits = 0;
588  for (i = 0; i < na; i++)
589  for (j = 0; j < nc; j++)
590  if ((AdunitNames[3 * i + 1][0]) && (!strcmp(AdunitNames[3 * i + 1], CountryNames[j])) && (atoi(AdunitNames[3 * i]) != 0))
591  {
592  AdUnits[P.NumAdunits].id = atoi(AdunitNames[3 * i]);
593  P.AdunitLevel1Lookup[(AdUnits[P.NumAdunits].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor] = P.NumAdunits;
594  if (strlen(AdunitNames[3 * i + 1]) < 100) strcpy(AdUnits[P.NumAdunits].cnt_name, AdunitNames[3 * i + 1]);
595  if (strlen(AdunitNames[3 * i + 2]) < 200) strcpy(AdUnits[P.NumAdunits].ad_name, AdunitNames[3 * i + 2]);
596  // fprintf(stderr,"%i %s %s ## ",AdUnits[P.NumAdunits].id,AdUnits[P.NumAdunits].cnt_name,AdUnits[P.NumAdunits].ad_name);
597  P.NumAdunits++;
598  }
599  }
600  else
601  {
602  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Number of level 1 administrative units to include", "%i", (void*) & (P.NumAdunits), 1, 1, 0)) P.NumAdunits = 0;
603  if (P.NumAdunits > 0)
604  {
605  P.DoAdunitBoundaries = 1;
606  if (P.NumAdunits > MAX_ADUNITS) ERR_CRITICAL("MAX_ADUNITS too small.\n");
607  GetInputParameter(PreParamFile_dat, AdminFile_dat, "List of level 1 administrative units to include", "%s", (P.NumAdunits > 1) ? ((void*)AdunitListNames) : ((void*)AdunitListNames[0]), P.NumAdunits, 1, 0);
608  na = P.NumAdunits;
609  for (i = 0; i < P.NumAdunits; i++)
610  {
611  f = 0;
612  if (na > 0)
613  {
614  for (j = 0; (j < na) && (!f); j++) f = (!strcmp(AdunitNames[3 * j + 2], AdunitListNames[i]));
615  if(f) k = atoi(AdunitNames[3 * (j-1)]);
616  }
617  if ((na == 0) || (!f)) k = atoi(AdunitListNames[i]);
618  AdUnits[i].id = k;
619  P.AdunitLevel1Lookup[(k % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor] = i;
620  for (j = 0; j < na; j++)
621  if (atoi(AdunitNames[3 * j]) == k)
622  {
623  if (strlen(AdunitNames[3 * j + 1]) < 100) strcpy(AdUnits[i].cnt_name, AdunitNames[3 * j + 1]);
624  if (strlen(AdunitNames[3 * j + 2]) < 200) strcpy(AdUnits[i].ad_name, AdunitNames[3 * j + 2]);
625  j = na;
626  }
627  }
628  }
629  else
630  P.DoAdunitBoundaries = 0;
631  }
632  free(AdunitNames);
633  free(AdunitNamesBuf);
634 
635  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Output incidence by administrative unit", "%i", (void*) & (P.DoAdunitOutput), 1, 1, 0)) P.DoAdunitOutput = 0;
636  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Draw administrative unit boundaries on maps", "%i", (void*) & (P.DoAdunitBoundaryOutput), 1, 1, 0)) P.DoAdunitBoundaryOutput = 0;
637  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Correct administrative unit populations", "%i", (void*) & (P.DoCorrectAdunitPop), 1, 1, 0)) P.DoCorrectAdunitPop = 0;
638  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Fix population size at specified value", "%i", (void*) & (P.DoSpecifyPop), 1, 1, 0)) P.DoSpecifyPop = 0;
639  fprintf(stderr, "Using %i administrative units\n", P.NumAdunits);
640  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Divisor for administrative unit codes for boundary plotting on bitmaps", "%i", (void*) & (P.AdunitBitmapDivisor), 1, 1, 0)) P.AdunitBitmapDivisor = 1;
641  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Only output household to place distance distribution for one administrative unit", "%i", (void*) & (P.DoOutputPlaceDistForOneAdunit), 1, 1, 0)) P.DoOutputPlaceDistForOneAdunit = 0;
642  if (P.DoOutputPlaceDistForOneAdunit)
643  {
644  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Administrative unit for which household to place distance distribution to be output", "%i", (void*) & (P.OutputPlaceDistAdunit), 1, 1, 0)) P.DoOutputPlaceDistForOneAdunit = 0;
645  }
646  }
647  else
648  {
649  P.DoAdunitBoundaries = P.DoAdunitBoundaryOutput = P.DoAdunitOutput = P.DoCorrectAdunitPop = P.DoSpecifyPop = 0;
650  P.AdunitLevel1Divisor = 1; P.AdunitLevel1Mask = 1000000000;
651  P.AdunitBitmapDivisor = P.AdunitLevel1Divisor;
652  }
653 
654  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Include age", "%i", (void*) & (P.DoAge), 1, 1, 0)) P.DoAge = 1;
655  if (!P.DoAge)
656  {
657  for (i = 0; i < NUM_AGE_GROUPS; i++)
658  P.PropAgeGroup[0][i] = 1.0 / NUM_AGE_GROUPS;
659  for (i = 0; i < NUM_AGE_GROUPS; i++)
660  {
661  P.InitialImmunity[i] = 0;
662  P.AgeInfectiousness[i] = P.AgeSusceptibility[i] = 1;
663  P.RelativeSpatialContact[i] = P.RelativeTravelRate[i] = 1.0;
664  }
665  }
666  else
667  {
668 
669  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Initial immunity acts as partial immunity", "%i", (void*)&(P.DoPartialImmunity), 1, 1, 0)) P.DoPartialImmunity = 1;
670  if ((P.DoHouseholds)&&(!P.DoPartialImmunity))
671  {
672  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Initial immunity applied to all household members", "%i", (void*) & (P.DoWholeHouseholdImmunity), 1, 1, 0)) P.DoWholeHouseholdImmunity = 0;
673  }
674  else
675  P.DoWholeHouseholdImmunity = 0;
676  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Initial immunity profile by age", "%lf", (void*)P.InitialImmunity, NUM_AGE_GROUPS, 1, 0))
677  for (i = 0; i < NUM_AGE_GROUPS; i++)
678  P.InitialImmunity[i] = 0;
679  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative spatial contact rates by age", "%lf", (void*)P.RelativeSpatialContact, NUM_AGE_GROUPS, 1, 0))
680  for (i = 0; i < NUM_AGE_GROUPS; i++)
681  P.RelativeSpatialContact[i] = 1;
682  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Age-dependent infectiousness", "%lf", (void*)P.AgeInfectiousness, NUM_AGE_GROUPS, 1, 0))
683  for (i = 0; i < NUM_AGE_GROUPS; i++)
684  P.AgeInfectiousness[i] = 1.0;
685  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Age-dependent susceptibility", "%lf", (void*)P.AgeSusceptibility, NUM_AGE_GROUPS, 1, 0))
686  for (i = 0; i < NUM_AGE_GROUPS; i++)
687  P.AgeSusceptibility[i] = 1.0;
688  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Age distribution of population", "%lf", (void*)P.PropAgeGroup[0], NUM_AGE_GROUPS, 1, 0);
689  t = 0;
690  for (i = 0; i < NUM_AGE_GROUPS; i++)
691  t += P.PropAgeGroup[0][i];
692  for (i = 0; i < NUM_AGE_GROUPS; i++)
693  P.PropAgeGroup[0][i] /= t;
694  t = 0;
695  for (i = 0; i < NUM_AGE_GROUPS; i++)
696  if (P.AgeSusceptibility[i] > t) t = P.AgeSusceptibility[i]; //peak susc has to be 1
697  for (i = 0; i < NUM_AGE_GROUPS; i++)
698  P.AgeSusceptibility[i] /= t;
699  AgeSuscScale = t;
700  if (P.DoHouseholds) P.HouseholdTrans *= AgeSuscScale;
701  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Relative travel rates by age", "%lf", (void*)P.RelativeTravelRate, NUM_AGE_GROUPS, 1, 0))
702  for (i = 0; i < NUM_AGE_GROUPS; i++)
703  P.RelativeTravelRate[i] = 1;
704  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "WAIFW matrix", "%lf", (void*)P.WAIFW_Matrix, NUM_AGE_GROUPS, NUM_AGE_GROUPS, 0))
705  {
706  for (i = 0; i < NUM_AGE_GROUPS; i++)
707  for (j = 0; j < NUM_AGE_GROUPS; j++)
708  P.WAIFW_Matrix[i][j] = 1.0;
709  }
710  else
711  {
712  /* WAIFW matrix needs to be scaled to have max value of 1.
713  1st index of matrix specifies host being infected, second the infector.
714  Overall age variation in infectiousness/contact rates/susceptibility should be factored
715  out of WAIFW_matrix and put in Age dep infectiousness/susceptibility for efficiency. */
716  t = 0;
717  for (i = 0; i < NUM_AGE_GROUPS; i++)
718  for (j = 0; j < NUM_AGE_GROUPS; j++)
719  if (P.WAIFW_Matrix[i][j] > t) t = P.WAIFW_Matrix[i][j];
720  if (t > 0)
721  {
722  for (i = 0; i < NUM_AGE_GROUPS; i++)
723  for (j = 0; j < NUM_AGE_GROUPS; j++)
724  P.WAIFW_Matrix[i][j] /= t;
725  }
726  else
727  {
728  for (i = 0; i < NUM_AGE_GROUPS; i++)
729  for (j = 0; j < NUM_AGE_GROUPS; j++)
730  P.WAIFW_Matrix[i][j] = 1.0;
731  }
732  }
733  P.DoDeath = 0;
734  t = 0;
735  for (i = 0; i < NUM_AGE_GROUPS; i++) t += P.AgeInfectiousness[i] * P.PropAgeGroup[0][i];
736  for (i = 0; i < NUM_AGE_GROUPS; i++) P.AgeInfectiousness[i] /= t;
737  }
738  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Include spatial transmission", "%i", (void*) & (P.DoSpatial), 1, 1, 0)) P.DoSpatial = 1;
739  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Kernel type", "%i", (void*) & (P.MoveKernelType), 1, 1, 0);
740  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Kernel scale", "%lf", (void*) & (P.MoveKernelScale), 1, 1, 0);
741  if (P.KernelOffsetScale != 1)
742  {
743  P.MoveKernelScale *= P.KernelOffsetScale;
744  }
745  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Kernel 3rd param", "%lf", (void*) & (P.MoveKernelP3), 1, 1, 0)) P.MoveKernelP3 = 0;
746  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Kernel 4th param", "%lf", (void*) & (P.MoveKernelP4), 1, 1, 0)) P.MoveKernelP4 = 0;
747  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Kernel Shape", "%lf", (void*) & (P.MoveKernelShape), 1, 1, 0)) P.MoveKernelShape = 1.0;
748  if (P.KernelPowerScale != 1)
749  {
750  P.MoveKernelShape *= P.KernelPowerScale;
751  }
752  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Airport Kernel Type", "%i", (void*) & (P.AirportKernelType), 1, 1, 0)) P.AirportKernelType = P.MoveKernelType;
753  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Airport Kernel Scale", "%lf", (void*) & (P.AirportKernelScale), 1, 1, 0)) P.AirportKernelScale = P.MoveKernelScale;
754  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Airport Kernel Shape", "%lf", (void*) & (P.AirportKernelShape), 1, 1, 0)) P.AirportKernelShape = P.MoveKernelShape;
755  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Airport Kernel 3rd param", "%lf", (void*) & (P.AirportKernelP3), 1, 1, 0)) P.AirportKernelP3 = P.MoveKernelP3;
756  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Airport Kernel 4th param", "%lf", (void*) & (P.AirportKernelP4), 1, 1, 0)) P.AirportKernelP4 = P.MoveKernelP4;
757 
758  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Include places", "%i", (void*)&(P.DoPlaces), 1, 1, 0)) P.DoPlaces = 1;
759  if (P.DoPlaces)
760  {
761  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Number of types of places", "%i", (void*)&(P.PlaceTypeNum), 1, 1, 0)) P.PlaceTypeNum = 0;
762  if (P.PlaceTypeNum == 0) P.DoPlaces = P.DoAirports = 0;
763  }
764  else
765  P.PlaceTypeNum = P.DoAirports = 0;
766  if (P.DoPlaces)
767  {
768  if (P.PlaceTypeNum > NUM_PLACE_TYPES) ERR_CRITICAL("Too many place types\n");
769  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Minimum age for age group 1 in place types", "%i", (void*)P.PlaceTypeAgeMin, P.PlaceTypeNum, 1, 0);
770  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Maximum age for age group 1 in place types", "%i", (void*)P.PlaceTypeAgeMax, P.PlaceTypeNum, 1, 0);
771  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Proportion of age group 1 in place types", "%lf", (void*) & (P.PlaceTypePropAgeGroup), P.PlaceTypeNum, 1, 0);
772  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Proportion of age group 2 in place types", "%lf", (void*) & (P.PlaceTypePropAgeGroup2), P.PlaceTypeNum, 1, 0))
773  {
774  for (i = 0; i < NUM_PLACE_TYPES; i++)
775  {
776  P.PlaceTypePropAgeGroup2[i] = 0;
777  P.PlaceTypeAgeMin2[i] = 0;
778  P.PlaceTypeAgeMax2[i] = 1000;
779  }
780  }
781  else
782  {
783  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Minimum age for age group 2 in place types", "%i", (void*)P.PlaceTypeAgeMin2, P.PlaceTypeNum, 1, 0);
784  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Maximum age for age group 2 in place types", "%i", (void*)P.PlaceTypeAgeMax2, P.PlaceTypeNum, 1, 0);
785  }
786  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Proportion of age group 3 in place types", "%lf", (void*) & (P.PlaceTypePropAgeGroup3), P.PlaceTypeNum, 1, 0))
787  {
788  for (i = 0; i < NUM_PLACE_TYPES; i++)
789  {
790  P.PlaceTypePropAgeGroup3[i] = 0;
791  P.PlaceTypeAgeMin3[i] = 0;
792  P.PlaceTypeAgeMax3[i] = 1000;
793  }
794  }
795  else
796  {
797  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Minimum age for age group 3 in place types", "%i", (void*)P.PlaceTypeAgeMin3, P.PlaceTypeNum, 1, 0);
798  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Maximum age for age group 3 in place types", "%i", (void*)P.PlaceTypeAgeMax3, P.PlaceTypeNum, 1, 0);
799  }
800  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Kernel shape params for place types", "%lf", (void*) & (P.PlaceTypeKernelShape), P.PlaceTypeNum, 1, 0))
801  {
802  for (i = 0; i < NUM_PLACE_TYPES; i++)
803  {
804  P.PlaceTypeKernelShape[i] = P.MoveKernelShape;
805  P.PlaceTypeKernelScale[i] = P.MoveKernelScale;
806  }
807  }
808  else
809  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Kernel scale params for place types", "%lf", (void*) & (P.PlaceTypeKernelScale), P.PlaceTypeNum, 1, 0);
810  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Kernel 3rd param for place types", "%lf", (void*) & (P.PlaceTypeKernelP3), P.PlaceTypeNum, 1, 0))
811  {
812  for (i = 0; i < NUM_PLACE_TYPES; i++)
813  {
814  P.PlaceTypeKernelP3[i] = P.MoveKernelP3;
815  P.PlaceTypeKernelP4[i] = P.MoveKernelP4;
816  }
817  }
818  else
819  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Kernel 4th param for place types", "%lf", (void*) & (P.PlaceTypeKernelP4), P.PlaceTypeNum, 1, 0);
820  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Number of closest places people pick from (0=all) for place types", "%i", (void*) & (P.PlaceTypeNearestNeighb), P.PlaceTypeNum, 1, 0))
821  for (i = 0; i < NUM_PLACE_TYPES; i++)
822  P.PlaceTypeNearestNeighb[i] = 0;
823  if (P.DoAdUnits)
824  {
825  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Degree to which crossing administrative unit boundaries to go to places is inhibited", "%lf", (void*) & (P.InhibitInterAdunitPlaceAssignment), P.PlaceTypeNum, 1, 0))
826  for (i = 0; i < NUM_PLACE_TYPES; i++)
827  P.InhibitInterAdunitPlaceAssignment[i] = 0;
828  }
829 
830  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Include air travel", "%i", (void*)&(P.DoAirports), 1, 1, 0)) P.DoAirports = 0;
831  if (!P.DoAirports)
832  {
833  // Airports disabled => all places are not to do with airports, and we
834  // have no hotels.
835  P.PlaceTypeNoAirNum = P.PlaceTypeNum;
836  P.HotelPlaceType = P.PlaceTypeNum;
837  }
838  else
839  {
840  // When airports are activated we must have at least one airport place
841  // // and a hotel type.
842  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Number of non-airport places", "%i", (void*)&(P.PlaceTypeNoAirNum), 1, 1, 0);
843  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Hotel place type", "%i", (void*)&(P.HotelPlaceType), 1, 1, 0);
844  if (P.PlaceTypeNoAirNum >= P.PlaceTypeNum) {
845  ERR_CRITICAL_FMT("[Number of non-airport places] parameter (%d) is greater than number of places (%d).\n", P.PlaceTypeNoAirNum, P.PlaceTypeNum);
846  }
847  if (P.HotelPlaceType < P.PlaceTypeNoAirNum || P.HotelPlaceType >= P.PlaceTypeNum) {
848  ERR_CRITICAL_FMT("[Hotel place type] parameter (%d) not in the range [%d, %d)\n", P.HotelPlaceType, P.PlaceTypeNoAirNum, P.PlaceTypeNum);
849  }
850 
851  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Scaling factor for input file to convert to daily traffic", "%lf", (void*) & (P.AirportTrafficScale), 1, 1, 0)) P.AirportTrafficScale = 1.0;
852  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of hotel attendees who are local", "%lf", (void*) & (P.HotelPropLocal), 1, 1, 0)) P.HotelPropLocal = 0;
853  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Distribution of duration of air journeys", "%lf", (void*) & (P.JourneyDurationDistrib), MAX_TRAVEL_TIME, 1, 0))
854  {
855  P.JourneyDurationDistrib[0] = 1;
856  for (i = 0; i < MAX_TRAVEL_TIME; i++)
857  P.JourneyDurationDistrib[i] = 0;
858  }
859  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Distribution of duration of local journeys", "%lf", (void*) & (P.LocalJourneyDurationDistrib), MAX_TRAVEL_TIME, 1, 0))
860  {
861  P.LocalJourneyDurationDistrib[0] = 1;
862  for (i = 0; i < MAX_TRAVEL_TIME; i++)
863  P.LocalJourneyDurationDistrib[i] = 0;
864  }
865  P.MeanJourneyTime = P.MeanLocalJourneyTime = 0;
866  for (i = 0; i < MAX_TRAVEL_TIME; i++)
867  {
868  P.MeanJourneyTime += ((double)(i)) * P.JourneyDurationDistrib[i];
869  P.MeanLocalJourneyTime += ((double)(i)) * P.LocalJourneyDurationDistrib[i];
870  }
871  fprintf(stderr, "Mean duration of local journeys = %lf days\n", P.MeanLocalJourneyTime);
872  for (i = 1; i < MAX_TRAVEL_TIME; i++)
873  {
874  P.JourneyDurationDistrib[i] += P.JourneyDurationDistrib[i - 1];
875  P.LocalJourneyDurationDistrib[i] += P.LocalJourneyDurationDistrib[i - 1];
876  }
877  for (i = j = 0; i <= 1024; i++)
878  {
879  s = ((double)i) / 1024;
880  while (P.JourneyDurationDistrib[j] < s)j++;
881  P.InvJourneyDurationDistrib[i] = j;
882  }
883  for (i = j = 0; i <= 1024; i++)
884  {
885  s = ((double)i) / 1024;
886  while (P.LocalJourneyDurationDistrib[j] < s)j++;
887  P.InvLocalJourneyDurationDistrib[i] = j;
888  }
889  }
890  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Mean size of place types", "%lf", (void*)P.PlaceTypeMeanSize, P.PlaceTypeNum, 1, 0);
891  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Param 1 of place group size distribution", "%lf", (void*)P.PlaceTypeGroupSizeParam1, P.PlaceTypeNum, 1, 0);
892  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Power of place size distribution", "%lf", (void*)P.PlaceTypeSizePower, P.PlaceTypeNum, 1, 0))
893  for (i = 0; i < NUM_PLACE_TYPES; i++)
894  P.PlaceTypeSizePower[i] = 0;
895  //added to enable lognormal distribution - ggilani 09/02/17
896  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Standard deviation of place size distribution", "%lf", (void*)P.PlaceTypeSizeSD, P.PlaceTypeNum, 1, 0))
897  for (i = 0; i < NUM_PLACE_TYPES; i++)
898  P.PlaceTypeSizeSD[i] = 0;
899  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Offset of place size distribution", "%lf", (void*)P.PlaceTypeSizeOffset, P.PlaceTypeNum, 1, 0))
900  for (i = 0; i < NUM_PLACE_TYPES; i++)
901  P.PlaceTypeSizeOffset[i] = 0;
902  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Maximum of place size distribution", "%lf", (void*)P.PlaceTypeSizeMax, P.PlaceTypeNum, 1, 0))
903  for (i = 0; i < NUM_PLACE_TYPES; i++)
904  P.PlaceTypeSizeMax[i] = 1e20;
905  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Kernel type for place types", "%i", (void*)P.PlaceTypeKernelType, P.PlaceTypeNum, 1, 0))
906  for (i = 0; i < NUM_PLACE_TYPES; i++)
907  P.PlaceTypeKernelType[i] = P.MoveKernelType;
908  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Place overlap matrix", "%lf", (void*)P.PlaceExclusivityMatrix, P.PlaceTypeNum * P.PlaceTypeNum, 1, 0); //changed from P.PlaceTypeNum,P.PlaceTypeNum,0);
909 /* Note P.PlaceExclusivityMatrix not used at present - places assumed exclusive (each person belongs to 0 or 1 place) */
910 
911  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Proportion of between group place links", "%lf", (void*)P.PlaceTypePropBetweenGroupLinks, P.PlaceTypeNum, 1, 0);
912  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Relative transmission rates for place types", "%lf", (void*)P.PlaceTypeTrans, P.PlaceTypeNum, 1, 0);
913  for (i = 0; i < P.PlaceTypeNum; i++) P.PlaceTypeTrans[i] *= AgeSuscScale;
914  }
915  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Daily seasonality coefficients", "%lf", (void*)P.Seasonality, DAYS_PER_YEAR, 1, 0))
916  {
917  P.DoSeasonality = 0;
918  for (i = 0; i < DAYS_PER_YEAR; i++)
919  P.Seasonality[i] = 1;
920  }
921  else
922  {
923  P.DoSeasonality = 1;
924  s = 0;
925  for (i = 0; i < DAYS_PER_YEAR; i++)
926  s += P.Seasonality[i];
927  s += 1e-20;
928  s /= DAYS_PER_YEAR;
929  for (i = 0; i < DAYS_PER_YEAR; i++)
930  P.Seasonality[i] /= s;
931  }
932  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Number of seed locations", "%i", (void*) & (P.NumSeedLocations), 1, 1, 0)) P.NumSeedLocations = 1;
933  if (P.NumSeedLocations > MAX_NUM_SEED_LOCATIONS)
934  {
935  fprintf(stderr, "Too many seed locations\n");
936  P.NumSeedLocations = MAX_NUM_SEED_LOCATIONS;
937  }
938  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Initial number of infecteds", "%i", (void*)P.NumInitialInfections, P.NumSeedLocations, 1, 0);
939  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Location of initial infecteds", "%lf", (void*)&(P.LocationInitialInfection[0][0]), P.NumSeedLocations * 2, 1, 0)) P.LocationInitialInfection[0][0] = P.LocationInitialInfection[0][1] = 0.0;
940  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Minimum population in microcell of initial infection", "%i", (void*) & (P.MinPopDensForInitialInfection), 1, 1, 0)) P.MinPopDensForInitialInfection = 0;
941  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Maximum population in microcell of initial infection", "%i", (void*)&(P.MaxPopDensForInitialInfection), 1, 1, 0)) P.MaxPopDensForInitialInfection = 10000000;
942  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Randomise initial infection location", "%i", (void*) & (P.DoRandomInitialInfectionLoc), 1, 1, 0)) P.DoRandomInitialInfectionLoc=1;
943  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "All initial infections located in same microcell", "%i", (void*) & (P.DoAllInitialInfectioninSameLoc), 1, 1, 0)) P.DoAllInitialInfectioninSameLoc=0;
944  if (P.DoAdUnits)
945  {
946  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Administrative unit to seed initial infection into", "%s", (P.NumSeedLocations > 1) ? ((void*)AdunitListNames) : ((void*)AdunitListNames[0]), P.NumSeedLocations, 1, 0))
947  for (i = 0; i < P.NumSeedLocations; i++) P.InitialInfectionsAdminUnit[i] = 0;
948  else
949  for (i = 0; i < P.NumSeedLocations; i++)
950  {
951  f = 0;
952  if (P.NumAdunits > 0)
953  {
954  for (j = 0; (j < P.NumAdunits) && (!f); j++) f = (!strcmp(AdUnits[j].ad_name, AdunitListNames[i]));
955  if (f) k = AdUnits[j-1].id;
956  }
957  if (!f) k = atoi(AdunitListNames[i]);
958  P.InitialInfectionsAdminUnit[i] = k;
959  P.InitialInfectionsAdminUnitId[i]=P.AdunitLevel1Lookup[(k % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor];
960  }
961  if(!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Administrative unit seeding weights", "%lf", (void*) & (P.InitialInfectionsAdminUnitWeight[0]), P.NumSeedLocations, 1, 0))
962  for(i = 0; i < P.NumSeedLocations; i++) P.InitialInfectionsAdminUnitWeight[i] = 1.0;
963  s=0;
964  for(i = 0; i < P.NumSeedLocations; i++) s+=P.InitialInfectionsAdminUnitWeight[i];
965  for(i = 0; i < P.NumSeedLocations; i++) P.InitialInfectionsAdminUnitWeight[i]/=s;
966  // for (i = 0; i < P.NumSeedLocations; i++) fprintf(stderr, "## %i %s %i %i %lf\n",i, AdUnits[P.InitialInfectionsAdminUnitId[i]].ad_name, P.InitialInfectionsAdminUnitId[i], P.InitialInfectionsAdminUnit[i], P.InitialInfectionsAdminUnitWeight[i]);
967  }
968  else
969  {
970  for (i = 0; i < P.NumSeedLocations; i++) P.InitialInfectionsAdminUnit[i] = 0;
971  }
972  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Initial rate of importation of infections", "%lf", (void*)&(P.InfectionImportRate1), 1, 1, 0)) P.InfectionImportRate1 = 0;
973  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Changed rate of importation of infections", "%lf", (void*)&(P.InfectionImportRate2), 1, 1, 0)) P.InfectionImportRate2 = 0;
974  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Time when infection rate changes", "%lf", (void*)&(P.InfectionImportChangeTime), 1, 1, 0)) P.InfectionImportChangeTime = 1e10;
975  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Imports via air travel", "%i", (void*)&(P.DoImportsViaAirports), 1, 1, 0)) P.DoImportsViaAirports = 0;
976  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Length of importation time profile provided", "%i", (void*)&(P.DurImportTimeProfile), 1, 1, 0)) P.DurImportTimeProfile = 0;
977  if (P.DurImportTimeProfile > 0)
978  {
979  if (P.DurImportTimeProfile >= MAX_DUR_IMPORT_PROFILE) ERR_CRITICAL("MAX_DUR_IMPORT_PROFILE too small\n");
980  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Daily importation time profile", "%lf", (void*)P.ImportInfectionTimeProfile, P.DurImportTimeProfile, 1, 0);
981  }
982  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Reproduction number", "%lf", (void*) & (P.R0), 1, 1, 0);
983  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Infectious period", "%lf", (void*) & (P.InfectiousPeriod), 1, 1, 0);
984  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "SD of individual variation in susceptibility", "%lf", (void*)&(P.SusceptibilitySD), 1, 1, 0)) P.SusceptibilitySD = 0;
985  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "SD of individual variation in infectiousness", "%lf", (void*) & (P.InfectiousnessSD), 1, 1, 0)) P.InfectiousnessSD = 0;
986  if (GetInputParameter2(ParamFile_dat, PreParamFile_dat, "k of individual variation in infectiousness", "%lf", (void*)& s, 1, 1, 0)) P.InfectiousnessSD = 1.0 / sqrt(s);
987  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Model time varying infectiousness", "%i", (void*) & (P.DoInfectiousnessProfile), 1, 1, 0)) P.DoInfectiousnessProfile = 0;
988  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Power of scaling of spatial R0 with density", "%lf", (void*) & (P.R0DensityScalePower), 1, 1, 0)) P.R0DensityScalePower = 0;
989  if (P.DoInfectiousnessProfile)
990  {
991  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Infectiousness profile", "%lf", (void*)P.infectious_prof, INFPROF_RES, 1, 0))
992  {
993  for (i = 0; i < INFPROF_RES; i++)
994  P.infectious_prof[i] = 1;
995  }
996  k = (int)ceil(P.InfectiousPeriod / P.TimeStep);
997  if (k >= MAX_INFECTIOUS_STEPS) ERR_CRITICAL("MAX_INFECTIOUS_STEPS not big enough\n");
998  s = 0;
999  P.infectious_prof[INFPROF_RES] = 0;
1000  for (i = 0; i < MAX_INFECTIOUS_STEPS; i++) P.infectiousness[i] = 0;
1001  for (i = 0; i < k; i++)
1002  {
1003  t = (((double)i) * P.TimeStep / P.InfectiousPeriod * INFPROF_RES);
1004  j = (int)t;
1005  t -= (double)j;
1006  if (j < INFPROF_RES)
1007  s += (P.infectiousness[i] = P.infectious_prof[j] * (1 - t) + P.infectious_prof[j + 1] * t);
1008  else
1009  s += (P.infectiousness[i] = P.infectious_prof[INFPROF_RES]);
1010  }
1011  s /= ((double)k);
1012  for (i = 0; i <= k; i++) P.infectiousness[i] /= s;
1013  for (i = 0; i <= CDF_RES; i++) P.infectious_icdf[i] = exp(-1.0);
1014  }
1015  else
1016  {
1017  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Infectious period inverse CDF", "%lf", (void*)P.infectious_icdf, CDF_RES + 1, 1, 0))
1018  {
1019  SetICDF(P.infectious_icdf, ICDF_START);
1020  }
1021  k = (int)ceil(P.InfectiousPeriod * P.infectious_icdf[CDF_RES] / P.TimeStep);
1022  if (k >= MAX_INFECTIOUS_STEPS) ERR_CRITICAL("MAX_INFECTIOUS_STEPS not big enough\n");
1023  for (i = 0; i < k; i++) P.infectiousness[i] = 1.0;
1024  P.infectiousness[k] = 0;
1025  for (i = 0; i <= CDF_RES; i++) P.infectious_icdf[i] = exp(-P.infectious_icdf[i]);
1026  }
1027  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Include latent period", "%i", (void*) & (P.DoLatent), 1, 1, 0)) P.DoLatent = 0;
1028  if (P.DoLatent)
1029  {
1030  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Latent period", "%lf", (void*) & (P.LatentPeriod), 1, 1, 0);
1031  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Latent period inverse CDF", "%lf", (void*)P.latent_icdf, CDF_RES + 1, 1, 0))
1032  {
1033  SetICDF(P.latent_icdf, 1e10);
1034  }
1035  for (i = 0; i <= CDF_RES; i++)
1036  P.latent_icdf[i] = exp(-P.latent_icdf[i]);
1037  }
1038 
1039  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Include symptoms", "%i", (void*) & (P.DoSymptoms), 1, 1, 0)) P.DoSymptoms = 0;
1040  if (!P.DoSymptoms)
1041  {
1042  for (i = 0; i < NUM_AGE_GROUPS; i++)
1043  P.ProportionSymptomatic[i] = 0;
1044  P.FalsePositiveRate = 0;
1045  P.SymptInfectiousness = 1.0;
1046  P.LatentToSymptDelay = 0;
1047  }
1048  else
1049  {
1050  if (P.DoAge)
1051  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Proportion symptomatic by age group", "%lf", (void*)P.ProportionSymptomatic, NUM_AGE_GROUPS, 1, 0);
1052  else
1053  {
1054  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Proportion symptomatic", "%lf", (void*)P.ProportionSymptomatic, 1, 1, 0);
1055  for (i = 1; i < NUM_AGE_GROUPS; i++)
1056  P.ProportionSymptomatic[i] = P.ProportionSymptomatic[0];
1057  }
1058  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Delay from end of latent period to start of symptoms", "%lf", (void*) & (P.LatentToSymptDelay), 1, 1, 0);
1059  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Relative rate of random contacts if symptomatic", "%lf", (void*) & (P.SymptSpatialContactRate), 1, 1, 0);
1060  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Symptomatic infectiousness relative to asymptomatic", "%lf", (void*) & (P.SymptInfectiousness), 1, 1, 0);
1061  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Model symptomatic withdrawal to home as true absenteeism", "%i", (void*)& P.DoRealSymptWithdrawal, 1, 1, 0)) P.DoRealSymptWithdrawal = 0;
1062  if (P.DoPlaces)
1063  {
1064  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Relative level of place attendance if symptomatic", "%lf", (void*)P.SymptPlaceTypeContactRate, P.PlaceTypeNum, 1, 0);
1065  if (P.DoRealSymptWithdrawal)
1066  {
1067  for (j = 0; j < NUM_PLACE_TYPES; j++)
1068  {
1069  P.SymptPlaceTypeWithdrawalProp[j] = 1.0 - P.SymptPlaceTypeContactRate[j];
1070  P.SymptPlaceTypeContactRate[j] = 1.0;
1071  }
1072  }
1073  else
1074  for (j = 0; j < NUM_PLACE_TYPES; j++) P.SymptPlaceTypeWithdrawalProp[j] = 0.0;
1075  }
1076  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Maximum age of child at home for whom one adult also stays at home", "%i", (void*)& P.CaseAbsentChildAgeCutoff, 1, 1, 0)) P.CaseAbsentChildAgeCutoff = 0;
1077  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of children at home for whom one adult also stays at home", "%lf", (void*)& P.CaseAbsentChildPropAdultCarers, 1, 1, 0)) P.CaseAbsentChildPropAdultCarers = 0;
1078  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place close round household", "%i", (void*)&P.PlaceCloseRoundHousehold, 1, 1, 0)) P.PlaceCloseRoundHousehold = 1;
1079  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Absenteeism place closure", "%i", (void*)&P.AbsenteeismPlaceClosure, 1, 1, 0)) P.AbsenteeismPlaceClosure = 0;
1080  if (P.AbsenteeismPlaceClosure)
1081  {
1082  P.CaseAbsenteeismDelay = 0; // Set to zero for tracking absenteeism
1083  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Max absent time", "%i", (void*)&P.MaxAbsentTime, 1, 1, 0)) P.MaxAbsentTime = MAX_ABSENT_TIME;
1084  if (P.MaxAbsentTime > MAX_ABSENT_TIME || P.MaxAbsentTime < 0)
1085  {
1086  ERR_CRITICAL_FMT("[Max absent time] out of range (%d), should be in range [0, %d]", P.MaxAbsentTime, MAX_ABSENT_TIME);
1087  }
1088  }
1089  else
1090  {
1091  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay in starting place absenteeism for cases who withdraw", "%lf", (void*)& P.CaseAbsenteeismDelay, 1, 1, 0)) P.CaseAbsenteeismDelay = 0;
1092  P.MaxAbsentTime = 0; // Not used when !P.AbsenteeismPlaceClosure
1093  }
1094  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of place absenteeism for cases who withdraw", "%lf", (void*)& P.CaseAbsenteeismDuration, 1, 1, 0)) P.CaseAbsenteeismDuration = 7;
1095 
1096  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "False positive rate", "%lf", (void*) & (P.FalsePositiveRate), 1, 1, 0)) P.FalsePositiveRate = 0.0;
1097  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "False positive per capita incidence", "%lf", (void*) & (P.FalsePositivePerCapitaIncidence), 1, 1, 0)) P.FalsePositivePerCapitaIncidence = 0.0;
1098  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "False positive relative incidence by age", "%lf", (void*)P.FalsePositiveAgeRate, NUM_AGE_GROUPS, 1, 0))
1099  for (j = 0; j < NUM_AGE_GROUPS; j++) P.FalsePositiveAgeRate[j] = 1.0;
1100  }
1101 
1102  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Do Severity Analysis", "%i", (void*) & (P.DoSeverity), 1, 1, 0)) P.DoSeverity = 0;
1103  if(P.DoSeverity == 1)
1104  {
1106  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "MeanTimeToTest", "%lf", (void*)&(P.Mean_TimeToTest), 1, 1, 0)) P.Mean_TimeToTest = 0.0;
1107  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "MeanTimeToTestOffset", "%lf", (void*)&(P.Mean_TimeToTestOffset), 1, 1, 0)) P.Mean_TimeToTestOffset = 1.0;
1108  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "MeanTimeToTestCriticalOffset", "%lf", (void*)&(P.Mean_TimeToTestCriticalOffset), 1, 1, 0)) P.Mean_TimeToTestCriticalOffset = 1.0;
1109  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "MeanTimeToTestCritRecovOffset", "%lf", (void*)&(P.Mean_TimeToTestCritRecovOffset), 1, 1, 0)) P.Mean_TimeToTestCritRecovOffset = 1.0;
1110  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Age dependent severity delays", "%i", (void*)&i, 1, 1, 0)) i = 0;
1111  if (!i)
1112  {
1113  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_MildToRecovery", "%lf", (void*)&(P.Mean_MildToRecovery[0]), 1, 1, 0);
1114  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_ILIToRecovery", "%lf", (void*)&(P.Mean_ILIToRecovery[0]), 1, 1, 0);
1115  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_SARIToRecovery", "%lf", (void*)&(P.Mean_SARIToRecovery[0]), 1, 1, 0);
1116  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_CriticalToCritRecov", "%lf", (void*)&(P.Mean_CriticalToCritRecov[0]), 1, 1, 0);
1117  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_CritRecovToRecov", "%lf", (void*)&(P.Mean_CritRecovToRecov[0]), 1, 1, 0);
1118  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_ILIToSARI", "%lf", (void*)&(P.Mean_ILIToSARI[0]), 1, 1, 0);
1119  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Mean_ILIToDeath", "%lf", (void*)&(P.Mean_ILIToDeath[0]), 1, 1, 0)) P.Mean_ILIToDeath[0] = 7.0;
1120  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_SARIToCritical", "%lf", (void*)&(P.Mean_SARIToCritical[0]), 1, 1, 0);
1121  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_SARIToDeath", "%lf", (void*)&(P.Mean_SARIToDeath[0]), 1, 1, 0);
1122  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_CriticalToDeath", "%lf", (void*)&(P.Mean_CriticalToDeath[0]), 1, 1, 0);
1123  for (j = 1; j < NUM_AGE_GROUPS; j++)
1124  {
1126  P.Mean_ILIToRecovery[j] = P.Mean_ILIToRecovery[0];
1127  P.Mean_SARIToRecovery[j] = P.Mean_SARIToRecovery[0];
1128  P.Mean_CriticalToCritRecov[j] = P.Mean_CriticalToCritRecov[0];
1129  P.Mean_CritRecovToRecov[j] = P.Mean_CritRecovToRecov[0];
1130  P.Mean_ILIToSARI[j] = P.Mean_ILIToSARI[0];
1131  P.Mean_ILIToDeath[j] = P.Mean_ILIToDeath[0];
1132  P.Mean_SARIToCritical[j] = P.Mean_SARIToCritical[0];
1133  P.Mean_SARIToDeath[j] = P.Mean_SARIToDeath[0];
1134  P.Mean_CriticalToDeath[j] = P.Mean_CriticalToDeath[0];
1135  }
1136  }
1137  else
1138  {
1139  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_MildToRecovery", "%lf", (void*)(P.Mean_MildToRecovery), NUM_AGE_GROUPS, 1, 0);
1140  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_ILIToRecovery", "%lf", (void*)(P.Mean_ILIToRecovery), NUM_AGE_GROUPS, 1, 0);
1141  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_SARIToRecovery", "%lf", (void*)(P.Mean_SARIToRecovery), NUM_AGE_GROUPS, 1, 0);
1142  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_CriticalToCritRecov", "%lf", (void*)(P.Mean_CriticalToCritRecov), NUM_AGE_GROUPS, 1, 0);
1143  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_CritRecovToRecov", "%lf", (void*)(P.Mean_CritRecovToRecov), NUM_AGE_GROUPS, 1, 0);
1144  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_ILIToSARI", "%lf", (void*)(P.Mean_ILIToSARI), NUM_AGE_GROUPS, 1, 0);
1145  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Mean_ILIToDeath", "%lf", (void*)(P.Mean_ILIToDeath), NUM_AGE_GROUPS, 1, 0))
1146  for (j = 0; j < NUM_AGE_GROUPS; j++) P.Mean_ILIToDeath[j] = 7.0;
1147  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_SARIToCritical", "%lf", (void*)(P.Mean_SARIToCritical), NUM_AGE_GROUPS, 1, 0);
1148  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_SARIToDeath", "%lf", (void*)(P.Mean_SARIToDeath), NUM_AGE_GROUPS, 1, 0);
1149  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Mean_CriticalToDeath", "%lf", (void*)(P.Mean_CriticalToDeath), NUM_AGE_GROUPS, 1, 0);
1150  }
1152  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "MildToRecovery_icdf", "%lf", (void*)P.MildToRecovery_icdf, CDF_RES + 1, 1, 0))
1153  {
1154  SetICDF(P.MildToRecovery_icdf, ICDF_START);
1155  }
1156  for(i = 0; i <= CDF_RES; i++) P.MildToRecovery_icdf[i] = exp(-P.MildToRecovery_icdf[i]);
1157 
1158  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "ILIToRecovery_icdf", "%lf", (void*)P.ILIToRecovery_icdf, CDF_RES + 1, 1, 0))
1159  {
1160  SetICDF(P.ILIToRecovery_icdf, ICDF_START);
1161  }
1162  for(i = 0; i <= CDF_RES; i++) P.ILIToRecovery_icdf[i] = exp(-P.ILIToRecovery_icdf[i]);
1163 
1164  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "ILIToDeath_icdf", "%lf", (void*)P.ILIToDeath_icdf, CDF_RES + 1, 1, 0))
1165  {
1166  SetICDF(P.ILIToDeath_icdf, ICDF_START);
1167  }
1168  for (i = 0; i <= CDF_RES; i++) P.ILIToDeath_icdf[i] = exp(-P.ILIToDeath_icdf[i]);
1169 
1170  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "SARIToRecovery_icdf", "%lf", (void*)P.SARIToRecovery_icdf, CDF_RES + 1, 1, 0))
1171  {
1172  SetICDF(P.SARIToRecovery_icdf, ICDF_START);
1173  }
1174  for(i = 0; i <= CDF_RES; i++) P.SARIToRecovery_icdf[i] = exp(-P.SARIToRecovery_icdf[i]);
1175 
1176  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "CriticalToCritRecov_icdf", "%lf", (void*)P.CriticalToCritRecov_icdf, CDF_RES + 1, 1, 0))
1177  {
1178  SetICDF(P.CriticalToCritRecov_icdf, ICDF_START);
1179  }
1180  for(i = 0; i <= CDF_RES; i++) P.CriticalToCritRecov_icdf[i] = exp(-P.CriticalToCritRecov_icdf[i]);
1181 
1182  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "CritRecovToRecov_icdf", "%lf", (void*)P.CritRecovToRecov_icdf, CDF_RES + 1, 1, 0))
1183  {
1184  SetICDF(P.CritRecovToRecov_icdf, ICDF_START);
1185  }
1186  for(i = 0; i <= CDF_RES; i++) P.CritRecovToRecov_icdf[i] = exp(-P.CritRecovToRecov_icdf[i]);
1187 
1188  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "ILIToSARI_icdf", "%lf", (void*)P.ILIToSARI_icdf, CDF_RES + 1, 1, 0))
1189  {
1190  SetICDF(P.ILIToSARI_icdf, ICDF_START);
1191  }
1192  for(i = 0; i <= CDF_RES; i++) P.ILIToSARI_icdf[i] = exp(-P.ILIToSARI_icdf[i]);
1193 
1194  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "SARIToCritical_icdf", "%lf", (void*)P.SARIToCritical_icdf, CDF_RES + 1, 1, 0))
1195  {
1196  SetICDF(P.SARIToCritical_icdf, ICDF_START);
1197  }
1198  for(i = 0; i <= CDF_RES; i++) P.SARIToCritical_icdf[i] = exp(-P.SARIToCritical_icdf[i]);
1199 
1200  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "SARIToDeath_icdf" , "%lf", (void*)P.SARIToDeath_icdf, CDF_RES + 1, 1, 0))
1201  {
1202  SetICDF(P.SARIToDeath_icdf, ICDF_START);
1203  }
1204  for (i = 0; i <= CDF_RES; i++) P.SARIToDeath_icdf[i] = exp(-P.SARIToDeath_icdf[i]);
1205 
1206  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "CriticalToDeath_icdf", "%lf", (void*)P.CriticalToDeath_icdf, CDF_RES + 1, 1, 0))
1207  {
1208  SetICDF(P.CriticalToDeath_icdf, ICDF_START);
1209  }
1210  for(i = 0; i <= CDF_RES; i++) P.CriticalToDeath_icdf[i] = exp(-P.CriticalToDeath_icdf[i]);
1211 
1212  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Prop_Mild_ByAge", "%lf", (void*)P.Prop_Mild_ByAge, NUM_AGE_GROUPS, 1, 0))
1213  for(i = 0; i < NUM_AGE_GROUPS; i++)
1214  P.Prop_Mild_ByAge[i] = 0.5;
1215 
1216  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Prop_ILI_ByAge", "%lf", (void*)P.Prop_ILI_ByAge, NUM_AGE_GROUPS, 1, 0))
1217  for(i = 0; i < NUM_AGE_GROUPS; i++)
1218  P.Prop_ILI_ByAge[i] = 0.3;
1219 
1220  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Prop_SARI_ByAge", "%lf", (void*)P.Prop_SARI_ByAge, NUM_AGE_GROUPS, 1, 0))
1221  for(i = 0; i < NUM_AGE_GROUPS; i++)
1222  P.Prop_SARI_ByAge[i] = 0.15;
1223 
1224  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Prop_Critical_ByAge", "%lf", (void*)P.Prop_Critical_ByAge, NUM_AGE_GROUPS, 1, 0))
1225  for(i = 0; i < NUM_AGE_GROUPS; i++)
1226  P.Prop_Critical_ByAge[i] = 0.05;
1227 
1228  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "CFR_SARI_ByAge", "%lf", (void*)P.CFR_SARI_ByAge, NUM_AGE_GROUPS, 1, 0))
1229  for(i = 0; i < NUM_AGE_GROUPS; i++)
1230  P.CFR_SARI_ByAge[i] = 0.50;
1231 
1232  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "CFR_Critical_ByAge", "%lf", (void*)P.CFR_Critical_ByAge, NUM_AGE_GROUPS, 1, 0))
1233  for(i = 0; i < NUM_AGE_GROUPS; i++)
1234  P.CFR_Critical_ByAge[i] = 0.50;
1235 
1236  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "CFR_ILI_ByAge", "%lf", (void*)P.CFR_ILI_ByAge, NUM_AGE_GROUPS, 1, 0))
1237  for (i = 0; i < NUM_AGE_GROUPS; i++)
1238  P.CFR_ILI_ByAge[i] = 0.00;
1239  }
1240 
1241  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Bounding box for bitmap", "%lf", (void*) & (P.BoundingBox[0]), 4, 1, 0))
1242  {
1243  P.BoundingBox[0] = P.BoundingBox[1] = 0.0;
1244  P.BoundingBox[2] = P.BoundingBox[3] = 1.0;
1245  }
1246  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Spatial domain for simulation", "%lf", (void*) & (P.SpatialBoundingBox[0]), 4, 1, 0))
1247  {
1248  P.SpatialBoundingBox[0] = P.SpatialBoundingBox[1] = 0.0;
1249  P.SpatialBoundingBox[2] = P.SpatialBoundingBox[3] = 1.0;
1250  }
1251  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Grid size", "%lf", (void*) & (P.in_cells_.width_), 1, 1, 0)) P.in_cells_.width_ = 1.0 / 120.0;
1252  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Use long/lat coord system", "%i", (void*) & (P.DoUTM_coords), 1, 1, 0)) P.DoUTM_coords = 1;
1253  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Bitmap scale", "%lf", (void*) & (P.BitmapScale), 1, 1, 0)) P.BitmapScale = 1.0;
1254  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Bitmap y:x aspect scaling", "%lf", (void*) & (P.BitmapAspectScale), 1, 1, 0)) P.BitmapAspectScale = 1.0;
1255  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Bitmap movie frame interval", "%i", (void*) & (P.BitmapMovieFrame), 1, 1, 0)) P.BitmapMovieFrame = 250;
1256  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Output bitmap", "%i", (void*) & (P.OutputBitmap), 1, 1, 0)) P.OutputBitmap = 0;
1257  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Output bitmap detected", "%i", (void*) & (P.OutputBitmapDetected), 1, 1, 0)) P.OutputBitmapDetected = 0;
1258  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Output immunity on bitmap", "%i", (void*) & (P.DoImmuneBitmap), 1, 1, 0)) P.DoImmuneBitmap = 0;
1259  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Output infection tree", "%i", (void*) & (P.DoInfectionTree), 1, 1, 0)) P.DoInfectionTree = 0;
1260  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Do one generation", "%i", (void*) & (P.DoOneGen), 1, 1, 0)) P.DoOneGen = 0;
1261  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Output every realisation", "%i", (void*) & (P.OutputEveryRealisation), 1, 1, 0)) P.OutputEveryRealisation = 0;
1262  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Maximum number to sample for correlations", "%i", (void*) & (P.MaxCorrSample), 1, 1, 0)) P.MaxCorrSample = 1000000000;
1263  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Assume SI model", "%i", (void*) & (P.DoSI), 1, 1, 0)) P.DoSI = 0;
1264  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Assume periodic boundary conditions", "%i", (void*) & (P.DoPeriodicBoundaries), 1, 1, 0)) P.DoPeriodicBoundaries = 0;
1265  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Only output non-extinct realisations", "%i", (void*) & (P.OutputOnlyNonExtinct), 1, 1, 0)) P.OutputOnlyNonExtinct = 0;
1266 
1267  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Use cases per thousand threshold for area controls", "%i", (void*) & (P.DoPerCapitaTriggers), 1, 1, 0)) P.DoPerCapitaTriggers = 0;
1268  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Use global triggers for interventions", "%i", (void*) & (P.DoGlobalTriggers), 1, 1, 0)) P.DoGlobalTriggers = 0;
1269  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Use admin unit triggers for interventions", "%i", (void*) & (P.DoAdminTriggers), 1, 1, 0)) P.DoAdminTriggers = 0;
1270  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Use ICU case triggers for interventions", "%i", (void*) & (P.DoICUTriggers), 1, 1, 0)) P.DoICUTriggers = 0;
1271  if (P.DoGlobalTriggers) P.DoAdminTriggers = 0;
1272  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Divisor for per-capita area threshold (default 1000)", "%i", (void*) & (P.IncThreshPop), 1, 1, 0)) P.IncThreshPop = 1000;
1273  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Divisor for per-capita global threshold (default 1000)", "%i", (void*) & (P.GlobalIncThreshPop), 1, 1, 0)) P.GlobalIncThreshPop = 1000;
1274 
1275 
1276  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of sampling intervals over which cumulative incidence measured for global trigger", "%i", (void*) & (P.TriggersSamplingInterval), 1, 1, 0)) P.TriggersSamplingInterval = 10000000;
1277  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of cases detected for treatment", "%lf", (void*) & (P.PostAlertControlPropCasesId), 1, 1, 0)) P.PostAlertControlPropCasesId = 1;
1278  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of cases detected before outbreak alert", "%lf", (void*) & (P.PreAlertControlPropCasesId), 1, 1, 0)) P.PreAlertControlPropCasesId = 1.0;
1279  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Trigger alert on deaths", "%i", (void*)&(P.PreControlClusterIdUseDeaths), 1, 1, 0)) P.PreControlClusterIdUseDeaths = 0;
1280  if (P.PreControlClusterIdUseDeaths)
1281  {
1282  if (P.PreControlClusterIdCaseThreshold == 0)
1283  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of deaths accummulated before alert", "%i", (void*)&(P.PreControlClusterIdCaseThreshold), 1, 1, 0)) P.PreControlClusterIdCaseThreshold = 0;
1284  }
1285  else if (P.PreControlClusterIdCaseThreshold == 0)
1286  {
1287  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of detected cases needed before outbreak alert triggered", "%i", (void*) & (P.PreControlClusterIdCaseThreshold), 1, 1, 0)) P.PreControlClusterIdCaseThreshold = 0;
1288  }
1289  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Alert trigger starts after interventions", "%i", (void*)&(P.DoAlertTriggerAfterInterv), 1, 1, 0)) P.DoAlertTriggerAfterInterv = 0;
1290  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Day of year trigger is reached", "%lf", (void*)&(P.PreControlClusterIdCalTime), 1, 1, 0)) P.PreControlClusterIdCalTime = -1;
1291  if (P.DoAlertTriggerAfterInterv)
1292  {
1293  GetInputParameter(ParamFile_dat, PreParamFile_dat, "Day of year interventions start", "%lf", (void*)&(P.PreIntervIdCalTime), 1, 1, 0);
1294  if (P.PreControlClusterIdCalTime <= P.PreIntervIdCalTime)
1295  P.DoAlertTriggerAfterInterv = 0;
1296  else
1297  {
1298  P.AlertTriggerAfterIntervThreshold = P.PreControlClusterIdCaseThreshold;
1299  P.PreControlClusterIdCaseThreshold = 1000;
1300  }
1301  }
1302  else
1303  P.PreIntervIdCalTime = P.PreControlClusterIdCalTime;
1304  P.PreControlClusterIdCaseThreshold2 = P.PreControlClusterIdCaseThreshold;
1305  //if (P.DoAlertTriggerAfterInterv) P.ResetSeeds =P.KeepSameSeeds = 1;
1306  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of days to accummulate cases/deaths before alert", "%i", (void*)&(P.PreControlClusterIdDuration), 1, 1, 0)) P.PreControlClusterIdDuration = 1000;
1307 
1308  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Only use confirmed cases to trigger alert", "%i", (void*) & (P.DoEarlyCaseDiagnosis), 1, 1, 0)) P.DoEarlyCaseDiagnosis = 0;
1309  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Only treat mixing groups within places", "%i", (void*) & (P.DoPlaceGroupTreat), 1, 1, 0)) P.DoPlaceGroupTreat = 0;
1310 
1311  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Treatment trigger incidence per cell" , "%lf", (void*) & (P.TreatCellIncThresh) , 1, 1, 0)) P.TreatCellIncThresh = 1000000000;
1312  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Case isolation trigger incidence per cell" , "%lf", (void*) & (P.CaseIsolation_CellIncThresh) , 1, 1, 0)) P.CaseIsolation_CellIncThresh = P.TreatCellIncThresh;
1313  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Household quarantine trigger incidence per cell" , "%lf", (void*) & (P.HHQuar_CellIncThresh) , 1, 1, 0)) P.HHQuar_CellIncThresh = P.TreatCellIncThresh;
1314 
1315  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative susceptibility of treated individual", "%lf", (void*) & (P.TreatSuscDrop), 1, 1, 0)) P.TreatSuscDrop = 1;
1316  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative infectiousness of treated individual", "%lf", (void*) & (P.TreatInfDrop), 1, 1, 0)) P.TreatInfDrop = 1;
1317  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of symptomatic cases resulting in death prevented by treatment", "%lf", (void*) & (P.TreatDeathDrop), 1, 1, 0)) P.TreatDeathDrop = 0;
1318  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of symptomatic cases prevented by treatment", "%lf", (void*) & (P.TreatSympDrop), 1, 1, 0)) P.TreatSympDrop = 0;
1319  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to treat cell", "%lf", (void*) & (P.TreatDelayMean), 1, 1, 0)) P.TreatDelayMean = 0;
1320  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of course of treatment", "%lf", (void*) & (P.TreatCaseCourseLength), 1, 1, 0)) P.TreatCaseCourseLength = 5;
1321  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of course of prophylaxis", "%lf", (void*) & (P.TreatProphCourseLength), 1, 1, 0)) P.TreatProphCourseLength = 10;
1322  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of detected cases treated", "%lf", (void*) & (P.TreatPropCases), 1, 1, 0)) P.TreatPropCases = 1;
1323  if (P.DoHouseholds)
1324  {
1325  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of households of cases treated", "%lf", (void*) & (P.TreatPropCaseHouseholds), 1, 1, 0)) P.TreatPropCaseHouseholds = 0;
1326  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of household prophylaxis policy", "%lf", (void*) & (P.TreatHouseholdsDuration), 1, 1, 0)) P.TreatHouseholdsDuration = USHRT_MAX / P.TimeStepsPerDay;
1327  }
1328  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion treated", "%lf", (void*) & (P.TreatPropRadial), 1, 1, 0)) P.TreatPropRadial = 1.0;
1329  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion treated in radial prophylaxis", "%lf", (void*) & (P.TreatPropRadial), 1, 1, 0)) P.TreatPropRadial = 1.0;
1330  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Treatment radius", "%lf", (void*) & (P.TreatRadius), 1, 1, 0)) P.TreatRadius = 0;
1331  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of place/geographic prophylaxis policy", "%lf", (void*) & (P.TreatPlaceGeogDuration), 1, 1, 0)) P.TreatPlaceGeogDuration = USHRT_MAX / P.TimeStepsPerDay;
1332  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Treatment start time", "%lf", (void*) & (P.TreatTimeStartBase), 1, 1, 0)) P.TreatTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1333  if (P.DoPlaces)
1334  {
1335  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of places treated after case detected", "%lf", (void*)P.TreatPlaceProbCaseId, P.PlaceTypeNum, 1, 0))
1336  for (i = 0; i < NUM_PLACE_TYPES; i++) P.TreatPlaceProbCaseId[i] = 0;
1337  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of people treated in targeted places", "%lf", (void*)P.TreatPlaceTotalProp, P.PlaceTypeNum, 1, 0))
1338  for (i = 0; i < NUM_PLACE_TYPES; i++) P.TreatPlaceTotalProp[i] = 0;
1339  }
1340  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Maximum number of doses available", "%lf", (void*) & (P.TreatMaxCoursesBase), 1, 1, 0)) P.TreatMaxCoursesBase = 1e20;
1341  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Start time of additional treatment production", "%lf", (void*) & (P.TreatNewCoursesStartTime), 1, 1, 0)) P.TreatNewCoursesStartTime = USHRT_MAX / P.TimeStepsPerDay;
1342  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Rate of additional treatment production (courses per day)", "%lf", (void*) & (P.TreatNewCoursesRate), 1, 1, 0)) P.TreatNewCoursesRate = 0;
1343  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Maximum number of people targeted with radial prophylaxis per case", "%i", (void*) & (P.TreatMaxCoursesPerCase), 1, 1, 0)) P.TreatMaxCoursesPerCase = 1000000000;
1344 
1345 
1346  if (P.DoAdUnits)
1347  {
1348  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Treat administrative units rather than rings", "%i", (void*) & (P.TreatByAdminUnit), 1, 1, 0)) P.TreatByAdminUnit = 0;
1349  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Administrative unit divisor for treatment", "%i", (void*) & (P.TreatAdminUnitDivisor), 1, 1, 0)) P.TreatAdminUnitDivisor = 1;
1350  if ((P.TreatAdminUnitDivisor == 0) || (P.TreatByAdminUnit == 0)) { P.TreatByAdminUnit = 0; P.TreatAdminUnitDivisor = 1; }
1351  }
1352  else
1353  {
1354  P.TreatAdminUnitDivisor = 1; P.TreatByAdminUnit = 0;
1355  }
1356 
1357  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Vaccination trigger incidence per cell", "%lf", (void*) & (P.VaccCellIncThresh), 1, 1, 0)) P.VaccCellIncThresh = 1000000000;
1358  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative susceptibility of vaccinated individual", "%lf", (void*) & (P.VaccSuscDrop), 1, 1, 0)) P.VaccSuscDrop = 1;
1359  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative susceptibility of individual vaccinated after switch time", "%lf", (void*) & (P.VaccSuscDrop2), 1, 1, 0)) P.VaccSuscDrop2 = 1;
1360  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Switch time at which vaccine efficacy increases", "%lf", (void*) & (P.VaccTimeEfficacySwitch), 1, 1, 0)) P.VaccTimeEfficacySwitch = USHRT_MAX / P.TimeStepsPerDay;
1361  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Decay rate of vaccine efficacy (per year)", "%lf", (void*) & (P.VaccEfficacyDecay), 1, 1, 0)) P.VaccEfficacyDecay = 0;
1362  P.VaccEfficacyDecay /= DAYS_PER_YEAR;
1363  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative infectiousness of vaccinated individual", "%lf", (void*) & (P.VaccInfDrop), 1, 1, 0)) P.VaccInfDrop = 1;
1364  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of symptomatic cases resulting in death prevented by vaccination", "%lf", (void*) & (P.VaccMortDrop), 1, 1, 0)) P.VaccMortDrop = 0;
1365  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of symptomatic cases prevented by vaccination", "%lf", (void*) & (P.VaccSympDrop), 1, 1, 0)) P.VaccSympDrop = 0;
1366  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to vaccinate", "%lf", (void*) & (P.VaccDelayMean), 1, 1, 0)) P.VaccDelayMean = 0;
1367 
1368  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay from vaccination to full protection", "%lf", (void*) & (P.VaccTimeToEfficacy), 1, 1, 0)) P.VaccTimeToEfficacy = 0;
1369 
1370  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Years between rounds of vaccination", "%lf", (void*) & (P.VaccCampaignInterval), 1, 1, 0)) P.VaccCampaignInterval = 1e10;
1371  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Max vaccine doses per day", "%i", (void*) & (P.VaccDosePerDay), 1, 1, 0)) P.VaccDosePerDay = -1;
1372  P.VaccCampaignInterval *= DAYS_PER_YEAR;
1373  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Maximum number of rounds of vaccination", "%i", (void*) & (P.VaccMaxRounds), 1, 1, 0)) P.VaccMaxRounds = 1;
1374  if (P.DoHouseholds)
1375  {
1376  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of households of cases vaccinated", "%lf", (void*) & (P.VaccPropCaseHouseholds), 1, 1, 0)) P.VaccPropCaseHouseholds = 0;
1377  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of household vaccination policy", "%lf", (void*) & (P.VaccHouseholdsDuration), 1, 1, 0)) P.VaccHouseholdsDuration = USHRT_MAX / P.TimeStepsPerDay;
1378  }
1379 
1380  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Vaccination start time", "%lf", (void*) & (P.VaccTimeStartBase), 1, 1, 0)) P.VaccTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1381  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of population vaccinated", "%lf", (void*) & (P.VaccProp), 1, 1, 0)) P.VaccProp = 0;
1382  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Time taken to reach max vaccination coverage (in years)", "%lf", (void*) & (P.VaccCoverageIncreasePeriod), 1, 1, 0)) P.VaccCoverageIncreasePeriod = 0;
1383  P.VaccCoverageIncreasePeriod *= DAYS_PER_YEAR;
1384  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Time to start geographic vaccination", "%lf", (void*) & (P.VaccTimeStartGeo), 1, 1, 0)) P.VaccTimeStartGeo = 1e10;
1385  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Vaccination radius", "%lf", (void*) & (P.VaccRadius), 1, 1, 0)) P.VaccRadius = 0;
1386  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Minimum radius from case to vaccinate", "%lf", (void*) & (P.VaccMinRadius), 1, 1, 0)) P.VaccMinRadius = 0;
1387  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Maximum number of vaccine courses available", "%lf", (void*) & (P.VaccMaxCoursesBase), 1, 1, 0)) P.VaccMaxCoursesBase = 1e20;
1388  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Start time of additional vaccine production", "%lf", (void*) & (P.VaccNewCoursesStartTime), 1, 1, 0)) P.VaccNewCoursesStartTime = USHRT_MAX / P.TimeStepsPerDay;
1389  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "End time of additional vaccine production", "%lf", (void*) & (P.VaccNewCoursesEndTime), 1, 1, 0)) P.VaccNewCoursesEndTime = USHRT_MAX / P.TimeStepsPerDay;
1390  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Rate of additional vaccine production (courses per day)", "%lf", (void*) & (P.VaccNewCoursesRate), 1, 1, 0)) P.VaccNewCoursesRate = 0;
1391  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Apply mass rather than reactive vaccination", "%i", (void*) & (P.DoMassVacc), 1, 1, 0)) P.DoMassVacc = 0;
1392  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Priority age range for mass vaccination", "%i", (void*)P.VaccPriorityGroupAge, 2, 1, 0)) { P.VaccPriorityGroupAge[0] = 1; P.VaccPriorityGroupAge[1] = 0; }
1393  if (P.DoAdUnits)
1394  {
1395  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Vaccinate administrative units rather than rings", "%i", (void*) & (P.VaccByAdminUnit), 1, 1, 0)) P.VaccByAdminUnit = 0;
1396  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Administrative unit divisor for vaccination", "%i", (void*) & (P.VaccAdminUnitDivisor), 1, 1, 0)) P.VaccAdminUnitDivisor = 1;
1397  if ((P.VaccAdminUnitDivisor == 0) || (P.VaccByAdminUnit == 0)) P.VaccAdminUnitDivisor = 1;
1398  }
1399  else
1400  {
1401  P.VaccAdminUnitDivisor = 1; P.VaccByAdminUnit = 0;
1402  }
1403 
1404  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Movement restrictions trigger incidence per cell", "%i", (void*) & (P.MoveRestrCellIncThresh), 1, 1, 0)) P.MoveRestrCellIncThresh = 1000000000;
1405  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to start movement restrictions", "%lf", (void*) & (P.MoveDelayMean), 1, 1, 0)) P.MoveDelayMean = 0;
1406  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of movement restrictions", "%lf", (void*) & (P.MoveRestrDuration), 1, 1, 0)) P.MoveRestrDuration = 7;
1407  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual movements after restrictions", "%lf", (void*) & (P.MoveRestrEffect), 1, 1, 0)) P.MoveRestrEffect = 0;
1408  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Minimum radius of movement restrictions", "%lf", (void*) & (P.MoveRestrRadius), 1, 1, 0)) P.MoveRestrRadius = 0;
1409  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Movement restrictions start time", "%lf", (void*) & (P.MoveRestrTimeStartBase), 1, 1, 0)) P.MoveRestrTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1410  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Impose blanket movement restrictions", "%i", (void*) & (P.DoBlanketMoveRestr), 1, 1, 0)) P.DoBlanketMoveRestr = 0;
1411  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Movement restrictions only once", "%i", (void*) & (P.DoMoveRestrOnceOnly), 1, 1, 0)) P.DoMoveRestrOnceOnly = 0;
1412  if (P.DoMoveRestrOnceOnly) P.DoMoveRestrOnceOnly = 4;
1413  if (P.DoAdUnits)
1414  {
1415  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Movement restrictions in administrative units rather than rings", "%i", (void*) & (P.MoveRestrByAdminUnit), 1, 1, 0)) P.MoveRestrByAdminUnit = 0;
1416  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Administrative unit divisor for movement restrictions", "%i", (void*) & (P.MoveRestrAdminUnitDivisor), 1, 1, 0)) P.MoveRestrAdminUnitDivisor = 1;
1417  if ((P.MoveRestrAdminUnitDivisor == 0) || (P.MoveRestrByAdminUnit == 0)) P.MoveRestrAdminUnitDivisor = 1;
1418  }
1419  else
1420  {
1421  P.MoveRestrAdminUnitDivisor = 1; P.MoveRestrByAdminUnit = 0;
1422  }
1423 
1424  //Intervention delays and durations by admin unit: ggilani 16/03/20
1425  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Include intervention delays by admin unit", "%i", (void*) & (P.DoInterventionDelaysByAdUnit), 1, 1, 0)) P.DoInterventionDelaysByAdUnit = 0;
1426  if (P.DoInterventionDelaysByAdUnit)
1427  {
1428  //Set up arrays to temporarily store parameters per admin unit
1429  double AdunitDelayToSocialDistance [MAX_ADUNITS];
1430  double AdunitDelayToHQuarantine [MAX_ADUNITS];
1431  double AdunitDelayToCaseIsolation [MAX_ADUNITS];
1432  double AdunitDelayToPlaceClose [MAX_ADUNITS];
1433  double AdunitDurationSocialDistance [MAX_ADUNITS];
1434  double AdunitDurationHQuarantine [MAX_ADUNITS];
1435  double AdunitDurationCaseIsolation [MAX_ADUNITS];
1436  double AdunitDurationPlaceClose [MAX_ADUNITS];
1437 
1438  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to social distancing by admin unit" , "%lf", (void*)AdunitDelayToSocialDistance , P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDelayToSocialDistance [i] = 0;
1439  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to household quarantine by admin unit" , "%lf", (void*)AdunitDelayToHQuarantine , P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDelayToHQuarantine [i] = 0;
1440  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to case isolation by admin unit" , "%lf", (void*)AdunitDelayToCaseIsolation , P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDelayToCaseIsolation [i] = 0;
1441  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to place closure by admin unit" , "%lf", (void*)AdunitDelayToPlaceClose , P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDelayToPlaceClose [i] = 0;
1442  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of social distancing by admin unit" , "%lf", (void*)AdunitDurationSocialDistance, P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDurationSocialDistance [i] = 0;
1443  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of household quarantine by admin unit" , "%lf", (void*)AdunitDurationHQuarantine , P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDurationHQuarantine [i] = 0;
1444  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of case isolation by admin unit" , "%lf", (void*)AdunitDurationCaseIsolation , P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDurationCaseIsolation [i] = 0;
1445  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of place closure by admin unit" , "%lf", (void*)AdunitDurationPlaceClose , P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDurationPlaceClose [i] = 0;
1446 
1447  for (i = 0; i < P.NumAdunits; i++)
1448  {
1449  AdUnits[i].SocialDistanceDelay = AdunitDelayToSocialDistance [i];
1450  AdUnits[i].SocialDistanceDuration = AdunitDurationSocialDistance [i];
1451  AdUnits[i].HQuarantineDelay = AdunitDelayToHQuarantine [i];
1452  AdUnits[i].HQuarantineDuration = AdunitDurationHQuarantine [i];
1453  AdUnits[i].CaseIsolationDelay = AdunitDelayToCaseIsolation [i];
1454  AdUnits[i].CaseIsolationPolicyDuration = AdunitDurationCaseIsolation [i];
1455  AdUnits[i].PlaceCloseDelay = AdunitDelayToPlaceClose [i];
1456  AdUnits[i].PlaceCloseDuration = AdunitDurationPlaceClose [i];
1457  }
1458  }
1459 
1463 
1464  //New code for digital contact tracing - ggilani: 09/03/20
1465  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Include digital contact tracing", "%i", (void*) & (P.DoDigitalContactTracing), 1, 1, 0)) P.DoDigitalContactTracing = 0;
1466  if (P.DoDigitalContactTracing)
1467  {
1468  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Digital contact tracing trigger incidence per cell", "%lf", (void*) & (P.DigitalContactTracing_CellIncThresh), 1, 1, 0)) P.DigitalContactTracing_CellIncThresh = 1000000000;
1469 
1470  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of population or households covered by digital contact tracing", "%lf", (void*) & (P.PropPopUsingDigitalContactTracing), 1, 1, 0)) P.PropPopUsingDigitalContactTracing = 1;
1471  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of smartphone users by age", "%lf", (void*)P.ProportionSmartphoneUsersByAge, NUM_AGE_GROUPS, 1, 0))
1472  {
1473  for (i = 0; i < NUM_AGE_GROUPS; i++)
1474  {
1475  P.ProportionSmartphoneUsersByAge[i] = 1;
1476  }
1477  }
1478  if (P.DoPlaces)
1479  {
1480  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Cluster digital app clusters by household", "%i", (void*) & (P.ClusterDigitalContactUsers), 1, 1, 0)) P.ClusterDigitalContactUsers = 0; // by default, don't cluster by location
1481  }
1482  else
1483  {
1484  P.ClusterDigitalContactUsers = 0;
1485  }
1486  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of digital contacts who self-isolate", "%lf", (void*) & (P.ProportionDigitalContactsIsolate), 1, 1, 0)) P.ProportionDigitalContactsIsolate = 0;
1487  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Maximum number of contacts to trace per index case", "%i", (void*)&(P.MaxDigitalContactsToTrace), 1, 1, 0)) P.MaxDigitalContactsToTrace = MAX_CONTACTS;
1488  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay between isolation of index case and contacts", "%lf", (void*) & (P.DigitalContactTracingDelay), 1, 1, 0)) P.DigitalContactTracingDelay = P.TimeStep;
1489  //we really need one timestep between to make sure contact is not processed before index
1490  if (P.DigitalContactTracingDelay == 0) P.DigitalContactTracingDelay = P.TimeStep;
1491  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Length of self-isolation for digital contacts", "%lf", (void*) & (P.LengthDigitalContactIsolation), 1, 1, 0)) P.LengthDigitalContactIsolation = 0;
1492  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Spatial scaling factor - digital contact tracing", "%lf", (void*) & (P.ScalingFactorSpatialDigitalContacts), 1, 1, 0)) P.ScalingFactorSpatialDigitalContacts = 1;
1493  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place scaling factor - digital contact tracing", "%lf", (void*)&(P.ScalingFactorPlaceDigitalContacts), 1, 1, 0)) P.ScalingFactorPlaceDigitalContacts = 1;
1494  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Digital contact tracing start time", "%lf", (void*) & (P.DigitalContactTracingTimeStartBase), 1, 1, 0)) P.DigitalContactTracingTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1495  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of digital contact tracing policy", "%lf", (void*) & (P.DigitalContactTracingPolicyDuration), 1, 1, 0)) P.DigitalContactTracingPolicyDuration = 7;
1496  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Output digital contact tracing", "%i", (void*) & (P.OutputDigitalContactTracing), 1, 1, 0)) P.OutputDigitalContactTracing = 0;
1497  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Output digital contact distribution", "%i", (void*)&(P.OutputDigitalContactDist), 1, 1, 0)) P.OutputDigitalContactDist = 0;
1498 
1499  //if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Include household contacts in digital contact tracing", "%i", (void*) & (P.IncludeHouseholdDigitalContactTracing), 1, 1, 0)) P.IncludeHouseholdDigitalContactTracing = 1;
1500  //if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Include place group contacts in digital contact tracing", "%i", (void*) & (P.IncludePlaceGroupDigitalContactTracing), 1, 1, 0)) P.IncludePlaceGroupDigitalContactTracing = 1;
1501 
1502  //added admin unit specific delays by admin unit
1503  if (P.DoInterventionDelaysByAdUnit)
1504  {
1505  double AdunitDelayToDCT[MAX_ADUNITS];
1506  double AdunitDurationDCT[MAX_ADUNITS];
1507 
1508  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to digital contact tracing by admin unit", "%lf", (void*)AdunitDelayToDCT, P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDelayToDCT[i] = 0;
1509  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of digital contact tracing by admin unit", "%lf", (void*)AdunitDurationDCT, P.NumAdunits, 1, 0)) for (i = 0; i < P.NumAdunits; i++) AdunitDurationDCT[i] = 0;
1510  for (i = 0; i < P.NumAdunits; i++)
1511  {
1512  AdUnits[i].DCTDelay = AdunitDelayToDCT[i];
1513  AdUnits[i].DCTDuration = AdunitDurationDCT[i];
1514  }
1515  }
1516  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Isolate index cases in digital contact tracing", "%i", (void*)&(P.DCTIsolateIndexCases), 1, 1, 0)) P.DCTIsolateIndexCases = 1;
1517  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual contacts after digital contact tracing isolation", "%lf", (void*)&(P.DCTCaseIsolationEffectiveness), 1, 1, 0)) P.DCTCaseIsolationEffectiveness = P.CaseIsolationEffectiveness;
1518  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual household contacts after digital contact tracing isolation", "%lf", (void*)&(P.DCTCaseIsolationHouseEffectiveness), 1, 1, 0)) P.DCTCaseIsolationHouseEffectiveness = P.CaseIsolationHouseEffectiveness;
1519  //initialise total number of users to 0
1520  P.NDigitalContactUsers = 0;
1521  P.NDigitalHouseholdUsers = 0;
1522 
1523  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay between symptom onset and isolation for index case", "%lf", (void*)&(P.DelayFromIndexCaseDetectionToDCTIsolation), 1, 1, 0)) P.DelayFromIndexCaseDetectionToDCTIsolation = 0;
1524  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Test index cases and contacts", "%i", (void*)&(P.DoDCTTest), 1, 1, 0)) P.DoDCTTest = 0;
1525  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to test index case", "%lf", (void*)&(P.DelayToTestIndexCase), 1, 1, 0)) P.DelayToTestIndexCase = 1;
1526  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to test DCT contacts", "%lf", (void*)&(P.DelayToTestDCTContacts), 1, 1, 0)) P.DelayToTestDCTContacts = 7;
1527  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Testing specificity - DCT", "%lf", (void*)&(P.SpecificityDCT), 1, 1, 0)) P.SpecificityDCT = 1;
1528  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Testing sensitivity - DCT", "%lf", (void*)&(P.SensitivityDCT), 1, 1, 0)) P.SensitivityDCT = 1;
1529  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Find contacts of digital contacts", "%i", (void*)&(P.FindContactsOfDCTContacts), 1, 1, 0)) P.FindContactsOfDCTContacts = 0;
1530  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Remove contacts of a negative index case", "%i", (void*)&(P.RemoveContactsOfNegativeIndexCase), 1, 1, 0)) P.RemoveContactsOfNegativeIndexCase = 0;
1531  }
1532  else
1533  {
1534  //Set these to 1 so it doesn't interfere with code if we aren't using digital contact tracing.
1535 
1536  P.ScalingFactorSpatialDigitalContacts = 1;
1537  P.ScalingFactorPlaceDigitalContacts = 1;
1538  }
1539 
1543 
1544 
1545  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Trigger incidence per cell for place closure", "%i", (void*) & (P.PlaceCloseCellIncThresh1), 1, 1, 0)) P.PlaceCloseCellIncThresh1 = 1000000000;
1546  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Trigger incidence per cell for second place closure", "%i", (void*)&(P.PlaceCloseCellIncThresh2), 1, 1, 0)) P.PlaceCloseCellIncThresh2 = 1000000000;
1547  if (P.PlaceCloseCellIncThresh1 < 0) P.PlaceCloseCellIncThresh1 = 1000000000;
1548  if (P.PlaceCloseCellIncThresh2 < 0) P.PlaceCloseCellIncThresh2 = 1000000000;
1549  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Trigger incidence per cell for end of place closure", "%i", (void*) & (P.PlaceCloseCellIncStopThresh), 1, 1, 0)) P.PlaceCloseCellIncStopThresh = 0;
1550  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to start place closure", "%lf", (void*) & (P.PlaceCloseDelayMean), 1, 1, 0)) P.PlaceCloseDelayMean = 0;
1551  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of place closure", "%lf", (void*) & (P.PlaceCloseDurationBase), 1, 1, 0)) P.PlaceCloseDurationBase = 7;
1552  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of second place closure", "%lf", (void*) & (P.PlaceCloseDuration2), 1, 1, 0)) P.PlaceCloseDuration2 = 7;
1553  if (P.DoPlaces)
1554  {
1555  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of places remaining open after closure by place type", "%lf", (void*)P.PlaceCloseEffect, P.PlaceTypeNum, 1, 0))
1556  for (i = 0; i < NUM_PLACE_TYPES; i++) P.PlaceCloseEffect[i] = 1;
1557  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportional attendance after closure by place type", "%lf", (void*)P.PlaceClosePropAttending, P.PlaceTypeNum, 1, 0))
1558  for (i = 0; i < NUM_PLACE_TYPES; i++) P.PlaceClosePropAttending[i] = 0;
1559  }
1560  if (P.DoHouseholds)
1561  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rate after closure", "%lf", (void*)& P.PlaceCloseHouseholdRelContact, 1, 1, 0)) P.PlaceCloseHouseholdRelContact = 1;
1562  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative spatial contact rate after closure", "%lf", (void*)& P.PlaceCloseSpatialRelContact, 1, 1, 0)) P.PlaceCloseSpatialRelContact = 1;
1563 
1564  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Include holidays", "%i", (void*) & (P.DoHolidays), 1, 1, 0)) P.DoHolidays = 0;
1565  if (P.DoHolidays)
1566  {
1567  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Proportion of places remaining open during holidays by place type", "%lf", (void*)P.HolidayEffect, P.PlaceTypeNum, 1, 0))
1568  for (i = 0; i < NUM_PLACE_TYPES; i++) P.HolidayEffect[i] = 1;
1569  if (!GetInputParameter2(PreParamFile_dat, AdminFile_dat, "Number of holidays", "%i", (void*) & (P.NumHolidays), 1, 1, 0)) P.NumHolidays = 0;
1570  if (P.NumHolidays > DAYS_PER_YEAR) P.NumHolidays = DAYS_PER_YEAR;
1571  if (P.NumHolidays > 0)
1572  {
1573  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Holiday start times", "%lf", (void*)P.HolidayStartTime, P.NumHolidays, 1, 0);
1574  GetInputParameter(PreParamFile_dat, AdminFile_dat, "Holiday durations", "%lf", (void*)P.HolidayDuration, P.NumHolidays, 1, 0);
1575  }
1576  }
1577  else
1578  P.NumHolidays = 0;
1579  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Minimum radius for place closure", "%lf", (void*) & (P.PlaceCloseRadius), 1, 1, 0)) P.PlaceCloseRadius = 0;
1580  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place closure start time", "%lf", (void*) & (P.PlaceCloseTimeStartBase), 1, 1, 0)) P.PlaceCloseTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1581  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place closure second start time", "%lf", (void*) & (P.PlaceCloseTimeStartBase2), 1, 1, 0)) P.PlaceCloseTimeStartBase2 = USHRT_MAX / P.TimeStepsPerDay;
1582  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Places close only once", "%i", (void*) & (P.DoPlaceCloseOnceOnly), 1, 1, 0)) P.DoPlaceCloseOnceOnly = 0;
1583  if (P.DoPlaceCloseOnceOnly) P.DoPlaceCloseOnceOnly = 4;
1584  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place closure incidence threshold", "%i", (void*) & (P.PlaceCloseIncTrig1), 1, 1, 0)) P.PlaceCloseIncTrig1 = 1;
1585  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place closure second incidence threshold", "%i", (void*)&(P.PlaceCloseIncTrig2), 1, 1, 0)) P.PlaceCloseIncTrig2 = P.PlaceCloseIncTrig1;
1586  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place closure fractional incidence threshold", "%lf", (void*) & (P.PlaceCloseFracIncTrig), 1, 1, 0)) P.PlaceCloseFracIncTrig = 0;
1587  if ((P.DoAdUnits) && (P.DoPlaces))
1588  {
1589  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place closure in administrative units rather than rings", "%i", (void*) & (P.PlaceCloseByAdminUnit), 1, 1, 0)) P.PlaceCloseByAdminUnit = 0;
1590  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Administrative unit divisor for place closure", "%i", (void*) & (P.PlaceCloseAdminUnitDivisor), 1, 1, 0)) P.PlaceCloseAdminUnitDivisor = 1;
1591  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place types to close for admin unit closure (0/1 array)", "%i", (void*) & (P.PlaceCloseAdunitPlaceTypes), P.PlaceTypeNum, 1, 0))
1592  for (i = 0; i < P.PlaceTypeNum; i++) P.PlaceCloseAdunitPlaceTypes[i] = 0;
1593  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Cumulative proportion of place members needing to become sick for admin unit closure", "%lf", (void*) & (P.PlaceCloseCasePropThresh), 1, 1, 0)) P.PlaceCloseCasePropThresh = 2;
1594  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of places in admin unit needing to pass threshold for place closure", "%lf", (void*) & (P.PlaceCloseAdunitPropThresh), 1, 1, 0)) P.PlaceCloseAdunitPropThresh = 2;
1595  if ((P.PlaceCloseAdminUnitDivisor < 1) || (P.PlaceCloseByAdminUnit == 0)) P.PlaceCloseAdminUnitDivisor = 1;
1596  }
1597  else
1598  {
1599  P.PlaceCloseAdminUnitDivisor = 1; P.PlaceCloseByAdminUnit = 0;
1600  }
1601 
1605 
1606  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Trigger incidence per cell for social distancing", "%i", (void*) & (P.SocDistCellIncThresh), 1, 1, 0)) P.SocDistCellIncThresh = 1000000000;
1607  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Trigger incidence per cell for end of social distancing", "%i", (void*) & (P.SocDistCellIncStopThresh), 1, 1, 0)) P.SocDistCellIncStopThresh = 0;
1608  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of social distancing", "%lf", (void*) & (P.SocDistDuration), 1, 1, 0)) P.SocDistDuration = 7;
1609  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of social distancing after change", "%lf", (void*) & (P.SocDistDuration2), 1, 1, 0)) P.SocDistDuration2 = 7;
1610  if (P.DoPlaces)
1611  {
1612  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative place contact rate given social distancing by place type", "%lf", (void*)P.SocDistPlaceEffect, P.PlaceTypeNum, 1, 0))
1613  for (i = 0; i < NUM_PLACE_TYPES; i++) P.SocDistPlaceEffect[i] = 1;
1614  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative place contact rate given enhanced social distancing by place type", "%lf", (void*)P.EnhancedSocDistPlaceEffect, P.PlaceTypeNum, 1, 0))
1615  for (i = 0; i < NUM_PLACE_TYPES; i++) P.EnhancedSocDistPlaceEffect[i] = 1;
1616  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative place contact rate given social distancing by place type after change", "%lf", (void*)P.SocDistPlaceEffect2, P.PlaceTypeNum, 1, 0))
1617  for (i = 0; i < NUM_PLACE_TYPES; i++) P.SocDistPlaceEffect2[i] = P.SocDistPlaceEffect[i];
1618  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative place contact rate given enhanced social distancing by place type after change", "%lf", (void*)P.EnhancedSocDistPlaceEffect2, P.PlaceTypeNum, 1, 0))
1619  for (i = 0; i < NUM_PLACE_TYPES; i++) P.EnhancedSocDistPlaceEffect2[i] = P.EnhancedSocDistPlaceEffect[i];
1620  }
1621  if (P.DoHouseholds)
1622  {
1623  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rate given social distancing", "%lf", (void*)&P.SocDistHouseholdEffect, 1, 1, 0)) P.SocDistHouseholdEffect = 1;
1624  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rate given enhanced social distancing", "%lf", (void*)&P.EnhancedSocDistHouseholdEffect, 1, 1, 0)) P.EnhancedSocDistHouseholdEffect = 1;
1625  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rate given social distancing after change", "%lf", (void*)&P.SocDistHouseholdEffect2, 1, 1, 0)) P.SocDistHouseholdEffect2 = P.SocDistHouseholdEffect;
1626  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rate given enhanced social distancing after change", "%lf", (void*)&P.EnhancedSocDistHouseholdEffect2, 1, 1, 0)) P.EnhancedSocDistHouseholdEffect2 = P.EnhancedSocDistHouseholdEffect;
1627  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Cluster compliance with enhanced social distancing by household", "%i", (void*)&P.EnhancedSocDistClusterByHousehold, 1, 1, 0)) P.EnhancedSocDistClusterByHousehold = 0;
1628  }
1629  else
1630  P.EnhancedSocDistClusterByHousehold = 0;
1631  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative spatial contact rate given social distancing", "%lf", (void*)& P.SocDistSpatialEffect, 1, 1, 0)) P.SocDistSpatialEffect = 1;
1632  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative spatial contact rate given social distancing after change", "%lf", (void*)&P.SocDistSpatialEffect2, 1, 1, 0)) P.SocDistSpatialEffect2 = P.SocDistSpatialEffect;
1633  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Minimum radius for social distancing", "%lf", (void*) & (P.SocDistRadius), 1, 1, 0)) P.SocDistRadius = 0;
1634  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Social distancing start time", "%lf", (void*) & (P.SocDistTimeStartBase), 1, 1, 0)) P.SocDistTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1635  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay for change in effectiveness of social distancing", "%lf", (void*)&(P.SocDistChangeDelay), 1, 1, 0)) P.SocDistChangeDelay = USHRT_MAX / P.TimeStepsPerDay;
1636  if(!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion compliant with enhanced social distancing by age group", "%lf", (void*)P.EnhancedSocDistProportionCompliant, NUM_AGE_GROUPS, 1, 0))
1637  {
1638  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion compliant with enhanced social distancing", "%lf", (void*)&t, 1, 1, 0)) t = 0;
1639  for (i = 0; i < NUM_AGE_GROUPS; i++)
1640  P.EnhancedSocDistProportionCompliant[i] = t;
1641  }
1642  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative spatial contact rate given enhanced social distancing", "%lf", (void*)& P.EnhancedSocDistSpatialEffect, 1, 1, 0)) P.EnhancedSocDistSpatialEffect = 1;
1643  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative spatial contact rate given enhanced social distancing after change", "%lf", (void*)&P.EnhancedSocDistSpatialEffect2, 1, 1, 0)) P.EnhancedSocDistSpatialEffect2 = P.EnhancedSocDistSpatialEffect;
1644 
1645  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Social distancing only once", "%i", (void*) & (P.DoSocDistOnceOnly), 1, 1, 0)) P.DoSocDistOnceOnly = 0;
1646  if (P.DoSocDistOnceOnly) P.DoSocDistOnceOnly = 4;
1647 
1648  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Airport closure effectiveness", "%lf", (void*) & (P.AirportCloseEffectiveness), 1, 1, 0)) P.AirportCloseEffectiveness = 0;
1649  P.AirportCloseEffectiveness = 1.0 - P.AirportCloseEffectiveness;
1650  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Airport closure start time", "%lf", (void*) & (P.AirportCloseTimeStartBase), 1, 1, 0)) P.AirportCloseTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1651  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Airport closure duration", "%lf", (void*) & (P.AirportCloseDuration), 1, 1, 0)) P.AirportCloseDuration = USHRT_MAX / P.TimeStepsPerDay;
1652 
1656 
1657  if (P.DoHouseholds)
1658  {
1659  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Retrigger household quarantine with each new case in quarantine window", "%i", (void*) & (P.DoHQretrigger), 1, 1, 0)) P.DoHQretrigger =0;
1660  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Household quarantine start time", "%lf", (void*) & (P.HQuarantineTimeStartBase), 1, 1, 0)) P.HQuarantineTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1661  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to start household quarantine", "%lf", (void*) & (P.HQuarantineDelay), 1, 1, 0)) P.HQuarantineDelay = 0;
1662  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Length of time households are quarantined", "%lf", (void*) & (P.HQuarantineHouseDuration), 1, 1, 0)) P.HQuarantineHouseDuration = 0;
1663  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of household quarantine policy", "%lf", (void*) & (P.HQuarantinePolicyDuration), 1, 1, 0)) P.HQuarantinePolicyDuration = USHRT_MAX / P.TimeStepsPerDay;
1664  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rate after quarantine", "%lf", (void*) & (P.HQuarantineHouseEffect), 1, 1, 0)) P.HQuarantineHouseEffect = 1;
1665  if (P.DoPlaces)
1666  {
1667  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual place contacts after household quarantine by place type", "%lf", (void*)P.HQuarantinePlaceEffect, P.PlaceTypeNum, 1, 0))
1668  for (i = 0; i < NUM_PLACE_TYPES; i++) P.HQuarantinePlaceEffect[i] = 1;
1669  }
1670  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual spatial contacts after household quarantine", "%lf", (void*) & (P.HQuarantineSpatialEffect), 1, 1, 0)) P.HQuarantineSpatialEffect = 1;
1671  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Household level compliance with quarantine", "%lf", (void*) & (P.HQuarantinePropHouseCompliant), 1, 1, 0)) P.HQuarantinePropHouseCompliant = 1;
1672  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Individual level compliance with quarantine", "%lf", (void*) & (P.HQuarantinePropIndivCompliant), 1, 1, 0)) P.HQuarantinePropIndivCompliant = 1;
1673  }
1674  else
1675  P.HQuarantineTimeStartBase = 1e10;
1676  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Case isolation start time", "%lf", (void*) & (P.CaseIsolationTimeStartBase), 1, 1, 0)) P.CaseIsolationTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1677  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of detected cases isolated", "%lf", (void*) & (P.CaseIsolationProp), 1, 1, 0)) P.CaseIsolationProp = 0;
1678  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Delay to start case isolation", "%lf", (void*) & (P.CaseIsolationDelay), 1, 1, 0)) P.CaseIsolationDelay = 0;
1679  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of case isolation", "%lf", (void*) & (P.CaseIsolationDuration), 1, 1, 0)) P.CaseIsolationDuration = 0;
1680  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of case isolation policy", "%lf", (void*) & (P.CaseIsolationPolicyDuration), 1, 1, 0)) P.CaseIsolationPolicyDuration = 1e10;
1681  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual contacts after case isolation", "%lf", (void*) & (P.CaseIsolationEffectiveness), 1, 1, 0)) P.CaseIsolationEffectiveness = 1;
1682  if (P.DoHouseholds)
1683  {
1684  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual household contacts after case isolation", "%lf", (void*) & (P.CaseIsolationHouseEffectiveness), 1, 1, 0))
1685  P.CaseIsolationHouseEffectiveness = P.CaseIsolationEffectiveness;
1686  }
1687 
1691 
1692  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Vary efficacies over time", "%i", (void*) & (P.VaryEfficaciesOverTime), 1, 1, 0)) P.VaryEfficaciesOverTime = 0;
1694  if (!P.VaryEfficaciesOverTime)
1695  {
1696  P.Num_SD_ChangeTimes = 1;
1697  P.Num_CI_ChangeTimes = 1;
1698  P.Num_HQ_ChangeTimes = 1;
1699  P.Num_PC_ChangeTimes = 1;
1700  P.Num_DCT_ChangeTimes = 1;
1701  }
1702  else
1703  {
1704  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of change times for levels of social distancing" , "%i", (void*) & (P.Num_SD_ChangeTimes) , 1, 1, 0)) P.Num_SD_ChangeTimes = 1;
1705  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of change times for levels of case isolation" , "%i", (void*) & (P.Num_CI_ChangeTimes) , 1, 1, 0)) P.Num_CI_ChangeTimes = 1;
1706  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of change times for levels of household quarantine" , "%i", (void*) & (P.Num_HQ_ChangeTimes) , 1, 1, 0)) P.Num_HQ_ChangeTimes = 1;
1707  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of change times for levels of place closure" , "%i", (void*) & (P.Num_PC_ChangeTimes) , 1, 1, 0)) P.Num_PC_ChangeTimes = 1;
1708  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of change times for levels of digital contact tracing" , "%i", (void*) & (P.Num_DCT_ChangeTimes) , 1, 1, 0)) P.Num_DCT_ChangeTimes = 1;
1709  }
1710 
1713  P.SD_ChangeTimes [0] = 0;
1714  P.CI_ChangeTimes [0] = 0;
1715  P.HQ_ChangeTimes [0] = 0;
1716  P.PC_ChangeTimes [0] = 0;
1717  P.DCT_ChangeTimes [0] = 0;
1718  for (int ChangeTime = 1; ChangeTime < MAX_NUM_INTERVENTION_CHANGE_TIMES; ChangeTime++)
1719  {
1720  P.SD_ChangeTimes [ChangeTime] = 1e10;
1721  P.CI_ChangeTimes [ChangeTime] = 1e10;
1722  P.HQ_ChangeTimes [ChangeTime] = 1e10;
1723  P.PC_ChangeTimes [ChangeTime] = 1e10;
1724  P.DCT_ChangeTimes [ChangeTime] = 1e10;
1725  }
1727  GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Change times for levels of social distancing" , "%lf", (void*)P.SD_ChangeTimes , P.Num_SD_ChangeTimes , 1, 0);
1728  GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Change times for levels of case isolation" , "%lf", (void*)P.CI_ChangeTimes , P.Num_CI_ChangeTimes , 1, 0);
1729  GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Change times for levels of household quarantine" , "%lf", (void*)P.HQ_ChangeTimes , P.Num_HQ_ChangeTimes , 1, 0);
1730  GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Change times for levels of place closure" , "%lf", (void*)P.PC_ChangeTimes , P.Num_PC_ChangeTimes , 1, 0);
1731  GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Change times for levels of digital contact tracing", "%lf", (void*)P.DCT_ChangeTimes, P.Num_DCT_ChangeTimes , 1, 0);
1732 
1733  // initialize to zero (regardless of whether doing places or households).
1734  for (int ChangeTime = 0; ChangeTime < MAX_NUM_INTERVENTION_CHANGE_TIMES; ChangeTime++)
1735  {
1738  P.SD_SpatialEffects_OverTime [ChangeTime] = 0;
1739  P.Enhanced_SD_SpatialEffects_OverTime [ChangeTime] = 0;
1740  P.CI_SpatialAndPlaceEffects_OverTime [ChangeTime] = 0;
1741  P.HQ_SpatialEffects_OverTime [ChangeTime] = 0;
1742  P.PC_SpatialEffects_OverTime [ChangeTime] = 0;
1743  P.DCT_SpatialAndPlaceEffects_OverTime [ChangeTime] = 0;
1744 
1746  P.SD_HouseholdEffects_OverTime [ChangeTime] = 0;
1747  P.Enhanced_SD_HouseholdEffects_OverTime [ChangeTime] = 0;
1748  P.CI_HouseholdEffects_OverTime [ChangeTime] = 0;
1749  P.HQ_HouseholdEffects_OverTime [ChangeTime] = 0;
1750  P.PC_HouseholdEffects_OverTime [ChangeTime] = 0;
1751  P.DCT_HouseholdEffects_OverTime [ChangeTime] = 0;
1752 
1754  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1755  {
1756  P.SD_PlaceEffects_OverTime [ChangeTime][PlaceType] = 0;
1757  P.Enhanced_SD_PlaceEffects_OverTime [ChangeTime][PlaceType] = 0;
1758  P.HQ_PlaceEffects_OverTime [ChangeTime][PlaceType] = 0;
1759  P.PC_PlaceEffects_OverTime [ChangeTime][PlaceType] = 0;
1760  }
1761  P.PC_Durs_OverTime[ChangeTime] = 0;
1762 
1764  P.CI_Prop_OverTime [ChangeTime] = 0;
1765  P.HQ_Individual_PropComply_OverTime [ChangeTime] = 0;
1766  P.HQ_Household_PropComply_OverTime [ChangeTime] = 0;
1767  P.DCT_Prop_OverTime [ChangeTime] = 0;
1768  }
1769 
1770 
1774  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative spatial contact rates over time given social distancing" , "%lf", (void*)P.SD_SpatialEffects_OverTime, P.Num_SD_ChangeTimes, 1, 0))
1775  for (int ChangeTime = 0; ChangeTime < P.Num_SD_ChangeTimes; ChangeTime++) P.SD_SpatialEffects_OverTime[ChangeTime] = P.SocDistSpatialEffect;
1776  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative spatial contact rates over time given enhanced social distancing" , "%lf", (void*)P.Enhanced_SD_SpatialEffects_OverTime, P.Num_SD_ChangeTimes, 1, 0))
1778  for (int ChangeTime = 0; ChangeTime < P.Num_SD_ChangeTimes; ChangeTime++) P.Enhanced_SD_SpatialEffects_OverTime[ChangeTime] = P.EnhancedSocDistSpatialEffect;
1779  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual contacts after case isolation over time" , "%lf", (void*)P.CI_SpatialAndPlaceEffects_OverTime, P.Num_CI_ChangeTimes, 1, 0))
1781  for (int ChangeTime = 0; ChangeTime < P.Num_CI_ChangeTimes; ChangeTime++) P.CI_SpatialAndPlaceEffects_OverTime[ChangeTime] = P.CaseIsolationEffectiveness;
1783  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual spatial contacts over time after household quarantine" , "%lf", (void*)P.HQ_SpatialEffects_OverTime, P.Num_HQ_ChangeTimes, 1, 0))
1784  for (int ChangeTime = 0; ChangeTime < P.Num_HQ_ChangeTimes; ChangeTime++) P.HQ_SpatialEffects_OverTime[ChangeTime] = P.HQuarantineSpatialEffect;
1786  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative spatial contact rates over time after place closure" , "%lf", (void*)P.PC_SpatialEffects_OverTime, P.Num_PC_ChangeTimes, 1, 0))
1787  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++) P.PC_SpatialEffects_OverTime[ChangeTime] = P.PlaceCloseSpatialRelContact;
1789  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual contacts after digital contact tracing isolation over time" , "%lf", (void*)P.DCT_SpatialAndPlaceEffects_OverTime, P.Num_DCT_ChangeTimes, 1, 0))
1790  for (int ChangeTime = 0; ChangeTime < P.Num_DCT_ChangeTimes; ChangeTime++) P.DCT_SpatialAndPlaceEffects_OverTime[ChangeTime] = P.DCTCaseIsolationEffectiveness;
1791 
1793  if (P.DoHouseholds)
1794  {
1796  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rates over time given social distancing" , "%lf", (void*)P.SD_HouseholdEffects_OverTime, P.Num_SD_ChangeTimes, 1, 0))
1797  for (int ChangeTime = 0; ChangeTime < P.Num_SD_ChangeTimes; ChangeTime++) P.SD_HouseholdEffects_OverTime[ChangeTime] = P.SocDistHouseholdEffect;
1799  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rates over time given enhanced social distancing" , "%lf", (void*)P.Enhanced_SD_HouseholdEffects_OverTime, P.Num_SD_ChangeTimes, 1, 0))
1800  for (int ChangeTime = 0; ChangeTime < P.Num_SD_ChangeTimes; ChangeTime++) P.Enhanced_SD_HouseholdEffects_OverTime[ChangeTime] = P.EnhancedSocDistHouseholdEffect;
1802  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual household contacts after case isolation over time" , "%lf", (void*)P.CI_HouseholdEffects_OverTime, P.Num_CI_ChangeTimes, 1, 0))
1803  for (int ChangeTime = 0; ChangeTime < P.Num_CI_ChangeTimes; ChangeTime++) P.CI_HouseholdEffects_OverTime[ChangeTime] = P.CaseIsolationHouseEffectiveness;
1805  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rates over time after quarantine" , "%lf", (void*)P.HQ_HouseholdEffects_OverTime, P.Num_HQ_ChangeTimes, 1, 0))
1806  for (int ChangeTime = 0; ChangeTime < P.Num_HQ_ChangeTimes; ChangeTime++) P.HQ_HouseholdEffects_OverTime[ChangeTime] = P.HQuarantineHouseEffect;
1808  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative household contact rates over time after place closure" , "%lf", (void*)P.PC_HouseholdEffects_OverTime, P.Num_PC_ChangeTimes, 1, 0))
1809  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++) P.PC_HouseholdEffects_OverTime[ChangeTime] = P.PlaceCloseHouseholdRelContact;
1811  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual household contacts after digital contact tracing isolation over time", "%lf", (void*)P.DCT_HouseholdEffects_OverTime, P.Num_DCT_ChangeTimes, 1, 0))
1812  for (int ChangeTime = 0; ChangeTime < P.Num_DCT_ChangeTimes; ChangeTime++) P.DCT_HouseholdEffects_OverTime[ChangeTime] = P.DCTCaseIsolationHouseEffectiveness;
1813  }
1814 
1816  if (P.DoPlaces)
1817  {
1819  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative place contact rates over time given social distancing by place type", "%lf", (void*) &P.SD_PlaceEffects_OverTime[0][0], P.Num_SD_ChangeTimes * P.PlaceTypeNum, 1, 0))
1820  for (int ChangeTime = 0; ChangeTime < P.Num_SD_ChangeTimes; ChangeTime++)
1821  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1822  P.SD_PlaceEffects_OverTime[ChangeTime][PlaceType] = P.SocDistPlaceEffect[PlaceType];
1823 
1825  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Relative place contact rates over time given enhanced social distancing by place type", "%lf", (void*) &P.Enhanced_SD_PlaceEffects_OverTime[0][0], P.Num_SD_ChangeTimes * P.PlaceTypeNum, 1, 0))
1826  for (int ChangeTime = 0; ChangeTime < P.Num_SD_ChangeTimes; ChangeTime++)
1827  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1828  P.Enhanced_SD_PlaceEffects_OverTime[ChangeTime][PlaceType] = P.EnhancedSocDistPlaceEffect[PlaceType];
1829 
1831  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Residual place contacts over time after household quarantine by place type", "%lf", (void*) &P.HQ_PlaceEffects_OverTime[0][0], P.Num_HQ_ChangeTimes * P.PlaceTypeNum, 1, 0))
1832  for (int ChangeTime = 0; ChangeTime < P.Num_HQ_ChangeTimes; ChangeTime++)
1833  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1834  P.HQ_PlaceEffects_OverTime[ChangeTime][PlaceType] = P.HQuarantinePlaceEffect[PlaceType];
1835 
1837  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of places remaining open after closure by place type over time", "%lf", (void*) &P.PC_PlaceEffects_OverTime[0][0], P.Num_PC_ChangeTimes * P.PlaceTypeNum, 1, 0))
1838  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++)
1839  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1840  P.PC_PlaceEffects_OverTime[ChangeTime][PlaceType] = P.PlaceCloseEffect[PlaceType];
1841 
1842  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportional attendance after closure by place type over time", "%lf", (void*) &P.PC_PropAttending_OverTime[0][0], P.Num_PC_ChangeTimes * P.PlaceTypeNum, 1, 0))
1843  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++)
1844  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1845  P.PC_PropAttending_OverTime[ChangeTime][PlaceType] = P.PlaceClosePropAttending[PlaceType];
1846  }
1847 
1848 
1851  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of detected cases isolated over time", "%lf", (void*)P.CI_Prop_OverTime, P.Num_CI_ChangeTimes, 1, 0))
1852  for (int ChangeTime = 0; ChangeTime < P.Num_CI_ChangeTimes; ChangeTime++) P.CI_Prop_OverTime[ChangeTime] = P.CaseIsolationProp;
1854  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Individual level compliance with quarantine over time" , "%lf", (void*)P.HQ_Individual_PropComply_OverTime, P.Num_HQ_ChangeTimes, 1, 0))
1855  for (int ChangeTime = 0; ChangeTime < P.Num_HQ_ChangeTimes; ChangeTime++) P.HQ_Individual_PropComply_OverTime[ChangeTime] = P.HQuarantinePropIndivCompliant;
1857  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Household level compliance with quarantine over time" , "%lf", (void*)P.HQ_Household_PropComply_OverTime, P.Num_HQ_ChangeTimes, 1, 0))
1858  for (int ChangeTime = 0; ChangeTime < P.Num_HQ_ChangeTimes; ChangeTime++) P.HQ_Household_PropComply_OverTime[ChangeTime] = P.HQuarantinePropHouseCompliant;
1860  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of digital contacts who self-isolate over time", "%lf", (void*)P.DCT_Prop_OverTime, P.Num_DCT_ChangeTimes, 1, 0))
1861  for (int ChangeTime = 0; ChangeTime < P.Num_DCT_ChangeTimes; ChangeTime++) P.DCT_Prop_OverTime[ChangeTime] = P.ProportionDigitalContactsIsolate;
1862  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Maximum number of contacts to trace per index case over time", "%i", (void*)P.DCT_MaxToTrace_OverTime, P.Num_DCT_ChangeTimes, 1, 0))
1863  for (int ChangeTime = 0; ChangeTime < P.Num_DCT_ChangeTimes; ChangeTime++) P.DCT_MaxToTrace_OverTime[ChangeTime] = P.MaxDigitalContactsToTrace;
1864  if (P.DoPlaces)
1865  {
1868  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place closure incidence threshold over time", "%lf", (void*)P.PC_IncThresh_OverTime, P.Num_PC_ChangeTimes, 1, 0))
1869  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++) P.PC_IncThresh_OverTime[ChangeTime] = P.PlaceCloseIncTrig1;
1871  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Place closure fractional incidence threshold over time", "%lf", (void*)P.PC_FracIncThresh_OverTime, P.Num_PC_ChangeTimes, 1, 0))
1872  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++) P.PC_FracIncThresh_OverTime[ChangeTime] = P.PlaceCloseFracIncTrig;
1874  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Trigger incidence per cell for place closure over time", "%i", (void*)P.PC_CellIncThresh_OverTime, P.Num_PC_ChangeTimes, 1, 0))
1875  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++) P.PC_CellIncThresh_OverTime[ChangeTime] = P.PlaceCloseCellIncThresh1;
1876  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++) if(P.PC_CellIncThresh_OverTime[ChangeTime]<0) P.PC_CellIncThresh_OverTime[ChangeTime] = 1000000000; // allows -1 to be used as a proxy for no cell-based triggering
1877  }
1879  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Household quarantine trigger incidence per cell over time", "%lf", (void*)P.HQ_CellIncThresh_OverTime, P.Num_HQ_ChangeTimes, 1, 0))
1880  for (int ChangeTime = 0; ChangeTime < P.Num_HQ_ChangeTimes; ChangeTime++) P.HQ_CellIncThresh_OverTime[ChangeTime] = P.HHQuar_CellIncThresh;
1882  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Case isolation trigger incidence per cell over time", "%lf", (void*)P.CI_CellIncThresh_OverTime, P.Num_CI_ChangeTimes, 1, 0))
1883  for (int ChangeTime = 0; ChangeTime < P.Num_CI_ChangeTimes; ChangeTime++) P.CI_CellIncThresh_OverTime[ChangeTime] = P.CaseIsolation_CellIncThresh;
1885  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Trigger incidence per cell for social distancing over time", "%i", (void*)P.SD_CellIncThresh_OverTime, P.Num_SD_ChangeTimes, 1, 0))
1886  for (int ChangeTime = 0; ChangeTime < P.Num_SD_ChangeTimes; ChangeTime++) P.SD_CellIncThresh_OverTime[ChangeTime] = P.SocDistCellIncThresh;
1887 
1889  // place closure
1890  if (!P.VaryEfficaciesOverTime || !GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of place closure over time", "%lf", (void*)P.PC_Durs_OverTime, P.Num_PC_ChangeTimes, 1, 0))
1891  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++) P.PC_Durs_OverTime[ChangeTime] = P.PlaceCloseDurationBase;
1892 
1894  if (P.VaryEfficaciesOverTime)
1895  {
1897  for (int SD_ChangeTime = P.Num_SD_ChangeTimes; SD_ChangeTime < MAX_NUM_INTERVENTION_CHANGE_TIMES - 1; SD_ChangeTime++)
1898  {
1900  P.SD_SpatialEffects_OverTime [SD_ChangeTime] = P.SD_SpatialEffects_OverTime [P.Num_SD_ChangeTimes - 1];
1901  P.SD_HouseholdEffects_OverTime [SD_ChangeTime] = P.SD_HouseholdEffects_OverTime [P.Num_SD_ChangeTimes - 1];
1902  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1903  P.SD_PlaceEffects_OverTime[SD_ChangeTime][PlaceType] = P.SD_PlaceEffects_OverTime[P.Num_SD_ChangeTimes - 1][PlaceType];
1905  P.Enhanced_SD_SpatialEffects_OverTime [SD_ChangeTime] = P.Enhanced_SD_SpatialEffects_OverTime [P.Num_SD_ChangeTimes - 1];
1906  P.Enhanced_SD_HouseholdEffects_OverTime [SD_ChangeTime] = P.Enhanced_SD_HouseholdEffects_OverTime [P.Num_SD_ChangeTimes - 1];
1907  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1908  P.Enhanced_SD_PlaceEffects_OverTime[SD_ChangeTime][PlaceType] = P.Enhanced_SD_PlaceEffects_OverTime[P.Num_SD_ChangeTimes - 1][PlaceType];
1909 
1910  P.SD_CellIncThresh_OverTime [SD_ChangeTime] = P.SD_CellIncThresh_OverTime [P.Num_SD_ChangeTimes - 1];
1911  }
1912 
1914  for (int CI_ChangeTime = P.Num_CI_ChangeTimes; CI_ChangeTime < MAX_NUM_INTERVENTION_CHANGE_TIMES - 1; CI_ChangeTime++)
1915  {
1916  P.CI_SpatialAndPlaceEffects_OverTime[CI_ChangeTime] = P.CI_SpatialAndPlaceEffects_OverTime [P.Num_CI_ChangeTimes - 1];
1917  P.CI_HouseholdEffects_OverTime [CI_ChangeTime] = P.CI_HouseholdEffects_OverTime [P.Num_CI_ChangeTimes - 1];
1918  P.CI_Prop_OverTime [CI_ChangeTime] = P.CI_Prop_OverTime [P.Num_CI_ChangeTimes - 1];
1919  P.CI_CellIncThresh_OverTime [CI_ChangeTime] = P.CI_CellIncThresh_OverTime [P.Num_CI_ChangeTimes - 1];
1920  }
1921 
1923  for (int HQ_ChangeTime = P.Num_HQ_ChangeTimes; HQ_ChangeTime < MAX_NUM_INTERVENTION_CHANGE_TIMES - 1; HQ_ChangeTime++)
1924  {
1925  P.HQ_SpatialEffects_OverTime [HQ_ChangeTime] = P.HQ_SpatialEffects_OverTime [P.Num_HQ_ChangeTimes - 1];
1926  P.HQ_HouseholdEffects_OverTime [HQ_ChangeTime] = P.HQ_HouseholdEffects_OverTime[P.Num_HQ_ChangeTimes - 1];
1927  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1928  P.HQ_PlaceEffects_OverTime[HQ_ChangeTime][PlaceType] = P.HQ_PlaceEffects_OverTime[P.Num_HQ_ChangeTimes - 1][PlaceType];
1929 
1930  P.HQ_Individual_PropComply_OverTime [HQ_ChangeTime] = P.HQ_Individual_PropComply_OverTime [P.Num_HQ_ChangeTimes - 1];
1931  P.HQ_Household_PropComply_OverTime [HQ_ChangeTime] = P.HQ_Household_PropComply_OverTime [P.Num_HQ_ChangeTimes - 1];
1932 
1933  P.HQ_CellIncThresh_OverTime [HQ_ChangeTime] = P.HQ_CellIncThresh_OverTime [P.Num_HQ_ChangeTimes - 1];
1934  }
1935 
1937  for (int PC_ChangeTime = P.Num_PC_ChangeTimes; PC_ChangeTime < MAX_NUM_INTERVENTION_CHANGE_TIMES - 1; PC_ChangeTime++)
1938  {
1939  P.PC_SpatialEffects_OverTime [PC_ChangeTime] = P.PC_SpatialEffects_OverTime [P.Num_PC_ChangeTimes - 1];
1940  P.PC_HouseholdEffects_OverTime [PC_ChangeTime] = P.PC_HouseholdEffects_OverTime[P.Num_PC_ChangeTimes - 1];
1941  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
1942  {
1943  P.PC_PlaceEffects_OverTime[PC_ChangeTime][PlaceType] = P.PC_PlaceEffects_OverTime[P.Num_PC_ChangeTimes - 1][PlaceType];
1944  P.PC_PropAttending_OverTime[PC_ChangeTime][PlaceType] = P.PC_PropAttending_OverTime[P.Num_PC_ChangeTimes - 1][PlaceType];
1945  }
1946 
1947  P.PC_IncThresh_OverTime [PC_ChangeTime] = P.PC_IncThresh_OverTime [P.Num_PC_ChangeTimes - 1];
1948  P.PC_FracIncThresh_OverTime [PC_ChangeTime] = P.PC_FracIncThresh_OverTime [P.Num_PC_ChangeTimes - 1];
1949  P.PC_CellIncThresh_OverTime [PC_ChangeTime] = P.PC_CellIncThresh_OverTime [P.Num_PC_ChangeTimes - 1];
1950  }
1951 
1953  for (int DCT_ChangeTime = P.Num_DCT_ChangeTimes; DCT_ChangeTime < MAX_NUM_INTERVENTION_CHANGE_TIMES - 1; DCT_ChangeTime++)
1954  {
1955  P.DCT_SpatialAndPlaceEffects_OverTime [DCT_ChangeTime] = P.DCT_SpatialAndPlaceEffects_OverTime[P.Num_DCT_ChangeTimes - 1];
1956  P.DCT_HouseholdEffects_OverTime [DCT_ChangeTime] = P.DCT_HouseholdEffects_OverTime [P.Num_DCT_ChangeTimes - 1];
1957  P.DCT_Prop_OverTime [DCT_ChangeTime] = P.DCT_Prop_OverTime [P.Num_DCT_ChangeTimes - 1];
1958  P.DCT_MaxToTrace_OverTime [DCT_ChangeTime] = P.DCT_MaxToTrace_OverTime [P.Num_DCT_ChangeTimes - 1];
1959  }
1960  }
1961 
1962  if (P.DoPlaces)
1963  {
1964  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of key workers randomly distributed in the population", "%i", (void*) & (P.KeyWorkerPopNum), 1, 1, 0)) P.KeyWorkerPopNum = 0;
1965  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Number of key workers in different places by place type", "%i", (void*)P.KeyWorkerPlaceNum, P.PlaceTypeNum, 1, 0))
1966  for (i = 0; i < NUM_PLACE_TYPES; i++) P.KeyWorkerPlaceNum[i] = 0;
1967  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of staff who are key workers per chosen place by place type", "%lf", (void*)P.KeyWorkerPropInKeyPlaces, P.PlaceTypeNum, 1, 0))
1968  for (i = 0; i < NUM_PLACE_TYPES; i++) P.KeyWorkerPropInKeyPlaces[i] = 1.0;
1969  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Trigger incidence per cell for key worker prophylaxis", "%i", (void*) & (P.KeyWorkerProphCellIncThresh), 1, 1, 0)) P.KeyWorkerProphCellIncThresh = 1000000000;
1970  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Key worker prophylaxis start time", "%lf", (void*) & (P.KeyWorkerProphTimeStartBase), 1, 1, 0)) P.KeyWorkerProphTimeStartBase = USHRT_MAX / P.TimeStepsPerDay;
1971  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Duration of key worker prophylaxis", "%lf", (void*) & (P.KeyWorkerProphDuration), 1, 1, 0)) P.KeyWorkerProphDuration = 0;
1972  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Time interval from start of key worker prophylaxis before policy restarted", "%lf", (void*) & (P.KeyWorkerProphRenewalDuration), 1, 1, 0)) P.KeyWorkerProphRenewalDuration = P.KeyWorkerProphDuration;
1973  if (P.DoHouseholds)
1974  {
1975  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Proportion of key workers whose households are also treated as key workers", "%lf", (void*) & (P.KeyWorkerHouseProp), 1, 1, 0)) P.KeyWorkerHouseProp = 0;
1976  }
1977  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Minimum radius for key worker prophylaxis", "%lf", (void*) & (P.KeyWorkerProphRadius), 1, 1, 0)) P.KeyWorkerProphRadius = 0;
1978  }
1979  else
1980  {
1981  P.KeyWorkerPopNum = 0;
1982  P.KeyWorkerProphTimeStartBase = 1e10;
1983  }
1984 
1985  //Added this to parameter list so that recording infection events (and the number to record) can easily be turned off and on: ggilani - 10/10/2014
1986  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Record infection events", "%i", (void*) & (P.DoRecordInfEvents), 1, 1, 0)) P.DoRecordInfEvents = 0;
1987  if (P.DoRecordInfEvents)
1988  {
1989  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Max number of infection events to record", "%i", (void*) & (P.MaxInfEvents), 1, 1, 0)) P.MaxInfEvents = 1000;
1990  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Record infection events per run", "%i", (void*) & (P.RecordInfEventsPerRun), 1, 1, 0)) P.RecordInfEventsPerRun = 0;
1991  }
1992  else
1993  {
1994  P.MaxInfEvents = 0;
1995  }
1996  //Include a limit to the number of infections to simulate, if this happens before time runs out
1997  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Limit number of infections", "%i", (void*) & (P.LimitNumInfections), 1, 1, 0)) P.LimitNumInfections = 0;
1998  if (P.LimitNumInfections)
1999  {
2000  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Max number of infections", "%i", (void*) & (P.MaxNumInfections), 1, 1, 0)) P.MaxNumInfections = 60000;
2001  }
2002  //Add origin-destination matrix parameter
2003  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Output origin destination matrix", "%i", (void*) & (P.DoOriginDestinationMatrix), 1, 1, 0)) P.DoOriginDestinationMatrix = 0;
2004 
2005  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Mean child age gap", "%i", (void*) & (P.MeanChildAgeGap), 1, 1, 0)) P.MeanChildAgeGap=2;
2006  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Min adult age", "%i", (void*)&(P.MinAdultAge), 1, 1, 0)) P.MinAdultAge = 19;
2007  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Max MF partner age gap", "%i", (void*) & (P.MaxMFPartnerAgeGap), 1, 1, 0)) P.MaxMFPartnerAgeGap = 5;
2008  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Max FM partner age gap", "%i", (void*) & (P.MaxFMPartnerAgeGap), 1, 1, 0)) P.MaxFMPartnerAgeGap = 5;
2009  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Min parent age gap", "%i", (void*) & (P.MinParentAgeGap), 1, 1, 0)) P.MinParentAgeGap = 19;
2010  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Max parent age gap", "%i", (void*) & (P.MaxParentAgeGap), 1, 1, 0)) P.MaxParentAgeGap = 44;
2011  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Max child age", "%i", (void*) & (P.MaxChildAge), 1, 1, 0)) P.MaxChildAge = 20;
2012  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "One Child Two Pers Prob", "%lf", (void*) & (P.OneChildTwoPersProb), 1, 1, 0)) P.OneChildTwoPersProb = 0.08;
2013  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Two Child Three Pers Prob", "%lf", (void*) & (P.TwoChildThreePersProb), 1, 1, 0)) P.TwoChildThreePersProb = 0.11;
2014  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "One Pers House Prob Old", "%lf", (void*) & (P.OnePersHouseProbOld), 1, 1, 0)) P.OnePersHouseProbOld = 0.5;
2015  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Two Pers House Prob Old", "%lf", (void*) & (P.TwoPersHouseProbOld), 1, 1, 0)) P.TwoPersHouseProbOld = 0.5;
2016  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "One Pers House Prob Young", "%lf", (void*) & (P.OnePersHouseProbYoung), 1, 1, 0)) P.OnePersHouseProbYoung = 0.23;
2017  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Two Pers House Prob Young", "%lf", (void*) & (P.TwoPersHouseProbYoung), 1, 1, 0)) P.TwoPersHouseProbYoung = 0.23;
2018  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "One Child Prob Youngest Child Under Five", "%lf", (void*) & (P.OneChildProbYoungestChildUnderFive), 1, 1, 0)) P.OneChildProbYoungestChildUnderFive = 0.5;
2019  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Two Children Prob Youngest Under Five", "%lf", (void*) & (P.TwoChildrenProbYoungestUnderFive), 1, 1, 0)) P.TwoChildrenProbYoungestUnderFive = 0.0;
2020  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Prob Youngest Child Under Five", "%lf", (void*) & (P.ProbYoungestChildUnderFive), 1, 1, 0)) P.ProbYoungestChildUnderFive = 0;
2021  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Zero Child Three Pers Prob", "%lf", (void*) & (P.ZeroChildThreePersProb), 1, 1, 0)) P.ZeroChildThreePersProb = 0.25;
2022  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "One Child Four Pers Prob", "%lf", (void*) & (P.OneChildFourPersProb), 1, 1, 0)) P.OneChildFourPersProb = 0.2;
2023  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Young And Single Slope", "%lf", (void*) & (P.YoungAndSingleSlope), 1, 1, 0)) P.YoungAndSingleSlope = 0.7;
2024  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Young And Single", "%i", (void*) & (P.YoungAndSingle), 1, 1, 0)) P.YoungAndSingle = 36;
2025  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "No Child Pers Age", "%i", (void*) & (P.NoChildPersAge), 1, 1, 0)) P.NoChildPersAge = 44;
2026  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Old Pers Age", "%i", (void*) & (P.OldPersAge), 1, 1, 0)) P.OldPersAge = 60;
2027  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Three Child Five Pers Prob", "%lf", (void*) & (P.ThreeChildFivePersProb), 1, 1, 0)) P.ThreeChildFivePersProb = 0.5;
2028  if (!GetInputParameter2(ParamFile_dat, PreParamFile_dat, "Older Gen Gap", "%i", (void*) & (P.OlderGenGap), 1, 1, 0)) P.OlderGenGap = 19;
2029 
2030  // Close input files.
2031  fclose(ParamFile_dat);
2032  if (PreParamFile_dat != NULL) fclose(PreParamFile_dat);
2033  if (ParamFile_dat != AdminFile_dat && AdminFile_dat != NULL) fclose(AdminFile_dat);
2034 
2035  if (P.DoOneGen != 0) P.DoOneGen = 1;
2036  P.ColourPeriod = 2000;
2037  P.MoveRestrRadius2 = P.MoveRestrRadius * P.MoveRestrRadius;
2038  P.SocDistRadius2 = P.SocDistRadius * P.SocDistRadius;
2039  P.VaccRadius2 = P.VaccRadius * P.VaccRadius;
2040  P.VaccMinRadius2 = P.VaccMinRadius * P.VaccMinRadius;
2041  P.TreatRadius2 = P.TreatRadius * P.TreatRadius;
2042  P.PlaceCloseRadius2 = P.PlaceCloseRadius * P.PlaceCloseRadius;
2043  P.KeyWorkerProphRadius2 = P.KeyWorkerProphRadius * P.KeyWorkerProphRadius;
2044  if (P.TreatRadius2 == 0) P.TreatRadius2 = -1;
2045  if (P.VaccRadius2 == 0) P.VaccRadius2 = -1;
2046  if (P.PlaceCloseRadius2 == 0) P.PlaceCloseRadius2 = -1;
2047  if (P.MoveRestrRadius2 == 0) P.MoveRestrRadius2 = -1;
2048  if (P.SocDistRadius2 == 0) P.SocDistRadius2 = -1;
2049  if (P.KeyWorkerProphRadius2 == 0) P.KeyWorkerProphRadius2 = -1;
2050 /* if (P.TreatCellIncThresh < 1) P.TreatCellIncThresh = 1;
2051  if (P.CaseIsolation_CellIncThresh < 1) P.CaseIsolation_CellIncThresh = 1;
2052  if (P.DigitalContactTracing_CellIncThresh < 1) P.DigitalContactTracing_CellIncThresh = 1;
2053  if (P.HHQuar_CellIncThresh < 1) P.HHQuar_CellIncThresh = 1;
2054  if (P.MoveRestrCellIncThresh < 1) P.MoveRestrCellIncThresh = 1;
2055  if (P.PlaceCloseCellIncThresh < 1) P.PlaceCloseCellIncThresh = 1;
2056  if (P.KeyWorkerProphCellIncThresh < 1) P.KeyWorkerProphCellIncThresh = 1;
2057 */
2058 
2060  P.usHQuarantineHouseDuration = ((unsigned short int) (P.HQuarantineHouseDuration * P.TimeStepsPerDay));
2061  P.usVaccTimeToEfficacy = ((unsigned short int) (P.VaccTimeToEfficacy * P.TimeStepsPerDay));
2062  P.usVaccTimeEfficacySwitch = ((unsigned short int) (P.VaccTimeEfficacySwitch * P.TimeStepsPerDay));
2063  P.usCaseIsolationDelay = ((unsigned short int) (P.CaseIsolationDelay * P.TimeStepsPerDay));
2064  P.usCaseIsolationDuration = ((unsigned short int) (P.CaseIsolationDuration * P.TimeStepsPerDay));
2065  P.usCaseAbsenteeismDuration = ((unsigned short int) (P.CaseAbsenteeismDuration * P.TimeStepsPerDay));
2066  P.usCaseAbsenteeismDelay = ((unsigned short int) (P.CaseAbsenteeismDelay * P.TimeStepsPerDay));
2067  if (P.DoUTM_coords)
2068  {
2069  for (i = 0; i <= 1000; i++)
2070  {
2071  asin2sqx[i] = asin(sqrt(((double)(i)) / 1000));
2072  asin2sqx[i] = asin2sqx[i] * asin2sqx[i];
2073  }
2074  for (t = 0; t <= 360; t++)
2075  {
2076  sinx[(int)t] = sin(PI * t / 180);
2077  cosx[(int)t] = cos(PI * t / 180);
2078  }
2079  }
2080  fprintf(stderr, "Parameters read\n");
2081 }
2082 void ReadInterventions(char* IntFile)
2083 {
2084  FILE* dat;
2085  double r, s, startt, stopt;
2086  int j, k, au, ni, f, nsr;
2087  char buf[65536], txt[65536];
2088  Intervention CurInterv;
2089 
2090  fprintf(stderr, "Reading intervention file.\n");
2091  if (!(dat = fopen(IntFile, "rb"))) ERR_CRITICAL("Unable to open intervention file\n");
2092  if(fscanf(dat, "%*[^<]") != 0) { // needs to be separate line because start of file
2093  ERR_CRITICAL("fscanf failed in ReadInterventions\n");
2094  }
2095  if(fscanf(dat, "<%[^>]", txt) != 1) {
2096  ERR_CRITICAL("fscanf failed in ReadInterventions\n");
2097  }
2098  if (strcmp(txt, "\?xml version=\"1.0\" encoding=\"ISO-8859-1\"\?") != 0) ERR_CRITICAL("Intervention file not XML.\n");
2099  if(fscanf(dat, "%*[^<]<%[^>]", txt) != 1) {
2100  ERR_CRITICAL("fscanf failed in ReadInterventions\n");
2101  }
2102  if (strcmp(txt, "InterventionSettings") != 0) ERR_CRITICAL("Intervention has no top level.\n");
2103  ni = 0;
2104  while (!feof(dat))
2105  {
2106  if(fscanf(dat, "%*[^<]<%[^>]", txt) != 1) {
2107  ERR_CRITICAL("fscanf failed in ReadInterventions\n");
2108  }
2109  if (strcmp(txt, "intervention") == 0)
2110  {
2111  ni++;
2112  if(fscanf(dat, "%*[^<]<%[^>]", txt) != 1) {
2113  ERR_CRITICAL("fscanf failed in ReadInterventions\n");
2114  }
2115  if (strcmp(txt, "parameters") != 0) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2116  if (!GetXMLNode(dat, "Type", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2117  if (strcmp(txt, "Treatment") == 0)
2118  CurInterv.InterventionType = 0;
2119  else if (strcmp(txt, "Vaccination") == 0)
2120  CurInterv.InterventionType = 1;
2121  else if (strcmp(txt, "ITN") == 0)
2122  CurInterv.InterventionType = 2;
2123  else if (strcmp(txt, "IRS") == 0)
2124  CurInterv.InterventionType = 3;
2125  else if (strcmp(txt, "GM") == 0)
2126  CurInterv.InterventionType = 4;
2127  else if (strcmp(txt, "MSAT") == 0)
2128  CurInterv.InterventionType = 5;
2129  else
2130  sscanf(txt, "%i", &CurInterv.InterventionType);
2131  if (!GetXMLNode(dat, "AUThresh", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2132  sscanf(txt, "%i", &CurInterv.DoAUThresh);
2133  if (!GetXMLNode(dat, "StartTime", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2134  sscanf(txt, "%lf", &CurInterv.StartTime);
2135  startt = CurInterv.StartTime;
2136  if (!GetXMLNode(dat, "StopTime", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2137  sscanf(txt, "%lf", &CurInterv.StopTime);
2138  stopt = CurInterv.StopTime;
2139  if (!GetXMLNode(dat, "MinDuration", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2140  sscanf(txt, "%lf", &CurInterv.MinDuration);
2141  CurInterv.MinDuration *= DAYS_PER_YEAR;
2142  if (!GetXMLNode(dat, "RepeatInterval", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2143  sscanf(txt, "%lf", &CurInterv.RepeatInterval);
2144  CurInterv.RepeatInterval *= DAYS_PER_YEAR;
2145  if (!GetXMLNode(dat, "MaxPrevAtStart", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2146  sscanf(txt, "%lf", &CurInterv.StartThresholdHigh);
2147  if (!GetXMLNode(dat, "MinPrevAtStart", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2148  sscanf(txt, "%lf", &CurInterv.StartThresholdLow);
2149  if (!GetXMLNode(dat, "MaxPrevAtStop", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2150  sscanf(txt, "%lf", &CurInterv.StopThreshold);
2151  if (GetXMLNode(dat, "NoStartAfterMinDur", "parameters", txt, 1))
2152  sscanf(txt, "%i", &CurInterv.NoStartAfterMin);
2153  else
2154  CurInterv.NoStartAfterMin = 0;
2155  if (!GetXMLNode(dat, "Level", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2156  sscanf(txt, "%lf", &CurInterv.Level);
2157  if (GetXMLNode(dat, "LevelCellVar", "parameters", txt, 1))
2158  sscanf(txt, "%lf", &CurInterv.LevelCellVar);
2159  else
2160  CurInterv.LevelCellVar = 0;
2161  if (GetXMLNode(dat, "LevelAUVar", "parameters", txt, 1))
2162  sscanf(txt, "%lf", &CurInterv.LevelAUVar);
2163  else
2164  CurInterv.LevelCellVar = 0;
2165  if (GetXMLNode(dat, "LevelCountryVar", "parameters", txt, 1))
2166  sscanf(txt, "%lf", &CurInterv.LevelCountryVar);
2167  else
2168  CurInterv.LevelCellVar = 0;
2169  if (GetXMLNode(dat, "LevelClustering", "parameters", txt, 1))
2170  sscanf(txt, "%lf", &CurInterv.LevelClustering);
2171  else
2172  CurInterv.LevelClustering = 0;
2173  if (GetXMLNode(dat, "ControlParam", "parameters", txt, 1))
2174  sscanf(txt, "%lf", &CurInterv.ControlParam);
2175  else
2176  CurInterv.ControlParam = 0;
2177  if (GetXMLNode(dat, "TimeOffset", "parameters", txt, 1))
2178  sscanf(txt, "%lf", &CurInterv.TimeOffset);
2179  else
2180  CurInterv.TimeOffset = 0;
2181 
2182  if (!GetXMLNode(dat, "MaxRounds", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2183  sscanf(txt, "%u", &CurInterv.MaxRounds);
2184  if (!GetXMLNode(dat, "MaxResource", "parameters", txt, 1)) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2185  sscanf(txt, "%u", &CurInterv.MaxResource);
2186  if (GetXMLNode(dat, "NumSequentialReplicas", "parameters", txt, 1))
2187  sscanf(txt, "%i", &nsr);
2188  else
2189  nsr = 0;
2190  do {
2191  if(fscanf(dat, "%*[^<]<%[^>]", txt) != 1) {
2192  ERR_CRITICAL("fscanf failed in ReadInterventions\n");
2193  }
2194  } while ((strcmp(txt, "/intervention") != 0) && (strcmp(txt, "/parameters") != 0) && (!feof(dat)));
2195  if (strcmp(txt, "/parameters") != 0) ERR_CRITICAL("Incomplete intervention parameter specification in intervention file\n");
2196  if(fscanf(dat, "%*[^<]<%[^>]", txt) != 1) {
2197  ERR_CRITICAL("fscanf failed in ReadInterventions\n");
2198  }
2199  if ((strcmp(txt, "adunits") != 0) && (strcmp(txt, "countries") != 0)) ERR_CRITICAL("Incomplete adunits/countries specification in intervention file\n");
2200  if (strcmp(txt, "adunits") == 0)
2201  {
2202  while (GetXMLNode(dat, "A", "adunits", buf, 0))
2203  {
2204  sscanf(buf, "%s", txt);
2205  j = atoi(txt);
2206  if (j == 0)
2207  {
2208  f = 1; au = -1;
2209  do
2210  {
2211  au++; f = strcmp(txt, AdUnits[au].ad_name);
2212  } while ((f) && (au < P.NumAdunits));
2213  if (!f)
2214  {
2215  r = fabs(CurInterv.Level) + (2.0 * ranf() - 1) * CurInterv.LevelAUVar;
2216  if ((CurInterv.Level < 1) && (r > 1))
2217  r = 1;
2218  else if (r < 0)
2219  r = 0;
2220  for (k = 0; k <= nsr; k++)
2221  {
2222  AdUnits[au].InterventionList[AdUnits[au].NI] = CurInterv;
2223  AdUnits[au].InterventionList[AdUnits[au].NI].Level = r;
2224  AdUnits[au].InterventionList[AdUnits[au].NI].StartTime = startt + ((double)k) * (stopt - startt);
2225  AdUnits[au].InterventionList[AdUnits[au].NI].StopTime = stopt + ((double)k) * (stopt - startt);
2226  AdUnits[au].NI++;
2227  }
2228  }
2229  }
2230  else
2231  {
2232  k = (j % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor;
2233  au = P.AdunitLevel1Lookup[k];
2234  if ((au >= 0) && (AdUnits[au].id / P.AdunitLevel1Divisor == j / P.AdunitLevel1Divisor))
2235  {
2236  r = CurInterv.Level + (2.0 * ranf() - 1) * CurInterv.LevelAUVar;
2237  if ((CurInterv.Level < 1) && (r > 1))
2238  r = 1;
2239  else if (r < 0)
2240  r = 0;
2241  for (k = 0; k <= nsr; k++)
2242  {
2243  AdUnits[au].InterventionList[AdUnits[au].NI] = CurInterv;
2244  AdUnits[au].InterventionList[AdUnits[au].NI].Level = r;
2245  AdUnits[au].InterventionList[AdUnits[au].NI].StartTime = startt + ((double)k) * (stopt - startt);
2246  AdUnits[au].InterventionList[AdUnits[au].NI].StopTime = stopt + ((double)k) * (stopt - startt);
2247  AdUnits[au].NI++;
2248  }
2249  }
2250  }
2251  }
2252  }
2253  else
2254  {
2255  while (GetXMLNode(dat, "C", "countries", buf, 0))
2256  {
2257  s = (2.0 * ranf() - 1) * CurInterv.LevelCountryVar;
2258  sscanf(buf, "%s", txt);
2259  j = atoi(txt);
2260  for (au = 0; au < P.NumAdunits; au++)
2261  if (((j == 0) && (strcmp(txt, AdUnits[au].cnt_name) == 0)) || ((j > 0) && (j == AdUnits[au].cnt_id)))
2262  {
2263  r = CurInterv.Level + (2.0 * ranf() - 1) * CurInterv.LevelAUVar + s;
2264  if ((CurInterv.Level < 1) && (r > 1))
2265  r = 1;
2266  else if (r < 0)
2267  r = 0;
2268  for (k = 0; k <= nsr; k++)
2269  {
2270  AdUnits[au].InterventionList[AdUnits[au].NI] = CurInterv;
2271  AdUnits[au].InterventionList[AdUnits[au].NI].Level = r;
2272  AdUnits[au].InterventionList[AdUnits[au].NI].StartTime = startt + ((double)k) * (stopt - startt);
2273  AdUnits[au].InterventionList[AdUnits[au].NI].StopTime = stopt + ((double)k) * (stopt - startt);
2274  AdUnits[au].NI++;
2275  }
2276  }
2277  }
2278  }
2279  if(fscanf(dat, "%*[^<]<%[^>]", txt) != 1) {
2280  ERR_CRITICAL("fscanf failed in ReadInterventions\n");
2281  }
2282  if (strcmp(txt, "/intervention") != 0) ERR_CRITICAL("Incorrect intervention specification in intervention file\n");
2283  }
2284  }
2285  if (strcmp(txt, "/InterventionSettings") != 0) ERR_CRITICAL("Intervention has no top level closure.\n");
2286  fprintf(stderr, "%i interventions read\n", ni);
2287  fclose(dat);
2288 }
2289 int GetXMLNode(FILE* dat, const char* NodeName, const char* ParentName, char* Value, int ResetFilePos)
2290 {
2291  // ResetFilePos=1 leaves dat cursor in same position as when function was called. 0 leaves it at end of NodeName closure
2292  // GetXMLNode returns 1 if NodeName found, 0 otherwise. If NodeName not found, ParentName closure must be
2293 
2294  char buf[65536], CloseNode[2048], CloseParent[2048];
2295  int CurPos, ret;
2296 
2297  sprintf(CloseParent, "/%s", ParentName);
2298  CurPos = ftell(dat);
2299  do
2300  {
2301  if(fscanf(dat, "%*[^<]<%[^>]", buf) != 1) {
2302  ERR_CRITICAL("fscanf failed in GetXMLNode");
2303  }
2304  } while ((strcmp(buf, CloseParent) != 0) && (strcmp(buf, NodeName) != 0) && (!feof(dat)));
2305  if (strcmp(buf, CloseParent) == 0)
2306  ret = 0;
2307  else
2308  {
2309  if (strcmp(buf, NodeName) != 0) ERR_CRITICAL("Incomplete node specification in XML file\n");
2310  if(fscanf(dat, ">%[^<]", buf) != 1) {
2311  ERR_CRITICAL("fscanf failed in GetXMLNode");
2312  }
2313  if (strlen(buf) < 2048) strcpy(Value, buf);
2314  // fprintf(stderr,"# %s=%s\n",NodeName,Value);
2315  if(fscanf(dat, "<%[^>]", buf) != 1) {
2316  ERR_CRITICAL("fscanf failed in GetXMLNode");
2317  }
2318  sprintf(CloseNode, "/%s", NodeName);
2319  if (strcmp(buf, CloseNode) != 0) ERR_CRITICAL("Incomplete node specification in XML file\n");
2320  ret = 1;
2321  }
2322  if (ResetFilePos) fseek(dat, CurPos, 0);
2323  return ret;
2324 }
2325 void ReadAirTravel(char* AirTravelFile)
2326 {
2327  int i, j, k, l;
2328  float sc, t, t2;
2329  float* buf;
2330  double traf;
2331  char outname[1024];
2332  FILE* dat;
2333 
2334  fprintf(stderr, "Reading airport data...\nAirports with no connections = ");
2335  if (!(dat = fopen(AirTravelFile, "rb"))) ERR_CRITICAL("Unable to open airport file\n");
2336  if(fscanf(dat, "%i %i", &P.Nairports, &P.Air_popscale) != 2) {
2337  ERR_CRITICAL("fscanf failed in void ReadAirTravel\n");
2338  }
2339  sc = (float)((double)P.PopSize / (double)P.Air_popscale);
2340  if (P.Nairports > MAX_AIRPORTS) ERR_CRITICAL("Too many airports\n");
2341  if (P.Nairports < 2) ERR_CRITICAL("Too few airports\n");
2342  if (!(buf = (float*)calloc(P.Nairports + 1, sizeof(float)))) ERR_CRITICAL("Unable to allocate airport storage\n");
2343  if (!(Airports = (Airport*)calloc(P.Nairports, sizeof(Airport)))) ERR_CRITICAL("Unable to allocate airport storage\n");
2344  for (i = 0; i < P.Nairports; i++)
2345  {
2346  if(fscanf(dat, "%f %f %lf", &(Airports[i].loc_x), &(Airports[i].loc_y), &traf) != 3) {
2347  ERR_CRITICAL("fscanf failed in void ReadAirTravel\n");
2348  }
2349  traf *= (P.AirportTrafficScale * sc);
2350  if ((Airports[i].loc_x < P.SpatialBoundingBox[0]) || (Airports[i].loc_x >= P.SpatialBoundingBox[2])
2351  || (Airports[i].loc_y < P.SpatialBoundingBox[1]) || (Airports[i].loc_y >= P.SpatialBoundingBox[3]))
2352  {
2353  Airports[i].loc_x = Airports[i].loc_y = -1;
2354  Airports[i].total_traffic = 0;
2355  }
2356  else
2357  {
2358  //fprintf(stderr,"(%f\t%f) ",Airports[i].loc_x,Airports[i].loc_y);
2359  Airports[i].loc_x -= (float)P.SpatialBoundingBox[0];
2360  Airports[i].loc_y -= (float)P.SpatialBoundingBox[1];
2361  Airports[i].total_traffic = (float)traf;
2362  }
2363  t = 0;
2364  for (j = k = 0; j < P.Nairports; j++)
2365  {
2366  if(fscanf(dat, "%f", buf + j) != 1) {
2367  ERR_CRITICAL("fscanf failed in void ReadAirTravel\n");
2368  }
2369  if (buf[j] > 0) { k++; t += buf[j]; }
2370  }
2371  Airports[i].num_connected = k;
2372  if (Airports[i].num_connected > 0)
2373  {
2374  if (!(Airports[i].prop_traffic = (float*)calloc(Airports[i].num_connected, sizeof(float)))) ERR_CRITICAL("Unable to allocate airport storage\n");
2375  if (!(Airports[i].conn_airports = (unsigned short int*) calloc(Airports[i].num_connected, sizeof(unsigned short int)))) ERR_CRITICAL("Unable to allocate airport storage\n");
2376  for (j = k = 0; j < P.Nairports; j++)
2377  if (buf[j] > 0)
2378  {
2379  Airports[i].conn_airports[k] = j;
2380  Airports[i].prop_traffic[k] = buf[j] / t;
2381  k++;
2382  }
2383  }
2384  else
2385  {
2386  if (Airports[i].total_traffic > 0)
2387  fprintf(stderr, "#%i# ", i);
2388  else
2389  fprintf(stderr, "%i ", i);
2390  }
2391  }
2392  fclose(dat);
2393  free(buf);
2394  fprintf(stderr, "\nAirport data read OK.\n");
2395  for (i = 0; i < P.Nairports; i++)
2396  {
2397  /* fprintf(stderr,"(%f %i|",Airports[i].total_traffic,Airports[i].num_connected);
2398  */ t = 0; k = 0;
2399  for (j = Airports[i].num_connected - 1; j >= 0; j--)
2400  {
2401  if ((Airports[i].prop_traffic[j] > 0) && (Airports[Airports[i].conn_airports[j]].total_traffic == 0))
2402  {
2403  t += Airports[i].prop_traffic[j];
2404  Airports[i].num_connected--;
2405  if (j < Airports[i].num_connected)
2406  {
2407  Airports[i].prop_traffic[j] = Airports[i].prop_traffic[Airports[i].num_connected];
2408  Airports[i].conn_airports[j] = Airports[i].conn_airports[Airports[i].num_connected];
2409  }
2410  Airports[i].prop_traffic[Airports[i].num_connected] = 0;
2411  Airports[i].conn_airports[Airports[i].num_connected] = 0;
2412  }
2413  else if (Airports[i].prop_traffic[j] > 0)
2414  k = 1;
2415  }
2416  /* fprintf(stderr,"%f %i ",t,k);
2417  */ t = 1.0f - t;
2418  if (k)
2419  {
2420  Airports[i].total_traffic *= t;
2421  t2 = 0;
2422  for (j = 0; j < Airports[i].num_connected; j++)
2423  {
2424  Airports[i].prop_traffic[j] = t2 + Airports[i].prop_traffic[j];
2425  t2 = Airports[i].prop_traffic[j];
2426  }
2427  for (j = 0; j < Airports[i].num_connected; j++)
2428  Airports[i].prop_traffic[j] /= t2;
2429  /* if((Airports[i].num_connected>0)&&(Airports[i].prop_traffic[Airports[i].num_connected-1]!=1))
2430  fprintf(stderr,"<%f> ",Airports[i].prop_traffic[Airports[i].num_connected-1]);
2431  */
2432  }
2433  else
2434  {
2435  Airports[i].total_traffic = 0; Airports[i].num_connected = 0;
2436  }
2437  if (Airports[i].num_connected > 0)
2438  {
2439  for (j = k = 0; k < 128; k++)
2440  {
2441  t = (float)((double)k / 128);
2442  while (Airports[i].prop_traffic[j] < t) j++;
2443  Airports[i].Inv_prop_traffic[k] = j;
2444  }
2445  Airports[i].Inv_prop_traffic[128] = Airports[i].num_connected - 1;
2446  }
2447  /* fprintf(stderr,"%f) ",Airports[i].total_traffic);
2448  */
2449  }
2450  fprintf(stderr, "Airport data clipped OK.\n");
2451  for (i = 0; i < MAX_DIST; i++) AirTravelDist[i] = 0;
2452  for (i = 0; i < P.Nairports; i++)
2453  if (Airports[i].total_traffic > 0)
2454  {
2455  for (j = 0; j < Airports[i].num_connected; j++)
2456  {
2457  k = (int)Airports[i].conn_airports[j];
2458  traf = floor(sqrt(dist2_raw(Airports[i].loc_x, Airports[i].loc_y, Airports[k].loc_x, Airports[k].loc_y)) / OUTPUT_DIST_SCALE);
2459  l = (int)traf;
2460  //fprintf(stderr,"%(%i) ",l);
2461  if (l < MAX_DIST)
2462  AirTravelDist[l] += Airports[i].total_traffic * Airports[i].prop_traffic[j];
2463  }
2464  }
2465  sprintf(outname, "%s.airdist.xls", OutFile);
2466  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open air travel output file\n");
2467  fprintf(dat, "dist\tfreq\n");
2468  for (i = 0; i < MAX_DIST; i++)
2469  fprintf(dat, "%i\t%.10f\n", i, AirTravelDist[i]);
2470  fclose(dat);
2471 }
2472 
2473 void InitModel(int run) // passing run number so we can save run number in the infection event log: ggilani - 15/10/2014
2474 {
2475  int nim;
2476  int nsi[MAX_NUM_SEED_LOCATIONS];
2477 
2478  if (P.OutputBitmap)
2479  {
2480 #ifdef _WIN32
2481  //if (P.OutputBitmap == 1)
2482  //{
2483  // char buf[200];
2484  // sprintf(buf, "%s.ge" DIRECTORY_SEPARATOR "%s.avi", OutFile, OutFile);
2485  // avi = CreateAvi(buf, P.BitmapMovieFrame, NULL);
2486  //}
2487 #endif
2488  for (unsigned p = 0; p < bmh->imagesize; p++)
2489  {
2490  bmInfected[p] = bmRecovered[p] = bmTreated[p] = 0;
2491  }
2492  }
2493  ns = 0;
2494  State.S = P.PopSize;
2495  State.L = State.I = State.R = State.D = 0;
2496  State.cumI = State.cumR = State.cumC = State.cumFC = State.cumH = State.cumCT = State.cumCC = State.cumTC = State.cumD = State.cumDC = State.trigDC = State.DCT = State.cumDCT
2497  = State.cumHQ
2498  = State.cumAC = State.cumAH = State.cumAA = State.cumACS
2499  = State.cumAPC = State.cumAPA = State.cumAPCS = 0;
2500  State.cumT = State.cumUT = State.cumTP = State.cumV = State.sumRad2 = State.maxRad2 = State.cumV_daily = State.cumVG = 0; //added State.cumVG
2501  State.mvacc_cum = 0;
2502  if (P.DoSeverity)
2503  {
2504  State.Mild = State.ILI = State.SARI = State.Critical = State.CritRecov = 0;
2505  State.cumMild = State.cumILI = State.cumSARI = State.cumCritical = State.cumCritRecov = 0;
2506  State.cumDeath_ILI = State.cumDeath_SARI = State.cumDeath_Critical = 0;
2507 
2508  for (int AdminUnit = 0; AdminUnit <= P.NumAdunits; AdminUnit++)
2509  {
2510  State.Mild_adunit[AdminUnit] = State.ILI_adunit[AdminUnit] =
2511  State.SARI_adunit[AdminUnit] = State.Critical_adunit[AdminUnit] = State.CritRecov_adunit[AdminUnit] =
2512  State.cumMild_adunit[AdminUnit] = State.cumILI_adunit[AdminUnit] =
2513  State.cumSARI_adunit[AdminUnit] = State.cumCritical_adunit[AdminUnit] = State.cumCritRecov_adunit[AdminUnit] =
2514  State.cumDeath_ILI_adunit[AdminUnit] = State.cumDeath_SARI_adunit[AdminUnit] = State.cumDeath_Critical_adunit[AdminUnit] =
2515  State.cumD_adunit[AdminUnit] = 0;
2516  }
2517  for (int AgeGroup = 0; AgeGroup < NUM_AGE_GROUPS; AgeGroup++)
2518  {
2519  State.Mild_age[AgeGroup] = State.ILI_age[AgeGroup] =
2520  State.SARI_age[AgeGroup] = State.Critical_age[AgeGroup] = State.CritRecov_age[AgeGroup] =
2521  State.cumMild_age[AgeGroup] = State.cumILI_age[AgeGroup] =
2522  State.cumSARI_age[AgeGroup] = State.cumCritical_age[AgeGroup] = State.cumCritRecov_age[AgeGroup] =
2523  State.cumDeath_ILI_age[AgeGroup] = State.cumDeath_SARI_age[AgeGroup] = State.cumDeath_Critical_age[AgeGroup] = 0;
2524  }
2525  }
2526 
2527  for (int i = 0; i < NUM_AGE_GROUPS; i++) State.cumCa[i] = State.cumIa[i] = State.cumDa[i] = 0;
2528  for (int i = 0; i < 2; i++) State.cumC_keyworker[i] = State.cumI_keyworker[i] = State.cumT_keyworker[i] = 0;
2529  for (int i = 0; i < NUM_PLACE_TYPES; i++) State.NumPlacesClosed[i] = 0;
2530  for (int i = 0; i < INFECT_TYPE_MASK; i++) State.cumItype[i] = 0;
2531  //initialise cumulative case counts per country to zero: ggilani 12/11/14
2532  for (int i = 0; i < MAX_COUNTRIES; i++) State.cumC_country[i] = 0;
2533  if (P.DoAdUnits)
2534  for (int i = 0; i <= P.NumAdunits; i++)
2535  {
2536  State.cumI_adunit[i] = State.cumC_adunit[i] = State.cumD_adunit[i] = State.cumT_adunit[i] = State.cumH_adunit[i] =
2537  State.cumDC_adunit[i] = State.cumCT_adunit[i] = State.cumCC_adunit[i] = State.trigDC_adunit[i] = State.DCT_adunit[i] = State.cumDCT_adunit[i] = 0; //added hospitalisation, added detected cases, contact tracing per adunit, cases who are contacts: ggilani 03/02/15, 15/06/17
2538  AdUnits[i].place_close_trig = 0;
2539  AdUnits[i].CaseIsolationTimeStart = AdUnits[i].HQuarantineTimeStart = AdUnits[i].DigitalContactTracingTimeStart = AdUnits[i].SocialDistanceTimeStart = AdUnits[i].PlaceCloseTimeStart = 1e10;
2540  AdUnits[i].ndct = 0; //noone being digitally contact traced at beginning of run
2541  }
2542 
2543  //update state variables for storing contact distribution
2544  for (int i = 0; i < MAX_CONTACTS+1; i++) State.contact_dist[i] = 0;
2545 
2546  for (int j = 0; j < MAX_NUM_THREADS; j++)
2547  {
2548  StateT[j].L = StateT[j].I = StateT[j].R = StateT[j].D = 0;
2549  StateT[j].cumI = StateT[j].cumR = StateT[j].cumC = StateT[j].cumFC = StateT[j].cumH = StateT[j].cumCT = StateT[j].cumCC = StateT[j].DCT = StateT[j].cumDCT = StateT[j].cumTC = StateT[j].cumD = StateT[j].cumDC
2550  = StateT[j].cumHQ = StateT[j].cumAC = StateT[j].cumACS
2551  = StateT[j].cumAH = StateT[j].cumAA = StateT[j].cumAPC = StateT[j].cumAPA = StateT[j].cumAPCS = 0;
2552  StateT[j].cumT = StateT[j].cumUT = StateT[j].cumTP = StateT[j].cumV = StateT[j].sumRad2 = StateT[j].maxRad2 = StateT[j].cumV_daily = 0;
2553  for (int i = 0; i < NUM_AGE_GROUPS; i++) StateT[j].cumCa[i] = StateT[j].cumIa[i] = StateT[j].cumDa[i] = 0;
2554  for (int i = 0; i < 2; i++) StateT[j].cumC_keyworker[i] = StateT[j].cumI_keyworker[i] = StateT[j].cumT_keyworker[i] = 0;
2555  for (int i = 0; i < NUM_PLACE_TYPES; i++) StateT[j].NumPlacesClosed[i] = 0;
2556  for (int i = 0; i < INFECT_TYPE_MASK; i++) StateT[j].cumItype[i] = 0;
2557  //initialise cumulative case counts per country per thread to zero: ggilani 12/11/14
2558  for (int i = 0; i < MAX_COUNTRIES; i++) StateT[j].cumC_country[i] = 0;
2559  if (P.DoAdUnits)
2560  for (int i = 0; i <= P.NumAdunits; i++)
2561  StateT[j].cumI_adunit[i] = StateT[j].cumC_adunit[i] = StateT[j].cumD_adunit[i] = StateT[j].cumT_adunit[i] = StateT[j].cumH_adunit[i] = StateT[j].cumDC_adunit[i] =
2562  StateT[j].cumCT_adunit[i] = StateT[j].cumCC_adunit[i] = StateT[j].nct_queue[i] = StateT[j].cumDCT_adunit[i] = StateT[j].DCT_adunit[i] = StateT[j].ndct_queue[i] = 0; //added hospitalisation, detected cases, contact tracing per adunit, cases who are contacts: ggilani 03/02/15, 15/06/17
2563 
2564  if (P.DoSeverity)
2565  {
2566  StateT[j].Mild = StateT[j].ILI = StateT[j].SARI = StateT[j].Critical = StateT[j].CritRecov = 0;
2567  StateT[j].cumMild = StateT[j].cumILI = StateT[j].cumSARI = StateT[j].cumCritical = StateT[j].cumCritRecov = 0;
2568  StateT[j].cumDeath_ILI = StateT[j].cumDeath_SARI = StateT[j].cumDeath_Critical = 0;
2569 
2570  for (int AdminUnit = 0; AdminUnit <= P.NumAdunits; AdminUnit++)
2571  {
2572  StateT[j].Mild_adunit[AdminUnit] = StateT[j].ILI_adunit[AdminUnit] =
2573  StateT[j].SARI_adunit[AdminUnit] = StateT[j].Critical_adunit[AdminUnit] = StateT[j].CritRecov_adunit[AdminUnit] =
2574  StateT[j].cumMild_adunit[AdminUnit] = StateT[j].cumILI_adunit[AdminUnit] =
2575  StateT[j].cumSARI_adunit[AdminUnit] = StateT[j].cumCritical_adunit[AdminUnit] = StateT[j].cumCritRecov_adunit[AdminUnit] =
2576  StateT[j].cumDeath_ILI_adunit[AdminUnit] = StateT[j].cumDeath_SARI_adunit[AdminUnit] = StateT[j].cumDeath_Critical_adunit[AdminUnit] =
2577  StateT[j].cumD_adunit[AdminUnit] = 0;
2578  }
2579  for (int AgeGroup = 0; AgeGroup < NUM_AGE_GROUPS; AgeGroup++)
2580  {
2581  StateT[j].Mild_age[AgeGroup] = StateT[j].ILI_age[AgeGroup] =
2582  StateT[j].SARI_age[AgeGroup] = StateT[j].Critical_age[AgeGroup] = StateT[j].CritRecov_age[AgeGroup] =
2583  StateT[j].cumMild_age[AgeGroup] = StateT[j].cumILI_age[AgeGroup] =
2584  StateT[j].cumSARI_age[AgeGroup] = StateT[j].cumCritical_age[AgeGroup] = StateT[j].cumCritRecov_age[AgeGroup] =
2585  StateT[j].cumDeath_ILI_age[AgeGroup] = StateT[j].cumDeath_SARI_age[AgeGroup] = StateT[j].cumDeath_Critical_age[AgeGroup] = 0;
2586  }
2587 
2588  }
2589  //resetting thread specific parameters for storing contact distribution
2590  for (int i = 0; i < MAX_CONTACTS+1; i++) StateT[j].contact_dist[i] = 0;
2591 
2592  }
2593  nim = 0;
2594 
2595 #pragma omp parallel for schedule(static,1) default(none) \
2596  shared(P, Hosts)
2597  for (int tn = 0; tn < P.NumThreads; tn++)
2598  for (int k = tn; k < P.PopSize; k+= P.NumThreads)
2599  {
2600  Hosts[k].absent_start_time = USHRT_MAX - 1;
2601  Hosts[k].absent_stop_time = 0;
2602  if (P.DoAirports) Hosts[k].PlaceLinks[P.HotelPlaceType] = -1;
2603  Hosts[k].vacc_start_time = Hosts[k].treat_start_time = Hosts[k].quar_start_time = Hosts[k].isolation_start_time = Hosts[k].absent_start_time = Hosts[k].dct_start_time = Hosts[k].dct_trigger_time = USHRT_MAX - 1;
2604  Hosts[k].treat_stop_time = Hosts[k].absent_stop_time = Hosts[k].dct_end_time = 0;
2605  Hosts[k].quar_comply = 2;
2606  Hosts[k].to_die = 0;
2607  Hosts[k].Travelling = 0;
2608  Hosts[k].detected = 0; //set detected to zero initially: ggilani - 19/02/15
2609  Hosts[k].detected_time = 0;
2610  Hosts[k].digitalContactTraced = 0;
2611  Hosts[k].inf = InfStat_Susceptible;
2612  Hosts[k].num_treats = 0;
2613  Hosts[k].latent_time = Hosts[k].recovery_or_death_time = 0; //also set hospitalisation time to zero: ggilani 28/10/2014
2614  Hosts[k].infector = -1;
2615  Hosts[k].infect_type = 0;
2616  Hosts[k].index_case_dct = 0;
2617  Hosts[k].ProbAbsent =(float) ranf_mt(tn);
2618  Hosts[k].ProbCare = (float) ranf_mt(tn);
2619  Hosts[k].susc = (float)((P.DoPartialImmunity) ? (1.0 - P.InitialImmunity[HOST_AGE_GROUP(k)]) : 1.0);
2620  if(P.SusceptibilitySD > 0) Hosts[k].susc *= (float) gen_gamma_mt(1 / (P.SusceptibilitySD * P.SusceptibilitySD), 1 / (P.SusceptibilitySD * P.SusceptibilitySD), tn);
2621  if (P.DoSeverity)
2622  {
2623  Hosts[k].SARI_time = USHRT_MAX - 1;
2624  Hosts[k].Critical_time = USHRT_MAX - 1;
2625  Hosts[k].RecoveringFromCritical_time = USHRT_MAX - 1;
2626  Hosts[k].Severity_Current = Severity_Asymptomatic;
2627  Hosts[k].Severity_Final = Severity_Asymptomatic;
2628  Hosts[k].inf = InfStat_Susceptible;
2629  }
2630  }
2631 
2632 #pragma omp parallel for reduction(+:nim) schedule(static,1) default(none) \
2633  shared(P, Cells, Hosts, Households)
2634  for (int tn = 0; tn < P.NumThreads; tn++)
2635  {
2636  for (int i = tn; i < P.NC; i+=P.NumThreads)
2637  {
2638  if ((Cells[i].tot_treat != 0) || (Cells[i].tot_vacc != 0) || (Cells[i].S != Cells[i].n) || (Cells[i].D > 0) || (Cells[i].R > 0))
2639  {
2640  for (int j = 0; j < Cells[i].n; j++)
2641  {
2642  int k = Cells[i].members[j];
2643  Cells[i].susceptible[j] = k; //added this in here instead
2644  Hosts[k].listpos = j;
2645  }
2646  Cells[i].S = Cells[i].n;
2647  Cells[i].L = Cells[i].I = Cells[i].R = Cells[i].cumTC = Cells[i].D = 0;
2648  Cells[i].infected = Cells[i].latent = Cells[i].susceptible + Cells[i].S;
2649  Cells[i].tot_treat = Cells[i].tot_vacc = 0;
2650  for (int l = 0; l < MAX_INTERVENTION_TYPES; l++) Cells[i].CurInterv[l] = -1;
2651 
2652  // Next loop needs to count down for DoImmune host list reordering to work
2653  if(!P.DoPartialImmunity)
2654  for (int j = Cells[i].n - 1; j >= 0; j--)
2655  {
2656  int k = Cells[i].members[j];
2657  if (P.DoWholeHouseholdImmunity)
2658  {
2659  // note that this breaks determinism of runs if executed due to reordering of Cell members list each realisation
2660  if (P.InitialImmunity[0] != 0)
2661  {
2662  if (Households[Hosts[k].hh].FirstPerson == k)
2663  {
2664  if ((P.InitialImmunity[0] == 1) || (ranf_mt(tn) < P.InitialImmunity[0]))
2665  {
2666  nim += Households[Hosts[k].hh].nh;
2667  for (int m = Households[Hosts[k].hh].nh - 1; m >= 0; m--)
2668  DoImmune(k + m);
2669  }
2670  }
2671  }
2672  }
2673  else
2674  {
2675  int m = HOST_AGE_GROUP(k);
2676  if ((P.InitialImmunity[m] == 1) || ((P.InitialImmunity[m] > 0) && (ranf_mt(tn) < P.InitialImmunity[m])))
2677  {
2678  DoImmune(k); nim += 1;
2679  }
2680  }
2681  }
2682  }
2683  }
2684  }
2685 
2686 #pragma omp parallel for schedule(static,500) default(none) \
2687  shared(P, Mcells, McellLookup)
2688  for (int l = 0; l < P.NMCP; l++)
2689  {
2690  int i = (int)(McellLookup[l] - Mcells);
2691  Mcells[i].vacc_start_time = Mcells[i].treat_start_time = USHRT_MAX - 1;
2692  Mcells[i].treat_end_time = 0;
2693  Mcells[i].treat_trig = Mcells[i].vacc_trig = Mcells[i].vacc = Mcells[i].treat = 0;
2694  Mcells[i].place_trig = Mcells[i].move_trig = Mcells[i].socdist_trig = Mcells[i].keyworkerproph_trig =
2695  Mcells[i].placeclose = Mcells[i].moverest = Mcells[i].socdist = Mcells[i].keyworkerproph = 0;
2696  Mcells[i].move_start_time = USHRT_MAX - 1;
2697  Mcells[i].place_end_time = Mcells[i].move_end_time =
2698  Mcells[i].socdist_end_time = Mcells[i].keyworkerproph_end_time = 0;
2699  }
2700  if (P.DoPlaces)
2701 #pragma omp parallel for schedule(static,1) default(none) \
2702  shared(P, Places)
2703  for (int m = 0; m < P.PlaceTypeNum; m++)
2704  {
2705  for(int l = 0; l < P.Nplace[m]; l++)
2706  {
2707  Places[m][l].close_start_time = USHRT_MAX - 1;
2708  Places[m][l].treat = Places[m][l].control_trig = 0;
2709  Places[m][l].treat_end_time = Places[m][l].close_end_time = 0;
2710  Places[m][l].ProbClose = (float) ranf_mt(m);
2711  if (P.AbsenteeismPlaceClosure)
2712  {
2713  Places[m][l].AbsentLastUpdateTime = 0;
2714  for (int i2 = 0; i2 < P.MaxAbsentTime; i2++) Places[m][l].Absent[i2] = 0;
2715  }
2716  }
2717  }
2718 
2721  P.SocDistDurationCurrent = P.SocDistDuration;
2722  P.SocDistSpatialEffectCurrent = P.SD_SpatialEffects_OverTime [0];
2723  P.SocDistHouseholdEffectCurrent = P.SD_HouseholdEffects_OverTime[0];
2724  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
2725  P.SocDistPlaceEffectCurrent[PlaceType] = P.SD_PlaceEffects_OverTime[0][PlaceType];
2726  P.SocDistCellIncThresh = P.SD_CellIncThresh_OverTime [0];
2727 
2729  P.EnhancedSocDistSpatialEffectCurrent = P.Enhanced_SD_SpatialEffects_OverTime [0];
2730  P.EnhancedSocDistHouseholdEffectCurrent = P.Enhanced_SD_HouseholdEffects_OverTime [0];
2731  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
2732  P.EnhancedSocDistPlaceEffectCurrent[PlaceType] = P.Enhanced_SD_PlaceEffects_OverTime[0][PlaceType];
2733 
2735  P.CaseIsolationEffectiveness = P.CI_SpatialAndPlaceEffects_OverTime [0];
2736  P.CaseIsolationHouseEffectiveness = P.CI_HouseholdEffects_OverTime [0];
2737  P.CaseIsolationProp = P.CI_Prop_OverTime [0];
2738  P.CaseIsolation_CellIncThresh = P.CI_CellIncThresh_OverTime [0];
2739 
2740 
2742  P.HQuarantineSpatialEffect = P.HQ_SpatialEffects_OverTime [0];
2743  P.HQuarantineHouseEffect = P.HQ_HouseholdEffects_OverTime[0];
2744  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
2745  P.HQuarantinePlaceEffect[PlaceType] = P.HQ_PlaceEffects_OverTime [0][PlaceType];
2746  P.HQuarantinePropIndivCompliant = P.HQ_Individual_PropComply_OverTime [0];
2747  P.HQuarantinePropHouseCompliant = P.HQ_Household_PropComply_OverTime [0];
2748  P.HHQuar_CellIncThresh = P.HQ_CellIncThresh_OverTime [0];
2749 
2750 
2752  P.PlaceCloseSpatialRelContact = P.PC_SpatialEffects_OverTime [0];
2753  P.PlaceCloseHouseholdRelContact = P.PC_HouseholdEffects_OverTime[0];
2754  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
2755  {
2756  P.PlaceCloseEffect[PlaceType] = P.PC_PlaceEffects_OverTime[0][PlaceType];
2757  P.PlaceClosePropAttending[PlaceType] = P.PC_PropAttending_OverTime[0][PlaceType];
2758  }
2759  P.PlaceCloseIncTrig1 = P.PC_IncThresh_OverTime [0];
2760  P.PlaceCloseFracIncTrig = P.PC_FracIncThresh_OverTime [0];
2761  P.PlaceCloseCellIncThresh1 = P.PC_CellIncThresh_OverTime [0];
2762  P.PlaceCloseDurationBase = P.PC_Durs_OverTime[0];
2763 
2764 
2766  P.DCTCaseIsolationEffectiveness = P.DCT_SpatialAndPlaceEffects_OverTime [0];
2767  P.DCTCaseIsolationHouseEffectiveness = P.DCT_HouseholdEffects_OverTime [0];
2768  P.ProportionDigitalContactsIsolate = P.DCT_Prop_OverTime [0];
2769  P.MaxDigitalContactsToTrace = P.DCT_MaxToTrace_OverTime [0];
2770 
2771 
2772 
2773  for (int i = 0; i < MAX_NUM_THREADS; i++)
2774  {
2775  for (int j = 0; j < MAX_NUM_THREADS; j++) StateT[i].n_queue[j] = 0;
2776  for (int j = 0; j < P.PlaceTypeNum; j++) StateT[i].np_queue[j] = 0;
2777  }
2778  if (DoInitUpdateProbs)
2779  {
2780  UpdateProbs(0);
2781  DoInitUpdateProbs = 0;
2782  }
2783  //initialise event log to zero at the beginning of every run: ggilani - 10/10/2014. UPDATE: 15/10/14 - we are now going to store all events from all realisations in one file
2784  if ((P.DoRecordInfEvents) && (P.RecordInfEventsPerRun))
2785  {
2786  nEvents = 0;
2787  for (int i = 0; i < P.MaxInfEvents; i++)
2788  {
2789  InfEventLog[i].t = InfEventLog[i].infectee_x = InfEventLog[i].infectee_y = InfEventLog[i].t_infector = 0.0;
2790  InfEventLog[i].infectee_ind = InfEventLog[i].infector_ind = 0;
2791  InfEventLog[i].infectee_adunit = InfEventLog[i].listpos = InfEventLog[i].infectee_cell = InfEventLog[i].infector_cell = InfEventLog[i].thread = 0;
2792  }
2793  }
2794 
2795  for (int i = 0; i < P.NumSeedLocations; i++) nsi[i] = (int) (((double) P.NumInitialInfections[i]) * P.InitialInfectionsAdminUnitWeight[i]* P.SeedingScaling +0.5);
2796  SeedInfection(0, nsi, 0, run);
2797  P.ControlPropCasesId = P.PreAlertControlPropCasesId;
2798  P.TreatTimeStart = 1e10;
2799 
2800  P.VaccTimeStart = 1e10;
2801  P.MoveRestrTimeStart = 1e10;
2802  P.PlaceCloseTimeStart = 1e10;
2803  P.PlaceCloseTimeStart2 = 2e10;
2804  P.SocDistTimeStart = 1e10;
2805  P.AirportCloseTimeStart = 1e10;
2806  //P.DigitalContactTracingTimeStart = 1e10;
2807  P.HQuarantineTimeStart = 1e10;
2808  P.KeyWorkerProphTimeStart = 1e10;
2809  P.TreatMaxCourses = P.TreatMaxCoursesBase;
2810  P.VaccMaxCourses = P.VaccMaxCoursesBase;
2811  P.PlaceCloseDuration = P.PlaceCloseDurationBase;
2812  P.PlaceCloseIncTrig = P.PlaceCloseIncTrig1;
2813  P.PlaceCloseTimeStartPrevious = 1e10;
2814  P.PlaceCloseCellIncThresh = P.PlaceCloseCellIncThresh1;
2815  P.ResetSeedsFlag = 0; //added this to allow resetting seeds part way through run: ggilani 27/11/2019
2816  if (!P.StopCalibration) P.PreControlClusterIdTime = 0;
2817 
2818  fprintf(stderr, "Finished InitModel.\n");
2819 }
2820 
2821 void SeedInfection(double t, int* nsi, int rf, int run) //adding run number to pass it to event log
2822 {
2823  /* *nsi is an array of the number of seeding infections by location. During runtime, usually just a single int (given by a poisson distribution)*/
2824  /*rf set to 0 when initializing model, otherwise set to 1 during runtime. */
2825 
2826  int i /*seed location index*/;
2827  int j /*microcell number*/;
2828  int k, l /*k,l are grid coords at first, then l changed to be person within Microcell j, then k changed to be index of new infection*/;
2829  int m = 0/*guard against too many infections and infinite loop*/;
2830  int f /*range = {0, 1000}*/;
2831  int n /*number of seed locations?*/;
2832 
2833  n = ((rf == 0) ? P.NumSeedLocations : 1);
2834  for (i = 0; i < n; i++)
2835  {
2836  if ((!P.DoRandomInitialInfectionLoc) || ((P.DoAllInitialInfectioninSameLoc) && (rf)))
2837  {
2838  k = (int)(P.LocationInitialInfection[i][0] / P.in_microcells_.width_);
2839  l = (int)(P.LocationInitialInfection[i][1] / P.in_microcells_.height_);
2840  j = k * P.get_number_of_micro_cells_high() + l;
2841  m = 0;
2842  for (k = 0; (k < nsi[i]) && (m < 10000); k++)
2843  {
2844  l = Mcells[j].members[(int)(ranf() * ((double)Mcells[j].n))];
2845  if (Hosts[l].inf == InfStat_Susceptible)
2846  {
2847  if (CalcPersonSusc(l, 0, 0, 0) > 0)
2848  {
2849  //only reset the initial location if rf==0, i.e. when initial seeds are being set, not when imported cases are being set
2850  if (rf == 0)
2851  {
2852  P.LocationInitialInfection[i][0] = Households[Hosts[l].hh].loc_x;
2853  P.LocationInitialInfection[i][1] = Households[Hosts[l].hh].loc_y;
2854  }
2855  Hosts[l].infector = -2;
2856  Hosts[l].infect_type = INFECT_TYPE_MASK - 1;
2857  DoInfect(l, t, 0, run);
2858  m = 0;
2859  }
2860  }
2861  else { k--; m++; }
2862  }
2863  }
2864  else if (P.DoAllInitialInfectioninSameLoc)
2865  {
2866  f = 0;
2867  do
2868  {
2869  m = 0;
2870  do
2871  {
2872  l = (int)(ranf() * ((double)P.PopSize));
2873  j = Hosts[l].mcell;
2874  //fprintf(stderr,"%i ",AdUnits[Mcells[j].adunit].id);
2875  } while ((Mcells[j].n < nsi[i]) || (Mcells[j].n > P.MaxPopDensForInitialInfection)
2876  || (Mcells[j].n < P.MinPopDensForInitialInfection)
2877  || ((P.InitialInfectionsAdminUnit[i] > 0) && ((AdUnits[Mcells[j].adunit].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor != (P.InitialInfectionsAdminUnit[i] % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor)));
2878  for (k = 0; (k < nsi[i]) && (m < 10000); k++)
2879  {
2880  l = Mcells[j].members[(int)(ranf() * ((double)Mcells[j].n))];
2881  if (Hosts[l].inf == InfStat_Susceptible)
2882  {
2883  if (CalcPersonSusc(l, 0, 0, 0) > 0)
2884  {
2885  P.LocationInitialInfection[i][0] = Households[Hosts[l].hh].loc_x;
2886  P.LocationInitialInfection[i][1] = Households[Hosts[l].hh].loc_y;
2887  Hosts[l].infector = -2; Hosts[l].infect_type = INFECT_TYPE_MASK - 1;
2888  DoInfect(l, t, 0, run);
2889  m = 0;
2890  }
2891  }
2892  else
2893  {
2894  k--; m++;
2895  }
2896  }
2897  if (m)
2898  f++;
2899  else
2900  f = 0;
2901  } while ((f > 0) && (f < 1000));
2902  }
2903  else
2904  {
2905  m = 0;
2906  for (k = 0; (k < nsi[i]) && (m < 10000); k++)
2907  {
2908  do
2909  {
2910  l = (int)(ranf() * ((double)P.PopSize));
2911  j = Hosts[l].mcell;
2912  //fprintf(stderr,"@@ %i %i ",AdUnits[Mcells[j].adunit].id, (int)(AdUnits[Mcells[j].adunit].id / P.CountryDivisor));
2913  } while ((Mcells[j].n == 0) || (Mcells[j].n > P.MaxPopDensForInitialInfection)
2914  || (Mcells[j].n < P.MinPopDensForInitialInfection)
2915  || ((P.InitialInfectionsAdminUnit[i] > 0) && ((AdUnits[Mcells[j].adunit].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor != (P.InitialInfectionsAdminUnit[i] % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor)));
2916  l = Mcells[j].members[(int)(ranf() * ((double)Mcells[j].n))];
2917  if (Hosts[l].inf == InfStat_Susceptible)
2918  {
2919  if (CalcPersonSusc(l, 0, 0, 0) > 0)
2920  {
2921  P.LocationInitialInfection[i][0] = Households[Hosts[l].hh].loc_x;
2922  P.LocationInitialInfection[i][1] = Households[Hosts[l].hh].loc_y;
2923  Hosts[l].infector = -2; Hosts[l].infect_type = INFECT_TYPE_MASK - 1;
2924  DoInfect(l, t, 0, run);
2925  m = 0;
2926  }
2927  else
2928  {
2929  k--; m++;
2930  }
2931  }
2932  else
2933  {
2934  k--; m++;
2935  }
2936  }
2937  }
2938  }
2939  if (m > 0) fprintf(stderr, "### Seeding error ###\n");
2940 }
2941 
2942 
2943 int RunModel(int run) //added run number as parameter
2944 {
2945  int j, k, l, fs, fs2, nu, ni, nsi[MAX_NUM_SEED_LOCATIONS] /*Denotes either Num imported Infections given rate ir, or number false positive "infections"*/;
2946  double ir; // infection import rate?;
2947  double t, cI, lcI, t2;
2948  unsigned short int ts;
2949  int continueEvents = 1;
2950 
2951 
2952 /* fprintf(stderr, "Checking consistency of initial state...\n");
2953  int i, i2, k2;
2954  for (i = j = k = ni = fs2 = i2 = 0; i < P.N; i++)
2955  {
2956  if (i % 1000 == 0) fprintf(stderr, "\r*** %i ", i);
2957  if (Hosts[i].inf == 0) j++;
2958  if ((Hosts[i].pcell < P.NC) && (Hosts[i].pcell >= 0))
2959  {
2960  if (Cells[Hosts[i].pcell].susceptible[Hosts[i].listpos] != i)
2961  {
2962  k++;
2963  for (l = fs = 0; (l < Cells[Hosts[i].pcell].n) && (!fs); l++)
2964  fs = (Cells[Hosts[i].pcell].susceptible[l] == i);
2965  if (!fs) ni++;
2966  }
2967  else
2968  {
2969  if ((Hosts[i].listpos > Cells[Hosts[i].pcell].S - 1) && (Hosts[i].inf == InfStat_Susceptible)) i2++;
2970  if ((Hosts[i].listpos < Cells[Hosts[i].pcell].S + Cells[Hosts[i].pcell].L + Cells[Hosts[i].pcell].I - 1) && (abs(Hosts[i].inf) == InfStat_Recovered)) i2++;
2971  }
2972  if ((Cells[Hosts[i].pcell].S + Cells[Hosts[i].pcell].L + Cells[Hosts[i].pcell].I + Cells[Hosts[i].pcell].R + Cells[Hosts[i].pcell].D) != Cells[Hosts[i].pcell].n)
2973  {
2974  k2++;
2975  }
2976  }
2977  else
2978  fs2++;
2979  }
2980  fprintf(stderr, "\n*** susceptibles=%i\nincorrect listpos=%i\nhosts not found in cell list=%i\nincorrect cell refs=%i\nincorrect positioning in cell susc list=%i\nwrong cell totals=%i\n", j, k, ni, fs2, i2, k2);
2981 */
2982  InterruptRun = 0;
2983  lcI = 1;
2984  if (P.DoLoadSnapshot)
2985  {
2986  P.ts_age = (int)(P.SnapshotLoadTime * P.TimeStepsPerDay);
2987  t = ((double)P.ts_age) * P.TimeStep;
2988  }
2989  else
2990  {
2991  t = 0;
2992  P.ts_age = 0;
2993  }
2994  fs = 1;
2995  fs2 = 0;
2996  nu = 0;
2997 
2998  for (ns = 1; ((ns < P.NumSamples) && (!InterruptRun)); ns++) //&&(continueEvents) <-removed this
2999  {
3000  RecordSample(t, ns - 1);
3001  fprintf(stderr, "\r t=%lg %i %i|%i %i %i [=%i] %i (%lg %lg %lg) %lg ", t,
3002  State.S, State.L, State.I, State.R, State.D, State.S + State.L + State.I + State.R + State.D, State.cumD, State.cumT, State.cumV, State.cumVG, sqrt(State.maxRad2) / 1000); //added State.cumVG
3003  if (!InterruptRun)
3004  {
3005  //Only run to a certain number of infections: ggilani 28/10/14
3006  if (P.LimitNumInfections) continueEvents = (State.cumI < P.MaxNumInfections);
3007 
3008  for (j = 0; ((j < P.UpdatesPerSample) && (!InterruptRun) && (continueEvents)); j++)
3009  {
3010  ts = (unsigned short int) (P.TimeStepsPerDay * t);
3011 
3012  //if we are to reset random numbers after an intervention event, specific time
3013  if (P.ResetSeedsPostIntervention)
3014  if ((P.ResetSeedsFlag == 0) && (ts >= (P.TimeToResetSeeds * P.TimeStepsPerDay)))
3015  {
3016  setall(&P.nextRunSeed1, &P.nextRunSeed2);
3017  P.ResetSeedsFlag = 1;
3018  }
3019 
3020  if (fs)
3021  {
3022  if (P.DoAirports) TravelDepartSweep(t);
3023  k = (int)t;
3024  if (P.DurImportTimeProfile > 0)
3025  {
3026  if (k < P.DurImportTimeProfile)
3027  ir = P.ImportInfectionTimeProfile[k] * ((t > P.InfectionImportChangeTime) ? (P.InfectionImportRate2 / P.InfectionImportRate1) : 1.0);
3028  else
3029  ir = 0;
3030  }
3031  else ir = (t > P.InfectionImportChangeTime) ? P.InfectionImportRate2 : P.InfectionImportRate1;
3032  if (ir > 0)
3033  {
3034  for (k = ni = 0; k < P.NumSeedLocations; k++) ni += (nsi[k] = (int)ignpoi(P.TimeStep * ir * P.InitialInfectionsAdminUnitWeight[k] * P.SeedingScaling));
3035  if (ni > 0) SeedInfection(t, nsi, 1, run);
3036  }
3037  if (P.FalsePositivePerCapitaIncidence > 0)
3038  {
3039  ni = (int)ignpoi(P.TimeStep * P.FalsePositivePerCapitaIncidence * ((double)P.PopSize));
3040  if (ni > 0)
3041  {
3042  for (k = 0; k < ni; k++)
3043  {
3044  do
3045  {
3046  l = (int)(((double)P.PopSize) * ranf());
3047  } while ((abs(Hosts[l].inf) == InfStat_Dead) || (ranf() > P.FalsePositiveAgeRate[HOST_AGE_GROUP(l)]));
3048  DoFalseCase(l, t, ts, 0);
3049  }
3050  }
3051  }
3052  InfectSweep(t, run); // loops over all infectious people and decides which susceptible people to infect (at household, place and spatial level), and adds them to queue. Then changes each person's various characteristics using DoInfect function. adding run number as a parameter to infect sweep so we can track run number: ggilani - 15/10/14
3054  if (!P.DoSI) IncubRecoverySweep(t, run);
3055  // If doing new contact tracing, update numbers of people under contact tracing after each time step
3056 
3057  if (P.DoDigitalContactTracing) DigitalContactTracingSweep(t);
3058 
3059  nu++;
3060  fs2 = ((P.DoDeath) || (State.L + State.I > 0) || (ir > 0) || (P.FalsePositivePerCapitaIncidence > 0));
3062  if (!TreatSweep(t))
3063  {
3064  if ((!fs2) && (State.L + State.I == 0) && (P.FalsePositivePerCapitaIncidence == 0)) { if ((ir == 0) && (((int)t) > P.DurImportTimeProfile)) fs = 0; }
3065  }
3066  if (P.DoAirports) TravelReturnSweep(t);
3067  }
3068  t += P.TimeStep;
3069  if (P.DoDeath) P.ts_age++;
3070  if ((P.DoSaveSnapshot) && (t <= P.SnapshotSaveTime) && (t + P.TimeStep > P.SnapshotSaveTime)) SaveSnapshot();
3071  if (t > P.TreatNewCoursesStartTime) P.TreatMaxCourses += P.TimeStep * P.TreatNewCoursesRate;
3072  if ((t > P.VaccNewCoursesStartTime) && (t < P.VaccNewCoursesEndTime)) P.VaccMaxCourses += P.TimeStep * P.VaccNewCoursesRate;
3073  cI = ((double)(State.S)) / ((double)P.PopSize);
3074  if ((lcI - cI) > 0.2)
3075  {
3076  lcI = cI;
3077  UpdateProbs(0);
3078  DoInitUpdateProbs = 1;
3079  }
3080  }
3081  }
3082  }
3083  if (!InterruptRun) RecordSample(t, P.NumSamples - 1);
3084  fprintf(stderr, "\nEnd of run\n");
3085  t2 = t + P.SampleTime;
3086 // if(!InterruptRun)
3087  while (fs)
3088  {
3089  fs = TreatSweep(t2);
3090  t2 += P.SampleStep;
3091  }
3092  // fprintf(stderr,"End RunModel\n");
3093  if (P.DoAirports)
3094  {
3095  t2 = t;
3096  for (t2 = t; t2 <= t + MAX_TRAVEL_TIME; t2 += P.TimeStep)
3097  TravelReturnSweep(t2);
3098  }
3099 /* if (!InterruptRun)
3100  {
3101  fprintf(stderr, "Checking consistency of final state...\n");
3102  int i, i2, k2;
3103  for (i = j = k = ni = fs2 = i2 = 0; i < P.PopSize; i++)
3104  {
3105  if (i % 1000 == 0) fprintf(stderr, "\r*** %i ", i);
3106  if (Hosts[i].inf == 0) j++;
3107  if ((Hosts[i].pcell < P.NC) && (Hosts[i].pcell >= 0))
3108  {
3109  if (Cells[Hosts[i].pcell].susceptible[Hosts[i].listpos] != i)
3110  {
3111  k++;
3112  for (l = fs = 0; (l < Cells[Hosts[i].pcell].n) && (!fs); l++)
3113  fs = (Cells[Hosts[i].pcell].susceptible[l] == i);
3114  if (!fs) ni++;
3115  }
3116  else
3117  {
3118  if ((Hosts[i].listpos > Cells[Hosts[i].pcell].S - 1) && (Hosts[i].inf == InfStat_Susceptible)) i2++;
3119  if ((Hosts[i].listpos < Cells[Hosts[i].pcell].S + Cells[Hosts[i].pcell].L + Cells[Hosts[i].pcell].I - 1) && (abs(Hosts[i].inf) == InfStat_Recovered)) i2++;
3120  }
3121  if ((Cells[Hosts[i].pcell].S + Cells[Hosts[i].pcell].L + Cells[Hosts[i].pcell].I + Cells[Hosts[i].pcell].R + Cells[Hosts[i].pcell].D) != Cells[Hosts[i].pcell].n)
3122  {
3123  k2++;
3124  }
3125  }
3126  else
3127  fs2++;
3128  }
3129  fprintf(stderr, "\n*** susceptibles=%i\nincorrect listpos=%i\nhosts not found in cell list=%i\nincorrect cell refs=%i\nincorrect positioning in cell susc list=%i\nwrong cell totals=%i\n", j, k, ni, fs2, i2, k2);
3130  }
3131 */
3132  if(!InterruptRun) RecordInfTypes();
3133  return (InterruptRun);
3134 }
3135 
3136 void SaveDistribs(void)
3137 {
3138  int i, j, k;
3139  FILE* dat;
3140  char outname[1024];
3141  double s;
3142 
3143  if (P.DoPlaces)
3144  {
3145  for (j = 0; j < P.PlaceTypeNum; j++)
3146  if (j != P.HotelPlaceType)
3147  {
3148  for (i = 0; i < P.Nplace[j]; i++)
3149  Places[j][i].n = 0;
3150  for (i = 0; i < P.PopSize; i++)
3151  {
3152  if (Hosts[i].PlaceLinks[j] >= P.Nplace[j])
3153  fprintf(stderr, "*%i %i: %i %i", i, j, Hosts[i].PlaceLinks[j], P.Nplace[j]);
3154  else if (Hosts[i].PlaceLinks[j] >= 0)
3155  Places[j][Hosts[i].PlaceLinks[j]].n++;
3156  }
3157  }
3158  for (j = 0; j < P.PlaceTypeNum; j++)
3159  for (i = 0; i < MAX_DIST; i++)
3160  PlaceDistDistrib[j][i] = 0;
3161  for (i = 0; i < P.PopSize; i++)
3162  for (j = 0; j < P.PlaceTypeNum; j++)
3163  if ((j != P.HotelPlaceType) && (Hosts[i].PlaceLinks[j] >= 0))
3164  {
3165  if (Hosts[i].PlaceLinks[j] >= P.Nplace[j])
3166  fprintf(stderr, "*%i %i: %i ", i, j, Hosts[i].PlaceLinks[j]);
3167  else if ((!P.DoOutputPlaceDistForOneAdunit) ||
3168  ((AdUnits[Mcells[Hosts[i].mcell].adunit].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor == (P.OutputPlaceDistAdunit % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor))
3169  {
3170  k = Hosts[i].PlaceLinks[j];
3171  s = sqrt(dist2_raw(Households[Hosts[i].hh].loc_x, Households[Hosts[i].hh].loc_y, Places[j][k].loc_x, Places[j][k].loc_y)) / OUTPUT_DIST_SCALE;
3172  k = (int)s;
3173  if (k < MAX_DIST) PlaceDistDistrib[j][k]++;
3174  }
3175  }
3176  for (j = 0; j < P.PlaceTypeNum; j++)
3177  for (i = 0; i < MAX_PLACE_SIZE; i++)
3178  PlaceSizeDistrib[j][i] = 0;
3179  for (j = 0; j < P.PlaceTypeNum; j++)
3180  if (j != P.HotelPlaceType)
3181  for (i = 0; i < P.Nplace[j]; i++)
3182  if (Places[j][i].n < MAX_PLACE_SIZE)
3183  PlaceSizeDistrib[j][Places[j][i].n]++;
3184  sprintf(outname, "%s.placedist.xls", OutFile);
3185  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3186  fprintf(dat, "dist");
3187  for (j = 0; j < P.PlaceTypeNum; j++)
3188  if (j != P.HotelPlaceType)
3189  fprintf(dat, "\tfreq_p%i", j);
3190  fprintf(dat, "\n");
3191  for (i = 0; i < MAX_DIST; i++)
3192  {
3193  fprintf(dat, "%i", i);
3194  for (j = 0; j < P.PlaceTypeNum; j++)
3195  if (j != P.HotelPlaceType)
3196  fprintf(dat, "\t%i", PlaceDistDistrib[j][i]);
3197  fprintf(dat, "\n");
3198  }
3199  fclose(dat);
3200  sprintf(outname, "%s.placesize.xls", OutFile);
3201  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3202  fprintf(dat, "size");
3203  for (j = 0; j < P.PlaceTypeNum; j++)
3204  if (j != P.HotelPlaceType)
3205  fprintf(dat, "\tfreq_p%i", j);
3206  fprintf(dat, "\n");
3207  for (i = 0; i < MAX_PLACE_SIZE; i++)
3208  {
3209  fprintf(dat, "%i", i);
3210  for (j = 0; j < P.PlaceTypeNum; j++)
3211  if (j != P.HotelPlaceType)
3212  fprintf(dat, "\t%i", PlaceSizeDistrib[j][i]);
3213  fprintf(dat, "\n");
3214  }
3215  fclose(dat);
3216  }
3217 }
3218 void SaveOriginDestMatrix(void)
3219 {
3228  int i, j;
3229  FILE* dat;
3230  char outname[1024];
3231 
3232  sprintf(outname, "%s.origdestmat.xls", OutFile);
3233  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3234  fprintf(dat, "0,");
3235  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "%i,", (AdUnits[i].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor);
3236  fprintf(dat, "\n");
3237  for (i = 0; i < P.NumAdunits; i++)
3238  {
3239  fprintf(dat, "%i,", (AdUnits[i].id % P.AdunitLevel1Mask) / P.AdunitLevel1Divisor);
3240  for (j = 0; j < P.NumAdunits; j++)
3241  {
3242  fprintf(dat, "%.10f,", AdUnits[i].origin_dest[j]);
3243  }
3244  fprintf(dat, "\n");
3245  }
3246  fclose(dat);
3247 }
3248 
3249 void SaveResults(void)
3250 {
3251  int i, j;
3252  FILE* dat;
3253  char outname[1024];
3254 
3255  if (P.OutputNonSeverity)
3256  {
3257  sprintf(outname, "%s.xls", OutFile);
3258  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3259  fprintf(dat, "t\tS\tL\tI\tR\tD\tincI\tincR\tincFC\tincC\tincDC\tincTC\tincH\tincCT\tincCC\tcumT\tcumTP\tcumV\tcumVG\tExtinct\trmsRad\tmaxRad\n");//\t\t%.10f\t%.10f\t%.10f\n",P.R0household,P.R0places,P.R0spatial);
3260  for(i = 0; i < P.NumSamples; i++)
3261  {
3262  fprintf(dat, "%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\n",
3263  TimeSeries[i].t, TimeSeries[i].S, TimeSeries[i].L, TimeSeries[i].I,
3264  TimeSeries[i].R, TimeSeries[i].D, TimeSeries[i].incI,
3265  TimeSeries[i].incR, TimeSeries[i].incFC, TimeSeries[i].incC, TimeSeries[i].incDC, TimeSeries[i].incTC, TimeSeries[i].incH, TimeSeries[i].incCT, TimeSeries[i].incCC,
3266  TimeSeries[i].cumT, TimeSeries[i].cumTP, TimeSeries[i].cumV, TimeSeries[i].cumVG, TimeSeries[i].extinct, TimeSeries[i].rmsRad, TimeSeries[i].maxRad);
3267  }
3268  fclose(dat);
3269  }
3270 
3271  if ((P.DoAdUnits) && (P.DoAdunitOutput))
3272  {
3273  sprintf(outname, "%s.adunit.xls", OutFile);
3274  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3275  fprintf(dat, "t");
3276  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tI_%s", AdUnits[i].ad_name);
3277  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tC_%s", AdUnits[i].ad_name);
3278  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tDC_%s", AdUnits[i].ad_name);
3279 
3280  fprintf(dat, "\n");
3281  for (i = 0; i < P.NumSamples; i++)
3282  {
3283  fprintf(dat, "%.10f", TimeSeries[i].t);
3284  for (j = 0; j < P.NumAdunits; j++)
3285  fprintf(dat, "\t%.10f", TimeSeries[i].incI_adunit[j]);
3286  for (j = 0; j < P.NumAdunits; j++)
3287  fprintf(dat, "\t%.10f", TimeSeries[i].incC_adunit[j]);
3288  for (j = 0; j < P.NumAdunits; j++)
3289  fprintf(dat, "\t%.10f", TimeSeries[i].incDC_adunit[j]);
3290  fprintf(dat, "\n");
3291  }
3292  fclose(dat);
3293  }
3294 
3295  if ((P.DoDigitalContactTracing) && (P.DoAdUnits) && (P.OutputDigitalContactTracing))
3296  {
3297  sprintf(outname, "%s.digitalcontacttracing.xls", OutFile); //modifying to csv file
3298  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3299  fprintf(dat, "t");
3300  for (i = 0; i < P.NumAdunits; i++)
3301  {
3302  fprintf(dat, "\tincDCT_%s", AdUnits[i].ad_name);
3303  }
3304  for (i = 0; i < P.NumAdunits; i++)
3305  {
3306  fprintf(dat, "\tDCT_%s", AdUnits[i].ad_name);
3307  }
3308  fprintf(dat, "\n");
3309  //print actual output
3310  for(i=0; i<P.NumSamples; i++)
3311  {
3312  fprintf(dat, "%.10lf", TimeSeries[i].t);
3313  for (j = 0; j < P.NumAdunits; j++)
3314  {
3315  fprintf(dat, "\t%.10lf", TimeSeries[i].incDCT_adunit[j]);
3316  }
3317  for (j = 0; j < P.NumAdunits; j++)
3318  {
3319  fprintf(dat, "\t%.10lf", TimeSeries[i].DCT_adunit[j]);
3320  }
3321  fprintf(dat, "\n");
3322  }
3323  fclose(dat);
3324 
3325  }
3326 
3327  if ((P.DoDigitalContactTracing) && (P.OutputDigitalContactDist))
3328  {
3329  sprintf(outname, "%s.digitalcontactdist.xls", OutFile); //modifying to csv file
3330  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3331  //print headers
3332  fprintf(dat, "nContacts\tFrequency\n");
3333  for (i = 0; i < (MAX_CONTACTS + 1); i++)
3334  {
3335  fprintf(dat, "%i\t%i\n", i, State.contact_dist[i]);
3336  }
3337  fclose(dat);
3338  }
3339 
3340  if(P.KeyWorkerProphTimeStartBase < P.SampleTime)
3341  {
3342  sprintf(outname, "%s.keyworker.xls", OutFile);
3343  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3344  fprintf(dat, "t");
3345  for(i = 0; i < 2; i++) fprintf(dat, "\tI%i", i);
3346  for(i = 0; i < 2; i++) fprintf(dat, "\tC%i", i);
3347  for(i = 0; i < 2; i++) fprintf(dat, "\tT%i", i);
3348  fprintf(dat, "\t%i\t%i\n", P.KeyWorkerNum, P.KeyWorkerIncHouseNum);
3349  for(i = 0; i < P.NumSamples; i++)
3350  {
3351  fprintf(dat, "%.10f", TimeSeries[i].t);
3352  for(j = 0; j < 2; j++)
3353  fprintf(dat, "\t%.10f", TimeSeries[i].incI_keyworker[j]);
3354  for(j = 0; j < 2; j++)
3355  fprintf(dat, "\t%.10f", TimeSeries[i].incC_keyworker[j]);
3356  for(j = 0; j < 2; j++)
3357  fprintf(dat, "\t%.10f", TimeSeries[i].cumT_keyworker[j]);
3358  fprintf(dat, "\n");
3359  }
3360  fclose(dat);
3361  }
3362 
3363  if(P.DoInfectionTree)
3364  {
3365  sprintf(outname, "%s.tree.xls", OutFile);
3366  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3367  for(i = 0; i < P.PopSize; i++)
3368  if(Hosts[i].infect_type % INFECT_TYPE_MASK > 0)
3369  fprintf(dat, "%i\t%i\t%i\t%i\n", i, Hosts[i].infector, Hosts[i].infect_type % INFECT_TYPE_MASK, (int)HOST_AGE_YEAR(i));
3370  fclose(dat);
3371  }
3372 #if defined(_WIN32) || defined(IMAGE_MAGICK)
3373  static int dm[13] ={0,31,28,31,30,31,30,31,31,30,31,30,31};
3374  int d, m, y, dml, f;
3375 #ifdef _WIN32
3376  //if(P.OutputBitmap == 1) CloseAvi(avi);
3377  //if((TimeSeries[P.NumSamples - 1].extinct) && (P.OutputOnlyNonExtinct))
3378  // {
3379  // sprintf(outname, "%s.ge" DIRECTORY_SEPARATOR "%s.avi", OutFile, OutFile);
3380  // DeleteFile(outname);
3381  // }
3382 #endif
3383  if(P.OutputBitmap >= 1 && P.BitmapFormat == BF_PNG)
3384  {
3385  // Generate Google Earth .kml file
3386  sprintf(outname, "%s.ge" DIRECTORY_SEPARATOR "%s.ge.kml", OutFile, OutFile); //sprintf(outname,"%s.ge" DIRECTORY_SEPARATOR "%s.kml",OutFileBase,OutFile);
3387  if(!(dat = fopen(outname, "wb")))
3388  {
3389  ERR_CRITICAL("Unable to open output kml file\n");
3390  }
3391  fprintf(dat, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://earth.google.com/kml/2.2\">\n<Document>\n");
3392  fprintf(dat, "<name>%s</name>\n", OutFile);
3393  y = 2009;
3394  m = 1;
3395  d = 1;
3396  for(i = 0; i < P.NumSamples; i++)
3397  {
3398  fprintf(dat, "<GroundOverlay>\n<name>Snapshot %i</name>\n", i + 1);
3399  fprintf(dat, "<TimeSpan>\n<begin>%i-%02i-%02iT00:00:00Z</begin>\n", y, m, d);
3400  d += (int)P.SampleStep; // SampleStep has to be an integer here.
3401  do
3402  {
3403  f = 1;
3404  dml = dm[m];
3405  if((m == 2) && (y % 4 == 0)) dml = 29;
3406  if(d > dml)
3407  {
3408  m++;
3409  if(m > 12)
3410  {
3411  m -= 12;
3412  y++;
3413  }
3414  d -= dml;
3415  f = 0;
3416  }
3417  } while(!f);
3418  fprintf(dat, "<end>%i-%02i-%02iT00:00:00Z</end>\n</TimeSpan>\n", y, m, d);
3419  sprintf(outname, "%s.ge" DIRECTORY_SEPARATOR "%s.%i.png", OutFile, OutFile, i + 1);
3420  fprintf(dat, "<Icon>\n<href>%s</href>\n</Icon>\n", outname);
3421  fprintf(dat, "<LatLonBox>\n<north>%.10f</north>\n<south>%.10f</south>\n<east>%.10f</east>\n<west>%.10f</west>\n</LatLonBox>\n",
3422  P.SpatialBoundingBox[3], P.SpatialBoundingBox[1], P.SpatialBoundingBox[2], P.SpatialBoundingBox[0]);
3423  fprintf(dat, "</GroundOverlay>\n");
3424  }
3425  fprintf(dat, "</Document>\n</kml>\n");
3426  fclose(dat);
3427  }
3428 #endif
3429 
3430 
3431  if(P.DoSeverity)
3432  {
3433  sprintf(outname, "%s.severity.xls", OutFile);
3434  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open severity output file\n");
3435  fprintf(dat, "t\tS\tI\tR\tincI\tMild\tILI\tSARI\tCritical\tCritRecov\tincMild\tincILI\tincSARI\tincCritical\tincCritRecov\tincDeath\tincDeath_ILI\tincDeath_SARI\tincDeath_Critical\tcumMild\tcumILI\tcumSARI\tcumCritical\tcumCritRecov\tcumDeath\tcumDeath_ILI\tcumDeath_SARI\tcumDeath_Critical\n");//\t\t%.10f\t%.10f\t%.10f\n",P.R0household,P.R0places,P.R0spatial);
3436  for (i = 0; i < P.NumSamples; i++)
3437  {
3438  fprintf(dat, "%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\n",
3439  TimeSeries[i].t, TimeSeries[i].S, TimeSeries[i].I, TimeSeries[i].R, TimeSeries[i].incI,
3440  TimeSeries[i].Mild , TimeSeries[i].ILI , TimeSeries[i].SARI , TimeSeries[i].Critical , TimeSeries[i].CritRecov ,
3441  TimeSeries[i].incMild , TimeSeries[i].incILI , TimeSeries[i].incSARI , TimeSeries[i].incCritical , TimeSeries[i].incCritRecov,
3442  TimeSeries[i].incD, TimeSeries[i].incDeath_ILI, TimeSeries[i].incDeath_SARI, TimeSeries[i].incDeath_Critical,
3443  TimeSeries[i].cumMild , TimeSeries[i].cumILI , TimeSeries[i].cumSARI , TimeSeries[i].cumCritical , TimeSeries[i].cumCritRecov, TimeSeries[i].D ,
3444  TimeSeries[i].cumDeath_ILI, TimeSeries[i].cumDeath_SARI, TimeSeries[i].cumDeath_Critical);
3445  }
3446  fclose(dat);
3447 
3448  if((P.DoAdUnits) && (P.OutputSeverityAdminUnit))
3449  {
3451  sprintf(outname, "%s.severity.adunit.xls", OutFile);
3452  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3453  fprintf(dat, "t");
3454 
3457  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tMild_%s" , AdUnits[i].ad_name);
3458  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tILI_%s" , AdUnits[i].ad_name);
3459  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tSARI_%s" , AdUnits[i].ad_name);
3460  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tCritical_%s" , AdUnits[i].ad_name);
3461  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tCritRecov_%s" , AdUnits[i].ad_name);
3462 
3464  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincI_%s" , AdUnits[i].ad_name);
3465  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincMild_%s" , AdUnits[i].ad_name);
3466  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincILI_%s" , AdUnits[i].ad_name);
3467  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincSARI_%s" , AdUnits[i].ad_name);
3468  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincCritical_%s" , AdUnits[i].ad_name);
3469  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincCritRecov_%s" , AdUnits[i].ad_name);
3470  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincDeath_adu%s" , AdUnits[i].ad_name);
3471  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincDeath_ILI_adu%s" , AdUnits[i].ad_name);
3472  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincDeath_SARI_adu%s" , AdUnits[i].ad_name);
3473  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincDeath_Critical_adu%s" , AdUnits[i].ad_name);
3474 
3476  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumMild_%s" , AdUnits[i].ad_name);
3477  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumILI_%s" , AdUnits[i].ad_name);
3478  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumSARI_%s" , AdUnits[i].ad_name);
3479  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumCritical_%s" , AdUnits[i].ad_name);
3480  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumCritRecov_%s" , AdUnits[i].ad_name);
3481  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumDeaths_%s" , AdUnits[i].ad_name);
3482  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumDeath_ILI_%s" , AdUnits[i].ad_name);
3483  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumDeath_SARI_%s" , AdUnits[i].ad_name);
3484  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumDeath_Critical_%s" , AdUnits[i].ad_name);
3485 
3486  fprintf(dat, "\n");
3487 
3489  for(i = 0; i < P.NumSamples; i++)
3490  {
3491  fprintf(dat, "%.10f", TimeSeries[i].t);
3492 
3494  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].Mild_adunit[j]);
3495  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].ILI_adunit[j]);
3496  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].SARI_adunit[j]);
3497  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].Critical_adunit[j]);
3498  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].CritRecov_adunit[j]);
3499 
3501  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incI_adunit[j]);
3502  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incMild_adunit[j]);
3503  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incILI_adunit[j]);
3504  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incSARI_adunit[j]);
3505  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incCritical_adunit[j]);
3506  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incCritRecov_adunit[j]);
3507  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incD_adunit[j]);
3508  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incDeath_ILI_adunit[j]);
3509  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incDeath_SARI_adunit[j]);
3510  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].incDeath_Critical_adunit[j]);
3511 
3513  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].cumMild_adunit[j]);
3514  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].cumILI_adunit[j]);
3515  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].cumSARI_adunit[j]);
3516  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].cumCritical_adunit[j]);
3517  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].cumCritRecov_adunit[j]);
3518  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].cumD_adunit[j]);
3519  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].cumDeath_ILI_adunit[j]);
3520  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].cumDeath_SARI_adunit[j]);
3521  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", TimeSeries[i].cumDeath_Critical_adunit[j]);
3522 
3523  if(i != P.NumSamples - 1) fprintf(dat, "\n");
3524  }
3525  fclose(dat);
3526  }
3527  }
3528 }
3529 
3530 void SaveSummaryResults(void)
3531 {
3532  int i, j;
3533  double c, t;
3534  FILE* dat;
3535  char outname[1024];
3536 
3537  c = 1 / ((double)(P.NRactE + P.NRactNE));
3538 
3539  if (P.OutputNonSeverity)
3540  {
3541  sprintf(outname, "%s.xls", OutFile);
3542  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3544  fprintf(dat, "t\tS\tL\tI\tR\tD\tincI\tincR\tincD\tincC\tincDC\tincTC\tincH\tcumT\tcumTmax\tcumTP\tcumV\tcumVmax\tExtinct\trmsRad\tmaxRad\tvS\tvI\tvR\tvD\tvincI\tvincR\tvincFC\tvincC\tvincDC\tvincTC\tvincH\tvrmsRad\tvmaxRad\t\t%i\t%i\t%.10f\t%.10f\t%.10f\t\t%.10f\t%.10f\t%.10f\t%.10f\n",
3545  P.NRactNE, P.NRactE, P.R0household, P.R0places, P.R0spatial, c * PeakHeightSum, c * PeakHeightSS - c * c * PeakHeightSum * PeakHeightSum, c * PeakTimeSum, c * PeakTimeSS - c * c * PeakTimeSum * PeakTimeSum);
3546  c = 1 / ((double)P.NRactual);
3547 
3549  for(i = 0; i < P.NumSamples; i++)
3550  {
3551  fprintf(dat, "%.10f\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t%10lf\t",
3552  c * TSMean[i].t, c * TSMean[i].S, c * TSMean[i].L, c * TSMean[i].I, c * TSMean[i].R,
3553  c * TSMean[i].D, c * TSMean[i].incI, c * TSMean[i].incR, c * TSMean[i].incFC, c * TSMean[i].incC, c * TSMean[i].incDC, c * TSMean[i].incTC, c * TSMean[i].incH,
3554  c * TSMean[i].cumT, TSMean[i].cumTmax, c * TSMean[i].cumTP, c * TSMean[i].cumV, TSMean[i].cumVmax, c * TSMean[i].extinct, c * TSMean[i].rmsRad, c * TSMean[i].maxRad);
3555  fprintf(dat, "%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\n",
3556  c * TSVar[i].S - c * c * TSMean[i].S * TSMean[i].S,
3557  c * TSVar[i].I - c * c * TSMean[i].I * TSMean[i].I,
3558  c * TSVar[i].R - c * c * TSMean[i].R * TSMean[i].R,
3559  c * TSVar[i].D - c * c * TSMean[i].D * TSMean[i].D,
3560  c * TSVar[i].incI - c * c * TSMean[i].incI * TSMean[i].incI,
3561  c * TSVar[i].incR - c * c * TSMean[i].incR * TSMean[i].incR,
3562  c * TSVar[i].incD - c * c * TSMean[i].incD * TSMean[i].incD,
3563  c * TSVar[i].incC - c * c * TSMean[i].incC * TSMean[i].incC,
3564  c * TSVar[i].incDC - c * c * TSMean[i].incDC * TSMean[i].incDC, //added detected cases
3565  c * TSVar[i].incTC - c * c * TSMean[i].incTC * TSMean[i].incTC,
3566  c * TSVar[i].incH - c * c * TSMean[i].incH * TSMean[i].incH, //added hospitalisation
3567  c * TSVar[i].rmsRad - c * c * TSMean[i].rmsRad * TSMean[i].rmsRad,
3568  c * TSVar[i].maxRad - c * c * TSMean[i].maxRad * TSMean[i].maxRad);
3569  }
3570  fclose(dat);
3571  }
3572 
3573  if (P.OutputControls)
3574  {
3575  sprintf(outname, "%s.controls.xls", OutFile);
3576  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3577  fprintf(dat, "t\tS\tincC\tincTC\tincFC\tincH\tcumT\tcumUT\tcumTP\tcumV\tincHQ\tincAC\tincAH\tincAA\tincACS\tincAPC\tincAPA\tincAPCS\tpropSocDist");
3578  for(j = 0; j < NUM_PLACE_TYPES; j++) fprintf(dat, "\tprClosed_%i", j);
3579  fprintf(dat, "t\tvS\tvincC\tvincTC\tvincFC\tvincH\tvcumT\tvcumUT\tvcumTP\tvcumV");
3580  for(j = 0; j < NUM_PLACE_TYPES; j++) fprintf(dat, "\tvprClosed_%i", j);
3581  fprintf(dat, "\n");
3582  for(i = 0; i < P.NumSamples; i++)
3583  {
3584  fprintf(dat, "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
3585  c * TSMean[i].t, c * TSMean[i].S, c * TSMean[i].incC, c * TSMean[i].incTC, c * TSMean[i].incFC, c * TSMean[i].incH,
3586  c * TSMean[i].cumT, c * TSMean[i].cumUT, c * TSMean[i].cumTP, c * TSMean[i].cumV, c * TSMean[i].incHQ,
3587  c * TSMean[i].incAC, c * TSMean[i].incAH, c * TSMean[i].incAA, c * TSMean[i].incACS,
3588  c * TSMean[i].incAPC, c * TSMean[i].incAPA, c * TSMean[i].incAPCS,c*TSMean[i].PropSocDist);
3589  for(j = 0; j < NUM_PLACE_TYPES; j++) fprintf(dat, "\t%lf", c * TSMean[i].PropPlacesClosed[j]);
3590  fprintf(dat, "\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
3591  c * TSVar[i].S - c * c * TSMean[i].S * TSMean[i].S,
3592  c * TSVar[i].incC - c * c * TSMean[i].incC * TSMean[i].incC,
3593  c * TSVar[i].incTC - c * c * TSMean[i].incTC * TSMean[i].incTC,
3594  c * TSVar[i].incFC - c * c * TSMean[i].incFC * TSMean[i].incFC,
3595  c * TSVar[i].incH - c * c * TSMean[i].incH * TSMean[i].incH,
3596  c * TSVar[i].cumT - c * c * TSMean[i].cumT * TSMean[i].cumT,
3597  c * TSVar[i].cumUT - c * c * TSMean[i].cumUT * TSMean[i].cumUT,
3598  c * TSVar[i].cumTP - c * c * TSMean[i].cumTP * TSMean[i].cumTP,
3599  c * TSVar[i].cumV - c * c * TSMean[i].cumV * TSMean[i].cumV);
3600  for(j = 0; j < NUM_PLACE_TYPES; j++) fprintf(dat, "\t%lf", TSVar[i].PropPlacesClosed[j]);
3601  fprintf(dat, "\n");
3602  }
3603  fclose(dat);
3604 
3605  }
3606 
3607  if (P.OutputAge)
3608  {
3609  sprintf(outname, "%s.age.xls", OutFile);
3610  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3611  fprintf(dat, "t");
3612  for(i = 0; i < NUM_AGE_GROUPS; i++)
3613  fprintf(dat, "\tI%i-%i", AGE_GROUP_WIDTH * i, AGE_GROUP_WIDTH * (i + 1));
3614  for(i = 0; i < NUM_AGE_GROUPS; i++)
3615  fprintf(dat, "\tC%i-%i", AGE_GROUP_WIDTH * i, AGE_GROUP_WIDTH * (i + 1));
3616  for(i = 0; i < NUM_AGE_GROUPS; i++)
3617  fprintf(dat, "\tD%i-%i", AGE_GROUP_WIDTH * i, AGE_GROUP_WIDTH * (i + 1));
3618  fprintf(dat, "\n");
3619  for(i = 0; i < P.NumSamples; i++)
3620  {
3621  fprintf(dat, "%.10f", c * TSMean[i].t);
3622  for(j = 0; j < NUM_AGE_GROUPS; j++)
3623  fprintf(dat, "\t%.10f", c * TSMean[i].incIa[j]);
3624  for(j = 0; j < NUM_AGE_GROUPS; j++)
3625  fprintf(dat, "\t%.10f", c * TSMean[i].incCa[j]);
3626  for(j = 0; j < NUM_AGE_GROUPS; j++)
3627  fprintf(dat, "\t%.10f", c * TSMean[i].incDa[j]);
3628  fprintf(dat, "\n");
3629  }
3630  fprintf(dat, "dist");
3631  for(j = 0; j < NUM_AGE_GROUPS; j++)
3632  fprintf(dat, "\t%.10f", AgeDist[j]);
3633  fprintf(dat, "\n");
3634  fclose(dat);
3635  }
3636 
3637  if((P.DoAdUnits) && (P.DoAdunitOutput))
3638  {
3639  sprintf(outname, "%s.adunit.xls", OutFile);
3640  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3641  fprintf(dat, "t");
3642  for(i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tI_%s", AdUnits[i].ad_name);
3643  for(i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tC_%s", AdUnits[i].ad_name);
3644  for(i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tDC_%s", AdUnits[i].ad_name); //added detected cases: ggilani 03/02/15
3645  for(i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tT_%s", AdUnits[i].ad_name);
3646  for(i = 0; i < P.NumAdunits; i++) fprintf(dat, "\t%.10f", P.PopByAdunit[i][0]);
3647  for(i = 0; i < P.NumAdunits; i++) fprintf(dat, "\t%.10f", P.PopByAdunit[i][1]);
3648  fprintf(dat, "\n");
3649  for(i = 0; i < P.NumSamples; i++)
3650  {
3651  fprintf(dat, "%.10f", c * TSMean[i].t);
3652  for(j = 0; j < P.NumAdunits; j++)
3653  fprintf(dat, "\t%.10f", c * TSMean[i].incI_adunit[j]);
3654  for(j = 0; j < P.NumAdunits; j++)
3655  fprintf(dat, "\t%.10f", c * TSMean[i].incC_adunit[j]);
3656  for(j = 0; j < P.NumAdunits; j++)
3657  fprintf(dat, "\t%.10f", c * TSMean[i].incDC_adunit[j]); //added detected cases: ggilani 03/02/15
3658  for(j = 0; j < P.NumAdunits; j++)
3659  fprintf(dat, "\t%.10f", c * TSMean[i].cumT_adunit[j]);
3660  fprintf(dat, "\n");
3661  }
3662  fclose(dat);
3663 
3664  if (P.OutputAdUnitVar)
3665  {
3666  sprintf(outname, "%s.adunitVar.xls", OutFile);
3667  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3668  fprintf(dat, "t");
3669  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tI_%s", AdUnits[i].ad_name);
3670  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tC_%s", AdUnits[i].ad_name);
3671  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tDC_%s", AdUnits[i].ad_name); //added detected cases: ggilani 03/02/15
3672  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tT_%s", AdUnits[i].ad_name);
3673  fprintf(dat, "\n");
3674  for (i = 0; i < P.NumSamples; i++)
3675  {
3676  fprintf(dat, "%.10f", c * TSMean[i].t);
3677  for (j = 0; j < P.NumAdunits; j++)
3678  fprintf(dat, "\t%.10f", c * TSVar[i].incI_adunit[j] - c * c * TSMean[i].incI_adunit[j] * TSMean[i].incI_adunit[j]);
3679  for (j = 0; j < P.NumAdunits; j++)
3680  fprintf(dat, "\t%.10f", c * TSVar[i].incC_adunit[j] - c * c * TSMean[i].incC_adunit[j] * TSMean[i].incC_adunit[j]);
3681  for (j = 0; j < P.NumAdunits; j++)
3682  fprintf(dat, "\t%.10f", c * TSVar[i].incDC_adunit[j] - c * c * TSMean[i].incDC_adunit[j] * TSMean[i].incDC_adunit[j]); //added detected cases: ggilani 03/02/15
3683  for (j = 0; j < P.NumAdunits; j++)
3684  fprintf(dat, "\t%.10f", c * TSVar[i].cumT_adunit[j] - c * c * TSMean[i].cumT_adunit[j] * TSMean[i].cumT_adunit[j]);
3685  fprintf(dat, "\n");
3686  }
3687  fclose(dat);
3688  }
3689  }
3690 
3691  if ((P.DoDigitalContactTracing) && (P.DoAdUnits) && (P.OutputDigitalContactTracing))
3692  {
3693  sprintf(outname, "%s.digitalcontacttracing.xls", OutFile);
3694  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3695  fprintf(dat, "t");
3696  for (i = 0; i < P.NumAdunits; i++)
3697  {
3698  fprintf(dat, "\tincDCT_%s", AdUnits[i].ad_name); // //printing headers for inc per admin unit
3699  }
3700  for (i = 0; i < P.NumAdunits; i++)
3701  {
3702  fprintf(dat, "\tDCT_%s", AdUnits[i].ad_name); // //printing headers for prevalence of digital contact tracing per admin unit
3703  }
3704  fprintf(dat, "\n");
3705  //print actual output
3706  for (i = 0; i < P.NumSamples; i++)
3707  {
3708  fprintf(dat, "%.10lf", c* TSMean[i].t);
3709  for (j = 0; j < P.NumAdunits; j++)
3710  {
3711  fprintf(dat, "\t%.10lf", c * TSMean[i].incDCT_adunit[j]);
3712  }
3713  for (j = 0; j < P.NumAdunits; j++)
3714  {
3715  fprintf(dat, "\t%.10lf", c * TSMean[i].DCT_adunit[j]);
3716  }
3717  fprintf(dat, "\n");
3718  }
3719 
3720  fclose(dat);
3721 
3722  }
3723 
3724  if(P.KeyWorkerProphTimeStartBase < P.SampleTime)
3725  {
3726  sprintf(outname, "%s.keyworker.xls", OutFile);
3727  if(!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3728  fprintf(dat, "t");
3729  for(i = 0; i < 2; i++) fprintf(dat, "\tI%i", i);
3730  for(i = 0; i < 2; i++) fprintf(dat, "\tC%i", i);
3731  for(i = 0; i < 2; i++) fprintf(dat, "\tT%i", i);
3732  for(i = 0; i < 2; i++) fprintf(dat, "\tvI%i", i);
3733  for(i = 0; i < 2; i++) fprintf(dat, "\tvC%i", i);
3734  for(i = 0; i < 2; i++) fprintf(dat, "\tvT%i", i);
3735  fprintf(dat, "\t%i\t%i\n", P.KeyWorkerNum, P.KeyWorkerIncHouseNum);
3736  for(i = 0; i < P.NumSamples; i++)
3737  {
3738  fprintf(dat, "%.10f", c * TSMean[i].t);
3739  for(j = 0; j < 2; j++)
3740  fprintf(dat, "\t%.10f", c * TSMean[i].incI_keyworker[j]);
3741  for(j = 0; j < 2; j++)
3742  fprintf(dat, "\t%.10f", c * TSMean[i].incC_keyworker[j]);
3743  for(j = 0; j < 2; j++)
3744  fprintf(dat, "\t%.10f", c * TSMean[i].cumT_keyworker[j]);
3745  for(j = 0; j < 2; j++)
3746  fprintf(dat, "\t%.10f", c * TSVar[i].incI_keyworker[j] - c * c * TSMean[i].incI_keyworker[j] * TSMean[i].incI_keyworker[j]);
3747  for(j = 0; j < 2; j++)
3748  fprintf(dat, "\t%.10f", c * TSVar[i].incC_keyworker[j] - c * c * TSMean[i].incC_keyworker[j] * TSMean[i].incC_keyworker[j]);
3749  for(j = 0; j < 2; j++)
3750  fprintf(dat, "\t%.10f", c * TSVar[i].cumT_keyworker[j] - c * c * TSMean[i].cumT_keyworker[j] * TSMean[i].cumT_keyworker[j]);
3751  fprintf(dat, "\n");
3752  }
3753  fclose(dat);
3754  }
3755 
3756  if (P.OutputInfType)
3757  {
3758  sprintf(outname, "%s.inftype.xls", OutFile);
3759  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3760  fprintf(dat, "t\tR");
3761  for (j = 0; j < INFECT_TYPE_MASK; j++) fprintf(dat, "\tRtype_%i", j);
3762  for (j = 0; j < INFECT_TYPE_MASK; j++) fprintf(dat, "\tincItype_%i", j);
3763  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\tRage_%i", j);
3764  fprintf(dat, "\n");
3765  for (i = 0; i < P.NumSamples; i++)
3766  {
3767  fprintf(dat, "%lf\t%lf", c * TSMean[i].t, c * TSMean[i].Rdenom);
3768  for (j = 0; j < INFECT_TYPE_MASK; j++) fprintf(dat, "\t%lf", c * TSMean[i].Rtype[j]);
3769  for (j = 0; j < INFECT_TYPE_MASK; j++) fprintf(dat, "\t%lf", c * TSMean[i].incItype[j]);
3770  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%lf", c * TSMean[i].Rage[j]);
3771  fprintf(dat, "\n");
3772  }
3773  fclose(dat);
3774  }
3775 
3776  if (P.OutputR0)
3777  {
3778  sprintf(outname, "%s.R0.xls", OutFile);
3779  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3780  for (i = 0; i < MAX_SEC_REC; i++)
3781  {
3782  fprintf(dat, "%i", i);
3783  for (j = 0; j < MAX_GEN_REC; j++)
3784  fprintf(dat, "\t%.10f", c * indivR0_av[i][j]);
3785  fprintf(dat, "\n");
3786  }
3787  fclose(dat);
3788  }
3789 
3790  if (P.OutputHousehold)
3791  {
3792  sprintf(outname, "%s.household.xls", OutFile);
3793  for (i = 1; i <= MAX_HOUSEHOLD_SIZE; i++)
3794  {
3795  t = 0;
3796  for (j = 1; j <= MAX_HOUSEHOLD_SIZE; j++)
3797  t += inf_household_av[i][j];
3798  inf_household_av[i][0] = denom_household[i] / c - t;
3799  }
3800  for (i = 1; i <= MAX_HOUSEHOLD_SIZE; i++)
3801  {
3802  t = 0;
3803  for (j = 1; j <= MAX_HOUSEHOLD_SIZE; j++)
3804  t += case_household_av[i][j];
3805  case_household_av[i][0] = denom_household[i] / c - t;
3806  }
3807  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3808  for (i = 1; i <= MAX_HOUSEHOLD_SIZE; i++)
3809  fprintf(dat, "\t%i", i);
3810  fprintf(dat, "\n");
3811  for (i = 0; i <= MAX_HOUSEHOLD_SIZE; i++)
3812  {
3813  fprintf(dat, "%i", i);
3814  for (j = 1; j <= MAX_HOUSEHOLD_SIZE; j++)
3815  fprintf(dat, "\t%.10f", inf_household_av[j][i] * c);
3816  fprintf(dat, "\n");
3817  }
3818  fprintf(dat, "\n");
3819  for (i = 1; i <= MAX_HOUSEHOLD_SIZE; i++)
3820  fprintf(dat, "\t%i", i);
3821  fprintf(dat, "\n");
3822  for (i = 0; i <= MAX_HOUSEHOLD_SIZE; i++)
3823  {
3824  fprintf(dat, "%i", i);
3825  for (j = 1; j <= MAX_HOUSEHOLD_SIZE; j++)
3826  fprintf(dat, "\t%.10f", case_household_av[j][i] * c);
3827  fprintf(dat, "\n");
3828  }
3829  fclose(dat);
3830  }
3831 
3832  if (P.OutputCountry)
3833  {
3834  sprintf(outname, "%s.country.xls", OutFile);
3835  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3836  for (i = 0; i < MAX_COUNTRIES; i++)
3837  fprintf(dat, "%i\t%.10f\t%.10f\n", i, infcountry_av[i] * c, infcountry_num[i] * c);
3838  fclose(dat);
3839  }
3840 
3841  if (P.DoSeverity)
3842  {
3844  sprintf(outname, "%s.severity.xls", OutFile);
3845 
3846  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open severity output file\n");
3847  fprintf(dat, "t\tPropSocDist\tS\tI\tR\tincI\tincC\tMild\tILI\tSARI\tCritical\tCritRecov\tSARIP\tCriticalP\tCritRecovP\tincMild\tincILI\tincSARI\tincCritical\tincCritRecov\tincSARIP\tincCriticalP\tincCritRecovP\tincDeath\tincDeath_ILI\tincDeath_SARI\tincDeath_Critical\tcumMild\tcumILI\tcumSARI\tcumCritical\tcumCritRecov\tcumDeath\tcumDeath_ILI\tcumDeath_SARI\tcumDeath_Critical\t");
3848  fprintf(dat, "PropSocDist_v\tS_v\tI_v\tR_v\tincI_v\tincC_v\tMild_v\tILI_v\tSARI_v\tCritical_v\tCritRecov_v\tincMild_v\tincILI_v\tincSARI_v\tincCritical_v\tincCritRecov_v\tincDeath_v\tincDeath_ILI_v\tincDeath_SARI_v\tincDeath_Critical_v\tcumMild_v\tcumILI_v\tcumSARI_v\tcumCritical_v\tcumCritRecov_v\tcumDeath_v\tcumDeath_ILI_v\tcumDeath_SARI_v\tcumDeath_Critical_v\n");
3849  double SARI, Critical, CritRecov, incSARI, incCritical, incCritRecov, sc1, sc2,sc3,sc4; //this stuff corrects bed prevalence for exponentially distributed time to test results in hospital
3850  sc1 = (P.Mean_TimeToTest > 0) ? exp(-1.0 / P.Mean_TimeToTest) : 0.0;
3851  sc2 = (P.Mean_TimeToTest > 0) ? exp(-P.Mean_TimeToTestOffset / P.Mean_TimeToTest) : 0.0;
3852  sc3 = (P.Mean_TimeToTest > 0) ? exp(-P.Mean_TimeToTestCriticalOffset / P.Mean_TimeToTest) : 0.0;
3853  sc4 = (P.Mean_TimeToTest > 0) ? exp(-P.Mean_TimeToTestCritRecovOffset / P.Mean_TimeToTest) : 0.0;
3854  incSARI = incCritical = incCritRecov = 0;
3855  for (i = 0; i < P.NumSamples; i++)
3856  {
3857  if (i > 0)
3858  {
3859  SARI = (TSMean[i].SARI - TSMean[i - 1].SARI) * sc2 + SARI * sc1;
3860  Critical = (TSMean[i].Critical - TSMean[i - 1].Critical) * sc3 + Critical * sc1;
3861  CritRecov = (TSMean[i].CritRecov - TSMean[i - 1].CritRecov) * sc4 + CritRecov * sc1;
3862  incSARI = TSMean[i].incSARI * (1.0 - sc2) + incSARI * sc1;
3863  incCritical = TSMean[i].incCritical * (1.0 - sc3) + incCritical * sc1;
3864  incCritRecov = TSMean[i].incCritRecov * (1.0 - sc4) + incCritRecov * sc1;
3865  }
3866  else
3867  {
3868  SARI = TSMean[i].SARI * sc2;
3869  Critical = TSMean[i].Critical * sc3;
3870  CritRecov = TSMean[i].CritRecov * sc4;
3871  }
3872 
3873  fprintf(dat, "%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t",
3874  c* TSMean[i].t, c* TSMean[i].PropSocDist, c* TSMean[i].S, c* TSMean[i].I, c* TSMean[i].R, c* TSMean[i].incI, c* TSMean[i].incC,
3875  c* TSMean[i].Mild, c* TSMean[i].ILI, c* TSMean[i].SARI,c* TSMean[i].Critical, c* TSMean[i].CritRecov,c* (TSMean[i].SARI - SARI), c* (TSMean[i].Critical - Critical), c* (TSMean[i].CritRecov - CritRecov),
3876  c * TSMean[i].incMild, c * TSMean[i].incILI, c * TSMean[i].incSARI, c * TSMean[i].incCritical, c * TSMean[i].incCritRecov, c * incSARI, c * incCritical, c * incCritRecov, c * TSMean[i].incD,
3877  c * TSMean[i].incDeath_ILI, c * TSMean[i].incDeath_SARI, c * TSMean[i].incDeath_Critical,
3878  c * TSMean[i].cumMild, c * TSMean[i].cumILI, c * TSMean[i].cumSARI, c * TSMean[i].cumCritical, c * TSMean[i].cumCritRecov, c*TSMean[i].D,
3879  c * TSMean[i].cumDeath_ILI, c * TSMean[i].cumDeath_SARI, c * TSMean[i].cumDeath_Critical);
3880  fprintf(dat, "%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\t%.10f\n",
3881  c* TSVar[i].PropSocDist- c * TSMean[i].PropSocDist* c * TSMean[i].PropSocDist,
3882  c* TSVar[i].S- c * TSMean[i].S* c * TSMean[i].S,
3883  c* TSVar[i].I- c * TSMean[i].I* c * TSMean[i].I,
3884  c* TSVar[i].R- c * TSMean[i].R* c * TSMean[i].R,
3885  c* TSVar[i].incI- c * TSMean[i].incI* c * TSMean[i].incI,
3886  c* TSVar[i].incC- c * TSMean[i].incC* c * TSMean[i].incC,
3887  c* TSVar[i].Mild- c * TSMean[i].Mild* c * TSMean[i].Mild,
3888  c* TSVar[i].ILI- c * TSMean[i].incILI* c * TSMean[i].incILI,
3889  c* TSVar[i].SARI- c * TSMean[i].SARI* c * TSMean[i].SARI,
3890  c* TSVar[i].Critical- c * TSMean[i].Critical* c * TSMean[i].Critical,
3891  c* TSVar[i].CritRecov- c * TSMean[i].CritRecov* c * TSMean[i].CritRecov,
3892  c* TSVar[i].incMild- c * TSMean[i].incMild* c * TSMean[i].incMild,
3893  c* TSVar[i].incILI- c * TSMean[i].incILI* c * TSMean[i].incILI,
3894  c* TSVar[i].incSARI- c * TSMean[i].incSARI* c * TSMean[i].incSARI,
3895  c* TSVar[i].incCritical- c * TSMean[i].incCritical* c * TSMean[i].incCritical,
3896  c* TSVar[i].incCritRecov- c * TSMean[i].incCritRecov* c * TSMean[i].incCritRecov,
3897  c* TSVar[i].incD- c * TSMean[i].incD* c * TSMean[i].incD,
3898  c* TSVar[i].incDeath_ILI- c * TSMean[i].incDeath_ILI* c * TSMean[i].incDeath_ILI,
3899  c* TSVar[i].incDeath_SARI- c * TSMean[i].incDeath_SARI* c * TSMean[i].incDeath_SARI,
3900  c* TSVar[i].incDeath_Critical- c * TSMean[i].incDeath_Critical* c * TSMean[i].incDeath_Critical,
3901  c* TSVar[i].cumMild- c * TSMean[i].cumMild* c * TSMean[i].cumMild,
3902  c* TSVar[i].cumILI- c * TSMean[i].cumILI* c * TSMean[i].cumILI,
3903  c* TSVar[i].cumSARI- c * TSMean[i].cumSARI* c * TSMean[i].cumSARI,
3904  c* TSVar[i].cumCritical- c * TSMean[i].cumCritical* c * TSMean[i].cumCritical,
3905  c* TSVar[i].cumCritRecov- c * TSMean[i].cumCritRecov* c * TSMean[i].cumCritRecov,
3906  c* TSVar[i].D- c * TSMean[i].D* c * TSMean[i].D,
3907  c* TSVar[i].cumDeath_ILI- c * TSMean[i].cumDeath_ILI* c * TSMean[i].cumDeath_ILI,
3908  c* TSVar[i].cumDeath_SARI- c * TSMean[i].cumDeath_SARI* c * TSMean[i].cumDeath_SARI,
3909  c* TSVar[i].cumDeath_Critical- c * TSMean[i].cumDeath_Critical* c * TSMean[i].cumDeath_Critical);
3910  }
3911  fclose(dat);
3912  if (P.OutputSeverityAge)
3913  {
3914  double* SARI_a, * Critical_a, * CritRecov_a, * incSARI_a, * incCritical_a, * incCritRecov_a, sc1a, sc2a, sc3a, sc4a; //this stuff corrects bed prevalence for exponentially distributed time to test results in hospital
3915 
3916  if (!(SARI_a = (double*)malloc(NUM_AGE_GROUPS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
3917  if (!(Critical_a = (double*)malloc(NUM_AGE_GROUPS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
3918  if (!(CritRecov_a = (double*)malloc(NUM_AGE_GROUPS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
3919  if (!(incSARI_a = (double*)malloc(NUM_AGE_GROUPS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
3920  if (!(incCritical_a = (double*)malloc(NUM_AGE_GROUPS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
3921  if (!(incCritRecov_a = (double*)malloc(NUM_AGE_GROUPS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
3922  sc1a = (P.Mean_TimeToTest > 0) ? exp(-1.0 / P.Mean_TimeToTest) : 0.0;
3923  sc2a = (P.Mean_TimeToTest > 0) ? exp(-P.Mean_TimeToTestOffset / P.Mean_TimeToTest) : 0.0;
3924  sc3a = (P.Mean_TimeToTest > 0) ? exp(-P.Mean_TimeToTestCriticalOffset / P.Mean_TimeToTest) : 0.0;
3925  sc4a = (P.Mean_TimeToTest > 0) ? exp(-P.Mean_TimeToTestCritRecovOffset / P.Mean_TimeToTest) : 0.0;
3926  for (i = 0; i < NUM_AGE_GROUPS; i++) incSARI_a[i] = incCritical_a[i] = incCritRecov_a[i] = 0;
3928  sprintf(outname, "%s.severity.age.xls", OutFile);
3929  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
3930  fprintf(dat, "t");
3931 
3934  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tMild_%i", i);
3935  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tILI_%i", i);
3936  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tSARI_%i", i);
3937  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tCritical_%i", i);
3938  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tCritRecov_%i", i);
3939  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tSARIP_%i", i);
3940  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tCriticalP_%i", i);
3941  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tCritRecovP_%i", i);
3942 
3944  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincI_%i", i);
3945  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincMild_%i", i);
3946  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincILI_%i", i);
3947  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincSARI_%i", i);
3948  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincCritical_%i", i);
3949  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincCritRecov_%i", i);
3950  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincSARIP_%i", i);
3951  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincCriticalP_%i", i);
3952  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincCritRecovP_%i", i);
3953  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincDeath_%i", i);
3954  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincDeath_ILI_%i", i);
3955  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincDeath_SARI_%i", i);
3956  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tincDeath__Critical_%i", i);
3957 
3959  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tcumMild_%i", i);
3960  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tcumILI_%i", i);
3961  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tcumSARI_%i", i);
3962  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tcumCritical_%i", i);
3963  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tcumCritRecov_%i", i);
3964  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tcumDeaths_%i", i);
3965  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tcumDeaths_ILI_%i", i);
3966  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tcumDeaths_SARI_%i", i);
3967  for (i = 0; i < NUM_AGE_GROUPS; i++) fprintf(dat, "\tcumDeaths_Critical_%i", i);
3968 
3969  fprintf(dat, "\n");
3970 
3972  for (i = 0; i < P.NumSamples; i++)
3973  {
3974  for (j = 0; j < NUM_AGE_GROUPS; j++)
3975  {
3976  if (i > 0)
3977  {
3978  SARI_a[j] = (TSMean[i].SARI_age[j] - TSMean[i - 1].SARI_age[j]) * sc2a + SARI_a[j] * sc1a;
3979  Critical_a[j] = (TSMean[i].Critical_age[j] - TSMean[i - 1].Critical_age[j]) * sc3a + Critical_a[j] * sc1a;
3980  CritRecov_a[j] = (TSMean[i].CritRecov_age[j] - TSMean[i - 1].CritRecov_age[j]) * sc4a + CritRecov_a[j] * sc1a;
3981  incSARI_a[j] = TSMean[i].incSARI_age[j] * (1.0 - sc2a) + incSARI_a[j] * sc1a;
3982  incCritical_a[j] = TSMean[i].incCritical_age[j] * (1.0 - sc3a) + incCritical_a[j] * sc1a;
3983  incCritRecov_a[j] = TSMean[i].incCritRecov_age[j] * (1.0 - sc4a) + incCritRecov_a[j] * sc1a;
3984  }
3985  else
3986  {
3987  SARI_a[j] = TSMean[i].SARI_age[j] * sc2a;
3988  Critical_a[j] = TSMean[i].Critical_age[j] * sc3a;
3989  CritRecov_a[j] = TSMean[i].CritRecov_age[j] * sc4a;
3990  }
3991  }
3992  fprintf(dat, "%.10f", c * TSMean[i].t);
3994  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].Mild_age[j]);
3995  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].ILI_age[j]);
3996  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].SARI_age[j]);
3997  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].Critical_age[j]);
3998  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].CritRecov_age[j]);
3999  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * (TSMean[i].SARI_age[j] - SARI_a[j]));
4000  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * (TSMean[i].Critical_age[j] - Critical_a[j]));
4001  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * (TSMean[i].CritRecov_age[j] - CritRecov_a[j]));
4002 
4004  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incIa[j]);
4005  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incMild_age[j]);
4006  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incILI_age[j]);
4007  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incSARI_age[j]);
4008  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incCritical_age[j]);
4009  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incCritRecov_age[j]);
4010  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * incSARI_a[j]);
4011  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * incCritical_a[j]);
4012  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * incCritRecov_a[j]);
4013  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incDa[j]);
4014  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incDeath_ILI_age[j]);
4015  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incDeath_SARI_age[j]);
4016  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incDeath_Critical_age[j]);
4017 
4019  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumMild_age[j]);
4020  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumILI_age[j]);
4021  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumSARI_age[j]);
4022  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumCritical_age[j]);
4023  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumCritRecov_age[j]);
4024  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * (TSMean[i].cumDeath_ILI_age[j] + TSMean[i].cumDeath_SARI_age[j] + TSMean[i].cumDeath_Critical_age[j]));
4025  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumDeath_ILI_age[j]);
4026  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumDeath_SARI_age[j]);
4027  for (j = 0; j < NUM_AGE_GROUPS; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumDeath_Critical_age[j]);
4028  fprintf(dat, "\n");
4029  }
4030  fclose(dat);
4031  free(SARI_a); free(Critical_a); free(CritRecov_a);
4032  free(incSARI_a); free(incCritical_a); free(incCritRecov_a);
4033  }
4034  if ((P.DoAdUnits) && (P.OutputSeverityAdminUnit))
4035  {
4036  double* SARI_a, * Critical_a, * CritRecov_a, * incSARI_a, * incCritical_a, * incCritRecov_a, sc1a, sc2a,sc3a,sc4a; //this stuff corrects bed prevalence for exponentially distributed time to test results in hospital
4037 
4038  if (!(SARI_a = (double*)malloc(MAX_ADUNITS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
4039  if (!(Critical_a = (double*)malloc(MAX_ADUNITS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
4040  if (!(CritRecov_a = (double*)malloc(MAX_ADUNITS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
4041  if (!(incSARI_a = (double*)malloc(MAX_ADUNITS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
4042  if (!(incCritical_a = (double*)malloc(MAX_ADUNITS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
4043  if (!(incCritRecov_a = (double*)malloc(MAX_ADUNITS * sizeof(double)))) ERR_CRITICAL("Unable to allocate temp storage\n");
4044  sc1a = (P.Mean_TimeToTest > 0) ? exp(-1.0 / P.Mean_TimeToTest) : 0.0;
4045  sc2a = (P.Mean_TimeToTest > 0) ? exp(-P.Mean_TimeToTestOffset / P.Mean_TimeToTest) : 0.0;
4046  sc3a = (P.Mean_TimeToTest > 0) ? exp(-P.Mean_TimeToTestCriticalOffset / P.Mean_TimeToTest) : 0.0;
4047  sc4a = (P.Mean_TimeToTest > 0) ? exp(-P.Mean_TimeToTestCritRecovOffset / P.Mean_TimeToTest) : 0.0;
4048  for (i = 0; i < P.NumAdunits; i++) incSARI_a[i] = incCritical_a[i] = incCritRecov_a[i] = 0;
4050  sprintf(outname, "%s.severity.adunit.xls", OutFile);
4051  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
4052  fprintf(dat, "t");
4053 
4056  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tMild_%s" , AdUnits[i].ad_name);
4057  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tILI_%s" , AdUnits[i].ad_name);
4058  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tSARI_%s" , AdUnits[i].ad_name);
4059  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tCritical_%s" , AdUnits[i].ad_name);
4060  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tCritRecov_%s" , AdUnits[i].ad_name);
4061  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tSARIP_%s" , AdUnits[i].ad_name);
4062  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tCriticalP_%s" , AdUnits[i].ad_name);
4063  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tCritRecovP_%s" , AdUnits[i].ad_name);
4064 
4066  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincI_%s" , AdUnits[i].ad_name);
4067  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincMild_%s" , AdUnits[i].ad_name);
4068  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincILI_%s" , AdUnits[i].ad_name);
4069  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincSARI_%s" , AdUnits[i].ad_name);
4070  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincCritical_%s" , AdUnits[i].ad_name);
4071  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincCritRecov_%s" , AdUnits[i].ad_name);
4072  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincSARIP_%s" , AdUnits[i].ad_name);
4073  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincCriticalP_%s" , AdUnits[i].ad_name);
4074  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincCritRecovP_%s" , AdUnits[i].ad_name);
4075  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincDeath_%s" , AdUnits[i].ad_name);
4076  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincDeath_ILI_%s" , AdUnits[i].ad_name);
4077  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincDeath_SARI_%s" , AdUnits[i].ad_name);
4078  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tincDeath__Critical_%s" , AdUnits[i].ad_name);
4079 
4081  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumMild_%s" , AdUnits[i].ad_name);
4082  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumILI_%s" , AdUnits[i].ad_name);
4083  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumSARI_%s" , AdUnits[i].ad_name);
4084  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumCritical_%s" , AdUnits[i].ad_name);
4085  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumCritRecov_%s" , AdUnits[i].ad_name);
4086  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumDeaths_%s" , AdUnits[i].ad_name);
4087  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumDeaths_ILI_%s" , AdUnits[i].ad_name);
4088  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumDeaths_SARI_%s" , AdUnits[i].ad_name);
4089  for (i = 0; i < P.NumAdunits; i++) fprintf(dat, "\tcumDeaths_Critical_%s" , AdUnits[i].ad_name);
4090 
4091  fprintf(dat, "\n");
4092 
4094  for (i = 0; i < P.NumSamples; i++)
4095  {
4096  for (j = 0; j < P.NumAdunits; j++)
4097  {
4098  if (i > 0)
4099  {
4100  SARI_a[j] = (TSMean[i].SARI_adunit[j] - TSMean[i - 1].SARI_adunit[j]) * sc2a + SARI_a[j] * sc1a;
4101  Critical_a[j] = (TSMean[i].Critical_adunit[j] - TSMean[i - 1].Critical_adunit[j]) * sc3a + Critical_a[j] * sc1a;
4102  CritRecov_a[j] = (TSMean[i].CritRecov_adunit[j] - TSMean[i - 1].CritRecov_adunit[j]) * sc4a + CritRecov_a[j] * sc1a;
4103  incSARI_a[j] = TSMean[i].incSARI_adunit[j] * (1.0 - sc2a) + incSARI_a[j] * sc1a;
4104  incCritical_a[j] = TSMean[i].incCritical_adunit[j] * (1.0 - sc3a) + incCritical_a[j] * sc1a;
4105  incCritRecov_a[j] = TSMean[i].incCritRecov_adunit[j] * (1.0 - sc4a) + incCritRecov_a[j] * sc1a;
4106  }
4107  else
4108  {
4109  SARI_a[j] = TSMean[i].SARI_adunit[j] * sc2a;
4110  Critical_a[j] = TSMean[i].Critical_adunit[j] * sc3a;
4111  CritRecov_a[j] = TSMean[i].CritRecov_adunit[j] * sc4a;
4112  }
4113  }
4114  fprintf(dat, "%.10f", c*TSMean[i].t);
4116  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].Mild_adunit[j]);
4117  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].ILI_adunit[j]);
4118  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].SARI_adunit[j]);
4119  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].Critical_adunit[j]);
4120  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].CritRecov_adunit[j]);
4121  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * (TSMean[i].SARI_adunit[j] - SARI_a[j]));
4122  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * (TSMean[i].Critical_adunit[j] - Critical_a[j]));
4123  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * (TSMean[i].CritRecov_adunit[j] - CritRecov_a[j]));
4124 
4126  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incI_adunit[j]);
4127  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incMild_adunit[j]);
4128  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incILI_adunit[j]);
4129  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incSARI_adunit[j]);
4130  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incCritical_adunit[j]);
4131  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incCritRecov_adunit[j]);
4132  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * incSARI_a[j]);
4133  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * incCritical_a[j]);
4134  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * incCritRecov_a[j]);
4135  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incD_adunit[j]);
4136  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incDeath_ILI_adunit[j]);
4137  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incDeath_SARI_adunit[j]);
4138  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].incDeath_Critical_adunit[j]);
4139 
4141  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumMild_adunit[j]);
4142  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumILI_adunit[j]);
4143  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumSARI_adunit[j]);
4144  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumCritical_adunit[j]);
4145  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumCritRecov_adunit[j]);
4146  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumD_adunit[j]);
4147  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumDeath_ILI_adunit[j]);
4148  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumDeath_SARI_adunit[j]);
4149  for (j = 0; j < P.NumAdunits; j++) fprintf(dat, "\t%.10f", c * TSMean[i].cumDeath_Critical_adunit[j]);
4150 
4151  fprintf(dat, "\n");
4152  }
4153  fclose(dat);
4154  free(SARI_a); free(Critical_a); free(CritRecov_a);
4155  free(incSARI_a); free(incCritical_a); free(incCritRecov_a);
4156  }
4157  }
4158 }
4159 
4160 void SaveRandomSeeds(void)
4161 {
4162  /* function: SaveRandomSeeds(void)
4163  *
4164  * Purpose: outputs the random seeds used for each run to a file
4165  * Parameter: none
4166  * Returns: none
4167  *
4168  * Author: ggilani, 09/03/17
4169  */
4170  FILE* dat;
4171  char outname[1024];
4172 
4173  sprintf(outname, "%s.seeds.xls", OutFile);
4174  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
4175  fprintf(dat, "%i\t%i\n", P.nextRunSeed1, P.nextRunSeed2);
4176  fclose(dat);
4177 }
4178 
4179 void SaveEvents(void)
4180 {
4181  /* function: SaveEvents(void)
4182  *
4183  * Purpose: outputs event log to a csv file if required
4184  * Parameters: none
4185  * Returns: none
4186  *
4187  * Author: ggilani, 15/10/2014
4188  */
4189  int i;
4190  FILE* dat;
4191  char outname[1024];
4192 
4193  sprintf(outname, "%s.infevents.xls", OutFile);
4194  if (!(dat = fopen(outname, "wb"))) ERR_CRITICAL("Unable to open output file\n");
4195  fprintf(dat, "type,t,thread,ind_infectee,cell_infectee,listpos_infectee,adunit_infectee,x_infectee,y_infectee,t_infector,ind_infector,cell_infector\n");
4196  for (i = 0; i < nEvents; i++)
4197  {
4198  fprintf(dat, "%i\t%.10f\t%i\t%i\t%i\t%i\t%i\t%.10f\t%.10f\t%.10f\t%i\t%i\n",
4199  InfEventLog[i].type, InfEventLog[i].t, InfEventLog[i].thread, InfEventLog[i].infectee_ind, InfEventLog[i].infectee_cell, InfEventLog[i].listpos, InfEventLog[i].infectee_adunit, InfEventLog[i].infectee_x, InfEventLog[i].infectee_y, InfEventLog[i].t_infector, InfEventLog[i].infector_ind, InfEventLog[i].infector_cell);
4200  }
4201  fclose(dat);
4202 }
4203 
4204 void LoadSnapshot(void)
4205 {
4206  FILE* dat;
4207  int i, j, * CellMemberArray, * CellSuscMemberArray;
4208  int32_t l;
4209  long long CM_offset, CSM_offset;
4210  double t;
4211  int** Array_InvCDF;
4212  float* Array_tot_prob, ** Array_cum_trans, ** Array_max_trans;
4213 
4214  if (!(dat = fopen(SnapshotLoadFile, "rb"))) ERR_CRITICAL("Unable to open snapshot file\n");
4215  fprintf(stderr, "Loading snapshot.");
4216  if (!(Array_InvCDF = (int**)malloc(P.NCP * sizeof(int*)))) ERR_CRITICAL("Unable to allocate temp cell storage\n");
4217  if (!(Array_max_trans = (float**)malloc(P.NCP * sizeof(float*)))) ERR_CRITICAL("Unable to temp allocate cell storage\n");
4218  if (!(Array_cum_trans = (float**)malloc(P.NCP * sizeof(float*)))) ERR_CRITICAL("Unable to temp allocate cell storage\n");
4219  if (!(Array_tot_prob = (float*)malloc(P.NCP * sizeof(float)))) ERR_CRITICAL("Unable to temp allocate cell storage\n");
4220  for (i = 0; i < P.NCP; i++)
4221  {
4222  Array_InvCDF[i] = Cells[i].InvCDF;
4223  Array_max_trans[i] = Cells[i].max_trans;
4224  Array_cum_trans[i] = Cells[i].cum_trans;
4225  Array_tot_prob[i] = Cells[i].tot_prob;
4226  }
4227 
4228  fread_big((void*)& i, sizeof(int), 1, dat); if (i != P.PopSize) ERR_CRITICAL_FMT("Incorrect N (%i %i) in snapshot file.\n", P.PopSize, i);
4229  fread_big((void*)& i, sizeof(int), 1, dat); if (i != P.NH) ERR_CRITICAL("Incorrect NH in snapshot file.\n");
4230  fread_big((void*)&i, sizeof(int), 1, dat); if (i != P.NC) ERR_CRITICAL_FMT("## %i neq %i\nIncorrect NC in snapshot file.", i, P.NC);
4231  fread_big((void*)& i, sizeof(int), 1, dat); if (i != P.NCP) ERR_CRITICAL("Incorrect NCP in snapshot file.\n");
4232  fread_big((void*)& i, sizeof(int), 1, dat); if (i != P.ncw) ERR_CRITICAL("Incorrect ncw in snapshot file.\n");
4233  fread_big((void*)& i, sizeof(int), 1, dat); if (i != P.nch) ERR_CRITICAL("Incorrect nch in snapshot file.\n");
4234  fread_big((void*)& l, sizeof(int32_t), 1, dat); if (l != P.setupSeed1) ERR_CRITICAL("Incorrect setupSeed1 in snapshot file.\n");
4235  fread_big((void*)& l, sizeof(int32_t), 1, dat); if (l != P.setupSeed2) ERR_CRITICAL("Incorrect setupSeed2 in snapshot file.\n");
4236  fread_big((void*)& t, sizeof(double), 1, dat); if (t != P.TimeStep) ERR_CRITICAL("Incorrect TimeStep in snapshot file.\n");
4237  fread_big((void*) & (P.SnapshotLoadTime), sizeof(double), 1, dat);
4238  P.NumSamples = 1 + (int)ceil((P.SampleTime - P.SnapshotLoadTime) / P.SampleStep);
4239  fprintf(stderr, ".");
4240  fread_big((void*)& CellMemberArray, sizeof(int*), 1, dat);
4241  fprintf(stderr, ".");
4242  fread_big((void*)& CellSuscMemberArray, sizeof(int*), 1, dat);
4243  fprintf(stderr, ".");
4244  CM_offset = State.CellMemberArray - CellMemberArray;
4245  CSM_offset = State.CellSuscMemberArray - CellSuscMemberArray;
4246 
4247  fread_big((void*)Hosts, sizeof(Person), (size_t)P.PopSize, dat);
4248  fprintf(stderr, ".");
4249  fread_big((void*)Households, sizeof(Household), (size_t)P.NH, dat);
4250  fprintf(stderr, ".");
4251  fread_big((void*)Cells, sizeof(Cell), (size_t)P.NC, dat);
4252  fprintf(stderr, ".");
4253  fread_big((void*)Mcells, sizeof(Microcell), (size_t)P.NMC, dat);
4254  fprintf(stderr, ".");
4255  fread_big((void*)State.CellMemberArray, sizeof(int), (size_t)P.PopSize, dat);
4256  fprintf(stderr, ".");
4257  fread_big((void*)State.CellSuscMemberArray, sizeof(int), (size_t)P.PopSize, dat);
4258  fprintf(stderr, ".");
4259  for (i = 0; i < P.NC; i++)
4260  {
4261  if (Cells[i].n > 0)
4262  {
4263  Cells[i].members += CM_offset;
4264  Cells[i].susceptible += CSM_offset;
4265  Cells[i].latent += CSM_offset;
4266  Cells[i].infected += CSM_offset;
4267  }
4268  for (j = 0; j < MAX_INTERVENTION_TYPES; j++) Cells[i].CurInterv[j] = -1; // turn interventions off in loaded image
4269  }
4270  for (i = 0; i < P.NMC; i++)
4271  if (Mcells[i].n > 0)
4272  Mcells[i].members += CM_offset;
4273 
4274  for (i = 0; i < P.NCP; i++)
4275  {
4276  Cells[i].InvCDF = Array_InvCDF[i];
4277  Cells[i].max_trans = Array_max_trans[i];
4278  Cells[i].cum_trans = Array_cum_trans[i];
4279  Cells[i].tot_prob = Array_tot_prob[i];
4280  }
4281  free(Array_tot_prob);
4282  free(Array_cum_trans);
4283  free(Array_max_trans);
4284  free(Array_InvCDF);
4285  fprintf(stderr, "\n");
4286  fclose(dat);
4287 }
4288 
4289 void SaveSnapshot(void)
4290 {
4291  FILE* dat;
4292  int i = 1;
4293 
4294  if (!(dat = fopen(SnapshotSaveFile, "wb"))) ERR_CRITICAL("Unable to open snapshot file\n");
4295 
4296  fwrite_big((void*) & (P.PopSize), sizeof(int), 1, dat);
4297  fprintf(stderr, "## %i\n", i++);
4298  fwrite_big((void*) & (P.NH), sizeof(int), 1, dat);
4299  fprintf(stderr, "## %i\n", i++);
4300  fwrite_big((void*) & (P.NC), sizeof(int), 1, dat);
4301  fprintf(stderr, "## %i\n", i++);
4302  fwrite_big((void*) & (P.NCP), sizeof(int), 1, dat);
4303  fprintf(stderr, "## %i\n", i++);
4304  fwrite_big((void*) & (P.ncw), sizeof(int), 1, dat);
4305  fprintf(stderr, "## %i\n", i++);
4306  fwrite_big((void*) & (P.nch), sizeof(int), 1, dat);
4307  fprintf(stderr, "## %i\n", i++);
4308  fwrite_big((void*) & (P.setupSeed1), sizeof(int32_t), 1, dat);
4309  fprintf(stderr, "## %i\n", i++);
4310  fwrite_big((void*) & (P.setupSeed2), sizeof(int32_t), 1, dat);
4311  fprintf(stderr, "## %i\n", i++);
4312  fwrite_big((void*) & (P.TimeStep), sizeof(double), 1, dat);
4313  fprintf(stderr, "## %i\n", i++);
4314  fwrite_big((void*) & (P.SnapshotSaveTime), sizeof(double), 1, dat);
4315  fprintf(stderr, "## %i\n", i++);
4316  fwrite_big((void*) & (State.CellMemberArray), sizeof(int*), 1, dat);
4317  fprintf(stderr, "## %i\n", i++);
4318  fwrite_big((void*) & (State.CellSuscMemberArray), sizeof(int*), 1, dat);
4319  fprintf(stderr, "## %i\n", i++);
4320 
4321  fwrite_big((void*)Hosts, sizeof(Person), (size_t)P.PopSize, dat);
4322 
4323  fprintf(stderr, "## %i\n", i++);
4324  fwrite_big((void*)Households, sizeof(Household), (size_t)P.NH, dat);
4325  fprintf(stderr, "## %i\n", i++);
4326  fwrite_big((void*)Cells, sizeof(Cell), (size_t)P.NC, dat);
4327  fprintf(stderr, "## %i\n", i++);
4328  fwrite_big((void*)Mcells, sizeof(Microcell), (size_t)P.NMC, dat);
4329  fprintf(stderr, "## %i\n", i++);
4330 
4331  fwrite_big((void*)State.CellMemberArray, sizeof(int), (size_t)P.PopSize, dat);
4332  fprintf(stderr, "## %i\n", i++);
4333  fwrite_big((void*)State.CellSuscMemberArray, sizeof(int), (size_t)P.PopSize, dat);
4334  fprintf(stderr, "## %i\n", i++);
4335 
4336  fclose(dat);
4337 }
4338 
4339 void UpdateProbs(int DoPlace)
4340 {
4341  if (!DoPlace)
4342  {
4343 #pragma omp parallel for schedule(static,500) default(none) \
4344  shared(P, CellLookup)
4345  for (int j = 0; j < P.NCP; j++)
4346  {
4347  CellLookup[j]->tot_prob = 0;
4348  CellLookup[j]->S0 = CellLookup[j]->S + CellLookup[j]->L + CellLookup[j]->I;
4349  if (P.DoDeath)
4350  {
4351  CellLookup[j]->S0 += CellLookup[j]->n / 5;
4352  if ((CellLookup[j]->n < 100) || (CellLookup[j]->S0 > CellLookup[j]->n)) CellLookup[j]->S0 = CellLookup[j]->n;
4353  }
4354  }
4355  }
4356  else
4357  {
4358 #pragma omp parallel for schedule(static,500) default(none) \
4359  shared(P, CellLookup)
4360  for (int j = 0; j < P.NCP; j++)
4361  {
4362  CellLookup[j]->S0 = CellLookup[j]->S;
4363  CellLookup[j]->tot_prob = 0;
4364  }
4365  }
4366 #pragma omp parallel for schedule(static,500) default(none) \
4367  shared(P, CellLookup)
4368  for (int j = 0; j < P.NCP; j++)
4369  {
4370  int m, k;
4371  float t;
4372  CellLookup[j]->cum_trans[0] = ((float)(CellLookup[0]->S0)) * CellLookup[j]->max_trans[0];
4373  t = ((float)CellLookup[0]->n) * CellLookup[j]->max_trans[0];
4374  for (m = 1; m < P.NCP; m++)
4375  {
4376  CellLookup[j]->cum_trans[m] = CellLookup[j]->cum_trans[m - 1] + ((float)(CellLookup[m]->S0)) * CellLookup[j]->max_trans[m];
4377  t += ((float)CellLookup[m]->n) * CellLookup[j]->max_trans[m];
4378  }
4379  CellLookup[j]->tot_prob = CellLookup[j]->cum_trans[P.NCP - 1];
4380  for (m = 0; m < P.NCP; m++)
4381  CellLookup[j]->cum_trans[m] /= CellLookup[j]->tot_prob;
4382  CellLookup[j]->tot_prob /= t;
4383  for (k = m = 0; k <= 1024; k++)
4384  {
4385  while (CellLookup[j]->cum_trans[m] * 1024 < ((float)k)) m++;
4386  CellLookup[j]->InvCDF[k] = m;
4387  }
4388  }
4389 }
4390 
4391 int ChooseTriggerVariableAndValue(int AdUnit)
4392 {
4393  int VariableAndValue = 0;
4394  if (P.DoGlobalTriggers)
4395  {
4396  if (P.DoPerCapitaTriggers)
4397  VariableAndValue = (int)floor(((double)State.trigDC) * P.GlobalIncThreshPop / ((double)P.PopSize));
4398  else
4399  VariableAndValue = State.trigDC;
4400  }
4401  else if (P.DoAdminTriggers) VariableAndValue = State.trigDC_adunit[AdUnit];
4402  else VariableAndValue = INT_MAX;
4403 
4404  return VariableAndValue;
4405 }
4406 double ChooseThreshold(int AdUnit, double WhichThreshold)
4407 {
4408  double Threshold = 0;
4409  if (P.DoGlobalTriggers) Threshold = WhichThreshold;
4410  else if (P.DoAdminTriggers)
4411  {
4412  if (P.DoPerCapitaTriggers)
4413  Threshold = (int)ceil(((double)(AdUnits[AdUnit].n * WhichThreshold)) / P.IncThreshPop);
4414  else
4415  Threshold = WhichThreshold;
4416  }
4417  return Threshold;
4418 }
4419 
4420 
4421 void UpdateEfficaciesAndComplianceProportions(double t)
4422 {
4424  for (int ChangeTime = 0; ChangeTime < P.Num_SD_ChangeTimes; ChangeTime++)
4425  if (t == P.SD_ChangeTimes[ChangeTime])
4426  {
4428  P.SocDistHouseholdEffectCurrent = P.SD_HouseholdEffects_OverTime[ChangeTime];
4429  P.SocDistSpatialEffectCurrent = P.SD_SpatialEffects_OverTime [ChangeTime];
4430  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
4431  P.SocDistPlaceEffectCurrent[PlaceType] = P.SD_PlaceEffects_OverTime[ChangeTime][PlaceType];
4432 
4434  P.EnhancedSocDistHouseholdEffectCurrent = P.Enhanced_SD_HouseholdEffects_OverTime [ChangeTime];
4435  P.EnhancedSocDistSpatialEffectCurrent = P.Enhanced_SD_SpatialEffects_OverTime [ChangeTime];
4436  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
4437  P.EnhancedSocDistPlaceEffectCurrent[PlaceType] = P.Enhanced_SD_PlaceEffects_OverTime[ChangeTime][PlaceType];
4438 
4439  P.SocDistCellIncThresh = P.SD_CellIncThresh_OverTime[ChangeTime];
4440  }
4441 
4443  for (int ChangeTime = 0; ChangeTime < P.Num_CI_ChangeTimes; ChangeTime++)
4444  if (t == P.CI_ChangeTimes[ChangeTime])
4445  {
4446  P.CaseIsolationEffectiveness = P.CI_SpatialAndPlaceEffects_OverTime [ChangeTime];
4447  P.CaseIsolationHouseEffectiveness = P.CI_HouseholdEffects_OverTime [ChangeTime];
4448 
4449  P.CaseIsolationProp = P.CI_Prop_OverTime [ChangeTime];
4450  P.CaseIsolation_CellIncThresh = P.CI_CellIncThresh_OverTime [ChangeTime];
4451  }
4452 
4454  if (P.DoHouseholds)
4455  for (int ChangeTime = 0; ChangeTime < P.Num_HQ_ChangeTimes; ChangeTime++)
4456  if (t == P.HQ_ChangeTimes[ChangeTime])
4457  {
4458  P.HQuarantineSpatialEffect = P.HQ_SpatialEffects_OverTime [ChangeTime];
4459  P.HQuarantineHouseEffect = P.HQ_HouseholdEffects_OverTime [ChangeTime];
4460  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
4461  P.HQuarantinePlaceEffect[PlaceType] = P.HQ_PlaceEffects_OverTime [ChangeTime][PlaceType];
4462 
4463  P.HQuarantinePropIndivCompliant = P.HQ_Individual_PropComply_OverTime [ChangeTime];
4464  P.HQuarantinePropHouseCompliant = P.HQ_Household_PropComply_OverTime [ChangeTime];
4465 
4466  P.HHQuar_CellIncThresh = P.HQ_CellIncThresh_OverTime [ChangeTime];
4467  }
4468 
4470  if (P.DoPlaces)
4471  {
4472  for (int ChangeTime = 0; ChangeTime < P.Num_PC_ChangeTimes; ChangeTime++)
4473  if (t == P.PC_ChangeTimes[ChangeTime])
4474  {
4476 // unsigned short int ts = (unsigned short int) (P.TimeStepsPerDay * t);
4477 // for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
4478 //#pragma omp parallel for schedule(static,1)
4479 // for (int ThreadNum = 0; ThreadNum < P.NumThreads; ThreadNum++)
4480 // for (int PlaceNum = ThreadNum; PlaceNum < P.Nplace[PlaceType]; PlaceNum += P.NumThreads)
4481 // DoPlaceOpen(PlaceType, PlaceNum, ts, ThreadNum);
4482 
4483  P.PlaceCloseSpatialRelContact = P.PC_SpatialEffects_OverTime [ChangeTime];
4484  P.PlaceCloseHouseholdRelContact = P.PC_HouseholdEffects_OverTime[ChangeTime];
4485  for (int PlaceType = 0; PlaceType < P.PlaceTypeNum; PlaceType++)
4486  {
4487  P.PlaceCloseEffect[PlaceType] = P.PC_PlaceEffects_OverTime[ChangeTime][PlaceType];
4488  P.PlaceClosePropAttending[PlaceType] = P.PC_PropAttending_OverTime[ChangeTime][PlaceType];
4489  }
4490 
4491  P.PlaceCloseIncTrig = P.PC_IncThresh_OverTime [ChangeTime];
4492  P.PlaceCloseFracIncTrig = P.PC_FracIncThresh_OverTime [ChangeTime];
4493  P.PlaceCloseCellIncThresh = P.PC_CellIncThresh_OverTime [ChangeTime];
4494  P.PlaceCloseDuration = P.PC_Durs_OverTime [ChangeTime];
4495 
4496 
4498  if(P.PlaceCloseTimeStart<1e10) P.PlaceCloseTimeStart = t;
4499 
4500  // ensure that new duration doesn't go over next change time. Judgement call here - talk to Neil if this is what he wants.
4501  if ((ChangeTime < P.Num_PC_ChangeTimes - 1) && (P.PlaceCloseTimeStart + P.PlaceCloseDuration >= P.PC_ChangeTimes[ChangeTime + 1]))
4502  P.PlaceCloseDuration = P.PC_ChangeTimes[ChangeTime + 1] - P.PC_ChangeTimes[ChangeTime]; // -1;
4503  //fprintf(stderr, "\nt=%lf, n=%i (%i) PlaceCloseDuration = %lf (%lf) \n", t, ChangeTime, P.Num_PC_ChangeTimes, P.PlaceCloseDuration, P.PC_ChangeTimes[ChangeTime+1]);
4504  }
4505  }
4506 
4508  for (int ChangeTime = 0; ChangeTime < P.Num_DCT_ChangeTimes; ChangeTime++)
4509  if (t == P.DCT_ChangeTimes[ChangeTime])
4510  {
4511  P.DCTCaseIsolationEffectiveness = P.DCT_SpatialAndPlaceEffects_OverTime [ChangeTime];
4512  P.DCTCaseIsolationHouseEffectiveness = P.DCT_HouseholdEffects_OverTime [ChangeTime];
4513  P.ProportionDigitalContactsIsolate = P.DCT_Prop_OverTime [ChangeTime];
4514  P.MaxDigitalContactsToTrace = P.DCT_MaxToTrace_OverTime [ChangeTime];
4515  }
4516 }
4517 
4518 void RecordSample(double t, int n)
4519 {
4520  int j, k, S, L, I, R, D, N, cumC, cumTC, cumI, cumR, cumD, cumDC, cumFC;
4521  int cumH; //add number of hospitalised, cumulative hospitalisation: ggilani 28/10/14
4522  int cumCT; //added cumulative number of contact traced: ggilani 15/06/17
4523  int cumCC; //added cumulative number of cases who are contacts: ggilani 28/05/2019
4524  int cumDCT; //added cumulative number of cases who are digitally contact traced: ggilani 11/03/20
4525  int cumHQ, cumAC, cumAH, cumAA, cumACS, cumAPC, cumAPA, cumAPCS, numPC, trigDC,trigAlert, trigAlertC;
4526  int cumC_country[MAX_COUNTRIES]; //add cumulative cases per country
4527  unsigned short int ts;
4528  double s,thr;
4529 
4531  int Mild, ILI, SARI, Critical, CritRecov, cumMild, cumILI, cumSARI, cumCritical, cumCritRecov, cumDeath_ILI, cumDeath_SARI, cumDeath_Critical;
4532 
4533  ts = (unsigned short int) (P.TimeStepsPerDay * t);
4534 
4536  S = L = I = R = D = cumI = cumC = cumDC = cumTC = cumFC = cumHQ = cumAC = cumAA = cumAH = cumACS = cumAPC = cumAPA = cumAPCS = cumD = cumH = cumCT = cumCC = cumDCT = 0;
4537  for (int i = 0; i < MAX_COUNTRIES; i++) cumC_country[i] = 0;
4538  if (P.DoSeverity)
4539  Mild = ILI = SARI = Critical = CritRecov = cumMild = cumILI = cumSARI = cumCritical = cumCritRecov = cumDeath_ILI = cumDeath_SARI = cumDeath_Critical = 0;
4540 
4541 #pragma omp parallel for schedule(static,10000) reduction(+:S,L,I,R,D,cumTC) default(none) \
4542  shared(P, CellLookup)
4543  for (int i = 0; i < P.NCP; i++)
4544  {
4545  Cell* ct = CellLookup[i];
4546  S += (int)ct->S;
4547  L += (int)ct->L;
4548  I += (int)ct->I;
4549  R += (int)ct->R;
4550  D += (int)ct->D;
4551  cumTC += (int)ct->cumTC;
4552  }
4553  cumR = R;
4554  cumD = D;
4555  //cumD = 0;
4556  N = S + L + I + R + D;
4557  if (N != P.PopSize) fprintf(stderr, "## %i #\n", P.PopSize - N);
4558  State.sumRad2 = 0;
4559  for (j = 0; j < P.NumThreads; j++)
4560  {
4561  cumI += StateT[j].cumI;
4562  cumC += StateT[j].cumC;
4563  cumDC += StateT[j].cumDC;
4564  cumFC += StateT[j].cumFC;
4565  cumH += StateT[j].cumH; //added cumulative hospitalisation
4566  cumCT += StateT[j].cumCT; //added contact tracing
4567  cumCC += StateT[j].cumCC; //added cases who are contacts
4568  cumDCT += StateT[j].cumDCT; //added cases who are digitally contact traced
4569  State.sumRad2 += StateT[j].sumRad2;
4570  State.sumRad2 += StateT[j].sumRad2;
4571  cumHQ += StateT[j].cumHQ;
4572  cumAC += StateT[j].cumAC;
4573  cumAA += StateT[j].cumAA;
4574  cumAPC += StateT[j].cumAPC;
4575  cumAPA += StateT[j].cumAPA;
4576  cumAPCS += StateT[j].cumAPCS;
4577  cumAH += StateT[j].cumAH;
4578  cumACS += StateT[j].cumACS;
4579  //cumD += StateT[j].cumD;
4580 
4581  if (P.DoSeverity)
4582  {
4584  Mild += StateT[j].Mild ;
4585  ILI += StateT[j].ILI ;
4586  SARI += StateT[j].SARI ;
4587  Critical += StateT[j].Critical ;
4588  CritRecov += StateT[j].CritRecov ;
4589 
4591  cumMild += StateT[j].cumMild ;
4592  cumILI += StateT[j].cumILI ;
4593  cumSARI += StateT[j].cumSARI ;
4594  cumCritical += StateT[j].cumCritical ;
4595  cumCritRecov += StateT[j].cumCritRecov ;
4596  cumDeath_ILI += StateT[j].cumDeath_ILI ;
4597  cumDeath_SARI += StateT[j].cumDeath_SARI ;
4598  cumDeath_Critical += StateT[j].cumDeath_Critical ;
4599  }
4600 
4601  //add up cumulative country counts: ggilani - 12/11/14
4602  for (int i = 0; i < MAX_COUNTRIES; i++) cumC_country[i] += StateT[j].cumC_country[i];
4603  if (State.maxRad2 < StateT[j].maxRad2) State.maxRad2 = StateT[j].maxRad2;
4604  }
4605  for (j = 0; j < P.NumThreads; j++)
4606  StateT[j].maxRad2 = State.maxRad2;
4607  TimeSeries[n].t = t;
4608  TimeSeries[n].S = (double)S;
4609  TimeSeries[n].L = (double)L;
4610  TimeSeries[n].I = (double)I;
4611  TimeSeries[n].R = (double)R;
4612  TimeSeries[n].D = (double)D;
4613  TimeSeries[n].incI = (double)(cumI - State.cumI);
4614  TimeSeries[n].incC = (double)(cumC - State.cumC);
4615  TimeSeries[n].incFC = (double)(cumFC - State.cumFC);
4616  TimeSeries[n].incH = (double)(cumH - State.cumH); //added incidence of hospitalisation
4617  TimeSeries[n].incCT = (double)(cumCT - State.cumCT); // added contact tracing
4618  TimeSeries[n].incCC = (double)(cumCC - State.cumCC); // added cases who are contacts
4619  TimeSeries[n].incDCT = (double)(cumDCT - State.cumDCT); //added cases who are digitally contact traced
4620  TimeSeries[n].incDC = (double)(cumDC - State.cumDC); //added incidence of detected cases
4621  TimeSeries[n].incTC = (double)(cumTC - State.cumTC);
4622  TimeSeries[n].incR = (double)(cumR - State.cumR);
4623  TimeSeries[n].incD = (double)(cumD - State.cumD);
4624  TimeSeries[n].incHQ = (double)(cumHQ - State.cumHQ);
4625  TimeSeries[n].incAC = (double)(cumAC - State.cumAC);
4626  TimeSeries[n].incAH = (double)(cumAH - State.cumAH);
4627  TimeSeries[n].incAA = (double)(cumAA - State.cumAA);
4628  TimeSeries[n].incACS = (double)(cumACS - State.cumACS);
4629  TimeSeries[n].incAPC = (double)(cumAPC - State.cumAPC);
4630  TimeSeries[n].incAPA = (double)(cumAPA - State.cumAPA);
4631  TimeSeries[n].incAPCS = (double)(cumAPCS - State.cumAPCS);
4632  TimeSeries[n].cumT = State.cumT;
4633  TimeSeries[n].cumUT = State.cumUT;
4634  TimeSeries[n].cumTP = State.cumTP;
4635  TimeSeries[n].cumV = State.cumV;
4636  TimeSeries[n].cumVG = State.cumVG; //added VG;
4637  TimeSeries[n].cumDC = cumDC;
4638  //fprintf(stderr, "\ncumD=%i last_cumD=%i incD=%lg\n ", cumD, State.cumD, TimeSeries[n].incD);
4639  //incidence per country
4640  for (int i = 0; i < MAX_COUNTRIES; i++) TimeSeries[n].incC_country[i] = (double)(cumC_country[i] - State.cumC_country[i]);
4641  if (P.DoICUTriggers)
4642  {
4643  trigDC = cumCritical;
4644  if (n >= P.TriggersSamplingInterval) trigDC -= (int)TimeSeries[n - P.TriggersSamplingInterval].cumCritical;
4645  }
4646  else
4647  {
4648  trigDC = cumDC;
4649  if (n >= P.TriggersSamplingInterval) trigDC -= (int)TimeSeries[n - P.TriggersSamplingInterval].cumDC;
4650  }
4651  State.trigDC = trigDC;
4652 
4654  State.S = S;
4655  State.L = L;
4656  State.I = I;
4657  State.R = R;
4658  State.D = D;
4659  State.cumI = cumI;
4660  State.cumDC = cumDC;
4661  State.cumTC = cumTC;
4662  State.cumFC = cumFC;
4663  State.cumH = cumH; //added cumulative hospitalisation
4664  State.cumCT = cumCT; //added cumulative contact tracing
4665  State.cumCC = cumCC; //added cumulative cases who are contacts
4666  State.cumDCT = cumDCT; //added cumulative cases who are digitally contact traced
4667  State.cumC = cumC;
4668  State.cumR = cumR;
4669  State.cumD = cumD;
4670  State.cumHQ = cumHQ;
4671  State.cumAC = cumAC;
4672  State.cumAH = cumAH;
4673  State.cumAA = cumAA;
4674  State.cumACS = cumACS;
4675  State.cumAPC = cumAPC;
4676  State.cumAPA = cumAPA;
4677  State.cumAPCS = cumAPCS;
4678 
4679  if (P.DoSeverity)
4680  {
4682  TimeSeries[n].incMild = (double)(cumMild - State.cumMild );
4683  TimeSeries[n].incILI = (double)(cumILI - State.cumILI );
4684  TimeSeries[n].incSARI = (double)(cumSARI - State.cumSARI );
4685  TimeSeries[n].incCritical = (double)(cumCritical - State.cumCritical );
4686  TimeSeries[n].incCritRecov = (double)(cumCritRecov - State.cumCritRecov );
4687  TimeSeries[n].incDeath_ILI = (double)(cumDeath_ILI - State.cumDeath_ILI );
4688  TimeSeries[n].incDeath_SARI = (double)(cumDeath_SARI - State.cumDeath_SARI );
4689  TimeSeries[n].incDeath_Critical = (double)(cumDeath_Critical - State.cumDeath_Critical );
4690 
4692  State.Mild = Mild ;
4693  State.ILI = ILI ;
4694  State.SARI = SARI ;
4695  State.Critical = Critical ;
4696  State.CritRecov = CritRecov ;
4697  State.cumMild = cumMild ;
4698  State.cumILI = cumILI ;
4699  State.cumSARI = cumSARI ;
4700  State.cumCritical = cumCritical ;
4701  State.cumCritRecov = cumCritRecov ;
4702  State.cumDeath_ILI = cumDeath_ILI ;
4703  State.cumDeath_SARI = cumDeath_SARI ;
4704  State.cumDeath_Critical = cumDeath_Critical ;
4705 
4707  TimeSeries[n].Mild = Mild ;
4708  TimeSeries[n].ILI = ILI ;
4709  TimeSeries[n].SARI = SARI ;
4710  TimeSeries[n].Critical = Critical ;
4711  TimeSeries[n].CritRecov = CritRecov ;
4712  TimeSeries[n].cumMild = cumMild ;
4713  TimeSeries[n].cumILI = cumILI ;
4714  TimeSeries[n].cumSARI = cumSARI ;
4715  TimeSeries[n].cumCritical = cumCritical ;
4716  TimeSeries[n].cumCritRecov = cumCritRecov ;
4717  TimeSeries[n].cumDeath_ILI = cumDeath_ILI ;
4718  TimeSeries[n].cumDeath_SARI = cumDeath_SARI ;
4719  TimeSeries[n].cumDeath_Critical = cumDeath_Critical ;
4720 
4721  for (int i = 0; i < NUM_AGE_GROUPS; i++)
4722  {
4725  TimeSeries[n].incMild_age[i] = (double)(-State.cumMild_age[i]);
4726  TimeSeries[n].incILI_age[i] = (double)(-State.cumILI_age[i]);
4727  TimeSeries[n].incSARI_age[i] = (double)(-State.cumSARI_age[i]);
4728  TimeSeries[n].incCritical_age[i] = (double)(-State.cumCritical_age[i]);
4729  TimeSeries[n].incCritRecov_age[i] = (double)(-State.cumCritRecov_age[i]);
4730  TimeSeries[n].incDeath_ILI_age[i] = (double)(-State.cumDeath_ILI_age[i]);
4731  TimeSeries[n].incDeath_SARI_age[i] = (double)(-State.cumDeath_SARI_age[i]);
4732  TimeSeries[n].incDeath_Critical_age[i] = (double)(-State.cumDeath_Critical_age[i]);
4733 
4734  State.Mild_age[i] = 0;
4735  State.ILI_age[i] = 0;
4736  State.SARI_age[i] = 0;
4737  State.Critical_age[i] = 0;
4738  State.CritRecov_age[i] = 0;
4739  State.cumMild_age[i] = 0;
4740  State.cumILI_age[i] = 0;
4741  State.cumSARI_age[i] = 0;
4742  State.cumCritical_age[i] = 0;
4743  State.cumCritRecov_age[i] = 0;
4744  State.cumDeath_ILI_age[i] = 0;
4745  State.cumDeath_SARI_age[i] = 0;
4746  State.cumDeath_Critical_age[i] = 0;
4747 
4748  for (j = 0; j < P.NumThreads; j++)
4749  {
4751  State.Mild_age[i] += StateT[j].Mild_age[i];
4752  State.ILI_age[i] += StateT[j].ILI_age[i];
4753  State.SARI_age[i] += StateT[j].SARI_age[i];
4754  State.Critical_age[i] += StateT[j].Critical_age[i];
4755  State.CritRecov_age[i] += StateT[j].CritRecov_age[i];
4756  State.cumMild_age[i] += StateT[j].cumMild_age[i];
4757  State.cumILI_age[i] += StateT[j].cumILI_age[i];
4758  State.cumSARI_age[i] += StateT[j].cumSARI_age[i];
4759  State.cumCritical_age[i] += StateT[j].cumCritical_age[i];
4760  State.cumCritRecov_age[i] += StateT[j].cumCritRecov_age[i];
4761  State.cumDeath_ILI_age[i] += StateT[j].cumDeath_ILI_age[i];
4762  State.cumDeath_SARI_age[i] += StateT[j].cumDeath_SARI_age[i];
4763  State.cumDeath_Critical_age[i] += StateT[j].cumDeath_Critical_age[i];
4764  }
4765 
4767  TimeSeries[n].incMild_age[i] += (double)(State.cumMild_age[i]);
4768  TimeSeries[n].incILI_age[i] += (double)(State.cumILI_age[i]);
4769  TimeSeries[n].incSARI_age[i] += (double)(State.cumSARI_age[i]);
4770  TimeSeries[n].incCritical_age[i] += (double)(State.cumCritical_age[i]);
4771  TimeSeries[n].incCritRecov_age[i] += (double)(State.cumCritRecov_age[i]);
4772  TimeSeries[n].incDeath_ILI_age[i] += (double)(State.cumDeath_ILI_age[i]);
4773  TimeSeries[n].incDeath_SARI_age[i] += (double)(State.cumDeath_SARI_age[i]);
4774  TimeSeries[n].incDeath_Critical_age[i] += (double)(State.cumDeath_Critical_age[i]);
4775 
4777  TimeSeries[n].Mild_age[i] = State.Mild_age[i];
4778  TimeSeries[n].ILI_age[i] = State.ILI_age[i];
4779  TimeSeries[n].SARI_age[i] = State.SARI_age[i];
4780  TimeSeries[n].Critical_age[i] = State.Critical_age[i];
4781  TimeSeries[n].CritRecov_age[i] = State.CritRecov_age[i];
4782  TimeSeries[n].cumMild_age[i] = State.cumMild_age[i];
4783  TimeSeries[n].cumILI_age[i] = State.cumILI_age[i];
4784  TimeSeries[n].cumSARI_age[i] = State.cumSARI_age[i];
4785  TimeSeries[n].cumCritical_age[i] = State.cumCritical_age[i];
4786  TimeSeries[n].cumCritRecov_age[i] = State.cumCritRecov_age[i];
4787  TimeSeries[n].cumDeath_ILI_age[i] = State.cumDeath_ILI_age[i];
4788  TimeSeries[n].cumDeath_SARI_age[i] = State.cumDeath_SARI_age[i];
4789  TimeSeries[n].cumDeath_Critical_age[i] = State.cumDeath_Critical_age[i];
4790  }
4791  if (P.DoAdUnits)
4792  for (int i = 0; i <= P.NumAdunits; i++)
4793  {
4796  TimeSeries[n].incMild_adunit [i] = (double)(-State.cumMild_adunit [i]);
4797  TimeSeries[n].incILI_adunit [i] = (double)(-State.cumILI_adunit [i]);
4798  TimeSeries[n].incSARI_adunit [i] = (double)(-State.cumSARI_adunit [i]);
4799  TimeSeries[n].incCritical_adunit [i] = (double)(-State.cumCritical_adunit [i]);
4800  TimeSeries[n].incCritRecov_adunit [i] = (double)(-State.cumCritRecov_adunit [i]);
4801  TimeSeries[n].incD_adunit [i] = (double)(-State.cumD_adunit [i]);
4802  TimeSeries[n].incDeath_ILI_adunit [i] = (double)(-State.cumDeath_ILI_adunit [i]);
4803  TimeSeries[n].incDeath_SARI_adunit [i] = (double)(-State.cumDeath_SARI_adunit [i]);
4804  TimeSeries[n].incDeath_Critical_adunit [i] = (double)(-State.cumDeath_Critical_adunit [i]);
4805 
4807  State.Mild_adunit [i] = 0;
4808  State.ILI_adunit [i] = 0;
4809  State.SARI_adunit [i] = 0;
4810  State.Critical_adunit [i] = 0;
4811  State.CritRecov_adunit [i] = 0;
4812  State.cumMild_adunit [i] = 0;
4813  State.cumILI_adunit [i] = 0;
4814  State.cumSARI_adunit [i] = 0;
4815  State.cumCritical_adunit [i] = 0;
4816  State.cumCritRecov_adunit [i] = 0;
4817  State.cumD_adunit [i] = 0;
4818  State.cumDeath_ILI_adunit [i] = 0;
4819  State.cumDeath_SARI_adunit [i] = 0;
4820  State.cumDeath_Critical_adunit [i] = 0;
4821 
4822  for (j = 0; j < P.NumThreads; j++)
4823  {
4825  State.Mild_adunit [i] += StateT[j].Mild_adunit [i];
4826  State.ILI_adunit [i] += StateT[j].ILI_adunit [i];
4827  State.SARI_adunit [i] += StateT[j].SARI_adunit [i];
4828  State.Critical_adunit [i] += StateT[j].Critical_adunit [i];
4829  State.CritRecov_adunit [i] += StateT[j].CritRecov_adunit [i];
4830  State.cumMild_adunit [i] += StateT[j].cumMild_adunit [i];
4831  State.cumILI_adunit [i] += StateT[j].cumILI_adunit [i];
4832  State.cumSARI_adunit [i] += StateT[j].cumSARI_adunit [i];
4833  State.cumCritical_adunit [i] += StateT[j].cumCritical_adunit [i];
4834  State.cumCritRecov_adunit [i] += StateT[j].cumCritRecov_adunit [i];
4835  State.cumD_adunit [i] += StateT[j].cumD_adunit [i];
4836  State.cumDeath_ILI_adunit [i] += StateT[j].cumDeath_ILI_adunit [i];
4837  State.cumDeath_SARI_adunit [i] += StateT[j].cumDeath_SARI_adunit [i];
4838  State.cumDeath_Critical_adunit [i] += StateT[j].cumDeath_Critical_adunit [i];
4839  }
4840 
4842  TimeSeries[n].incMild_adunit [i] += (double)(State.cumMild_adunit [i]);
4843  TimeSeries[n].incILI_adunit [i] += (double)(State.cumILI_adunit [i]);
4844  TimeSeries[n].incSARI_adunit [i] += (double)(State.cumSARI_adunit [i]);
4845  TimeSeries[n].incCritical_adunit [i] += (double)(State.cumCritical_adunit [i]);
4846  TimeSeries[n].incCritRecov_adunit [i] += (double)(State.cumCritRecov_adunit [i]);
4847  TimeSeries[n].incD_adunit [i] += (double)(State.cumD_adunit [i]);
4848  TimeSeries[n].incDeath_ILI_adunit [i] += (double)(State.cumDeath_ILI_adunit [i]);
4849  TimeSeries[n].incDeath_SARI_adunit [i] += (double)(State.cumDeath_SARI_adunit [i]);
4850  TimeSeries[n].incDeath_Critical_adunit [i] += (double)(State.cumDeath_Critical_adunit [i]);
4851 
4853  TimeSeries[n].Mild_adunit [i] = State.Mild_adunit [i];
4854  TimeSeries[n].ILI_adunit [i] = State.ILI_adunit [i];
4855  TimeSeries[n].SARI_adunit [i] = State.SARI_adunit [i];
4856  TimeSeries[n].Critical_adunit [i] = State.Critical_adunit [i];
4857  TimeSeries[n].CritRecov_adunit [i] = State.CritRecov_adunit [i];
4858  TimeSeries[n].cumMild_adunit [i] = State.cumMild_adunit [i];
4859  TimeSeries[n].cumILI_adunit [i] = State.cumILI_adunit [i];
4860  TimeSeries[n].cumSARI_adunit [i] = State.cumSARI_adunit [i];
4861  TimeSeries[n].cumCritical_adunit [i] = State.cumCritical_adunit [i];
4862  TimeSeries[n].cumCritRecov_adunit [i] = State.cumCritRecov_adunit [i];
4863  TimeSeries[n].cumD_adunit [i] = State.cumD_adunit [i];
4864  TimeSeries[n].cumDeath_ILI_adunit [i] = State.cumDeath_ILI_adunit [i];
4865  TimeSeries[n].cumDeath_SARI_adunit [i] = State.cumDeath_SARI_adunit [i];
4866  TimeSeries[n].cumDeath_Critical_adunit [i] = State.cumDeath_Critical_adunit [i];
4867  }
4868  }
4869 
4870  //update cumulative cases per country
4871  for (int i = 0; i < MAX_COUNTRIES; i++) State.cumC_country[i] = cumC_country[i];
4872  //update overall state variable for cumulative cases per adunit
4873 
4874  TimeSeries[n].rmsRad = (State.cumI > 0) ? sqrt(State.sumRad2 / ((double)State.cumI)) : 0;
4875  TimeSeries[n].maxRad = sqrt(State.maxRad2);
4876  TimeSeries[n].extinct = ((((P.SmallEpidemicCases >= 0) && (State.R <= P.SmallEpidemicCases)) || (P.SmallEpidemicCases < 0)) && (State.I + State.L == 0)) ? 1 : 0;
4877  for (int i = 0; i < NUM_AGE_GROUPS; i++)
4878  {
4879  TimeSeries[n].incCa[i] = TimeSeries[n].incIa[i] = TimeSeries[n].incDa[i] = 0;
4880  for (j = 0; j < P.NumThreads; j++)
4881  {
4882  TimeSeries[n].incCa[i] += (double)StateT[j].cumCa[i];
4883  TimeSeries[n].incIa[i] += (double)StateT[j].cumIa[i];
4884  TimeSeries[n].incDa[i] += (double)StateT[j].cumDa[i];
4885  }
4886  }
4887 
4888  for (int i = 0; i < 2; i++)
4889  {
4890  TimeSeries[n].incC_keyworker[i] = TimeSeries[n].incI_keyworker[i] = TimeSeries[n].cumT_keyworker[i] = 0;
4891  for (j = 0; j < P.NumThreads; j++)
4892  {
4893  TimeSeries[n].incC_keyworker[i] += (double)StateT[j].cumC_keyworker[i];
4894  TimeSeries[n].incI_keyworker[i] += (double)StateT[j].cumI_keyworker[i];
4895  TimeSeries[n].cumT_keyworker[i] += (double)StateT[j].cumT_keyworker[i];
4896  StateT[j].cumC_keyworker[i] = StateT[j].cumI_keyworker[i] = 0;
4897  }
4898  }
4899 
4900  for (int i = 0; i < INFECT_TYPE_MASK; i++)
4901  {
4902  TimeSeries[n].incItype[i] = 0;
4903  for (j = 0; j < P.NumThreads; j++)
4904  {
4905  TimeSeries[n].incItype[i] += (double)StateT[j].cumItype[i];
4906  StateT[j].cumItype[i] = 0;
4907  }
4908  }
4909  if (P.DoAdUnits)
4910  for (int i = 0; i <= P.NumAdunits; i++)
4911  {
4912  TimeSeries[n].incI_adunit[i] = TimeSeries[n].incC_adunit[i] = TimeSeries[n].cumT_adunit[i] = TimeSeries[n].incH_adunit[i] = TimeSeries[n].incDC_adunit[i] = TimeSeries[n].incCT_adunit[i] = TimeSeries[n].incDCT_adunit[i] = 0; //added detected cases: ggilani 03/02/15
4913  for (j = 0; j < P.NumThreads; j++)
4914  {
4915  TimeSeries[n].incI_adunit[i] += (double)StateT[j].cumI_adunit[i];
4916  TimeSeries[n].incC_adunit[i] += (double)StateT[j].cumC_adunit[i];
4917  TimeSeries[n].incDC_adunit[i] += (double)StateT[j].cumDC_adunit[i]; //added detected cases: ggilani 03/02/15
4918  TimeSeries[n].incH_adunit[i] += (double)StateT[j].cumH_adunit[i]; //added hospitalisation
4919  TimeSeries[n].incCT_adunit[i] += (double)StateT[j].cumCT_adunit[i]; //added contact tracing: ggilani 15/06/17
4920  TimeSeries[n].incCC_adunit[i] += (double)StateT[j].cumCC_adunit[i]; //added cases who are contacts: ggilani 28/05/2019
4921  TimeSeries[n].incDCT_adunit[i] += (double)StateT[j].cumDCT_adunit[i]; //added cases who are digitally contact traced: ggilani 11/03/20
4922  TimeSeries[n].cumT_adunit[i] += (double)StateT[j].cumT_adunit[i];
4923  State.cumC_adunit[i] += StateT[j].cumC_adunit[i];
4924  State.cumDC_adunit[i] += StateT[j].cumDC_adunit[i];
4925  StateT[j].cumI_adunit[i] = StateT[j].cumC_adunit[i] = StateT[j].cumH_adunit[i] = StateT[j].cumDC_adunit[i] = StateT[j].cumCT_adunit[i] = StateT[j].cumCC_adunit[i] = StateT[j].cumDCT_adunit[i] = 0; //added hospitalisation, detected cases, contact tracing: ggilani 03/02/15, 15/06/17
4926  }
4927  if (P.DoICUTriggers)
4928  {
4929  State.trigDC_adunit[i] += (int)TimeSeries[n].incCritical_adunit[i];
4930  if (n >= P.TriggersSamplingInterval) State.trigDC_adunit[i] -= (int)TimeSeries[n - P.TriggersSamplingInterval].incCritical_adunit[i];
4931  }
4932  else
4933  {
4934  State.trigDC_adunit[i] += (int)TimeSeries[n].incDC_adunit[i];
4935  if (n >= P.TriggersSamplingInterval) State.trigDC_adunit[i] -= (int)TimeSeries[n - P.TriggersSamplingInterval].incDC_adunit[i];
4936  }
4937  }
4938  if (P.DoDigitalContactTracing)
4939  for (int i = 0; i < P.NumAdunits; i++)
4940  TimeSeries[n].DCT_adunit[i] = (double)AdUnits[i].ndct; //added total numbers of contacts currently isolated due to digital contact tracing: ggilani 11/03/20
4941  if (P.DoPlaces)
4942  for (int i = 0; i < NUM_PLACE_TYPES; i++)
4943  {
4944  numPC = 0;
4945  for (j = 0; j < P.Nplace[i]; j++)
4946  if (PLACE_CLOSED(i, j)) numPC++;
4947  State.NumPlacesClosed[i] = numPC;
4948  TimeSeries[n].PropPlacesClosed[i] = ((double)numPC) / ((double)P.Nplace[i]);
4949  }
4950  for (int i = k = 0; i < P.NMC; i++) if (Mcells[i].socdist == 2) k++;
4951  TimeSeries[n].PropSocDist=((double)k)/((double)P.NMC);
4952 
4953  //update contact number distribution in State
4954  for (int i = 0; i < (MAX_CONTACTS+1); i++)
4955  {
4956  for (j = 0; j < P.NumThreads; j++)
4957  {
4958  State.contact_dist[i] += StateT[j].contact_dist[i];
4959  StateT[j].contact_dist[i] = 0;
4960  }
4961  }
4962 
4963  trigAlertC = State.cumDC;
4964  if (n >= P.PreControlClusterIdDuration) trigAlertC -= (int)TimeSeries[n - P.PreControlClusterIdDuration].cumDC;
4965 
4966  if (P.PreControlClusterIdUseDeaths)
4967  {
4968  trigAlert = (int)TimeSeries[n].D;
4969  if (n >= P.PreControlClusterIdDuration) trigAlert -= (int) TimeSeries[n - P.PreControlClusterIdDuration].D;
4970  }
4971  else
4972  {
4973  trigAlert = trigAlertC;
4974  }
4975 
4976  if(((!P.DoAlertTriggerAfterInterv) && (trigAlert >= P.PreControlClusterIdCaseThreshold)) || ((P.DoAlertTriggerAfterInterv) &&
4977  (((trigAlertC >= P.PreControlClusterIdCaseThreshold)&&(P.ModelCalibIteration<4)) || ((t>=P.PreIntervTime) && (P.ModelCalibIteration >= 4)))))
4978  {
4979  if((!P.StopCalibration)&&(!InterruptRun))
4980  {
4981  if (P.PreControlClusterIdTime == 0)
4982  {
4983  P.PreIntervTime = P.PreControlClusterIdTime = t;
4984  if (P.PreControlClusterIdCalTime >= 0)
4985  {
4986  P.PreControlClusterIdHolOffset = P.PreControlClusterIdTime - P.PreIntervIdCalTime;
4987 // fprintf(stderr, "@@## trigAlertC=%i P.PreControlClusterIdHolOffset=%lg \n",trigAlertC, P.PreControlClusterIdHolOffset);
4988  }
4989  }
4990  if ((P.PreControlClusterIdCalTime >= 0)&& (!P.DoAlertTriggerAfterInterv))
4991  {
4992  P.StopCalibration = 1;
4993  InterruptRun = 1;
4994  }
4995  if ((P.DoAlertTriggerAfterInterv) && (t == P.PreControlClusterIdTime + P.PreControlClusterIdCalTime - P.PreIntervIdCalTime))
4996  {
4997  if ((trigAlert > 0)&&(P.ModelCalibIteration<20))
4998  {
4999  s = ((double)trigAlert)/((double)P.AlertTriggerAfterIntervThreshold);
5000  thr = 1.1 / sqrt((double)P.AlertTriggerAfterIntervThreshold);
5001  if (thr < 0.05) thr = 0.05;
5002  fprintf(stderr, "\n** %i %lf %lf | %lg / %lg \t", P.ModelCalibIteration, t, P.PreControlClusterIdTime + P.PreControlClusterIdCalTime - P.PreIntervIdCalTime, P.PreControlClusterIdHolOffset,s);
5003  fprintf(stderr, "| %i %i %i %i -> ", trigAlert, trigAlertC, P.AlertTriggerAfterIntervThreshold, P.PreControlClusterIdCaseThreshold);
5004  if (P.ModelCalibIteration == 1)
5005  {
5006  if ((((s - 1.0) <= thr) && (s >= 1)) || (((1.0 - s) <= thr / 2) && (s < 1)))
5007  {
5008  P.ModelCalibIteration = 100;
5009  P.StopCalibration = 1;
5010  fprintf(stderr, "Calibration ended.\n");
5011  }
5012  else
5013  {
5014  s = pow(s, 0.95);
5015  k = (int)(((double)P.PreControlClusterIdCaseThreshold) / s);
5016  if (k > 0) P.PreControlClusterIdCaseThreshold = k;
5017  }
5018  }
5019  else if ((P.ModelCalibIteration >= 3) && ((P.ModelCalibIteration) % 2 == 1))
5020  {
5021  if ((((s - 1.0) <= thr) && (s >= 1)) || (((1.0 - s) <= thr / 2) && (s < 1)))
5022  {
5023  P.ModelCalibIteration=100;
5024  P.StopCalibration = 1;
5025  fprintf(stderr, "Calibration ended.\n");
5026  }
5027  else if (s > 1)
5028  {
5029  P.PreIntervTime--;
5030  P.PreControlClusterIdHolOffset--;
5031  }
5032  else if (s < 1)
5033  {
5034  P.PreIntervTime++;
5035  P.PreControlClusterIdHolOffset++;
5036  }
5037  }
5038  else if ((P.ModelCalibIteration >= 3) && ((P.ModelCalibIteration) % 2 == 0))
5039  {
5040  if ((((s - 1.0) <= thr) && (s >= 1)) || (((1.0 - s) <= thr / 2) && (s < 1)))
5041  {
5042  P.ModelCalibIteration = 100;
5043  P.StopCalibration = 1;
5044  fprintf(stderr, "Calibration ended.\n");
5045  }
5046  else
5047  P.SeedingScaling /=pow(s, 0.5);
5048  }
5049  P.ModelCalibIteration++;
5050  if(P.ModelCalibIteration<16) InterruptRun = 1;
5051  fprintf(stderr, "%i : %lg\n", P.PreControlClusterIdCaseThreshold, P.SeedingScaling);
5052  }
5053  else
5054  {
5055  P.StopCalibration = 1;
5056  InterruptRun = 1;
5057  }
5058  }
5059  }
5060  P.ControlPropCasesId = P.PostAlertControlPropCasesId;
5061 
5062  if (P.VaryEfficaciesOverTime)
5063  UpdateEfficaciesAndComplianceProportions(t - P.PreIntervTime);
5064 
5065 // changed to a define for speed (though always likely inlined anyway) and to avoid clang compiler warnings re double alignment
5066 #define DO_OR_DONT_AMEND_START_TIME(X,Y) if(X>=1e10) X=Y;
5067 
5069  for (int i = 0; i < P.NumAdunits; i++)
5070  if (ChooseTriggerVariableAndValue(i) > ChooseThreshold(i, P.CaseIsolation_CellIncThresh))
5071  DO_OR_DONT_AMEND_START_TIME(AdUnits[i].CaseIsolationTimeStart, t + ((P.DoInterventionDelaysByAdUnit)?AdUnits[i].CaseIsolationDelay: P.CaseIsolationTimeStartBase))
5073  for (int i = 0; i < P.NumAdunits; i++)
5074  if (ChooseTriggerVariableAndValue(i) > ChooseThreshold(i, P.HHQuar_CellIncThresh))
5075  DO_OR_DONT_AMEND_START_TIME(AdUnits[i].HQuarantineTimeStart, t + ((P.DoInterventionDelaysByAdUnit)?AdUnits[i].HQuarantineDelay: P.HQuarantineTimeStartBase));
5076 
5078  if (P.DoDigitalContactTracing)
5079  for (int i = 0; i < P.NumAdunits; i++)
5080  if (ChooseTriggerVariableAndValue(i) > ChooseThreshold(i, P.DigitalContactTracing_CellIncThresh))
5081  DO_OR_DONT_AMEND_START_TIME(AdUnits[i].DigitalContactTracingTimeStart, t + ((P.DoInterventionDelaysByAdUnit)?AdUnits[i].DCTDelay: P.DigitalContactTracingTimeStartBase));
5082 
5083  if (P.DoGlobalTriggers)
5084  {
5085  int TriggerValue = ChooseTriggerVariableAndValue(0);
5086  if (TriggerValue >= ChooseThreshold(0, P.TreatCellIncThresh))
5087  DO_OR_DONT_AMEND_START_TIME((P.TreatTimeStart), t + P.TreatTimeStartBase);
5088  if (TriggerValue >= P.VaccCellIncThresh) DO_OR_DONT_AMEND_START_TIME(P.VaccTimeStart, t + P.VaccTimeStartBase);
5089  if (TriggerValue >= P.SocDistCellIncThresh)
5090  {
5091  DO_OR_DONT_AMEND_START_TIME(P.SocDistTimeStart, t + P.SocDistTimeStartBase);
5092  //added this for admin unit based intervention delays based on a global trigger: ggilani 17/03/20
5093  if (P.DoInterventionDelaysByAdUnit)
5094  for (int i = 0; i < P.NumAdunits; i++)
5095  DO_OR_DONT_AMEND_START_TIME(AdUnits[i].SocialDistanceTimeStart, t + AdUnits[i].SocialDistanceDelay);
5096  }
5097  if (TriggerValue >= P.PlaceCloseCellIncThresh)
5098  {
5099  DO_OR_DONT_AMEND_START_TIME(P.PlaceCloseTimeStart, t + P.PlaceCloseTimeStartBase);
5100  if (P.DoInterventionDelaysByAdUnit)
5101  for (int i = 0; i < P.NumAdunits; i++)
5102  DO_OR_DONT_AMEND_START_TIME(AdUnits[i].PlaceCloseTimeStart, t + AdUnits[i].PlaceCloseDelay);
5103  }
5104  if (TriggerValue >= P.MoveRestrCellIncThresh)
5105  DO_OR_DONT_AMEND_START_TIME(P.MoveRestrTimeStart, t + P.MoveRestrTimeStartBase);
5106  if (TriggerValue >= P.KeyWorkerProphCellIncThresh)
5107  DO_OR_DONT_AMEND_START_TIME(P.KeyWorkerProphTimeStart, t + P.KeyWorkerProphTimeStartBase);
5108  }
5109  else
5110  {
5111  DO_OR_DONT_AMEND_START_TIME(P.TreatTimeStart, t + P.TreatTimeStartBase);
5112  DO_OR_DONT_AMEND_START_TIME(P.VaccTimeStart , t + P.VaccTimeStartBase);
5113  DO_OR_DONT_AMEND_START_TIME(P.SocDistTimeStart, t + P.SocDistTimeStartBase);
5114  DO_OR_DONT_AMEND_START_TIME(P.PlaceCloseTimeStart, t + P.PlaceCloseTimeStartBase);
5115  DO_OR_DONT_AMEND_START_TIME(P.MoveRestrTimeStart, t + P.MoveRestrTimeStartBase);
5116  DO_OR_DONT_AMEND_START_TIME(P.KeyWorkerProphTimeStart, t + P.KeyWorkerProphTimeStartBase);
5117  }
5118  DO_OR_DONT_AMEND_START_TIME(P.AirportCloseTimeStart, t + P.AirportCloseTimeStartBase);
5119  }
5120  if ((P.PlaceCloseIndepThresh > 0) && (((double)State.cumDC) >= P.PlaceCloseIndepThresh))
5121  DO_OR_DONT_AMEND_START_TIME(P.PlaceCloseTimeStart, t + P.PlaceCloseTimeStartBase);
5122 
5123  if (t > P.SocDistTimeStart + P.SocDistChangeDelay)
5124  {
5125  P.SocDistDurationCurrent = P.SocDistDuration2;
5126  P.SocDistHouseholdEffectCurrent = P.SocDistHouseholdEffect2;
5127  P.SocDistSpatialEffectCurrent = P.SocDistSpatialEffect2;
5128  P.EnhancedSocDistHouseholdEffectCurrent = P.EnhancedSocDistHouseholdEffect2;
5129  P.EnhancedSocDistSpatialEffectCurrent = P.EnhancedSocDistSpatialEffect2;
5130  for (int i = 0; i < P.PlaceTypeNum; i++)
5131  {
5132  P.SocDistPlaceEffectCurrent[i] = P.SocDistPlaceEffect2[i];
5133  P.EnhancedSocDistPlaceEffectCurrent[i] = P.EnhancedSocDistPlaceEffect2[i];
5134  }
5135  }
5136  //fix to switch off first place closure after P.PlaceCloseDuration has elapsed, if there are no school or cell-based triggers set
5137  if (t == P.PlaceCloseTimeStart + P.PlaceCloseDuration)
5138  {
5139  P.PlaceCloseTimeStartPrevious = P.PlaceCloseTimeStart;
5140  if ((P.PlaceCloseIncTrig == 0) && (P.PlaceCloseFracIncTrig == 0) && (P.PlaceCloseCellIncThresh == 0)) P.PlaceCloseTimeStart = 9e9;
5141  }
5142 
5143  if (!P.VaryEfficaciesOverTime)
5144  {
5145  if ((P.PlaceCloseTimeStart2 > P.PlaceCloseTimeStartPrevious) &&
5146  (t >= P.PlaceCloseTimeStartPrevious + P.PlaceCloseDuration) &&
5147  (t >= P.PlaceCloseTimeStartPrevious + P.PlaceCloseTimeStartBase2 - P.PlaceCloseTimeStartBase))
5148  {
5149  fprintf(stderr, "\nSecond place closure period (t=%lg)\n", t);
5150  P.PlaceCloseTimeStartPrevious = P.PlaceCloseTimeStart2 = P.PlaceCloseTimeStart = t;
5151  P.PlaceCloseDuration = P.PlaceCloseDuration2;
5152  P.PlaceCloseIncTrig = P.PlaceCloseIncTrig2;
5153  P.PlaceCloseCellIncThresh = P.PlaceCloseCellIncThresh2;
5154  }
5155  }
5156 
5157  if (P.OutputBitmap >= 1)
5158  {
5159  TSMean = TSMeanNE; TSVar = TSVarNE;
5160  CaptureBitmap ();
5161  OutputBitmap (0);
5162  }
5163 }
5164 
5165 void RecordInfTypes(void)
5166 {
5167  int i, j, k, l, lc, lc2, b, c, n, nf, i2;
5168  double* res, * res_av, * res_var, t, s;
5169 
5170  for (n = 0; n < P.NumSamples; n++)
5171  {
5172  for (i = 0; i < INFECT_TYPE_MASK; i++) TimeSeries[n].Rtype[i] = 0;
5173  for (i = 0; i < NUM_AGE_GROUPS; i++) TimeSeries[n].Rage[i] = 0;
5174  TimeSeries[n].Rdenom = 0;
5175  }
5176  for (i = 0; i < INFECT_TYPE_MASK; i++) inftype[i] = 0;
5177  for (i = 0; i < MAX_COUNTRIES; i++) infcountry[i] = 0;
5178  for (i = 0; i < MAX_SEC_REC; i++)
5179  for (j = 0; j < MAX_GEN_REC; j++)
5180  indivR0[i][j] = 0;
5181  for (i = 0; i <= MAX_HOUSEHOLD_SIZE; i++)
5182  for (j = 0; j <= MAX_HOUSEHOLD_SIZE; j++)
5183  inf_household[i][j] = case_household[i][j] = 0;
5184  for (b = 0; b < P.NC; b++)
5185  if ((Cells[b].S != Cells[b].n) || (Cells[b].R > 0))
5186  for (c = 0; c < Cells[b].n; c++)
5187  Hosts[Cells[b].members[c]].listpos = 0;
5188  // for(b=0;b<P.NC;b++)
5189  // if((Cells[b].S!=Cells[b].n)||(Cells[b].R>0))
5190  {
5191  j = k = l = lc = lc2 = 0; t = 1e10;
5192  // for(c=0;c<Cells[b].n;c++)
5193  for (i = 0; i < P.PopSize; i++)
5194  {
5195  // i=Cells[b].members[c];
5196  if (j == 0) j = k = Households[Hosts[i].hh].nh;
5197  if ((Hosts[i].inf != InfStat_Susceptible) && (Hosts[i].inf != InfStat_ImmuneAtStart))
5198  {
5199  if (Hosts[i].latent_time * P.TimeStep <= P.SampleTime)
5200  TimeSeries[(int)(Hosts[i].latent_time * P.TimeStep / P.SampleStep)].Rdenom++;
5201  infcountry[Mcells[Hosts[i].mcell].country]++;
5202  if (abs(Hosts[i].inf) < InfStat_Recovered)
5203  l = -1;
5204  else if (l >= 0)
5205  l++;
5206  if ((l >= 0) && ((Hosts[i].inf == InfStat_RecoveredFromSymp) || (Hosts[i].inf == InfStat_Dead_WasSymp)))
5207  {
5208  lc2++;
5209  if (Hosts[i].latent_time * P.TimeStep <= t) // This convoluted logic is to pick up households where the index is symptomatic
5210  {
5211  lc = 1; t = Hosts[i].latent_time * P.TimeStep;
5212  }
5213  }
5214  else if ((l > 0) && (Hosts[i].latent_time * P.TimeStep < t))
5215  {
5216  lc = 0; t = Hosts[i].latent_time * P.TimeStep;
5217  }
5218  i2 = Hosts[i].infector;
5219  if (i2 >= 0)
5220  {
5221  Hosts[i2].listpos++;
5222  if (Hosts[i2].latent_time * P.TimeStep <= P.SampleTime)
5223  {
5224  TimeSeries[(int)(Hosts[i2].latent_time * P.TimeStep / P.SampleStep)].Rtype[Hosts[i].infect_type % INFECT_TYPE_MASK]++;
5225  TimeSeries[(int)(Hosts[i2].latent_time * P.TimeStep / P.SampleStep)].Rage[HOST_AGE_GROUP(i)]++;
5226  }
5227  }
5228  }
5229  inftype[Hosts[i].infect_type % INFECT_TYPE_MASK]++;
5230  j--;
5231  if (j == 0)
5232  {
5233  if (l < 0) l = 0;
5234  inf_household[k][l]++;
5235  case_household[k][lc2]++; //now recording total symptomatic cases, rather than infections conditional on symptomatic index
5236  l = lc = lc2 = 0; t = 1e10;
5237  }
5238  }
5239  }
5240  for (b = 0; b < P.NC; b++)
5241  if ((Cells[b].S != Cells[b].n) || (Cells[b].R > 0))
5242  for (c = 0; c < Cells[b].n; c++)
5243  {
5244  i = Cells[b].members[c];
5245  if ((abs(Hosts[i].inf) == InfStat_Recovered) || (abs(Hosts[i].inf) == InfStat_Dead))
5246  {
5247  l = Hosts[i].infect_type / INFECT_TYPE_MASK;
5248  if ((l < MAX_GEN_REC) && (Hosts[i].listpos < MAX_SEC_REC)) indivR0[Hosts[i].listpos][l]++;
5249  }
5250  }
5251  /* if(!TimeSeries[P.NumSamples-1].extinct) */
5252  {
5253  for (i = 0; i < INFECT_TYPE_MASK; i++) inftype_av[i] += inftype[i];
5254  for (i = 0; i < MAX_COUNTRIES; i++)
5255  {
5256  infcountry_av[i] += infcountry[i];
5257  if (infcountry[i] > 0) infcountry_num[i]++;
5258  }
5259  for (i = 0; i < MAX_SEC_REC; i++)
5260  for (j = 0; j < MAX_GEN_REC; j++)
5261  indivR0_av[i][j] += indivR0[i][j];
5262  for (i = 0; i <= MAX_HOUSEHOLD_SIZE; i++)
5263  for (j = 0; j <= MAX_HOUSEHOLD_SIZE; j++)
5264  {
5265  inf_household_av[i][j] += inf_household[i][j];
5266  case_household_av[i][j] += case_household[i][j];
5267  }
5268  }
5269  k = (P.PreIntervIdCalTime>0)?((int) (P.PreIntervIdCalTime - P.PreControlClusterIdTime)):0;
5270  for (n = 0; n < P.NumSamples; n++)
5271  {
5272  TimeSeries[n].t += k;
5273  s = 0;
5274  if (TimeSeries[n].Rdenom == 0) TimeSeries[n].Rdenom = 1e-10;
5275  for (i = 0; i < NUM_AGE_GROUPS; i++)
5276  TimeSeries[n].Rage[i] /= TimeSeries[n].Rdenom;
5277  for (i = 0; i < INFECT_TYPE_MASK; i++)
5278  s += (TimeSeries[n].Rtype[i] /= TimeSeries[n].Rdenom);
5279  TimeSeries[n].Rdenom = s;
5280  }
5281  nf = sizeof(Results) / sizeof(double);
5282  if (!P.DoAdUnits) nf -= MAX_ADUNITS; // TODO: This still processes most of the AdUnit arrays; just not the last one
5283  fprintf(stderr, "extinct=%i (%i)\n", (int) TimeSeries[P.NumSamples - 1].extinct, P.NumSamples - 1);
5284  if (TimeSeries[P.NumSamples - 1].extinct)
5285  {
5286  TSMean = TSMeanE; TSVar = TSVarE; P.NRactE++;
5287  }
5288  else
5289  {
5290  TSMean = TSMeanNE; TSVar = TSVarNE; P.NRactNE++;
5291  }
5292  lc = -k;
5293  for (n = 0; n < P.NumSamples; n++)
5294  {
5295  if ((n + lc >= 0) && (n + lc < P.NumSamples))
5296  {
5297  if (s < TimeSeries[n + lc].incC) { s = TimeSeries[n + lc].incC; t = P.SampleStep * ((double)(n + lc)); }
5298  res = (double*)&TimeSeries[n + lc];
5299  res_av = (double*)&TSMean[n];
5300  res_var = (double*)&TSVar[n];
5301  for (i = 1 /* skip over `t` */; i < nf; i++)
5302  {
5303  res_av[i] += res[i];
5304  res_var[i] += res[i] * res[i];
5305  }
5306  if (TSMean[n].cumTmax < TimeSeries[n + lc].cumT) TSMean[n].cumTmax = TimeSeries[n + lc].cumT;
5307  if (TSMean[n].cumVmax < TimeSeries[n + lc].cumV) TSMean[n].cumVmax = TimeSeries[n + lc].cumV;
5308  }
5309  TSMean[n].t += ((double) n )* P.SampleStep;
5310  }
5311  PeakHeightSum += s;
5312  PeakHeightSS += s * s;
5313  PeakTimeSum += t;
5314  PeakTimeSS += t * t;
5315 }
5316 
5317 
5318 void CalcOriginDestMatrix_adunit()
5319 {
5331 #pragma omp parallel for schedule(static) default(none) \
5332  shared(P, Cells, CellLookup, Mcells, StateT)
5333  for (int tn = 0; tn < P.NumThreads; tn++)
5334  {
5335  for (int i = tn; i < P.NCP; i += P.NumThreads)
5336  {
5337  //reset pop density matrix to zero
5338  double pop_dens_from[MAX_ADUNITS] = {};
5339 
5340  //find index of cell from which flow travels
5341  ptrdiff_t cl_from = CellLookup[i] - Cells;
5342  ptrdiff_t cl_from_mcl = (cl_from / P.nch) * P.NMCL * P.get_number_of_micro_cells_high() + (cl_from % P.nch) * P.NMCL;
5343 
5344  //loop over microcells in these cells to find populations in each admin unit and so flows
5345  for (int k = 0; k < P.NMCL; k++)
5346  {
5347  for (int l = 0; l < P.NMCL; l++)
5348  {
5349  //get index of microcell
5350  ptrdiff_t mcl_from = cl_from_mcl + l + k * P.get_number_of_micro_cells_high();
5351  if (Mcells[mcl_from].n > 0)
5352  {
5353  //get proportion of each population of cell that exists in each admin unit
5354  pop_dens_from[Mcells[mcl_from].adunit] += (((double)Mcells[mcl_from].n) / ((double)Cells[cl_from].n));
5355  }
5356  }
5357  }
5358 
5359  for (int j = i; j < P.NCP; j++)
5360  {
5361  //reset pop density matrix to zero
5362  double pop_dens_to[MAX_ADUNITS] = {};
5363 
5364  //find index of cell which flow travels to
5365  ptrdiff_t cl_to = CellLookup[j] - Cells;
5366  ptrdiff_t cl_to_mcl = (cl_to / P.nch) * P.NMCL * P.get_number_of_micro_cells_high() + (cl_to % P.nch) * P.NMCL;
5367  //calculate distance and kernel between the cells
5368  //total_flow=Cells[cl_from].max_trans[j]*Cells[cl_from].n*Cells[cl_to].n;
5369  double total_flow;
5370  if (j == 0)
5371  {
5372  total_flow = Cells[cl_from].cum_trans[j] * Cells[cl_from].n;
5373  }
5374  else
5375  {
5376  total_flow = (Cells[cl_from].cum_trans[j] - Cells[cl_from].cum_trans[j - 1]) * Cells[cl_from].n;
5377  }
5378 
5379  //loop over microcells within destination cell
5380  for (int m = 0; m < P.NMCL; m++)
5381  {
5382  for (int p = 0; p < P.NMCL; p++)
5383  {
5384  //get index of microcell
5385  ptrdiff_t mcl_to = cl_to_mcl + p + m * P.get_number_of_micro_cells_high();
5386  if (Mcells[mcl_to].n > 0)
5387  {
5388  //get proportion of each population of cell that exists in each admin unit
5389  pop_dens_to[Mcells[mcl_to].adunit] += (((double)Mcells[mcl_to].n) / ((double)Cells[cl_to].n));
5390  }
5391  }
5392  }
5393 
5394  for (int m = 0; m < P.NumAdunits; m++)
5395  {
5396  for (int p = 0; p < P.NumAdunits; p++)
5397  {
5398  if (m != p)
5399  {
5400  double flow = total_flow * pop_dens_from[m] * pop_dens_to[p]; //updated to remove reference to cross-border flows: ggilani 26/03/20
5401  StateT[tn].origin_dest[m][p] += flow;
5402  StateT[tn].origin_dest[p][m] += flow;
5403  }
5404  }
5405  }
5406  }
5407  }
5408  }
5409 
5410  //Sum up flow between adunits across threads
5411  for (int i = 0; i < P.NumAdunits; i++)
5412  {
5413  for (int j = 0; j < P.NumAdunits; j++)
5414  {
5415  for (int k = 0; k < P.NumThreads; k++)
5416  {
5417  AdUnits[i].origin_dest[j] += StateT[k].origin_dest[i][j];
5418  }
5419  }
5420  }
5421 }
5422 
5424 int GetInputParameter (FILE* dat, FILE* dat2, const char* SItemName, const char* ItemType, void* ItemPtr, int NumItem, int NumItem2, int Offset)
5425 {
5426  int FindFlag;
5427 
5428  FindFlag = GetInputParameter2(dat, dat2, SItemName, ItemType, ItemPtr, NumItem, NumItem2, Offset);
5429  if (!FindFlag)
5430  {
5431  ERR_CRITICAL_FMT("\nUnable to find parameter `%s' in input file. Aborting program...\n", SItemName);
5432  }
5433  return FindFlag;
5434 }
5435 int GetInputParameter2(FILE* dat, FILE* dat2, const char* SItemName, const char* ItemType, void* ItemPtr, int NumItem, int NumItem2, int Offset)
5436 {
5437  int FindFlag = 0;
5438 
5439  if (dat2) FindFlag = GetInputParameter3(dat2, SItemName, ItemType, ItemPtr, NumItem, NumItem2, Offset);
5440  if (!FindFlag)
5441  FindFlag = GetInputParameter3(dat, SItemName, ItemType, ItemPtr, NumItem, NumItem2, Offset);
5442  return FindFlag;
5443 }
5444 
5445 /*
5446  Reads a string (as per fscanf %s).
5447  Returns true if it succeeds, false on EOF, and does not return on error.
5448 */
5449 bool readString(const char* SItemName, FILE* dat, char *buf) {
5450  int r = fscanf(dat, "%s", buf);
5451  if(r == 1) {
5452  return true;
5453  } else if (r == EOF) {
5454  if(ferror(dat)) {
5455  ERR_CRITICAL_FMT("fscanf failed for %s: %s.\n", SItemName, strerror(errno));
5456  } else {
5457  // EOF
5458  return false;
5459  }
5460  } else {
5461  ERR_CRITICAL_FMT("Unexpected fscanf result %d for %s.\n", r, SItemName);
5462  }
5463 }
5464 
5465 int GetInputParameter3(FILE* dat, const char* SItemName, const char* ItemType, void* ItemPtr, int NumItem, int NumItem2, int Offset)
5466 {
5467  char match[10000] = "", ReadItemName[10000] = "", ItemName[10000];
5468  int FindFlag = 0, EndString, CurPos, i, j, n;
5469 
5470  n = 0;
5471  fseek(dat, 0, 0);
5472  sprintf(ItemName, "[%s]", SItemName);
5473  while (!FindFlag)
5474  {
5475  if(!readString(SItemName, dat, match)) return 0;
5476  FindFlag = (!strncmp(match, ItemName, strlen(match)));
5477  if (FindFlag)
5478  {
5479  CurPos = ftell(dat);
5480  strcpy(ReadItemName, match);
5481  EndString = (match[strlen(match) - 1] == ']');
5482  while ((!EndString) && (FindFlag))
5483  {
5484  if(!readString(SItemName, dat, match)) return 0;
5485  strcat(ReadItemName, " ");
5486  strcat(ReadItemName, match);
5487  FindFlag = (!strncmp(ReadItemName, ItemName, strlen(ReadItemName)));
5488  EndString = (ReadItemName[strlen(ReadItemName) - 1] == ']');
5489  }
5490  if (!EndString)
5491  {
5492  fseek(dat, CurPos, 0);
5493  FindFlag = 0;
5494  }
5495  }
5496  }
5497  if (FindFlag)
5498  {
5499  FindFlag = 0;
5500  if (!strcmp(ItemType, "%lf")) n = 1;
5501  else if (!strcmp(ItemType, "%i")) n = 2;
5502  else if (!strcmp(ItemType, "%s")) n = 3;
5503  if (NumItem2 < 2)
5504  {
5505  if (NumItem == 1)
5506  {
5507  if(fscanf(dat, "%s", match) != 1) { ERR_CRITICAL_FMT("fscanf failed for %s\n", SItemName); }
5508  if ((match[0] == '#') && (match[1] == '1'))
5509  {
5510  FindFlag++;
5511  if (n == 1)
5512  * ((double*)ItemPtr) = P.clP1;
5513  else if (n == 2)
5514  * ((int*)ItemPtr) = (int)P.clP1;
5515  else if (n == 3)
5516  sscanf(match, "%s", (char*)ItemPtr);
5517  }
5518  else if ((match[0] == '#') && (match[1] == '2'))
5519  {
5520  FindFlag++;
5521  if (n == 1)
5522  * ((double*)ItemPtr) = P.clP2;
5523  else if (n == 2)
5524  * ((int*)ItemPtr) = (int)P.clP2;
5525  else if (n == 3)
5526  sscanf(match, "%s", (char*)ItemPtr);
5527  }
5528  else if((match[0] == '#') && (match[1] == '3'))
5529  {
5530  FindFlag++;
5531  if(n == 1)
5532  * ((double*)ItemPtr) = P.clP3;
5533  else if(n == 2)
5534  * ((int*)ItemPtr) = (int)P.clP3;
5535  else if(n == 3)
5536  sscanf(match, "%s", (char*)ItemPtr);
5537  }
5538  else if((match[0] == '#') && (match[1] == '4'))
5539  {
5540  FindFlag++;
5541  if(n == 1)
5542  * ((double*)ItemPtr) = P.clP4;
5543  else if(n == 2)
5544  * ((int*)ItemPtr) = (int)P.clP4;
5545  else if(n == 3)
5546  sscanf(match, "%s", (char*)ItemPtr);
5547  }
5548  else if((match[0] == '#') && (match[1] == '5'))
5549  {
5550  FindFlag++;
5551  if(n == 1)
5552  * ((double*)ItemPtr) = P.clP5;
5553  else if(n == 2)
5554  * ((int*)ItemPtr) = (int)P.clP5;
5555  else if(n == 3)
5556  sscanf(match, "%s", (char*)ItemPtr);
5557  }
5558  else if((match[0] == '#') && (match[1] == '6'))
5559  {
5560  FindFlag++;
5561  if(n == 1)
5562  * ((double*)ItemPtr) = P.clP6;
5563  else if(n == 2)
5564  * ((int*)ItemPtr) = (int)P.clP6;
5565  else if(n == 3)
5566  sscanf(match, "%s", (char*)ItemPtr);
5567  }
5568  else if ((match[0] != '[') && (!feof(dat)))
5569  {
5570  FindFlag++;
5571  if (n == 1)
5572  sscanf(match, "%lf", (double*)ItemPtr);
5573  else if (n == 2)
5574  sscanf(match, "%i", (int*)ItemPtr);
5575  else if (n == 3)
5576  sscanf(match, "%s", (char*)ItemPtr);
5577  }
5578  }
5579  else
5580  {
5581  for (CurPos = 0; CurPos < NumItem; CurPos++)
5582  {
5583  if(fscanf(dat, "%s", match) != 1) { ERR_CRITICAL_FMT("fscanf failed for %s\n", SItemName); }
5584  if ((match[0] != '[') && (!feof(dat)))
5585  {
5586  FindFlag++;
5587  if (n == 1)
5588  sscanf(match, "%lf", ((double*)ItemPtr) + CurPos + Offset);
5589  else if (n == 2)
5590  sscanf(match, "%i", ((int*)ItemPtr) + CurPos + Offset);
5591  else if (n == 3)
5592  sscanf(match, "%s", *(((char**)ItemPtr) + CurPos + Offset));
5593  }
5594  else
5595  CurPos = NumItem;
5596  }
5597  }
5598  }
5599  else
5600  {
5601  for (j = 0; j < NumItem; j++)
5602  { //added these braces
5603  for (i = 0; i < NumItem2; i++)
5604  {
5605  if(fscanf(dat, "%s", match) != 1) { ERR_CRITICAL_FMT("fscanf failed for %s\n", SItemName); }
5606  if ((match[0] != '[') && (!feof(dat)))
5607  {
5608  FindFlag++;
5609  if (n == 1)
5610  sscanf(match, "%lf", ((double**)ItemPtr)[j + Offset] + i + Offset); //changed from [j+Offset]+i+Offset to +j+Offset+i, as ItemPtr isn't an array - 01/10: changed it back
5611  else
5612  sscanf(match, "%i", ((int**)ItemPtr)[j + Offset] + i + Offset);
5613  }
5614  else
5615  {
5616  i = NumItem2;
5617  j = NumItem;
5618  }
5619  }
5620  //Offset=Offset+(NumItem2-1); //added this line to get the correct offset in address position when incrementing j
5621  } //added these braces
5622  }
5623  }
5624  // fprintf(stderr,"%s\n",SItemName);
5625  return FindFlag;
5626 }
5627 
5628 /* helper function to set icdf arrays */
5629 void SetICDF(double* icdf, double startValue)
5630 {
5631  icdf[CDF_RES] = startValue;
5632  for (int i = 0; i < CDF_RES; i++)
5633  icdf[i] = -log(1 - ((double)i) / CDF_RES);
5634 }
5635 
5636 
5637 
5638 
double DCT_ChangeTimes[MAX_NUM_INTERVENTION_CHANGE_TIMES]
Definition: Param.h:238
int cumMild_adunit[MAX_ADUNITS]
cum incidence quantities. (+ by admin unit)
Definition: Model.h:128
int NumRealisations
Definition: Param.h:35
double Enhanced_SD_SpatialEffects_OverTime[MAX_NUM_INTERVENTION_CHANGE_TIMES]
Definition: Param.h:201
Recorded time-series variables (typically populated from the POPVAR state)
Definition: Model.h:156
double PC_ChangeTimes[MAX_NUM_INTERVENTION_CHANGE_TIMES]
Definition: Param.h:227
The basic unit of the simulation and is associated to a geographical location.
Definition: Model.h:265
Definition: Model.h:15
Airport state.
Definition: Model.h:249
double Mean_MildToRecovery[NUM_AGE_GROUPS]
means for above icdf&#39;s.
Definition: Param.h:93
DomainSize in_microcells_
Size of spatial domain in microcells.
Definition: Param.h:108
double Mild
Definition: Model.h:173
double height_
The height.
Definition: Param.h:24
double HQ_ChangeTimes[MAX_NUM_INTERVENTION_CHANGE_TIMES]
Definition: Param.h:218
Holds microcells.
Definition: Model.h:292
double width_
The width.
Definition: Param.h:21
int NCP
Definition: Param.h:53
The global state of the model.
Definition: Model.h:96
Stores the parameters for the simulation.
Definition: Param.h:31
double SD_ChangeTimes[MAX_NUM_INTERVENTION_CHANGE_TIMES]
Definition: Param.h:194
Represents an institution that people may belong to.
Definition: Model.h:311
int cumMild_age[NUM_AGE_GROUPS]
cum incidence quantities. (+ by age group)
Definition: Model.h:131
A political entity that administers a geographical area.
Definition: Model.h:339
int VaryEfficaciesOverTime
Definition: Param.h:189
double CI_ChangeTimes[MAX_NUM_INTERVENTION_CHANGE_TIMES]
Definition: Param.h:211
int PopSize
Definition: Param.h:33
int NumNonExtinctRealisations
Definition: Param.h:36
DomainSize in_cells_
Size of spatial domain in cells.
Definition: Param.h:107
Definition: Model.h:211
Deprecated intervention mechanism.
Definition: Model.h:328