Example #1
0
        private void OnCLEMStartOfTimeStep(object sender, EventArgs e)
        {
            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd;

            // Natural weaning takes place here before animals eat or take milk from mother.
            foreach (var ind in herd.Where(a => a.Weaned == false))
            {
                double weaningAge = ind.BreedParams.NaturalWeaningAge;
                if (weaningAge == 0)
                {
                    weaningAge = ind.BreedParams.GestationLength;
                }

                if (ind.Age >= weaningAge)
                {
                    ind.Wean(true, "Natural");
                    if (ind.Mother != null)
                    {
                        // report conception status changed when last multiple birth dies.
                        ind.Mother.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Weaned, ind.Mother, Clock.Today));
                    }
                }
            }
        }
        private void OnCommencing(object sender, EventArgs e)
        {
            ruminantHerd = resources.FindResourceGroup <RuminantHerd>();

            // determine any herd filtering
            herdFilters = new List <RuminantGroup>();
            IModel current = this;

            while (current.GetType() != typeof(ZoneCLEM))
            {
                var filtergroup = current.Children.OfType <RuminantGroup>();
                if (filtergroup.Count() > 1)
                {
                    Summary.WriteWarning(this, "Multiple ruminant filter groups have been supplied for [" + current.Name + "]" + Environment.NewLine + "Only the first filter group will be used.");
                }
                if (filtergroup.FirstOrDefault() != null)
                {
                    herdFilters.Insert(0, filtergroup.FirstOrDefault());
                }
                current = current.Parent as IModel;
            }

            // get full name for reporting
            current = this;
            string name = this.Name;

            while (current.GetType() != typeof(ZoneCLEM))
            {
                string quoteName = (current.GetType() == typeof(ActivitiesHolder)) ? "[" + current.Name + "]":current.Name;
                name    = quoteName + "." + name;
                current = current.Parent as IModel;
            }
        }
Example #3
0
        private void OnCLEMAnimalMilking(object sender, EventArgs e)
        {
            if (this.TimingOK & this.Status != ActivityStatus.Ignored)
            {
                if (ProportionToRemove > 0)
                {
                    // get labour shortfall
                    double labourLimiter = 1.0;
                    if (this.Status == ActivityStatus.Partial & this.OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.UseResourcesAvailable)
                    {
                        double labourLimit    = 1;
                        double labourNeeded   = ResourceRequestList.Where(a => a.ResourceType == typeof(Labour)).Sum(a => a.Required);
                        double labourProvided = ResourceRequestList.Where(a => a.ResourceType == typeof(Labour)).Sum(a => a.Provided);
                        if (labourNeeded > 0)
                        {
                            labourLimit = labourProvided / labourNeeded;
                        }
                    }

                    // get dry breeders
                    RuminantHerd          ruminantHerd = Resources.RuminantHerd();
                    List <RuminantFemale> herd         = this.CurrentHerd(true).Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().ToList();

                    // get dry breeders from females
                    foreach (RuminantFemale female in herd.Where(a => a.Age - a.AgeAtLastBirth >= MonthsSinceBirth & a.PreviousConceptionRate >= MinimumConceptionBeforeSell & a.AgeAtLastBirth > 0))
                    {
                        if (ZoneCLEM.RandomGenerator.NextDouble() <= ProportionToRemove * labourLimiter)
                        {
                            // flag female ready to transport.
                            female.SaleFlag = HerdChangeReason.DryBreederSale;
                        }
                    }
                }
            }
        }
Example #4
0
 /// <summary>
 /// Method to determine resources required for this activity in the current month
 /// </summary>
 /// <returns>List of required resource requests</returns>
 public override List <ResourceRequest> DetermineResourcesNeeded()
 {
     ResourceRequestList = null;
     if (Clock.Today.Month == Month)
     {
         // if labour item(s) found labour will be requested for this activity.
         if (LabourRequired > 0)
         {
             if (ResourceRequestList == null)
             {
                 ResourceRequestList = new List <ResourceRequest>();
             }
             // determine head to be mustered
             RuminantHerd    ruminantHerd = Resources.RuminantHerd();
             List <Ruminant> herd         = ruminantHerd.Herd;
             int             head         = herd.Filter(this).Count();
             ResourceRequestList.Add(new ResourceRequest()
             {
                 AllowTransmutation = true,
                 Required           = Math.Ceiling(head / this.LabourHeadUnit) * this.LabourRequired,
                 ResourceName       = "Labour",
                 ResourceTypeName   = "",
                 Requestor          = this.Name,
                 FilterSortDetails  = LabourFilterList
             }
                                     );
         }
     }
     return(ResourceRequestList);
 }
