ALMaSS Skylark ODDox  1.1
The skylark model description following ODdox protocol
NLMaize Class Reference

NLMaize class
. More...

#include <NLMaize.h>

Public Member Functions

virtual bool Do (Farm *a_farm, LE *a_field, FarmEvent *a_ev)
 The one and only method for a crop management plan. All farm actions go through here. More...
 
 NLMaize ()
 
- Public Member Functions inherited from Crop
virtual ~Crop ()
 
 Crop ()
 
int GetFirstDate (void)
 
void ChooseNextCrop (int a_no_dates)
 Chooses the next crop to grow in a field. More...
 
int GetCropClassification ()
 
void SetCropClassification (int a_classification)
 

Additional Inherited Members

- Protected Member Functions inherited from Crop
void SimpleEvent (long a_date, int a_todo, bool a_lock)
 Adds an event to this crop management. More...
 
void SimpleEvent_ (long a_date, int a_todo, bool a_lock, Farm *a_farm, LE *a_field)
 Adds an event to this crop management without relying on member variables. More...
 
- Protected Attributes inherited from Crop
Farmm_farm
 
LE * m_field
 
FarmEventm_ev
 
int m_first_date
 
int m_count
 
int m_last_date
 
int m_ddegstoharvest
 
int m_CropClassification
 

Detailed Description

NLMaize class
.

See NLMaize.h::NLMaizeToDo for a complete list of all possible events triggered codes by the mazie management plan. When triggered these events are handled by Farm and are available as information for other objects such as animal and bird models.

Constructor & Destructor Documentation

◆ NLMaize()

NLMaize::NLMaize ( )
inline
71  {
72  // When we start it off, the first possible date for a farm operation is 5th November
73  // This information is used by other crops when they decide how much post processing of
74  // the management is allowed after harvest before the next crop starts.
75  m_first_date=g_date->DayInYear( 31,10 );
76  }

References Crop::m_first_date.

Member Function Documentation

◆ Do()

bool NLMaize::Do ( Farm a_farm,
LE *  a_field,
FarmEvent a_ev 
)
virtual

The one and only method for a crop management plan. All farm actions go through here.

Called every time something is done to the crop by the farmer in the first instance it is always called with a_ev->todo set to start, but susequently will be called whenever the farmer wants to carry out a new operation.
This method details all the management and relationships between operations necessary to grow and ALMaSS crop - in this case conventional maize.

Reimplemented from Crop.

