/// <summary> /// Calculate conception rate for a female /// </summary> /// <param name="female">Female to calculate conception rate for</param> /// <returns></returns> public double ConceptionRate(RuminantFemale female) { double rate = 0; bool isConceptionReady = false; if (female.Age >= female.BreedParams.MinimumAge1stMating && female.NumberOfBirths == 0) { isConceptionReady = true; } else { double currentIPI = female.BreedParams.InterParturitionIntervalIntercept * Math.Pow((female.Weight / female.StandardReferenceWeight), female.BreedParams.InterParturitionIntervalCoefficient) * 30.64; // calculate inter-parturition interval currentIPI = Math.Max(currentIPI, female.BreedParams.GestationLength * 30.4 + female.BreedParams.MinimumDaysBirthToConception); // 2nd param was 61 double ageNextConception = female.AgeAtLastConception + (currentIPI / 30.4); isConceptionReady = (female.Age >= ageNextConception); } // if first mating and of age or suffcient time since last birth/conception if (isConceptionReady) { rate = ConceptionRateAsymptote / (1 + Math.Exp(ConceptionRateCoefficent * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept)); } return(rate / 100); }
/// <summary> /// Calculate conception rate for a female /// </summary> /// <param name="female">Female to calculate conception rate for</param> /// <returns></returns> public double ConceptionRate(RuminantFemale female) { double rate = 0; if (female.StandardReferenceWeight > 0) { rate = ConceptionRateAsymptote / (1 + Math.Exp(ConceptionRateCoefficent * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept)); } rate = Math.Max(0, Math.Min(rate, 100)); return(rate / 100); }
/// <summary> /// Calculate conception rate for a female /// </summary> /// <param name="female">Female to calculate conception rate for</param> /// <returns></returns> public double ConceptionRate(RuminantFemale female) { double rate = 0; if (female.StandardReferenceWeight > 0) { // generalised curve switch (female.NumberOfBirths) { case 0: // first mating //if (female.BreedParams.MinimumAge1stMating >= 24) if (female.Age >= 24) { // 1st mated at 24 months or older rate = ConceptionRateAsymptote[1] / (1 + Math.Exp(ConceptionRateCoefficent[1] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[1])); } //else if (female.BreedParams.MinimumAge1stMating >= 12) else if (female.Age >= 12) { // 1st mated between 12 and 24 months double rate24 = ConceptionRateAsymptote[1] / (1 + Math.Exp(ConceptionRateCoefficent[1] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[1])); double rate12 = ConceptionRateAsymptote[0] / (1 + Math.Exp(ConceptionRateCoefficent[0] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[0])); // interpolate, not just average double propOfYear = (female.Age - 12) / 12; rate = rate12 + ((rate24 - rate12) * propOfYear); } else { // first mating < 12 months old rate = ConceptionRateAsymptote[0] / (1 + Math.Exp(ConceptionRateCoefficent[0] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[0])); } break; case 1: // second offspring mother rate = ConceptionRateAsymptote[2] / (1 + Math.Exp(ConceptionRateCoefficent[2] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[2])); break; default: // females who have had more than two births (twins should count as one birth) if (female.WeightAtConception > female.BreedParams.CriticalCowWeight * female.StandardReferenceWeight) { rate = ConceptionRateAsymptote[3] / (1 + Math.Exp(ConceptionRateCoefficent[3] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[3])); } break; } } rate = Math.Max(0, Math.Min(rate, 100)); return(rate / 100); }
/// <summary> /// Set the conception details of the female provided /// </summary> /// <param name="female">Female to set details</param> public void SetConceptionDetails(RuminantFemale female) { // if female can breed if (NumberMonthsPregnant < female.BreedParams.GestationLength && female.Age - NumberMonthsPregnant >= female.BreedParams.MinimumAge1stMating) { int offspring = female.CalulateNumberOfOffspringThisPregnancy(); if (offspring > 0) { female.UpdateConceptionDetails(offspring, 1, -1 * NumberMonthsPregnant); // report conception status changed female.BreedParams.OnConceptionStatusChanged(new Reporting.ConceptionStatusChangedEventArgs(Reporting.ConceptionStatus.Conceived, female, clock.Today.AddMonths(-1 * NumberMonthsPregnant))); } } }
/// <summary> /// Create the individual ruminant animals using the Cohort parameterisations. /// </summary> /// <returns></returns> public List <Ruminant> CreateIndividuals() { List <Ruminant> Individuals = new List <Ruminant>(); RuminantType parent = this.Parent.Parent as RuminantType; // get Ruminant Herd resource for unique ids RuminantHerd ruminantHerd = Resources.RuminantHerd(); if (Number > 0) { for (int i = 1; i <= Number; i++) { object ruminantBase = null; if (this.Gender == Sex.Male) { ruminantBase = new RuminantMale(); } else { ruminantBase = new RuminantFemale(); } Ruminant ruminant = ruminantBase as Ruminant; ruminant.ID = ruminantHerd.NextUniqueID; ruminant.BreedParams = parent; ruminant.Breed = parent.Breed; ruminant.HerdName = parent.Name; ruminant.Gender = Gender; ruminant.Age = Age; ruminant.SaleFlag = HerdChangeReason.None; if (Suckling) { ruminant.SetUnweaned(); } if (Sire) { if (this.Gender == Sex.Male) { RuminantMale ruminantMale = ruminantBase as RuminantMale; ruminantMale.BreedingSire = true; } else { Summary.WriteWarning(this, "Breeding sire switch is not valid for individual females"); } } double u1 = ZoneCLEM.RandomGenerator.NextDouble(); double u2 = ZoneCLEM.RandomGenerator.NextDouble(); double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2); ruminant.Weight = Weight + WeightSD * randStdNormal; ruminant.PreviousWeight = ruminant.Weight; if (this.Gender == Sex.Female) { RuminantFemale ruminantFemale = ruminantBase as RuminantFemale; ruminantFemale.DryBreeder = true; ruminantFemale.WeightAtConception = ruminant.Weight; ruminantFemale.NumberOfBirths = 0; } Individuals.Add(ruminantBase as Ruminant); } } return(Individuals); }
/// <summary> /// Create the individual ruminant animals using the Cohort parameterisations. /// </summary> /// <param name="number">The number of individuals to create</param> /// <param name="initialAttributes">The initial attributes found from parent and this cohort</param> /// <param name="ruminantType">The breed parameters if overwritten</param> /// <returns>List of ruminants</returns> public List <Ruminant> CreateIndividuals(int number, List <ISetAttribute> initialAttributes, RuminantType ruminantType = null) { List <Ruminant> individuals = new List <Ruminant>(); if (number > 0) { RuminantType parent = ruminantType; if (parent is null) { parent = FindAncestor <RuminantType>(); } // get Ruminant Herd resource for unique ids RuminantHerd ruminantHerd = parent.Parent as RuminantHerd; // Resources.FindResourceGroup<RuminantHerd>(); for (int i = 1; i <= number; i++) { double weight = 0; if (Weight > 0) { // avoid accidental small weight if SD provided but weight is 0 // if weight is 0 then the normalised weight will be applied in Ruminant constructor. double u1 = RandomNumberGenerator.Generator.NextDouble(); double u2 = RandomNumberGenerator.Generator.NextDouble(); double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2); weight = Weight + WeightSD * randStdNormal; } Ruminant ruminant = Ruminant.Create(Sex, parent, Age, weight); ruminant.ID = ruminantHerd.NextUniqueID; ruminant.Breed = parent.Breed; ruminant.HerdName = parent.Name; ruminant.SaleFlag = HerdChangeReason.None; if (Suckling) { if (Age >= ((parent.NaturalWeaningAge == 0)?parent.GestationLength: parent.NaturalWeaningAge)) { string limitstring = (parent.NaturalWeaningAge == 0) ? $"gestation length [{parent.GestationLength}]" : $"natural weaning age [{parent.NaturalWeaningAge}]"; string warn = $"Individuals older than {limitstring} cannot be assigned as suckling [r={parent.Name}][r={this.Parent.Name}][r={this.Name}]{Environment.NewLine}These individuals have not been assigned suckling."; Warnings.CheckAndWrite(warn, Summary, this, MessageType.Warning); } else { ruminant.SetUnweaned(); } } if (Sire) { if (this.Sex == Sex.Male) { RuminantMale ruminantMale = ruminant as RuminantMale; ruminantMale.Attributes.Add("Sire"); } else { string warn = $"Breeding sire switch is not valid for individual females [r={parent.Name}][r={this.Parent.Name}][r={this.Name}]{Environment.NewLine}These individuals have not been assigned sires. Change Sex to Male to create sires in initial herd."; Warnings.CheckAndWrite(warn, Summary, this, MessageType.Warning); } } // if weight not provided use normalised weight ruminant.PreviousWeight = ruminant.Weight; if (this.Sex == Sex.Female) { RuminantFemale ruminantFemale = ruminant as RuminantFemale; ruminantFemale.WeightAtConception = ruminant.Weight; ruminantFemale.NumberOfBirths = 0; if (setPreviousConception != null) { setPreviousConception.SetConceptionDetails(ruminantFemale); } } // initialise attributes foreach (ISetAttribute item in initialAttributes) { ruminant.Attributes.Add(item.AttributeName, item.GetAttribute(true)); } individuals.Add(ruminant); } // add any mandatory attributes to the list on the ruminant type foreach (var mattrib in initialAttributes.Where(a => a.Mandatory)) { parent.AddMandatoryAttribute(mattrib.AttributeName); } } return(individuals); }
/// <summary> /// Calculate conception rate for a female based on condition score /// </summary> /// <param name="female">Female to calculate conception rate for</param> /// <returns></returns> public double ConceptionRate(RuminantFemale female) { return((female.RelativeCondition >= ConditionCutOff) ? 1 : 0); }
/// <summary> /// Create the individual ruminant animals using the Cohort parameterisations. /// </summary> /// <param name="number">The number of individuals to create</param> /// <returns>List of ruminants</returns> public List <Ruminant> CreateIndividuals(int number) { List <Ruminant> individuals = new List <Ruminant>(); if (number > 0) { RuminantType parent = FindAncestor <RuminantType>(); // get Ruminant Herd resource for unique ids RuminantHerd ruminantHerd = Resources.RuminantHerd(); for (int i = 1; i <= number; i++) { double weight = 0; if (Weight > 0) { // avoid accidental small weight if SD provided but weight is 0 // if weight is 0 then the normalised weight will be applied in Ruminant constructor. double u1 = RandomNumberGenerator.Generator.NextDouble(); double u2 = RandomNumberGenerator.Generator.NextDouble(); double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2); weight = Weight + WeightSD * randStdNormal; } object ruminantBase; if (this.Gender == Sex.Male) { ruminantBase = new RuminantMale(Age, Gender, weight, parent); } else { ruminantBase = new RuminantFemale(Age, Gender, weight, parent); } Ruminant ruminant = ruminantBase as Ruminant; ruminant.ID = ruminantHerd.NextUniqueID; ruminant.Breed = parent.Breed; ruminant.HerdName = parent.Name; ruminant.SaleFlag = HerdChangeReason.None; if (Suckling) { ruminant.SetUnweaned(); } if (Sire) { if (this.Gender == Sex.Male) { RuminantMale ruminantMale = ruminantBase as RuminantMale; ruminantMale.IsSire = true; } else { Summary.WriteWarning(this, "Breeding sire switch is not valid for individual females [r=" + parent.Name + "].[r=" + this.Parent.Name + "].[r=" + this.Name + "]"); } } // if weight not provided use normalised weight ruminant.PreviousWeight = ruminant.Weight; if (this.Gender == Sex.Female) { RuminantFemale ruminantFemale = ruminantBase as RuminantFemale; ruminantFemale.DryBreeder = true; ruminantFemale.WeightAtConception = ruminant.Weight; ruminantFemale.NumberOfBirths = 0; } individuals.Add(ruminantBase as Ruminant); } } return(individuals); }
/// <summary> /// Calculate conception rate for a female /// </summary> /// <param name="female">Female to calculate conception rate for</param> /// <returns></returns> public double ConceptionRate(RuminantFemale female) { double rate = 0; bool isConceptionReady = false; if (female.Age >= female.BreedParams.MinimumAge1stMating && female.NumberOfBirths == 0) { isConceptionReady = true; } else { double currentIPI = female.BreedParams.InterParturitionIntervalIntercept * Math.Pow((female.Weight / female.StandardReferenceWeight), female.BreedParams.InterParturitionIntervalCoefficient) * 30.64; // calculate inter-parturition interval currentIPI = Math.Max(currentIPI, female.BreedParams.GestationLength * 30.4 + female.BreedParams.MinimumDaysBirthToConception); // 2nd param was 61 double ageNextConception = female.AgeAtLastConception + (currentIPI / 30.4); isConceptionReady = (female.Age >= ageNextConception); } // if first mating and of age or suffcient time since last birth/conception if (isConceptionReady) { // generalised curve switch (female.NumberOfBirths) { case 0: // first mating //if (female.BreedParams.MinimumAge1stMating >= 24) if (female.Age >= 24) { // 1st mated at 24 months or older rate = ConceptionRateAsymptote[1] / (1 + Math.Exp(ConceptionRateCoefficent[1] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[1])); } //else if (female.BreedParams.MinimumAge1stMating >= 12) else if (female.Age >= 12) { // 1st mated between 12 and 24 months double rate24 = ConceptionRateAsymptote[1] / (1 + Math.Exp(ConceptionRateCoefficent[1] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[1])); double rate12 = ConceptionRateAsymptote[0] / (1 + Math.Exp(ConceptionRateCoefficent[0] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[0])); // interpolate, not just average double propOfYear = (female.Age - 12) / 12; rate = rate12 + ((rate24 - rate12) * propOfYear); } else { // first mating < 12 months old rate = ConceptionRateAsymptote[0] / (1 + Math.Exp(ConceptionRateCoefficent[0] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[0])); } break; case 1: // second offspring mother rate = ConceptionRateAsymptote[2] / (1 + Math.Exp(ConceptionRateCoefficent[2] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[2])); break; default: // females who have had more than two births (twins should count as one birth) if (female.WeightAtConception > female.BreedParams.CriticalCowWeight * female.StandardReferenceWeight) { rate = ConceptionRateAsymptote[3] / (1 + Math.Exp(ConceptionRateCoefficent[3] * female.Weight / female.StandardReferenceWeight + ConceptionRateIntercept[3])); } break; } } return(rate / 100); }
/// <summary> /// Create the individual ruminant animals using the Cohort parameterisations. /// </summary> /// <param name="number">The number of individuals to create</param> /// <param name="initialAttributes">The initial attributes found from parent and this cohort</param> /// <param name="ruminantType">The breed parameters if overwritten</param> /// <returns>List of ruminants</returns> public List <Ruminant> CreateIndividuals(int number, List <ISetAttribute> initialAttributes, RuminantType ruminantType = null) { List <Ruminant> individuals = new List <Ruminant>(); if (number > 0) { RuminantType parent = ruminantType; if (parent is null) { parent = FindAncestor <RuminantType>(); } // get Ruminant Herd resource for unique ids RuminantHerd ruminantHerd = parent.Parent as RuminantHerd; // Resources.FindResourceGroup<RuminantHerd>(); for (int i = 1; i <= number; i++) { double weight = 0; if (Weight > 0) { // avoid accidental small weight if SD provided but weight is 0 // if weight is 0 then the normalised weight will be applied in Ruminant constructor. double u1 = RandomNumberGenerator.Generator.NextDouble(); double u2 = RandomNumberGenerator.Generator.NextDouble(); double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2); weight = Weight + WeightSD * randStdNormal; } Ruminant ruminant = Ruminant.Create(Sex, parent, Age, weight); ruminant.ID = ruminantHerd.NextUniqueID; ruminant.Breed = parent.Breed; ruminant.HerdName = parent.Name; ruminant.SaleFlag = HerdChangeReason.None; if (Suckling) { ruminant.SetUnweaned(); } if (Sire) { if (this.Sex == Sex.Male) { RuminantMale ruminantMale = ruminant as RuminantMale; ruminantMale.Attributes.Add("Sire"); } else { Summary.WriteWarning(this, "Breeding sire switch is not valid for individual females [r=" + parent.Name + "].[r=" + this.Parent.Name + "].[r=" + this.Name + "]"); } } // if weight not provided use normalised weight ruminant.PreviousWeight = ruminant.Weight; if (this.Sex == Sex.Female) { RuminantFemale ruminantFemale = ruminant as RuminantFemale; ruminantFemale.WeightAtConception = ruminant.Weight; ruminantFemale.NumberOfBirths = 0; if (setPreviousConception != null) { setPreviousConception.SetConceptionDetails(ruminantFemale); } } // initialise attributes foreach (ISetAttribute item in initialAttributes) { ruminant.Attributes.Add(item.AttributeName, item.GetAttribute(true)); } individuals.Add(ruminant); } // add any mandatory attributes to the list on the ruminant type foreach (var mattrib in initialAttributes.Where(a => a.Mandatory)) { parent.AddMandatoryAttribute(mattrib.AttributeName); } } return(individuals); }
/// <summary> /// Calculate conception rate for a female based on condition score /// </summary> /// <param name="female">Female to calculate conception rate for</param> /// <returns></returns> public double ConceptionRate(RuminantFemale female) { return((female.RelativeCondition >= ConditionCutOff) ? MaximumConceptionProbability : 0); }