private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            InsideMultiHarvestSequence = false;

            // activity is performed in CLEMDoCutAndCarry not CLEMGetResources
            this.AllocationStyle = ResourceAllocationStyle.Manual;

            fileCrop = simulation.FindAllDescendants().Where(a => a.Name == ModelNameFileCrop).FirstOrDefault() as IFileCrop;
            if (fileCrop == null)
            {
                throw new ApsimXException(this, String.Format("Unable to locate crop data reader [x={0}] requested by [a={1}]", this.ModelNameFileCrop ?? "Unknown", this.Name));
            }

            LinkedResourceItem = Resources.FindResourceType <ResourceBaseWithTransactions, IResourceType>(this, StoreItemName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop);
            if ((LinkedResourceItem as Model).Parent is GrazeFoodStore)
            {
                // set manager of graze food store if linked
                (LinkedResourceItem as GrazeFoodStoreType).Manager = (Parent as IPastureManager);
                addReason = "Growth";
            }

            // look up tree until we find a parent to allow nested crop products for rotate vs mixed cropping/products
            parentManagementActivity = FindAncestor <CropActivityManageCrop>();

            // Retrieve harvest data from the forage file for the entire run.
            // only get entries where a harvest happened (Amtkg > 0)
            HarvestData = fileCrop.GetCropDataForEntireRun(parentManagementActivity.LinkedLandItem.SoilType, CropName,
                                                           clock.StartDate, clock.EndDate).Where(a => a.AmtKg > 0).OrderBy(a => a.Year * 100 + a.Month).ToList <CropDataType>();
            if ((HarvestData == null) || (HarvestData.Count == 0))
            {
                Summary.WriteWarning(this, $"Unable to locate any harvest data in [x={fileCrop.Name}] using [x={fileCrop.FileName}] for soil type [{parentManagementActivity.LinkedLandItem.SoilType}] and crop name [{CropName}] between the dates [{clock.StartDate.ToShortDateString()}] and [{clock.EndDate.ToShortDateString()}]");
            }

            IsTreeCrop = (TreesPerHa == 0) ? false : true;  //using this boolean just makes things more readable.

            UnitsToHaConverter = (parentManagementActivity.LinkedLandItem.Parent as Land).UnitsOfAreaToHaConversion;

            // locate a cut and carry limiter associated with this event.
            limiter = LocateCutAndCarryLimiter(this);

            // check if harvest type tags have been provided
            HarvestTagsUsed = HarvestData.Where(a => a.HarvestType != "").Count() > 0;

            if (LinkedResourceItem is GrazeFoodStoreType)
            {
                double       firstMonthsGrowth = 0;
                CropDataType cropData          = HarvestData.Where(a => a.Year == clock.StartDate.Year && a.Month == clock.StartDate.Month).FirstOrDefault();
                if (cropData != null)
                {
                    firstMonthsGrowth = cropData.AmtKg;
                }

                (LinkedResourceItem as GrazeFoodStoreType).SetupStartingPasturePools(UnitsToHaConverter * (Parent as CropActivityManageCrop).Area * UnitsToHaConverter, firstMonthsGrowth);
                addReason = "Growth";
            }
        }
Пример #2
0
        /// <summary>
        /// Get the cost date from the harvest date.
        /// This will happen every month in case the harvest has occured and there is a new harvest date.
        /// </summary>
        /// <returns></returns>
        private DateTime CostDateFromHarvestDate()
        {
            DateTime     nextdate;
            CropDataType nextharvest = parentGrowCrop.HarvestData.FirstOrDefault();

            if (nextharvest != null)
            {
                nextdate = nextharvest.HarvestDate;
                return(nextdate.AddMonths(-1 * MthsBeforeHarvest));
            }
            else
            {
                return(new DateTime());
            }
        }
Пример #3
0
        private void OnCLEMDoCutAndCarry(object sender, EventArgs e)
        {
            int year  = Clock.Today.Year;
            int month = Clock.Today.Month;

            //nb. we are relying on the fact that the HarvestData list is sorted by date.
            CropDataType nextHarvest = HarvestData.FirstOrDefault();

            if (nextHarvest != null)
            {
                //if this month is a harvest month for this crop
                if ((year == nextHarvest.Year) && (month == nextHarvest.Month))
                {
                    double totalamount;
                    if (IsTreeCrop)
                    {
                        totalamount = nextHarvest.AmtKg * TreesPerHa * cropLand.Area * unitsToHaConverter * (PercentKept / 100);
                    }
                    else
                    {
                        totalamount = nextHarvest.AmtKg * cropLand.Area * unitsToHaConverter * (PercentKept / 100);
                    }


                    switch (Store)
                    {
                    case StoresForCrops.HumanFoodStore:
                        if (totalamount > 0)
                        {
                            //TODO: check that there is no N provided with grain
                            LinkedHumanFoodItem.Add(totalamount, this.Name, "Harvest");
                        }
                        break;

                    case StoresForCrops.AnimalFoodStore:
                        if (totalamount > 0)
                        {
                            //if Npct column was not in the file
                            if (nextHarvest.Npct == double.NaN)
                            {
                                //Add without adding any new nitrogen.
                                //The nitrogen value for this feed item in the store remains the same.
                                LinkedAnimalFoodItem.Add(totalamount, this.Name, "Harvest");
                            }
                            else
                            {
                                FoodResourcePacket packet = new FoodResourcePacket()
                                {
                                    Amount   = totalamount,
                                    PercentN = nextHarvest.Npct
                                };
                                LinkedAnimalFoodItem.Add(packet, this.Name, "Harvest");
                            }
                        }
                        break;

                    case StoresForCrops.ProductStore:
                        if (totalamount > 0)
                        {
                            LinkedProductItem.Add(totalamount, this.Name, "Harvest");
                        }
                        break;

                    default:
                        throw new Exception(String.Format("Store {0} is not supported for {1}", Enum.GetName(typeof(StoresForCrops), Store), this.Name));
                    }



                    //Now remove the first item from the harvest data list because it has happened.

                    //This causes a problem for the children of this model
                    //because of a race condition that occurs if user sets MthsBeforeHarvest = 0
                    //for any of the children of this model.
                    //Then because this model and children are all executing on the harvest month and
                    //this executes first and it removes the harvest from the harvest list,
                    //then the chidren never get the Clock.Today == harvest date (aka costdate).
                    //So to fix this problem, in the children we store the next harvest date (aka costdate)
                    //in a global variable and don't update its value
                    //until after we have done the Clock.Today == harvest date (aka costdate) comparison.

                    HarvestData.RemoveAt(0);
                }
            }
        }