Example #5
0
        private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            this.InitialiseHerd(false, true);

            bankAccount = Resources.GetResourceItem(this, typeof(Finance), BankAccountName, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.ReportErrorAndStop) as FinanceType;

            // get labour specifications
            labour = Apsim.Children(this, typeof(LabourFilterGroupSpecified)).Cast <LabourFilterGroupSpecified>().ToList(); //  this.Children.Where(a => a.GetType() == typeof(LabourFilterGroupSpecified)).Cast<LabourFilterGroupSpecified>().ToList();
            if (labour == null)
            {
                labour = new List <LabourFilterGroupSpecified>();
            }

            // get trucking settings
            trucking = Apsim.Children(this, typeof(TruckingSettings)).FirstOrDefault() as TruckingSettings;

            // check if pricing is present
            if (bankAccount != null)
            {
                RuminantHerd ruminantHerd = Resources.RuminantHerd();
                var          breeds       = ruminantHerd.Herd.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).GroupBy(a => a.HerdName);
                foreach (var herd in breeds)
                {
                    if (!herd.FirstOrDefault().BreedParams.PricingAvailable())
                    {
                        Summary.WriteWarning(this, String.Format("No pricing schedule has been provided for herd ({0}). No transactions will be recorded for activity ({1}).", herd.Key, this.Name));
                    }
                }
            }
        }
        /// <summary>
        /// Method to determine resources required for this activity in the current month
        /// </summary>
        /// <returns>List of required resource requests</returns>
        public override List <ResourceRequest> DetermineResourcesNeeded()
        {
            ResourceRequestList = null;
            if (ControlledMatings != null)
            {
                ResourceRequestList = new List <ResourceRequest>();
                RuminantHerd    ruminantHerd = Resources.RuminantHerd();
                List <Ruminant> herd         = ruminantHerd.Herd.Where(a => a.BreedParams.Name == HerdName).ToList();
                int             breeders     = (from ind in herd
                                                where
                                                (ind.Gender == Sex.Female &
                                                 ind.Age >= ind.BreedParams.MinimumAge1stMating &
                                                 ind.Weight >= (ind.BreedParams.MinimumSize1stMating * ind.StandardReferenceWeight)
                                                )
                                                select ind).Count();

                ResourceRequestList.Add(new ResourceRequest()
                {
                    AllowTransmutation = false,
                    Required           = Math.Ceiling(breeders / ControlledMatings.LabourBreedersUnit) * ControlledMatings.LabourRequired,
                    ResourceName       = "Labour",
                    ResourceTypeName   = this.HerdName,
                    Requestor          = this.Name,
                    FilterSortDetails  = ControlledMatings.LabourFilterList
                }
                                        );
            }
            return(ResourceRequestList);
        }
        private void OnCLEMPotentialIntake(object sender, EventArgs e)
        {
            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd;

            // Calculate potential intake and reset stores
            // Order age descending so breeder females calculate milkproduction before suckings grow

            DateTime start = DateTime.Now;

            foreach (var ind in herd.GroupBy(a => a.Weaned).OrderByDescending(a => a.Key))
            {
                foreach (var indi in ind)
                {
                    // reset tallies at start of the month
                    indi.DietDryMatterDigestibility = 0;
                    indi.PercentNOfIntake           = 0;
                    indi.Intake     = 0;
                    indi.MilkIntake = 0;
                    CalculatePotentialIntake(indi);
                }
            }

            var diff = DateTime.Now - start;
        }
Example #8
0
        private void OnCLEMAnimalStock(object sender, EventArgs e)
        {
            // this event happens after management has marked individuals for purchase or sale.
            if (Clock.Today.Month == AssessmentMonth)
            {
                this.Status = ActivityStatus.NotNeeded;
                // calculate dry season pasture available for each managed paddock holding stock not flagged for sale
                RuminantHerd ruminantHerd = Resources.RuminantHerd();
                foreach (var paddockGroup in ruminantHerd.Herd.Where(a => a.Location != "").GroupBy(a => a.Location))
                {
                    // multiple breeds are currently not supported as we need to work out what to do with diferent AEs
                    if (paddockGroup.GroupBy(a => a.Breed).Count() > 1)
                    {
                        throw new ApsimXException(this, "Dry season destocking paddocks with multiple breeds is currently not supported\nActivity:" + this.Name + ", Paddock: " + paddockGroup.Key);
                    }

                    // total adult equivalents not marked for sale of all breeds on pasture for utilisation
                    double totalAE = paddockGroup.Where(a => a.SaleFlag == HerdChangeReason.None).Sum(a => a.AdultEquivalent);

                    double shortfallAE = 0;
                    // Determine total feed requirements for dry season for all ruminants on the pasture
                    // We assume that all ruminant have the BaseAnimalEquivalent to the specified herd
                    shortfallAE = 0;
                    GrazeFoodStoreType pasture        = Resources.GetResourceItem(this, typeof(GrazeFoodStore), paddockGroup.Key, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop) as GrazeFoodStoreType;
                    double             pastureBiomass = pasture.Amount;

                    // Adjust fodder balance for detachment rate (6%/month)
                    double feedRequiredAE = paddockGroup.FirstOrDefault().BreedParams.BaseAnimalEquivalent * 0.02 * 30.4; //  2% of AE animal per day
                    for (int i = 0; i < this.DrySeasonLength; i++)
                    {
                        pastureBiomass *= (1.0 - pasture.DetachRate);
                        pastureBiomass -= feedRequiredAE * totalAE;
                    }

                    // Shortfall in Fodder in kg per hectare
                    // pasture at end of period in kg/ha
                    double pastureShortFallKgHa = pastureBiomass / pasture.Manager.Area;
                    // shortfall from low limit
                    pastureShortFallKgHa = Math.Max(0, FeedLowLimit - pastureShortFallKgHa);
                    // Shortfall in Fodder in kg for paddock
                    double pastureShortFallKg = pastureShortFallKgHa * pasture.Manager.Area;

                    if (pastureShortFallKg == 0)
                    {
                        return;
                    }

                    // number of AE to sell to balance shortfall_kg
                    shortfallAE = pastureShortFallKg / feedRequiredAE;

                    // get prediction
                    HandleDestocking(shortfallAE, paddockGroup.Key);
                }
            }
            else
            {
                this.Status = ActivityStatus.Ignored;
            }
        }
