示例#1
0
        /// <summary>
        /// Executes a "buy" event
        /// </summary>
        /// <param name="AnimalInfo"></param>
        /// <returns></returns>
        protected int Buy(TPurchaseInfo AnimalInfo)
        {
            TAnimalParamSet aGenotype;
            TAnimalGroup NewGroup;
            double fBodyCondition;
            double fLiveWeight;
            double fLowBaseWeight = 0.0;
            double fHighBaseWeight = 0.0;
            TAnimalList WeanList;
            int PaddNo;

            int result = 0;

            if (AnimalInfo.Number > 0)
            {
                aGenotype = getGenotype(AnimalInfo.sGenotype);

                if (AnimalInfo.LiveWt > 0.0)
                    fLiveWeight = AnimalInfo.LiveWt;
                else
                {
                    fLiveWeight = GrowthCurve(AnimalInfo.AgeDays, AnimalInfo.Repro, aGenotype);
                    if (AnimalInfo.fCondScore > 0.0)
                        fLiveWeight = fLiveWeight * TAnimalParamSet.CondScore2Condition(AnimalInfo.fCondScore);
                    if (aGenotype.Animal == GrazType.AnimalType.Sheep)
                        fLiveWeight = fLiveWeight + AnimalInfo.GFW;
                }

                // Construct a new group of animals.
                NewGroup = new TAnimalGroup(aGenotype,
                                                 AnimalInfo.Repro,                         //   Repro should be Empty, Castrated or
                                                 AnimalInfo.Number,                        //   Male; pregnancy is handled with the
                                                 AnimalInfo.AgeDays,                       //   Preg  field.
                                                 fLiveWeight,
                                                 AnimalInfo.GFW,
                                                 RandFactory);

                if ((AnimalInfo.fCondScore > 0.0) && (AnimalInfo.LiveWt > 0.0))        // Adjust the condition score if it has
                {                                                                      //   been given
                    fBodyCondition = TAnimalParamSet.CondScore2Condition(AnimalInfo.fCondScore);
                    NewGroup.WeightRangeForCond(AnimalInfo.Repro, AnimalInfo.AgeDays,
                                                fBodyCondition, NewGroup.Genotype,
                                                ref fLowBaseWeight, ref fHighBaseWeight);

                    if ((NewGroup.BaseWeight >= fLowBaseWeight) && (NewGroup.BaseWeight <= fHighBaseWeight))
                        NewGroup.setConditionAtWeight(fBodyCondition);
                    else
                    {
                        NewGroup = null;
                        throw new Exception("Purchased animals with condition score "
                                                + AnimalInfo.fCondScore.ToString() + "\n"
                                                + " must have a base weight in the range "
                                                + fLowBaseWeight.ToString()
                                                + "-" + fHighBaseWeight.ToString() + " kg");
                    }
                }

                if (NewGroup.ReproState == GrazType.ReproType.Empty)
                {
                    if (AnimalInfo.sMatedTo != "")                                      // Use TAnimalGroup's property interface
                        NewGroup.MatedTo = getGenotype(AnimalInfo.sMatedTo);            //   to set up pregnancy and lactation.
                    NewGroup.Pregnancy = AnimalInfo.Preg;
                    NewGroup.Lactation = AnimalInfo.Lact;
                    if ((NewGroup.Animal == GrazType.AnimalType.Cattle)
                       && (AnimalInfo.Lact > 0) && (AnimalInfo.NYoung == 0))            // NYoung denotes the number of
                    {                                                                   //   *suckling* young in lactating cows,
                        WeanList = null;                                                //   which isn't quite the same as the
                        NewGroup.Wean(true, true, ref WeanList, ref WeanList);          //   YoungNo property
                        WeanList = null; ;
                    }
                    else if (AnimalInfo.NYoung > 0)
                    {
                        // if the animals are pregnant then they need feotuses
                        if (NewGroup.Pregnancy > 0)
                        {
                            if ((AnimalInfo.Lact > 0) && (NewGroup.Animal == GrazType.AnimalType.Cattle))
                            {
                                NewGroup.NoOffspring = 1;
                                NewGroup.NoFoetuses = Math.Min(2, Math.Max(0, AnimalInfo.NYoung - 1));
                            }
                            else
                            {
                                NewGroup.NoFoetuses = Math.Min(3, AnimalInfo.NYoung);                 // recalculates livewt
                            }
                        }
                        else
                            NewGroup.NoOffspring = AnimalInfo.NYoung;
                    }

                    if (NewGroup.Young != null)                                         // Lamb/calf weights and lamb fleece
                    {                                                                   //   weights are optional.
                        if (bIsGiven(AnimalInfo.YoungWt))
                            NewGroup.Young.LiveWeight = AnimalInfo.YoungWt;
                        if (bIsGiven(AnimalInfo.YoungGFW))
                            NewGroup.Young.FleeceCutWeight = AnimalInfo.YoungGFW;
                    }
                } //if (ReproState = Empty)

                PaddNo = 0;                                                             // Newly bought animals have tag # zero
                while ((PaddNo < Paddocks.Count()) && (Paddocks.byIndex(PaddNo).sName == ""))  // and go in the first named paddock.
                    PaddNo++;
                if (PaddNo >= Paddocks.Count())
                    PaddNo = 0;
                result = Add(NewGroup, Paddocks.byIndex(PaddNo), 0, 0);
            } // if AnimalInfo.Number > 0
            return result;
        }
