WEPPModel.java [src/java/m/wepp] Revision: Date:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package m.wepp;
import csip.api.client.ModelDataServiceCall;
import csip.api.server.ServiceException;
import csip.SessionLogger;
import java.io.*;
import org.apache.commons.io.FileUtils;
import org.json.XML;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
/**
* This class has misc functions. Needs to be reviewed to see if these can be
* moved or are not needed.
*
* @author jrf
*/
public class WEPPModel {
private static final double BAD_DOUBLE_VALUE = -999;
private static final int BAD_INT_VALUE = -999;
private double precip = BAD_DOUBLE_VALUE,
soilLoss = BAD_DOUBLE_VALUE,
runoff = BAD_DOUBLE_VALUE,
sedYield = BAD_DOUBLE_VALUE,
fuel = BAD_DOUBLE_VALUE,
stir = BAD_DOUBLE_VALUE,
sci = BAD_DOUBLE_VALUE;
private double om = Double.NaN,
er = Double.NaN,
fo = Double.NaN;
private double deposition, irrigation, nrcsLoss;
private int contoursHeld = BAD_INT_VALUE, contoursFailed = BAD_INT_VALUE;
private JSONObject segments;
private boolean useBuiltin;
private String weppversion;
private String preprocversion;
String contourServiceURL;
String manServiceURL;
String stripsServiceURL;
SessionLogger LOG;
WEPPModel(SessionLogger log) {
LOG = log;
useBuiltin = true;
weppversion = "";
preprocversion = "";
}
public void setServiceURLS(String contourURL, String managementURL, String stripsURL) {
contourServiceURL = contourURL;
manServiceURL = managementURL;
stripsServiceURL = stripsURL;
}
public double getPrecip() {
return precip;
}
public double getLoss() {
return soilLoss;
}
public double getRunoff() {
return runoff;
}
public double getSedyield() {
return sedYield;
}
public double getFuel() {
return fuel;
}
public double getSTIR() {
return stir;
}
public double getSCI() {
return sci;
}
public double getOM() {
return om;
}
public double getFO() {
return fo;
}
public double getER() {
return er;
}
public int getContoursHeld() {
return contoursHeld;
}
public int getContoursFailed() {
return contoursFailed;
}
public double getDeposition() {
return deposition;
}
public double getIrrigation() {
return irrigation;
}
public double getNRCSLoss() {
return nrcsLoss;
}
public JSONObject getSegments() {
return segments;
}
public String getWEPPVersion() {
return weppversion;
}
public String getPreprocversion() {
return preprocversion;
}
/*
* getManagement()
* This takes a LMOD key are returns the data in LMOD format that will be parsed
* to use in WEPP. Any sub objects such as vegetations, operations or residues are
* looked up the local WEPP sqlite database to get the WEPP specfic parameters.
*/
public String getManagement(String csip_lmod_file_key) throws Exception {
ModelDataServiceCall r = new ModelDataServiceCall()
.put("file_key", csip_lmod_file_key)
.put("format", "lmod")
.withDefaultLogger()
.url(manServiceURL)
.call();
if (r.serviceFinished()) {
try {
JSONObject obj = r.getJSONObject(r.getNames().get(0)).getJSONArray("managements").getJSONObject(0);
return obj.toString();
} catch (JSONException E) {
LOG.warning("Could not get management data from LMOD: " + E.getMessage());
return null;
}
} else {
LOG.info("Management request failed: " + r.getError());
return null;
}
}
/**
* Get the details of a contour given a specific name. Calls the CSIP contout
* service.
*
* @param lmod_contour_name name of the contour
* @return JSON with contour parameters.
*/
public JSONObject getContour(String lmod_contour_name) throws Exception {
if (useBuiltin) {
double abs;
if (lmod_contour_name.equals("c. perfect contouring no row grade")) {
abs = 0;
} else if (lmod_contour_name.equals("a. rows up-and-down hill")) {
abs = 0;
} else {
String sslp = lmod_contour_name.substring("b. absolute row grade ".length());
String[] p = sslp.trim().split(" ");
abs = Double.parseDouble(p[0]);
}
try {
JSONObject obj = new JSONObject()
.put("name", lmod_contour_name)
.put("abs", abs);
return obj;
} catch (Exception e) {
return null;
}
} else {
String[] parts = lmod_contour_name.split("\\\\");
ModelDataServiceCall r = new ModelDataServiceCall()
.put("name", parts[parts.length - 1])
.withDefaultLogger()
.url(contourServiceURL)
.call();
if (r.serviceFinished()) {
try {
return r.getJSONObject(r.getNames().get(0)).getJSONArray("contours").getJSONObject(0);
} catch (JSONException E) {
LOG.warning("Could not get contour data from LMOD");
return null;
}
} else {
LOG.warning("Contour request failed: " + r.getError());
return null;
}
}
}
/**
* Gets a specific strip/barrier set of parameters give a name.
*
* @param lmod_strip_name name of strip/barrier
* @return JSON returned from CSIP service
*/
public JSONObject getStripBarrier(String lmod_strip_name) throws Exception {
String[] parts = lmod_strip_name.split("\\\\");
ModelDataServiceCall r = new ModelDataServiceCall()
.put("name", parts[parts.length - 1])
.put("format", "r2")
.withDefaultLogger()
.url(stripsServiceURL)
.call();
if (r.serviceFinished()) {
try {
return r.getJSONObject(r.getNames().get(0)).getJSONArray("strips").getJSONObject(0);
} catch (JSONException E) {
LOG.warning("Error: Could not get strip data." + E.getMessage());
return null;
}
} else {
LOG.warning("Strips service failed: " + r.getError());
return null;
}
}
/**
* After a WEPP run a brief put file lists the main 4 outputs which as read
* and saved.
*
* @param resultsFile WEPP results
* @throws IOException error reading file
*/
public void parseOutputs(File resultsFile) throws IOException {
contoursHeld = 0;
contoursFailed = 0;
String restring;
try {
String fc = FileUtils.readFileToString(resultsFile, "UTF-8");
// restring = XML.toJSONObject(fileContents.toString()).toString();
restring = XML.toJSONObject(fc).toString();
} catch (org.json.JSONException ex) {
throw new IOException("Cannot convert WEPP output XML file to JSON: " + ex.getMessage(), ex);
}
if ((restring != null) && (!restring.isEmpty())) {
JSONObject results;
try {
results = new JSONObject(restring);
} catch (JSONException ex) {
throw new IOException("Cannot convert WEPP output XML file to JSON: " + ex.getMessage(), ex);
}
if ((results == null) || (!results.has("RESULTS"))) {
throw new IOException("The contents of the WEPP output XML file could not be processed. Contents missing or \"RESULTS\" xml tag not found.");
}
results = results.optJSONObject("RESULTS");
precip = results.optDouble("PRECIP", BAD_DOUBLE_VALUE);
soilLoss = results.optDouble("LOSS", BAD_DOUBLE_VALUE);
sedYield = results.optDouble("SEDYIELD", BAD_DOUBLE_VALUE);
runoff = results.optDouble("RUNOFF", BAD_DOUBLE_VALUE);
fuel = results.optDouble("FUEL", BAD_DOUBLE_VALUE);
stir = results.optDouble("STIR", BAD_DOUBLE_VALUE);
sci = results.optDouble("SCI", BAD_DOUBLE_VALUE);
om = results.optDouble("OM", BAD_DOUBLE_VALUE);
er = results.optDouble("ER", BAD_DOUBLE_VALUE);
fo = results.optDouble("FO", BAD_DOUBLE_VALUE);
deposition = results.optDouble("DEPOSITION", BAD_DOUBLE_VALUE);
irrigation = results.optDouble("IRRIGATION", BAD_DOUBLE_VALUE);
nrcsLoss = results.optDouble("NRCSLOSS", BAD_DOUBLE_VALUE);
try {
weppversion = results.getString("WEPP_VERSION");
preprocversion = results.getString("PREPROCESSOR_VERSION");
} catch (JSONException ex) {
throw new IOException("WEPP output XML file is missing a mandatory tag value: " + ex.getMessage(), ex);
}
JSONObject contours = results.optJSONObject("Contours");
if (contours != null) {
contoursHeld = contours.optInt("Held", BAD_INT_VALUE);
contoursFailed = contours.optInt("Failed", BAD_INT_VALUE);
}
segments = results.optJSONObject("Management");
// }catch (JSONException e) {
// precip = soilLoss = sedYield = runoff = fuel = stir = sci = BAD_DOUBLE_VALUE;
// contoursHeld = contoursFailed = BAD_INT_VALUE;
// }
} else {
throw new IOException("The WEPP output XML file is empty");
}
}
}