/// <summary> /// Get value of a specific individual /// </summary> /// <returns>value</returns> public double ValueofIndividual(Ruminant ind, PurchaseOrSalePricingStyleType purchaseStyle) { if (PricingAvailable()) { List <Ruminant> animalList = new List <Ruminant>() { ind }; // search through RuminantPriceGroups for first match with desired purchase or sale flag foreach (AnimalPriceGroup item in priceGroups.Where(a => a.PurchaseOrSale == purchaseStyle || a.PurchaseOrSale == PurchaseOrSalePricingStyleType.Both)) { if (animalList.Filter(item).Count() == 1) { return(item.Value * ((item.PricingStyle == PricingStyleType.perKg) ? ind.Weight : 1.0)); } } // no price match found. string warningString = $"No [{purchaseStyle.ToString()}] price entry was found for [r={ind.Breed}] meeting the required criteria [f=age: {ind.Age}] [f=gender: {ind.GenderAsString}] [f=weight: {ind.Weight.ToString("##0")}]"; if (!Warnings.Exists(warningString)) { Warnings.Add(warningString); Summary.WriteWarning(this, warningString); } } return(0); }
/// <summary> /// Add individual/cohort to the the herd /// </summary> /// <param name="ind">Individual Ruminant to add</param> /// <param name="model">Model adding individual</param> public void AddRuminant(Ruminant ind, IModel model) { if (ind.ID == 0) { ind.ID = this.NextUniqueID; } Herd.Add(ind); LastIndividualChanged = ind; ResourceTransaction details = new ResourceTransaction(); details.Gain = 1; details.Activity = model.Name; details.ActivityType = model.GetType().Name; details.Reason = ind.SaleFlag.ToString(); details.ResourceType = this.Name; details.ExtraInformation = ind; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); // remove change flag ind.SaleFlag = HerdChangeReason.None; }
/// <summary> /// Provides the closing html tags for object /// </summary> /// <returns></returns> public override string ModelSummaryInnerClosingTags(bool formatForParentControl) { string html = ""; if (formatForParentControl) { RuminantType rumtype = FindAncestor <RuminantType>(); Ruminant newInd = null; string normWtString = "Unavailable"; double normalisedWt = 0; if (rumtype != null) { newInd = new Ruminant(this.Age, this.Gender, 0, FindAncestor <RuminantType>()); normWtString = newInd.NormalisedAnimalWeight.ToString("#,##0"); normalisedWt = newInd.NormalisedAnimalWeight; if (Math.Abs(this.Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { normWtString = "<span class=\"errorlink\">" + normWtString + "</span>"; (this.Parent as RuminantInitialCohorts).WeightWarningOccurred = true; } html += "\n<tr><td>" + this.Name + "</td><td><span class=\"setvalue\">" + this.Gender + "</span></td><td><span class=\"setvalue\">" + this.Age.ToString() + "</span></td><td><span class=\"setvalue\">" + this.Weight.ToString() + ((this.WeightSD > 0) ? " (" + this.WeightSD.ToString() + ")" : "") + "</spam></td><td>" + normWtString + "</td><td><span class=\"setvalue\">" + this.Number.ToString() + "</span></td><td" + ((this.Suckling) ? " class=\"fill\"" : "") + "></td><td" + ((this.Sire) ? " class=\"fill\"" : "") + "></td></tr>"; } } else { html += "\n</div>"; } return(html); }
/// <summary> /// Get value of a specific individual /// </summary> /// <returns>value</returns> public AnimalPriceGroup ValueofIndividual(Ruminant ind, PurchaseOrSalePricingStyleType purchaseStyle, string warningMessage = "") { if (PricingAvailable()) { if (ind.CurrentPrice == null || !ind.CurrentPrice.Filter(ind)) { // search through RuminantPriceGroups for first match with desired purchase or sale flag foreach (AnimalPriceGroup priceGroup in priceGroups.Where(a => a.PurchaseOrSale == purchaseStyle || a.PurchaseOrSale == PurchaseOrSalePricingStyleType.Both)) { if (priceGroup.Filter(ind)) { ind.CurrentPrice = priceGroup; return(priceGroup); } } // no price match found. string warningString = warningMessage; if (warningString == "") { warningString = $"No [{purchaseStyle}] price entry was found for [r={ind.Breed}] meeting the required criteria [f=age: {ind.Age}] [f=sex: {ind.Sex}] [f=weight: {ind.Weight:##0}]"; } Warnings.CheckAndWrite(warningString, Summary, this); } return(ind.CurrentPrice); } return(null); }
/// <summary> /// Get value of a specific individual /// </summary> /// <returns>value</returns> public double ValueofIndividual(Ruminant ind, bool PurchasePrice) { if (PricingAvailable()) { // ordering now done when the list is created for speed //AnimalPriceValue getvalue = PriceList.Where(a => a.Age < ind.Age).OrderBy(a => a.Age).LastOrDefault(); AnimalPriceValue getvalue = PriceList.Where(a => a.Age <= ind.Age).LastOrDefault(); if (getvalue == null) { getvalue = PriceList.OrderBy(a => a.Age).FirstOrDefault(); Summary.WriteWarning(this, "No pricing was found for indiviudal [" + ind.HerdName + "] of age [" + ind.Age + "]"); Summary.WriteWarning(this, "Using pricing for individual of age [" + getvalue.Age + "]"); } if (PurchasePrice) { return(getvalue.PurchaseValue * ((getvalue.Style == PricingStyleType.perKg) ? ind.Weight : 1.0)); } else { return(getvalue.SellValue * ((getvalue.Style == PricingStyleType.perKg) ? ind.Weight : 1.0)); } } else { return(0); } }
/// <summary> /// Add individual/cohort to the the herd /// </summary> /// <param name="ind">Individual Ruminant to add</param> /// <param name="model">Model adding individual</param> public void AddRuminant(Ruminant ind, IModel model) { if (ind.ID == 0) { ind.ID = this.NextUniqueID; } Herd.Add(ind); LastIndividualChanged = ind; // check mandatory attributes ind.BreedParams.CheckMandatoryAttributes(ind, model); ResourceTransaction details = new ResourceTransaction { TransactionType = TransactionType.Gain, Amount = 1, Activity = model as CLEMModel, Category = ind.SaleFlag.ToString(), ResourceType = ind.BreedParams, RelatesToResource = ind.BreedParams.NameWithParent, ExtraInformation = ind }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); // remove change flag ind.SaleFlag = HerdChangeReason.None; }
/// <summary> /// Remove individual/cohort from the herd /// </summary> /// <param name="ind">Individual Ruminant to remove</param> public void RemoveRuminant(Ruminant ind) { // Remove mother ID from any suckling offspring if (ind.Gender == Sex.Female) { foreach (var offspring in (ind as RuminantFemale).SucklingOffspring) { offspring.Mother = null; } } Herd.Remove(ind); LastIndividualChanged = ind; ResourceTransaction details = new ResourceTransaction(); details.Debit = -1; details.Activity = "Unknown"; details.Reason = "Unknown"; details.ResourceType = this.Name; details.ExtraInformation = ind; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); // remove change flag ind.SaleFlag = HerdChangeReason.None; }
/// <summary> /// Add individual/cohort to the the herd /// </summary> /// <param name="ind">Individual Ruminant to add</param> public void AddRuminant(Ruminant ind) { if (ind.ID == 0) { ind.ID = this.NextUniqueID; } Herd.Add(ind); LastIndividualChanged = ind; ResourceTransaction details = new ResourceTransaction(); details.Credit = 1; details.Activity = "Unknown"; details.Reason = "Unknown"; details.ResourceType = this.Name; details.ExtraInformation = ind; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); // remove change flag ind.SaleFlag = HerdChangeReason.None; }
/// <summary> /// Get value of a specific individual /// </summary> /// <returns>value</returns> public double ValueofIndividual(Ruminant ind, PurchaseOrSalePricingStyleType purchaseStyle) { if (PricingAvailable()) { List <Ruminant> animalList = new List <Ruminant>() { ind }; // search through RuminantPriceGroups for first match with desired purchase or sale flag foreach (AnimalPriceGroup item in Apsim.Children(PriceList, typeof(AnimalPriceGroup)).Cast <AnimalPriceGroup>().Where(a => a.PurchaseOrSale == purchaseStyle || a.PurchaseOrSale == PurchaseOrSalePricingStyleType.Both)) { if (animalList.Filter(item).Count() == 1) { return(item.Value * ((item.PricingStyle == PricingStyleType.perKg) ? ind.Weight : 1.0)); } } // no price match found. string warning = "No " + purchaseStyle.ToString() + " price entry was found for an indiviudal with details ([f=age: " + ind.Age + "] [f=herd: " + ind.HerdName + "] [f=gender: " + ind.GenderAsString + "] [f=weight: " + ind.Weight.ToString("##0") + "])"; if (!Warnings.Exists(warning)) { Warnings.Add(warning); Summary.WriteWarning(this, warning); } } return(0); }
/// <summary> /// Add individual/cohort to the the herd /// </summary> /// <param name="ind">Individual Ruminant to add</param> /// <param name="model">Model adding individual</param> public void AddRuminant(Ruminant ind, IModel model) { if (ind.ID == 0) { ind.ID = this.NextUniqueID; } Herd.Add(ind); LastIndividualChanged = ind; ResourceTransaction details = new ResourceTransaction { Gain = 1, Activity = model as CLEMModel, Reason = ind.SaleFlag.ToString(), ResourceType = ind.BreedParams, ExtraInformation = ind }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); // remove change flag ind.SaleFlag = HerdChangeReason.None; }
/// <summary> /// Remove individual/cohort from the herd /// </summary> /// <param name="ind">Individual Ruminant to remove</param> /// <param name="model">Model removing individual</param> public void RemoveRuminant(Ruminant ind, IModel model) { // Remove mother ID from any suckling offspring if (ind.Sex == Sex.Female) { foreach (var offspring in (ind as RuminantFemale).SucklingOffspringList) { offspring.Mother = null; } } // if sold and unweaned set mothers weaning count + 1 as effectively weaned in process and not death if (!ind.Weaned & !ind.SaleFlag.ToString().Contains("Died")) { if (ind.Mother != null) { ind.Mother.NumberOfWeaned++; } } Herd.Remove(ind); LastIndividualChanged = ind; // report transaction of herd change ResourceTransaction details = new ResourceTransaction { TransactionType = TransactionType.Loss, Amount = 1, Activity = model as CLEMModel, Category = ind.SaleFlag.ToString(), ResourceType = ind.BreedParams, RelatesToResource = ind.BreedParams.NameWithParent, ExtraInformation = ind }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); // report female breeding stats if needed if (ind.Sex == Sex.Female & ind.Age >= ind.BreedParams.MinimumAge1stMating) { RuminantReportItemEventArgs args = new RuminantReportItemEventArgs { RumObj = ind, Category = "breeding stats" }; OnFinalFemaleOccurred(args); } // remove change flag ind.SaleFlag = HerdChangeReason.None; }
/// <summary> /// Provides the description of the model settings for summary (GetFullSummary) /// </summary> /// <param name="formatForParentControl">Use full verbose description</param> /// <returns></returns> public override string ModelSummary(bool formatForParentControl) { string html = ""; if (!formatForParentControl) { html += "\n<div class=\"activityentry\">"; if (Number <= 0) { html += "<span class=\"errorlink\">" + Number.ToString() + "</span> x "; } else if (Number > 1) { html += "<span class=\"setvalue\">" + Number.ToString() + "</span> x "; } else { html += "A "; } html += "<span class=\"setvalue\">"; html += Age.ToString("0") + "</span> month old "; html += "<span class=\"setvalue\">" + Gender.ToString() + "</span></div>"; if (Suckling) { html += "\n<div class=\"activityentry\">" + ((Number > 1)?"These individuals are suckling":"This individual is a suckling") + "</div>"; } if (Sire) { html += "\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals are breeding sires" : "This individual is a breeding sire") + "</div>"; } Ruminant newInd = new Ruminant(this.Age, this.Gender, 0, Apsim.Parent(this, typeof(RuminantType)) as RuminantType); string normWtString = newInd.NormalisedAnimalWeight.ToString("#,##0"); double weightToUse = newInd.Weight; if (WeightSD > 0) { html += "\n<div class=\"activityentry\">Individuals will be randomally assigned a weight based on a mean " + ((Weight == 0) ? "(using the normalised weight) " : "") + "of <span class=\"setvalue\">" + Weight.ToString("#,##0") + "</span> kg with a standard deviation of <span class=\"setvalue\">" + WeightSD.ToString() + "</span></div>"; if (Math.Abs(Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { html += "<div class=\"activityentry\">These individuals should weigh close to the normalised weight of <span class=\"errorlink\">" + normWtString + "</span> kg for their age</div>"; } } else { html += "\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals " : "This individual ") + "weigh" + ((Number > 1) ? "" : "s") + ((Weight == 0)?" the normalised weight of ":"") + " <span class=\"setvalue\">" + Weight.ToString("#,##0") + "</span> kg"; if (Math.Abs(Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { html += ", but should weigh close to the normalised weight of <span class=\"errorlink\">" + normWtString + "</span> kg for their age"; } html += "</div>"; } html += "</div>"; } return(html); }
/// <summary> /// Check whether an individual has all mandotory attributes /// </summary> /// <param name="ind">Individual ruminant to check</param> /// <param name="model">Model adding individuals</param> public void CheckMandatoryAttributes(Ruminant ind, IModel model) { foreach (var attribute in mandatoryAttributes) { if (!ind.Attributes.Exists(attribute)) { string warningString = $"No mandatory attribute [{attribute.ToUpper()}] present for individual added by [a={model.Name}]"; Warnings.CheckAndWrite(warningString, Summary, this, MessageType.Error); } } }
/// <summary> /// Check whether an individual has all mandotory attributes /// </summary> /// <param name="ind">Individual ruminant to check</param> /// <param name="model">Model adding individuals</param> public void CheckMandatoryAttributes(Ruminant ind, IModel model) { foreach (var attribute in mandatoryAttributes) { if (!ind.AttributeExists(attribute)) { string warningString = $"No mandatory attribute [{attribute.ToUpper()}] present for individual added by [a={model.Name}]"; if (!Warnings.Exists(warningString)) { Warnings.Add(warningString); Summary.WriteWarning(this, warningString); } } } }
/// <summary> /// Provides the closing html tags for object /// </summary> /// <returns></returns> public override string ModelSummaryInnerClosingTags(bool formatForParentControl) { string html = ""; if (formatForParentControl) { Ruminant newInd = new Ruminant(this.Age, this.Gender, 0, Apsim.Parent(this, typeof(RuminantType)) as RuminantType); double normalisedWt = newInd.NormalisedAnimalWeight; string normWtString = normalisedWt.ToString("#,##0"); if (Math.Abs(this.Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { normWtString = "<span class=\"errorlink\">" + normWtString + "</span>"; } html += "\n<tr><td>" + this.Name + "</td><td><span class=\"setvalue\">" + this.Gender + "</span></td><td><span class=\"setvalue\">" + this.Age.ToString() + "</span></td><td><span class=\"setvalue\">" + this.Weight.ToString() + ((this.WeightSD > 0) ? " (" + this.WeightSD.ToString() + ")" : "") + "</spam></td><td>" + normWtString + "</td><td><span class=\"setvalue\">" + this.Number.ToString() + "</span></td><td" + ((this.Suckling) ? " class=\"fill\"" : "") + "></td><td" + ((this.Sire) ? " class=\"fill\"" : "") + "></td></tr>"; } else { html += "\n</div>"; } return(html); }
/// <summary> /// Get value of a specific individual with special requirements check (e.g. breeding sire or draught purchase) /// </summary> /// <returns>value</returns> public double ValueofIndividual(Ruminant ind, PurchaseOrSalePricingStyleType purchaseStyle, RuminantFilterParameters property, string value) { double price = 0; if (PricingAvailable()) { string criteria = property.ToString().ToUpper() + ":" + value.ToUpper(); List <Ruminant> animalList = new List <Ruminant>() { ind }; //find first pricing entry matching specific criteria AnimalPriceGroup matchIndividual = null; AnimalPriceGroup matchCriteria = null; foreach (AnimalPriceGroup item in PriceList.FindAllChildren <AnimalPriceGroup>().Cast <AnimalPriceGroup>().Where(a => a.PurchaseOrSale == purchaseStyle || a.PurchaseOrSale == PurchaseOrSalePricingStyleType.Both)) { if (animalList.Filter(item).Count() == 1 && matchIndividual == null) { matchIndividual = item; } // check that pricing item meets the specified criteria. if (item.FindAllChildren <RuminantFilter>().Cast <RuminantFilter>().Where(a => (a.Parameter.ToString().ToUpper() == property.ToString().ToUpper() && a.Value.ToUpper() == value.ToUpper())).Count() > 0) { if (matchCriteria == null) { matchCriteria = item; } else { // multiple price entries were found. using first. value = xxx. if (!WarningsMultipleEntry.Contains(criteria)) { WarningsMultipleEntry.Add(criteria); Summary.WriteWarning(this, "Multiple specific [" + purchaseStyle.ToString() + "] price entries were found for [r=" + ind.Breed + "] where [" + property + "]" + (value.ToUpper() != "TRUE" ? " = [" + value + "]." : ".") + "\nOnly the first entry will be used. Price [" + matchCriteria.Value.ToString("#,##0.##") + "] [" + matchCriteria.PricingStyle.ToString() + "]."); } } } } if (matchCriteria == null) { // report specific criteria not found in price list string warningString = "No [" + purchaseStyle.ToString() + "] price entry was found for [r=" + ind.Breed + "] meeting the required criteria [" + property + "]" + (value.ToUpper() != "TRUE" ? " = [" + value + "]." : "."); if (matchIndividual != null) { // add using the best pricing available for [][] purchases of xx per head warningString += "\nThe best available price [" + matchIndividual.Value.ToString("#,##0.##") + "] [" + matchIndividual.PricingStyle.ToString() + "] will be used."; price = matchIndividual.Value * ((matchIndividual.PricingStyle == PricingStyleType.perKg) ? ind.Weight : 1.0); } else { warningString += "\nNo alternate price for individuals could be found for the individuals. Add a new [r=AnimalPriceGroup] entry in the [r=AnimalPricing] for [" + ind.Breed + "]"; } if (!WarningsNotFound.Contains(criteria)) { WarningsNotFound.Add(criteria); Summary.WriteWarning(this, warningString); } } else { price = matchCriteria.Value * ((matchCriteria.PricingStyle == PricingStyleType.perKg) ? ind.Weight : 1.0); } } return(price); }
/// <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); }
/// <inheritdoc/> public override string ModelSummaryInnerClosingTags() { using (StringWriter htmlWriter = new StringWriter()) { if (FormatForParentControl) { if (!(CurrentAncestorList.Count >= 3 && CurrentAncestorList[CurrentAncestorList.Count - 1] == typeof(RuminantInitialCohorts).Name)) { RuminantType rumtype = FindAncestor <RuminantType>(); if (rumtype != null) { var newInd = Ruminant.Create(Sex, rumtype, Age); string normWtString = newInd.NormalisedAnimalWeight.ToString("#,##0"); if (this.Weight != 0 && Math.Abs(this.Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { normWtString = "<span class=\"errorlink\">" + normWtString + "</span>"; (this.Parent as RuminantInitialCohorts).WeightWarningOccurred = true; } string weightstring = ""; if (this.Weight > 0) { weightstring = $"<span class=\"setvalue\">{this.Weight.ToString() + ((this.WeightSD > 0) ? " (" + this.WeightSD.ToString() + ")" : "")}</span>"; } htmlWriter.Write($"\r\n<tr{(this.Enabled ? "" : " class=\"disabled\"")}><td>{this.Name}</td><td><span class=\"setvalue\">{this.Sex}</span></td><td><span class=\"setvalue\">{this.Age.ToString()}</span></td><td>{weightstring}</td><td>{normWtString}</td><td><span class=\"setvalue\">{this.Number.ToString()}</span></td><td{((this.Suckling) ? " class=\"fill\"" : "")}></td><td{((this.Sire) ? " class=\"fill\"" : "")}></td>"); if ((Parent as RuminantInitialCohorts).ConceptionsFound) { var setConceptionFound = this.FindChild <SetPreviousConception>(); if (setConceptionFound != null) { htmlWriter.Write($"<td class=\"fill\"><span class=\"setvalue\">{setConceptionFound.NumberMonthsPregnant}</span> mths</td>"); } else { htmlWriter.Write("<td></td>"); } } if ((Parent as RuminantInitialCohorts).AttributesFound) { var setAttributesFound = this.FindAllChildren <SetAttributeWithValue>(); if (setAttributesFound.Any()) { htmlWriter.Write($"<td class=\"fill\">"); foreach (var attribute in setAttributesFound) { htmlWriter.Write($"<span class=\"setvalue\">{attribute.AttributeName}</span> "); } htmlWriter.Write($"</td>"); } else { htmlWriter.Write("<td></td>"); } } htmlWriter.Write("</tr>"); } } } else { htmlWriter.Write("\r\n</div>"); } return(htmlWriter.ToString()); } }
/// <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); }
/// <inheritdoc/> public override string ModelSummary() { RuminantType rumType; bool specifyRuminantParent = false; using (StringWriter htmlWriter = new StringWriter()) { if (!FormatForParentControl) { rumType = FindAncestor <RuminantType>(); if (rumType is null) { // look for rum type in SpecifyRuminant var specParent = this.FindAllAncestors <SpecifyRuminant>().FirstOrDefault(); if (specParent != null) { var resHolder = this.FindAncestor <ZoneCLEM>().FindDescendant <ResourcesHolder>(); rumType = resHolder.FindResourceType <RuminantHerd, RuminantType>(this, specParent.RuminantTypeName, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore); specifyRuminantParent = true; } } htmlWriter.Write("\r\n<div class=\"activityentry\">"); if (!specifyRuminantParent & Number <= 0) { htmlWriter.Write("<span class=\"errorlink\">" + Number.ToString() + "</span> x "); } else if (!specifyRuminantParent & Number > 1) { htmlWriter.Write("<span class=\"setvalue\">" + Number.ToString() + "</span> x "); } else { htmlWriter.Write("A "); } htmlWriter.Write($"<span class=\"setvalue\">{Age}</span> month old "); htmlWriter.Write("<span class=\"setvalue\">" + Sex.ToString() + "</span></div>"); if (Suckling) { htmlWriter.Write("\r\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals are suckling" : "This individual is a suckling") + "</div>"); } if (Sire) { htmlWriter.Write("\r\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals are breeding sires" : "This individual is a breeding sire") + "</div>"); } Ruminant newInd = null; string normWtString = "Unavailable"; if (rumType != null) { newInd = Ruminant.Create(Sex, rumType, Age); normWtString = newInd.NormalisedAnimalWeight.ToString("#,##0"); } if (WeightSD > 0) { htmlWriter.Write("\r\n<div class=\"activityentry\">Individuals will be randomly assigned a weight based on a mean " + ((Weight == 0) ? "(using the normalised weight) " : "") + "of <span class=\"setvalue\">" + Weight.ToString("#,##0") + "</span> kg with a standard deviation of <span class=\"setvalue\">" + WeightSD.ToString() + "</span></div>"); if (newInd != null && Math.Abs(Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { htmlWriter.Write("<div class=\"activityentry\">These individuals should weigh close to the normalised weight of <span class=\"errorlink\">" + normWtString + "</span> kg for their age</div>"); } } else { htmlWriter.Write("\r\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals " : "This individual ") + "weigh" + ((Number > 1) ? "" : "s") + ((Weight == 0) ? " the normalised weight of " : "") + " <span class=\"setvalue\">" + Weight.ToString("#,##0") + "</span> kg"); if (newInd != null && Math.Abs(Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { htmlWriter.Write(", but should weigh close to the normalised weight of <span class=\"errorlink\">" + normWtString + "</span> kg for their age"); } htmlWriter.Write("</div>"); } } else { if (this.Parent is CLEMActivityBase | this.Parent is SpecifyRuminant) { bool parentIsSpecify = (Parent is SpecifyRuminant); // when formatted for parent control. i.e. child fo trade htmlWriter.Write("\r\n<div class=\"resourcebanneralone clearfix\">"); if (!parentIsSpecify) { htmlWriter.Write("Buy "); if (Number > 0) { htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write(Number.ToString()); } else { htmlWriter.Write("<span class=\"errorlink\">"); htmlWriter.Write("NOT SET"); } htmlWriter.Write("</span> x "); } if (Age > 0) { htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write(Age.ToString()); } else { htmlWriter.Write("<span class=\"errorlink\">"); htmlWriter.Write("NOT SET"); } htmlWriter.Write("</span> month old "); htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write(Sex.ToString() + ((Number > 1 | parentIsSpecify) ? "s" : "")); htmlWriter.Write("</span> weighing "); if (Weight > 0) { htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write(Weight.ToString()); htmlWriter.Write("</span> kg "); if (WeightSD > 0) { htmlWriter.Write("with a standard deviation of <span class=\"setvalue\">"); htmlWriter.Write(WeightSD.ToString()); htmlWriter.Write("</span>"); } } else { htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write("Normalised weight"); htmlWriter.Write("</span>"); } if (Sire || Suckling) { htmlWriter.Write(" and "); htmlWriter.Write(Sire ? "<span class=\"setvalue\">Sires</span>" : ""); if (Suckling) { htmlWriter.Write($"<span class=\"{(Sire ? "errorlink":"setvalue")}\">Suckling</span>"); } } htmlWriter.Write("\r\n</div>"); } } return(htmlWriter.ToString()); } }
/// <summary> /// Get value of a specific individual with special requirements check (e.g. breeding sire or draught purchase) /// </summary> /// <returns>value</returns> public AnimalPriceGroup GetPriceGroupOfIndividual(Ruminant ind, PurchaseOrSalePricingStyleType purchaseStyle, string property, string value, string warningMessage = "") { double price = 0; if (PricingAvailable()) { AnimalPriceGroup animalPrice = (purchaseStyle == PurchaseOrSalePricingStyleType.Purchase) ? ind.CurrentPriceGroups.Buy : ind.CurrentPriceGroups.Sell; if (animalPrice == null || !animalPrice.Filter(ind)) { string criteria = property.ToUpper() + ":" + value.ToUpper(); //find first pricing entry matching specific criteria AnimalPriceGroup matchIndividual = null; AnimalPriceGroup matchCriteria = null; var priceGroups = PriceList.FindAllChildren <AnimalPriceGroup>() .Where(a => a.PurchaseOrSale == purchaseStyle || a.PurchaseOrSale == PurchaseOrSalePricingStyleType.Both); foreach (AnimalPriceGroup priceGroup in priceGroups) { if (priceGroup.Filter(ind) && matchIndividual == null) { matchIndividual = priceGroup; } var suitableFilters = priceGroup.FindAllChildren <FilterByProperty>() .Where(a => (a.PropertyOfIndividual == property) & ( (a.Operator == System.Linq.Expressions.ExpressionType.Equal && a.Value.ToString().ToUpper() == value.ToUpper()) | (a.Operator == System.Linq.Expressions.ExpressionType.NotEqual && a.Value.ToString().ToUpper() != value.ToUpper()) | (a.Operator == System.Linq.Expressions.ExpressionType.IsTrue && value.ToUpper() == "TRUE") | (a.Operator == System.Linq.Expressions.ExpressionType.IsFalse && value.ToUpper() == "FALSE") ) ).Any(); // check that pricing item meets the specified criteria. if (suitableFilters) { if (matchCriteria == null) { matchCriteria = priceGroup; } else // multiple price entries were found. using first. value = xxx. if (!warningsMultipleEntry.Contains(criteria)) { warningsMultipleEntry.Add(criteria); Summary.WriteMessage(this, "Multiple specific [" + purchaseStyle.ToString() + "] price entries were found for [r=" + ind.Breed + "] where [" + property + "]" + (value.ToUpper() != "TRUE" ? " = [" + value + "]." : ".") + "\r\nOnly the first entry will be used. Price [" + matchCriteria.Value.ToString("#,##0.##") + "] [" + matchCriteria.PricingStyle.ToString() + "].", MessageType.Warning); } } } if (matchCriteria == null) { string warningString = warningMessage; if (warningString != "") { // no warning string passed to method so calculate one // report specific criteria not found in price list warningString = "No [" + purchaseStyle.ToString() + "] price entry was found for [r=" + ind.Breed + "] meeting the required criteria [" + property + "]" + (value.ToUpper() != "TRUE" ? " = [" + value + "]." : "."); if (matchIndividual != null) { // add using the best pricing available for [][] purchases of xx per head warningString += "\r\nThe best available price [" + matchIndividual.Value.ToString("#,##0.##") + "] [" + matchIndividual.PricingStyle.ToString() + "] will be used."; price = matchIndividual.Value * ((matchIndividual.PricingStyle == PricingStyleType.perKg) ? ind.Weight : 1.0); } else { warningString += "\r\nNo alternate price for individuals could be found for the individuals. Add a new [r=AnimalPriceGroup] entry in the [r=AnimalPricing] for [" + ind.Breed + "]"; } } if (!warningsNotFound.Contains(criteria)) { warningsNotFound.Add(criteria); Summary.WriteMessage(this, warningString, MessageType.Warning); } } if (purchaseStyle == PurchaseOrSalePricingStyleType.Purchase) { ind.CurrentPriceGroups = (matchCriteria, ind.CurrentPriceGroups.Sell); return(matchCriteria); } else { ind.CurrentPriceGroups = (ind.CurrentPriceGroups.Buy, matchCriteria); return(matchCriteria); } } } return(null); }
/// <summary> /// Remove individual/cohort from the herd /// </summary> /// <param name="ind">Individual Ruminant to remove</param> /// <param name="model">Model removing individual</param> public void RemoveRuminant(Ruminant ind, IModel model) { // Remove mother ID from any suckling offspring if (ind is RuminantFemale) { string reason; switch (ind.SaleFlag) { case HerdChangeReason.Consumed: case HerdChangeReason.DiedUnderweight: case HerdChangeReason.DiedMortality: reason = "MotherDied"; break; case HerdChangeReason.MarkedSale: case HerdChangeReason.TradeSale: case HerdChangeReason.ExcessBreederSale: case HerdChangeReason.MaxAgeSale: reason = "MotherSold"; break; default: reason = "Unknown"; break; } while ((ind as RuminantFemale).SucklingOffspringList.Any()) { Ruminant offspring = (ind as RuminantFemale).SucklingOffspringList.FirstOrDefault(); offspring.Wean(true, reason); offspring.Mother = null; } } // if sold and unweaned set mothers weaning count + 1 as effectively weaned in process and not death if (!ind.Weaned & !ind.SaleFlag.ToString().Contains("Died")) { if (ind.Mother != null) { ind.Mother.NumberOfWeaned++; } } Herd.Remove(ind); LastIndividualChanged = ind; // report transaction of herd change ResourceTransaction details = new ResourceTransaction { TransactionType = TransactionType.Loss, Amount = 1, Activity = model as CLEMModel, Category = ind.SaleFlag.ToString(), ResourceType = ind.BreedParams, RelatesToResource = ind.BreedParams.NameWithParent, ExtraInformation = ind }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); // report female breeding stats if needed if (ind.Sex == Sex.Female & ind.Age >= ind.BreedParams.MinimumAge1stMating) { RuminantReportItemEventArgs args = new RuminantReportItemEventArgs { RumObj = ind, Category = "breeding stats" }; OnFinalFemaleOccurred(args); } // remove change flag ind.SaleFlag = HerdChangeReason.None; }
/// <summary> /// Provides the description of the model settings for summary (GetFullSummary) /// </summary> /// <param name="formatForParentControl">Use full verbose description</param> /// <returns></returns> public override string ModelSummary(bool formatForParentControl) { RuminantType rumType; using (StringWriter htmlWriter = new StringWriter()) { if (!formatForParentControl) { rumType = FindAncestor <RuminantType>(); htmlWriter.Write("\r\n<div class=\"activityentry\">"); if (Number <= 0) { htmlWriter.Write("<span class=\"errorlink\">" + Number.ToString() + "</span> x "); } else if (Number > 1) { htmlWriter.Write("<span class=\"setvalue\">" + Number.ToString() + "</span> x "); } else { htmlWriter.Write("A "); } htmlWriter.Write($"<span class=\"setvalue\">{Age}</span> month old "); htmlWriter.Write("<span class=\"setvalue\">" + Gender.ToString() + "</span></div>"); if (Suckling) { htmlWriter.Write("\r\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals are suckling" : "This individual is a suckling") + "</div>"); } if (Sire) { htmlWriter.Write("\r\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals are breeding sires" : "This individual is a breeding sire") + "</div>"); } Ruminant newInd = null; string normWtString = "Unavailable"; if (rumType != null) { newInd = new Ruminant(this.Age, this.Gender, 0, rumType); normWtString = newInd.NormalisedAnimalWeight.ToString("#,##0"); } if (WeightSD > 0) { htmlWriter.Write("\r\n<div class=\"activityentry\">Individuals will be randomly assigned a weight based on a mean " + ((Weight == 0) ? "(using the normalised weight) " : "") + "of <span class=\"setvalue\">" + Weight.ToString("#,##0") + "</span> kg with a standard deviation of <span class=\"setvalue\">" + WeightSD.ToString() + "</span></div>"); if (newInd != null && Math.Abs(Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { htmlWriter.Write("<div class=\"activityentry\">These individuals should weigh close to the normalised weight of <span class=\"errorlink\">" + normWtString + "</span> kg for their age</div>"); } } else { htmlWriter.Write("\r\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals " : "This individual ") + "weigh" + ((Number > 1) ? "" : "s") + ((Weight == 0) ? " the normalised weight of " : "") + " <span class=\"setvalue\">" + Weight.ToString("#,##0") + "</span> kg"); if (newInd != null && Math.Abs(Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { htmlWriter.Write(", but should weigh close to the normalised weight of <span class=\"errorlink\">" + normWtString + "</span> kg for their age"); } htmlWriter.Write("</div>"); } htmlWriter.Write("</div>"); } else { if (this.Parent is CLEMActivityBase | this.Parent is SpecifyRuminant) { bool parentIsSpecify = (Parent is SpecifyRuminant); // when formatted for parent control. i.e. child fo trade htmlWriter.Write("\r\n<div class=\"resourcebanneralone clearfix\">"); if (!parentIsSpecify) { htmlWriter.Write("Buy "); if (Number > 0) { htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write(Number.ToString()); } else { htmlWriter.Write("<span class=\"errorlink\">"); htmlWriter.Write("NOT SET"); } htmlWriter.Write("</span> x "); } if (Age > 0) { htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write(Age.ToString()); } else { htmlWriter.Write("<span class=\"errorlink\">"); htmlWriter.Write("NOT SET"); } htmlWriter.Write("</span> month old "); htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write(Gender.ToString() + ((Number > 1 | parentIsSpecify) ? "s" : "")); htmlWriter.Write("</span> weighing "); if (Weight > 0) { htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write(Weight.ToString()); htmlWriter.Write("</span> kg "); if (WeightSD > 0) { htmlWriter.Write("with a standard deviation of <span class=\"setvalue\">"); htmlWriter.Write(WeightSD.ToString()); htmlWriter.Write("</span>"); } } else { htmlWriter.Write("<span class=\"setvalue\">"); htmlWriter.Write("Normalised weight"); htmlWriter.Write("</span>"); } if (Sire || Suckling) { htmlWriter.Write(" and "); htmlWriter.Write(Sire ? "<span class=\"setvalue\">Sires</span>" : ""); if (Suckling) { htmlWriter.Write($"<span class=\"{(Sire ? "errorlink":"setvalue")}\">Suckling</span>"); } } htmlWriter.Write("\r\n</div>"); } } return(htmlWriter.ToString()); } }
/// <summary> /// Provides the description of the model settings for summary (GetFullSummary) /// </summary> /// <param name="formatForParentControl">Use full verbose description</param> /// <returns></returns> public override string ModelSummary(bool formatForParentControl) { string html = ""; if (!formatForParentControl) { html += "\n<div class=\"activityentry\">"; if (Number <= 0) { html += "<span class=\"errorlink\">" + Number.ToString() + "</span> x "; } else if (Number > 1) { html += "<span class=\"setvalue\">" + Number.ToString() + "</span> x "; } else { html += "A "; } html += "<span class=\"setvalue\">"; html += Age.ToString("0") + "</span> month old "; html += "<span class=\"setvalue\">" + Gender.ToString() + "</span></div>"; if (Suckling) { html += "\n<div class=\"activityentry\">" + ((Number > 1)?"These individuals are suckling":"This individual is a suckling") + "</div>"; } if (Sire) { html += "\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals are breeding sires" : "This individual is a breeding sire") + "</div>"; } RuminantType rumtype = FindAncestor <RuminantType>(); Ruminant newInd = null; string normWtString = "Unavailable"; if (rumtype != null) { newInd = new Ruminant(this.Age, this.Gender, 0, FindAncestor <RuminantType>()); normWtString = newInd.NormalisedAnimalWeight.ToString("#,##0"); } if (WeightSD > 0) { html += "\n<div class=\"activityentry\">Individuals will be randomally assigned a weight based on a mean " + ((Weight == 0) ? "(using the normalised weight) " : "") + "of <span class=\"setvalue\">" + Weight.ToString("#,##0") + "</span> kg with a standard deviation of <span class=\"setvalue\">" + WeightSD.ToString() + "</span></div>"; if (newInd != null && Math.Abs(Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { html += "<div class=\"activityentry\">These individuals should weigh close to the normalised weight of <span class=\"errorlink\">" + normWtString + "</span> kg for their age</div>"; } } else { html += "\n<div class=\"activityentry\">" + ((Number > 1) ? "These individuals " : "This individual ") + "weigh" + ((Number > 1) ? "" : "s") + ((Weight == 0)?" the normalised weight of ":"") + " <span class=\"setvalue\">" + Weight.ToString("#,##0") + "</span> kg"; if (newInd != null && Math.Abs(Weight - newInd.NormalisedAnimalWeight) / newInd.NormalisedAnimalWeight > 0.2) { html += ", but should weigh close to the normalised weight of <span class=\"errorlink\">" + normWtString + "</span> kg for their age"; } html += "</div>"; } html += "</div>"; } else { if (this.Parent is CLEMActivityBase) { // when formatted for parent control. i.e. child fo trade html += "\n<div class=\"resourcebanneralone clearfix\">"; html += "Buy "; if (Number > 0) { html += "<span class=\"setvalue\">"; html += Number.ToString(); } else { html += "<span class=\"errorlink\">"; html += "NOT SET"; } html += "</span> x "; if (Age > 0) { html += "<span class=\"setvalue\">"; html += Number.ToString(); } else { html += "<span class=\"errorlink\">"; html += "NOT SET"; } html += "</span> month old "; html += "<span class=\"setvalue\">"; html += Gender.ToString() + ((Number > 1) ? "s" : ""); html += "</span> weighing "; if (Weight > 0) { html += "<span class=\"setvalue\">"; html += Weight.ToString(); html += "</span> kg "; if (WeightSD > 0) { html += "with a standard deviation of <span class=\"setvalue\">"; html += WeightSD.ToString(); html += "</span>"; } } else { html += "<span class=\"setvalue\">"; html += "Normalised weight"; html += "</span>"; } html += "\n</div>"; } } return(html); }
/// <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); }