示例#2
0
        /// <summary>
        /// Manage the replacement of adults by purchasing or ageing the existing stock.
        /// </summary>
        /// <param name="currentDay"></param>
        /// <param name="curEnt"></param>
        protected void manageReplacement(int currentDay, TEnterpriseInfo curEnt)
        {
            double area;
            int numToBuy;
            int totalStock;
            int g, groups;
            int groupIdx;
            TPurchaseInfo AnimalInfo = new TPurchaseInfo();
            int yrs;
            TAnimalParamSet genoprms;
            TEnterpriseInfo.TStockEnterprise stockEnt;

            if (curEnt.ReplacementDay == currentDay)
            {
                area = calcStockArea(curEnt);
                if (area > 0)
                {
                    totalStock = 0;
                    g = 1;
                    groups = Count();
                    while (g <= groups)                       //for each group
                    {
                        if (curEnt.ContainsTag(getTag(g)))        //if this group belongs to this ent
                            totalStock = totalStock + At(g).NoAnimals;
                        g++;
                    }
                    numToBuy = Convert.ToInt32(Math.Truncate(curEnt.StockRateFemale * area) - totalStock);  //calc how many to purchase to maintain stocking rate
                    if (!curEnt.getPurchase(1))       //if self replacing
                    {
                        // tag enough young ewes as replacements
                        // sell excess young ewes
                    }
                    else
                    {
                        stockEnt = curEnt.EntTypeFromName(curEnt.EntClass);
                        genoprms = getGenotype(curEnt.BaseGenoType);
                        switch (stockEnt)
                        {
                            case TEnterpriseInfo.TStockEnterprise.entLamb:
                            case TEnterpriseInfo.TStockEnterprise.entWether:
                            case TEnterpriseInfo.TStockEnterprise.entSteer:
                                AnimalInfo.sGenotype = curEnt.BaseGenoType;
                                AnimalInfo.Number = numToBuy;
                                AnimalInfo.Repro = GrazType.ReproType.Castrated;
                                AnimalInfo.AgeDays = Convert.ToInt32(Math.Truncate(MONTH2DAY * curEnt.ReplaceAge + 0.5));
                                AnimalInfo.LiveWt = curEnt.ReplaceWeight;
                                AnimalInfo.GFW = 0;
                                AnimalInfo.fCondScore = TAnimalParamSet.Condition2CondScore(curEnt.ReplaceCond);
                                AnimalInfo.sMatedTo = "";
                                AnimalInfo.Preg = 0;
                                AnimalInfo.Lact = 0;
                                AnimalInfo.NYoung = 0;
                                AnimalInfo.NYoung = 0;
                                AnimalInfo.YoungWt = 0;
                                AnimalInfo.YoungGFW = 0;
                                if ((stockEnt == TEnterpriseInfo.TStockEnterprise.entWether) || (stockEnt == TEnterpriseInfo.TStockEnterprise.entLamb))
                                {
                                    AnimalInfo.GFW = genoprms.PotentialGFW * DaysFromDOY(curEnt.ShearingDate, currentDay) / 365.0;
                                }
                                if (AnimalInfo.Number > 0)
                                {
                                    groupIdx = Buy(AnimalInfo);
                                    yrs = AnimalInfo.AgeDays / 365;
                                    TagGroup(curEnt, groupIdx, 1);        //tag the group

                                    // {TODO: before drafting, a request of forages should be done}

                                    DraftToOpenPaddocks(curEnt, area);
                                    /*
                                    //find the first paddock to be stocked for this enterprise
                                    p = 0;
                                    while (p <= paddocks.Count - 1) do
                                    begin
                                      if curEnt.StockedPaddock[p+1]    //if paddock to be stocked
                                      begin
                                        InPadd[groupIdx] = paddocks.byIndex(p).sName;  //move into correct paddock
                                        p = paddocks.Count; //terminate loop
                                      end;
                                      inc(p);
                                    end;
                                    //if none found default to the first paddock
                                    if p = paddocks.Count
                                      InPadd[groupIdx] = paddocks.byIndex(0).sName;
                                      */
                                }
                                break;
                        }
                    }

                }
            }
        }