Example #9
0
 private void OnCommencing(object sender, EventArgs e)
 {
     ruminantHerd = resources.FindResourceGroup <RuminantHerd>();
     if (ruminantHerd is null)
     {
         return;
     }
 }
 /// <summary>
 /// Method to get the set herd filters
 /// </summary>
 public void InitialiseHerd(bool allowMultipleBreeds, bool allowMultipleHerds)
 {
     HerdResource = Resources.FindResourceGroup <RuminantHerd>();
     GetHerdFilters();
     this.allowMultipleBreeds = allowMultipleBreeds;
     this.allowMultipleHerds  = allowMultipleHerds;
     DetermineHerdName();
 }
        /// <summary>
        /// Method to perform destocking
        /// </summary>
        /// <param name="animalEquivalentsForSale"></param>
        /// <param name="paddockName"></param>
        /// <returns>The AE that were not handled</returns>
        private double HandleDestocking(double animalEquivalentsForSale, string paddockName)
        {
            if (animalEquivalentsForSale <= 0)
            {
                return(0);
            }

            // move to underutilised paddocks
            // TODO: This can be added later as an activity including spelling

            // remove all potential purchases from list as they can't be supported.
            // This does not change the shortfall AE as they were not counted in TotalAE pressure.
            RuminantHerd ruminantHerd = Resources.RuminantHerd();

            ruminantHerd.PurchaseIndividuals.RemoveAll(a => a.Location == paddockName);

            var destockGroups = FindAllChildren <RuminantGroup>().Where(a => a.Reason == RuminantStockGroupStyle.Destock);

            if (destockGroups.Count() == 0)
            {
                string warn = $"No [f=FilterGroup]s with a [Destock] Reason were provided in [a={this.Name}]\r\nNo destocking will be performed.";
                this.Status = ActivityStatus.Warning;
                if (!Warnings.Exists(warn))
                {
                    Summary.WriteWarning(this, warn);
                    Warnings.Add(warn);
                }
            }

            // remove individuals to sale as specified by destock groups
            foreach (RuminantGroup item in destockGroups)
            {
                // works with current filtered herd to obey filtering.
                var herd = CurrentHerd(false)
                           .Where(a => a.Location == paddockName && !a.ReadyForSale)
                           .FilterRuminants(item).FilterRuminants(item).FilterRuminants(item)
                           .ToList();

                int cnt = 0;
                while (cnt < herd.Count() && animalEquivalentsForSale > 0)
                {
                    if (herd[cnt].SaleFlag != HerdChangeReason.DestockSale)
                    {
                        animalEquivalentsForSale -= herd[cnt].AdultEquivalent;
                        herd[cnt].SaleFlag        = HerdChangeReason.DestockSale;
                    }
                    cnt++;
                }
                if (animalEquivalentsForSale <= 0)
                {
                    return(0);
                }
            }
            return(animalEquivalentsForSale);

            // handling of sucklings with sold female is in RuminantActivityBuySell
            // buy or sell is handled by the buy sell activity
        }
Example #12
0
        private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            this.InitialiseHerd(false, true);
            breedParams = Resources.GetResourceItem(this, typeof(RuminantHerd), this.PredictedHerdName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop) as RuminantType;

            // max sires
            if (MaximumSiresKept < 1 & MaximumSiresKept > 0)
            {
                SiresKept = Convert.ToInt32(Math.Ceiling(MaximumBreedersKept * MaximumSiresKept), CultureInfo.InvariantCulture);
            }
            else
            {
                SiresKept = Convert.ToInt32(Math.Truncate(MaximumSiresKept), CultureInfo.InvariantCulture);
            }

            if (FillBreedingMalesAtStartup)
            {
                RuminantHerd herd = Resources.RuminantHerd();
                if (herd != null)
                {
                    // get number in herd
                    int numberPresent = this.CurrentHerd(false).Where(a => a.Gender == Sex.Male).Cast <RuminantMale>().Where(a => a.BreedingSire).Count();
                    // fill to number needed
                    for (int i = numberPresent; i < SiresKept; i++)
                    {
                        RuminantMale newbull = new RuminantMale(48, Sex.Male, 450, breedParams)
                        {
                            Breed          = this.PredictedHerdBreed,
                            HerdName       = this.PredictedHerdName,
                            BreedingSire   = true,
                            ID             = herd.NextUniqueID,
                            PreviousWeight = 450,
                            SaleFlag       = HerdChangeReason.InitialHerd
                        };
                        herd.AddRuminant(newbull, this);
                    }
                }
            }

            // check GrazeFoodStoreExists
            grazeStore = "";
            if (GrazeFoodStoreName != null && !GrazeFoodStoreName.StartsWith("Not specified"))
            {
                grazeStore = GrazeFoodStoreName.Split('.').Last();
                foodStore  = Resources.GetResourceItem(this, GrazeFoodStoreName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop) as GrazeFoodStoreType;
            }

            // check for managed paddocks and warn if animals placed in yards.
            if (grazeStore == "")
            {
                var ah = Apsim.Find(this, typeof(ActivitiesHolder));
                if (Apsim.ChildrenRecursively(ah, typeof(PastureActivityManage)).Count() != 0)
                {
                    Summary.WriteWarning(this, String.Format("Animals purchased by [a={0}] are currently placed in [Not specified - general yards] while a managed pasture is available. These animals will not graze until mustered and will require feeding while in yards.\nSolution: Set the [GrazeFoodStore to place purchase in] located in the properties [General].[PastureDetails]", this.Name));
                }
            }
        }
