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

NLBeet class
. More...

#include <NLBeet.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...
 
 NLBeet ()
 
- 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

NLBeet class
.

See NLBeet.h::NLBeetToDo for a complete list of all possible events triggered codes by the beet 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

◆ NLBeet()

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

References Crop::m_first_date.

Member Function Documentation

◆ Do()

bool NLBeet::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 beet.

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_be_start:
72  {
73  // nl_be_start just sets up all the starting conditions and reference dates that are needed to start a nl_be
74  NL_BE_HERBI1 = false;
75  NL_BE_FUNGI1 = false;
76 
77 
78  // Set up the date management stuff
79  // The next bit of code just allows for altering dates after harvest if it is necessary
80  // to allow for a crop which starts its management early.
81 
82  // 2 start and stop dates for all 'movable' events for this crop
83  int noDates = 1;
84  a_field->SetMDates(0, 0, g_date->DayInYear(15, 12)); // last possible day of harvest
85  a_field->SetMDates(1, 0, g_date->DayInYear(15, 12));
86 
87  a_field->SetMConstants(0, 1);
88 
89  // Check the next crop for early start, unless it is a spring crop
90  // in which case we ASSUME that no checking is necessary!!!!
91  // So DO NOT implement a crop that runs over the year boundary (i.e. from spring to spring!), at least not without fixing this.
92 
93  //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)
94  //optimising farms not used for now so most of related code is removed (but not in 'start' case)
95  if (!(a_farm->GetType() == tof_OptimisingFarm && g_date->GetYearNumber() > 0)) {
96 
97  if (a_ev->m_startday > g_date->DayInYear(1, 7)) {
98  if (a_field->GetMDates(0, 0) >= a_ev->m_startday)
99  {
100  g_msg->Warn(WARN_BUG, "NLBeet::Do(): ", "Harvest too late for the next crop to start!!!");
101  int almassnum = g_landscape_p->BackTranslateVegTypes(a_ev->m_next_tov);
102  g_msg->Warn("Next Crop ", (double)almassnum); // this causes exit
103  }
104  // Now fix any late finishing problems
105  for (int i = 0; i < noDates; i++) {
106  if (a_field->GetMDates(0, i) >= a_ev->m_startday) {
107  a_field->SetMDates(0, i, a_ev->m_startday - 1); //move the starting date
108  }
109  if (a_field->GetMDates(1, i) >= a_ev->m_startday) {
110  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)
111  a_field->SetMDates(1, i, a_ev->m_startday - 1); //move the finishing date
112  }
113  }
114  }
115  // Now no operations can be timed after the start of the next crop.
116 
117  if (!a_ev->m_first_year) {
118  // Are we before July 1st?
119  d1 = g_date->OldDays() + g_date->DayInYear(1, 7);
120  if (g_date->Date() < d1) {
121  // Yes, too early. We assumme this is because the last crop was late
122  printf("Poly: %d\n", a_field->GetPoly());
123  g_msg->Warn(WARN_BUG, "NLBeet::Do(): ", "Crop start attempt between 1st Jan & 1st July");
124  int prev = g_landscape_p->BackTranslateVegTypes(a_field->GetOwner()->GetPreviousCrop(a_field->GetRotIndex()));
125  g_msg->Warn(WARN_BUG, "Previous Crop ", prev);
126  int almassnum = g_landscape_p->BackTranslateVegTypes(a_ev->m_next_tov);
127  g_msg->Warn("Next Crop ", (double)almassnum); // this causes exit
128  }
129  else {
130  d1 = g_date->OldDays() + m_first_date; // Add 365 for spring crop
131  if (g_date->Date() > d1) {
132  // Yes too late - should not happen - raise an error
133  g_msg->Warn(WARN_BUG, "NLBeet::Do(): ", "Crop start attempt after last possible start date");
134  g_msg->Warn(WARN_BUG, "Previous Crop ", "");
135  a_field->GetOwner()->GetPreviousCrop(a_field->GetRotIndex());
136  int almassnum = g_landscape_p->BackTranslateVegTypes(a_ev->m_next_tov);
137  g_msg->Warn("Next Crop ", (double)almassnum); // this causes exit
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(1, 3), nl_be_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_be_stubble_harrow_sandy, false, a_farm, a_field);
157  }
158  else SimpleEvent_(d1, nl_be_stubble_harrow_clay, false, a_farm, a_field);
159  }
160  break;
161 
162  // This is the first real farm operation
164  if (!a_farm->StubbleHarrowing(a_field, 0.0, g_date->DayInYear(31, 10) - g_date->DayInYear())) {
165  SimpleEvent_(g_date->Date() + 1, nl_be_stubble_harrow_sandy, true, a_farm, a_field);
166  break;
167  }
168  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 3) + 365, nl_be_spring_plough_sandy, false, a_farm, a_field);
169  break;
171  if (!a_farm->SpringPlough(a_field, 0.0, g_date->DayInYear(30, 3) - g_date->DayInYear())) {
172  SimpleEvent_(g_date->Date() + 1, nl_be_spring_plough_sandy, true, a_farm, a_field);
173  break;
174  }
175  if (a_farm->IsStockFarmer()) //Stock Farmer
176  {
177  SimpleEvent_(g_date->Date() + 7, nl_be_ferti_s1, false, a_farm, a_field);
178  }
179  else SimpleEvent_(g_date->Date() + 7, nl_be_ferti_p1, false, a_farm, a_field);
180  break;
182  if (a_ev->m_lock || a_farm->DoIt_prob(0.15))
183  {
184  if (!a_farm->StubbleHarrowing(a_field, 0.0, g_date->DayInYear(31, 12) - g_date->DayInYear())) {
185  SimpleEvent_(g_date->Date() + 1, nl_be_stubble_harrow_clay, true, a_farm, a_field);
186  break;
187  }
188  }
189  d1 = g_date->Date() + 21;
190  if (d1 < g_date->OldDays() + g_date->DayInYear(15, 10)) {
191  d1 = g_date->OldDays() + g_date->DayInYear(15, 10);
192  }
193  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(15, 10), nl_be_winter_plough_clay, false, a_farm, a_field);
194  break;
196  if (!a_farm->WinterPlough(a_field, 0.0, g_date->DayInYear(15, 12) - g_date->DayInYear())) {
197  SimpleEvent_(g_date->Date() + 1, nl_be_winter_plough_clay, true, a_farm, a_field);
198  break;
199  }
200  if (a_farm->IsStockFarmer()) //Stock Farmer
201  {
202  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 3) + 365, nl_be_ferti_s1, false, a_farm, a_field);
203  }
204  else SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 3) + 365, nl_be_ferti_p1, false, a_farm, a_field);
205  break;
206  case nl_be_ferti_p1:
207  if (a_ev->m_lock || a_farm->DoIt_prob(0.60))
208  {
209  if (!a_farm->FP_NPK(a_field, 0.0, g_date->DayInYear(10, 4) - g_date->DayInYear())) {
210  SimpleEvent_(g_date->Date() + 1, nl_be_ferti_p1, true, a_farm, a_field);
211  break;
212  }
213  }
214  SimpleEvent_(g_date->Date() + 1, nl_be_preseeding_cultivator, false, a_farm, a_field);
215  break;
216  case nl_be_ferti_s1:
217  if (a_ev->m_lock || a_farm->DoIt_prob(0.60))
218  {
219  if (!a_farm->FA_NPK(a_field, 0.0, g_date->DayInYear(10, 4) - g_date->DayInYear())) {
220  SimpleEvent_(g_date->Date() + 1, nl_be_ferti_s1, true, a_farm, a_field);
221  break;
222  }
223  }
224  SimpleEvent_(g_date->Date() + 1, nl_be_preseeding_cultivator, false, a_farm, a_field);
225  break;
227  if (!a_farm->PreseedingCultivator(a_field, 0.0, g_date->DayInYear(14, 4) - g_date->DayInYear())) {
228  SimpleEvent_(g_date->Date() + 1, nl_be_preseeding_cultivator, true, a_farm, a_field);
229  break;
230  }
231  SimpleEvent_(g_date->Date() + 1, nl_be_spring_sow, false, a_farm, a_field);
232  break;
233  case nl_be_spring_sow:
234  if (!a_farm->SpringSow(a_field, 0.0, g_date->DayInYear(15, 4) - g_date->DayInYear())) {
235  SimpleEvent_(g_date->Date() + 1, nl_be_spring_sow, true, a_farm, a_field);
236  break;
237  }
238  // Here is a fork leading to four parallel events
239  SimpleEvent_(g_date->Date() + 5, nl_be_herbicide1, false, a_farm, a_field); // Herbicide thread
240  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(1, 7), nl_be_fungicide1, false, a_farm, a_field); // Fungicide thread = MAIN THREAD
241  if (a_farm->IsStockFarmer()) //Stock Farmer
242  {
243  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(15, 4), nl_be_ferti_s2, false, a_farm, a_field); // Fertilizers thread
244  }
245  else SimpleEvent_(g_date->OldDays() + g_date->DayInYear(15, 4), nl_be_ferti_p2, false, a_farm, a_field);
246  break;
247  case nl_be_ferti_p2:
248  // Here comes fertilizers thread
249  if (a_field->GetGreenBiomass() <= 0) {
250  SimpleEvent_(g_date->Date() + 1, nl_be_ferti_p2, false, a_farm, a_field);
251  }
252  else
253  {
254  if (!a_farm->FP_AmmoniumSulphate(a_field, 0.0, g_date->DayInYear(15, 5) - g_date->DayInYear())) {
255  SimpleEvent_(g_date->Date() + 1, nl_be_ferti_p2, true, a_farm, a_field);
256  break;
257  }
258  }
259  // End of thread
260  break;
261  case nl_be_ferti_s2:
262  if (a_field->GetGreenBiomass() <= 0) {
263  SimpleEvent_(g_date->Date() + 1, nl_be_ferti_s2, false, a_farm, a_field);
264  break;
265  }
266  else
267  {
268  if (!a_farm->FA_AmmoniumSulphate(a_field, 0.0, g_date->DayInYear(15, 5) - g_date->DayInYear())) {
269  SimpleEvent_(g_date->Date() + 1, nl_be_ferti_s2, true, a_farm, a_field);
270  break;
271  }
272  }
273  // End of thread
274  break;
275  case nl_be_herbicide1: // The first of the pesticide managements.
276  // Here comes the herbicide thread
277  // We assume that farmers do max 3 herbicide treatments
278  if (a_field->GetGreenBiomass() <= 0)
279  {
280  if (a_ev->m_lock || a_farm->DoIt_prob(0.75))
281  {
282  if (!a_farm->HerbicideTreat(a_field, 0.0, g_date->DayInYear(20, 4) - g_date->DayInYear())) {
283  SimpleEvent_(g_date->Date() + 1, nl_be_herbicide1, true, a_farm, a_field);
284  break;
285  }
286  NL_BE_HERBI1 = true;
287  }
288  SimpleEvent_(g_date->Date() + 14, nl_be_herbicide2, false, a_farm, a_field);
289  break;
290  }
291  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(15, 3), nl_be_herbicide2, false, a_farm, a_field);
292  break;
293  case nl_be_herbicide2:
294  if (a_field->GetGreenBiomass() <= 0) {
295  SimpleEvent_(g_date->Date() + 1, nl_be_herbicide2, false, a_farm, a_field);
296  }
297  else
298  {
299  if (!a_farm->HerbicideTreat(a_field, 0.0, g_date->DayInYear(30, 4) - g_date->DayInYear())) {
300  SimpleEvent_(g_date->Date() + 1, nl_be_herbicide2, true, a_farm, a_field);
301  break;
302  }
303  SimpleEvent_(g_date->Date() + 14, nl_be_herbicide3, false, a_farm, a_field);
304  break;
305  }
306  break;
307  case nl_be_herbicide3:
308  if (!a_farm->HerbicideTreat(a_field, 0.0, g_date->DayInYear(15, 5) - g_date->DayInYear())) {
309  SimpleEvent_(g_date->Date() + 1, nl_be_herbicide3, true, a_farm, a_field);
310  break;
311  }
312  SimpleEvent_(g_date->Date() + 14, nl_be_herbicide4, false, a_farm, a_field);
313  break;
314  case nl_be_herbicide4:
315  if (a_ev->m_lock || (a_farm->DoIt_prob(0.20) && (NL_BE_HERBI1 == false)))
316  {
317  if (!a_farm->HerbicideTreat(a_field, 0.0, g_date->DayInYear(30, 5) - g_date->DayInYear())) {
318  SimpleEvent_(g_date->Date() + 1, nl_be_herbicide4, true, a_farm, a_field);
319  break;
320  }
321  }
322  // End of thread
323  break;
324  case nl_be_fungicide1:
325  // Here comes the fungicide thread
326  if (!a_farm->FungicideTreat(a_field, 0.0, g_date->DayInYear(5, 8) - g_date->DayInYear())) {
327  SimpleEvent_(g_date->Date() + 1, nl_be_fungicide1, true, a_farm, a_field);
328  break;
329  }
330  SimpleEvent_(g_date->Date() + 21, nl_be_fungicide2, false, a_farm, a_field);
331  break;
332  case nl_be_fungicide2:
333  if (a_ev->m_lock || a_farm->DoIt_prob(0.75))
334  {
335  if (!a_farm->FungicideTreat(a_field, 0.0, g_date->DayInYear(25, 8) - g_date->DayInYear())) {
336  SimpleEvent_(g_date->Date() + 1, nl_be_fungicide2, true, a_farm, a_field);
337  break;
338  }
339  NL_BE_FUNGI1 = true;
340  }
341  SimpleEvent_(g_date->Date() + 21, nl_be_fungicide3, false, a_farm, a_field);
342  break;
343  case nl_be_fungicide3:
344  if (a_ev->m_lock || (a_farm->DoIt_prob(0.667) && NL_BE_FUNGI1 == 1)) // 50% of all farmers
345  {
346  if (!a_farm->FungicideTreat(a_field, 0.0, g_date->DayInYear(15, 9) - g_date->DayInYear())) {
347  SimpleEvent_(g_date->Date() + 1, nl_be_fungicide3, true, a_farm, a_field);
348  break;
349  }
350  }
351  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(20, 9), nl_be_harvest, false, a_farm, a_field);
352  break;
353  case nl_be_harvest:
354  // Here the MAIN thread continues
355  // We don't move harvest days
356  if (!a_farm->Harvest(a_field, 0.0, a_field->GetMDates(0, 0) - g_date->DayInYear())) {
357  SimpleEvent_(g_date->Date() + 1, nl_be_harvest, true, a_farm, a_field);
358  break;
359  }
360  done = true;
361  // So we are done, and somwhere else the farmer will queue up the start event of the next crop
362  // END of MAIN THREAD
363  break;
364  default:
365  g_msg->Warn(WARN_BUG, "NLBeet::Do(): "
366  "Unknown event type! ", "");
367  exit(1);
368  }
369  return done;
370 }

