mrc-ide / covid-sim

This is the COVID-19 CovidSim microsimulation model developed by the MRC Centre for Global Infectious Disease Analysis hosted at Imperial College, London.
GNU General Public License v3.0
1.23k stars 256 forks source link

Relationship between global/local triggers/alerts/interventions #423

Open kevinminors opened 4 years ago

kevinminors commented 4 years ago

Hi all,

I think this is a support question and I know the model is released without support so please feel free to ignore and focus on more pressing matters. I am sure this will be covered in future documentation releases.

If you do have time, I'm just looking for some information on the relationship between the global and local triggers, alerts, and interventions.

I can't quite grasp the logic from the code for the alerts. Is it that when people start dying, an alert goes off. Once that alert goes off, the interventions start happening? How is this represented by the parameters?

For example, what is the link between the parameters "Alert trigger starts after interventions", ""Day of year trigger is reached", "Number of deaths accummulated before alert", and "Day of year interventions start"?

If I want to model the interventions starting the day after the first case is detected, how exactly do I configure these parameters? How do we control when the first case occurs?

Thanks for your help!

WardThomas commented 4 years ago

Hi Kevin, I am not part of the covid-sim team , so don't place too much weight on this answer.

Is it that when people start dying, an alert goes off.

As far As I can see the alerts are not based on people dying rather the main interventions are based on "Detected Cases" or "ICU cases" then later on other interventions or changes in policy are triggered by things like people being off work.

Once that alert goes off, the interventions start happening?

yes the interventions are controlled by the "alerts" , "thresholds", "controls" and "triggers". There isn't a formal differentiation between those words in the code but you can work out most of the variables from the context in the code.

How is this represented by the parameters?

There are three types of "trigger" - which are often linked to a stochastic decision, so reaching the threshold doesn't always result in a change of policy.

There are some comments in the markdown (.md) files and also occasionally in the C code which can be helpful to working out what the triggers are, but be aware that the naming of the parameters don't have a consistent convention so can be a bit confusing.  I have found the text in "Read Params" give some information but some things can only be worked out by following the logic in the code. Note that some parameters are never used.

Triggers The word Trigger and Control and Threshold are used for similar items

Do Switches

what is the link between the parameters  "Alert trigger starts after interventions"   ""Day of year trigger is reached","Number of deaths accumulated before alert",and "Day of year interventions start"?

If I want to model the interventions starting the day after the first case is detected, how exactly do I configure these parameters? How do we control when the first case occurs?  

I don't fully understand what you mean by "model"  , but in general I think you could force an intervention to occur after the first case is detected by setting the threshold to 1. and one of the Proportion variables (usually called .....Prop....) to 1. or 0 as appropriate

How do we control when the first case occurs?   The model is seeded with Initial infections. but the progress is stochastic, you can vary the distribution functions of how infectious and susceptible each age is in different environments

At the end of this reply there is an incomplete partial list of some of the "triggers" - its not super helpful and just grepped out of some python code I am working on but might give you some pointers

regards,

Thomas

Incomplete list of some triggers

self.NumberOfDeathsNeededToTriggerAlert=float(lines[i]);  #P.PreControlClusterIdCaseThreshold 
self.NumberOfDetectedCasesToTriggerAlert  =float(lines[i]);#P.PreControlClusterIdCaseThreshold
self.DayOfYearWhenTriggered  =float(lines[i]);# P.PreControlClusterIdCalTime

if self.DayOfYearWhenTriggered <= self.DayOfYearToStartInterventions:
    self.DoAlertTriggerAfterInterv=0
    P.NumberOfEventsToTriggerAlertAfterInterventionsHaveStarted =max(self.NumberOfDetectedCasesToTriggerAlert, self.NumberOfDeathsNeededToTriggerAlert)# P.AlertTriggerAfterIntervThreshold
    if self.NumberOfDeathsNeededToTriggerAlert>0:self.NumberOfDeathsNeededToTriggerAlert=1000
 else:self.NumberOfDetectedCasesToTriggerAlert=1000

self.IncidentsPerCellToTriggerTreatment=float(lines[i])

self.StartTriggersForAlertAfterInterventions #P.DoAlertTriggerAfterInterv 

self.NumberSampleIntervalsForMeasuringCummulativeIncidence=float(lines[i]);# 1000
self.UseCasesPerThousandToTriggerAreaControl=float(lines[i]);#P.DoPerCapitaTriggers
self.UseGlobalTriggersForInterventions=int(lines[i]); #P.DoGlobalTriggers   
self.UseAdministrationTriggersForInterventions==float(lines[i]);# P.DoAdminTriggers           
self.UseICUcaseToTriggerInterventions=int(lines[i]);# P.DoICUTriggers     

UseCasesPerThousandToTriggerAreaControl=float(lines[i]);#just set the number to be Noneelif l=='[Trigger alert on deaths]'.strip().lower().replace(" ", ""):i+=1;self.=float(lines[i]);
self.NumberOfDeathsNeededToTriggerAlert=float(lines[i]);#PreControlClusterIdCaseThreshold
self.DayOfYearWhenTriggered=float(lines[i]);#PreControlClusterIdCalTime #TODO - is this really day of year?
self.StartTriggersForAlertAfterInterventions=float(lines[i]); # P.DoAlertTriggerAfterInterv
self.IncidentsPerCellToTriggerTreatment=float(lines[i]);  # P.TreatCellIncThresh 
self.UseICUcaseToTriggerInterventions=int(lines[i]);# P.DoICUTriggers 
self.ProportionOfDetectedCasesForAlert =float(lines[i]);#doesn't seem to be ProportionOfCasesToTriggerAlert used for ProportionOfCasesDetected
self.NumberOfDetectedCasesToTriggerAlert=float(lines[i]);

self.NumberOfCasesCloseToPlacesToTriggerClosure[0] =float(lines[i]);#P.PlaceCloseCellIncThresh1 = 1000000000;
self.NumberOfCasesCloseToPlacesToTriggerClosure[1] =float(lines[i]);#P.PlaceCloseCellIncThresh2 = 1000000000;
self.NumberOfCasesCloseToPlacesToAllowOpening[0] =float(lines[i]);#P.PlaceCloseCellIncStopThresh = 0;
self.NumberOfCasesToTriggerClosureOfPlaces[0] =float(lines[i]) # P.PlaceCloseIncTrig1 = 1;
self.NumberOfCasesToTriggerClosureOfPlaces[1]=float(lines[i]) #P.PlaceCloseIncTrig2 = P.PlaceCloseIncTrig1;
self.ProportionOfCasesToTriggerClosureOfPlaces[0] =float(lines[i]) # P.PlaceCloseFracIncTrig = 0; 
self.NumberOfCasesToTriggerRestrictionOfMovements  =float(lines[i]); # P.MoveRestrCellIncThresh 
self.TimeFromTriggerToStartOfRestrictionOfMovements =float(lines[i]); # P.MoveDelayMean 

#Place:
control_trigger =self.NumberOfPeopleAbsentAtTimestep[day] if P.ClosePlacesIfTooManyPeopleAreAbsent else self.numberOfCases;

#Host:
if self.P.DoDigitalContactTracing and self.digitalContactTrace_User and self.digitalContactTrace_trigger_time is None and within_range( self.house.administration.DigitalContactTracingPeriod , self.day_detected)
kevinminors commented 4 years ago

Hey Thomas, Thank you so much for this. This is all really helpful. There's so much here that it may take me some time to work through it. Thanks again! I really appreciate it.

WardThomas commented 4 years ago

No worries Kevin,

I am slowly working my way through understanding the code, if it becomes clearer to me I will try to post some more concise info.

regards