Example #13
0
        private void OnCLEMHerdSummary(object sender, EventArgs e)
        {
            timestep++;
            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd;

            // one individual
            herd = herd.ToList();

            // group by breed
            foreach (var breedGroup in herd.GroupBy(a => a.Breed))
            {
                // group by herd
                foreach (var herdGroup in breedGroup.GroupBy(a => a.HerdName))
                {
                    // group by sex
                    foreach (var sexGroup in herdGroup.GroupBy(a => a.Gender))
                    {
                        // weaned
                        foreach (var ageGroup in sexGroup.OrderBy(a => a.Age).GroupBy(a => Math.Truncate(a.Age / 12.0)))
                        {
                            ReportDetails                   = new HerdReportItemGeneratedEventArgs();
                            ReportDetails.TimeStep          = timestep;
                            ReportDetails.Breed             = breedGroup.Key;
                            ReportDetails.Herd              = herdGroup.Key;
                            ReportDetails.Age               = Convert.ToInt32(ageGroup.Key);
                            ReportDetails.Sex               = sexGroup.Key.ToString().Substring(0, 1);
                            ReportDetails.Number            = ageGroup.Sum(a => a.Number);
                            ReportDetails.AverageWeight     = ageGroup.Average(a => a.Weight);
                            ReportDetails.AverageWeightGain = ageGroup.Average(a => a.WeightGain);
                            ReportDetails.AverageIntake     = ageGroup.Average(a => (a.Intake + a.MilkIntake)); //now daily/30.4;
                            ReportDetails.AdultEquivalents  = ageGroup.Sum(a => a.AdultEquivalent);
                            if (sexGroup.Key == Sex.Female)
                            {
                                ReportDetails.NumberPregnant  = ageGroup.Cast <RuminantFemale>().Where(a => a.IsPregnant).Count();
                                ReportDetails.NumberLactating = ageGroup.Cast <RuminantFemale>().Where(a => a.IsLactating).Count();
                                ReportDetails.NumberOfBirths  = ageGroup.Cast <RuminantFemale>().Sum(a => a.NumberOfBirthsThisTimestep);
                            }
                            else
                            {
                                ReportDetails.NumberPregnant  = 0;
                                ReportDetails.NumberLactating = 0;
                                ReportDetails.NumberOfBirths  = 0;
                            }

                            ReportItemGenerated(ReportDetails);

                            // reset birth count
                            if (sexGroup.Key == Sex.Female)
                            {
                                ageGroup.Cast <RuminantFemale>().ToList().ForEach(a => a.NumberOfBirthsThisTimestep = 0);
                            }
                        }
                    }
                }
            }
        }
        private void HandleDestocking(double animalEquivalentsforSale, string paddockName)
        {
            if (animalEquivalentsforSale <= 0)
            {
                AeDestocked = 0;
                this.Status = ActivityStatus.Ignored;
                return;
            }

            // move to underutilised paddocks
            // TODO: This can be added later as an activity including spelling

            // remove all potential purchases from list as they can't be supported.
            // This does not change the shortfall AE as they were not counted in TotalAE pressure.
            RuminantHerd ruminantHerd = Resources.RuminantHerd();

            ruminantHerd.PurchaseIndividuals.RemoveAll(a => a.Location == paddockName);

            // remove individuals to sale as specified by destock groups
            foreach (RuminantDestockGroup item in this.Children.Where(a => a.GetType() == typeof(RuminantDestockGroup)))
            {
                // works with current filtered herd to obey filtering.
                List <Ruminant> herd = this.CurrentHerd(false).Where(a => a.Location == paddockName && !a.ReadyForSale).ToList();
                herd = herd.Filter(item);
                int cnt = 0;
                while (cnt < herd.Count() && animalEquivalentsforSale > 0)
                {
                    this.Status = ActivityStatus.Success;
                    animalEquivalentsforSale -= herd[cnt].AdultEquivalent;
                    herd[cnt].SaleFlag        = HerdChangeReason.DestockSale;
                    //if (animalEquivalentsforSale < herd.Min(a => a.AdultEquivalent))
                    //{
                    //    animalEquivalentsforSale = 0;
                    //}
                    cnt++;
                }
                if (animalEquivalentsforSale <= 0)
                {
                    AeDestocked = 0;
                    this.Status = ActivityStatus.Success;
                    return;
                }
            }
            AeDestocked = AeToDestock - animalEquivalentsforSale;
            this.Status = ActivityStatus.Partial;

            // Idea of possible destock groups
            // Steers, Male, Not BreedingSire, > Age
            // Dry Cows, IsDryBreeder
            // Breeders, IsBreeder, !IsPregnant, > Age
            // Underweight ProportionOfMaxWeight < 0.6

            // handling of sucklings with sold female is in RuminantActivityBuySell

            // buy or sell is handled by the buy sell activity
        }
