Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating Tillering Configuration #7357

Merged
merged 8 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Models/AgPasture/PastureSpecies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,15 @@ public string[] CultivarNames
/// <param name="budNumber">The number of buds (optional)</param>
/// <param name="rowConfig">The row configuration.</param>
/// <param name="seeds">The number of seeds sown.</param>
/// <param name="tillering">tillering method (-1, 0, 1).</param>
/// <param name="ftn">Fertile Tiller Number.</param>
/// <remarks>
/// For AgPasture species the sow parameters are not used, the command to sow simply enables the plant to grow. This is done
/// by setting the plant status to 'alive'. From this point germination processes takes place and eventually emergence occurs.
/// At emergence, plant DM is set to its default minimum value, allocated according to EmergenceFractions and with
/// optimum N concentration. Plant height and root depth are set to their minimum values.
/// </remarks>
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0)
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0, int tillering = 0, double ftn = 0.0)
{
if (isAlive)
mySummary.WriteMessage(this, " Cannot sow the pasture species \"" + Name + "\", as it is already growing", MessageType.Warning);
Expand Down
4 changes: 3 additions & 1 deletion Models/Core/IPlant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public interface IPlant : IModel
/// <param name="budNumber">The bud number.</param>
/// <param name="rowConfig">The bud number.</param>
/// <param name="seeds">The number of seeds sown (/m2).</param>
void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0);
/// <param name="tillering">tillering method (-1, 0, 1).</param>
/// <param name="ftn">Fertile Tiller Number.</param>
void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0, int tillering = 0, double ftn = 0.0);

/// <summary>Returns true if the crop is ready for harvesting</summary>
bool IsReadyForHarvesting { get; }
Expand Down
3 changes: 1 addition & 2 deletions Models/Functions/Senescence/LightSenescenceFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ virtual protected void OnPlantSowing(object sender, SowingParameters data)
totalLaiEqlbLight = 0;
avgLaiEquilibLight = 0;
laiEqlbLightTodayQ = new Queue<double>();

}

/// <summary>Called when [EndCrop].</summary>
Expand All @@ -54,7 +53,7 @@ private void OnPlantEnding(object sender, EventArgs e)
{
totalLaiEqlbLight = 0;
avgLaiEquilibLight = 0;
laiEqlbLightTodayQ.Clear();
laiEqlbLightTodayQ?.Clear();
}

/// <summary>Gets the value.</summary>
Expand Down
2 changes: 1 addition & 1 deletion Models/Functions/Senescence/WaterSenescenceFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void OnPlantEnding(object sender, EventArgs e)
{
totalLaiEquilibWater = 0.0;
avLaiEquilibWater = 0.0;
laiEquilibWaterQ.Clear();
laiEquilibWaterQ?.Clear();
}

/// <summary>Gets the value.</summary>
Expand Down
4 changes: 3 additions & 1 deletion Models/G_Range/G_Range.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ public IBiomass AboveGround
/// <param name="budNumber">The bud number.</param>
/// <param name="rowConfig">The bud number.</param>
/// <param name="seeds">The number of seeds sown.</param>
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0 ) { }
/// <param name="tillering">tillering method (-1, 0, 1).</param>
/// <param name="ftn">Fertile Tiller Number.</param>
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0, int tillering = 0, double ftn = 0.0) { }

/// <summary>Returns true if the crop is ready for harvesting</summary>
public bool IsReadyForHarvesting { get { return false; } }
Expand Down
6 changes: 6 additions & 0 deletions Models/PMF/Interfaces/ITilleringMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,11 @@ public interface ITilleringMethod : IModel

/// <summary> Calculate the actual Area for the Culms</summary>
double CalcActualLeafArea(double dltStressedLAI);