65 {
66  bool done = false; // The boolean value done indicates when we are totally finished with this plan (i.e. it is set to true).
67  int d1 = 0;
68  // Depending what event has occured jump to the correct bit of code
69  switch (a_ev->m_todo)
70  {
71  case nl_m_start:
72  {
73  // nl_m_start just sets up all the starting conditions and reference dates that are needed to start a nl_maize
74  NL_M_START_FERTI = false;
75  // Set up the date management stuff
76  // The next bit of code just allows for altering dates after harvest if it is necessary
77  // to allow for a crop which starts its management early.
78 
79  // 5 start and stop dates for all 'movable' events for this crop
80  int noDates = 1;
81  a_field->SetMDates(0, 0, g_date->DayInYear(5, 10)); // last possible day of harvest
82  a_field->SetMDates(1, 0, g_date->DayInYear(10, 10)); // last possible day of straw chopping
83  // then these will be reduced in value to 0
84 
85  a_field->SetMConstants(0, 1);
86 
87  // Check the next crop for early start, unless it is a spring crop
88  // in which case we ASSUME that no checking is necessary!!!!
89  // So DO NOT implement a crop that runs over the year boundary (i.e. from spring to spring!), at least not without fixing this.
90 
91  //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)
92  //optimising farms not used for now so most of related code is removed (but not in 'start' case)
93  if (!(a_farm->GetType() == tof_OptimisingFarm && g_date->GetYearNumber() > 0)) {
94 
95  if (a_ev->m_startday > g_date->DayInYear(1, 7)) {
96  if (a_field->GetMDates(0, 0) >= a_ev->m_startday)
97  {
98  g_msg->Warn(WARN_BUG, "NLMaize::Do(): ", "Harvest too late for the next crop to start!!!");
99  int almassnum = g_landscape_p->BackTranslateVegTypes(a_ev->m_next_tov);
100  g_msg->Warn("Next Crop ", (double)almassnum); // this causes exit
101  }
102  // Now fix any late finishing problems
103  for (int i = 0; i < noDates; i++) {
104  if (a_field->GetMDates(0, i) >= a_ev->m_startday) {
105  a_field->SetMDates(0, i, a_ev->m_startday - 1); //move the starting date
106  }
107  if (a_field->GetMDates(1, i) >= a_ev->m_startday) {
108  a_field->SetMConstants(i, 0); //change the default value of the MConst (=1) to 0 (necessary to correctly execute farm events in case the finishing date (MDate) was moved)
109  a_field->SetMDates(1, i, a_ev->m_startday - 1); //move the finishing date
110  }
111  }
112  }
113  // Now no operations can be timed after the start of the next crop.
114 
115  if (!a_ev->m_first_year) {
116  // Are we before July 1st?
117  d1 = g_date->OldDays() + g_date->DayInYear(1, 7);
118  if (g_date->Date() < d1) {
119  // Yes, too early. We assumme this is because the last crop was late
120  printf("Poly: %d\n", a_field->GetPoly());
121  g_msg->Warn(WARN_BUG, "NLMaize::Do(): ", "Crop start attempt between 1st Jan & 1st July");
122  int prev = g_landscape_p->BackTranslateVegTypes(a_field->GetOwner()->GetPreviousCrop(a_field->GetRotIndex()));
123  g_msg->Warn(WARN_BUG, "Previous Crop ", prev);
124  int almassnum = g_landscape_p->BackTranslateVegTypes(a_ev->m_next_tov);
125  g_msg->Warn("Next Crop ", (double)almassnum); // this causes exit
126  exit(1);
127  }
128  else {
129  d1 = g_date->OldDays() + m_first_date; // Add 365 for spring crop
130  if (g_date->Date() > d1) {
131  // Yes too late - should not happen - raise an error
132  g_msg->Warn(WARN_BUG, "NLMaize::Do(): ", "Crop start attempt after last possible start date");
133  int prev = g_landscape_p->BackTranslateVegTypes(a_field->GetOwner()->GetPreviousCrop(a_field->GetRotIndex()));
134  g_msg->Warn(WARN_BUG, "Previous Crop ", prev);
135  int almassnum = g_landscape_p->BackTranslateVegTypes(a_ev->m_next_tov);
136  g_msg->Warn("Next Crop ", (double)almassnum); // this causes exit
137  exit(1);
138  }
139  }
140  }
141  else {
142  // Is the first year
143  // Some special code to cope with that first start-up year in ALMaSS - ignore for all practical purposes
144  // Code for first spring treatment used
145  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(15, 4), nl_m_spring_sow, false, a_farm, a_field);
146  break;
147  }
148  }//if
149 
150  // End single block date checking code. Please see next line comment as well.
151  // Reinit d1 to first possible starting date.
152  d1 = g_date->OldDays() + g_date->DayInYear(1, 9);
153  // OK, let's go.
154  // Here we queue up the first event - this differs depending on whether we have field on snady or clay soils
155  if (a_field->GetSoilType() == 2 || a_field->GetSoilType() == 6) { // on sandy soils (NL ZAND & LOSS)
156  SimpleEvent_(d1, nl_m_stubble_harrow1, false, a_farm, a_field);
157  }
158  else SimpleEvent_(d1, nl_m_stubble_harrow2, false, a_farm, a_field);
159  }
160  break;
161 
162  // This is the first real farm operation
164  if (a_ev->m_lock || a_farm->DoIt_prob(1.00))
165  {
166  if (!a_farm->StubbleHarrowing(a_field, 0.0, g_date->DayInYear(31, 10) - g_date->DayInYear())) {
167  SimpleEvent_(g_date->Date() + 1, nl_m_stubble_harrow1, true, a_farm, a_field);
168  break;
169  }
170  }
171  d1 = g_date->Date() + 10;
172  if (d1 < g_date->OldDays() + g_date->DayInYear(15, 10)) {
173  d1 = g_date->OldDays() + g_date->DayInYear(15, 10);
174  }
175  SimpleEvent_(d1, nl_m_winter_plough1, false, a_farm, a_field);
176  break;
177  case nl_m_winter_plough1:
178  if (a_ev->m_lock || a_farm->DoIt_prob(0))
179  {
180  if (!a_farm->WinterPlough(a_field, 0.0, g_date->DayInYear(1, 12) - g_date->DayInYear())) {
181  SimpleEvent_(g_date->Date() + 1, nl_m_winter_plough1, true, a_farm, a_field);
182  break;
183  }
184  }
185  if (a_farm->IsStockFarmer()) //Stock Farmer
186  {
187  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 4) + 365, nl_m_ferti_s1, false, a_farm, a_field);
188  }
189  else SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 4) + 365, nl_m_ferti_p1, false, a_farm, a_field);
190  break;
192  if (a_ev->m_lock || a_farm->DoIt_prob(0.20))
193  {
194  if (!a_farm->StubbleHarrowing(a_field, 0.0, g_date->DayInYear(31, 10) - g_date->DayInYear())) {
195  SimpleEvent_(g_date->Date() + 1, nl_m_stubble_harrow2, true, a_farm, a_field);
196  break;
197  }
198  }
199  d1 = g_date->Date() + 10;
200  if (d1 < g_date->OldDays() + g_date->DayInYear(15, 11)) {
201  d1 = g_date->OldDays() + g_date->DayInYear(15, 11);
202  }
203  SimpleEvent_(d1, nl_m_winter_plough2, false, a_farm, a_field);
204  break;
205  case nl_m_winter_plough2:
206  if (a_ev->m_lock || a_farm->DoIt_prob(1.00))
207  {
208  if (!a_farm->WinterPlough(a_field, 0.0, g_date->DayInYear(1, 12) - g_date->DayInYear())) {
209  SimpleEvent_(g_date->Date() + 1, nl_m_winter_plough2, true, a_farm, a_field);
210  break;
211  }
212  }
213  if (a_farm->IsStockFarmer()) //Stock Farmer
214  {
215  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 4) + 365, nl_m_ferti_s1, false, a_farm, a_field);
216  }
217  else SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 4) + 365, nl_m_ferti_p1, false, a_farm, a_field);
218  break;
219  case nl_m_ferti_p1:
220  if (!a_farm->FP_Slurry(a_field, 0.0, g_date->DayInYear(25, 4) - g_date->DayInYear())) {
221  SimpleEvent_(g_date->Date() + 1, nl_m_ferti_p1, true, a_farm, a_field);
222  break;
223  }
224  if (a_field->GetSoilType() == 2 || a_field->GetSoilType() == 6) { // on sandy soils (NL ZAND & LOSS)
225  SimpleEvent_(g_date->Date() + 1, nl_m_spring_plough1, false, a_farm, a_field);
226  }
227  else SimpleEvent_(g_date->Date() + 1, nl_m_spring_plough2, false, a_farm, a_field);
228  break;
229  case nl_m_ferti_s1:
230  if (!a_farm->FA_Slurry(a_field, 0.0, g_date->DayInYear(25, 4) - g_date->DayInYear())) {
231  SimpleEvent_(g_date->Date() + 1, nl_m_ferti_s1, true, a_farm, a_field);
232  break;
233  }
234  if (a_field->GetSoilType() == 2 || a_field->GetSoilType() == 6) { // on sandy soils (NL ZAND & LOSS)
235  SimpleEvent_(g_date->Date() + 1, nl_m_spring_plough1, false, a_farm, a_field);
236  }
237  else SimpleEvent_(g_date->Date() + 1, nl_m_spring_plough2, false, a_farm, a_field);
238  break;
239  case nl_m_spring_plough1:
240  if (a_ev->m_lock || a_farm->DoIt_prob(0.20))
241  {
242  if (!a_farm->SpringPlough(a_field, 0.0, g_date->DayInYear(30, 4) - g_date->DayInYear())) {
243  SimpleEvent_(g_date->Date() + 1, nl_m_spring_plough1, true, a_farm, a_field);
244  break;
245  }
246  }
247  SimpleEvent_(g_date->Date() + 10, nl_m_preseeding_cultivator, false, a_farm, a_field);
248  break;
249  case nl_m_spring_plough2:
250  if (a_ev->m_lock || a_farm->DoIt_prob(0))
251  {
252  if (!a_farm->SpringPlough(a_field, 0.0, g_date->DayInYear(30, 4) - g_date->DayInYear())) {
253  SimpleEvent_(g_date->Date() + 1, nl_m_spring_plough2, true, a_farm, a_field);
254  break;
255  }
256  }
257  SimpleEvent_(g_date->Date() + 10, nl_m_preseeding_cultivator, false, a_farm, a_field);
258  break;
260  if (!a_farm->PreseedingCultivator(a_field, 0.0, g_date->DayInYear(4, 5) - g_date->DayInYear())) {
261  SimpleEvent_(g_date->Date() + 1, nl_m_preseeding_cultivator, true, a_farm, a_field);
262  break;
263  }
264  SimpleEvent_(g_date->Date() + 1, nl_m_spring_sow_with_ferti, false, a_farm, a_field);
265  break;
267  // 75% will do sow with firtilizer
268  if (a_ev->m_lock || a_farm->DoIt_prob(0.75))
269  {
270  if (!a_farm->SpringSowWithFerti(a_field, 0.0, g_date->DayInYear(5, 5) - g_date->DayInYear())) {
271  SimpleEvent_(g_date->Date() + 1, nl_m_spring_sow_with_ferti, true, a_farm, a_field);
272  break;
273  }
274  else
275  {
276  // 75% of farmers will do this, but the other 25% won't so we need to remember whether we are in one or the other group
277  NL_M_START_FERTI = true;
278  // Here is a fork leading to parallel events
279  SimpleEvent_(g_date->Date() + 3, nl_m_harrow, false, a_farm, a_field);
280  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 5), nl_m_herbicide1, false, a_farm, a_field); // Herbidide thread
281  if (a_farm->IsStockFarmer()) //Stock Farmer // N thread = MAIN
282  {
283  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(20, 5), nl_m_ferti_s2, false, a_farm, a_field);
284  }
285  else SimpleEvent_(g_date->OldDays() + g_date->DayInYear(20, 5), nl_m_ferti_p2, false, a_farm, a_field);
286  break;
287  }
288  }
289  SimpleEvent_(g_date->Date() + 1, nl_m_spring_sow, false, a_farm, a_field);
290  break;
291  case nl_m_spring_sow:
292  if (!a_farm->SpringSow(a_field, 0.0, g_date->DayInYear(5, 5) - g_date->DayInYear())) {
293  SimpleEvent_(g_date->Date() + 1, nl_m_spring_sow, true, a_farm, a_field);
294  break;
295  }
296  // Here is a fork leading to parallel events
297  SimpleEvent_(g_date->Date() + 3, nl_m_harrow, false, a_farm, a_field);
298  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 5), nl_m_herbicide1, false, a_farm, a_field); // Herbidide thread
299  if (a_farm->IsStockFarmer()) //Stock Farmer // N thread = MAIN
300  {
301  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(20, 5), nl_m_ferti_s2, false, a_farm, a_field);
302  }
303  else SimpleEvent_(g_date->OldDays() + g_date->DayInYear(20, 5), nl_m_ferti_p2, false, a_farm, a_field);
304  break;
305  case nl_m_ferti_p2:
306  // Here comes N thread
307  if (a_ev->m_lock || a_farm->DoIt_prob(0.60) && (NL_M_START_FERTI==0))
308  {
309  if (!a_farm->FP_AmmoniumSulphate(a_field, 0.0, g_date->DayInYear(10, 6) - g_date->DayInYear())) {
310  SimpleEvent_(g_date->Date() + 1, nl_m_ferti_p2, true, a_farm, a_field);
311  break;
312  }
313  }
314  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(10, 9), nl_m_harvest, false, a_farm, a_field);
315  break;
316  case nl_m_ferti_s2:
317  if (a_ev->m_lock || a_farm->DoIt_prob(0.60) && (NL_M_START_FERTI == 0))
318  {
319  if (!a_farm->FA_AmmoniumSulphate(a_field, 0.0, g_date->DayInYear(10, 6) - g_date->DayInYear())) {
320  SimpleEvent_(g_date->Date() + 1, nl_m_ferti_s2, true, a_farm, a_field);
321  break;
322  }
323  }
324  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(10, 9), nl_m_harvest, false, a_farm, a_field);
325  break;
326  case nl_m_herbicide1:
327  // Here comes the herbicide thread
328  if (a_field->GetGreenBiomass() <= 0)
329  {
330  SimpleEvent_(g_date->Date() + 1, nl_m_herbicide1, false, a_farm, a_field);
331  }
332  else
333  {
334  if (a_ev->m_lock || a_farm->DoIt_prob(0.90))
335  {
336  if (!a_farm->HerbicideTreat(a_field, 0.0, g_date->DayInYear(25, 5) - g_date->DayInYear())) {
337  SimpleEvent_(g_date->Date() + 1, nl_m_herbicide1, true, a_farm, a_field);
338  break;
339  }
340  }
341  }
342  // End of thread
343  break;
344  case nl_m_harrow:
345  // Here comes the MAIN thread
346  if (a_ev->m_lock || a_farm->DoIt_prob(0.15))
347  {
348  if (a_field->GetGreenBiomass() <= 0)
349  {
350  if (!a_farm->ShallowHarrow(a_field, 0.0, g_date->DayInYear(15, 5) - g_date->DayInYear())) {
351  SimpleEvent_(g_date->Date() + 1, nl_m_harrow, true, a_farm, a_field);
352  break;
353  }
354  }
355  else { SimpleEvent_(g_date->Date() + 1, nl_m_harrow, true, a_farm, a_field); }
356  }
357  // End of thread
358  break;
359  case nl_m_harvest:
360  // Here the MAIN thread continues
361  // We don't move harvest days
362  if (!a_farm->Harvest(a_field, 0.0, a_field->GetMDates(0, 0) - g_date->DayInYear())) {
363  SimpleEvent_(g_date->Date() + 1, nl_m_harvest, true, a_farm, a_field);
364  break;
365  }
366  SimpleEvent_(g_date->Date() + 1, nl_m_straw_chopping, false, a_farm, a_field);
367  break;
368  case nl_m_straw_chopping:
369  if (a_field->GetMConstants(0) == 0) {
370  if (!a_farm->StrawChopping(a_field, 0.0, -1)) { // raise an error
371  g_msg->Warn(WARN_BUG, "NLMaize::Do(): failure in 'StrawChopping' execution", "");
372  exit(1);
373  }
374  }
375  else {
376  if (!a_farm->StrawChopping(a_field, 0.0, a_field->GetMDates(1, 0) - g_date->DayInYear())) {
377  SimpleEvent_(g_date->Date() + 1, nl_m_straw_chopping, true, a_farm, a_field);
378  break;
379  }
380  }
381  done = true;
382  // So we are done, and somwhere else the farmer will queue up the start event of the next crop
383  // END of MAIN THREAD
384  break;
385  default:
386  g_msg->Warn(WARN_BUG, "NLMaize::Do(): "
387  "Unknown event type! ", "");
388  exit(1);
389  }
390  return done;
391 }

