ALMaSS Hare ODDox  1.1
The hare model description following ODdox protocol
HareForagenPeg.cpp
Go to the documentation of this file.
1 /*
2 *******************************************************************************************************
3 Copyright (c) 2011, Christopher John Topping, University of Aarhus
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided
7 that the following conditions are met:
8 
9 Redistributions of source code must retain the above copyright notice, this list of conditions and the
10 following disclaimer.
11 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
12 the following disclaimer in the documentation and/or other materials provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
17 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
19 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 ********************************************************************************************************
23 */
24 //---------------------------------------------------------------------------
25 
26 #include <cmath>
27 #include <iostream>
28 #include <fstream>
29 #ifdef __UNIX
30 #undef max
31 #endif
32 #include "../Landscape/ls.h"
33 #include "../BatchALMaSS/PopulationManager.h"
34 #include "../Hare/hare_all.h"
35 
36 #include "../BatchALMaSS/BoostRandomGenerators.h"
37 extern boost::variate_generator<base_generator_type&, boost::uniform_real<> > g_rand_uni;
38 
39 //---------------------------------------------------------------------------
40 
41 extern CfgFloat cfg_hare_ExtEff;
42 extern double g_hare_peg_inertia;
43 extern double g_FarmIntensiveness;
44 
45 CfgInt cfg_hare_pegmoveto_chance("HARE_PEGMOVETOCHANCE", CFG_CUSTOM, 250000);
46 CfgFloat cfg_hare_pesticide_contact_exposure_rate("HARE_PESTICIDE_CONTACT_RATE", CFG_CUSTOM, 0.0);
47 CfgFloat cfg_hare_pesticide_ingestion_exposure_rate("HARE_PESTICIDE_INGESTION_RATE", CFG_CUSTOM, 0.0);
48 #define __FSQRS 10
49 
50 //---------------------------------------------------------------------------
51 // THARE CODE
52 //---------------------------------------------------------------------------
53 
54 double THare::Forage(int &a_time)
55 {
64  #define __SQRS 100 // __SQRS is the number of m2 foraged per forage square
65  int y_add[8] = { -10, -10, 0, 10, 10, 10, 0, -10 }; // N,NE,E,SE,S,SW,W,NW
66  int x_add[8] = { 0, 10, 10, 10, 0, -10, -10, -10 }; // N,NE,E,SE,S,SW,W,NW
67  unsigned next=0;
68  double food[8];
69  int bestsquare = 0;
77  // Get the top corner of our square
78  int x=m_Location_x;
79  int y=m_Location_y;
80  // Search central square
81  double TotalFood = ForageSquare(x,y); // this calls walking automatically
82  a_time -= __SQRS;
83  EnergyBalance(activity_Foraging, __SQRS * 5); // Assume a 20cm swath, therefore distance = 5 * m2
84  if ((a_time - __SQRS)<0)
85  {
86  return TotalFood;
87  }
88  // Set up searching for the next 8 squares around this one
89  food[0]=0;
90  int equal=0;
91  double best=-1;
92  for (int i=0; i<8; i++)
93  {
94  x = m_Location_x+x_add[i];
95  y = m_Location_y+y_add[i];
96  food[i]=ForageSquare(x,y);
97  if (food[i]>best) {
98  best=food[i];
99  equal=0;
100  bestsquare=i;
101  } else if (food[i]==best)
102  {
103  equal++;
104  }
105  }
106  if (equal>0)
107  {
108  // No real direction to move in, so go towards our peg if this is OK
109  unsigned pd=(GetPegDirection());
110  // Our normal directions are 0-7 N,NE,E,SE,S,SW,W,NW //
111  if (food[pd]== best) bestsquare=pd;
112  else {
113  pd= (pd-1) & 0x07;
114  if (food[pd]== best) bestsquare=pd;
115  else {
116  // First check the directions
117  bestsquare=-1;
118  while (bestsquare==-1)
119  {
120  int t=random(8);
121  if (food[t]==best) bestsquare=t;
122  }
123  }
124  }
125  }
126  // Now move to the next square, also the best in food return
127  a_time -= __SQRS;
129  Walking(10, bestsquare);
130  TotalFood+=food[bestsquare];
131  if (TotalFood>=m_EnergyMax)
132  {
133  return TotalFood;
134  }
135  // OK now dependent upon the direction bestsquare, we need to check 3 or 5 new squares for food
136  while (a_time>0)
137  {
138  int nsqs;
139  int subtract=1+(bestsquare & 1);
140  if ( subtract == 1) nsqs = 3; else nsqs = 5;
141  for (int j=0; j<nsqs; j++) {
142  next=((bestsquare-subtract)+j) & 7;
143  x = m_Location_x+x_add[next];
144  y = m_Location_y+y_add[next];
145  food[j]=ForageSquare(x,y);
146  TotalFood+=food[j];
147  a_time -= __SQRS;
149  }
150  // Choose the best
151  int found=0;
152  //bestsquare=0;
153  for (int j=1; j<nsqs; j++) {
154  if (food[j]>food[found]) found=j;
155  else if (food[j]==food[found]) {
156  if (random(3)==0) {
157  found=j;
158  }
159  }
160  }
161  bestsquare=((bestsquare-subtract)+found) & 7;
162  if (GetPegPull()> random(cfg_hare_pegmoveto_chance.value()))
163  {
164  bestsquare=(GetPegDirection());
165  // Our normal directions are 0-7 N,NE,E,SE,S,SW,W,NW
166  }
167  //
168  Walking(10,bestsquare);
169  if (TotalFood>m_EnergyMax) {
170  return TotalFood;
171  }
172  }
173  if (TotalFood > m_EnergyMax)
174  {
175  TotalFood = m_EnergyMax;
176  }
177  return TotalFood;
178 }
179 //---------------------------------------------------------------------------
180 
181 double THare::ForageP(int &a_time)
182 {
194  #define __SQRS 100 // __SQRS is the number of m2 foraged per forage square
195  int y_add[8] = { -10, -10, 0, 10, 10, 10, 0, -10 }; // N,NE,E,SE,S,SW,W,NW
196  int x_add[8] = { 0, 10, 10, 10, 0, -10, -10, -10 }; // N,NE,E,SE,S,SW,W,NW
197  unsigned next = 0;
198  double food[8];
199  double pesticide[8];
200  int bestsquare = 0;
208  // Get the top corner of our square
209  int x = m_Location_x;
210  int y = m_Location_y;
211  // Search central square
212  double PesticideExposure = 0.0;
213  double TotalFood = ForageSquareP(x, y, &PesticideExposure); // this calls walking automatically
214  a_time -= __SQRS;
215  EnergyBalance(activity_Foraging, __SQRS * 5); // Assume a 20cm swath, therefore distance = 5 * m2
216  if ((a_time - __SQRS)<0)
217  {
218  m_pesticide_burden += PesticideExposure;
219  return TotalFood;
220  }
221  // Set up searching for the next 8 squares around this one
222  food[0] = 0;
223  int equal = 0;
224  double best = -1;
225  double tempP;
226  for (int i = 0; i<8; i++)
227  {
228  x = m_Location_x + x_add[i];
229  y = m_Location_y + y_add[i];
230  tempP = 0.0;
231  food[i] = ForageSquareP(x, y, &tempP);
232  pesticide[i] = tempP;
233  if (food[i]>best) {
234  best = food[i];
235  equal = 0;
236  bestsquare = i;
237  }
238  else if (food[i] == best)
239  {
240  equal++;
241  }
242  }
243  if (equal>0)
244  {
245  // No real direction to move in, so go towards our peg if this is OK
246  unsigned pd = (GetPegDirection());
247  // Our normal directions are 0-7 N,NE,E,SE,S,SW,W,NW //
248  if (food[pd] == best) bestsquare = pd;
249  else {
250  pd = (pd - 1) & 0x07;
251  if (food[pd] == best) bestsquare = pd;
252  else {
253  // First check the directions
254  bestsquare = -1;
255  while (bestsquare == -1)
256  {
257  int t = random(8);
258  if (food[t] == best) bestsquare = t;
259  }
260  }
261  }
262  }
263  // Now move to the next square, also the best in food return
264  Walking(10, bestsquare);
265  a_time -= __SQRS;
267  TotalFood += food[bestsquare];
268  PesticideExposure += pesticide[bestsquare];
269  if (TotalFood >= m_EnergyMax)
270  {
271  m_pesticide_burden += PesticideExposure;
272  return TotalFood;
273  }
274  // OK now dependent upon the direction bestsquare, we need to check 3 or 5 new squares for food
275  while (a_time>0)
276  {
277  int nsqs;
278  int subtract = 1 + (bestsquare & 1);
279  if (subtract == 1) nsqs = 3; else nsqs = 5;
280  for (int j = 0; j<nsqs; j++) {
281  next = ((bestsquare - subtract) + j) & 7;
282  x = m_Location_x + x_add[next];
283  y = m_Location_y + y_add[next];
284  food[j] = ForageSquareP(x, y, &PesticideExposure);
285  TotalFood += food[j];
286  a_time -= __SQRS;
288  }
289  // Choose the best
290  int found = 0;
291  //bestsquare=0;
292  for (int j = 1; j<nsqs; j++) {
293  if (food[j]>food[found]) found = j;
294  else if (food[j] == food[found]) {
295  if (random(3) == 0) {
296  found = j;
297  }
298  }
299  }
300  bestsquare = ((bestsquare - subtract) + found) & 7;
301  if (GetPegPull()> random(cfg_hare_pegmoveto_chance.value()))
302  {
303  bestsquare = (GetPegDirection());
304  // Our normal directions are 0-7 N,NE,E,SE,S,SW,W,NW
305  }
306  //
307  Walking(10, bestsquare);
308  if (TotalFood>m_EnergyMax) {
309  m_pesticide_burden += PesticideExposure;
310  return TotalFood;
311  }
312  }
313  if (TotalFood > m_EnergyMax)
314  {
315  TotalFood = m_EnergyMax;
316  }
317  m_pesticide_burden += PesticideExposure;
318  return TotalFood;
319 }
320 //---------------------------------------------------------------------------
321 
322 double THare::ForageSquare(int a_x, int a_y)
323 {
324  int polyref;
325  double food=0.0;
328  // Do the search and return the value
329  // Now we need the irritating boundary check
330  if ((a_x >= sw-10) || (a_y > sh-10) || (a_x < 0 ) || (a_y < 0))
331  {
332  // We check __FSQRS% of the cell and assume that the hare can find forage matching the best square
333  for (int i=0; i<__FSQRS; i++)
334  {
335  // Here is the boundary check
336  int x = (sw+a_x+random(10)) % sw;
337  int y = (sh+a_y+random(10)) % sh;
338  // All OK now, so get the polygon information and food
339  polyref=m_OurLandscape->SupplyPolyRef(x,y);
340  double f=m_OurPopulationManager->GetPolyFood(polyref);
341  if (f==-1.0)
342  {
345  }
346  food+=f; //Changed foraging methods - now find the best sample cell and assume the whole square is this good - allows focus in foraging
347  //if (f > food) food = f;
348 
349  }
350  } else
351  {
352  for (int i=0; i<__FSQRS; i++)
353  {
354  int x = a_x+random(10);
355  int y = a_y+random(10);
356  polyref=m_OurLandscape->SupplyPolyRef(x,y);
357  double f=m_OurPopulationManager->GetPolyFood(polyref);
358  if (f==-1.0)
359  {
362  }
363  food+=f; //Changed foraging methods - now find the best sample cell and assume the whole square is this good - allows focus in foraging
364  //if (f > food) food = f;
365  }
366  }
367  return food * 10 * cfg_hare_ExtEff.value(); // Assume they eat from all 100 m2 at this rate
368 }
369 //---------------------------------------------------------------------------
370 
371 
372 double THare::ForageSquareP(int a_x, int a_y, double * a_pesticideexposure)
373 {
374  int polyref;
375  double somepesticide = 0.0;
376  double food = 0.0;
379  // Do the search and return the value
380  // Now we need the irritating boundary check
381  if ((a_x >= sw - 10) || (a_y > sh - 10) || (a_x < 0) || (a_y < 0))
382  {
383  // We check __FSQRS% of the cell and assume that the hare can find forage matching the best square
384  for (int i = 0; i<__FSQRS; i++)
385  {
386  // Here is the boundary check
387  int x = (sw + a_x + random(10)) % sw;
388  int y = (sh + a_y + random(10)) % sh;
389  // All OK now, so get the polygon information and food
390  polyref = m_OurLandscape->SupplyPolyRef(x, y);
391  somepesticide += m_OurLandscape->SupplyPesticideP(x, y, ppp_1);
392  double f = m_OurPopulationManager->GetPolyFood(polyref);
393  if (f == -1.0)
394  {
396  m_OurPopulationManager->SetPolyFood(polyref, f);
397  }
398  food += f; //Changed foraging methods - now find the best sample cell and assume the whole square is this good - allows focus in foraging
399  }
400  }
401  else
402  {
403  for (int i = 0; i<__FSQRS; i++)
404  {
405  int x = a_x + random(10);
406  int y = a_y + random(10);
407  polyref = m_OurLandscape->SupplyPolyRef(x, y);
408  somepesticide += m_OurLandscape->SupplyPesticideP(x, y, ppp_1);
409  double f = m_OurPopulationManager->GetPolyFood(polyref);
410  if (f == -1.0)
411  {
413  m_OurPopulationManager->SetPolyFood(polyref, f);
414  }
415  food += f;
416  }
417  }
418  // somepesticide now has the pesticide exposure in units per 10m2, but we need 100m and there are two routes with different rates of intake, so first X10
419  somepesticide *= 10;
420  // contact exposure
421  (*a_pesticideexposure) += somepesticide * cfg_hare_pesticide_contact_exposure_rate.value();
422  // ingestion exposure
423  (*a_pesticideexposure) += somepesticide * cfg_hare_pesticide_ingestion_exposure_rate.value();
424  return food * 10 * cfg_hare_ExtEff.value(); // Assume they eat from all 100 m2 at this rate
425 }
426 //---------------------------------------------------------------------------
427 
428 
429 //---------------------------------------------------------------------------
430 //---------------------------------------------------------------------------
431 // Peg Related Code
432 //---------------------------------------------------------------------------
433 //---------------------------------------------------------------------------
434 
436 {
444  int d1=abs(m_Location_x-m_peg_x);
445  if (d1 > (int) m_OurPopulationManager->SimWH) d1 = abs(d1-m_OurPopulationManager->SimW);
446  int d2=abs(m_Location_y-m_peg_y);
447  if (d2 > (int) m_OurPopulationManager->SimHH) d2 = abs(d2-m_OurPopulationManager->SimH);
448  return d1+d2;
449 }
450 
451 inline int THare::GetPegPull()
452 {
456  int d = GetPegDistance();
457  return d*d;
458 }
459 
461 {
469  int d1 = m_Location_x - m_peg_x;
470  int d2 = m_Location_y - m_peg_y;
471  if ((d1 == 0) && (d2 == 0)) return random(8);
472  if (abs(d1) > (int)m_OurPopulationManager->SimWH)
473  {
474  if (d1<0)
475  {
476  if ( abs(d2) > (int) m_OurPopulationManager->SimHH)
477  {
478  if (d2<0) return 7; //NW;
479  else return 5; //SW;
480  }
481  else
482  {
483  if (d2<0) return 5; //SW;
484  else return 7; //NW;
485  }
486  }
487  else
488  {
489  if ( abs(d2) > (int) m_OurPopulationManager->SimHH) {
490  if (d2<0) return 1; //NE;
491  else return 3; //SE;
492  }
493  else {
494  if (d2<0) return 3; //SE;
495  else return 1; //NE;
496  }
497  }
498  }
499  else
500  {
501  if (d1<0)
502  {
503  if ( abs(d2) > (int) m_OurPopulationManager->SimHH)
504  {
505  if (d2<0) return 1; //NE;
506  else return 3; //SE;
507  }
508  else {
509  if (d2<0) return 3; //SE;
510  else return 1; //NE;
511  }
512  }
513  else {
514  if ( abs(d2) > (int) m_OurPopulationManager->SimHH) {
515  if (d2<0) return 7; //NW;
516  else return 5; //SW;
517  }
518  else {
519  if (d2<0) return 5; //SW;
520  else return 7; //NW;
521  }
522  }
523  }
524 }
525 
526 
528 {
534  //
535  // Find the distance between the peg & x,y and add a fixed proportion to move peg
536  int d1=(m_Location_x-m_peg_x);
537  if (abs(d1)< (int) m_OurPopulationManager->SimWH) m_peg_x += int(d1*g_hare_peg_inertia); // Global used for speed
538  else {
539  if (d1<0) d1+=m_OurPopulationManager->SimWH; else d1-=m_OurPopulationManager->SimWH;
540  m_peg_x += int(d1*g_hare_peg_inertia);
541  }
542  d1=(m_Location_y-m_peg_y);
543  if (abs(d1)< (int) m_OurPopulationManager->SimHH) m_peg_y += int(d1*g_hare_peg_inertia);
544  else {
545  if (d1<0) d1+=m_OurPopulationManager->SimHH; else d1-=m_OurPopulationManager->SimHH;
546  m_peg_y += int(d1*g_hare_peg_inertia);
547  }
548  }
549  //-------------------------------------------------------------------------------------------------------------------------
550 
552  {
556  m_pesticide_burden *= m_pesticidedegradationrate; // Does nothing by default except internal degredation of the pesticide
557  }
558  //-------------------------------------------------------------------------------------------------------------------------
559 
THare_Population_Manager::SetPolyFood
void SetPolyFood(int a_poly, double a_value)
Set polygon food quality.
Definition: Hare_all.h:718
THare::m_vegPalatability
static double * m_vegPalatability
Will hold and array of palatability for hare for each tov type. Most are 1, but unpalatable vegetatio...
Definition: Hare_all.h:318
Landscape::SupplyVegType
TTypesOfVegetation SupplyVegType(int a_x, int a_y)
Definition: Landscape.h:1321
cfg_hare_pesticide_ingestion_exposure_rate
CfgFloat cfg_hare_pesticide_ingestion_exposure_rate("HARE_PESTICIDE_INGESTION_RATE", CFG_CUSTOM, 0.0)
THare::GetPegDirection
int GetPegDirection()
Get direction of peg.
Definition: HareForagenPeg.cpp:460
THare::m_pesticidedegradationrate
double m_pesticidedegradationrate
State variable used to hold the daily degredation rate of the pesticide in the body.
Definition: Hare_all.h:306
THare::m_EnergyMax
double m_EnergyMax
State variable - the amount of energy it is possible to eat as a multiplyer or RMR.
Definition: Hare_all.h:223
Population_Manager::SimWH
unsigned SimWH
Definition: PopulationManager.h:512
TAnimal::m_OurLandscape
Landscape * m_OurLandscape
Definition: PopulationManager.h:229
__SQRS
#define __SQRS
cfg_hare_ExtEff
CfgFloat cfg_hare_ExtEff
THare::InternalPesticideHandlingAndResponse
virtual void InternalPesticideHandlingAndResponse()
Handles internal effects of pesticide exposure. If any effects are needed this method must be re-impl...
Definition: HareForagenPeg.cpp:551
Population_Manager::SimHH
unsigned SimHH
Definition: PopulationManager.h:512
THare::ForageSquare
double ForageSquare(int a_x, int a_y)
Forage from an area.
Definition: HareForagenPeg.cpp:322
THare::m_OurPopulationManager
THare_Population_Manager * m_OurPopulationManager
Pointer to the hare population manager.
Definition: Hare_all.h:194
THare::Forage
double Forage(int &time)
Foraging.
Definition: HareForagenPeg.cpp:54
Population_Manager::SimW
int SimW
Definition: PopulationManager.h:511
THare::GetPegDistance
int GetPegDistance()
Get peg distance.
Definition: HareForagenPeg.cpp:435
__FSQRS
#define __FSQRS
Definition: HareForagenPeg.cpp:48
Landscape::SupplySimAreaHeight
int SupplySimAreaHeight(void)
Definition: Landscape.h:1637
activity_Foraging
Definition: Hare_all.h:92
Landscape::SupplySimAreaWidth
int SupplySimAreaWidth(void)
Definition: Landscape.h:1632
TAnimal::m_Location_y
int m_Location_y
Definition: PopulationManager.h:228
THare::Walking
void Walking(int a_dist, int a_direction)
Walking.
Definition: Hare_THare.cpp:183
THare::MovePeg
void MovePeg()
Move the peg according to attraction forces.
Definition: HareForagenPeg.cpp:527
g_FarmIntensiveness
double g_FarmIntensiveness
Definition: Hare_all.cpp:283
THare::EnergyBalance
void EnergyBalance(TTypeOfActivity a_activity, int dist)
Adjust energy balance for an activity.
Definition: Hare_THare.cpp:277
ppp_1
Definition: farm.h:422
THare::ForageSquareP
double ForageSquareP(int a_x, int a_y, double *a_pestexposure)
Forage from an area and resturn pesticide exposure as well as food.
Definition: HareForagenPeg.cpp:372
THare::m_pesticide_burden
double m_pesticide_burden
State variable used to hold the current body-burden of pesticide.
Definition: Hare_all.h:301
Landscape::SupplyPesticideP
double SupplyPesticideP(int a_x, int a_y, PlantProtectionProducts a_ppp)
Gets plant pesticide for a location.
Definition: Landscape.cpp:605
THare::ForageP
double ForageP(int &time)
Foraging but also incorporating pesticide exposure.
Definition: HareForagenPeg.cpp:181
Population_Manager::SimH
int SimH
Definition: PopulationManager.h:511
THare_Population_Manager::GetPolyFood
double GetPolyFood(int a_poly)
Get stored polygon food quality.
Definition: Hare_all.h:713
cfg_hare_pesticide_contact_exposure_rate
CfgFloat cfg_hare_pesticide_contact_exposure_rate("HARE_PESTICIDE_CONTACT_RATE", CFG_CUSTOM, 0.0)
g_rand_uni
boost::variate_generator< base_generator_type &, boost::uniform_real<> > g_rand_uni
cfg_hare_pegmoveto_chance
CfgInt cfg_hare_pegmoveto_chance("HARE_PEGMOVETOCHANCE", CFG_CUSTOM, 250000)
THare::GetPegPull
int GetPegPull()
Get attractive force of peg.
Definition: HareForagenPeg.cpp:451
THare::m_peg_y
int m_peg_y
peg y-coordinate
Definition: Hare_all.h:260
TAnimal::m_Location_x
int m_Location_x
Definition: PopulationManager.h:225
Landscape::SupplyPolyRef
int SupplyPolyRef(int a_x, int a_y)
Definition: Landscape.h:1488
THare::m_peg_x
int m_peg_x
peg x-coordinate
Definition: Hare_all.h:256
g_hare_peg_inertia
double g_hare_peg_inertia
Definition: Hare_all.cpp:50
Landscape::GetHareFoodQuality
double GetHareFoodQuality(int a_polygon)
Definition: Landscape.cpp:3403