Example #1
0
        /// <summary>
        /// Calculate conception rate for a female
        /// </summary>
        /// <param name="female">Female to calculate conception rate for</param>
        /// <param name="status">Returns conception status</param>
        /// <returns></returns>
        private double ConceptionRate(RuminantFemale female, out Reporting.ConceptionStatus status)
        {
            bool isConceptionReady = false;

            status = Reporting.ConceptionStatus.NotAvailable;
            if (!female.IsPregnant)
            {
                status = Reporting.ConceptionStatus.NotReady;
                if (female.Age >= female.BreedParams.MinimumAge1stMating && female.NumberOfBirths == 0)
                {
                    isConceptionReady = true;
                }
                else
                {
                    // add one to age to ensure that conception is due this timestep
                    if ((female.Age + 1 - female.AgeAtLastBirth) * 30.4 > female.BreedParams.MinimumDaysBirthToConception)
                    {
                        // only based upon period since birth
                        isConceptionReady = true;

                        // DEVELOPMENT NOTE:
                        // The following IPI calculation and check present in NABSA has been removed for testing
                        // It is assumed that the individual based model with weight influences will handle the old IPI calculation
                        // These parameters can now be removed form the RuminantType list
                        //double currentIPI = female.BreedParams.InterParturitionIntervalIntercept * Math.Pow(female.ProportionOfNormalisedWeight, female.BreedParams.InterParturitionIntervalCoefficient) * 30.4;
                        //double ageNextConception = female.AgeAtLastConception + (currentIPI / 30.4);
                        //isConceptionReady = (female.Age+1 >= ageNextConception);
                    }
                }
            }

            // if first mating and of age or sufficient time since last birth
            if (isConceptionReady)
            {
                status = Reporting.ConceptionStatus.Unsuccessful;

                // Get conception rate from conception model associated with the Ruminant Type parameters
                if (female.BreedParams.ConceptionModel == null)
                {
                    throw new ApsimXException(this, String.Format("No conception details were found for [r={0}]\r\nPlease add a conception component below the [r=RuminantType]", female.BreedParams.Name));
                }

                return(female.BreedParams.ConceptionModel.ConceptionRate(female));
            }
            return(0);
        }