Example #15
0
        private void OnCLEMAgeResources(object sender, EventArgs e)
        {
            RuminantHerd ruminantHerd = Resources.RuminantHerd();

            // grow all individuals
            foreach (Ruminant ind in ruminantHerd.Herd)
            {
                ind.IncrementAge();
            }
        }
        private void OnWFAnimalDeath(object sender, EventArgs e)
        {
            // remove individuals that died
            // currently performed in the month after weight has been adjusted
            // and before breeding, trading, culling etc (See Clock event order)

            // Calculated by
            // critical weight &
            // juvenile (unweaned) death based on mothers weight &
            // adult weight adjusted base mortality.

            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd;

            // weight based mortality
            List <Ruminant> died = herd.Where(a => a.Weight < (a.HighWeight * (1.0 - a.BreedParams.ProportionOfMaxWeightToSurvive))).ToList();

            // set died flag
            died.Select(a => { a.SaleFlag = Common.HerdChangeReason.Died; return(a); }).ToList();
            ruminantHerd.RemoveRuminant(died);

            // base mortality adjusted for condition
            foreach (var ind in ruminantHerd.Herd)
            {
                double mortalityRate = 0;
                if (!ind.Weaned)
                {
                    mortalityRate = 0;
                    if ((ind.Mother == null) || (ind.Mother.Weight < ind.BreedParams.CriticalCowWeight * ind.StandardReferenceWeight))
                    {
                        // if no mohter assigned or mother's weight is < CriticalCowWeight * SFR
                        mortalityRate = ind.BreedParams.JuvenileMortalityMaximum;
                    }
                    else
                    {
                        // if mother's weight >= criticalCowWeight * SFR
                        mortalityRate = Math.Exp(-Math.Pow(ind.BreedParams.JuvenileMortalityCoefficient * (ind.Mother.Weight / ind.Mother.NormalisedAnimalWeight), ind.BreedParams.JuvenileMortalityExponent));
                    }
                    mortalityRate = mortalityRate + ind.BreedParams.MortalityBase;
                    mortalityRate = Math.Max(mortalityRate, ind.BreedParams.JuvenileMortalityMaximum);
                }
                else
                {
                    mortalityRate = 1 - (1 - ind.BreedParams.MortalityBase) * (1 - Math.Exp(Math.Pow(-(ind.BreedParams.MortalityCoefficient * (ind.Weight / ind.NormalisedAnimalWeight - ind.BreedParams.MortalityIntercept)), ind.BreedParams.MortalityExponent)));
                }
                if (WholeFarm.RandomGenerator.NextDouble() <= mortalityRate)
                {
                    ind.Died = true;
                }
            }

            died = herd.Where(a => a.Died).ToList();
            died.Select(a => { a.SaleFlag = Common.HerdChangeReason.Died; return(a); }).ToList();
            ruminantHerd.RemoveRuminant(died);
        }
        private void OnWFAgeResources(object sender, EventArgs e)
        {
            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd;

            // grow all individuals
            foreach (Ruminant ind in herd)
            {
                ind.Age++;
            }
        }