References Landscape::BackTranslateVegTypes(), g_landscape_p, Farm::GetType(), Crop::m_first_date, FarmEvent::m_first_year, FarmEvent::m_lock, FarmEvent::m_next_tov, FarmEvent::m_startday, FarmEvent::m_todo, nl_be_ferti_p1, nl_be_ferti_p2, nl_be_ferti_s1, nl_be_ferti_s2, NL_BE_FUNGI1, nl_be_fungicide1, nl_be_fungicide2, nl_be_fungicide3, nl_be_harvest, NL_BE_HERBI1, nl_be_herbicide1, nl_be_herbicide2, nl_be_herbicide3, nl_be_herbicide4, nl_be_preseeding_cultivator, nl_be_spring_plough_sandy, nl_be_spring_sow, nl_be_start, nl_be_stubble_harrow_clay, nl_be_stubble_harrow_sandy, nl_be_winter_plough_clay, Crop::SimpleEvent_(), Farm::StubbleHarrowing(), and tof_OptimisingFarm.


The documentation for this class was generated from the following files:
nl_be_ferti_s2
Definition: NLBeet.h:49
nl_be_stubble_harrow_sandy
Definition: NLBeet.h:40
FarmEvent::m_lock
bool m_lock
Definition: farm.h:465
FarmEvent::m_first_year
bool m_first_year
Definition: farm.h:467
tof_OptimisingFarm
Definition: farm.h:273
Landscape::BackTranslateVegTypes
int BackTranslateVegTypes(TTypesOfVegetation VegReference)
Definition: Landscape.h:1669
nl_be_preseeding_cultivator
Definition: NLBeet.h:46
nl_be_fungicide3
Definition: NLBeet.h:56
Farm::GetType
TTypesOfFarm GetType(void)
Definition: farm.h:901
nl_be_spring_plough_sandy
Definition: NLBeet.h:41
nl_be_ferti_p2
Definition: NLBeet.h:48
nl_be_herbicide2
Definition: NLBeet.h:51
Crop::m_first_date
int m_first_date
Definition: farm.h:540
FarmEvent::m_startday
int m_startday
Definition: farm.h:466
nl_be_ferti_s1
Definition: NLBeet.h:45
NL_BE_FUNGI1
#define NL_BE_FUNGI1
Definition: NLBeet.h:29
nl_be_stubble_harrow_clay
Definition: NLBeet.h:42
nl_be_ferti_p1
Definition: NLBeet.h:44
NL_BE_HERBI1
#define NL_BE_HERBI1
A flag used to indicate autumn ploughing status.
Definition: NLBeet.h:28
nl_be_fungicide1
Definition: NLBeet.h:54
nl_be_fungicide2
Definition: NLBeet.h:55
nl_be_harvest
Definition: NLBeet.h:57
nl_be_herbicide4
Definition: NLBeet.h:53
FarmEvent::m_next_tov
TTypesOfVegetation m_next_tov
Definition: farm.h:471
FarmEvent::m_todo
int m_todo
Definition: farm.h:469
nl_be_herbicide3
Definition: NLBeet.h:52
nl_be_winter_plough_clay
Definition: NLBeet.h:43
nl_be_spring_sow
Definition: NLBeet.h:47
nl_be_start
Definition: NLBeet.h:38
nl_be_herbicide1
Definition: NLBeet.h:50
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