References Landscape::BackTranslateVegTypes(), Farm::DoIt_prob(), g_landscape_p, Farm::GetType(), Farm::IsStockFarmer(), Crop::m_first_date, FarmEvent::m_first_year, FarmEvent::m_lock, FarmEvent::m_next_tov, FarmEvent::m_startday, FarmEvent::m_todo, nl_m_ferti_p1, nl_m_ferti_p2, nl_m_ferti_s1, nl_m_ferti_s2, nl_m_harrow, nl_m_harvest, nl_m_herbicide1, nl_m_preseeding_cultivator, nl_m_spring_plough1, nl_m_spring_plough2, nl_m_spring_sow, nl_m_spring_sow_with_ferti, nl_m_start, NL_M_START_FERTI, nl_m_straw_chopping, nl_m_stubble_harrow1, nl_m_stubble_harrow2, nl_m_winter_plough1, nl_m_winter_plough2, Crop::SimpleEvent_(), Farm::StubbleHarrowing(), tof_OptimisingFarm, and Farm::WinterPlough().


The documentation for this class was generated from the following files:
nl_m_ferti_p1
Definition: NLMaize.h:42
nl_m_spring_sow_with_ferti
Definition: NLMaize.h:47
Farm::IsStockFarmer
bool IsStockFarmer(void)
Definition: farm.h:905
nl_m_stubble_harrow2
Definition: NLMaize.h:39
FarmEvent::m_lock
bool m_lock
Definition: farm.h:465
nl_m_spring_sow
Definition: NLMaize.h:48
FarmEvent::m_first_year
bool m_first_year
Definition: farm.h:467
tof_OptimisingFarm
Definition: farm.h:273
Farm::DoIt_prob
bool DoIt_prob(double a_probability)
Return chance out of 0 to 1.
Definition: farm.cpp:808
nl_m_winter_plough2
Definition: NLMaize.h:41
nl_m_harrow
Definition: NLMaize.h:49
Landscape::BackTranslateVegTypes
int BackTranslateVegTypes(TTypesOfVegetation VegReference)
Definition: Landscape.h:1669
Farm::GetType
TTypesOfFarm GetType(void)
Definition: farm.h:901
nl_m_spring_plough2
Definition: NLMaize.h:45
Crop::m_first_date
int m_first_date
Definition: farm.h:540
FarmEvent::m_startday
int m_startday
Definition: farm.h:466
NL_M_START_FERTI
#define NL_M_START_FERTI
A flag used to indicate autumn ploughing status.
Definition: NLMaize.h:28
nl_m_spring_plough1
Definition: NLMaize.h:44
nl_m_ferti_p2
Definition: NLMaize.h:50
nl_m_winter_plough1
Definition: NLMaize.h:40
nl_m_start
Definition: NLMaize.h:36
FarmEvent::m_next_tov
TTypesOfVegetation m_next_tov
Definition: farm.h:471
FarmEvent::m_todo
int m_todo
Definition: farm.h:469
nl_m_harvest
Definition: NLMaize.h:53
Farm::WinterPlough
virtual bool WinterPlough(LE *a_field, double a_user, int a_days)
Carry out a ploughing event in the winter on a_field.
Definition: farmfuncs.cpp:392
nl_m_ferti_s1
Definition: NLMaize.h:43
nl_m_straw_chopping
Definition: NLMaize.h:54
nl_m_herbicide1
Definition: NLMaize.h:52
nl_m_stubble_harrow1
Definition: NLMaize.h:38
nl_m_preseeding_cultivator
Definition: NLMaize.h:46
nl_m_ferti_s2
Definition: NLMaize.h:51
g_landscape_p
Landscape * g_landscape_p
Definition: Landscape.cpp:258
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
Crop::SimpleEvent_
void SimpleEvent_(long a_date, int a_todo, bool a_lock, Farm *a_farm, LE *a_field)
Adds an event to this crop management without relying on member variables.
Definition: farm.cpp:312