ALMaSS Vole ODDox  1.1
The vole model description following ODdox protocol
seedgrass1.cpp
Go to the documentation of this file.
1 //
2 // seedgrass1.cpp
3 //
4 /*
5 *******************************************************************************************************
6 Copyright (c) 2011, Christopher John Topping, Aarhus University
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/seedgrass1.h"
30 
31 extern CfgFloat cfg_ins_app_prop1;
32 extern CfgFloat cfg_herbi_app_prop;
33 extern CfgFloat cfg_fungi_app_prop1;
34 extern CfgFloat cfg_greg_app_prop;
35 
36 bool SeedGrass1::Do( Farm *a_farm, LE *a_field, FarmEvent *a_ev )
37 {
38  // NB IF SEED GRASS IS USED IN A ROTATION IT MUST FOLLOW AN UNDERSOWN CROP!!!
39 
40  m_farm = a_farm;
41  m_field = a_field;
42  m_ev = a_ev;
43 
44  bool done = false;
45 
46  switch ( m_ev->m_todo ) {
47  case sg1_start:
48  {
49  // End date checking block.
50  SG1_WATER_DATE = g_date->Date();
51  SG1_FUNGI_DATE = g_date->Date();
53  // Set up the date management stuff
54  m_last_date=g_date->DayInYear(15,8);
55  // Start and stop dates for all events after harvest
56  int noDates= 4;
57  m_field->SetMDates(0,0,g_date->DayInYear(10,7));
58  // Determined by harvest date - used to see if at all possible
59  m_field->SetMDates(1,0,g_date->DayInYear(20,7));
60  m_field->SetMDates(0,1,g_date->DayInYear(11,7));
61  m_field->SetMDates(1,1,g_date->DayInYear(25,7));
62  m_field->SetMDates(0,2,g_date->DayInYear(26,7));
63  m_field->SetMDates(1,2,g_date->DayInYear(20,7));
64  m_field->SetMDates(0,3,g_date->DayInYear(15,7));
65  m_field->SetMDates(1,3,g_date->DayInYear(15,8));
66  // Check the next crop for early start, unless it is a spring crop
67  // in which case we ASSUME that no checking is necessary!!!!
68  // So DO NOT implement a crop that runs over the year boundary
69 
70  //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)
71  int d1;
72  if(!(m_farm->GetType() == tof_OptimisingFarm && g_date->GetYearNumber()>0)){
73 
74  if (m_ev->m_startday>g_date->DayInYear(1,7))
75  {
76  if (m_field->GetMDates(0,0) >=m_ev->m_startday)
77  {
78  g_msg->Warn( WARN_BUG, "SeedGrass1::Do(): "
79  "Harvest too late for the next crop to start!!!", "" );
80  exit( 1 );
81  }
82  // Now fix any late finishing problems
83  for (int i=0; i<noDates; i++) {
84  if(m_field->GetMDates(0,i)>=m_ev->m_startday) {
85  m_field->SetMDates(0,i,m_ev->m_startday-1); //move the starting date
86  }
87  if(m_field->GetMDates(1,i)>=m_ev->m_startday){
88  m_field->SetMConstants(i,0);
89  m_field->SetMDates(1,i,m_ev->m_startday-1); //move the finishing date
90  }
91  }
92  }
93  // Now no operations can be timed after the start of the next crop.
94 
95  int today=g_date->Date();
96  d1 = g_date->OldDays() + m_first_date;
97  if ( ! m_ev->m_first_year ) d1+=365; // Add 365 for spring crop (not 1st yr)
98  if (today > d1)
99  {
100  // Yes too late - should not happen - raise an error
101  g_msg->Warn( WARN_BUG, "SeedGrass1::Do(): "
102  "Crop start attempt after last possible start date", "" );
103  exit( 1 );
104  }
105  }//if
106 
107  // Reinit d1 to first possible starting date.
108  d1 = g_date->OldDays() + m_first_date+365; // Add 365 for spring crop
109  if ( g_date->Date() > d1 ) {
110  d1 = g_date->Date();
111  }
112  m_field->SetLastSownVeg( m_field->GetVegType() ); //Force last sown, needed for goose habitat classification
113  // OK, let's go.
114  SimpleEvent( d1, sg1_ferti_zero, false );
115  break;
116  }
117 
118  case sg1_ferti_zero:
119  if ( m_ev->m_lock || m_farm->DoIt( 60 )) {
120  if (!m_farm->FP_NPK( m_field, 0.0,
121  g_date->DayInYear( 15, 4 ) -
122  g_date->DayInYear())) {
123  SimpleEvent( g_date->Date() + 1, sg1_ferti_zero, true );
124  break;
125  }
126  }
127  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 15, 4 ),
128  sg1_herbi_zero, false );
129  break;
130 
131  case sg1_herbi_zero:
132  if ( m_ev->m_lock || m_farm->DoIt( (int) (75*cfg_herbi_app_prop.value() * m_farm->Prob_multiplier()))) { //modified probability
133 
134  //new - for decision making
135  TTypesOfVegetation tov = m_field->GetVegType();
136  if(!m_ev->m_lock && !m_farm->Spraying_herbicides(tov)){
137  Field * pf = dynamic_cast<Field*>(m_field);
138  pf->Add_missed_herb_app();
139  if(m_farm->DoIt(67)) pf->Add_missed_herb_app(); //the 2nd missed application
141  } //end of the part for dec. making
142  else{
143  if (!m_farm->HerbicideTreat( m_field, 0.0, g_date->DayInYear( 25, 4 ) - g_date->DayInYear())) {
144  SimpleEvent( g_date->Date() + 1, sg1_herbi_zero, true );
145  break;
146  }
147  }
148  }
149  SimpleEvent( g_date->OldDays() + g_date->DayInYear() + 14,
150  sg1_herbi_one, false );
151  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 20, 5 ),
152  sg1_fungi_zero, false );
153  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 15, 5 ),
154  sg1_water_zero, false );
155  break;
156 
157  case sg1_herbi_one:
158  if ( m_ev->m_lock || m_farm->DoIt( (int) (67*cfg_herbi_app_prop.value() * SG1_DECIDE_TO_HERB * m_farm->Prob_multiplier()))) { //modified probability
159  if (!m_farm->HerbicideTreat( m_field, 0.0, g_date->DayInYear( 25, 4 ) - g_date->DayInYear())) {
160  SimpleEvent( g_date->Date() + 1, sg1_herbi_zero, true );
161  break;
162  }
163  }
164  break;
165 
166  case sg1_fungi_zero:
167  if ( m_ev->m_lock || m_farm->DoIt( (int) (17 * m_farm->Prob_multiplier()))) { //modified probability
168 
169  //new - for decision making
170  TTypesOfVegetation tov = m_field->GetVegType();
171  if(!m_ev->m_lock && !m_farm->Spraying_fungins(tov)){
172  Field * pf = dynamic_cast<Field*>(m_field);
173  pf->Add_missed_fi_app();
174  break;
175  } //end of the part for dec. making
176 
177  if ( SG1_WATER_DATE > g_date->Date() - 2 && SG1_WATER_DATE < g_date->Date() + 2 ) {
178  SimpleEvent( g_date->Date() + 1, sg1_fungi_zero, true );
179  break;
180  }
181  if ( !m_farm->FungicideTreat( m_field, 0.0, g_date->DayInYear( 1, 6 ) - g_date->DayInYear())) {
182  SimpleEvent( g_date->Date() + 1, sg1_fungi_zero, true );
183  break;
184  }
185  SG1_FUNGI_DATE = g_date->Date();
186  }
187  // End of thread.
188  break;
189 
190  case sg1_water_zero:
191  if ( m_ev->m_lock || m_farm->DoIt( 70 )) {
192  if ( SG1_FUNGI_DATE > g_date->Date() - 2 &&
193  SG1_FUNGI_DATE < g_date->Date() + 2 ) {
194  SimpleEvent( g_date->Date() + 1, sg1_water_zero, true );
195  break;
196  }
197  if ( !m_farm->Water( m_field, 0.0,
198  g_date->DayInYear( 30, 5 ) -
199  g_date->DayInYear())) {
200  SimpleEvent( g_date->Date() + 1, sg1_water_zero, true );
201  break;
202  }
203  SG1_WATER_DATE = g_date->Date();
204  {
205  int d1 = g_date->Date() + 7;
206  if ( d1 > g_date->OldDays() + g_date->DayInYear( 1, 6 ))
207  d1 = g_date->OldDays() + g_date->DayInYear( 1, 6 );
208  SimpleEvent( d1, sg1_water_zero_b, true );
209  break;
210  }
211  }
212  // Didn't do first water, so skip the second one too.
213  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 10, 7 ),
214  sg1_swarth, false );
215  break;
216 
217  case sg1_water_zero_b:
218  if ( m_ev->m_lock ) {
219  if ( SG1_FUNGI_DATE > g_date->Date() - 2 &&
220  SG1_FUNGI_DATE < g_date->Date() + 2 ) {
221  SimpleEvent( g_date->Date() + 1, sg1_water_zero_b, true );
222  break;
223  }
224  if ( !m_farm->Water( m_field, 0.0,
225  g_date->DayInYear( 30, 6 ) -
226  g_date->DayInYear())) {
227  SimpleEvent( g_date->Date() + 1, sg1_water_zero_b, true );
228  break;
229  }
230  SG1_WATER_DATE = g_date->Date();
231  }
232  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 10, 7 ),
233  sg1_swarth, false );
234  break;
235 
236  case sg1_swarth:
237  if ( m_ev->m_lock || m_farm->DoIt( 5 )) {
238  if ( !m_farm->Swathing( m_field, 0.0,
239  g_date->DayInYear( 15, 7 ) -
240  g_date->DayInYear())) {
241  SimpleEvent( g_date->Date() + 1, sg1_swarth, true );
242  break;
243  }
244  ChooseNextCrop (4);
245  SimpleEvent( g_date->Date() + 2, sg1_harvest, false );
246  break;
247  }
248 
249  ChooseNextCrop (4);
250 
251  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 10, 7 ), sg1_harvest, false );
252  break;
253 
254  case sg1_harvest:
255  if (m_field->GetMConstants(0)==0) {
256  if (!m_farm->Harvest( m_field, 0.0, -1)) { //raise an error
257  g_msg->Warn( WARN_BUG, "SeedGrass1::Do(): failure in 'Harvest' execution", "" );
258  exit( 1 );
259  }
260  }
261  else {
262  if ( !m_farm->Harvest( m_field, 0.0, m_field->GetMDates(1,0) - g_date->DayInYear())) {
263  SimpleEvent( g_date->Date() + 1, sg1_harvest, false );
264  break;
265  }
266  }
267 
268  SimpleEvent( g_date->Date(), sg1_strawchopping, false );
269  break;
270 
271  case sg1_strawchopping:
272  if ( m_ev->m_lock || m_farm->DoIt( 30 )) {
273  if (m_field->GetMConstants(0)==0) {
274  if (!m_farm->StrawChopping( m_field, 0.0, -1)) { //raise an error
275  g_msg->Warn( WARN_BUG, "SeedGrass1::Do(): failure in 'StrawChopping' execution", "" );
276  exit( 1 );
277  }
278  }
279  else {
280  if ( !m_farm->StrawChopping( m_field, 0.0, m_field->GetMDates(1,0) - g_date->DayInYear())) {
281  SimpleEvent( g_date->Date() + 1, sg1_strawchopping, true );
282  break;
283  }
284  }
285  done = true;
286  break;
287  }
288 
289  {
290  int d1 = g_date->Date()+1;
291  int d2 = g_date->OldDays() + m_field->GetMDates(0,1);
292  if (d1>d2) d1=d2;
293  SimpleEvent( d1, sg1_compress, false );
294  }
295  break;
296 
297  case sg1_compress:
298  if ( m_ev->m_lock || m_farm->DoIt( 60 )) {
299  if (m_field->GetMConstants(1)==0) {
300  if (!m_farm->HayTurning( m_field, 0.0, -1)) { //raise an error
301  g_msg->Warn( WARN_BUG, "SeedGrass1::Do(): failure in 'HayTurning' execution", "" );
302  exit( 1 );
303  }
304  }
305  else {
306  if ( !m_farm->HayTurning( m_field, 0.0, m_field->GetMDates(1,1) - g_date->DayInYear())) {
307  SimpleEvent( g_date->Date() + 1, sg1_compress, true );
308  break;
309  }
310  }
311  }
312  {
313  int d1 = g_date->Date();
314  if ( d1 < g_date->OldDays() + m_field->GetMDates(0,3))
315  d1 = g_date->OldDays() + m_field->GetMDates(0,3);
316  SimpleEvent( d1, sg1_burn_straw, false );
317  }
318  break;
319 
320  case sg1_burn_straw:
321  if ( m_ev->m_lock || m_farm->DoIt( 60 )) {
322  if (m_field->GetMConstants(3)==0) {
323  if (!m_farm->BurnStrawStubble( m_field, 0.0, -1)) { //raise an error
324  g_msg->Warn( WARN_BUG, "SeedGrass1::Do(): failure in 'BurnStrawStubble' execution", "" );
325  exit( 1 );
326  }
327  }
328  else {
329  if ( !m_farm->BurnStrawStubble( m_field, 0.0,m_field->GetMDates(1,3) - g_date->DayInYear())) {
330  SimpleEvent( g_date->Date() + 1, sg1_burn_straw, true );
331  break;
332  }
333  }
334  }
335  done = true;
336  break;
337 
338  default:
339  g_msg->Warn( WARN_BUG, "SeedGrass1::Do(): "
340  "Unknown event type! ", "" );
341  exit( 1 );
342  }
343 
344  return done;
345 }
346 
347 
sg1_ferti_zero
Definition: seedgrass1.h:37
sg1_water_zero
Definition: seedgrass1.h:41
sg1_water_zero_b
Definition: seedgrass1.h:42
Farm::HerbicideTreat
virtual bool HerbicideTreat(LE *a_field, double a_user, int a_days)
Apply herbicide to a_field.
Definition: farmfuncs.cpp:1156
SG1_WATER_DATE
#define SG1_WATER_DATE
Definition: OSeedGrass1.h:31
Farm::Harvest
virtual bool Harvest(LE *a_field, double a_user, int a_days)
Carry out a harvest on a_field.
Definition: farmfuncs.cpp:1769
FarmEvent::m_lock
bool m_lock
Definition: farm.h:465
sg1_strawchopping
Definition: seedgrass1.h:45
cfg_fungi_app_prop1
CfgFloat cfg_fungi_app_prop1
FarmEvent
A struct to hold the information required to trigger a farm event.
Definition: farm.h:463
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
SG1_FUNGI_DATE
#define SG1_FUNGI_DATE
Definition: seedgrass1.h:32
FarmEvent::m_first_year
bool m_first_year
Definition: farm.h:467
tof_OptimisingFarm
Definition: farm.h:273
Farm::GetType
TTypesOfFarm GetType(void)
Definition: farm.h:901
Crop::m_first_date
int m_first_date
Definition: farm.h:540
FarmEvent::m_startday
int m_startday
Definition: farm.h:466
sg1_herbi_zero
Definition: seedgrass1.h:38
cfg_greg_app_prop
CfgFloat cfg_greg_app_prop
Farm::FungicideTreat
virtual bool FungicideTreat(LE *a_field, double a_user, int a_days)
Apply fungicide to a_field.
Definition: farmfuncs.cpp:1279
Crop::SimpleEvent
void SimpleEvent(long a_date, int a_todo, bool a_lock)
Adds an event to this crop management.
Definition: farm.cpp:307
SG1_DECIDE_TO_HERB
#define SG1_DECIDE_TO_HERB
Definition: seedgrass1.h:33
Farm::Prob_multiplier
virtual double Prob_multiplier()
Definition: farm.h:786
sg1_start
Definition: seedgrass1.h:36
sg1_fungi_zero
Definition: seedgrass1.h:40
SeedGrass1::Do
bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
Definition: seedgrass1.cpp:36
TTypesOfVegetation
TTypesOfVegetation
Definition: tov_declaration.h:30
Farm::Spraying_herbicides
virtual bool Spraying_herbicides(TTypesOfVegetation)
Definition: farm.h:784
sg1_harvest
Definition: seedgrass1.h:44
Farm::StrawChopping
virtual bool StrawChopping(LE *a_field, double a_user, int a_days)
Carry out straw chopping on a_field.
Definition: farmfuncs.cpp:2132
sg1_compress
Definition: seedgrass1.h:46
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
sg1_swarth
Definition: seedgrass1.h:43
Farm::Water
virtual bool Water(LE *a_field, double a_user, int a_days)
Carry out a watering on a_field.
Definition: farmfuncs.cpp:1717
Crop::m_last_date
int m_last_date
Definition: farm.h:542
cfg_ins_app_prop1
CfgFloat cfg_ins_app_prop1
cfg_herbi_app_prop
CfgFloat cfg_herbi_app_prop
Farm
The base class for all farm types.
Definition: farm.h:767
sg1_burn_straw
Definition: seedgrass1.h:47
Farm::BurnStrawStubble
virtual bool BurnStrawStubble(LE *a_field, double a_user, int a_days)
Burn stubble on a_field.
Definition: farmfuncs.cpp:2236
Farm::Swathing
virtual bool Swathing(LE *a_field, double a_user, int a_days)
Cut the crop on a_field and leave it lying (probably rape)
Definition: farmfuncs.cpp:1744
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
Crop::m_ev
FarmEvent * m_ev
Definition: farm.h:539
sg1_herbi_one
Definition: seedgrass1.h:39
Farm::Spraying_fungins
virtual bool Spraying_fungins(TTypesOfVegetation)
Definition: farm.h:785