ALMaSS Hare ODDox  1.1
The hare model description following ODdox protocol
PermanentGrassGrazed.cpp
Go to the documentation of this file.
1 //
2 // PermanentGrassGrazed.cpp
3 //
4 /*
5 *******************************************************************************************************
6 Copyright (c) 2011, Christopher John Topping, University of Aarhus
7 All rights reserved.
8 
9 Redistribution and use in source and binary forms, with or without modification, are permitted provided
10 that the following conditions are met:
11 
12 Redistributions of source code must retain the above copyright notice, this list of conditions and the
13 following disclaimer.
14 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
15 the following disclaimer in the documentation and/or other materials provided with the distribution.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
20 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 ********************************************************************************************************
26 */
27 
28 #include "../../Landscape/ls.h"
29 #include "../../Landscape/cropprogs/PermanentGrassGrazed.h"
30 
31 
32 extern CfgFloat cfg_ins_app_prop1;
33 extern CfgFloat cfg_herbi_app_prop;
34 extern CfgFloat cfg_fungi_app_prop1;
35 extern CfgFloat cfg_greg_app_prop;
36 
37 bool PermanentGrassGrazed::Do( Farm *a_farm, LE *a_field, FarmEvent *a_ev )
38 {
39  m_farm = a_farm;
40  m_field = a_field;
41  m_ev = a_ev;
42 
43  int d1;
44 
45  bool done = false;
46 
47  switch ( m_ev->m_todo ) {
48  case pgg_start:
49  {
50  PGG_CUT_DATE =0;
52  // Set up the date management stuff
53  m_last_date=g_date->DayInYear(1,10);
54  // Start and stop dates for all events after harvest
55  int noDates= 1;
56  // Start and stop dates for all events after harvest
57  m_field->SetMDates(0,0,g_date->DayInYear(15,9));
58  // 0,0 determined by harvest date - used to see if at all possible
59  m_field->SetMDates( 1, 0, g_date->DayInYear(1,10) );
60  // Check the next crop for early start, unless it is a spring crop
61  // in which case we ASSUME that no checking is necessary!!!!
62  // So DO NOT implement a crop that runs over the year boundary
63 
64  //new if: do the check only for non-optimising farms and if year>0. (030713 - m_rotation used only in the hidden year, so I modified the condition from >7 to >0)
65  if(!(m_farm->GetType() == tof_OptimisingFarm && g_date->GetYearNumber()>0)){
66 
67  if (m_ev->m_startday>g_date->DayInYear(1,7))
68  {
69  if (m_field->GetMDates(0,0) >=m_ev->m_startday)
70  {
71  g_msg->Warn( WARN_BUG, "PermanentGrassGrazed::Do(): "
72  "Harvest too late for the next crop to start!!!", "" );
73  exit( 1 );
74  }
75  // Now fix any late finishing problems
76  for (int i=0; i<noDates; i++) {
77  if(m_field->GetMDates(0,i)>=m_ev->m_startday) {
78  m_field->SetMDates(0,i,m_ev->m_startday-1); //move the starting date
79  }
80  if(m_field->GetMDates(1,i)>=m_ev->m_startday){
81  m_field->SetMConstants(i,0);
82  m_field->SetMDates(1,i,m_ev->m_startday-1); //move the finishing date
83  }
84  }
85  }
86  // Now no operations can be timed after the start of the next crop.
87  int today=g_date->Date();
88  d1 = g_date->OldDays() + m_first_date+365; // Add 365 for spring crop
89  if (today > d1)
90  {
91  // Yes too late - should not happen - raise an error
92  g_msg->Warn( WARN_BUG, " PermanentGrassGrazed::Do(): "
93  "Crop start attempt after last possible start date", "" );
94  exit( 1 );
95  }
96  }//if
97 
98  // Reinit d1 to first possible starting date.
99  d1 = g_date->OldDays()+m_first_date;;
100  if ( ! m_ev->m_first_year ) d1+=365; // Add 365 for spring crop (not 1st yr)
101  if ( g_date->Date() > d1 ) {
102  d1 = g_date->Date();
103  }
104  // OK, let's go.
105  m_field->SetLastSownVeg( m_field->GetVegType() ); //Force last sown, needed for goose habitat classification
106 
107  if (m_farm->IsStockFarmer())
108  SimpleEvent(d1, pgg_ferti_s, false );
109  else
110  SimpleEvent(d1, pgg_ferti_p, false );
111  }
112  break;
113 
114  case pgg_ferti_s:
115  if ( m_ev->m_lock || m_farm->DoIt( 80 ))
116  {
117  if (!m_farm->FA_NPK( m_field, 0.0,
118  g_date->DayInYear( 15,6 ) - g_date->DayInYear())) {
119  SimpleEvent( g_date->Date() + 1, pgg_ferti_s, true );
120  break;
121  }
122  else PGG_FERTI_DATE=g_date->DayInYear();
123  }
124  SimpleEvent( g_date->Date() + 28,pgg_cut_to_hay, false );
125  break;
126 
127  case pgg_ferti_p:
128  if ( m_ev->m_lock || m_farm->DoIt( 70 ))
129  {
130  if (!m_farm->FP_NPK( m_field, 0.0,
131  g_date->DayInYear( 15,6 ) - g_date->DayInYear())) {
132  SimpleEvent( g_date->Date() + 1, pgg_ferti_p, true );
133  break;
134  }
135  else PGG_FERTI_DATE=g_date->DayInYear();
136  }
137  SimpleEvent( g_date->Date() + 28, pgg_cut_to_hay, false );
138  break;
139 
140  case pgg_cut_to_hay:
141  if ( m_ev->m_lock || m_farm->DoIt( 70 ))
142  {
143  if (!m_farm->CutToHay( m_field, 0.0,
144  g_date->DayInYear( 15,8 ) - g_date->DayInYear())) {
145  SimpleEvent( g_date->Date() + 1, pgg_cut_to_hay, true );
146  break;
147  }
148  // did cut to hay so try turning
149  else
150  {
151  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 15,6 ),
152  pgg_raking1, false );
153  PGG_CUT_DATE=g_date->Date();
154  }
155  break;
156  }
157  if (PGG_FERTI_DATE+28 < g_date->DayInYear( 15, 6 ))
158  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 15, 6 ),
159  pgg_cattle_out2, false ); // 80% of non-cutters graze
160  else
161  SimpleEvent( g_date->OldDays() + PGG_FERTI_DATE+28,
162  pgg_cattle_out2, false ); // 80% of non-cutters graze
163 
164  break;
165 
166  case pgg_raking1:
167  if (PGG_CUT_DATE+20>=g_date->Date()) m_ev->m_lock=true;
168  if ( m_ev->m_lock || m_farm->DoIt( 50 ))
169  {
170  if (!m_farm->HayTurning( m_field, 0.0,
171  g_date->DayInYear( 15,8 ) - g_date->DayInYear()))
172  {
173  SimpleEvent( g_date->Date() + 1, pgg_raking1, true );
174  break;
175  }
176  SimpleEvent( g_date->Date()+1, pgg_raking2, false );
177  break;
178  }
179  // Did cut but not rake
180  // --FN--
181 
182  ChooseNextCrop (1);
183 
185  // 100% of these graze
186  break;
187 
188  case pgg_raking2:
189  if ( m_ev->m_lock || m_farm->DoIt( 25 ))
190  {
191  if (!m_farm->HayTurning( m_field, 0.0,
192  g_date->DayInYear( 16,8 ) - g_date->DayInYear())) {
193  SimpleEvent( g_date->Date() + 1, pgg_raking2, true );
194  break;
195  }
196  }
197  SimpleEvent( g_date->Date() + 1, pgg_compress_straw, false );
198  break;
199 
200  case pgg_compress_straw:
201  if (!m_farm->HayBailing( m_field, 0.0,
202  g_date->DayInYear( 17,8 ) - g_date->DayInYear()))
203  {
204  SimpleEvent( g_date->Date() + 1, pgg_compress_straw, true );
205  break;
206  }
207  // Did compress straw
208 
209  ChooseNextCrop (1);
210 
211  SimpleEvent( g_date->Date() + 21,
212  pgg_cattle_out1, false ); // cut but no straw so 100% graze
213  break;
214 
215  case pgg_cattle_out1:
216  if (m_field->GetMConstants(0)==0) {
217  if (!m_farm->CattleOut( m_field, 0.0, -1)) { //raise an error
218  g_msg->Warn( WARN_BUG, "PermanentGrassGrazed::Do(): failure in 'CattleOut' execution", "" );
219  exit( 1 );
220  }
221  }
222  else {
223  if (!m_farm->CattleOut( m_field, 0.0, m_field->GetMDates(1,0) - g_date->DayInYear())) {
224  SimpleEvent( g_date->Date() + 1, pgg_cattle_out1, true );
225  break;
226  }
227  }
228  SimpleEvent( g_date->Date() + m_field->GetMConstants(0), pgg_cattle_is_out, false );
229  break;
230 
231  case pgg_cattle_out2:
232  if (( m_ev->m_lock || m_farm->DoIt( 33 )) || (PGG_FERTI_DATE!=0)) {
233  if (m_field->GetMConstants(0)==0) {
234  if (!m_farm->CattleOut( m_field, 0.0, -1)) { //raise an error
235  g_msg->Warn( WARN_BUG, "PermanentGrassGrazed::Do(): failure in 'CattleOut' execution", "" );
236  exit( 1 );
237  }
238  }
239  else {
240  if (!m_farm->CattleOut( m_field, 0.0, m_field->GetMDates(1,0) - g_date->DayInYear())) {
241  SimpleEvent( g_date->Date() + 1, pgg_cattle_out2, true );
242  break;
243  }
244  }
245  // Success
246  SimpleEvent( g_date->Date() + m_field->GetMConstants(0), pgg_cattle_is_out, false );
247  break;
248  }
249  //Don't graze - but don't end too early;
250  SimpleEvent( g_date->OldDays() +g_date->DayInYear(2,7), pgg_wait, false );
251  break;
252 
253  case pgg_wait:
254  done=true;
255  break;
256 
257  case pgg_cattle_is_out:
258  if (m_field->GetMConstants(0)==0) {
259  if (!m_farm->CattleIsOut( m_field, 0.0, -1, m_field->GetMDates(1,0))) { //raise an error
260  //added 28.08 - issue a warning only if we fail on the last day that this can be done, i.e. MDate
261  if(g_date->Date() == m_field->GetMDates(1,0)){
262  g_msg->Warn( WARN_BUG, "PermanentGrassGrazed::Do(): failure in 'CattleIsOut' execution", "" );
263  exit( 1 );
264  }
265  }
266  }
267  else {
268  if (!m_farm->CattleIsOut( m_field, 0.0, m_field->GetMDates(1,0) - g_date->DayInYear(), m_field->GetMDates(1,0))){
269  SimpleEvent( g_date->Date() + 1, pgg_cattle_is_out, true );
270  break;
271  }
272  }
273  // if they come in then send them out if too early
274  if (g_date->DayInYear()<g_date->DayInYear(10,9))
275  {
276  SimpleEvent( g_date->Date()+1, pgg_cattle_out2, true );
277  break;
278  }
279  SimpleEvent( g_date->OldDays() +g_date->DayInYear(15,6), pgg_herbicide, false );
280  break;
281 
282  case pgg_herbicide:
283  if (( m_ev->m_lock || m_farm->DoIt( (int) (5*cfg_herbi_app_prop.value() * m_farm->Prob_multiplier()))) && //modified probability
284  // --FN--
285  (g_date->DayInYear()<g_date->DayInYear(15,8)))
286  {
287  //new - for decision making
288  TTypesOfVegetation tov = m_field->GetVegType();
289  if(!m_ev->m_lock && !m_farm->Spraying_herbicides(tov)){
290  Field * pf = dynamic_cast<Field*>(m_field);
291  pf->Add_missed_herb_app();
292  } //end of the part for dec. making
293  else{
294  if (!m_farm->HerbicideTreat( m_field, 0.0, g_date->DayInYear( 15,8 ) - g_date->DayInYear())) {
295  // --FN--
296  SimpleEvent( g_date->Date() + 1, pgg_herbicide, true );
297  break;
298  }
299  }
300  }
301  SimpleEvent( g_date->OldDays() + g_date->DayInYear(15,8),
302  pgg_cut_weeds, false );
303  break;
304 
305  case pgg_cut_weeds:
306  if (( m_ev->m_lock || m_farm->DoIt( 25 ))&&
307  //--FN--
308  (g_date->DayInYear()<g_date->DayInYear(15,9)))
309  {
310  if (!m_farm->CutWeeds( m_field, 0.0,
311  g_date->DayInYear( 15,9 ) - g_date->DayInYear())) {
312  // --FN--
313  SimpleEvent( g_date->Date() + 1, pgg_cut_weeds, true );
314  break;
315  }
316  }
317  // END MAIN THREAD
318  done = true;
319  break;
320 
321  default:
322  g_msg->Warn( WARN_BUG, "PermanantGrassGrazed::Do(): "
323  "Unknown event type! ", "" );
324  exit( 1 );
325  }
326 
327  return done;
328 }
329 
330 
Farm::HerbicideTreat
virtual bool HerbicideTreat(LE *a_field, double a_user, int a_days)
Apply herbicide to a_field.
Definition: farmfuncs.cpp:1156
Farm::IsStockFarmer
bool IsStockFarmer(void)
Definition: farm.h:905
FarmEvent::m_lock
bool m_lock
Definition: farm.h:465
pgg_cut_weeds
Definition: PermanentGrassGrazed.h:41
FarmEvent
A struct to hold the information required to trigger a farm event.
Definition: farm.h:463
pgg_cut_to_hay
Definition: PermanentGrassGrazed.h:37
Farm::CattleIsOut
virtual bool CattleIsOut(LE *a_field, double a_user, int a_days, int a_max)
Generate a 'cattle_out' event for every day the cattle are on a_field.
Definition: farmfuncs.cpp:1974
Farm::FP_NPK
virtual bool FP_NPK(LE *a_field, double a_user, int a_days)
Apply NPK fertilizer, on a_field owned by an arable farmer.
Definition: farmfuncs.cpp:629
Farm::DoIt
bool DoIt(double a_probability)
Return chance out of 0 to 100.
Definition: farm.cpp:800
cfg_fungi_app_prop1
CfgFloat cfg_fungi_app_prop1
FarmEvent::m_first_year
bool m_first_year
Definition: farm.h:467
tof_OptimisingFarm
Definition: farm.h:273
pgg_cattle_out1
Definition: PermanentGrassGrazed.h:38
Farm::GetType
TTypesOfFarm GetType(void)
Definition: farm.h:901
Farm::CutToHay
virtual bool CutToHay(LE *a_field, double a_user, int a_days)
Carry out hay cutting on a_field.
Definition: farmfuncs.cpp:2269
Crop::m_first_date
int m_first_date
Definition: farm.h:540
FarmEvent::m_startday
int m_startday
Definition: farm.h:466
Farm::FA_NPK
virtual bool FA_NPK(LE *a_field, double a_user, int a_days)
Apply NPK fertilizer to a_field owned by an stock farmer.
Definition: farmfuncs.cpp:917
Crop::SimpleEvent
void SimpleEvent(long a_date, int a_todo, bool a_lock)
Adds an event to this crop management.
Definition: farm.cpp:307
Farm::Prob_multiplier
virtual double Prob_multiplier()
Definition: farm.h:786
cfg_herbi_app_prop
CfgFloat cfg_herbi_app_prop
TTypesOfVegetation
TTypesOfVegetation
Definition: tov_declaration.h:30
Farm::Spraying_herbicides
virtual bool Spraying_herbicides(TTypesOfVegetation)
Definition: farm.h:784
cfg_ins_app_prop1
CfgFloat cfg_ins_app_prop1
Farm::HayBailing
virtual bool HayBailing(LE *a_field, double a_user, int a_days)
Carry out hay bailing on a_field.
Definition: farmfuncs.cpp:2184
pgg_ferti_s
Definition: PermanentGrassGrazed.h:43
pgg_compress_straw
Definition: PermanentGrassGrazed.h:47
pgg_raking1
Definition: PermanentGrassGrazed.h:45
pgg_wait
Definition: PermanentGrassGrazed.h:48
pgg_cattle_is_out
Definition: PermanentGrassGrazed.h:40
Crop::m_farm
Farm * m_farm
Definition: farm.h:537
Crop::m_field
LE * m_field
Definition: farm.h:538
FarmEvent::m_todo
int m_todo
Definition: farm.h:469
pgg_raking2
Definition: PermanentGrassGrazed.h:46
Crop::m_last_date
int m_last_date
Definition: farm.h:542
Farm
The base class for all farm types.
Definition: farm.h:767
PermanentGrassGrazed::Do
bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
Definition: PermanentGrassGrazed.cpp:37
pgg_herbicide
Definition: PermanentGrassGrazed.h:42
PGG_CUT_DATE
#define PGG_CUT_DATE
Definition: PermanentGrassGrazed.h:32
pgg_cattle_out2
Definition: PermanentGrassGrazed.h:39
pgg_start
Definition: PermanentGrassGrazed.h:36
Crop::ChooseNextCrop
void ChooseNextCrop(int a_no_dates)
Chooses the next crop to grow in a field.
Definition: farm.cpp:318
Farm::HayTurning
virtual bool HayTurning(LE *a_field, double a_user, int a_days)
Carry out hay turning on a_field.
Definition: farmfuncs.cpp:2159
PGG_FERTI_DATE
#define PGG_FERTI_DATE
Definition: PermanentGrassGrazed.h:33
Crop::m_ev
FarmEvent * m_ev
Definition: farm.h:539
Farm::CattleOut
virtual bool CattleOut(LE *a_field, double a_user, int a_days)
Start a grazing event on a_field today.
Definition: farmfuncs.cpp:1910
pgg_ferti_p
Definition: PermanentGrassGrazed.h:44
cfg_greg_app_prop
CfgFloat cfg_greg_app_prop
Farm::CutWeeds
virtual bool CutWeeds(LE *a_field, double a_user, int a_days)
Carry out weed topping on a_field.
Definition: farmfuncs.cpp:2303