Example #18
0
        private void OnWFRequestFeed(object sender, EventArgs e)
        {
            if (labourLimiter > 0)
            {
                RuminantHerd    ruminantHerd = Resources.RuminantHerd();
                List <Ruminant> herd         = ruminantHerd.Herd;

                if (herd == null && herd.Count == 0)
                {
                    return;
                }

                // get month from clock
                int month = Clock.Today.Month;

                // get list from filters
                foreach (var child in this.Children)
                {
                    if (child.GetType() == typeof(RuminantFilterGroup))
                    {
                        foreach (Ruminant ind in herd.Filter(child as RuminantFilterGroup))
                        {
                            RuminantFeedRequest freqest = new RuminantFeedRequest();
                            freqest.FeedActivity = this;
                            freqest.Requestor    = ind;
                            freqest.Amount       = 0;
                            switch (FeedStyle)
                            {
                            case RuminantFeedActivityTypes.SpecifiedDailyAmount:
                                freqest.Amount = (child as RuminantFilterGroup).MonthlyValues[month - 1] * 30.4;                                         // * ind.Number;
                                break;

                            case RuminantFeedActivityTypes.ProportionOfWeight:
                                freqest.Amount = (child as RuminantFilterGroup).MonthlyValues[month - 1] * ind.Weight * 30.4;                                        // * ind.Number;
                                break;

                            case RuminantFeedActivityTypes.ProportionOfPotentialIntake:
                                freqest.Amount = (child as RuminantFilterGroup).MonthlyValues[month - 1] * ind.PotentialIntake;                                         // * ind.Number;
                                break;

                            case RuminantFeedActivityTypes.ProportionOfRemainingIntakeRequired:
                                freqest.Amount = (child as RuminantFilterGroup).MonthlyValues[month - 1] * (ind.PotentialIntake - ind.Intake);                                         // * ind.Number;
                                break;

                            default:
                                break;
                            }
                            freqest.Amount *= labourLimiter;
                            FoodSource.Remove(freqest);
                        }
                    }
                }
            }
        }
        private void OnCLEMAnimalStock(object sender, EventArgs e)
        {
            // this event happens after management has marked individuals for purchase or sale.
            if (Clock.Today.Month == AssessmentMonth)
            {
                // Get ENSO forcase for current time
                ENSOState forecastEnsoState = GetENSOMeasure();

                // calculate dry season pasture available for each managed paddock holding stock
                RuminantHerd ruminantHerd = Resources.RuminantHerd();
                foreach (var newgroup in ruminantHerd.Herd.Where(a => a.Location != "").GroupBy(a => a.Location))
                {
                    // total adult equivalents of all breeds on pasture for utilisation
                    double totalAE = newgroup.Sum(a => a.AdultEquivalent);
                    // determine AE marked for sale and purchase of managed herd
                    double markedForSaleAE = newgroup.Where(a => a.ReadyForSale && a.HerdName == HerdName).Sum(a => a.AdultEquivalent);
                    double purchaseAE      = ruminantHerd.PurchaseIndividuals.Where(a => a.Location == newgroup.Key && a.HerdName == HerdName).Sum(a => a.AdultEquivalent);

                    double herdChange = 1.0;
                    switch (forecastEnsoState)
                    {
                    case ENSOState.Neutral:
                        break;

                    case ENSOState.ElNino:
                        GrazeFoodStoreType pasture = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType;
                        double             kgha    = pasture.TonnesPerHectare * 1000;
                        //NOTE: ensure calculation method in relationship is fixed values
                        herdChange = this.PastureToStockingChangeElNino.SolveY(kgha);
                        break;

                    case ENSOState.LaNina:
                        pasture    = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType;
                        kgha       = pasture.TonnesPerHectare * 1000;
                        herdChange = this.PastureToStockingChangeLaNina.SolveY(kgha);
                        break;

                    default:
                        break;
                    }
                    if (herdChange > 1.0)
                    {
                        double toBuyAE = Math.Max(0, (totalAE * herdChange) - purchaseAE);
                        HandleRestocking(toBuyAE, newgroup.Key, newgroup.FirstOrDefault());
                    }
                    else if (herdChange < 1.0)
                    {
                        double toSellAE = Math.Max(0, (totalAE * (1 - herdChange)) - markedForSaleAE);
                        HandleDestocking(toSellAE, newgroup.Key);
                    }
                }
            }
        }
        private void HandleDestocking(double animalEquivalentsforSale, string paddockName)
        {
            if (animalEquivalentsforSale <= 0)
            {
                AeDestocked = 0;
                this.Status = ActivityStatus.Ignored;
                return;
            }

            // move to underutilised paddocks
            // TODO: This can be added later as an activity including spelling

            // remove all potential purchases from list as they can't be supported.
            // This does not change the shortfall AE as they were not counted in TotalAE pressure.
            RuminantHerd ruminantHerd = Resources.RuminantHerd();

            ruminantHerd.PurchaseIndividuals.RemoveAll(a => a.Location == paddockName);

            // remove individuals to sale as specified by destock groups
            foreach (var item in FindAllChildren <RuminantGroup>().Where(a => a.Reason == RuminantStockGroupStyle.Destock))
            {
                // works with current filtered herd to obey filtering.
                var herd = CurrentHerd(false)
                           .Where(a => a.Location == paddockName && !a.ReadyForSale)
                           .FilterRuminants(item)
                           .ToList();

                int cnt = 0;
                while (cnt < herd.Count() && animalEquivalentsforSale > 0)
                {
                    this.Status = ActivityStatus.Success;
                    if (herd[cnt].SaleFlag != HerdChangeReason.DestockSale)
                    {
                        animalEquivalentsforSale -= herd[cnt].AdultEquivalent;
                        herd[cnt].SaleFlag        = HerdChangeReason.DestockSale;
                    }
                    cnt++;
                }
                if (animalEquivalentsforSale <= 0)
                {
                    AeDestocked = 0;
                    this.Status = ActivityStatus.Success;
                    return;
                }
            }
            AeDestocked = AeToDestock - animalEquivalentsforSale;
            this.Status = ActivityStatus.Partial;

            // handling of sucklings with sold female is in RuminantActivityBuySell
            // buy or sell is handled by the buy sell activity
        }