示例#3
0
        /// <summary>
        /// The main stock management function that handles a number of events.
        /// </summary>
        /// <param name="Model"></param>
        /// <param name="stockEvent">The event parameters</param>
        /// <param name="dtToday"></param>
        /// <param name="fLatitude"></param>
        public void doStockManagement(TStockList Model, IStockEvent stockEvent, int dtToday = 0, double fLatitude = -35.0)
        {
            TCohortsInfo CohortsInfo = new TCohortsInfo();
            TPurchaseInfo PurchaseInfo = new TPurchaseInfo();
            List<string> sClosed;
            string sParam;
            int iParam1;
            int iParam3;
            double fValue;
            int iTag;
            int iGroups;

            if (stockEvent != null)
            {
                if (stockEvent.GetType() == typeof(TStockAdd))          // add_animals
                {
                    TStockAdd stockInfo = (TStockAdd)stockEvent;
                    CohortsInfo.sGenotype = stockInfo.genotype;
                    CohortsInfo.iNumber = Math.Max(0, stockInfo.number);
                    if (!ParseRepro(stockInfo.sex, ref CohortsInfo.ReproClass))
                        throw new Exception("Event ADD does not support sex='" + stockInfo.sex + "'");
                    if (dtToday > 0)
                        CohortsInfo.iAgeOffsetDays = DaysFromDOY365(stockInfo.birth_day, dtToday);
                    else
                        CohortsInfo.iAgeOffsetDays = 0;
                    CohortsInfo.iMinYears = stockInfo.min_years;
                    CohortsInfo.iMaxYears = stockInfo.max_years;
                    CohortsInfo.fMeanLiveWt = stockInfo.mean_weight;
                    CohortsInfo.fCondScore = stockInfo.cond_score;
                    CohortsInfo.fMeanGFW = stockInfo.mean_fleece_wt;
                    if (dtToday > 0)
                        CohortsInfo.iFleeceDays = DaysFromDOY365(stockInfo.shear_day, dtToday);
                    else
                        CohortsInfo.iFleeceDays = 0;
                    CohortsInfo.sMatedTo = stockInfo.mated_to;
                    CohortsInfo.iDaysPreg = stockInfo.pregnant;
                    CohortsInfo.fFoetuses = stockInfo.foetuses;
                    CohortsInfo.iDaysLact = stockInfo.lactating;
                    CohortsInfo.fOffspring = stockInfo.offspring;
                    CohortsInfo.fOffspringWt = stockInfo.young_wt;
                    CohortsInfo.fOffspringCS = stockInfo.young_cond_score;
                    CohortsInfo.fLambGFW = stockInfo.young_fleece_wt;

                    if (CohortsInfo.iNumber > 0)
                        Model.AddCohorts(CohortsInfo, 1 + DaysFromDOY365(1, dtToday), fLatitude, null);
                }

                else if (stockEvent.GetType() == typeof(TStockBuy))
                {
                    TStockBuy stockInfo = (TStockBuy)stockEvent;
                    PurchaseInfo.sGenotype = stockInfo.genotype;
                    PurchaseInfo.Number = Math.Max(0, stockInfo.number);
                    if (!ParseRepro(stockInfo.sex, ref PurchaseInfo.Repro))
                        throw new Exception("Event BUY does not support sex='" + stockInfo.sex + "'");
                    PurchaseInfo.AgeDays = Convert.ToInt32(Math.Round(MONTH2DAY * stockInfo.age));  // Age in months
                    PurchaseInfo.LiveWt = stockInfo.weight;
                    PurchaseInfo.GFW = stockInfo.fleece_wt;
                    PurchaseInfo.fCondScore = stockInfo.cond_score;
                    PurchaseInfo.sMatedTo = stockInfo.mated_to;
                    PurchaseInfo.Preg = stockInfo.pregnant;
                    PurchaseInfo.Lact = stockInfo.lactating;
                    PurchaseInfo.NYoung = stockInfo.no_young;
                    if ((PurchaseInfo.Preg > 0) || (PurchaseInfo.Lact > 0))
                        PurchaseInfo.NYoung = Math.Max(1, PurchaseInfo.NYoung);
                    PurchaseInfo.YoungWt = stockInfo.young_wt;
                    if ((PurchaseInfo.Lact == 0) || (PurchaseInfo.YoungWt == 0.0))                              // Can't use MISSING as default owing
                        PurchaseInfo.YoungWt = StdMath.DMISSING;                                                //   to double-to-single conversion
                    PurchaseInfo.YoungGFW = stockInfo.young_fleece_wt;
                    iTag = stockInfo.usetag;

                    if (PurchaseInfo.Number > 0)
                    {
                        Model.Buy(PurchaseInfo);
                        if (iTag > 0)
                            Model.setTag(Model.Count(), iTag);
                    }
                } //_ buy _

                //sell a number from a group of animals
                else if (stockEvent.GetType() == typeof(TStockSell))
                {
                    TStockSell stockInfo = (TStockSell)stockEvent;
                    Model.Sell(stockInfo.group, stockInfo.number);
                }
                //sell a number of animals tagged with a specific tag
                else if (stockEvent.GetType() == typeof(TStockSellTag))
                {
                    TStockSellTag stockInfo = (TStockSellTag)stockEvent;
                    Model.SellTag(stockInfo.tag, stockInfo.number);
                }

                else if (stockEvent.GetType() == typeof(TStockShear))
                {
                    TStockShear stockInfo = (TStockShear)stockEvent;
                    sParam = stockInfo.sub_group.ToLower();
                    Model.Shear(stockInfo.group, ((sParam == "adults") || (sParam == "both") || (sParam == "")), ((sParam == "lambs") || (sParam == "both")));
                }

                else if (stockEvent.GetType() == typeof(TStockMove))
                {
                    TStockMove stockInfo = (TStockMove)stockEvent;
                    iParam1 = stockInfo.group;
                    if ((iParam1 >= 1) && (iParam1 <= Model.Count()))
                        Model.setInPadd(iParam1, stockInfo.paddock);
                    else
                        throw new Exception("Invalid group number in MOVE event");
                }

                else if (stockEvent.GetType() == typeof(TStockJoin))
                {
                    TStockJoin stockInfo = (TStockJoin)stockEvent;
                    Model.Join(stockInfo.group, stockInfo.mate_to, stockInfo.mate_days);
                }
                else if (stockEvent.GetType() == typeof(TStockCastrate))
                {
                    TStockCastrate stockInfo = (TStockCastrate)stockEvent;
                    Model.Castrate(stockInfo.group, stockInfo.number);
                }
                else if (stockEvent.GetType() == typeof(TStockWean))
                {
                    TStockWean stockInfo = (TStockWean)stockEvent;
                    iParam1 = stockInfo.group;
                    sParam = stockInfo.sex.ToLower();
                    iParam3 = stockInfo.number;

                    if (sParam == "males")
                        Model.Wean(iParam1, iParam3, false, true);
                    else if (sParam == "females")
                        Model.Wean(iParam1, iParam3, true, false);
                    else if ((sParam == "all") || (sParam == ""))
                        Model.Wean(iParam1, iParam3, true, true);
                    else
                        throw new Exception("Invalid offspring type \"" + sParam + "\" in WEAN event");
                }

                else if (stockEvent.GetType() == typeof(TStockDryoff))
                {
                    TStockDryoff stockInfo = (TStockDryoff)stockEvent;
                    Model.DryOff(stockInfo.group, stockInfo.number);
                }
                //split off the requested animals from all groups
                else if (stockEvent.GetType() == typeof(TStockSplitAll))
                {
                    TStockSplitAll stockInfo = (TStockSplitAll)stockEvent;
                    iGroups = Model.Count(); //get pre-split count of groups
                    for (iParam1 = 1; iParam1 <= iGroups; iParam1++)
                    {
                        sParam = stockInfo.type.ToLower();
                        fValue = stockInfo.value;
                        iTag = stockInfo.othertag;

                        if (sParam == "age")
                            Model.SplitAge(iParam1, Convert.ToInt32(Math.Round(fValue)));
                        else if (sParam == "weight")
                            Model.SplitWeight(iParam1, fValue);
                        else if (sParam == "young")
                            Model.SplitYoung(iParam1);
                        else if (sParam == "number")
                            Model.Split(iParam1, Convert.ToInt32(Math.Round(fValue)));
                        else
                            throw new Exception("Stock: invalid keyword (" + sParam + ") in \"split\" event");
                        if ((iTag > 0) && (Model.Count() > iGroups))     //if a tag for any new group is given
                            Model.setTag(Model.Count(), iTag);
                    }
                }

                //split off the requested animals from one group
                else if (stockEvent.GetType() == typeof(TStockSplit))
                {
                    TStockSplit stockInfo = (TStockSplit)stockEvent;
                    iGroups = Model.Count(); //get pre-split count of groups
                    iParam1 = stockInfo.group;
                    sParam = stockInfo.type.ToLower();
                    fValue = stockInfo.value;
                    iTag = stockInfo.othertag;

                    if ((iParam1 < 1) && (iParam1 > Model.Count()))
                        throw new Exception("Invalid group number in SPLIT event");
                    else if (sParam == "age")
                        Model.SplitAge(iParam1, Convert.ToInt32(Math.Round(fValue)));
                    else if (sParam == "weight")
                        Model.SplitWeight(iParam1, fValue);
                    else if (sParam == "young")
                        Model.SplitYoung(iParam1);
                    else if (sParam == "number")
                        Model.Split(iParam1, Convert.ToInt32(Math.Round(fValue)));
                    else
                        throw new Exception("Stock: invalid keyword (" + sParam + ") in \"split\" event");
                    if ((iTag > 0) && (Model.Count() > iGroups))     //if a tag for the new group is given
                        Model.setTag(Model.Count(), iTag);
                }

                else if (stockEvent.GetType() == typeof(TStockTag))
                {
                    TStockTag stockInfo = (TStockTag)stockEvent;
                    iParam1 = stockInfo.group;
                    if ((iParam1 >= 1) && (iParam1 <= Model.Count()))
                        Model.setTag(iParam1, stockInfo.value);
                    else
                        throw new Exception("Invalid group number in TAG event");
                }

                else if (stockEvent.GetType() == typeof(TStockSort))
                {
                    Model.Sort();
                }

                else if (stockEvent.GetType() == typeof(TStockPrioritise))
                {
                    TStockPrioritise stockInfo = (TStockPrioritise)stockEvent;
                    iParam1 = stockInfo.group;
                    if ((iParam1 >= 1) && (iParam1 <= Model.Count()))
                        Model.setPriority(iParam1, stockInfo.value);
                    else
                        throw new Exception("Invalid group number in PRIORITISE event");
                }

                else if (stockEvent.GetType() == typeof(TStockDraft))
                {
                    TStockDraft stockInfo = (TStockDraft)stockEvent;
                    sClosed = new List<string>(stockInfo.closed);

                    Model.Draft(sClosed);
                }

                else
                    throw new Exception("Event not recognised in STOCK");
            }
        }