/// <summary> /// Default fleece weight as a function of age, sex and time since shearing /// </summary> /// <param name="Params"></param> /// <param name="iAgeDays"></param> /// <param name="Repr"></param> /// <param name="iFleeceDays"></param> /// <returns></returns> public static double fDefaultFleece(TAnimalParamSet Params, int iAgeDays, GrazType.ReproType Repr, int iFleeceDays) { double Result; double fMeanAgeFactor; iFleeceDays = Math.Min(iFleeceDays, iAgeDays); if ((Params.Animal == GrazType.AnimalType.Sheep) && (iFleeceDays > 0)) { fMeanAgeFactor = 1.0 - (1.0 - Params.WoolC[5]) * (Math.Exp(-Params.WoolC[12] * (iAgeDays - iFleeceDays)) - Math.Exp(-Params.WoolC[12] * iAgeDays)) / (Params.WoolC[12] * iFleeceDays); Result = Params.FleeceRatio * Params.fSexStdRefWt(Repr) * fMeanAgeFactor * iFleeceDays / 365.0; } else Result = 0.0; return Result; }
/// <summary> /// Default fibre diameter as a function of age, sex, time since shearing and fleece weight /// </summary> /// <param name="Params"></param> /// <param name="iAgeDays"></param> /// <param name="Repr"></param> /// <param name="iFleeceDays"></param> /// <param name="fGFW"></param> /// <returns></returns> public static double fDefaultMicron(TAnimalParamSet Params, int iAgeDays, GrazType.ReproType Repr, int iFleeceDays, double fGFW) { double fPotFleece; if ((iFleeceDays > 0) && (fGFW > 0.0)) { fPotFleece = fDefaultFleece(Params, iAgeDays, Repr, iFleeceDays); return Params.MaxMicrons * Math.Pow(fGFW / fPotFleece, Params.WoolC[13]); } else return Params.MaxMicrons; }
/// <summary> /// Set the LegumePropn, SelectFactor and TropLegume fields of a TGrazingInputs /// * Expects that the TotalGreen and TotalDead fields have already been computed /// </summary> /// <param name="GI"></param> public void populateHerbageType(ref GrazType.TGrazingInputs GI) { if (GI.TotalGreen + GI.TotalDead > 0.0) { GI.LegumePropn = FLegumeMass / (GI.TotalGreen + GI.TotalDead); GI.SelectFactor = 0.16 * this.FC4GrassMass / (GI.TotalGreen + GI.TotalDead); GI.LegumeTrop = 0.0; // FIX ME } else { GI.LegumePropn = 0.0; GI.SelectFactor = 0.0; GI.LegumeTrop = 0.0; } }
/// <summary> /// /// </summary> /// <param name="forageInputs"></param> public void setAvailForage(GrazType.TGrazingInputs forageInputs) { FUseForageData = true; FForageData.CopyFrom(forageInputs); }
/// <summary> /// Convert the dry matter pool /// </summary> /// <param name="Pool"></param> /// <param name="aValue"></param> /// <param name="bNPSVal"></param> public static void DMPool2Value(GrazType.DM_Pool Pool, TDMPoolHead aValue, bool bNPSVal = false) { if (!bNPSVal) { aValue.weight = Pool.DM; // Item[1] = "weight" kg/head aValue.n = Pool.Nu[(int)GrazType.TOMElement.N]; // Item[2] = "n" kg/head aValue.p = Pool.Nu[(int)GrazType.TOMElement.P]; // Item[3] = "p" kg/head aValue.s = Pool.Nu[(int)GrazType.TOMElement.S]; // Item[4] = "s" kg/head aValue.ash_alk = Pool.AshAlk; // Item[5] = "ash_alk" mol/head } else { aValue.n = Pool.Nu[(int)GrazType.TOMElement.N]; // Item[1] = "n" kg/head aValue.p = Pool.Nu[(int)GrazType.TOMElement.P]; // Item[2] = "p" kg/head aValue.s = Pool.Nu[(int)GrazType.TOMElement.S]; // Item[3] = "s" kg/head } }
/// <summary> /// /// </summary> /// <param name="GI"></param> /// <param name="dAvailPropn"></param> /// <param name="iDDM"></param> /// <param name="iIDM"></param> public void populateSeedRecord(ref GrazType.TGrazingInputs GI, double dAvailPropn, int iDDM, int iIDM) { double dTotalDM; double dMeanDMD; dTotalDM = FChemData[iDDM].dMass_KgHa + FChemData[iIDM].dMass_KgHa; dMeanDMD = FChemData[iDDM].dMass_KgHa / dTotalDM; GI.Seeds[1, FSeedType].Biomass = dAvailPropn * dTotalDM; GI.Seeds[1, FSeedType].Digestibility = dMeanDMD; GI.Seeds[1, FSeedType].Degradability = Math.Min(0.90, dMeanDMD + 0.10); if (GI.Seeds[1, FSeedType].Biomass > 0.0) { GI.Seeds[1, FSeedType].CrudeProtein = (FChemData[iDDM].dNitrogen_KgHa + FChemData[iIDM].dNitrogen_KgHa) / dTotalDM * GrazType.N2Protein; GI.Seeds[1, FSeedType].PhosContent = (FChemData[iDDM].dPhosphorus_KgHa + FChemData[iIDM].dPhosphorus_KgHa) / dTotalDM; GI.Seeds[1, FSeedType].SulfContent = (FChemData[iDDM].dSulphur_KgHa + FChemData[iIDM].dSulphur_KgHa) / dTotalDM; GI.Seeds[1, FSeedType].AshAlkalinity = (FChemData[iDDM].dAshAlk_MolHa + FChemData[iIDM].dAshAlk_MolHa) / dTotalDM; } GI.Seeds[1, FSeedType].HeightRatio = 0.0; }
/// <summary> /// /// </summary> /// <param name="forage"></param> /// <param name="Grazing"></param> /// <param name="sUnit"></param> public void passGrazingInputs(TForageInfo forage, GrazType.TGrazingInputs Grazing, string sUnit) { double fScale; if (sUnit == "kg/ha") // Convert to kg/ha fScale = 1.0; else if (sUnit == "g/m^2") fScale = 10.0; else throw new Exception("Stock: Unit (" + sUnit + ") not recognised"); if (forage != null) forage.setAvailForage(GrazType.scaleGrazingInputs(Grazing, fScale)); else throw new Exception("Stock: Forage not recognised"); }
/// <summary> /// Returns the number of breeds of a given animal type /// </summary> /// <param name="aAnimal"></param> /// <returns></returns> public int iBreedCount(GrazType.AnimalType aAnimal) { TAnimalParamSet breedSet; int Idx; int result = 0; for (Idx = 0; Idx <= iLeafCount(true) - 1; Idx++) // Current locale only { breedSet = (TAnimalParamSet)getLeaf(Idx, true); if (breedSet.Animal == aAnimal) result++; } return result; }
/// <summary> /// Converts a keyword to a ReproType. Allows plurals in the keyword. /// N.B. The routine is animal-insensitive, i.e. if 'COW' is passed in, /// Empty will be returned regardless of whether sheep or cattle are /// under consideration /// </summary> /// <param name="Keyword"></param> /// <param name="repro"></param> /// <returns></returns> private bool ParseRepro(string Keyword, ref GrazType.ReproType repro) { ReproRecord[] SexKeywords = new ReproRecord[8] { new ReproRecord( name : "ram", repro : GrazType.ReproType.Male ), new ReproRecord( name : "crypto", repro : GrazType.ReproType.Male ), new ReproRecord( name : "wether", repro : GrazType.ReproType.Castrated ), new ReproRecord( name : "ewe", repro : GrazType.ReproType.Empty ), new ReproRecord( name : "bull", repro : GrazType.ReproType.Male ), new ReproRecord( name : "steer", repro : GrazType.ReproType.Castrated ), new ReproRecord( name : "heifer", repro : GrazType.ReproType.Empty ), new ReproRecord( name : "cow", repro : GrazType.ReproType.Empty ) }; int Idx; bool result = true; Keyword = Keyword.ToLower().Trim(); if ((Keyword != "") && (Keyword[Keyword.Length - 1] == 's')) // Plurals are allowed Keyword = Keyword.Substring(0, Keyword.Length - 1); Idx = 0; while ((Idx <= 7) && (Keyword != SexKeywords[Idx].Name)) Idx++; if (Idx <= 7) repro = SexKeywords[Idx].Repro; else repro = GrazType.ReproType.Castrated; if ((Idx > 7) && (Keyword.Length > 0)) result = false; return result; }
public ReproRecord(string name, GrazType.ReproType repro) { Name = name; Repro = repro; }
/// <summary> /// MultiplyDMPool scales the contents of a pool /// </summary> /// <param name="Src"></param> /// <param name="X"></param> /// <returns></returns> protected GrazType.DM_Pool MultiplyDMPool(GrazType.DM_Pool Src, double X) { int N = (int)GrazType.TOMElement.N; int P = (int)GrazType.TOMElement.P; int S = (int)GrazType.TOMElement.S; GrazType.DM_Pool Result = new GrazType.DM_Pool(); Result.DM = Src.DM * X; Result.Nu[N] = Src.Nu[N] * X; Result.Nu[P] = Src.Nu[P] * X; Result.Nu[S] = Src.Nu[S] * X; Result.AshAlk = Src.AshAlk * X; return Result; }
/// <summary> /// Utility routines for manipulating the DM_Pool type. AddDMPool adds the /// contents of two pools together /// </summary> /// <param name="Pool1"></param> /// <param name="Pool2"></param> /// <returns></returns> protected GrazType.DM_Pool AddDMPool(GrazType.DM_Pool Pool1, GrazType.DM_Pool Pool2) { int N = (int)GrazType.TOMElement.N; int P = (int)GrazType.TOMElement.P; int S = (int)GrazType.TOMElement.S; GrazType.DM_Pool Result = new GrazType.DM_Pool(); Result.DM = Pool1.DM + Pool2.DM; Result.Nu[N] = Pool1.Nu[N] + Pool2.Nu[N]; Result.Nu[P] = Pool1.Nu[P] + Pool2.Nu[P]; Result.Nu[S] = Pool1.Nu[S] + Pool2.Nu[S]; Result.AshAlk = Pool1.AshAlk + Pool2.AshAlk; return Result; }
/// <summary> /// Calculate the growth from the standard growth curve /// </summary> /// <param name="iAgeDays"></param> /// <param name="Repr"></param> /// <param name="Params"></param> /// <returns></returns> public double GrowthCurve(int iAgeDays, GrazType.ReproType Repr, TAnimalParamSet Params) { double SRW; SRW = Params.BreedSRW; if ((Repr == GrazType.ReproType.Male) || (Repr == GrazType.ReproType.Castrated)) SRW = SRW * Params.SRWScalars[(int)Repr]; return MaxNormWtFunc(SRW, Params.StdBirthWt(1), iAgeDays, Params); }
/// <summary> /// Standard reference weight /// </summary> /// <param name="Repro"></param> /// <returns></returns> public double fSexStdRefWt(GrazType.ReproType Repro) { if ((Repro == GrazType.ReproType.Castrated) || (Repro == GrazType.ReproType.Male)) return SRWScalars[(int)Repro] * BreedSRW; else return BreedSRW; }
/// <summary> /// /// </summary> /// <param name="aValue"></param> /// <param name="Intake"></param> private void Value2IntakeRecord(TTypedValue aValue, ref GrazType.IntakeRecord Intake) { Intake.Biomass = aValue.item(1).asDouble(); // Item[1]="dm" Intake.Digestibility = aValue.item(2).asDouble(); // Item[2]="dmd" Intake.CrudeProtein = aValue.item(3).asDouble(); // Item[3]="cp_conc" Intake.PhosContent = aValue.item(4).asDouble(); // Item[4]="p_conc" Intake.SulfContent = aValue.item(5).asDouble(); // Item[5]="s_conc" Intake.Degradability = aValue.item(6).asDouble(); // Item[6]="prot_dg" Intake.AshAlkalinity = aValue.item(7).asDouble(); // Item[7]="ashalk" Intake.HeightRatio = aValue.item(8).asDouble(); // Item[8]="height_ratio" }
/// <summary> /// Populates a string list with the names of "breed groups", i.e. sets of /// parameter sets that are identical in all respects save their names. /// </summary> /// <param name="aAnimal"></param> /// <param name="aList"></param> public void getBreedGroups(GrazType.AnimalType aAnimal, List<string> aList) { bool bSameFound; int Idx, Jdx; aList.Clear(); // Start by forming a list of all breeds. for (Idx = 0; Idx <= iBreedCount(aAnimal) - 1; Idx++) aList.Add(sBreedName(aAnimal, Idx)); for (Idx = aList.Count - 1; Idx >= 1; Idx--) { bSameFound = false; for (Jdx = Idx - 1; Jdx >= 0; Jdx--) if (!bSameFound) { bSameFound = Match(aList[Idx]).bFunctionallySame(Match(aList[Jdx])); if (bSameFound) { aList[Jdx] = aList[Jdx] + ", " + aList[Idx]; aList.RemoveAt(Idx); } } } }
/// <summary> /// /// </summary> /// <param name="IR"></param> /// <param name="iDMD"></param> /// <param name="bUseMeanDMD"></param> /// <param name="dTotalMass"></param> /// <param name="dMeanDMD"></param> /// <param name="dMassFract"></param> /// <param name="dDDM_N"></param> /// <param name="dIDM_N"></param> /// <param name="dDDM_P"></param> /// <param name="dIDM_P"></param> /// <param name="dDDM_S"></param> /// <param name="dIDM_S"></param> /// <param name="dDDM_AA"></param> /// <param name="dIDM_AA"></param> /// <param name="dBulkDensity"></param> public void populateIntakeRecord(ref GrazType.IntakeRecord IR, int iDMD, bool bUseMeanDMD, double dTotalMass, double dMeanDMD, double dMassFract, double dDDM_N, double dIDM_N, double dDDM_P, double dIDM_P, double dDDM_S, double dIDM_S, double dDDM_AA, double dIDM_AA, double dBulkDensity) { double dDDMPropn; double dIDMPropn; if (bUseMeanDMD) IR.Digestibility = dMeanDMD; else IR.Digestibility = GrazType.ClassDig[iDMD]; if (dMassFract > 0.0) { dDDMPropn = dMassFract * (IR.Digestibility / dMeanDMD); if ((1.0 - dMeanDMD) != 0) dIDMPropn = dMassFract * ((1.0 - IR.Digestibility) / (1.0 - dMeanDMD)); else // trap div/0 dIDMPropn = 0; IR.Biomass = dMassFract * dTotalMass; IR.CrudeProtein = GrazType.N2Protein * (dDDMPropn * dDDM_N + dIDMPropn * dIDM_N) / IR.Biomass; IR.Degradability = Math.Min(0.90, IR.Digestibility + 0.10); IR.PhosContent = (dDDMPropn * dDDM_P + dIDMPropn * dIDM_P) / IR.Biomass; IR.SulfContent = (dDDMPropn * dDDM_S + dIDMPropn * dIDM_S) / IR.Biomass; IR.AshAlkalinity = (dDDMPropn * dDDM_AA + dIDMPropn * dIDM_AA) / IR.Biomass; IR.HeightRatio = GrazType.REF_HERBAGE_BD / dBulkDensity; } }
/// <summary> /// Iterates through breeds of a given animal type and returns the breed name /// </summary> /// <param name="aAnimal"></param> /// <param name="iBreed"></param> /// <returns></returns> public string sBreedName(GrazType.AnimalType aAnimal, int iBreed) { TAnimalParamSet breedSet; int iCount; int iFound; int Idx; iCount = iLeafCount(true); // Current locale only iFound = -1; Idx = 0; breedSet = null; while ((Idx < iCount) && (iFound < iBreed)) { breedSet = (TAnimalParamSet)getLeaf(Idx, true); if (breedSet.Animal == aAnimal) iFound++; Idx++; } if (iFound == iBreed) return breedSet.sName; else return ""; }
/// <summary> /// /// </summary> /// <param name="Model"></param> /// <param name="Animal"></param> /// <param name="aValue"></param> public static void MakeCattleValue(TStockList Model, GrazType.AnimalType Animal, ref TCattleInit[] aValue) { TAnimalGroup aGroup; int iCount; int Idx, Jdx; iCount = 0; for (Idx = 1; Idx <= Model.Count(); Idx++) if (Model.At(Idx).Genotype.Animal == Animal) iCount++; Array.Resize(ref aValue, iCount); Jdx = 0; for (Idx = 1; Idx <= Model.Count(); Idx++) { if (Model.At(Idx).Genotype.Animal == Animal) { aGroup = Model.At(Idx); aValue[Jdx] = new TCattleInit(); aValue[Jdx].genotype = aGroup.Genotype.sName; aValue[Jdx].number = aGroup.NoAnimals; aValue[Jdx].sex = Model.SexString(Idx, false); aValue[Jdx].age = aGroup.AgeDays; aValue[Jdx].weight = aGroup.LiveWeight; aValue[Jdx].max_prev_wt = aGroup.MaxPrevWeight; aValue[Jdx].pregnant = aGroup.Pregnancy; aValue[Jdx].lactating = aGroup.Lactation; /*if (Animal == GrazType.AnimalType.Sheep) { aValue[Jdx].fleece_wt = aGroup.FleeceCutWeight; aValue[Jdx].fibre_diam = aGroup.FibreDiam; aValue[Jdx].no_young = Math.Max(aGroup.NoFoetuses, aGroup.NoOffspring); } else*/ if (Animal == GrazType.AnimalType.Cattle) { aValue[Jdx].no_foetuses = aGroup.NoFoetuses; aValue[Jdx].no_suckling = aGroup.NoOffspring; } if (aGroup.Lactation > 0) aValue[Jdx].birth_cs = aGroup.BirthCondition; if ((aGroup.Pregnancy > 0) || (aGroup.Young != null)) { if (aGroup.MatedTo != null) aValue[Jdx].mated_to = aGroup.MatedTo.sName; else aValue[Jdx].mated_to = ""; } else aValue[Jdx].mated_to = ""; if (aGroup.Young != null) { /*if (Animal == GrazType.AnimalType.Sheep) { aValue[Jdx].lamb_wt = aGroup.Young.LiveWeight; aValue[Jdx].lamb_fleece_wt = aGroup.Young.FleeceCutWeight; } else*/ if (Animal == GrazType.AnimalType.Cattle) aValue[Jdx].calf_wt = aGroup.Young.LiveWeight; aValue[Jdx].paddock = Model.getInPadd(Idx); aValue[Jdx].tag = Model.getTag(Idx); aValue[Jdx].priority = Model.getPriority(Idx); } } Jdx++; } // next animal }