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);
                    }
                }
            }
        }
Example #2
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)
            {
                // 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 AETotal = newgroup.Sum(a => a.AdultEquivalent);
                    // determine AE marked for sale and purchase of managed herd
                    double AEmarkedForSale = newgroup.Where(a => a.ReadyForSale & a.HerdName == HerdName).Sum(a => a.AdultEquivalent);
                    double AEPurchase      = 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;
                        herdChange = this.PastureToStockingChangeElNino.SolveY(kgha, false);
                        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, false);
                        break;

                    default:
                        break;
                    }
                    if (herdChange > 1.0)
                    {
                        double AEtoBuy = Math.Max(0, (AETotal * herdChange) - AEPurchase);
                        HandleRestocking(AEtoBuy, newgroup.Key, newgroup.FirstOrDefault());
                    }
                    else if (herdChange < 1.0)
                    {
                        double AEtoSell = Math.Max(0, (AETotal * (1 - herdChange)) - AEmarkedForSale);
                        HandleDestocking(AEtoSell, newgroup.Key);
                    }

                    //switch (ForecastEnsoState)
                    //{
                    //    case ENSOState.Neutral:
                    //        break;
                    //    case ENSOState.LaNina:
                    //        double AEtoBuy = 0;
                    //        GrazeFoodStoreType pasture = Resources.GetResourceItem(typeof(GrazeFoodStoreType), newgroup.Key, out available) as GrazeFoodStoreType;
                    //        double kgha = pasture.TonnesPerHectare * 1000;
                    //        if (kgha > 3000)
                    //        {
                    //            AEtoBuy = AETotal * 0.2; //Buy 20% of Total Animal Equivalents
                    //        }
                    //        else if (kgha < 1000)
                    //        {
                    //            AEtoBuy = 0; //Don't buy any nore
                    //        }
                    //        else
                    //        {
                    //            AEtoBuy = AETotal * 0.1; //Buy 10 % of Total Animal Equivalents
                    //        }
                    //        // adjust for the AE already marked for purchase if any
                    //        AEtoBuy = Math.Max(0, AEtoBuy - AEPurchase);
                    //        HandleRestocking(AEtoBuy, newgroup.Key, newgroup.FirstOrDefault());
                    //        break;
                    //    case ENSOState.ElNino:
                    //        pasture = Resources.GetResourceItem(typeof(GrazeFoodStoreType), newgroup.Key, out available) as GrazeFoodStoreType;
                    //        kgha = pasture.TonnesPerHectare * 1000;
                    //        if (kgha > 3000)
                    //        {
                    //            ShortfallAE = AETotal * 0.1; //Sell 10% of Total Animal Equivalents
                    //        }
                    //        else if (kgha < 1000)
                    //        {
                    //            ShortfallAE = AETotal * 0.3; //Sell 30% of Total Animal Equivalents
                    //        }
                    //        else
                    //        {
                    //            ShortfallAE = AETotal * 0.2; //Sell 20 % of Total Animal Equivalents
                    //        }
                    //        // Adjust for AE already flagged for sale if any
                    //        ShortfallAE = Math.Max(0, ShortfallAE - AEmarkedForSale);
                    //        HandleDestocking(ShortfallAE, newgroup.Key);
                    //        break;
                    //    default:
                    //        break;
                    //}
                }
            }
        }
        private void OnCLEMAnimalStock(object sender, EventArgs e)
        {
            AeToDestock = 0;
            AeDestocked = 0;
            AeToRestock = 0;
            AeRestocked = 0;

            // this event happens after management has marked individuals for purchase or sale.
            if (this.TimingOK)
            {
                // Get ENSO forcase for current time
                ENSOState forecastEnsoState = GetENSOMeasure();

                this.Status = ActivityStatus.NotNeeded;

                // 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))
                {
                    double aELocationNeeded = 0;

                    // 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).Sum(a => a.AdultEquivalent);
                    double purchaseAE      = ruminantHerd.PurchaseIndividuals.Where(a => a.Location == newgroup.Key).Sum(a => a.AdultEquivalent);

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

                    case ENSOState.ElNino:
                        if (!(pastureToStockingChangeElNino is null))
                        {
                            GrazeFoodStoreType pasture = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType;
                            double             kgha    = pasture.TonnesPerHectare * 1000;
                            herdChange        = pastureToStockingChangeElNino.SolveY(kgha);
                            relationshipFound = true;
                        }
                        break;

                    case ENSOState.LaNina:
                        if (!(pastureToStockingChangeLaNina is null))
                        {
                            GrazeFoodStoreType pasture = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType;
                            double             kgha    = pasture.TonnesPerHectare * 1000;
                            herdChange        = pastureToStockingChangeLaNina.SolveY(kgha);
                            relationshipFound = true;
                        }
                        break;

                    default:
                        break;
                    }
                    if (!relationshipFound)
                    {
                        string warn = $"No pasture biomass to herd change proportion [Relationship] provided for {((forecastEnsoState== ENSOState.ElNino)? "El Niño":"La Niña")} phase in [a={this.Name}]\r\nNo stock management will be performed in this phase.";
                        this.Status = ActivityStatus.Warning;
                        if (!Warnings.Exists(warn))
                        {
                            Summary.WriteWarning(this, warn);
                            Warnings.Add(warn);
                        }
                    }

                    if (herdChange > 1.0)
                    {
                        aELocationNeeded = Math.Max(0, (totalAE * herdChange) - purchaseAE);
                        AeToRestock     += aELocationNeeded;
                        double notHandled = HandleRestocking(aELocationNeeded, newgroup.Key, newgroup.FirstOrDefault());
                        AeRestocked += (aELocationNeeded - notHandled);
                    }
                    else if (herdChange < 1.0)
                    {
                        aELocationNeeded = Math.Max(0, (totalAE * (1 - herdChange)) - markedForSaleAE);
                        AeToDestock     += aELocationNeeded;
                        double notHandled = HandleDestocking(AeToDestock, newgroup.Key);
                        AeDestocked += (aELocationNeeded - notHandled);
                    }
                }

                if (this.Status != ActivityStatus.Warning & AeToDestock + AeToRestock > 0)
                {
                    if (Math.Max(0, AeToRestock - AeRestocked) + Math.Max(0, AeToDestock - AeDestocked) == 0)
                    {
                        this.Status = ActivityStatus.Success;
                    }
                    else
                    {
                        this.Status = ActivityStatus.Partial;
                    }
                }
            }
        }