/// <summary> Fertile tiller Number (at harvest) </summary>
double FertileTillerNumber { get; set; }
/// <summary>Current Number of Tillers</summary>
double CurrentTillerNumber { get; set; }

}
}
4 changes: 3 additions & 1 deletion Models/PMF/OilPalm/OilPalm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -788,8 +788,10 @@ private void OnSimulationCommencing(object sender, EventArgs e)
/// <param name="budNumber">The bud number.</param>
/// <param name="rowConfig">The row configuration.</param>
/// <param name="seeds">The number of seeds sown.</param>
/// <param name="tillering">tillering method (-1, 0, 1).</param>
/// <param name="ftn">Fertile Tiller Number.</param>
/// <exception cref="System.Exception">Cultivar not specified on sow line.</exception>
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0)
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0, int tillering = 0, double ftn = 0.0)
{
SowingData = new SowingParameters();
SowingData.Population = population;
Expand Down
16 changes: 10 additions & 6 deletions Models/PMF/Organs/SorghumLeaf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class SorghumLeaf : Model, IHasWaterDemand, IOrgan, IArbitration, IOrganD
{
/// <summary>The plant</summary>
[Link]
private Plant plant = null; //todo change back to private
private Plant plant = null;

[Link]
private ISummary summary = null;
Expand Down Expand Up @@ -148,9 +148,14 @@ public SorghumLeaf()
/// <summary>Gets the canopy type. Should return null if no canopy present.</summary>
public string CanopyType => plant.PlantType;

/// <summary>Gets or sets the R50.</summary>
[Description("Tillering Method: 0 = Fixed - uses FTN, 1 = Dynamic")]
public int TilleringMethod { get; set; } = 0;
/// <summary>Gets the Tillering Method.</summary>
[Description("Tillering Method: -1 = Rule of Thumb, 0 = FixedTillering - uses FertileTillerNumber, 1 = DynamicTillering")]
public int TilleringMethod { get; set; }

/// <summary>Determined by the tillering method chosen.</summary>
/// <summary>If TilleringMethod == FixedTillering then this value needs to be set by the user.</summary>
[Description("")]
public double FertileTillerNumber { get; set; }

/// <summary>The initial biomass dry matter weight</summary>
[Description("Initial leaf dry matter weight")]
Expand Down Expand Up @@ -959,8 +964,7 @@ private void OnPhaseChanged(object sender, PhaseChangedType phaseChange)
if (phaseChange.StageName == LeafInitialisationStage)
{
leafInitialised = true;
culms.TilleringMethod = TilleringMethod;


Live.StructuralWt = InitialDMWeight * SowingDensity;
Live.StorageWt = 0.0;
LAI = InitialLAI * SowingDensity.ConvertSqM2SqMM();
Expand Down
12 changes: 11 additions & 1 deletion Models/PMF/Plant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,9 @@ private void EndOfDay(object sender, EventArgs e)
/// <param name="budNumber">The bud number.</param>
/// <param name="rowConfig">SkipRow configuration.</param>
/// <param name="seeds">The number of seeds sown (/m2).</param>
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 0, double seeds = 0)
/// <param name="tillering">tillering method (-1, 0, 1).</param>
/// <param name="ftn">Fertile Tiller Number.</param>
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 0, double seeds = 0, int tillering = 0, double ftn = 0.0)
{
SowingDate = clock.Today;

Expand All @@ -360,10 +362,18 @@ public void Sow(string cultivar, double population, double depth, double rowSpac
SowingData.RowSpacing = rowSpacing;
SowingData.SkipType = rowConfig;
SowingData.Seeds = seeds;
SowingData.TilleringMethod = tillering;
SowingData.FTN = ftn;

if (SowingData.Seeds != 0 && SowingData.Population != 0)
throw new Exception("Cannot specify both plant population and number of seeds when sowing.");

if (SowingData.TilleringMethod < -1 || SowingData.TilleringMethod > 1)
throw new Exception("Invalid TilleringMethod set in sowingData.");

if (SowingData.TilleringMethod != 0 && SowingData.FTN > 0.0)
throw new Exception("Cannot set a FertileTillerNumber when TilleringMethod is not set to FixedTillering.");

if (rowConfig == 0)
{
// No skip row
Expand Down
4 changes: 3 additions & 1 deletion Models/PMF/SimpleTree/SimpleTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,9 @@ public void SetActualNitrogenUptakes(List<ZoneWaterAndN> info)
/// <param name="budNumber">The bud number.</param>
/// <param name="rowConfig">The row configuration.</param>
/// <param name="seeds">The number of seeds sown.</param>
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0)
/// <param name="tillering">tillering method (-1, 0, 1).</param>
/// <param name="ftn">Fertile Tiller Number.</param>
public void Sow(string cultivar, double population, double depth, double rowSpacing, double maxCover = 1, double budNumber = 1, double rowConfig = 1, double seeds = 0, int tillering = 0, double ftn = 0.0)
{

}
Expand Down
7 changes: 7 additions & 0 deletions Models/PMF/SowingParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,12 @@ public class SowingParameters : EventArgs

/// <summary>The skip plant seed density adjustment</summary>
public double SkipDensityScale { get; set; } = 1;

/// <summary>Tillering Method to set Fixed or dynamic tillering</summary>
/// <summary>Tillering Method: -1 = Rule of Thumb, 0 = FixedTillering - uses FTN, 1 = DynamicTillering</summary>
public int TilleringMethod { get; set; } = 0;

/// <summary>Fertile Tiller Number</summary>
public double FTN { get; set; } = 0.0;
}
}
32 changes: 26 additions & 6 deletions Models/PMF/Structure/LeafCulms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ namespace Models.PMF.Struct
[PresenterName("UserInterface.Presenters.PropertyPresenter")]
public class LeafCulms : Model
{
/// <summary> Tillering Method that uses a fixed number of tillers</summary>
[Link(Type = LinkType.Child, ByName = true)]
/// <summary>The parent Plant</summary>
[Link]
Plant plant = null;

/// <summary> Tillering Method that uses a fixed number of tillers</summary>
[Link(Type = LinkType.Child, ByName = true)]
private ITilleringMethod fixedTillering = null;

/// <summary> Tillering Method that manages number of tillers dynamically</summary>
Expand Down Expand Up @@ -60,11 +64,14 @@ public class LeafCulms : Model
[Link(Type = LinkType.Child, ByName = true)]
private IFunction leafNoAtEmergence = null;

/// <summary> Enables Tillering method to be controlled via script</summary>
public double TilleringMethod { get; set; }
/// <summary> Set through Sowing Event</summary>
public int TilleringMethod { get; set; }

private ITilleringMethod tillering => TilleringMethod == 0 ? fixedTillering : dynamicTillering;

/// <summary> FertileTillerNumber is determined by the tillering method chosen</summary>
public double FertileTillerNumber { get => tillering.FertileTillerNumber; }

/// <summary> Subsequent tillers are slightly smaller - adjust that size using a percentage</summary>
[Link(Type = LinkType.Child, ByName = true)]
public IFunction VerticalTillerAdjustment = null;
Expand Down Expand Up @@ -92,7 +99,7 @@ public class LeafCulms : Model
public List<Culm> Culms;

/// <summary>Total TT required to get from emergence to floral init.</summary>
[JsonIgnore]
[JsonIgnore]
public double TTTargetFI { get; private set; }

/// <summary> Constructor. </summary>
Expand Down Expand Up @@ -166,5 +173,18 @@ public double getLeafAppearanceRate(double remainingLeaves)
return appearanceRate1.Value();
}

}
/// <summary>Called when crop is sowed</summary>
/// <param name="sender">The sender.</param>
/// <param name="data">The <see cref="EventArgs"/> instance containing the event data.</param>
[EventSubscribe("PlantSowing")]
protected void OnPlantSowing(object sender, SowingParameters data)
{
if (data.Plant == plant)
{
//sets which tillering method to reference via tillering
TilleringMethod = data.TilleringMethod;
}
}

}
}
41 changes: 25 additions & 16 deletions Models/PMF/Structure/Tillering/DynamicTillering.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;

namespace Models.PMF.Struct
{
Expand Down Expand Up @@ -71,17 +72,26 @@ public class DynamicTillering : Model, ITilleringMethod

/// <summary>Number of potential Fertile Tillers at harvest</summary>
public double CalculatedTillerNumber { get; private set; }

/// <summary>Actual Number of Fertile Tillers</summary>
public double FertileTillerNumber { get; private set; }
/// <summary>Current Number of Tillers</summary>
public double CurrentTillerNumber { get; set; }
/// <summary>Current Number of Tillers</summary>
public double DltTillerNumber { get; set; }

/// <summary>Actual Number of Fertile Tillers</summary>
[JsonIgnore]
public double FertileTillerNumber
{
get => CurrentTillerNumber;
set { throw new Exception("Cannot set the FertileTillerNumber for Dynamic Tillering. Make sure you set TilleringMethod before FertileTillerNmber"); }
}

/// <summary>Supply Demand Ratio used to calculate Tiller No</summary>
public double SupplyDemandRatio { get; private set; }

private int flagStage;
private int floweringStage;
private int endJuvenilePhase;
private double tillersAdded;
//private double tillersAdded;
private int startThermalQuotientLeafNo = 3;
private int endThermalQuotientLeafNo = 5;
private double plantsPerMetre;
Expand Down Expand Up @@ -191,7 +201,7 @@ void AddInitialTillers()
if (CalculatedTillerNumber > 3) //initiate T2:2 & T3:1
{
InitiateTiller(2, 1, 2);
tillersAdded = 1; // Reporting.
CurrentTillerNumber = 1; // Reporting.
}

}
Expand All @@ -201,15 +211,15 @@ double calcTillerAppearance(int newLeafNo, int currentLeafNo)
//and the newleaf is greater than 3
// get number of tillers added so far

if (tillersAdded >= FertileTillerNumber) return 0.0;
if (CurrentTillerNumber >= CalculatedTillerNumber) return 0.0;
// calculate linear LAI - plantsPerMeter is calculated at sowing
//tpla is LAI/density - remove x density from plantspermetre calc?
linearLAI = plantsPerMetre * (leaf.LAI + leaf.SenescedLai) / 10000.0;

if (linearLAI < maxLAIForTillerAddition.Value())
{
var appRate = culms.getLeafAppearanceRate(5);
return Math.Min(phenology.thermalTime.Value() / appRate, CalculatedTillerNumber - tillersAdded);
return Math.Min(phenology.thermalTime.Value() / appRate, CalculatedTillerNumber - CurrentTillerNumber);
}
return 0.0;
}
Expand All @@ -226,7 +236,7 @@ void InitiateTiller(int tillerNumber, double fractionToAdd, double initialLeaf)

newCulm.CulmNo = tillerNumber;
newCulm.CurrentLeafNo = initialLeaf;
newCulm.VertAdjValue = culms.MaxVerticalTillerAdjustment.Value() + (tillersAdded * culms.VerticalTillerAdjustment.Value());
newCulm.VertAdjValue = culms.MaxVerticalTillerAdjustment.Value() + (CurrentTillerNumber * culms.VerticalTillerAdjustment.Value());
newCulm.Proportion = fractionToAdd;
newCulm.FinalLeafNo = culms.Culms[0].FinalLeafNo;
//newCulm.calcLeafAppearance();
Expand All @@ -252,8 +262,8 @@ private void AddTillerProportion(double fractionToAdd)
{
InitiateTiller(lastCulm.CulmNo + 1, tillerFraction - 1.0, 1);
}

tillersAdded += fractionToAdd;
DltTillerNumber = fractionToAdd;
CurrentTillerNumber += fractionToAdd;
}

/// <summary> calculate the potential leaf area</summary>
Expand All @@ -279,7 +289,7 @@ public double CalcActualLeafArea(double dltStressedLAI)

var tillerLaiToReduce = calcCeaseTillerSignal(dltStressedLAI - laiReductionForSLA);

bool moreToAdd = (tillersAdded < CalculatedTillerNumber) && (linearLAI < maxLAIForTillerAddition.Value());
bool moreToAdd = (CurrentTillerNumber < CalculatedTillerNumber) && (linearLAI < maxLAIForTillerAddition.Value());
double nLeaves = culms.Culms.First().CurrentLeafNo;

if (nLeaves > 7 && !moreToAdd && tillerLaiToReduce > 0.0)
Expand Down Expand Up @@ -382,14 +392,13 @@ void reduceAllTillersProportionately(double laiReduction)
[EventSubscribe("PlantSowing")]
protected void OnPlantSowing(object sender, SowingParameters data)
{
if (data.Plant == plant)
if (data.Plant == plant && leaf.TilleringMethod == 1)
{
radiationAverages = new List<double>();
plantsPerMetre = data.RowSpacing / 1000.0 * data.SkipDensityScale;
//plantsPerMetre = data.Population * data.RowSpacing / 1000.0 * data.SkipDensityScale;

FertileTillerNumber = data.BudNumber;
tillersAdded = 0.0;
//plantsPerMetre = data.Population * data.RowSpacing / 1000.0 * data.SkipDensityScale;
CurrentTillerNumber = 0.0;
CalculatedTillerNumber = 0.0;
}
}
}
Expand Down
Loading