private void OnWFAnimalManage(object sender, EventArgs e) { RuminantHerd ruminantHerd = Resources.RuminantHerd(); List<Ruminant> herd = ruminantHerd.Herd.Where(a => a.HerdName == HerdName).ToList(); RuminantType breedParams; // get breedParams when no herd remaining if (herd.Count() == 0) { breedParams = Resources.GetResourceItem("Ruminants", HerdName) as RuminantType; } else { breedParams = herd.FirstOrDefault().BreedParams; } // can sell off males any month as per NABSA // if we don't need this monthly, then it goes into next if statement with herd declaration // NABSA MALES - weaners, 1-2, 2-3 and 3-4 yo, we check for any male weaned and not a breeding sire. // check for sell age/weight of young males // if SellYoungFemalesLikeMales then all apply to both sexes else only males. foreach (var ind in herd.Where(a => a.Weaned & (SellFemalesLikeMales ? true : (a.Gender == Sex.Male)) & (a.Age >= SellingAge ^ a.Weight >= SellingWeight))) { bool sell = true; if (ind.GetType() == typeof(RuminantMale)) { // don't sell breeding sires. sell = !((ind as RuminantMale).BreedingSire); } if (sell) { ind.SaleFlag = Common.HerdChangeReason.AgeWeightSale; } } // if management month if (Clock.Today.Month == ManagementMonth ^ MonthlyManagement) { // Perform weaning foreach (var ind in herd.Where(a => a.Weaned == false)) { if (ind.Age >= WeaningAge ^ ind.Weight >= WeaningWeight) { ind.Wean(); } } // check for maximum age (females and males have different cutoffs) foreach (var ind in herd.Where(a => a.Age >= ((a.Gender == Sex.Female) ? MaximumBreederAge : MaximumBullAge))) { ind.SaleFlag = Common.HerdChangeReason.MaxAgeSale; } // MALES // check for breeder bulls after sale of old individuals and buy/sell int numberinherd = herd.Where(a => a.Gender == Sex.Male & a.SaleFlag == Common.HerdChangeReason.None).Cast<RuminantMale>().Where(a => a.BreedingSire).Count(); if (numberinherd > MaximumSiresKept) { // sell bulls // What rule? oldest first as they may be lost soonest int numberToRemove = MaximumSiresKept - numberinherd; foreach (var male in herd.Where(a => a.Gender == Sex.Male).Cast<RuminantMale>().Where(a => a.BreedingSire).OrderByDescending(a => a.Age).Take(numberToRemove)) { male.SaleFlag = Common.HerdChangeReason.ExcessBullSale; } } else if(numberinherd < MaximumSiresKept) { // remove young bulls from sale herd to replace breed bulls (not those sold because too old) foreach (RuminantMale male in herd.Where(a => a.Gender == Sex.Male & a.SaleFlag == Common.HerdChangeReason.AgeWeightSale).OrderByDescending(a => a.Weight)) { male.SaleFlag = Common.HerdChangeReason.None; male.BreedingSire = true; numberinherd++; if (numberinherd >= MaximumSiresKept) break; } // if still insufficient buy bulls. if (numberinherd < MaximumSiresKept) { int numberToBuy = Convert.ToInt32((MaximumSiresKept - numberinherd) * 0.05); for (int i = 0; i < numberToBuy; i++) { RuminantMale newbull = new RuminantMale(); newbull.Age = 48; newbull.HerdName = HerdName; newbull.BreedingSire = true; newbull.BreedParams = breedParams; newbull.Gender = Sex.Male; newbull.ID = ruminantHerd.NextUniqueID; newbull.Weight = 450; newbull.HighWeight = newbull.Weight; newbull.SaleFlag = Common.HerdChangeReason.SirePurchase; // add to purchase request list and await purchase in Buy/ Sell ruminantHerd.PurchaseIndividuals.Add(newbull); } } } // FEMALES // check for maximum number of breeders remaining after sale and buy/sell numberinherd = herd.Where(a => a.Gender == Sex.Female & a.Age >= a.BreedParams.MinimumAge1stMating & a.SaleFlag == Common.HerdChangeReason.None).Count(); if (numberinherd > MaximumBreedersKept) { // sell breeders // What rule? oldest first as they may be lost soonest // should keep pregnant females... and young... // this will currently remove pregnant females and females with suckling calf int numberToRemove = MaximumBreedersKept - numberinherd; foreach (var female in herd.Where(a => a.Gender == Sex.Female & a.Age >= a.BreedParams.MinimumAge1stMating).OrderByDescending(a => a.Age).Take(numberToRemove)) { female.SaleFlag = Common.HerdChangeReason.ExcessBreederSale; } } else { // remove young females from sale herd to replace breeders (not those sold because too old) foreach (RuminantFemale female in herd.Where(a => a.Gender == Sex.Female & a.SaleFlag == Common.HerdChangeReason.AgeWeightSale).OrderByDescending(a => a.Weight)) { female.SaleFlag = Common.HerdChangeReason.None; numberinherd++; if (numberinherd >= MaximumBreedersKept) break; } // if still insufficient buy breeders. if (numberinherd < MaximumBreedersKept) { int ageOfHeifer = 12; double weightOfHeifer = 260; int numberToBuy = Convert.ToInt32((MaximumBreedersKept - numberinherd) * 0.05); for (int i = 0; i < numberToBuy; i++) { RuminantFemale newheifer = new RuminantFemale(); newheifer.Age = ageOfHeifer; newheifer.HerdName = HerdName; newheifer.BreedParams = breedParams; newheifer.Gender = Sex.Female; newheifer.ID = ruminantHerd.NextUniqueID; newheifer.Weight = weightOfHeifer; newheifer.HighWeight = newheifer.Weight; newheifer.SaleFlag = Common.HerdChangeReason.HeiferPurchase; // add to purchase request list and await purchase in Buy/ Sell ruminantHerd.PurchaseIndividuals.Add(newheifer); } } } } }
/// <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 OnWFAnimalManage(object sender, EventArgs e) { RuminantHerd ruminantHerd = Resources.RuminantHerd(); List <Ruminant> herd = ruminantHerd.Herd.Where(a => a.HerdName == HerdName).ToList(); RuminantType breedParams; // get breedParams when no herd remaining if (herd.Count() == 0) { breedParams = Resources.GetResourceItem("Ruminants", HerdName) as RuminantType; } else { breedParams = herd.FirstOrDefault().BreedParams; } // can sell off males any month as per NABSA // if we don't need this monthly, then it goes into next if statement with herd declaration // NABSA MALES - weaners, 1-2, 2-3 and 3-4 yo, we check for any male weaned and not a breeding sire. // check for sell age/weight of young males // if SellYoungFemalesLikeMales then all apply to both sexes else only males. foreach (var ind in herd.Where(a => a.Weaned & (SellFemalesLikeMales ? true : (a.Gender == Sex.Male)) & (a.Age >= SellingAge ^ a.Weight >= SellingWeight))) { bool sell = true; if (ind.GetType() == typeof(RuminantMale)) { // don't sell breeding sires. sell = !((ind as RuminantMale).BreedingSire); } if (sell) { ind.SaleFlag = Common.HerdChangeReason.AgeWeightSale; } } // if management month if (Clock.Today.Month == ManagementMonth ^ MonthlyManagement) { // Perform weaning foreach (var ind in herd.Where(a => a.Weaned == false)) { if (ind.Age >= WeaningAge ^ ind.Weight >= WeaningWeight) { ind.Wean(); } } // check for maximum age (females and males have different cutoffs) foreach (var ind in herd.Where(a => a.Age >= ((a.Gender == Sex.Female) ? MaximumBreederAge : MaximumBullAge))) { ind.SaleFlag = Common.HerdChangeReason.MaxAgeSale; } // MALES // check for breeder bulls after sale of old individuals and buy/sell int numberinherd = herd.Where(a => a.Gender == Sex.Male & a.SaleFlag == Common.HerdChangeReason.None).Cast <RuminantMale>().Where(a => a.BreedingSire).Count(); if (numberinherd > MaximumSiresKept) { // sell bulls // What rule? oldest first as they may be lost soonest int numberToRemove = MaximumSiresKept - numberinherd; foreach (var male in herd.Where(a => a.Gender == Sex.Male).Cast <RuminantMale>().Where(a => a.BreedingSire).OrderByDescending(a => a.Age).Take(numberToRemove)) { male.SaleFlag = Common.HerdChangeReason.ExcessBullSale; } } else if (numberinherd < MaximumSiresKept) { // remove young bulls from sale herd to replace breed bulls (not those sold because too old) foreach (RuminantMale male in herd.Where(a => a.Gender == Sex.Male & a.SaleFlag == Common.HerdChangeReason.AgeWeightSale).OrderByDescending(a => a.Weight)) { male.SaleFlag = Common.HerdChangeReason.None; male.BreedingSire = true; numberinherd++; if (numberinherd >= MaximumSiresKept) { break; } } // if still insufficient buy bulls. if (numberinherd < MaximumSiresKept) { int numberToBuy = Convert.ToInt32((MaximumSiresKept - numberinherd) * 0.05); for (int i = 0; i < numberToBuy; i++) { RuminantMale newbull = new RuminantMale(); newbull.Age = 48; newbull.HerdName = HerdName; newbull.BreedingSire = true; newbull.BreedParams = breedParams; newbull.Gender = Sex.Male; newbull.ID = ruminantHerd.NextUniqueID; newbull.Weight = 450; newbull.HighWeight = newbull.Weight; newbull.SaleFlag = Common.HerdChangeReason.SirePurchase; // add to purchase request list and await purchase in Buy/ Sell ruminantHerd.PurchaseIndividuals.Add(newbull); } } } // FEMALES // check for maximum number of breeders remaining after sale and buy/sell numberinherd = herd.Where(a => a.Gender == Sex.Female & a.Age >= a.BreedParams.MinimumAge1stMating & a.SaleFlag == Common.HerdChangeReason.None).Count(); if (numberinherd > MaximumBreedersKept) { // sell breeders // What rule? oldest first as they may be lost soonest // should keep pregnant females... and young... // this will currently remove pregnant females and females with suckling calf int numberToRemove = MaximumBreedersKept - numberinherd; foreach (var female in herd.Where(a => a.Gender == Sex.Female & a.Age >= a.BreedParams.MinimumAge1stMating).OrderByDescending(a => a.Age).Take(numberToRemove)) { female.SaleFlag = Common.HerdChangeReason.ExcessBreederSale; } } else { // remove young females from sale herd to replace breeders (not those sold because too old) foreach (RuminantFemale female in herd.Where(a => a.Gender == Sex.Female & a.SaleFlag == Common.HerdChangeReason.AgeWeightSale).OrderByDescending(a => a.Weight)) { female.SaleFlag = Common.HerdChangeReason.None; numberinherd++; if (numberinherd >= MaximumBreedersKept) { break; } } // if still insufficient buy breeders. if (numberinherd < MaximumBreedersKept) { int ageOfHeifer = 12; double weightOfHeifer = 260; int numberToBuy = Convert.ToInt32((MaximumBreedersKept - numberinherd) * 0.05); for (int i = 0; i < numberToBuy; i++) { RuminantFemale newheifer = new RuminantFemale(); newheifer.Age = ageOfHeifer; newheifer.HerdName = HerdName; newheifer.BreedParams = breedParams; newheifer.Gender = Sex.Female; newheifer.ID = ruminantHerd.NextUniqueID; newheifer.Weight = weightOfHeifer; newheifer.HighWeight = newheifer.Weight; newheifer.SaleFlag = Common.HerdChangeReason.HeiferPurchase; // add to purchase request list and await purchase in Buy/ Sell ruminantHerd.PurchaseIndividuals.Add(newheifer); } } } } }
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(); } } } } }
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(); } } } } }
/// <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; }