ALMaSS Vole ODDox  1.1
The vole model description following ODdox protocol
MaizeSilage.cpp
Go to the documentation of this file.
1 //
2 // MaizeSilage.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/MaizeSilage.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 MaizeSilage::Do( Farm *a_farm, LE *a_field, FarmEvent *a_ev )
37 {
38  m_farm = a_farm;
39  m_field = a_field;
40  m_ev = a_ev;
41  int d1=0;
42 
43  bool done = false;
44  switch ( m_ev->m_todo ) {
45  case ms_start:
46  {
49  // Set up the date management stuff
50  m_last_date=g_date->DayInYear(30,9);
51  // Start and stop dates for all events after harvest
52  int noDates= 2;
53  m_field->SetMDates(0,0,g_date->DayInYear(1,9));
54  // 0,0 determined by harvest date - used to see if at all possible
55  m_field->SetMDates(1,0,g_date->DayInYear(10,9));
56  m_field->SetMDates(0,1,g_date->DayInYear(15,9));
57  m_field->SetMDates(1,1,g_date->DayInYear(30,9));
58  // Check the next crop for early start, unless it is a spring crop
59  // in which case we ASSUME that no checking is necessary!!!!
60  // So DO NOT implement a crop that runs over the year boundary
61 
62  //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)
63  if(!(m_farm->GetType() == tof_OptimisingFarm && g_date->GetYearNumber()>0)){
64 
65  if (m_ev->m_startday>g_date->DayInYear(1,7))
66  {
67  if (m_field->GetMDates(0,0) >=m_ev->m_startday)
68  {
69  char veg_type[ 20 ];
70  //char farm_no[20];
71  //sprintf (farm_no, "%d", m_almass_no);
72  sprintf( veg_type, "%d", m_ev->m_next_tov );
73  g_msg->Warn( WARN_FILE, "MaizeSilage::Do(): Harvest too late for the next crop to start!!! The next crop is: ", veg_type);
74 
75  //g_msg->Warn( WARN_BUG, "MaizeSilage::Do(): Harvest too late for the next crop to start!!!", "" );
76  exit( 1 );
77  }
78  // Now fix any late finishing problems
79  for (int i=0; i<noDates; i++) {
80  if(m_field->GetMDates(0,i)>=m_ev->m_startday) {
81  m_field->SetMDates(0,i,m_ev->m_startday-1); //move the starting date
82  }
83  if(m_field->GetMDates(1,i)>=m_ev->m_startday){
84  m_field->SetMConstants(i,0);
85  m_field->SetMDates(1,i,m_ev->m_startday-1); //move the finishing date
86  }
87  }
88  }
89  // Now no operations can be timed after the start of the next crop.
90 
91  if ( ! m_ev->m_first_year )
92  {
93  int today=g_date->Date();
94  // Are we before July 1st?
95  d1 = g_date->OldDays() + g_date->DayInYear( 1,7 );
96  if (today < d1)
97  {
98  // Yes, too early. We assumme this is because the last crop was late
99  g_msg->Warn( WARN_BUG, "MaizeSilage::Do(): "
100  "Crop start attempt between 1st Jan & 1st July", "" );
101  exit( 1 );
102  }
103  else
104  {
105  d1 = g_date->OldDays() + m_first_date; // Add 365 for spring crop
106  if (today > d1)
107  {
108  // Yes too late - should not happen - raise an error
109  g_msg->Warn( WARN_BUG, "MaizeSilage::Do(): "
110  "Crop start attempt after last possible start date", "" );
111  exit( 1 );
112  }
113  }
114  }
115  else
116  {
117  SimpleEvent( g_date->OldDays() + g_date->DayInYear(25,4),
118  ms_spring_plough, false );
119  break;
120  }
121  }//if
122 
123  // End single block date checking code. Please see next line
124  // comment as well.
125  // Reinit d1 to first possible starting date.
126  d1 = g_date->OldDays() + m_first_date; // Add 365 for spring crop
127  if ( g_date->Date() > d1 ) {
128  d1 = g_date->Date();
129  }
130  // OK, let's go.
131  if ( m_farm->DoIt( 50 ))
132  {
133  SimpleEvent( d1, ms_fa_manure_a, false );
134  }
135  else
136  {
137  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 20, 3 ) + 365,
138  ms_fa_manure_b, false );
139  }
140  break;
141  }
142 
143  case ms_fa_manure_a:
144  if (!m_farm->FA_Manure( m_field, 0.0,
145  g_date->DayInYear( 30, 11 ) - g_date->DayInYear())) {
146  SimpleEvent( g_date->Date() + 1, ms_fa_manure_a, false );
147  break;
148  }
149  SimpleEvent( g_date->Date(), ms_autumn_plough, false );
150  break;
151 
152  case ms_autumn_plough:
153  if (!m_farm->AutumnPlough( m_field, 0.0,
154  g_date->DayInYear( 30, 11 ) - g_date->DayInYear())) {
155  SimpleEvent( g_date->Date() + 1, ms_autumn_plough, false );
156  break;
157  }
158  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 1, 4 ) + 365,
159  ms_spring_harrow, false );
160  break;
161 
162  case ms_fa_manure_b:
163  if (!m_farm->FA_Manure( m_field, 0.0,
164  g_date->DayInYear( 25, 4 ) - g_date->DayInYear())) {
165  SimpleEvent( g_date->Date() + 1, ms_fa_manure_b, false );
166  break;
167  }
168  {
169  d1 = g_date->OldDays() + g_date->DayInYear( 1, 4 );
170  if ( g_date->Date()+1 > d1 ) {
171  d1 = g_date->Date()+1;
172  }
173  SimpleEvent( d1, ms_fa_slurry_one, false );
174  }
175  break;
176 
177  case ms_fa_slurry_one:
178  if (!m_farm->FA_Slurry( m_field, 0.0,
179  g_date->DayInYear( 30, 4 ) - g_date->DayInYear())) {
180  SimpleEvent( g_date->Date() + 1, ms_fa_slurry_one, false );
181  break;
182  }
183  SimpleEvent( g_date->Date() + 1, ms_spring_plough, false );
184  break;
185 
186  case ms_spring_plough:
187  if (!m_farm->SpringPlough( m_field, 0.0,
188  g_date->DayInYear( 1, 5 ) - g_date->DayInYear())) {
189  SimpleEvent( g_date->Date() + 1, ms_spring_plough, false );
190  break;
191  }
192  SimpleEvent( g_date->Date(), ms_spring_harrow, false );
193  break;
194 
195  case ms_spring_harrow:
196  if (!m_farm->SpringHarrow( m_field, 0.0,
197  g_date->DayInYear( 10, 5 ) - g_date->DayInYear())) {
198  SimpleEvent( g_date->Date() + 1, ms_spring_harrow, false );
199  break;
200  }
201  {
202  d1 = g_date->OldDays() + g_date->DayInYear( 25, 4 );
203  if ( g_date->Date() > d1 ) {
204  d1 = g_date->Date();
205  }
206  SimpleEvent( d1, ms_spring_sow, false );
207  }
208  break;
209 
210  case ms_spring_sow:
211  if (!m_farm->SpringSow( m_field, 0.0,
212  g_date->DayInYear( 15, 5 ) - g_date->DayInYear())) {
213  SimpleEvent( g_date->Date() + 1, ms_spring_sow, false );
214  break;
215  }
216  MAIZESILAGE_SOW_DATE = g_date->Date();
217  SimpleEvent( g_date->Date(), ms_fa_npk, false );
218  break;
219 
220  case ms_fa_npk:
221  if (!m_farm->FA_NPK( m_field, 0.0,
222  g_date->DayInYear( 20, 5 ) - g_date->DayInYear())) {
223  SimpleEvent( g_date->Date() + 1, ms_fa_npk, false );
224  break;
225  }
226  if ( m_farm->DoIt( 70 )) {
227  {
228  d1 = g_date->OldDays() + g_date->DayInYear( 1, 5 );
229  if ( MAIZESILAGE_SOW_DATE + 5 > d1 ) {
230  d1 = MAIZESILAGE_SOW_DATE + 5;
231  }
232  SimpleEvent( d1, ms_herbi_one, false );
233  }
234  } else {
235  {
236  d1 = g_date->OldDays() + g_date->DayInYear( 2, 5 );
237  if ( MAIZESILAGE_SOW_DATE + 7 > d1 ) {
238  d1 = MAIZESILAGE_SOW_DATE + 7;
239  }
240  SimpleEvent( d1, ms_row_one, false );
241  }
242  }
243  break;
244 
245  case ms_herbi_one:
246  if ( m_ev->m_lock || m_farm->DoIt( (int) (100*cfg_herbi_app_prop.value() * m_farm->Prob_multiplier()) )) { //modified probability
247 
248  //new - for decision making
249  TTypesOfVegetation tov = m_field->GetVegType();
250  if(!m_ev->m_lock && !m_farm->Spraying_herbicides(tov)){
251  Field * pf = dynamic_cast<Field*>(m_field);
252  pf->Add_missed_herb_app();
253  if(m_farm->DoIt(59)) pf->Add_missed_herb_app(); //the 2nd missed application
254  } //end of the part for dec. making
255  else{
256  if (!m_farm->HerbicideTreat( m_field, 0.0, g_date->DayInYear( 25, 5 ) - g_date->DayInYear())) {
257  SimpleEvent( g_date->Date() + 1, ms_herbi_one, false );
258  break;
259  }
260  }
261  }
262  MAIZESILAGE_HERBI_ONE_DATE = g_date->Date();
263  {
264  d1 = g_date->OldDays() + g_date->DayInYear( 1, 5 );
265  if ( MAIZESILAGE_SOW_DATE + 5 > d1 ) {
266  d1 = MAIZESILAGE_SOW_DATE + 5;
267  }
268  SimpleEvent( d1, ms_fa_slurry_two, false );
269  }
270  break;
271 
272  case ms_row_one:
273  if (!m_farm->RowCultivation( m_field, 0.0,
274  g_date->DayInYear( 25, 5 ) - g_date->DayInYear())) {
275  SimpleEvent( g_date->Date() + 1, ms_row_one, false );
276  break;
277  }
278  {
279  d1 = g_date->OldDays() + g_date->DayInYear( 1, 5 );
280  if ( MAIZESILAGE_SOW_DATE + 5 > d1 ) {
281  d1 = MAIZESILAGE_SOW_DATE + 5;
282  }
283  SimpleEvent( d1, ms_fa_slurry_two, false );
284  }
285  break;
286 
287  case ms_fa_slurry_two:
288  if (!m_farm->FA_Slurry( m_field, 0.0,
289  g_date->DayInYear( 25, 5 ) - g_date->DayInYear())) {
290  SimpleEvent( g_date->Date() + 1, ms_fa_slurry_two, false );
291  break;
292  }
293  if ( m_farm->DoIt( 86 )) {
294  {
295  d1 = g_date->OldDays() + g_date->DayInYear( 10, 5 );
296  if ( MAIZESILAGE_HERBI_ONE_DATE + 10 > d1 ) {
297  d1 = MAIZESILAGE_HERBI_ONE_DATE + 10;
298  }
299  SimpleEvent( d1, ms_herbi_two, false );
300  }
301  } else {
302  {
303  d1 = g_date->OldDays() + g_date->DayInYear( 21, 5 );
304  if ( g_date->Date() + 1 > d1 ) {
305  d1 = g_date->Date() + 1;
306  }
307  SimpleEvent( d1, ms_row_two, false );
308  }
309  }
310  break;
311 
312  case ms_herbi_two:
313  if ( m_ev->m_lock || m_farm->DoIt( (int) (59*cfg_herbi_app_prop.value() * m_farm->Prob_multiplier()))) { //modified probability
314  if (!m_farm->HerbicideTreat( m_field, 0.0,
315  g_date->DayInYear( 5, 6 ) - g_date->DayInYear())) {
316  SimpleEvent( g_date->Date() + 1, ms_herbi_two, false );
317  break;
318  }
319  }
320  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 1, 7 ),
321  ms_water_one, false );
322  break;
323 
324  case ms_row_two:
325  if (!m_farm->RowCultivation( m_field, 0.0,
326  g_date->DayInYear( 20, 6 ) - g_date->DayInYear())) {
327  SimpleEvent( g_date->Date() + 1, ms_row_two, false );
328  break;
329  }
330  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 1, 7 ),
331  ms_water_one, false );
332  break;
333 
334  case ms_water_one:
335  if ( m_ev->m_lock || m_farm->DoIt( 30 )) {
336  if (!m_farm->Water( m_field, 0.0,
337  g_date->DayInYear( 15, 7 ) - g_date->DayInYear())) {
338  SimpleEvent( g_date->Date() + 1, ms_water_one, false );
339  break;
340  }
341  }
342  {
343  d1 = g_date->OldDays() + g_date->DayInYear( 16, 7 );
344  if ( g_date->Date() + 7 > d1 ) {
345  d1 = g_date->Date() + 7;
346  }
347  SimpleEvent( d1, ms_water_two, false );
348  }
349  break;
350 
351  case ms_water_two:
352  if (!m_farm->Water( m_field, 0.0,
353  g_date->DayInYear( 30, 7 ) - g_date->DayInYear())) {
354  SimpleEvent( g_date->Date() + 1, ms_water_two, false );
355  break;
356  }
357  ChooseNextCrop (2);
358  //*that's it
359  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 1, 9 ),
360  ms_harvest, false );
361  break;
362 
363  case ms_harvest:
364  if (m_field->GetMConstants(0)==0) {
365  if (!m_farm->Harvest( m_field, 0.0, -1)) { //raise an error
366  g_msg->Warn( WARN_BUG, "MaizeSilage::Do(): failure in 'Harvest' execution", "" );
367  exit( 1 );
368  }
369  }
370  else {
371  if (!m_farm->Harvest( m_field, 0.0, m_field->GetMDates(1,0) - g_date->DayInYear())) {
372  SimpleEvent( g_date->Date() + 1, ms_harvest, false );
373  break;
374  }
375  }
376  {
377  d1 = g_date->OldDays() + m_field->GetMDates(0,1);
378  if ( g_date->Date() > d1 ) {
379  d1 = g_date->Date();
380  }
381  SimpleEvent( d1, ms_stubble, false );
382  }
383  break;
384 
385  case ms_stubble:
386  if ( m_ev->m_lock || m_farm->DoIt( 25 )) {
387  if (m_field->GetMConstants(1)==0) {
388  if (!m_farm->StubbleHarrowing( m_field, 0.0, -1)) { //raise an error
389  g_msg->Warn( WARN_BUG, "MaizeSilage::Do(): failure in 'StubbleHarrowing' execution", "" );
390  exit( 1 );
391  }
392  }
393  else {
394  if (!m_farm->StubbleHarrowing( m_field, 0.0, m_field->GetMDates(1,1) - g_date->DayInYear())) {
395  SimpleEvent( g_date->Date() + 1, ms_stubble, false );
396  break;
397  }
398  }
399  }
400  d1=g_date->DayInYear();
401  done = true;
402  break;
403 
404  default:
405  g_msg->Warn( WARN_BUG, "MaizeSilage::Do(): "
406  "Unknown event type! ", "" );
407  exit( 1 );
408  }
409 
410  return done;
411 }
412 
413 
Farm::FA_Slurry
virtual bool FA_Slurry(LE *a_field, double a_user, int a_days)
Spready slurry on a_field owned by an stock farmer.
Definition: farmfuncs.cpp:965
MAIZESILAGE_SOW_DATE
#define MAIZESILAGE_SOW_DATE
Definition: MaizeSilage.h:32
Farm::SpringPlough
virtual bool SpringPlough(LE *a_field, double a_user, int a_days)
Carry out a ploughing event in the spring on a_field.
Definition: farmfuncs.cpp:444
Farm::HerbicideTreat
virtual bool HerbicideTreat(LE *a_field, double a_user, int a_days)
Apply herbicide to a_field.
Definition: farmfuncs.cpp:1156
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
FarmEvent
A struct to hold the information required to trigger a farm event.
Definition: farm.h:463
Farm::DoIt
bool DoIt(double a_probability)
Return chance out of 0 to 100.
Definition: farm.cpp:800
ms_herbi_two
Definition: MaizeSilage.h:48
FarmEvent::m_first_year
bool m_first_year
Definition: farm.h:467
tof_OptimisingFarm
Definition: farm.h:273
ms_autumn_plough
Definition: MaizeSilage.h:39
ms_harvest
Definition: MaizeSilage.h:52
Farm::FA_Manure
virtual bool FA_Manure(LE *a_field, double a_user, int a_days)
Spread manure on a_field owned by an stock farmer.
Definition: farmfuncs.cpp:1036
cfg_ins_app_prop1
CfgFloat cfg_ins_app_prop1
cfg_herbi_app_prop
CfgFloat cfg_herbi_app_prop
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
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
ms_stubble
Definition: MaizeSilage.h:53
ms_water_two
Definition: MaizeSilage.h:51
ms_row_one
Definition: MaizeSilage.h:46
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
TTypesOfVegetation
TTypesOfVegetation
Definition: tov_declaration.h:30
Farm::Spraying_herbicides
virtual bool Spraying_herbicides(TTypesOfVegetation)
Definition: farm.h:784
ms_fa_slurry_two
Definition: MaizeSilage.h:47
ms_spring_harrow
Definition: MaizeSilage.h:42
ms_start
Definition: MaizeSilage.h:36
ms_fa_manure_b
Definition: MaizeSilage.h:38
FarmEvent::m_next_tov
TTypesOfVegetation m_next_tov
Definition: farm.h:471
Crop::m_farm
Farm * m_farm
Definition: farm.h:537
Crop::m_field
LE * m_field
Definition: farm.h:538
MAIZESILAGE_HERBI_ONE_DATE
#define MAIZESILAGE_HERBI_ONE_DATE
Definition: MaizeSilage.h:33
ms_fa_manure_a
Definition: MaizeSilage.h:37
FarmEvent::m_todo
int m_todo
Definition: farm.h:469
Farm::RowCultivation
virtual bool RowCultivation(LE *a_field, double a_user, int a_days)
Carry out a harrowing between crop rows on a_field.
Definition: farmfuncs.cpp:1510
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
Farm::AutumnPlough
virtual bool AutumnPlough(LE *a_field, double a_user, int a_days)
Carry out a ploughing event in the autumn on a_field.
Definition: farmfuncs.cpp:132
Farm::SpringSow
virtual bool SpringSow(LE *a_field, double a_user, int a_days)
Carry out a sowing event in the spring on a_field.
Definition: farmfuncs.cpp:546
ms_fa_slurry_one
Definition: MaizeSilage.h:40
ms_spring_plough
Definition: MaizeSilage.h:41
Farm
The base class for all farm types.
Definition: farm.h:767
ms_row_two
Definition: MaizeSilage.h:49
ms_spring_sow
Definition: MaizeSilage.h:43
cfg_greg_app_prop
CfgFloat cfg_greg_app_prop
ms_fa_npk
Definition: MaizeSilage.h:44
Crop::ChooseNextCrop
void ChooseNextCrop(int a_no_dates)
Chooses the next crop to grow in a field.
Definition: farm.cpp:318
Crop::m_ev
FarmEvent * m_ev
Definition: farm.h:539
MaizeSilage::Do
bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
Definition: MaizeSilage.cpp:36
cfg_fungi_app_prop1
CfgFloat cfg_fungi_app_prop1
ms_herbi_one
Definition: MaizeSilage.h:45
ms_water_one
Definition: MaizeSilage.h:50
Farm::StubbleHarrowing
virtual bool StubbleHarrowing(LE *a_field, double a_user, int a_days)
Carry out stubble harrowing on a_field.
Definition: farmfuncs.cpp:2209
Farm::SpringHarrow
virtual bool SpringHarrow(LE *a_field, double a_user, int a_days)
Carry out a harrow event in the spring on a_field.
Definition: farmfuncs.cpp:471