Skip to content
Snippets Groups Projects
Commit 471dabbf authored by Tor-Einar Skog's avatar Tor-Einar Skog
Browse files

Version 1

parent 2fd678b5
No related branches found
No related tags found
No related merge requests found
...@@ -66,6 +66,16 @@ public class GrassDryingModel extends I18nImpl implements Model{ ...@@ -66,6 +66,16 @@ public class GrassDryingModel extends I18nImpl implements Model{
private Integer conditioning; private Integer conditioning;
private Double stringWidth; private Double stringWidth;
private Double harvestWidth; private Double harvestWidth;
// Either this is set...
private Double initialDryMatterFraction;
// ... or the three values below has to be set for estimates of dry matter fraction
private Integer seasonHarvestNumber; // First, second or [X]th harvest this season?
private Integer cloverFraction;
private Double precipitationLastDayBeforeHarvest;
// Constants for cloverFraction
private final Integer CLOVER_FRACTION_SMALL = 1;
private final Integer CLOVER_FRACTION_LARGE = 2;
public GrassDryingModel() public GrassDryingModel()
{ {
...@@ -92,6 +102,7 @@ public class GrassDryingModel extends I18nImpl implements Model{ ...@@ -92,6 +102,7 @@ public class GrassDryingModel extends I18nImpl implements Model{
Double dryMatter = this.calculateTS( Double dryMatter = this.calculateTS(
this.calculateMCWB( this.calculateMCWB(
this.calculateM( this.calculateM(
this.getMCWBInit(),
this.calculateMe(this.UM.get(i).getValue()), this.calculateMe(this.UM.get(i).getValue()),
sigma_E, sigma_E,
this.calculateR_a(this.stringWidth, this.RR.get(i).getValue()), this.calculateR_a(this.stringWidth, this.RR.get(i).getValue()),
...@@ -167,6 +178,10 @@ public class GrassDryingModel extends I18nImpl implements Model{ ...@@ -167,6 +178,10 @@ public class GrassDryingModel extends I18nImpl implements Model{
"\t\t\"conditioning\":2,\n" + "\t\t\"conditioning\":2,\n" +
"\t\t\"stringWidth\":3.0,\n" + "\t\t\"stringWidth\":3.0,\n" +
"\t\t\"harvestWidth\":3.0,\n" + "\t\t\"harvestWidth\":3.0,\n" +
"\t\t\"initialDryMatterFraction\":17.7,\n" +
"\t\t\"seasonHarvestNumber\":1,\n" +
"\t\t\"cloverFraction\":1,\n" +
"\t\t\"precipitationLastDayBeforeHarvest\":2.453987,\n" +
"\t\t\"observations\":[\n" + "\t\t\"observations\":[\n" +
"\t\t{\n" + "\t\t{\n" +
"\t\t\t\t\"timeMeasured\": \"2014-06-25T00:00:00+02:00\",\n" + "\t\t\t\t\"timeMeasured\": \"2014-06-25T00:00:00+02:00\",\n" +
...@@ -203,6 +218,11 @@ public class GrassDryingModel extends I18nImpl implements Model{ ...@@ -203,6 +218,11 @@ public class GrassDryingModel extends I18nImpl implements Model{
"}\n"; "}\n";
} }
/**
* TODO: Finish validation
* @param config
* @throws ConfigValidationException
*/
@Override @Override
public void setConfiguration(ModelConfiguration config) throws ConfigValidationException { public void setConfiguration(ModelConfiguration config) throws ConfigValidationException {
this.initCollections(); this.initCollections();
...@@ -212,6 +232,29 @@ public class GrassDryingModel extends I18nImpl implements Model{ ...@@ -212,6 +232,29 @@ public class GrassDryingModel extends I18nImpl implements Model{
this.timeZone = TimeZone.getTimeZone((String) config.getConfigParameter("timeZone")); this.timeZone = TimeZone.getTimeZone((String) config.getConfigParameter("timeZone"));
this.yield = (Double) config.getConfigParameter("yield"); this.yield = (Double) config.getConfigParameter("yield");
this.initialDryMatterFraction = (Double) config.getConfigParameter("initialDryMatterFraction");
if(this.initialDryMatterFraction == null || this.initialDryMatterFraction > 100)
{
this.seasonHarvestNumber = (Integer) config.getConfigParameter("seasonHarvestNumber");
if(this.seasonHarvestNumber == null || this.seasonHarvestNumber < 1 || this.seasonHarvestNumber > 2)
{
throw new ConfigValidationException("Acceptable values for seasonHarvestNumber are [1,2]");
}
this.precipitationLastDayBeforeHarvest = (Double) config.getConfigParameter("precipitationLastDayBeforeHarvest");
if(this.precipitationLastDayBeforeHarvest == null)
{
throw new ConfigValidationException("Missing value for precipitation last day before harvest");
}
this.cloverFraction = (Integer) config.getConfigParameter("cloverFraction");
if(
this.cloverFraction == null
|| (!this.cloverFraction.equals(this.CLOVER_FRACTION_SMALL)
&& !this.cloverFraction.equals(this.CLOVER_FRACTION_LARGE))
)
{
throw new ConfigValidationException("Missing or invalid value for clover fraction");
}
}
// 1 = weak, 2 = strong, 3 = crushed // 1 = weak, 2 = strong, 3 = crushed
this.conditioning = (Integer) config.getConfigParameter("conditioning"); this.conditioning = (Integer) config.getConfigParameter("conditioning");
if(!this.conditioning.equals(1) && !this.conditioning.equals(2) && !this.conditioning.equals(3)) if(!this.conditioning.equals(1) && !this.conditioning.equals(2) && !this.conditioning.equals(3))
...@@ -220,7 +263,8 @@ public class GrassDryingModel extends I18nImpl implements Model{ ...@@ -220,7 +263,8 @@ public class GrassDryingModel extends I18nImpl implements Model{
} }
this.stringWidth = (Double) config.getConfigParameter("stringWidth"); this.stringWidth = (Double) config.getConfigParameter("stringWidth");
this.harvestWidth = (Double) config.getConfigParameter("harvestWidth"); this.harvestWidth = (Double) config.getConfigParameter("harvestWidth");
// private Double yield; // Kgs? Tons?? Per hectar?
// ############ Weather data ############## // ############ Weather data ##############
...@@ -343,11 +387,15 @@ public class GrassDryingModel extends I18nImpl implements Model{ ...@@ -343,11 +387,15 @@ public class GrassDryingModel extends I18nImpl implements Model{
return M / (1 + M); return M / (1 + M);
} }
public Double calculateM(Double Me, Double sigma_E, Double R_a, Double Korr_DRC, Double rewet) public Double getMCWBInit() throws ModelExcecutionException
{
return 1.0 - this.getInitialDryMatterFraction() / 100;
}
public Double calculateM(Double MCWBInit, Double Me, Double sigma_E, Double R_a, Double Korr_DRC, Double rewet) throws ModelExcecutionException
{ {
// Constants // Constants
Double MCWBinit = 0.823; Double M_0 = MCWBInit/(1-MCWBInit);
Double M_0 = MCWBinit/(1-MCWBinit);
Double rainWaterEpoFactor = 0.0; Double rainWaterEpoFactor = 0.0;
return (M_0 - Me) * Math.exp(-Korr_DRC * (sigma_E - rainWaterEpoFactor * R_a)) + Me + rewet; return (M_0 - Me) * Math.exp(-Korr_DRC * (sigma_E - rainWaterEpoFactor * R_a)) + Me + rewet;
} }
...@@ -392,4 +440,66 @@ public class GrassDryingModel extends I18nImpl implements Model{ ...@@ -392,4 +440,66 @@ public class GrassDryingModel extends I18nImpl implements Model{
return dryingRateCoefficient * correctionFactor; return dryingRateCoefficient * correctionFactor;
} }
public Double getInitialDryMatterFraction() throws ModelExcecutionException {
if(this.initialDryMatterFraction != null)
{
return this.initialDryMatterFraction;
}
// If not set by user, estimate from other input data
if(this.seasonHarvestNumber == 1)
{
if(this.precipitationLastDayBeforeHarvest <= 1)
{
if(this.cloverFraction.equals(this.CLOVER_FRACTION_SMALL))
{
return this.yield * 0.0040 + 17.62;
}
else
{
return this.yield * 0.0012 + 18.03;
}
}
else
{
if(this.cloverFraction.equals(this.CLOVER_FRACTION_SMALL))
{
return (this.yield * 0.0040) - (this.precipitationLastDayBeforeHarvest * 0.4727) + 15.86;
}
else
{
return (this.yield * 0.0038) - (this.precipitationLastDayBeforeHarvest * 0.0520) + 15.97;
}
}
}
else if(this.seasonHarvestNumber == 2)
{
if(this.precipitationLastDayBeforeHarvest <= 1)
{
if(this.cloverFraction.equals(this.CLOVER_FRACTION_SMALL))
{
return this.yield * 0.0033 + 20.04;
}
else
{
return this.yield * 0.0133 + 16.31;
}
}
else
{
if(this.cloverFraction.equals(this.CLOVER_FRACTION_SMALL))
{
return (this.yield * 0.0152) - (this.precipitationLastDayBeforeHarvest * 0.0300) + 10.86;
}
else
{
return (this.yield * 0.0122) - (this.precipitationLastDayBeforeHarvest * 0.1964) + 14.22;
}
}
}
else
{
throw new ModelExcecutionException("Only able to estimate initial dry matter fraction from 1st and 2nd harvest.");
}
}
} }
...@@ -28,6 +28,8 @@ import java.util.Date; ...@@ -28,6 +28,8 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;
import static junit.framework.Assert.fail; import static junit.framework.Assert.fail;
import no.bioforsk.vips.entity.ModelConfiguration; import no.bioforsk.vips.entity.ModelConfiguration;
import no.bioforsk.vips.entity.Result; import no.bioforsk.vips.entity.Result;
...@@ -79,31 +81,7 @@ public class GrassDryingModelTest { ...@@ -79,31 +81,7 @@ public class GrassDryingModelTest {
// @Test // @Test
// public void hello() {} // public void hello() {}
@Test
public void testAcceptance()
{
System.out.println("testAcceptance");
try
{
GrassDryingModel instance = new GrassDryingModel();
ModelConfiguration config = this.getConfiguration("/weatherData.json");
config.setConfigParameter("yield", 750.0);
config.setConfigParameter("conditioning", 2);
config.setConfigParameter("stringWidth", 3.0);
config.setConfigParameter("harvestWidth", 3.0);
instance.setConfiguration(config);
List<Result> results = instance.getResult();
assertEquals(18.01757902,Double.valueOf(results.get(0).getValue(GrassDryingModel.MODEL_ID.toString(), "DRY_MATTER")), 0.0001);
assertEquals(19.16504279,Double.valueOf(results.get(16).getValue(GrassDryingModel.MODEL_ID.toString(), "DRY_MATTER")), 0.0001);
}
catch(ConfigValidationException | ModelExcecutionException ex)
{
fail("Exception: " + ex.getMessage());
}
}
@Test @Test
public void testCalculateE() public void testCalculateE()
...@@ -180,7 +158,13 @@ public class GrassDryingModelTest { ...@@ -180,7 +158,13 @@ public class GrassDryingModelTest {
System.out.println("testCalculateM"); System.out.println("testCalculateM");
GrassDryingModel instance = new GrassDryingModel(); GrassDryingModel instance = new GrassDryingModel();
Double sigma_E = instance.calculateE(15.1, 57.9, 91.3, 5.8); Double sigma_E = instance.calculateE(15.1, 57.9, 91.3, 5.8);
Double result = instance.calculateM(instance.calculateMe(57.9), sigma_E, instance.calculateR_a(3.0, 0.0), 0.141288948, 0.0); Double result = 0.0;
try {
result = instance.calculateM(0.823, instance.calculateMe(57.9), sigma_E, instance.calculateR_a(3.0, 0.0), 0.141288948, 0.0);
} catch (ModelExcecutionException ex) {
fail(ex.getMessage());
}
assertEquals(4.550135226, result,0.00001); assertEquals(4.550135226, result,0.00001);
} }
...@@ -193,6 +177,46 @@ public class GrassDryingModelTest { ...@@ -193,6 +177,46 @@ public class GrassDryingModelTest {
assertEquals(18.28797909, result, 0.0001); assertEquals(18.28797909, result, 0.0001);
} }
@Test
public void testAcceptance()
{
System.out.println("testAcceptance");
try
{
GrassDryingModel instance = new GrassDryingModel();
ModelConfiguration config = this.getConfiguration("/weatherData.json");
config.setConfigParameter("yield", 750.0);
config.setConfigParameter("conditioning", 2);
config.setConfigParameter("stringWidth", 3.0);
config.setConfigParameter("harvestWidth", 3.0);
config.setConfigParameter("seasonHarvestNumber", 1);
config.setConfigParameter("cloverFraction", 1);
// Optimized to give same MCWBInit as in Excel sheet
config.setConfigParameter("precipitationLastDayBeforeHarvest", 2.453987);
instance.setConfiguration(config);
List<Result> results = instance.getResult();
assertEquals(18.01757902,Double.valueOf(results.get(0).getValue(GrassDryingModel.MODEL_ID.toString(), "DRY_MATTER")), 0.0001);
assertEquals(19.16504279,Double.valueOf(results.get(16).getValue(GrassDryingModel.MODEL_ID.toString(), "DRY_MATTER")), 0.0001);
// Testing with predefined dry matter fraction
config.setConfigParameter("initialDryMatterFraction", 18.7);
instance.setConfiguration(config);
results = instance.getResult();
assertEquals(19.03080738,Double.valueOf(results.get(0).getValue(GrassDryingModel.MODEL_ID.toString(), "DRY_MATTER")), 0.0001);
assertEquals(20.22019628,Double.valueOf(results.get(16).getValue(GrassDryingModel.MODEL_ID.toString(), "DRY_MATTER")), 0.0001);
}
catch(ConfigValidationException | ModelExcecutionException ex)
{
fail("Exception: " + ex.getMessage());
}
}
private ModelConfiguration getConfiguration(String fileName) private ModelConfiguration getConfiguration(String fileName)
{ {
try { try {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment