WEPSModelArchive.java [tools/MetaModelTools/src/models] Revision: 04954fb50d3148fbace9e091840b77662ab98631 Date: Fri Nov 22 12:54:54 MST 2019
/*
* 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 models;
import csip.ServiceException;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import data.interpretors.CligenData;
import data.interpretors.IFCFile;
import data.interpretors.WindGenData;
import java.io.BufferedWriter;
import java.io.File;
import java.nio.file.Files;
import java.util.logging.Level;
import java.util.logging.Logger;
import nodes.WEPSManagement;
import org.codehaus.jettison.json.JSONArray;
import parsers.ParserException;
import utils.Urls;
/**
*
* @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
*/
public class WEPSModelArchive extends ModelArchive {
private IFCFile ifcFile;
private WindGenData windData;
private CligenData cligenData;
private String stdErrorFile;
private String stdOutFile;
private WEPSManagement management;
private boolean possibleBadModelRun = false;
private boolean badModelRun = false;
private String badModelMessage = "";
private WEPSMetaData wepsMetaData;
public WEPSModelArchive(String suid, String ctime, String etime, String service, String status, String req_ip, String filename) {
super(suid, ctime, etime, service, status, req_ip, filename);
}
public WEPSModelArchive(String suid, String ctime, String etime, String service, String status, String req_ip, String filename, byte[] fileData) throws IOException, JSONException {
super(suid, ctime, etime, service, status, req_ip, filename, fileData);
setFileDataEx(fileData);
}
@Override
public final void setFileDataEx(byte[] fileData) throws IOException, JSONException {
super.setFileDataEx(fileData);
try {
stdErrorFile = getStdErrorFile(fileData);
} catch (IOException ex) {
badModelRun = true;
badModelMessage += "##\n";
badModelMessage += ex.getMessage();
}
if (null != stdErrorFile) {
possibleBadModelRun = stdErrorFile.contains("IEEE_UNDERFLOW_FLAG") || stdErrorFile.contains("IEEE_DENORMAL");
if (possibleBadModelRun) {
badModelMessage += "##\nThe WEPS model executable stderr file contained: ";
badModelMessage += ((stdErrorFile.contains("IEEE_UNDERFLOW_FLAG")) ? "\nIEEE_UNDERFLOW_FLAG, Meaning that some values were rounded to zero because they were too small for the FORTRAN code to interpret." : "");
if (badModelMessage.contains("IEEE")) {
badModelMessage += "\n AND ";
}
badModelMessage += ((stdErrorFile.contains("IEEE_DENORMAL")) ? "\nIEEE_DENORMAL, Meaning that there are denormal numbers generated when running the code." : "");
badModelMessage += "\n This may be a hint about numerical problems in the model FORTRAN code, but it is not an error per se. Probably, the program finished successfully, but some result values may be suspect.";
}
}
// try {
// management = getManagementFile(fileData);
// } catch (IOException ex) {
// badModelRun = true;
// badModelMessage += "##\n";
// badModelMessage += ex.getMessage();
// }
try {
windData = getWindDataFile(fileData);
} catch (IOException ex) {
badModelRun = true;
badModelMessage += "##\n";
badModelMessage += ex.getMessage();
}
if (windData.badWindData()) {
badModelMessage += "##\nThe Wind data associated with this model run has some qualifying messages: \n" + windData.windDataMessages();
}
try {
cligenData = getClimateDataFile(fileData);
} catch (IOException ex) {
badModelRun = true;
badModelMessage += "##\n";
badModelMessage += ex.getMessage();
}
if (cligenData.badClimateData()) {
badModelMessage += "##\nThe Cligen data associated with this model run has some qualifying messages: \n" + cligenData.cligenDataMessages();
}
try {
stdOutFile = getStdOutFile(fileData);
} catch (IOException ex) {
badModelRun = true;
badModelMessage += "##\n";
badModelMessage += ex.getMessage();
}
try {
ifcFile = getIFCFile(fileData);
} catch (IOException ex) {
badModelRun = true;
badModelMessage += "##\n";
badModelMessage += ex.getMessage();
}
if (!badModelRun && badModelMessage.isEmpty()) {
calcWEPSMetaData();
}
}
public boolean questionableResults() {
return possibleBadModelRun;
}
public boolean badModelRun() {
return badModelRun;
}
public String badModelMessage() {
return badModelMessage;
}
public IFCFile iFCFile() {
return ifcFile;
}
public WindGenData windData() {
return windData;
}
public CligenData cligenData() {
return cligenData;
}
public String stdErrorFile() {
return stdErrorFile;
}
public String stdOutFile() {
return stdOutFile;
}
public WEPSMetaData getWEPSMetaData() {
return wepsMetaData;
}
public void calcWEPSMetaData() {
if (null == wepsMetaData) {
wepsMetaData = new WEPSMetaData();
}
wepsMetaData.suid(this.suid);
wepsMetaData.cokey(getOriginalRequest("soil"));
wepsMetaData.longitude(Double.parseDouble(getOriginalRequest("longitude")));
wepsMetaData.latitude(Double.parseDouble(getOriginalRequest("latitude")));
wepsMetaData.annualPrecip(cligenData.annualAvgPrecip());
wepsMetaData.windEnergy(windData.simulationAverage());
wepsMetaData.componentName(ifcFile.componentName);
wepsMetaData.fractionSand(ifcFile.fractionSand);
wepsMetaData.fractionSilt(ifcFile.fractionSilt);
wepsMetaData.fractionClay(ifcFile.fractionClay);
wepsMetaData.crustStability(ifcFile.crustStability);
wepsMetaData.surfRockFrag(ifcFile.surfaceFragmentCover);
wepsMetaData.albedo(ifcFile.surfaceAlbedo);
wepsMetaData.num_layers(ifcFile.layerThickness.length);
wepsMetaData.surface_thickness(((int) ifcFile.layerThickness[0]));
wepsMetaData.slope_gradient(ifcFile.surfaceSlope);
//TODO: Do we need to measure the layers before setting these?? WEPSSoilInput already filters/sorts layers, etc...
wepsMetaData.aggStability(ifcFile.aggregateStability[0]);
wepsMetaData.soilWiltPoint(ifcFile.wiltingPointSWC[0]);
String biomass_avg = getOriginalResponse("average_biomass");
if (!biomass_avg.isEmpty()) {
wepsMetaData.rotWeightResBiomass(Double.parseDouble(biomass_avg) * 2000);
} else {
badModelRun = true;
badModelMessage += "##\n";
badModelMessage += "Missing biomass_avg result in WEPS output result file.";
}
String stir_avg = getOriginalResponse("avg_all_stir");
if (!stir_avg.isEmpty()) {
wepsMetaData.rotWeightSoilTillIntensity(Double.parseDouble(stir_avg));
} else {
badModelRun = true;
badModelMessage += "##\n";
badModelMessage += "Missing avg_all_stir result in WEPS output result file.";
}
String wind_eros = getOriginalResponse("wind_eros");
if (!wind_eros.isEmpty()) {
wepsMetaData.errosionRate(Double.parseDouble(wind_eros));
} else {
badModelRun = true;
badModelMessage += "##\n";
badModelMessage += "Missing wind_eros result in WEPS output result file.";
}
wepsMetaData.errorMessages(badModelMessage);
}
private WEPSManagement getManagementFile(byte[] fileData) throws IOException {
WEPSManagement wepsManagement = new WEPSManagement(new Urls());
File managementFile = new File("management.man");
BufferedWriter bufferWriter = Files.newBufferedWriter(managementFile.toPath());
String data = getFileContents(fileData, ".man");
bufferWriter.write(data);
bufferWriter.flush();
bufferWriter.close();
try {
wepsManagement.readManData(managementFile);
} catch (ParserException | ServiceException ex) {
Logger.getLogger(WEPSModelArchive.class.getName()).log(Level.SEVERE, null, ex);
badModelRun = true;
badModelMessage += "##\n";
badModelMessage += "Error parsing the WEPS management file: " + ex.getMessage();
}
return wepsManagement;
}
private WindGenData getWindDataFile(byte[] fileData) throws IOException {
WindGenData wind;
wind = new WindGenData(getFileContents(fileData, ".win"));
return wind;
}
private CligenData getClimateDataFile(byte[] fileData) throws IOException {
CligenData climate;
climate = new CligenData(getFileContents(fileData, ".cli"));
return climate;
}
private IFCFile getIFCFile(byte[] fileData) throws IOException {
IFCFile requestData;
requestData = new IFCFile(getFileContents(fileData, ".ifc"));
return requestData;
}
private String getStdErrorFile(byte[] fileData) throws IOException {
String fileString = null;
try (ZipInputStream zin = new ZipInputStream(new ByteArrayInputStream(fileData))) {
ZipEntry entry;
while ((entry = zin.getNextEntry()) != null) {
if (entry.getName().contains("weps.") && entry.getName().contains("stderr.txt")) {
BufferedReader bReader = new BufferedReader(new InputStreamReader(zin));
StringBuilder fileContent = new StringBuilder();
String inputStr;
while ((inputStr = bReader.readLine()) != null) {
fileContent.append(inputStr).append(System.lineSeparator());
}
fileString = fileContent.toString();
break;
}
}
}
return fileString;
}
private String getStdOutFile(byte[] fileData) throws IOException {
String fileString = null;
try (ZipInputStream zin = new ZipInputStream(new ByteArrayInputStream(fileData))) {
ZipEntry entry;
while ((entry = zin.getNextEntry()) != null) {
if (entry.getName().contains("weps.exe") && entry.getName().contains("stdout.txt")) {
BufferedReader bReader = new BufferedReader(new InputStreamReader(zin));
StringBuilder fileContent = new StringBuilder();
String inputStr;
while ((inputStr = bReader.readLine()) != null) {
fileContent.append(inputStr).append(System.lineSeparator());
}
fileString = fileContent.toString();
break;
}
}
}
return fileString;
}
public class WEPSMetaData {
private double latitude;
private double longitude;
private String cokey;
private double windEnergy;
private double annualPrecip;
private double rotIrrEffect;
private double soilWiltPoint;
private double rotWeightResBiomass;
private double rotWeightSoilTillIntensity;
private double rotWeightResAddition;
private double aggStability;
private double crustStability;
private double surfRockFrag;
private double errosionRate;
private String componentName;
private double[] fractionSand;
private double[] fractionSilt;
private double[] fractionClay;
private double albedo;
private double slope_gradient;
private int surface_thickness;
private int num_layers;
private String suid;
private String errorMessages = "";
public String errorMessages() {
return errorMessages;
}
public void errorMessages(String value) {
errorMessages = value;
}
public String suid() {
return suid;
}
public void suid(String value) {
suid = value;
}
public double windEnergy() {
return windEnergy;
}
public double annualPrecip() {
return annualPrecip;
}
public double rotIrrEffect() {
return rotIrrEffect;
}
public double soilWiltPoint() {
return rotIrrEffect;
}
public double rotWeightResBiomass() {
return rotWeightResBiomass;
}
public double rotWeightSoilTillIntensity() {
return rotWeightSoilTillIntensity;
}
public double rotWeightResAddition() {
return rotWeightResAddition;
}
public double aggStability() {
return aggStability;
}
public double crustStability() {
return crustStability;
}
public double surfRockFrag() {
return surfRockFrag;
}
public double errosionRate() {
return errosionRate;
}
public void windEnergy(double value) {
windEnergy = value;
}
public void annualPrecip(double value) {
annualPrecip = value;
}
public void rotIrrEffect(double value) {
rotIrrEffect = value;
}
public void soilWiltPoint(double value) {
rotIrrEffect = value;
}
public void rotWeightResBiomass(double value) {
rotWeightResBiomass = value;
}
public void rotWeightSoilTillIntensity(double value) {
rotWeightSoilTillIntensity = value;
}
public void rotWeightResAddition(double value) {
rotWeightResAddition = value;
}
public void aggStability(double value) {
aggStability = value;
}
public void crustStability(double value) {
crustStability = value;
}
public void surfRockFrag(double value) {
surfRockFrag = value;
}
public void errosionRate(double value) {
errosionRate = value;
}
public String componentName() {
return componentName;
}
public double fractionSand(int index) {
if ((null != fractionSand) && (index < fractionSand.length)) {
return fractionSand[index];
}
return Double.NaN;
}
public double fractionSilt(int index) {
if ((null != fractionSand) && (index < fractionSilt.length)) {
return fractionSilt[index];
}
return Double.NaN;
}
public double fractionClay(int index) {
if ((null != fractionSand) && (index < fractionClay.length)) {
return fractionClay[index];
}
return Double.NaN;
}
public void componentName(String value) {
componentName = value;
}
public void fractionSand(double[] value) {
fractionSand = value;
}
public void fractionSilt(double[] value) {
fractionSilt = value;
}
public void fractionClay(double[] value) {
fractionClay = value;
}
public void albedo(double value) {
albedo = value;
}
public void slope_gradient(double value) {
slope_gradient = value;
}
public void surface_thickness(int value) {
surface_thickness = value;
}
public void num_layers(int value) {
num_layers = value;
}
public double albedo() {
return albedo;
}
public double slope_gradient() {
return slope_gradient;
}
public int surface_thickness() {
return surface_thickness;
}
public int num_layers() {
return num_layers;
}
public double latitude() {
return latitude;
}
public double longitude() {
return longitude;
}
public String cokey() {
return cokey;
}
public void latitude(double value) {
latitude = value;
}
public void longitude(double value) {
longitude = value;
}
public void cokey(String value) {
cokey = value;
}
public JSONArray toJSON() throws JSONException {
JSONArray ret_val = new JSONArray();
JSONObject results = new JSONObject();
results.put("weps_archive_suid", wepsMetaData.suid());
results.put("annual_precipitation", wepsMetaData.annualPrecip());
results.put("wind_energy", wepsMetaData.windEnergy());
results.put("crust_stability", wepsMetaData.crustStability());
results.put("surface_rock_fragments", wepsMetaData.surfRockFrag());
results.put("aggregate_stability", wepsMetaData.aggStability());
results.put("soil_wilting_poiont", wepsMetaData.soilWiltPoint());
results.put("rotation_weighted_biomass", wepsMetaData.rotWeightResBiomass());
results.put("annual_precipitation", wepsMetaData.annualPrecip());
results.put("rotation_weighted_soil_tillage_intensity", wepsMetaData.rotWeightSoilTillIntensity());
results.put("erosion_rate", wepsMetaData.errosionRate());
ret_val.put(results);
return ret_val;
}
}
}