-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfarm_defn.h
365 lines (306 loc) · 10.6 KB
/
farm_defn.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
#ifndef FARM_DEFN_H_INCLUDED
#define FARM_DEFN_H_INCLUDED
#include "const_parameters.h"
#include "Declarations.h"
#include "RandomFuncs.h"
#include "grids.h"
#include "variable_parameters.h"
void ImplementLocalMovementBan(int CentreFarm);
//Declaration of farm class
class farm{
public:
int ID;
int DayOfSim;
int DayOfYear;
double x[2]; //<------ Location of farm in BNG (metres)
double CountyNumber; //CPR county number for farm
//Grid locations for each farm
int TempGrid_x;
int TempGrid_y;
int RainGrid_x;
int RainGrid_y;
int MidgeGrid_x;
int MidgeGrid_y;
int ACGrid_x;
int ACGrid_y;
//Group of Farm local random effects
double V_intercept;
double sin_yearly;
double cos_yearly;
double sin_6_month;
double cos_6_month;
double cos_4_month;
double temp_eff;
double temp_eff_sq;
double rain_eff;
double wind_eff;
double autocorr;
double overdispersion;
double ExtInfBiting;
//Farm demography
double number_of_sheep,number_of_cattle;
double S_sheep;
double I_sheep[NumOfInfStagesSheep];
double R_sheep;
double S_cattle;
double I_cattle[NumOfInfStagesCattle];
double R_cattle;
//Transmission risks
double RelLocalWeight; //The rel weight of the farm against other local farms.
double force; // Rate at which susceptible hosts are infected
std::vector<std::vector<double> > movement_local_farms; // This is a vector list where each element is a non-zero link in contact matrix from farm, element 0 is the direction, element 1 is the risk
//Records of farm incidence
bool Detected; // Detected whether cases exist on farm
bool MovementBanned; //Determines if the farm has been banned from moving animals
bool ProtectionZone;
bool SurveillanceZone;
bool FreeArea;
bool EverBeenDetectedDuringRun;
bool EverBeenInfected; //Determines if the farm has ever had any infected animals
bool FirstInfectedAnimalDueToMovement; //Determines if the first infected animal on farm was due to movement onto the farm
//Each Days' weather effects
double TempToday;
double MeanRainLastWeek;
double WindToday;
//Faster sim stuff
std::vector<int> LocalFarmsID;
//FUNCTIONS FOR LOCAL COUNTS
double NumOfCattle(){
double sum = 0;
for(int i=0;i<NumOfInfStagesCattle;i++)
{
sum += I_cattle[i];
}
return sum + S_cattle + R_cattle;
}
double NumOfSheep(){
double sum = 0;
for(int i=0;i<NumOfInfStagesSheep;i++){
sum += I_sheep[i];
}
return sum + S_sheep + R_sheep;
}
double EffNumOfAnimals(double pref){
return NumOfCattle() + pref*NumOfSheep();
}
double EffNumOfInfAnimals(double pref){
double sum = 0;
for(int i=0;i<NumOfInfStagesSheep;i++){
sum += pref*I_sheep[i];
}
for(int i=0;i<NumOfInfStagesCattle;i++){
sum += I_cattle[i];
}
return sum;
}
double NumOfInfCattle(){
double sum = 0;
for(int i=0;i<NumOfInfStagesCattle;i++){
sum += I_cattle[i];
}
return sum;
}
double NumOfInfSheep(){
double sum = 0;
for(int i=0;i<NumOfInfStagesSheep;i++){
sum += I_sheep[i];
}
return sum;
}
bool SimulateFarmForDay(){
if(EffNumOfInfAnimals(1) > 0){
return true;
}
else{
return false;
}
}
//FUNCTIONS FOR EPIDEMIC EVENTS
// Perform all the events that occur over a day
void AnimalDeathsAndRecoveries(const gsl_rng * r){
double stages;
//~ //Step forward animal recoveries (using ~ hourly 0.04 days^{-1} timestep)
//~ //SHEEP
if(NumOfInfSheep()>0){
//Time-step forwards
stages = double(NumOfInfStagesSheep);
int X;
for(int t =0; double(t*DTFarm) < 1;t++){
X = IntMin(RandPoisson(r,DTFarm*stages*RecRateSheep*I_sheep[NumOfInfStagesSheep-1]),int(I_sheep[NumOfInfStagesSheep-1]));
I_sheep[NumOfInfStagesSheep-1] -= double(X);
R_sheep += double(X);
//Mortality
X = IntMin(RandPoisson(r,DTFarm*SheepMortRate*I_sheep[NumOfInfStagesSheep-1]),int(I_sheep[NumOfInfStagesSheep-1]));
if(X > 0 && !Detected){Detected = true; NumOfFarmsDetectedToday++;
#ifndef NOCONTROL
#ifndef NOFARMBAN
MovementBanned = true;
#endif
ImplementLocalMovementBan(ID);
if(!BTVObserved){
#ifdef VERBOSE
std::cout<<"BTV DETECTED!!! (by sheep death)"<<std::endl;
#endif
BTVObserved = true;
}
#endif
} //Farm detection due to sheep death due to BT
I_sheep[NumOfInfStagesSheep-1] -= X;
NumOfSheepDeaths +=X;
for(int n = NumOfInfStagesSheep-2;n>=0;n--){
X = IntMin(RandPoisson(r,DTFarm*stages*RecRateSheep*I_sheep[n]),int(I_sheep[n]));
I_sheep[n] -=X;
I_sheep[n+1] +=X;
X = IntMin(RandPoisson(r,DTFarm*SheepMortRate*I_sheep[n]),int(I_sheep[n]));
if(X > 0 && !Detected){Detected = true;NumOfFarmsDetectedToday++;
#ifndef NOCONTROL
#ifndef NOFARMBAN
MovementBanned = true;
#endif
ImplementLocalMovementBan(ID);
if(!BTVObserved){
#ifdef VERBOSE
std::cout<<"BTV DETECTED!!! (by sheep death)"<<std::endl;
#endif
BTVObserved = true;
}
#endif
} //Farm detection due to sheep death due to BT
I_sheep[n] -=X;
NumOfSheepDeaths +=X;
}
}
}
//CATTLE
if(NumOfInfCattle()>0){
//Time-step forwards
stages = double(NumOfInfStagesCattle);
int X;
for(int t =0; double(t*DTFarm) < 1;t++){
X = IntMin(RandPoisson(r,DTFarm*stages*RecRateCattle*I_cattle[NumOfInfStagesCattle-1]),int(I_cattle[NumOfInfStagesCattle-1]));
I_cattle[NumOfInfStagesCattle-1] -= double(X);
R_cattle += double(X);
for(int n = NumOfInfStagesCattle-2;n>=0;n--){
X = IntMin(RandPoisson(r,DTFarm*stages*RecRateSheep*I_cattle[n]),int(I_cattle[n]));
I_cattle[n] -=X;
I_cattle[n+1] +=X;
}
}
}
//Detection if not already detected
if(Detected == false){
double CattleNotDetectionProb = exp(NumOfInfCattle()*log(1 - DetectionProb_C));
double SheepNotDetectionProb = exp(NumOfInfSheep()*log(1 - DetectionProb_S));
double rand = RandU(RandGenerator);
//See if detected and ban movement if so
if(rand <= (1 - (CattleNotDetectionProb*SheepNotDetectionProb))){
Detected = true;
NumOfFarmsDetectedToday++;
#ifndef NOCONTROL
#ifndef NOFARMBAN
MovementBanned = true;
#endif
ImplementLocalMovementBan(ID);
if(!BTVObserved){
#ifdef VERBOSE
std::cout<<"BTV DETECTED!!!"<<std::endl;
#endif
BTVObserved = true;
FirstDetectedFarmID = ID;
}
#endif
}
}
}
void GetWeatherToday(){
TempToday = TempGrid[TempGrid_y][TempGrid_x][SimulationDay];
WindToday = 0;
MeanRainLastWeek = RainGrid[RainGrid_y][RainGrid_x][SimulationDay];
autocorr = 0.0;//ACGrid[ACGrid_y][ACGrid_x];
overdispersion = (1.08 + 0.3763)*RandN(RandGenerator);
}
//Calculate condition average number of infected midges
void TransmissionHostsToMidges(){
//Expected number of bites per Host
double MeanNumOfInfectedMidges, MeanNumBitesPerAnimal;
double doy = double(SimulationDay);
double climate_component;
//~ if(SimulationDay%365 >60 && SimulationDay%365 <330){
//~ climate_component = V_intercept; //Base
//~ climate_component += sin_yearly*sin(2*PI*doy/365.25) + cos_yearly*cos(2*PI*doy/365.25); //Yearly variation
//~ climate_component += sin_6_month*sin(4*PI*doy/365.25) + cos_6_month*cos(4*PI*doy/365.25);//6 month variation
//~ climate_component += cos_4_month*cos(6*PI*doy/365.25);//4 month variation
//~ climate_component += temp_eff*TempToday + temp_eff_sq*TempToday*TempToday; //Temperature driven abundance
//~ climate_component += overdispersion + autocorr; //Overdisperion and temporal autocorrelation
//~ //Get expected number biting insects from the general population per animal
//~ MeanNumBitesPerAnimal = TransmissionScalar*exp(climate_component);
//~ if(MeanNumBitesPerAnimal > 5000){MeanNumBitesPerAnimal = 5000;}
//~ }
//~ else{
//~ MeanNumBitesPerAnimal = 0;
//~ }
if(SimulationDay%365 >60 && SimulationDay%365 <330){
climate_component = V_intercept; //Base
climate_component += sin_yearly*sin(2*PI*doy/365.25) + cos_yearly*cos(2*PI*doy/365.25); //Yearly variation
climate_component += sin_6_month*sin(4*PI*doy/365.25) + cos_6_month*cos(4*PI*doy/365.25);//6 month variation
climate_component += cos_4_month*cos(6*PI*doy/365.25);//4 month variation
climate_component += temp_eff*TempToday + temp_eff_sq*TempToday*TempToday; //Temperature driven abundance
climate_component += overdispersion + autocorr; //Overdisperion and temporal autocorrelation
//Get expected number biting insects from the general population per animal
MeanNumBitesPerAnimal = TransmissionScalar*exp(climate_component);
if(MeanNumBitesPerAnimal > 5000){MeanNumBitesPerAnimal = 5000;}
}
else{
MeanNumBitesPerAnimal = 0;
}
MeanNumOfInfectedMidges = P_V*EffNumOfInfAnimals(PreferenceForSheep)*MeanNumBitesPerAnimal; //Mean number midges inoculated
//Introduce new latent vectors
LatentMidgeDensity[MidgeGrid_y][MidgeGrid_x][0] += MeanNumOfInfectedMidges;
}
//~ //Number of sucessfully infectious bites on animals
void TransmissionMidgesToHosts(const gsl_rng * r){
double biting_rate = BitingRate(TempToday);
double BitingProb = (1 - exp((-1)*biting_rate));
force = RelLocalWeight*InfMidgeDensity[MidgeGrid_y][MidgeGrid_x]*BitingProb;
int A,B;
double ProbBitePerSheep = PreferenceForSheep/EffNumOfAnimals(PreferenceForSheep);
double ProbBitePerCattle = 1/EffNumOfAnimals(PreferenceForSheep);
double ProbInfectionPerSheep = 1 - exp((-1)*force*ProbBitePerSheep*P_H );
double ProbInfectionPerCattle = 1 - exp((-1)*force*ProbBitePerCattle*P_H );
//~ //Use poisson approximation if appropriate
if((S_sheep > 100 && ProbInfectionPerSheep < 0.01) && S_sheep*ProbInfectionPerSheep < 20){
A = IntMin(RandPoisson(r,S_sheep*ProbInfectionPerSheep),int(S_sheep));
}
else{
A = RandBinomial(r,int(S_sheep),ProbInfectionPerSheep);
}
if((S_cattle > 100 && ProbInfectionPerCattle < 0.01) && S_cattle*ProbInfectionPerCattle < 20){
B = IntMin(RandPoisson(r,S_cattle*ProbInfectionPerCattle),int(S_cattle));
}
else{
B = RandBinomial(r,int(S_cattle),ProbInfectionPerCattle);
}
S_sheep -= A; I_sheep[0] += A; NumberOfSheepInfectedToday += A;
S_cattle -= B; I_cattle[0] +=B; NumberOfCattleInfectedToday += B;
}
//~ //FUNCTIONS FOR PRINTING
void PrintState(){
std::cout<<"FARM "<<ID<<" on day of year "<<DayOfYear%365 + 1<<" ("<<DayOfSim<<")"<<std::endl;
std::cout<<"S_C = "<<S_cattle<<", I_C = "<<NumOfInfCattle()<<", R_C = "<<R_cattle<<std::endl;
std::cout<<"S_S = "<<S_sheep<<", I_S = "<<NumOfInfSheep()<<", R_S = "<<R_sheep<<std::endl;
std::cout<<"Temp = "<<TempToday<<", mean rainfall = "<<MeanRainLastWeek<<std::endl;
}
};
//Declare and array of pointers to the farm types
farm* farms[N];
double DistSqBetweenFarms(int ID1,int ID2){
return (farms[ID1]->x[0] - farms[ID2]->x[0])*(farms[ID1]->x[0] - farms[ID2]->x[0]) + (farms[ID1]->x[1] - farms[ID2]->x[1])*(farms[ID1]->x[1] - farms[ID2]->x[1]);
}
void FindLocalFarms(int CentreFarmID){
for(int k = 0; k<N ; k++){
if(k != CentreFarmID && DistSqBetweenFarms(k,CentreFarmID) < BanRadius*BanRadius){
farms[CentreFarmID]->LocalFarmsID.push_back(k);
}
}
}
#endif