Example #2
0
        private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            this.AllocationStyle = ResourceAllocationStyle.Manual;

            controlledMating = this.FindAllChildren <RuminantActivityControlledMating>().FirstOrDefault();

            // Assignment of mothers was moved to RuminantHerd resource to ensure this is done even if no breeding activity is included
            this.InitialiseHerd(false, true);

            // report what is happening with timing when uncontrolled mating
            if (!useControlledMating & this.TimingExists)
            {
                Summary.WriteMessage(this, $"Uncontrolled/natural breeding should occur every month. The timer associated with [a={this.Name}] may restrict uncontrolled mating regardless of whether males and females of breeding condition are located together.\r\nYou can also seperate genders by moving to different paddocks to manage the timing of natural mating or add a [a=RuminantActivityControlledMating] component to define controlled mating", MessageType.Warning);
            }

            // set up pre start conception status of breeders
            IEnumerable <Ruminant> herd = CurrentHerd(true);

            // report previous pregnancies as conceptions
            foreach (RuminantFemale female in herd.OfType <RuminantFemale>().Where(a => a.IsPregnant))
            {
                // report conception status changed from those assigned suckling at startup
                female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Conceived, female, clock.Today));
            }

            // work out pregnancy status of initial herd
            if (InferStartupPregnancy)
            {
                // only initialise if herd present
                if (herd.Any())
                {
                    // go back (gestation - 1) months
                    // this won't include those individuals due to give birth on day 1.

                    int monthsAgoStart = 0 - (Convert.ToInt32(Math.Truncate(herd.FirstOrDefault().BreedParams.GestationLength), CultureInfo.InvariantCulture) - 1);
                    int monthsAgoStop  = -1;

                    for (int i = monthsAgoStart; i <= monthsAgoStop; i++)
                    {
                        DateTime previousDate = clock.Today.AddMonths(i);
                        DateTime conceiveDate = clock.Today.AddMonths(i);
                        conceiveDate = new DateTime(conceiveDate.Year, conceiveDate.Month, DateTime.DaysInMonth(conceiveDate.Year, conceiveDate.Month));

                        // get list of all individuals of breeding age and condition
                        // grouped by location
                        var breeders = from ind in herd
                                       where
                                       (ind.Sex == Sex.Male && ind.Age + i >= ind.BreedParams.MinimumAge1stMating) ||
                                       (ind.Sex == Sex.Female &&
                                        ind.Age + i >= ind.BreedParams.MinimumAge1stMating &&
                                        !(ind as RuminantFemale).IsPregnant
                                       )
                                       group ind by ind.Location into grp
                                       select grp;

                        // must be breeders to bother checking any further
                        // must be either uncontrolled mating or the timing of controlled mating
                        if (breeders.Count() > 0 & (!useControlledMating || this.TimingCheck(previousDate)))
                        {
                            int             numberPossible = 0;
                            int             numberServiced = 1;
                            double          limiter        = 1;
                            List <Ruminant> maleBreeders   = new List <Ruminant>();

                            // for each location where parts of this herd are located
                            foreach (var location in breeders)
                            {
                                // uncontrolled conception
                                if (!useControlledMating)
                                {
                                    // check if males and females of breeding condition are together
                                    if (location.GroupBy(a => a.Sex).Count() == 2)
                                    {
                                        // servicing rate
                                        int maleCount = location.Where(a => a.Sex == Sex.Male).Count();
                                        // get a list of males to provide attributes when incontrolled mating.
                                        if (maleCount > 0 && location.FirstOrDefault().BreedParams.IncludedAttributeInheritanceWhenMating)
                                        {
                                            maleBreeders = location.Where(a => a.Sex == Sex.Male).ToList();
                                        }

                                        int    femaleCount     = location.OfType <RuminantFemale>().Count();
                                        double matingsPossible = maleCount * location.FirstOrDefault().BreedParams.MaximumMaleMatingsPerDay * 30;

                                        double maleLimiter = Math.Min(1, matingsPossible / femaleCount);

                                        // only get non-pregnant females of breeding age at the time before the simulation included
                                        var availableBreeders = location.OfType <RuminantFemale>().Where(b => !b.IsPregnant && b.Age + i >= b.BreedParams.MinimumAge1stMating);

                                        // only get selection of these of breeders available to spread conceptions
                                        // only 15% of breeding herd of age can conceive in any month or male limited proportion whichever is smaller
                                        int count = Convert.ToInt32(Math.Ceiling(availableBreeders.Count() * Math.Min(0.15, maleLimiter)), CultureInfo.InvariantCulture);
                                        availableBreeders = availableBreeders.OrderBy(x => RandomNumberGenerator.Generator.NextDouble()).Take(count);

                                        foreach (RuminantFemale female in availableBreeders)
                                        {
                                            // calculate conception
                                            Reporting.ConceptionStatus status = Reporting.ConceptionStatus.NotMated;
                                            double conceptionRate             = ConceptionRate(female, out status);
                                            if (RandomNumberGenerator.Generator.NextDouble() <= conceptionRate)
                                            {
                                                female.UpdateConceptionDetails(female.CalulateNumberOfOffspringThisPregnancy(), conceptionRate, i);
                                                female.LastMatingStyle = MatingStyle.PreSimulation;

                                                // if mandatory attributes are present in the herd, save male value with female details.
                                                if (female.BreedParams.IncludedAttributeInheritanceWhenMating)
                                                {
                                                    // randomly select male as father
                                                    AddMalesAttributeDetails(female, maleBreeders[RandomNumberGenerator.Generator.Next(0, maleBreeders.Count() - 1)]);
                                                }

                                                // report conception status changed
                                                female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Conceived, female, conceiveDate));

                                                // check for perenatal mortality
                                                for (int j = i; j < monthsAgoStop; j++)
                                                {
                                                    DateTime lossDate = clock.Today.AddMonths(i);
                                                    lossDate = new DateTime(lossDate.Year, lossDate.Month, DateTime.DaysInMonth(lossDate.Year, lossDate.Month));

                                                    for (int k = 0; k < female.CarryingCount; i++)
                                                    {
                                                        if (RandomNumberGenerator.Generator.NextDouble() < (female.BreedParams.PrenatalMortality / (female.BreedParams.GestationLength + 1)))
                                                        {
                                                            female.OneOffspringDies();
                                                            if (female.NumberOfOffspring == 0)
                                                            {
                                                                // report conception status changed when last multiple birth dies.
                                                                female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Failed, female, lossDate));
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                // controlled conception
                                else
                                {
                                    numberPossible = Convert.ToInt32(limiter * location.OfType <RuminantFemale>().Count(), CultureInfo.InvariantCulture);
                                    foreach (RuminantFemale female in location.OfType <RuminantFemale>())
                                    {
                                        if (!female.IsPregnant && (female.Age - female.AgeAtLastBirth) * 30.4 >= female.BreedParams.MinimumDaysBirthToConception)
                                        {
                                            // calculate conception
                                            Reporting.ConceptionStatus status = Reporting.ConceptionStatus.NotMated;
                                            double conceptionRate             = ConceptionRate(female, out status);
                                            if (numberServiced <= numberPossible) // labour/finance limited number
                                            {
                                                if (RandomNumberGenerator.Generator.NextDouble() <= conceptionRate)
                                                {
                                                    female.UpdateConceptionDetails(female.CalulateNumberOfOffspringThisPregnancy(), conceptionRate, i);
                                                    female.LastMatingStyle = MatingStyle.Controlled;

                                                    // if mandatory attributes are present in the herd, save male value with female details.
                                                    if (female.BreedParams.IncludedAttributeInheritanceWhenMating)
                                                    {
                                                        // save all male attributes
                                                        AddMalesAttributeDetails(female, controlledMating.SireAttributes);
                                                    }

                                                    // report conception status changed
                                                    female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Conceived, female, conceiveDate));

                                                    // check for perenatal mortality
                                                    for (int j = i; j < monthsAgoStop; j++)
                                                    {
                                                        DateTime lossDate = clock.Today.AddMonths(i);
                                                        lossDate = new DateTime(lossDate.Year, lossDate.Month, DateTime.DaysInMonth(lossDate.Year, lossDate.Month));

                                                        for (int k = 0; k < female.CarryingCount; k++)
                                                        {
                                                            if (RandomNumberGenerator.Generator.NextDouble() < (female.BreedParams.PrenatalMortality / (female.BreedParams.GestationLength + 1)))
                                                            {
                                                                female.OneOffspringDies();
                                                                if (female.NumberOfOffspring == 0)
                                                                {
                                                                    // report conception status changed when last multiple birth dies.
                                                                    female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Failed, female, lossDate));
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                                numberServiced++;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #3
0
        private void OnCLEMAnimalBreeding(object sender, EventArgs e)
        {
            this.Status     = ActivityStatus.NotNeeded;
            NumberConceived = 0;

            // get list of all pregnant females
            List <RuminantFemale> pregnantherd = CurrentHerd(true).OfType <RuminantFemale>().Where(a => a.IsPregnant).ToList();

            // determine all fetus and newborn mortality of all pregnant females.
            foreach (RuminantFemale female in pregnantherd)
            {
                // calculate fetus and newborn mortality
                // total mortality / (gestation months + 1) to get monthly mortality
                // done here before births to account for post birth motality as well..
                // IsPregnant status does not change until births occur in next section so will include mortality in month of birth
                // needs to be calculated for each offspring carried.
                for (int i = 0; i < female.CarryingCount; i++)
                {
                    var rnd = RandomNumberGenerator.Generator.NextDouble();
                    if (rnd < (female.BreedParams.PrenatalMortality / (female.BreedParams.GestationLength + 1)))
                    {
                        female.OneOffspringDies();
                        if (female.NumberOfOffspring == 0)
                        {
                            // report conception status changed when last multiple birth dies.
                            female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Failed, female, clock.Today));
                        }
                    }
                }

                if (female.BirthDue)
                {
                    int numberOfNewborn = female.CarryingCount;
                    for (int i = 0; i < numberOfNewborn; i++)
                    {
                        bool   isMale = RandomNumberGenerator.Generator.NextDouble() <= female.BreedParams.ProportionOffspringMale;
                        Sex    sex    = isMale ? Sex.Male : Sex.Female;
                        double weight = female.BreedParams.SRWBirth * female.StandardReferenceWeight * (1 - 0.33 * (1 - female.Weight / female.StandardReferenceWeight));

                        Ruminant newSucklingRuminant = Ruminant.Create(sex, female.BreedParams, 0, weight);
                        newSucklingRuminant.HerdName = female.HerdName;
                        newSucklingRuminant.Breed    = female.BreedParams.Breed;
                        newSucklingRuminant.ID       = HerdResource.NextUniqueID;
                        newSucklingRuminant.Location = female.Location;
                        newSucklingRuminant.Mother   = female;
                        newSucklingRuminant.Number   = 1;
                        newSucklingRuminant.SetUnweaned();
                        // suckling/calf weight from Freer
                        newSucklingRuminant.PreviousWeight = newSucklingRuminant.Weight;
                        newSucklingRuminant.SaleFlag       = HerdChangeReason.Born;

                        // add attributes inherited from mother
                        foreach (var attribute in female.Attributes.Items)
                        {
                            if (attribute.Value != null)
                            {
                                newSucklingRuminant.Attributes.Add(attribute.Key, attribute.Value.GetInheritedAttribute() as IIndividualAttribute);
                            }
                        }

                        HerdResource.AddRuminant(newSucklingRuminant, this);

                        // add to sucklings
                        female.SucklingOffspringList.Add(newSucklingRuminant);
                        // this now reports for each individual born not a birth event as individual wean events are reported
                        female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Birth, female, clock.Today));
                    }
                    female.UpdateBirthDetails();
                    this.Status = ActivityStatus.Success;
                }
            }

            // Perform breeding
            IEnumerable <Ruminant> herd = null;

            if (useControlledMating && controlledMating.TimingOK)
            {
                // determined by controlled mating and subsequent timer (e.g. smart milking)
                herd = controlledMating.BreedersToMate();
            }
            else if (!useControlledMating && TimingOK)
            {
                // whole herd for activity including males
                herd = CurrentHerd(true);
            }

            if (herd != null && herd.Any())
            {
                // group by location
                var breeders = from ind in herd
                               where ind.IsAbleToBreed
                               group ind by ind.Location into grp
                               select grp;

                // identify not ready for reporting and tracking
                var notReadyBreeders = herd.Where(a => a.Sex == Sex.Female).Cast <RuminantFemale>().Where(a => a.IsBreeder && !a.IsAbleToBreed && !a.IsPregnant);
                foreach (RuminantFemale female in notReadyBreeders)
                {
                    female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.NotReady, female, clock.Today));
                }

                int             numberPossible = breeders.Sum(a => a.Count());
                int             numberServiced = 1;
                List <Ruminant> maleBreeders   = new List <Ruminant>();

                // for each location where parts of this herd are located
                foreach (var location in breeders)
                {
                    numberPossible = -1;
                    if (useControlledMating)
                    {
                        numberPossible = Convert.ToInt32(location.OfType <RuminantFemale>().Count(), CultureInfo.InvariantCulture);
                    }
                    else
                    {
                        numberPossible = 0;
                        // uncontrolled conception
                        if (location.GroupBy(a => a.Sex).Count() == 2)
                        {
                            int maleCount = location.OfType <RuminantMale>().Count();
                            // get a list of males to provide attributes when incontrolled mating.
                            if (maleCount > 0 && location.FirstOrDefault().BreedParams.IncludedAttributeInheritanceWhenMating)
                            {
                                maleBreeders = location.Where(a => a.Sex == Sex.Male).ToList();
                            }

                            int femaleCount = location.Where(a => a.Sex == Sex.Female).Count();
                            numberPossible = Convert.ToInt32(Math.Ceiling(maleCount * location.FirstOrDefault().BreedParams.MaximumMaleMatingsPerDay * 30), CultureInfo.InvariantCulture);
                        }
                    }

                    numberServiced = 0;
                    lastJoinIndex  = -1;
                    int cnt = 0;
                    // shuffle the not pregnant females when obtained to avoid any inherant order by creation of individuals affecting which individuals are available first
                    var notPregnantFemales = location.OfType <RuminantFemale>().Where(a => !a.IsPregnant).OrderBy(a => RandomNumberGenerator.Generator.Next()).ToList();
                    int totalToBreed       = notPregnantFemales.Count;
                    while (cnt < totalToBreed)
                    {
                        RuminantFemale             female = notPregnantFemales.ElementAt(cnt);
                        Reporting.ConceptionStatus status = Reporting.ConceptionStatus.NotMated;
                        if (numberServiced < numberPossible)
                        {
                            // calculate conception
                            double conceptionRate = ConceptionRate(female, out status);

                            // if mandatory attributes are present in the herd, save male value with female details.
                            // update male for both successful and failed matings (next if statement
                            if (female.BreedParams.IncludedAttributeInheritanceWhenMating)
                            {
                                object male = null;

                                if (useControlledMating)
                                {
                                    bool newJoining = needsNewJoiningMale(controlledMating.JoiningsPerMale, numberServiced);
                                    // save all male attributes
                                    AddMalesAttributeDetails(female, controlledMating.SireAttributes, newJoining);
                                }
                                else
                                {
                                    male = maleBreeders[RandomNumberGenerator.Generator.Next(0, maleBreeders.Count() - 1)];
                                    female.LastMatingStyle = ((male as RuminantMale).IsWildBreeder ? MatingStyle.WildBreeder : MatingStyle.Natural);

                                    // randomly select male
                                    AddMalesAttributeDetails(female, male as Ruminant);
                                }
                            }

                            if (conceptionRate > 0)
                            {
                                if (RandomNumberGenerator.Generator.NextDouble() <= conceptionRate)
                                {
                                    female.UpdateConceptionDetails(female.CalulateNumberOfOffspringThisPregnancy(), conceptionRate, 0);

                                    if (useControlledMating)
                                    {
                                        female.LastMatingStyle = MatingStyle.Controlled;
                                    }

                                    status = Reporting.ConceptionStatus.Conceived;
                                    NumberConceived++;
                                }
                                else
                                {
                                    status = Reporting.ConceptionStatus.Unsuccessful;
                                }
                            }
                            numberServiced++;
                            this.Status = ActivityStatus.Success;
                        }

                        // report change in breeding status
                        // do not report for -1 (controlled mating outside timing)
                        if (numberPossible >= 0 && status != Reporting.ConceptionStatus.NotAvailable)
                        {
                            female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(status, female, clock.Today));
                        }

                        cnt++;
                    }

                    // report a natural mating locations for transparency via a message
                    if (numberServiced > 0 & !useControlledMating)
                    {
                        string warning = $"Natural (uncontrolled) mating ocurred in [r={(location.Key ?? "Not specified - general yards")}]";
                        Warnings.CheckAndWrite(warning, Summary, this, MessageType.Information);
                    }
                }
            }
            // report that this activity was performed as it does not use base GetResourcesRequired
            this.TriggerOnActivityPerformed();
        }
        private void OnCLEMAnimalBreeding(object sender, EventArgs e)
        {
            this.Status     = ActivityStatus.NotNeeded;
            NumberConceived = 0;

            // get list of all pregnant females
            List <RuminantFemale> pregnantherd = CurrentHerd(true).Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().Where(a => a.IsPregnant).ToList();

            // determine all fetus and newborn mortality of all pregnant females.
            foreach (RuminantFemale female in pregnantherd)
            {
                // calculate fetus and newborn mortality
                // total mortality / (gestation months + 1) to get monthly mortality
                // done here before births to account for post birth motality as well..
                // IsPregnant status does not change until births occur in next section so will include mortality in month of birth
                // needs to be calculated for each offspring carried.
                for (int i = 0; i < female.CarryingCount; i++)
                {
                    if (RandomNumberGenerator.Generator.NextDouble() < (female.BreedParams.PrenatalMortality / (female.BreedParams.GestationLength + 1)))
                    {
                        female.OneOffspringDies();
                        if (female.NumberOfOffspring == 0)
                        {
                            // report conception status changed when last multiple birth dies.
                            female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Failed, female, Clock.Today));
                        }
                    }
                }

                if (female.BirthDue)
                {
                    int numberOfNewborn = female.CarryingCount;
                    for (int i = 0; i < numberOfNewborn; i++)
                    {
                        object newCalf = null;
                        bool   isMale  = (RandomNumberGenerator.Generator.NextDouble() <= female.BreedParams.ProportionOffspringMale);
                        double weight  = female.BreedParams.SRWBirth * female.StandardReferenceWeight * (1 - 0.33 * (1 - female.Weight / female.StandardReferenceWeight));
                        if (isMale)
                        {
                            newCalf = new RuminantMale(0, Sex.Male, weight, female.BreedParams);
                        }
                        else
                        {
                            newCalf = new RuminantFemale(0, Sex.Female, weight, female.BreedParams);
                        }
                        Ruminant newCalfRuminant = newCalf as Ruminant;
                        newCalfRuminant.HerdName = female.HerdName;
                        newCalfRuminant.Breed    = female.BreedParams.Breed;
                        newCalfRuminant.ID       = Resources.RuminantHerd().NextUniqueID;
                        newCalfRuminant.Location = female.Location;
                        newCalfRuminant.Mother   = female;
                        newCalfRuminant.Number   = 1;
                        newCalfRuminant.SetUnweaned();
                        // calf weight from  Freer
                        newCalfRuminant.PreviousWeight = newCalfRuminant.Weight;
                        newCalfRuminant.SaleFlag       = HerdChangeReason.Born;

                        // add attributes inherited from mother
                        foreach (var attribute in female.Attributes)
                        {
                            newCalfRuminant.AddAttribute(attribute.Key, attribute.Value.GetInheritedAttribute() as ICLEMAttribute);
                        }

                        Resources.RuminantHerd().AddRuminant(newCalfRuminant, this);

                        // add to sucklings
                        female.SucklingOffspringList.Add(newCalfRuminant);
                        // this now reports for each individual born not a birth event as individual wean events are reported
                        female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Birth, female, Clock.Today));
                    }
                    female.UpdateBirthDetails();
                    this.Status = ActivityStatus.Success;
                }
            }

            // Perform breeding
            IEnumerable <Ruminant> herd = null;

            if (useControlledMating && controlledMating.TimingOK)
            {
                // determined by controlled mating and subsequent timer (e.g. smart milking)
                herd = controlledMating.BreedersToMate();
                this.TriggerOnActivityPerformed();
            }
            else if (!useControlledMating && TimingOK)
            {
                // whole herd for activity
                herd = CurrentHerd(true);
                // report that this activity was performed as it does not use base GetResourcesRequired
                this.TriggerOnActivityPerformed();
            }

            if (herd != null && herd.Count() > 0)
            {
                // group by location
                var breeders = from ind in herd
                               where ind.IsAbleToBreed
                               group ind by ind.Location into grp
                               select grp;

                int             breedersCount  = breeders.Count();
                int             numberPossible = breedersCount;
                int             numberServiced = 1;
                List <Ruminant> maleBreeders   = new List <Ruminant>();

                // for each location where parts of this herd are located
                foreach (var location in breeders)
                {
                    numberPossible = -1;
                    if (useControlledMating)
                    {
                        numberPossible = Convert.ToInt32(location.Where(a => a.Gender == Sex.Female).Count(), CultureInfo.InvariantCulture);
                    }
                    else
                    {
                        numberPossible = 0;
                        // uncontrolled conception
                        if (location.GroupBy(a => a.Gender).Count() == 2)
                        {
                            int maleCount = location.Where(a => a.Gender == Sex.Male).Count();
                            // get a list of males to provide attributes when incontrolled mating.
                            if (maleCount > 0 && location.FirstOrDefault().BreedParams.IncludedAttributeInheritanceWhenMating)
                            {
                                maleBreeders = location.Where(a => a.Gender == Sex.Male).ToList();
                            }
                            int femaleCount = location.Where(a => a.Gender == Sex.Female).Count();
                            numberPossible = Convert.ToInt32(Math.Ceiling(maleCount * location.FirstOrDefault().BreedParams.MaximumMaleMatingsPerDay * 30), CultureInfo.InvariantCulture);
                        }
                    }

                    numberServiced = 1;
                    foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().Where(a => !a.IsPregnant & a.Age <= a.BreedParams.MaximumAgeMating).ToList())
                    {
                        Reporting.ConceptionStatus status = Reporting.ConceptionStatus.NotMated;
                        if (numberServiced <= numberPossible)
                        {
                            // calculate conception
                            double conceptionRate = ConceptionRate(female, out status);
                            if (conceptionRate > 0)
                            {
                                if (RandomNumberGenerator.Generator.NextDouble() <= conceptionRate)
                                {
                                    female.UpdateConceptionDetails(female.CalulateNumberOfOffspringThisPregnancy(), conceptionRate, 0);

                                    // if mandatory attributes are present in the herd, save male value with female details.
                                    if (female.BreedParams.IncludedAttributeInheritanceWhenMating)
                                    {
                                        if (useControlledMating)
                                        {
                                            // save all male attributes
                                            AddMalesAttributeDetails(female, controlledMating.SireAttributes);
                                        }
                                        else
                                        {
                                            // randomly select male
                                            AddMalesAttributeDetails(female, maleBreeders[RandomNumberGenerator.Generator.Next(0, maleBreeders.Count() - 1)]);
                                        }
                                    }
                                    status = Reporting.ConceptionStatus.Conceived;
                                    NumberConceived++;
                                }
                            }
                            numberServiced++;
                            this.Status = ActivityStatus.Success;
                        }

                        // report change in breeding status
                        // do not report for -1 (controlled mating outside timing)
                        if (numberPossible >= 0 && status != Reporting.ConceptionStatus.NotAvailable)
                        {
                            female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(status, female, Clock.Today));
                        }
                    }

                    // report a natural mating locations for transparency via a message
                    if (numberServiced > 0 & !useControlledMating)
                    {
                        string warning = "Natural (uncontrolled) mating ocurred in [r=" + location.Key + "]";
                        if (!Warnings.Exists(warning))
                        {
                            Warnings.Add(warning);
                            Summary.WriteMessage(this, warning);
                        }
                    }
                }
            }
        }
Example #5
0
        private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            this.AllocationStyle = ResourceAllocationStyle.Manual;

            // Assignment of mothers was moved to RuminantHerd resource to ensure this is done even if no breeding activity is included
            this.InitialiseHerd(false, true);

            // get labour specifications
            labour = this.FindAllChildren <LabourRequirement>().Cast <LabourRequirement>().ToList(); //  this.Children.Where(a => a.GetType() == typeof(LabourFilterGroupSpecified)).Cast<LabourFilterGroupSpecified>().ToList();
            if (labour.Count() == 0)
            {
                labour = new List <LabourRequirement>();
            }

            // check that timer exists for AI
            if (UseAI)
            {
                if (!this.TimingExists)
                {
                    Summary.WriteWarning(this, String.Format("Breeding with Artificial Insemination (AI) requires a Timer otherwise breeding will be undertaken every time step in activity [a={0}]", this.Name));
                }
            }
            else
            {
                if (this.TimingExists)
                {
                    Summary.WriteWarning(this, String.Format("Uncontrolled/natural breeding will occur every month and the timer associated with [a={0}] will be ignored.", this.Name));
                }
            }

            // work out pregnancy status of initial herd
            if (InferStartupPregnancy)
            {
                // set up pre start conception status of breeders
                List <Ruminant> herd = CurrentHerd(true);

                int aDay = Clock.Today.Year;

                // go back (gestation - 1) months
                // this won't include those individuals due to give birth on day 1.

                int monthsAgoStart = 0 - (Convert.ToInt32(Math.Truncate(herd.FirstOrDefault().BreedParams.GestationLength), CultureInfo.InvariantCulture) - 1);
                int monthsAgoStop  = -1;

                for (int i = monthsAgoStart; i <= monthsAgoStop; i++)
                {
                    DateTime previousDate = Clock.Today.AddMonths(i);

                    // get list of all individuals of breeding age and condition
                    // grouped by location
                    var breeders = from ind in herd
                                   where
                                   (ind.Gender == Sex.Male && ind.Age + i >= ind.BreedParams.MinimumAge1stMating) ||
                                   (ind.Gender == Sex.Female &&
                                    ind.Age + i >= ind.BreedParams.MinimumAge1stMating &&
                                    !(ind as RuminantFemale).IsPregnant
                                   )
                                   group ind by ind.Location into grp
                                   select grp;

                    int breedersCount = breeders.Count();

                    // must be breeders to bother checking any further
                    // must be either uncontrolled mating or the timing of controlled mating
                    if (breedersCount > 0 & (!UseAI || this.TimingCheck(previousDate)))
                    {
                        int    numberPossible = breedersCount;
                        int    numberServiced = 1;
                        double limiter        = 1;

                        // for each location where parts of this herd are located
                        foreach (var location in breeders)
                        {
                            // uncontrolled conception
                            if (!UseAI)
                            {
                                // check if males and females of breeding condition are together
                                if (location.GroupBy(a => a.Gender).Count() == 2)
                                {
                                    // servicing rate
                                    int    maleCount       = location.Where(a => a.Gender == Sex.Male).Count();
                                    int    femaleCount     = location.Where(a => a.Gender == Sex.Female).Count();
                                    double matingsPossible = maleCount * location.FirstOrDefault().BreedParams.MaximumMaleMatingsPerDay * 30;

                                    double maleLimiter = Math.Min(1, matingsPossible / femaleCount);

                                    // only get non-pregnant females of breeding age at the time before the simulation included
                                    var availableBreeders = location.Where(b => b.Gender == Sex.Female && b.Age + i >= b.BreedParams.MinimumAge1stMating)
                                                            .Cast <RuminantFemale>().Where(a => !a.IsPregnant).ToList();

                                    // only get selection of these of breeders available to spread conceptions
                                    // only 15% of breeding herd of age can conceive in any month or male limited proportion whichever is smaller
                                    int count = Convert.ToInt32(Math.Ceiling(availableBreeders.Count() * Math.Min(0.15, maleLimiter)));
                                    availableBreeders = availableBreeders.OrderBy(x => RandomNumberGenerator.Generator.NextDouble()).Take(count).ToList();

                                    foreach (RuminantFemale female in availableBreeders)
                                    {
                                        // calculate conception
                                        Reporting.ConceptionStatus status = Reporting.ConceptionStatus.NotMated;
                                        double conceptionRate             = ConceptionRate(female, out status);
                                        if (RandomNumberGenerator.Generator.NextDouble() <= conceptionRate)
                                        {
                                            female.UpdateConceptionDetails(female.CalulateNumberOfOffspringThisPregnancy(), conceptionRate, i);
                                            // report conception status changed
                                            female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Conceived, female, Clock.Today));

                                            // check for perenatal mortality
                                            for (int j = i; j < monthsAgoStop; j++)
                                            {
                                                for (int k = 0; k < female.CarryingCount; i++)
                                                {
                                                    if (RandomNumberGenerator.Generator.NextDouble() < (female.BreedParams.PrenatalMortality / (female.BreedParams.GestationLength + 1)))
                                                    {
                                                        female.OneOffspringDies();
                                                        if (female.NumberOfOffspring == 0)
                                                        {
                                                            // report conception status changed when last multiple birth dies.
                                                            female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Failed, female, Clock.Today));
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            // controlled conception
                            else
                            {
                                numberPossible = Convert.ToInt32(limiter * location.Where(a => a.Gender == Sex.Female).Count(), CultureInfo.InvariantCulture);
                                foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().ToList())
                                {
                                    if (!female.IsPregnant && (female.Age - female.AgeAtLastBirth) * 30.4 >= female.BreedParams.MinimumDaysBirthToConception)
                                    {
                                        // calculate conception
                                        Reporting.ConceptionStatus status = Reporting.ConceptionStatus.NotMated;
                                        double conceptionRate             = ConceptionRate(female, out status);
                                        if (numberServiced <= numberPossible) // labour/finance limited number
                                        {
                                            if (RandomNumberGenerator.Generator.NextDouble() <= conceptionRate)
                                            {
                                                female.UpdateConceptionDetails(female.CalulateNumberOfOffspringThisPregnancy(), conceptionRate, i);
                                                // report conception status changed
                                                female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Conceived, female, Clock.Today));

                                                // check for perenatal mortality
                                                for (int j = i; j < monthsAgoStop; j++)
                                                {
                                                    for (int k = 0; k < female.CarryingCount; k++)
                                                    {
                                                        if (RandomNumberGenerator.Generator.NextDouble() < (female.BreedParams.PrenatalMortality / (female.BreedParams.GestationLength + 1)))
                                                        {
                                                            female.OneOffspringDies();
                                                            if (female.NumberOfOffspring == 0)
                                                            {
                                                                // report conception status changed when last multiple birth dies.
                                                                female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Failed, female, Clock.Today));
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            numberServiced++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #6
0
        private void OnCLEMAnimalBreeding(object sender, EventArgs e)
        {
            List <Ruminant> herd = CurrentHerd(true);

            int aDay = Clock.Today.Year;

            // get list of all individuals of breeding age and condition
            // grouped by location
            var breeders = from ind in herd
                           where ind.IsBreedingCondition
                           group ind by ind.Location into grp
                           select grp;

            // calculate labour and finance limitations if needed when doing AI
            int    breedersCount  = breeders.Count();
            int    numberPossible = breedersCount;
            int    numberServiced = 1;
            double limiter        = 1;

            if (UseAI && TimingOK)
            {
                // attempt to get required resources
                List <ResourceRequest> resourcesneeded = GetResourcesNeededForActivityLocal();
                CheckResources(resourcesneeded, Guid.NewGuid());
                bool tookRequestedResources = TakeResources(resourcesneeded, true);
                // get all shortfalls
                if (tookRequestedResources && (ResourceRequestList != null))
                {
                    //TODO: fix this to account for perHead payments and labour and not fixed expenses
                    double amountCashNeeded     = resourcesneeded.Where(a => a.ResourceType == typeof(Finance)).Sum(a => a.Required);
                    double amountCashProvided   = resourcesneeded.Where(a => a.ResourceType == typeof(Finance)).Sum(a => a.Provided);
                    double amountLabourNeeded   = resourcesneeded.Where(a => a.ResourceType == typeof(Labour)).Sum(a => a.Required);
                    double amountLabourProvided = resourcesneeded.Where(a => a.ResourceType == typeof(Labour)).Sum(a => a.Provided);
                    double cashlimit            = 1;
                    if (amountCashNeeded > 0)
                    {
                        cashlimit = amountCashProvided == 0 ? 0 : amountCashNeeded / amountCashProvided;
                    }
                    double labourlimit = 1;
                    if (amountLabourNeeded > 0)
                    {
                        labourlimit = amountLabourProvided == 0 ? 0 : amountLabourNeeded / amountLabourProvided;
                    }
                    limiter = Math.Min(cashlimit, labourlimit);

                    // TODO: determine if fixed payments were not possible
                    // TODO: determine limits by insufficient labour or cash for per head payments
                }
                // report that this activity was performed as it does not use base GetResourcesRequired
                this.TriggerOnActivityPerformed();
            }

            if (!UseAI)
            {
                // report that this activity was performed as it does not use base GetResourcesRequired
                this.TriggerOnActivityPerformed();
                this.Status = ActivityStatus.NotNeeded;
            }

            // for each location where parts of this herd are located
            foreach (var location in breeders)
            {
                // determine all fetus and newborn mortality of all pregnant females.
                foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().Where(a => a.IsPregnant).ToList())
                {
                    // calculate fetus and newborn mortality
                    // total mortality / (gestation months + 1) to get monthly mortality
                    // done here before births to account for post birth motality as well..
                    // IsPregnant status does not change until births occur in next section so will include mortality in month of birth
                    // needs to be caclulated for each offspring carried.
                    for (int i = 0; i < female.CarryingCount; i++)
                    {
                        if (RandomNumberGenerator.Generator.NextDouble() < (female.BreedParams.PrenatalMortality / (female.BreedParams.GestationLength + 1)))
                        {
                            female.OneOffspringDies();
                            if (female.NumberOfOffspring == 0)
                            {
                                // report conception status changed when last multiple birth dies.
                                female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Failed, female, Clock.Today));
                            }
                        }
                    }
                }

                // check for births of all pregnant females.
                int month = Clock.Today.Month;
                foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().ToList())
                {
                    if (female.BirthDue)
                    {
                        int numberOfNewborn = female.CarryingCount;
                        for (int i = 0; i < numberOfNewborn; i++)
                        {
                            // Foetal mortality is now performed each timestep at base of this method
                            object newCalf = null;
                            bool   isMale  = (RandomNumberGenerator.Generator.NextDouble() <= female.BreedParams.ProportionOffspringMale);
                            double weight  = female.BreedParams.SRWBirth * female.StandardReferenceWeight * (1 - 0.33 * (1 - female.Weight / female.StandardReferenceWeight));
                            if (isMale)
                            {
                                newCalf = new RuminantMale(0, Sex.Male, weight, female.BreedParams);
                            }
                            else
                            {
                                newCalf = new RuminantFemale(0, Sex.Female, weight, female.BreedParams);
                            }
                            Ruminant newCalfRuminant = newCalf as Ruminant;
                            newCalfRuminant.HerdName = female.HerdName;
                            newCalfRuminant.Breed    = female.BreedParams.Breed;
                            newCalfRuminant.ID       = Resources.RuminantHerd().NextUniqueID;
                            newCalfRuminant.Location = female.Location;
                            newCalfRuminant.Mother   = female;
                            newCalfRuminant.Number   = 1;
                            newCalfRuminant.SetUnweaned();
                            // calf weight from  Freer
                            newCalfRuminant.PreviousWeight = newCalfRuminant.Weight;
                            newCalfRuminant.SaleFlag       = HerdChangeReason.Born;
                            Resources.RuminantHerd().AddRuminant(newCalfRuminant, this);

                            // add to sucklings
                            female.SucklingOffspringList.Add(newCalfRuminant);
                            // this now reports for each individual born not a birth event as individual wean events are reported
                            female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Birth, female, Clock.Today));
                        }
                        female.UpdateBirthDetails();
                        this.Status = ActivityStatus.Success;
                    }
                }

                numberPossible = -1;
                if (!UseAI)
                {
                    numberPossible = 0;
                    // uncontrolled conception
                    if (location.GroupBy(a => a.Gender).Count() == 2)
                    {
                        int maleCount   = location.Where(a => a.Gender == Sex.Male).Count();
                        int femaleCount = location.Where(a => a.Gender == Sex.Female).Count();
                        numberPossible = Convert.ToInt32(Math.Ceiling(maleCount * location.FirstOrDefault().BreedParams.MaximumMaleMatingsPerDay * 30), CultureInfo.InvariantCulture);
                    }
                }
                else
                {
                    // controlled mating (AI)
                    if (this.TimingOK)
                    {
                        numberPossible = Convert.ToInt32(limiter * location.Where(a => a.Gender == Sex.Female).Count(), CultureInfo.InvariantCulture);
                    }
                }

                numberServiced = 1;
                foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().Where(a => !a.IsPregnant & a.Age <= a.BreedParams.MaximumAgeMating).ToList())
                {
                    Reporting.ConceptionStatus status = Reporting.ConceptionStatus.NotMated;
                    if (numberServiced <= numberPossible)
                    {
                        // calculate conception
                        double conceptionRate = ConceptionRate(female, out status);
                        if (conceptionRate > 0)
                        {
                            if (RandomNumberGenerator.Generator.NextDouble() <= conceptionRate)
                            {
                                female.UpdateConceptionDetails(female.CalulateNumberOfOffspringThisPregnancy(), conceptionRate, 0);
                                status = Reporting.ConceptionStatus.Conceived;
                            }
                        }
                        numberServiced++;
                        this.Status = ActivityStatus.Success;
                    }

                    // report change in breeding status
                    // do not report for -1 (controlled mating outside timing)
                    if (numberPossible >= 0 && status != Reporting.ConceptionStatus.NotAvailable)
                    {
                        female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(status, female, Clock.Today));
                    }
                }

                // report a natural mating locations for transparency via a message
                if (this.Status == ActivityStatus.Success && !UseAI)
                {
                    string warning = "Natural (uncontrolled) mating ocurred in [r=" + location.Key + "]";
                    if (!Warnings.Exists(warning))
                    {
                        Warnings.Add(warning);
                        Summary.WriteMessage(this, warning);
                    }
                }
            }
        }
Example #7
0
        private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            // Assignment of mothers was moved to RuminantHerd resource to ensure this is done even if no breeding activity is included
            this.InitialiseHerd(false, true);

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

            // check that timer exists for AI
            if (UseAI)
            {
                if (!this.TimingExists)
                {
                    Summary.WriteWarning(this, String.Format("Breeding with Artificial Insemination (AI) requires a Timer otherwise breeding will be undertaken every time step in activity [a={0}]", this.Name));
                }
            }

            // work out pregnancy status of initial herd
            if (InferStartupPregnancy)
            {
                // set up pre start conception status of breeders
                List <Ruminant> herd = CurrentHerd(true);

                int aDay = Clock.Today.Year;

                // go back (gestation - 1) months
                // this won't include those individuals due to give birth on day 1.

                int monthsAgoStart = Clock.Today.Month - (Convert.ToInt32(Math.Truncate(herd.FirstOrDefault().BreedParams.GestationLength), CultureInfo.InvariantCulture) - 1);
                int monthsAgoStop  = -1;

                for (int i = monthsAgoStart; i <= monthsAgoStop; i++)
                {
                    DateTime previousDate = Clock.Today.AddMonths(i);

                    // get list of all individuals of breeding age and condition
                    // grouped by location
                    var breeders = from ind in herd
                                   where
                                   (ind.Gender == Sex.Male && ind.Age + i >= ind.BreedParams.MinimumAge1stMating) ||
                                   (ind.Gender == Sex.Female &&
                                    ind.Age + i >= ind.BreedParams.MinimumAge1stMating //&&
                                                                                       // ind.Weight >= (ind.BreedParams.MinimumSize1stMating * ind.StandardReferenceWeight)
                                   )
                                   group ind by ind.Location into grp
                                   select grp;

                    int    breedersCount  = breeders.Count();
                    int    numberPossible = breedersCount;
                    int    numberServiced = 1;
                    double limiter        = 1;

                    // for each location where parts of this herd are located
                    foreach (var location in breeders)
                    {
                        // uncontrolled conception
                        if (!UseAI)
                        {
                            // check if males and females of breeding condition are together
                            if (location.GroupBy(a => a.Gender).Count() == 2)
                            {
                                // servicing rate
                                int    maleCount       = location.Where(a => a.Gender == Sex.Male).Count();
                                int    femaleCount     = location.Where(a => a.Gender == Sex.Female).Count();
                                double matingsPossible = maleCount * location.FirstOrDefault().BreedParams.MaximumMaleMatingsPerDay * 30;
                                double maleLimiter     = Math.Min(1.0, matingsPossible / femaleCount);

                                foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().ToList())
                                {
                                    if (!female.IsPregnant && (female.Age - female.AgeAtLastBirth) * 30.4 >= female.BreedParams.MinimumDaysBirthToConception)
                                    {
                                        // calculate conception
                                        Reporting.ConceptionStatus status = Reporting.ConceptionStatus.NotMated;
                                        double conceptionRate             = ConceptionRate(female, out status) * maleLimiter;
                                        if (ZoneCLEM.RandomGenerator.NextDouble() <= conceptionRate)
                                        {
                                            female.UpdateConceptionDetails(female.CalulateNumberOfOffspringThisPregnancy(), conceptionRate, i);
                                            // report conception status changed
                                            female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Conceived, female, Clock.Today));
                                        }
                                    }
                                }
                            }
                        }
                        // controlled conception
                        else
                        {
                            if (this.TimingCheck(previousDate))
                            {
                                numberPossible = Convert.ToInt32(limiter * location.Where(a => a.Gender == Sex.Female).Count(), CultureInfo.InvariantCulture);
                                foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().ToList())
                                {
                                    if (!female.IsPregnant && (female.Age - female.AgeAtLastBirth) * 30.4 >= female.BreedParams.MinimumDaysBirthToConception)
                                    {
                                        // calculate conception
                                        Reporting.ConceptionStatus status = Reporting.ConceptionStatus.NotMated;
                                        double conceptionRate             = ConceptionRate(female, out status);
                                        if (numberServiced <= numberPossible) // labour/finance limited number
                                        {
                                            if (ZoneCLEM.RandomGenerator.NextDouble() <= conceptionRate)
                                            {
                                                female.UpdateConceptionDetails(female.CalulateNumberOfOffspringThisPregnancy(), conceptionRate, i);
                                                // report conception status changed
                                                female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Conceived, female, Clock.Today));
                                            }
                                            numberServiced++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }