@@ -5,6 +5,7 @@ |
*/ |
package m.rhem.model; |
|
+import csip.ServiceException; |
import java.sql.Connection; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
@@ -14,9 +15,12 @@ |
/** |
* |
* @author rumpal |
+ * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a> |
*/ |
public class Parameter { |
|
+ private static final double CLEN_MULTIPLIER = 2.5; |
+ |
protected String clen; |
protected String diams; |
protected String density; |
@@ -28,9 +32,8 @@ |
protected String g, dist, por; |
protected String fract; |
|
- private AoA aoa; |
- private double slopeLength; |
- |
+ private AoA aoa = null; |
+ private double slopeLength = 0.0; |
|
public Parameter(String diams, String density, String len, |
String chezy, String rchezy, String sl, String sx, String cv, |
@@ -57,32 +60,38 @@ |
this.dist = dist; |
this.por = por; |
this.fract = fract; |
+ this.aoa = null; |
|
- this.clen = String.valueOf(Double.parseDouble(len) * 2.5); |
+ this.clen = String.valueOf(Double.parseDouble(len) * CLEN_MULTIPLIER); |
} |
|
- |
- public Parameter(AoA aoa) { |
- this.cv = "1.00"; |
- this.sat = "0.25;"; |
- this.komega = "0.000007747"; |
- this.kcm = "0.00029936430000"; |
- this.adf = "0.0"; |
- this.alf = "0.8"; |
- this.bare = "0 ! INACTIVE"; |
- this.aoa = aoa; |
- this.slopeLength = aoa.slopeLength; |
+ public Parameter(AoA aoa) throws ServiceException { |
+ if (null != aoa) { |
+ this.cv = "1.00"; |
+ this.sat = "0.25;"; |
+ this.komega = "0.000007747"; |
+ this.kcm = "0.00029936430000"; |
+ this.adf = "0.0"; |
+ this.alf = "0.8"; |
+ this.bare = "0 ! INACTIVE"; |
+ this.aoa = aoa; |
+ this.slopeLength = aoa.slopeLength; |
+ } else { |
+ throw new ServiceException("AoA specified was NULL; Cannot continue."); |
+ } |
} |
|
- |
- public void computeParameters(Connection connection) throws SQLException { |
+ public void computeParameters(Connection connection) throws SQLException, ServiceException { |
+ if (null == aoa) { |
+ throw new ServiceException("Invalid AoA specified in the Parameter object."); |
+ } |
// canopy cover for grass |
// double grasscanopycover = aoa.bunchGgrassCanopyCover + aoa.forbsCanopyCover + aoa.sodGrassCanopyCover; |
// TOTAL CANOPY COVER |
double totalcanopycover = aoa.bunchGgrassCanopyCover + aoa.forbsCanopyCover + aoa.shrubsCanopyCover + aoa.sodGrassCanopyCover; |
// TOTAL GROUND COVER |
double totalgroundcover = aoa.rockCover + aoa.basalCover + aoa.litterCover + aoa.cryptogamsCover; |
- |
+ |
if (aoa.unit == 2) { |
slopeLength = aoa.slopeLength * 0.3048; |
} else { |
@@ -99,43 +108,49 @@ |
computeKssValue(totalcanopycover, totalgroundcover); |
} |
|
- |
public void computeChezyValue() { |
double ft = (-1 * 0.109) + (1.425 * aoa.litterCover) |
+ (0.442 * aoa.rockCover) + (1.764 * (aoa.basalCover |
+ aoa.cryptogamsCover)) + (2.068 * aoa.slopeSteepness); |
ft = Math.pow(10, ft); |
- rchezy = chezy = String.valueOf(Math.pow((8 * 9.8) / ft, 0.5)); |
- } |
- |
- |
- public void computeSlSxValues() { |
- switch (aoa.slopeShape) { |
- case "Uniform": |
- sl = aoa.slopeSteepness + ", " + aoa.slopeSteepness; |
- sx = 0.00 + ", " + 1.00; |
- break; |
- case "Convex": |
- sl = 0.001 + ", " + (aoa.slopeSteepness * 2); |
- sx = 0.00 + ", " + 1.00; |
- break; |
- case "Concave": |
- sl = (aoa.slopeSteepness * 2) + ", " + 0.001; |
- sx = 0.00 + ", " + 1.00; |
- break; |
- case "S-Shaped": |
- sl = 0.001 + ", " + (aoa.slopeSteepness * 2) + ", " + 0.001; |
- sx = 0.00 + ", " + 0.50 + ", " + 1.00; |
- break; |
+ if (ft != 0.0) { |
+ rchezy = chezy = String.valueOf(Math.pow((8 * 9.8) / ft, 0.5)); |
+ } else { |
+ throw new ArithmeticException("Divide by zero for ft value while computing ChezyValue; Cannot continue."); |
} |
} |
|
+ public void computeSlSxValues() throws ServiceException { |
+ if (null != aoa) { |
+ switch (aoa.slopeShape.toLowerCase()) { |
+ case "uniform": |
+ sl = aoa.slopeSteepness + ", " + aoa.slopeSteepness; |
+ sx = 0.00 + ", " + 1.00; |
+ break; |
+ case "convex": |
+ sl = 0.001 + ", " + (aoa.slopeSteepness * 2); |
+ sx = 0.00 + ", " + 1.00; |
+ break; |
+ case "concave": |
+ sl = (aoa.slopeSteepness * 2) + ", " + 0.001; |
+ sx = 0.00 + ", " + 1.00; |
+ break; |
+ case "s-shaped": |
+ sl = 0.001 + ", " + (aoa.slopeSteepness * 2) + ", " + 0.001; |
+ sx = 0.00 + ", " + 0.50 + ", " + 1.00; |
+ break; |
+ default: |
+ throw new ServiceException("Invalid slope shape, " + aoa.slopeShape + ", specified for this AoA; Cannot continue."); |
+ } |
+ } else { |
+ throw new ServiceException("No AoA object was found; Canot contiue."); |
+ } |
+ } |
|
public void computeClenValue() { |
- clen = String.valueOf(slopeLength * 2.5); |
+ clen = String.valueOf(slopeLength * CLEN_MULTIPLIER); |
} |
|
- |
public void getValuesFmDb(Connection connection) throws SQLException { |
try (Statement statement = connection.createStatement()) { |
try (ResultSet resultSet = statement.executeQuery(DBQueries.RunRHEMQuery01(aoa.soilTexture))) { |
@@ -166,51 +181,56 @@ |
} |
} |
|
- |
- private void computeKeValue(double totalcanopycover) { |
+ private void computeKeValue(double totalcanopycover) throws ServiceException { |
double Keb = 0; |
- switch (aoa.soilTexture) { |
- case "Sand": |
- Keb = 24 * Math.exp(0.3483 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Loamy Sand": |
- Keb = 10 * Math.exp(0.8755 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Sandy Loam": |
- Keb = 5 * Math.exp(1.1632 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Loam": |
- Keb = 2.5 * Math.exp(1.5686 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Silt Loam": |
- Keb = 1.2 * Math.exp(2.0149 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Silt": |
- Keb = 1.2 * Math.exp(2.0149 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Sandy Clay Loam": |
- Keb = 0.80 * Math.exp(2.1691 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Clay Loam": |
- Keb = 0.50 * Math.exp(2.3026 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Silty Clay Loam": |
- Keb = 0.40 * Math.exp(2.1691 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Sandy Clay": |
- Keb = 0.30 * Math.exp(2.1203 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Silty Clay": |
- Keb = 0.25 * Math.exp(1.7918 * (aoa.basalCover + aoa.litterCover)); |
- break; |
- case "Clay": |
- Keb = 0.2 * Math.exp(1.3218 * (aoa.basalCover + aoa.litterCover)); |
- break; |
+ if ((null != aoa) && (!aoa.soilTexture.isEmpty())) { |
+ switch (aoa.soilTexture) { |
+ case "Sand": |
+ Keb = 24 * Math.exp(0.3483 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Loamy Sand": |
+ Keb = 10 * Math.exp(0.8755 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Sandy Loam": |
+ Keb = 5 * Math.exp(1.1632 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Loam": |
+ Keb = 2.5 * Math.exp(1.5686 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Silt Loam": |
+ Keb = 1.2 * Math.exp(2.0149 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Silt": |
+ Keb = 1.2 * Math.exp(2.0149 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Sandy Clay Loam": |
+ Keb = 0.80 * Math.exp(2.1691 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Clay Loam": |
+ Keb = 0.50 * Math.exp(2.3026 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Silty Clay Loam": |
+ Keb = 0.40 * Math.exp(2.1691 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Sandy Clay": |
+ Keb = 0.30 * Math.exp(2.1203 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Silty Clay": |
+ Keb = 0.25 * Math.exp(1.7918 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ case "Clay": |
+ Keb = 0.2 * Math.exp(1.3218 * (aoa.basalCover + aoa.litterCover)); |
+ break; |
+ default: |
+ throw new ServiceException("Invalid soilTexture specified in the AoA, " + aoa.soilTexture); |
+ } |
+ } else { |
+ throw new ServiceException("No soil Texture specified, cannot continue"); |
} |
double weightedKe = 0; |
|
// calculate weighted Ke and Kss values for the vegetation types that have non-zero values |
- if (totalcanopycover != 0) { |
+ if (totalcanopycover != 0.0) { |
weightedKe = weightedKe + ((aoa.shrubsCanopyCover / totalcanopycover) * (Keb * 1.2)); |
weightedKe = weightedKe + ((aoa.sodGrassCanopyCover / totalcanopycover) * (Keb * 0.8)); |
weightedKe = weightedKe + ((aoa.bunchGgrassCanopyCover / totalcanopycover) * (Keb * 1.0)); |
@@ -221,7 +241,6 @@ |
ke = String.valueOf(weightedKe); |
} |
|
- |
public void computeKssValue(double totalcanopycover, double totalgroundcover) { |
// Kss variables |
double Kss_Seg_Bunch, Kss_Seg_Sod, Kss_Seg_Shrub, Kss_Seg_Shrub_0, Kss_Seg_Forbs; |
@@ -273,6 +292,14 @@ |
+ (aoa.forbsCanopyCover / totalcanopycover) * Kss_Seg_Forbs) |
+ (0.02 - totalcanopycover) / 0.02 * Kss_Seg_Shrub_0; |
} else { |
+ //?? add this or....why is there a test for 0 below, which won't happen |
+ // if this section gets called, even without the new exception.... |
+ // Something is really amiss with the logic of this calculation!! |
+ //?? |
+ |
+ if (totalcanopycover == 0.0) { //Just added this because if totalcanopycover is 0, this section of code will be called before step 3) below and we will NEVER get there. |
+ throw new ArithmeticException("Divide by zero for totalcanopycover value. Cannot continue with Kss_average calculation."); |
+ } |
Kss_Average = (aoa.shrubsCanopyCover / totalcanopycover) * Kss_Seg_Shrub |
+ (aoa.sodGrassCanopyCover / totalcanopycover) * Kss_Seg_Sod |
+ (aoa.bunchGgrassCanopyCover / totalcanopycover) * Kss_Seg_Bunch |
@@ -280,7 +307,7 @@ |
} |
|
// 3) CALCULATE KSS USED FOR RHEM |
- if (totalcanopycover == 0) { |
+ if (totalcanopycover == 0.0) { |
if (totalgroundcover < 0.475) { |
Kss_Final = 4.2587 + 2.5535 * aoa.slopeSteepness - 2.547 * totalgroundcover; |
Kss_Final = Math.pow(10, Kss_Final); |
@@ -297,107 +324,86 @@ |
kss = String.valueOf(Kss_Final); |
} |
|
- |
public String getClen() { |
return clen; |
} |
|
- |
public String getDiams() { |
return diams; |
} |
|
- |
public String getDensity() { |
return density; |
} |
|
- |
public String getLen() { |
return len; |
} |
|
- |
public String getChezy() { |
return chezy; |
} |
|
- |
public String getRchezy() { |
return rchezy; |
} |
|
- |
public String getSl() { |
return sl; |
} |
|
- |
public String getSx() { |
return sx; |
} |
|
- |
public String getCv() { |
return cv; |
} |
|
- |
public String getSat() { |
return sat; |
} |
|
- |
public String getKss() { |
return kss; |
} |
|
- |
public String getKomega() { |
return komega; |
} |
|
- |
public String getKcm() { |
return kcm; |
} |
|
- |
public String getKe() { |
return ke; |
} |
|
- |
public String getAdf() { |
return adf; |
} |
|
- |
public String getAlf() { |
return alf; |
} |
|
- |
public String getBare() { |
return bare; |
} |
|
- |
public String getG() { |
return g; |
} |
|
- |
public String getDist() { |
return dist; |
} |
|
- |
public String getPor() { |
return por; |
} |
|
- |
public String getFract() { |
return fract; |
} |
@@ -14,6 +14,8 @@ |
import csip.Config; |
import csip.Executable; |
import csip.ModelDataService; |
+import csip.PayloadParameter; |
+import csip.PayloadResults; |
import csip.ServiceException; |
import csip.annotations.Polling; |
import csip.annotations.Resource; |
@@ -32,15 +34,18 @@ |
import m.rhem.model.RhemModel; |
import csip.annotations.Description; |
import csip.annotations.Name; |
+import static csip.annotations.ResourceType.EXECUTABLE; |
+import static rhem.utils.Constants.RHEM_EXE; |
import rhem.utils.DBQueries; |
-import static rhem.utils.DBResources.RHEM_EXE; |
import rhem.utils.DBResources; |
|
+ |
/** |
* RHEM-01:Run RHEM Model |
* |
* @version 1.0 |
* @author Rumpal Sidhu |
+ * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a> |
*/ |
@Name("RHEM-01:Run RHEM Model") |
@Description("Run RHEM Model utilizing parameters including climate station, " |
@@ -51,9 +56,14 @@ |
@Path("m/rhem/runrhem/1.0") |
@Polling(first = 10000, next = 2000) |
@Resource(from = DBResources.class) |
- |
+//Run model executable |
+@Resource(type = EXECUTABLE, file = "/bin/${csip.arch}/rhem_v4.exe", id = RHEM_EXE) |
public class V1_0 extends ModelDataService { |
|
+ private static final int DEFAULT_MOISTURE_CONTENT = 25; |
+ private static final double DEFAULT_SLOPE_LENGTH_1 = 50.0; |
+ private static final double DEFAULT_SLOPE_LENGTH_2 = 164.04; |
+ |
private AoA aoa; |
private String parameterFileName; |
private String stormFileName; |
@@ -66,36 +76,42 @@ |
|
@Override |
public void preProcess() throws ServiceException { |
- int aoaId = getIntParam("AoAID", 0); |
- int rhemSiteId = getIntParam("rhem_site_id", 0); |
- String scenarioName = getStringParam("scenarioname"); |
- String scenarioDescription = getStringParam("scenariodescription"); |
- int unit = getIntParam("units", 0); |
- String stateId = getStringParam("stateid"); |
- String climatestationId = getStringParam("climatestationid"); |
- String soilTexture = getStringParam("soiltexture"); |
- String slopeShape = getStringParam("slopeshape"); |
- double slopeSteepness = getDoubleParam("slopesteepness", 0.0); |
- double bunchGgrassCanopyCover = getDoubleParam("bunchgrasscanopycover", 0.0); |
- double forbsCanopyCover = getDoubleParam("forbscanopycover", 0.0); |
- double shrubsCanopyCover = getDoubleParam("shrubscanopycover", 0.0); |
- double sodGrassCanopyCover = getDoubleParam("sodgrasscanopycover", 0.0); |
- double basalCover = getDoubleParam("basalcover", 0.0); |
- double rockCover = getDoubleParam("rockcover", 0.0); |
- double litterCover = getDoubleParam("littercover", 0.0); |
- double cryptogamsCover = getDoubleParam("cryptogamscover", 0.0); |
+ PayloadParameter parameters = this.parameter(); |
+ |
+ int aoaId = parameters.getInt("AoAID", 0); |
+ int rhemSiteId = parameters.getInt("rhem_site_id", 0); |
+ String scenarioName = parameters.getString("scenarioname"); |
+ String scenarioDescription = parameters.getString("scenariodescription"); |
+ int unit = parameters.getInt("units"); |
+ String stateId = parameters.getString("stateid"); |
+ String climatestationId = parameters.getString("climatestationid"); |
+ String soilTexture = parameters.getString("soiltexture"); |
+ String slopeShape = parameters.getString("slopeshape"); |
+ double slopeSteepness = parameters.getDouble("slopesteepness", 0.0); |
+ double bunchGgrassCanopyCover = parameters.getDouble("bunchgrasscanopycover", 0.0); |
+ double forbsCanopyCover = parameters.getDouble("forbscanopycover", 0.0); |
+ double shrubsCanopyCover = parameters.getDouble("shrubscanopycover", 0.0); |
+ double sodGrassCanopyCover = parameters.getDouble("sodgrasscanopycover", 0.0); |
+ double basalCover = parameters.getDouble("basalcover", 0.0); |
+ double rockCover = parameters.getDouble("rockcover", 0.0); |
+ double litterCover = parameters.getDouble("littercover", 0.0); |
+ double cryptogamsCover = parameters.getDouble("cryptogamscover", 0.0); |
|
//Validations |
//The values allowed for the field unit in the request are 1 and 2. 1 is for metric units and 2 is for English units |
- if (unit != 1 && unit != 2) { |
- LOG.log(Level.SEVERE, "RHEM-01: Invalid unit"); |
- throw new ServiceException("Unit should be 1-metric or 2 - English. Digit " + unit + " is not valid."); |
- } |
double slopeLength; |
- if (unit == 1) { |
- slopeLength = 50; |
- } else { |
- slopeLength = 164.04; |
+ switch (unit) { |
+ case 1: |
+ slopeLength = DEFAULT_SLOPE_LENGTH_1; |
+ break; |
+ |
+ case 2: |
+ slopeLength = DEFAULT_SLOPE_LENGTH_2; |
+ break; |
+ |
+ default: |
+ LOG.log(Level.SEVERE, "RHEM-01: Invalid unit:" + unit); |
+ throw new ServiceException("Unit should be 1-metric or 2-English. The value, " + unit + ", is not valid."); |
} |
|
aoa = new AoA(aoaId, rhemSiteId, scenarioName, |
@@ -103,7 +119,7 @@ |
soilTexture, slopeLength, slopeShape, slopeSteepness, |
bunchGgrassCanopyCover, forbsCanopyCover, shrubsCanopyCover, |
sodGrassCanopyCover, basalCover, rockCover, litterCover, |
- cryptogamsCover, 25); |
+ cryptogamsCover, DEFAULT_MOISTURE_CONTENT); |
} |
|
@Override |
@@ -169,25 +185,27 @@ |
|
@Override |
public void postProcess() { |
- putResult("AoAID", aoa.getAoaId(), "Area of Analysis Identifier"); |
- putResult("rhem_site_id", aoa.getRhemSiteId(), "RHEM Evaluation Site Identifier"); |
- putResult("CLEN", parameter.getClen()); |
- putResult("UNITS", "metric"); |
- putResult("DIAMS", parameter.getDiams()); |
- putResult("DENSITY", parameter.getDensity()); |
- putResult("CHEZY", parameter.getChezy()); |
- putResult("RCHEZY", parameter.getRchezy()); |
- putResult("SL", parameter.getSl()); |
- putResult("SX", parameter.getSx()); |
- putResult("KSS", parameter.getKss()); |
- putResult("KE", parameter.getKe()); |
- putResult("G", parameter.getG()); |
- putResult("DIST", parameter.getDist()); |
- putResult("POR", parameter.getPor()); |
- putResult("FRACT", parameter.getFract()); |
- putResult(new File(getWorkspaceDir(), parameterFileName), "Parameter input file"); |
- putResult(new File(getWorkspaceDir(), stormFileName), "Storm input file"); |
- putResult(new File(getWorkspaceDir(), summaryFileName), "Summary file"); |
- putResult(new File(getWorkspaceDir(), detailedOutputFileName), "Detailed"); |
+ PayloadResults resultJSON = results(); |
+ |
+ resultJSON.put("AoAID", aoa.getAoaId(), "Area of Analysis Identifier"); |
+ resultJSON.put("rhem_site_id", aoa.getRhemSiteId(), "RHEM Evaluation Site Identifier"); |
+ resultJSON.put("CLEN", parameter.getClen()); |
+ resultJSON.put("UNITS", "metric"); |
+ resultJSON.put("DIAMS", parameter.getDiams()); |
+ resultJSON.put("DENSITY", parameter.getDensity()); |
+ resultJSON.put("CHEZY", parameter.getChezy()); |
+ resultJSON.put("RCHEZY", parameter.getRchezy()); |
+ resultJSON.put("SL", parameter.getSl()); |
+ resultJSON.put("SX", parameter.getSx()); |
+ resultJSON.put("KSS", parameter.getKss()); |
+ resultJSON.put("KE", parameter.getKe()); |
+ resultJSON.put("G", parameter.getG()); |
+ resultJSON.put("DIST", parameter.getDist()); |
+ resultJSON.put("POR", parameter.getPor()); |
+ resultJSON.put("FRACT", parameter.getFract()); |
+ resultJSON.put(new File(getWorkspaceDir(), parameterFileName), "Parameter input file"); |
+ resultJSON.put(new File(getWorkspaceDir(), stormFileName), "Storm input file"); |
+ resultJSON.put(new File(getWorkspaceDir(), summaryFileName), "Summary file"); |
+ resultJSON.put(new File(getWorkspaceDir(), detailedOutputFileName), "Detailed"); |
} |
} |