Example #21
0
        public IEnumerable <RuminantType> GetRuminants(RuminantHerd herd)
        {
            List <RuminantType> types = new List <RuminantType>();

            // Iterate over all breeds, adding cohorts and pricing to each
            foreach (string breed in PresentBreeds)
            {
                RuminantType type = new RuminantType(herd, breed);
                SetParameters(type);
                types.Add(type);
            }

            return(types);
        }
        private void OnCLEMAnimalStock(object sender, EventArgs e)
        {
            // this event happens after management has marked individuals for purchase or sale.
            if (Clock.Today.Month == AssessmentMonth)
            {
                // calculate dry season pasture available for each managed paddock holding stock not flagged for sale
                RuminantHerd ruminantHerd = Resources.RuminantHerd();
                foreach (var paddockGroup in ruminantHerd.Herd.Where(a => a.Location != "" & a.SaleFlag == HerdChangeReason.None).GroupBy(a => a.Location))
                {
                    // total adult equivalents of all breeds on pasture for utilisation
                    double AETotal = paddockGroup.Sum(a => a.AdultEquivalent);
                    // determine AE marked for sale and purchase of managed herd
                    double AEmarkedForSale = paddockGroup.Where(a => a.ReadyForSale & a.HerdName == HerdName).Sum(a => a.AdultEquivalent);
                    double AEPurchase      = ruminantHerd.PurchaseIndividuals.Where(a => a.Location == paddockGroup.Key & a.HerdName == HerdName).Sum(a => a.AdultEquivalent);

                    double ShortfallAE = 0;
                    // Determine total feed requirements for dry season for all ruminants on the pasture
                    // We assume that all ruminant have the BaseAnimalEquivalent to the specified herd
                    ShortfallAE = 0;
                    GrazeFoodStoreType pasture        = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), paddockGroup.Key, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop) as GrazeFoodStoreType;
                    double             pastureBiomass = pasture.Amount;

                    // Adjust fodder balance for detachment rate (6%/month)
                    double feedRequiredAE = paddockGroup.FirstOrDefault().BreedParams.BaseAnimalEquivalent * 0.02 * 30.4; //  2% of AE animal per day
                    for (int i = 0; i < this.DrySeasonLength; i++)
                    {
                        pastureBiomass *= (1.0 - pasture.DetachRate);
                        pastureBiomass -= feedRequiredAE * AETotal;
                    }

                    // Shortfall in Fodder in kg per hectare
                    double pastureShortFallKgHa = pastureBiomass / pasture.Area;
                    pastureShortFallKgHa = Math.Max(0, pastureShortFallKgHa - FeedLowLimit);
                    // Shortfalll in Fodder in kg for paddock
                    double pastureShortFallKg = pastureShortFallKgHa * pasture.Area;

                    if (pastureShortFallKg == 0)
                    {
                        return;
                    }

                    // number of AE to sell to balance shortfall_kg
                    ShortfallAE = pastureShortFallKg / feedRequiredAE;

                    // get prediction
                    HandleDestocking(ShortfallAE, paddockGroup.Key);
                }
            }
        }
        private void OnWFAnimalBuy(object sender, EventArgs e)
        {
            RuminantHerd ruminantHerd = Resources.RuminantHerd();

            Finance     Accounts    = Resources.FinanceResource() as Finance;
            FinanceType bankAccount = Accounts.GetFirst() as FinanceType;

            var newRequests = ruminantHerd.PurchaseIndividuals.Where(a => a.BreedParams.Breed == BreedName).ToList();

            foreach (var newgroup in newRequests.GroupBy(a => a.SaleFlag))
            {
                double fundsAvailable = 100000000;
                if (bankAccount != null)
                {
                    fundsAvailable = bankAccount.FundsAvailable;
                }
                double cost = 0;
                foreach (var newind in newgroup)
                {
                    double value = 0;
                    if (newgroup.Key == Common.HerdChangeReason.SirePurchase)
                    {
                        value = BreedingSirePrice;
                    }
                    else
                    {
                        RuminantValue getvalue = PriceList.Where(a => a.Age < newind.Age).OrderBy(a => a.Age).LastOrDefault();
                        value = getvalue.PurchaseValue * ((getvalue.Style == Common.PricingStyleType.perKg) ? newind.Weight : 1.0);
                    }
                    if (cost + value <= fundsAvailable)
                    {
                        ruminantHerd.AddRuminant(newind);
                        cost += value;
                    }
                    else
                    {
                        break;
                    }
                }
                if (bankAccount != null)
                {
                    bankAccount.Remove(cost, this.Name, newgroup.Key.ToString());
                }
            }
        }
Example #24
0
        /// <summary>
        /// Validate model
        /// </summary>
        /// <param name="validationContext"></param>
        /// <returns></returns>
        public IEnumerable <ValidationResult> Validate(ValidationContext validationContext)
        {
            ruminantHerd = resources.FindResourceGroup <RuminantHerd>();
            var results = new List <ValidationResult>();

            // check that this activity has a parent of type CropActivityManageProduct

            if (ruminantHerd is null)
            {
                string[] memberNames = new string[] { "Missing resource" };
                results.Add(new ValidationResult($"No ruminant herd resource could be found for [ReportRuminantAttributeSummary] [{this.Name}]", memberNames));
            }
            if (!this.FindAllChildren <RuminantGroup>().Any())
            {
                string[] memberNames = new string[] { "Missing ruminant filter group" };
                results.Add(new ValidationResult($"The [ReportRuminantAttributeSummary] [{this.Name}] requires at least one filter group to identify individuals to report", memberNames));
            }
            return(results);
        }
