/// <summary> /// Create the individual ruminant animals using the Cohort parameterisations. /// </summary> /// <returns></returns> public List <Ruminant> CreateIndividuals() { List <Ruminant> Individuals = new List <Ruminant>(); IModel parentNode = Apsim.Parent(this, typeof(IModel)); RuminantType parent = parentNode as RuminantType; // get Ruminant Herd resource for unique ids RuminantHerd ruminantHerd = Resources.RuminantHerd(); parent = this.Parent as RuminantType; if (StartingNumber > 0) { //TODO: get random generator from global store with seed Random rand = new Random(); for (int i = 1; i <= StartingNumber; 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 = StartingAge; ruminant.SaleFlag = Common.HerdChangeReason.None; if (Suckling) { ruminant.SetUnweaned(); } double u1 = rand.NextDouble(); double u2 = rand.NextDouble(); double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2); ruminant.Weight = StartingWeight + StartingWeightSD * randStdNormal; ruminant.PreviousWeight = ruminant.Weight; if (this.Gender == Sex.Female) { RuminantFemale ruminantFemale = ruminantBase as RuminantFemale; ruminantFemale.DryBreeder = true; ruminantFemale.WeightAtConception = this.StartingWeight; ruminantFemale.NumberOfBirths = 0; } Individuals.Add(ruminantBase as Ruminant); } } return(Individuals); }
private void OnWFAnimalBreeding(object sender, EventArgs e) { RuminantHerd ruminantHerd = Resources.RuminantHerd(); List <Ruminant> herd = ruminantHerd.Herd.Where(a => a.BreedParams.Name == HerdName).ToList(); // 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 >= ind.BreedParams.MinimumAge1stMating) ^ (ind.Gender == Sex.Female & ind.Age >= ind.BreedParams.MinimumAge1stMating & ind.Weight >= (ind.BreedParams.MinimumSize1stMating * ind.StandardReferenceWeight) ) group ind by ind.Location into grp select grp; // for each location where parts of this herd are located foreach (var location in breeders) { // check for births of all pregnant females. foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().ToList()) { if (female.BirthDue) { int numberOfNewborn = (female.CarryingTwins) ? 2 : 1; for (int i = 0; i < numberOfNewborn; i++) { // Determine if the offspring died during pregancy from conception to after birth // This is currently only performed at time of birth rather than monthly during pregnancy // and so does not reflect changes in female intake etc after dead of foetus. // this now occurs monthly at the ned of this breeding method. //if (randomGenerator.RandNo > female.BreedParams.PrenatalMortality) //{ object newCalf = null; bool isMale = (randomGenerator.RandNo > 0.5); if (isMale) { newCalf = new RuminantMale(); } else { newCalf = new RuminantFemale(); } Ruminant newCalfRuminant = newCalf as Ruminant; newCalfRuminant.Age = 0; newCalfRuminant.HerdName = female.HerdName; newCalfRuminant.BreedParams = female.BreedParams; newCalfRuminant.Gender = (isMale) ? Sex.Male : Sex.Female; newCalfRuminant.ID = ruminantHerd.NextUniqueID; newCalfRuminant.Location = female.Location; newCalfRuminant.Mother = female; // newCalfRuminant.Number = 1; newCalfRuminant.SetUnweaned(); // calf weight from Freer newCalfRuminant.Weight = female.BreedParams.SRWBirth * female.StandardReferenceWeight * (1 - 0.33 * (1 - female.Weight / female.StandardReferenceWeight)); newCalfRuminant.HighWeight = newCalfRuminant.Weight; newCalfRuminant.SaleFlag = Common.HerdChangeReason.Born; ruminantHerd.AddRuminant(newCalfRuminant); // add to sucklings female.SucklingOffspring.Add(newCalfRuminant); //} } female.UpdateBirthDetails(); } } // Conception // 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.Max(1.0, matingsPossible / femaleCount); foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().ToList()) { //TODO: ensure enough time since last calf if (!female.IsPregnant & !female.IsLactating) { // calculate conception double conceptionRate = ConceptionRate(female) * maleLimiter; if (randomGenerator.RandNo <= conceptionRate) { female.UpdateConceptionDetails(randomGenerator.RandNo > female.BreedParams.TwinRate, conceptionRate); } } } } // determine all foetus and newborn mortality. foreach (RuminantFemale female in location.Where(a => a.Gender == Sex.Female).Cast <RuminantFemale>().ToList()) { if (female.IsPregnant) { // calculate foetus and newborn mortality // total mortality / gestation months to get monthly mortality // TODO: check if need to be done before births to get last month mortality if (randomGenerator.RandNo > female.BreedParams.PrenatalMortality / female.BreedParams.GestationLength) { female.OneOffspringDies(); } } } } }