Example #25
0
        private void OnCLEMStartOfTimeStep(object sender, EventArgs e)
        {
            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd;

            // Natural weaning takes place here before animals eat or take milk from mother.
            foreach (var ind in herd.Where(a => a.Weaned == false))
            {
                double weaningAge = ind.BreedParams.NaturalWeaningAge;
                if (weaningAge == 0)
                {
                    weaningAge = ind.BreedParams.GestationLength;
                }

                if (ind.Age >= weaningAge)
                {
                    ind.Wean(true, "Natural");
                }
            }
        }
        private void OnWFPotentialIntake(object sender, EventArgs e)
        {
            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd;

            // Natural weaning takes place here before animals eat or take milk from mother.
            foreach (var ind in herd.Where(a => a.Weaned == false))
            {
                if (ind.Age >= ind.BreedParams.GestationLength + 1)
                {
                    ind.Wean();
                }
            }

            // Calculate potential intake and reset stores
            foreach (var ind in herd)
            {
                // reset tallies at start of the month
                ind.DietDryMatterDigestibility = 0;
                ind.PercentNOfIntake           = 0;
                ind.Intake     = 0;
                ind.MilkIntake = 0;
                CalculatePotentialIntake(ind);
            }

            // TODO: Future cohort based run may speed up simulation
            // Calculate by cohort method and assign values to individuals.
            // Need work out what grouping should be based on Name, Breed, Gender, Weight, Parity...
            // This approach will not currently work as individual may have individual weights and females may be in various states of breeding.
            //
            //var cohorts = herd.GroupBy(a => new { a.BreedParams.Breed, a.Gender, a.Age, lactating = (a.DryBreeder | a.Milk) });
            //foreach (var cohort in cohorts)
            //{
            //	CalculatePotentialIntake(cohort.FirstOrDefault());
            //	double potintake = cohort.FirstOrDefault().PotentialIntake;
            //	foreach (var ind in cohort)
            //	{
            //		ind.PotentialIntake = potintake;
            //	}
            //}
        }
        private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            this.InitialiseHerd(false, true);
            List <Ruminant> testherd = this.CurrentHerd(true);

            // check if finance is available and warn if not supplying bank account.
            if (Resources.ResourceGroupExist(typeof(Finance)))
            {
                if (Resources.ResourceItemsExist(typeof(Finance)))
                {
                    if (BankAccountName == "")
                    {
                        Summary.WriteWarning(this, "No bank account has been specified in [a={0}] while Finances are available in the simulation. No financial transactions will be recorded for the purchase and sale of animals.");
                    }
                }
            }
            if (BankAccountName != "")
            {
                bankAccount = Resources.GetResourceItem(this, BankAccountName, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.ReportErrorAndStop) as FinanceType;
            }

            // get trucking settings
            trucking = Apsim.Children(this, typeof(TruckingSettings)).FirstOrDefault() as TruckingSettings;

            // check if pricing is present
            if (bankAccount != null)
            {
                RuminantHerd ruminantHerd = Resources.RuminantHerd();
                var          breeds       = ruminantHerd.Herd.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).GroupBy(a => a.HerdName);
                foreach (var herd in breeds)
                {
                    if (!herd.FirstOrDefault().BreedParams.PricingAvailable())
                    {
                        Summary.WriteWarning(this, String.Format("No pricing schedule has been provided for herd [r={0}]. No transactions will be recorded for activity [a={1}]", herd.Key, this.Name));
                    }
                }
            }
        }
Example #28
0
        /// <summary>
        /// Model all present ruminant breeds
        /// </summary>
        public IEnumerable <RuminantType> GetRuminants(RuminantHerd parent)
        {
            List <RuminantType> ruminants = new List <RuminantType>();

            // Iterate over all the present breeds
            foreach (int id in RumIDs)
            {
                RumActiveID = id;

                string breed = RumNumbers.ColumnNames[id].Replace(".", "");

                RuminantType ruminant = new RuminantType(parent)
                {
                    Name  = breed,
                    Breed = breed
                };
                SetParameters(ruminant);

                ruminants.Add(ruminant);
            }

            return(ruminants);
        }
        /// <summary>
        /// Method to determine resources required for this activity in the current month
        /// </summary>
        /// <returns>List of required resource requests</returns>
        public override List <ResourceRequest> GetResourcesNeededForActivity()
        {
            ResourceRequestList = null;
            double kgPerHa = grazeType.Amount / paddockActivity.Area;

            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd.Where(a => a.Location == PaddockName).ToList();

            if (herd.Count() > 0)
            {
                double amount = 0;
                // get list of all Ruminants in this paddock
                foreach (Ruminant ind in herd)
                {
                    // Reduce potential intake based on pasture quality for the proportion consumed.

                    // TODO: build in pasture quality intake correction

                    // calculate intake from potential modified by pasture availability and hours grazed
                    amount += ind.PotentialIntake * (1 - Math.Exp(-ind.BreedParams.IntakeCoefficientBiomass * kgPerHa)) * (HoursGrazed / 8);
                }
                if (ResourceRequestList == null)
                {
                    ResourceRequestList = new List <ResourceRequest>();
                }
                ResourceRequestList.Add(new ResourceRequest()
                {
                    AllowTransmutation = true,
                    Required           = amount,
                    ResourceType       = typeof(GrazeFoodStore),
                    ResourceTypeName   = this.grazeType.Name,
                    ActivityModel      = this
                }
                                        );
            }
            return(ResourceRequestList);
        }
Example #30
0
        private void Muster()
        {
            // get herd to muster
            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd;

            if (herd == null && herd.Count == 0)
            {
                return;
            }

            // get list from filters
            foreach (Ruminant ind in herd.Filter(this))
            {
                // set new location ID
                ind.Location = pasture.Name;

                // check if sucklings are to be moved with mother
                if (MoveSucklings)
                {
                    // if female
                    if (ind.GetType() == typeof(RuminantFemale))
                    {
                        RuminantFemale female = ind as RuminantFemale;
                        // check if mother with sucklings
                        if (female.SucklingOffspring.Count > 0)
                        {
                            foreach (var suckling in female.SucklingOffspring)
                            {
                                suckling.Location = pasture.Name;
                            }
                        }
                    }
                }
            }
        }