V1_3_1.java [src/java/m/weps] Revision: 3708c3615b1ff6ac28364436d8f6085c3b09d03d Date: Fri Sep 30 13:45:51 MDT 2016
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package m.weps;
import c.GIS_DB;
import c.GIS_DB.FileQryResult;
import c.GIS_DB_Factory;
import csip.*;
import csip.annotations.*;
import static csip.annotations.ResourceType.*;
import csip.utils.JSONUtils;
import oms3.annotations.*;
import usda.weru.weps.reports.query.WepsConnection;
import wepsreportdata.WepsReportData;
import java.io.*;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.Path;
import man2weps.WepsTranslator;
import man2weps.mcrew.ManageData;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.codehaus.jettison.json.*;
import static util.ErosionConst.*;
import static m.weps.V1_3_1.*;
/**
* WEPS Model Service.
*
* @author wlloyd, od
*/
@Name("WEPS")
@Description("WEPS")
@VersionInfo("1.3")
@Path("m/weps/1.3")
@Polling(first = 25000, next = 2000)
// weps, weps.version is in the csip-conf.file
@Resource(type = EXECUTABLE, file = "/bin/${arch}/${weps.version}/weps.exe", id = WEPS_EXE)
// cligen
@Resource(type = EXECUTABLE, file = "/bin/${arch}/cligen.exe", id = CLIGEN)
@Resource(type = FILE, file = "/data/upd_US_cligen_stations.par", id = STATION_PAR)
// windgen
@Resource(type = EXECUTABLE, file = "/bin/win-x86/wind_gen4.exe", wine = true, id = WINDGEN)
@Resource(type = EXECUTABLE, file = "/bin/${arch}/interpolate.exe", id = INTERPOLATE)
@Resource(type = EXECUTABLE, file = "/bin/${arch}/interp_wdb.exe", id = INTERP_WDB)
@Resource(type = FILE, file = "/data/wind_gen_his_upper_US_NRCS.idx", id = WINDGEN_IDX)
@Resource(type = FILE, file = "/data/wind_gen_his_upper_US.wdb", id = DEFAULT_WIND_STATION_DB)
@Resource(type = FILE, file = "/data/interpolation_boundary.pol", id = BOUNDARY_POL)
// report
@Resource(type = FILE, file = "/data/weps_report.json", id = REPORT_JSON_ID)
// Output
@Resource(type = OUTPUT, file = "stir_energy.out sci_energy.out *stdout.txt *stderr.txt")
public class V1_3_1 extends ModelDataService {
static final String REPORT_JSON_ID = "weps_report";
static final String WEPS_EXE = "weps";
static final String CLIGEN = "cligen";
static final String WINDGEN = "windgen";
static final String INTERPOLATE = "interpolate";
static final String INTERP_WDB = "interp_wdb";
static final String WINDGEN_IDX = "windgen.idx";
static final String BOUNDARY_POL = "boundary.pol";
static final String DEFAULT_WIND_STATION_DB = "wind_gen_his_upper_US.wdb";
static final String STATION_PAR = "station_par";
static final String ROMEDLL = "RomeDLL.dll";
//
// private String binDir = Config.getString("m.bin.dir", "/tmp/csip/bin");
static final String SOIL_FILE_EXT = ".ifc";
static final String WIND_STATIONS_DIR = "windstations";
static final String WIND_STATION_FILE_EXT = ".wdb";
static final String WEPS_MGMT = "wepsmgmt.man";
static final int NRCS_CYCLE_COUNT = 50;
// Variables for WEPS model run
private String soilkey = "";
private String soilfile = "";
private int simulationYears = 3 * NRCS_CYCLE_COUNT;
private JSONObject fieldGeometry = null;
private JsonRegion field_region = null;
private JsonRegion barrier_region = null;
private String soilPtr = "";
private String soilFilename = "";
private String windDbPath = "";
private String sWindgenStation = "";
private boolean cropCalibrationMode = false;
private GIS_DB db = null;
private WepsModelRun wmr = new WepsModelRun();
public WepsOutput wo = new WepsOutput();
private File stdout;
@Override
public void preProcess() throws Exception {
// required parameter - at least one of these must exist!
if (!(JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_SOIL))
&& !(JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_SOIL_FILE))) {
throw new ServiceException("No Value for " + WEPS_KEY_SOIL + " and " + WEPS_KEY_SOIL_FILE + ". At least one is required.");
}
// At least one of the two soil params must be populated
// This version is used by IET
soilkey = getStringParam(WEPS_KEY_SOIL, "");
// This version is used by ZedX
soilfile = getStringParam(WEPS_KEY_SOIL_FILE, "");
wmr.setLat(getStringParam(WEPS_KEY_LATITUDE));
wmr.setLongitude(getStringParam(WEPS_KEY_LONGITUDE));
double fieldLengthInM = getDoubleParam(WEPS_KEY_FIELD_LENGTH) * CONV_FT_TO_M;
if (fieldLengthInM <= 0) {
appendMetainfoWarning(WEPS_FIELD_LENGTH_IS_INVALID);
}
wmr.setSimYLen(String.valueOf(fieldLengthInM));
double fieldWidthInM = getDoubleParam(WEPS_KEY_FIELD_WIDTH) * CONV_FT_TO_M;
if (fieldWidthInM <= 0) {
appendMetainfoWarning(WEPS_FIELD_WIDTH_IS_INVALID);
}
wmr.setSimXLen(String.valueOf(fieldWidthInM));
JSONUtils.checkKeyExists(getParamMap(), WEPS_KEY_MANAGEMENT);
// optional parameter
if (hasParam(WEPS_KEY_ELEVATION)) {
double elevationInM = getDoubleParam(WEPS_KEY_ELEVATION) * CONV_FT_TO_M;
wmr.setElevation(String.valueOf(elevationInM));
} else {
appendMetainfoWarning(WEPS_ELEVATION_DEFAULT_USED);
}
if (hasParam(WEPS_KEY_WATER_EROSION_LOSS)) {
double waterErosionLoss = getDoubleParam(WEPS_KEY_WATER_EROSION_LOSS) * CONV_TONACRE_TO_KGM2;
wmr.setWaterErosionLoss(String.valueOf(waterErosionLoss));
}
if (hasParam(WEPS_KEY_FIELD_ORIENTATION)) {
double fieldOrient = getDoubleParam(WEPS_KEY_FIELD_ORIENTATION);
wmr.setSimRegionAngle(String.valueOf(fieldOrient));
}
if (hasParam(WEPS_KEY_SOIL_ROCK_FRAGMENTS)) {
double rockFragments = getDoubleParam(WEPS_KEY_SOIL_ROCK_FRAGMENTS);
wmr.setSoilRockFragments(String.valueOf(rockFragments));
}
if (hasParam(WEPS_KEY_CROP_CALIBRATION_MODE)) {
cropCalibrationMode = getBooleanParam(WEPS_KEY_CROP_CALIBRATION_MODE);
}
if (hasParam(WEPS_FIELD_BOUNDARY)) {
appendMetainfoWarning(WEPS_FIELD_BOUNDARY_IGNORED);
}
}
@Override
protected void doProcess() throws Exception {
try {
db = GIS_DB_Factory.createGISEngine();
} catch (Exception e) {
LOG.severe("Error obtaining DB connection in WEPS run!");
throw new ServiceException("WEPS error: Cannot obtain geospatial db connection");
}
try {
// get the mgmt as a json obj and create a WEPS man file using Jim's parser
String error = loadWepsMgmt();
if (error != null) {
LOG.info("ERROR: " + error);
throw new ServiceException(error);
}
// get wind barriers
getWindBarriers();
// Get climate info
getClimate();
// Get wind info
generateWindData();
// Get soils data
getSoilIfc();
// The WEPS GUI requires an empty notes.txt file per LEW to run
FileUtils.writeStringToFile(new File(getWorkspaceDir(), "notes.txt"), "");
// Always generate Weps Run file from JSON parameters (it is never provided in the model srvc signature)
LOG.info("creating wepsrun file.");
WepsRunFileGenerator.GenerateWepsRunFile(wmr, getWorkspaceDir().toString(), "weps.run");
LOG.info("starting weps process");
// run WEPS model
// model call uses the following cmd line args
// /weps -W1 -u0 -I2 -t1 -P./ >stdout.txt 2>stderr.txt
Executable exe = getResourceExe(WEPS_EXE);
exe.setArguments("-W1", "-u0", "-I2", "-t1", "-T1", "-P./");
if (cropCalibrationMode) {
// C15 tells WEPS to perform up to 15 calibration cycles for convergence, could do fewer cycles
// Z50 is required with calibration flag
exe.addArguments("-C15", "-Z50");
}
stdout = exe.stdout();
boolean handleProgress = Config.getBoolean("weps.progress", false);
if (handleProgress) {
exe.setStdoutHandler(new Executable.StdHandler() {
@Override
public void handle(String out) {
if (out == null)
return;
int idx = out.lastIndexOf("Year");
if (idx > -1) {
try {
String a = out.substring(idx, out.indexOf('\n', idx));
setProgress(a);
} catch (ServiceException ex) {
System.out.println("Error setting progress info.");
}
}
}
});
}
int result = exe.exec();
if (result != 0) {
throw new ServiceException("WEPS exit error :" + result);
}
// Check standard out for "inpsub" error - occurs when no soil file is available
if (exe.stdout().exists()) {
String out = FileUtils.readFileToString(exe.stdout());
if (out.contains("inpsub error")) {
throw new ServiceException("Error in WEPS--Standard output:" + out);
}
}
} catch (Exception e) {
LOG.log(Level.SEVERE, "ERROR EXECUTING WEPS", e);
throw e;
}
}
// @Override
// protected void postProcess() throws Exception {
// putResult(new File(getWorkspaceDir(), "stir_energy.out"));
// putResult(new File(getWorkspaceDir(), "sci_energy.out"));
// putResult(new File(getWorkspaceDir(), WEPS_EXE + "-stdout.txt"));
// putResult(new File(getWorkspaceDir(), WEPS_EXE + "-stderr.txt"));
// }
/////////////////////////////////////////////////////////////////////////////
/*
*/
private String loadWepsMgmt() throws ServiceException {
String error = null;
try {
LOG.info("WEPS MGMT exisitence check=" + JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_MANAGEMENT));
if (JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_MANAGEMENT)) {
LOG.info("Attempting to translate WEPS management JSON from LMOD to MAN file");
JSONObject mgmt = JSONUtils.getJSONObjectParam(getParamMap(), WEPS_KEY_MANAGEMENT);
WepsTranslator translator = new WepsTranslator();
translator.setConfigFilename("config/mcrew_start.xml");
translator.setInputManType(ManageData.InputManType.READ_LMOD_MAN_JSON);
translator.setOutputMan(true);
org.json.JSONObject mgmtObj = new org.json.JSONObject(mgmt.toString());
translator.setInputJSONObject(mgmtObj);
translator.setOutputFilename(getWorkspaceDir().toString() + "/" + WEPS_MGMT);
LOG.log(Level.INFO, "input filename =" + translator.getInputFilename());
LOG.log(Level.INFO, "output filename =" + translator.getOutputFilename());
LOG.log(Level.INFO, "rotation years =" + translator.getRotationYears());
LOG.log(Level.INFO, "JSON to translate=" + translator.getInputJSONObject());
try {
error = translator.Translate();
LOG.log(Level.INFO, "OUTPUT FROM THE TRANSLATOR ='" + error + "'");
if (error != null) {
try {
if (Integer.parseInt(error) != 1) {
LOG.log(Level.SEVERE, "THERE IS AN ERROR CODE RETURNED FROM THE MAN2WEPS TRANSLATOR. Code=" + error);
}
} catch (NumberFormatException ex) { // I want to transition the numeric errors to string errors like this
LOG.log(Level.SEVERE, "THERE IS AN ERROR: " + error);
}
}
} catch (Exception e) {
LOG.log(Level.SEVERE, "FLAT UP EXPLOSION FROM THE WEPS TRANSLATOR:", e);
throw new ServiceException("LMOD management translation error executing WEPS", e);
//return WEPS_ERROR_LMOD_TRANSLATION_ERROR;
}
// Set these values no matter what
wmr.setRunCycle(Integer.toString(translator.getRotationYears()));
LOG.log(Level.INFO, "*****************************************************set run cycle=" + wmr.getRunCycle());
simulationYears = Integer.parseInt(wmr.getRunCycle()) * NRCS_CYCLE_COUNT;
wmr.setNumYears(Integer.toString(simulationYears));
}
} catch (Exception e) {
LOG.log(Level.SEVERE, "LMOD TRANSLATOR ERROR:", e);
throw new ServiceException("WEPS error: error translating WEPS mgmt from LMOD.", e);
}
LOG.log(Level.INFO, "*****************************************************LEAVING loadWepsMgmt");
LOG.log(Level.INFO, "*****************************************************set run cycle=" + wmr.getRunCycle());
LOG.log(Level.INFO, "*****************************************************set num years=" + wmr.getNumYears());
return error;
}
private void getWindBarriers() throws ServiceException {
try {
String barrierdir = "";
if (JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_BARRIERS)) {
JSONArray barriers = JSONUtils.getJSONArrayParam(getParamMap(), WEPS_KEY_BARRIERS);
if ((barriers != null) && (barriers.length() > 0)) {
LinkedList<Barrier> lstBarriers = new LinkedList<Barrier>();
for (int i = 0; i < barriers.length(); i++) {
Barrier b = new Barrier();
JSONObject barrier = barriers.getJSONObject(i);
LOG.info("barrier obj " + i + "=" + barrier.toString());
JSONObject barriervalue = barrier.optJSONObject("value");
if (barriervalue != null) {
JSONObject lmodfile = barriervalue.optJSONObject("lmod_file");
JSONObject properties = barrier.optJSONObject("properties");
JSONObject barrierGeometry = barrier.optJSONObject(WEPS_GEOMETRY); // pass to Jim's code
if (barrierGeometry != null) {
LOG.info("barrier geometry=" + barrierGeometry.toString());
String barrier_json_in = barrierGeometry.toString();
org.json.JSONTokener barrier_json_tok = new org.json.JSONTokener(barrier_json_in);
org.json.JSONObject barrier_json_object = new org.json.JSONObject(barrier_json_tok);
barrier_region = new JsonRegion(barrier_json_object);
}
// Get barrier values from lmod mgmt json first
LOG.info("lmodfile obj=" + lmodfile.toString());
JSONObject barrierParamObj = lmodfile.optJSONObject("params");
b.type = lmodfile.getString("name");
LOG.info("barrierParamObj=" + barrierParamObj.toString());
JSONArray barrierParams = barrierParamObj.optJSONArray("param");
LOG.info("barrierParams array=" + barrierParams.toString());
for (int j = 0; j < barrierParams.length(); j++) {
JSONObject barrierp = barrierParams.getJSONObject(j);
LOG.info("barrierparam[" + j + "]=" + barrierp.toString());
String thisparam = barrierp.getString("name");
if (thisparam.equals(WEPS_BARRIERPARAM_WIDTH)) {
b.width = trimBrackets(barrierp.getString("data"));
}
if (thisparam.equals(WEPS_BARRIERPARAM_HEIGHT)) {
b.height = trimBrackets(barrierp.getString("data"));
}
if (thisparam.equals(WEPS_BARRIERPARAM_NUM_ROWS)) {
b.number = trimBrackets(barrierp.getString("data"));
}
if (thisparam.equals(WEPS_BARRIERPARAM_POROSITY)) {
b.porosity = trimBrackets(barrierp.getString("data"));
}
}
// check if barrier geometry is available and if so prefer these values instead
//if (field_region != null)
if (barrier_region != null) {
LOG.info("barrier_region obj=" + barrier_region.toString());
barrierdir = barrier_region.getCompassDir(field_region);
b.height = String.valueOf(barrier_region.getHeight());
b.width = String.valueOf(barrier_region.getWidth());
} else {
// The weps barrier location (n s e w) is described based on how coordinates are specified
barrierdir = properties.getString("placement");
}
if (barrierdir.equals(WEPS_BARRIER_NORTH)) {
b.x1 = "0";
b.y1 = wmr.getSimYLen();
b.x2 = wmr.getSimXLen();
b.y2 = Double.toString(Double.parseDouble(wmr.getSimYLen()) + Double.parseDouble(b.width));
}
if (barrierdir.equals(WEPS_BARRIER_SOUTH)) {
b.x1 = "0";
b.y1 = Double.toString(-Double.parseDouble(b.width));
b.x2 = wmr.getSimXLen();
b.y2 = "0";
}
if (barrierdir.equals(WEPS_BARRIER_EAST)) {
b.x1 = wmr.getSimXLen();
b.y1 = "0";
b.x2 = Double.toString(Double.parseDouble(wmr.getSimXLen()) + Double.parseDouble(b.width));
b.y2 = wmr.getSimYLen();
}
if (barrierdir.equals(WEPS_BARRIER_WEST)) {
b.x1 = Double.toString(-Double.parseDouble(b.width));
b.y1 = "0";
b.x2 = "0";
b.y2 = wmr.getSimYLen();
}
lstBarriers.add(b);
}
}
wmr.setNumBarriers(Integer.toString(lstBarriers.size()));
for (int ij = 0; ij < Integer.parseInt(wmr.getNumBarriers()); ij++) {
Barrier b = lstBarriers.get(ij);
LOG.info("Barrier #" + ij + " x1=" + b.x1 + " x2=" + b.x2 + " y1=" + b.y1 + " y2=" + b.y2 + " width=" + b.width + " height=" + b.height + " number=" + b.number + " type=" + b.type + " porosity=" + b.porosity);
}
// A blank dummy barrier is required in the weps.run file if there are none
if (lstBarriers.size() == 0) {
LOG.info("THIS WEPS RUN HAS NO BARRIERS!");
Barrier b = new Barrier();
lstBarriers.add(b);
}
wmr.setBarriers(lstBarriers);
}
}
} catch (Exception e) {
// Handle error in processing barriers
LOG.log(Level.SEVERE, "Error with wind barriers: ", e);
throw new ServiceException("WEPS error: error processing wind barriers information: ", e);
}
}
private void getClimate() throws ServiceException {
try {
double latitude = Double.parseDouble(wmr.getLat());
double longitude = Double.parseDouble(wmr.getLongitude());
GIS_DB.StationResult cligenStation = null;
// check if the field lat/long intersects any cli station geometries first- and use it if so
GIS_DB.StationResult cliStation = db.cliGeomIntersect(latitude, longitude);
if (cliStation != null) {
LOG.info("The cliStation name is '" + cliStation.name + "'");
if (cliStation.name.contentEquals("Out")) {
// in the mountain west polygon - use the nearest cligen station
cligenStation = db.findCligenStation(latitude, longitude);
LOG.info("***************************************************************set cligen station 1=" + cligenStation.name);
} else {
// use the cli station found by intersecting the climate station geometries
cligenStation = cliStation;
LOG.info("***************************************************************set cligen station 2=" + cligenStation.name);
}
} else {
// get climate station for this lat / long
LOG.info("FIND NEAREST CLIGEN STATION!");
LOG.info("lat=" + wmr.getLat());
LOG.info("long=" + wmr.getLongitude());
// not in the mountain west polygon, did not intersect any climate station, use the nearest station
cligenStation = db.findCligenStation(Double.parseDouble(wmr.getLat()), Double.parseDouble(wmr.getLongitude()));
LOG.info("***************************************************************set cligen station 3=" + cligenStation.name);
}
// generate cli file using this station
LOG.info("***************************************************************using cligen station=" + cligenStation.name);
if (wmr.getElevation().equals(WepsModelRun.UNSET_ELEVATION)) {
wmr.setElevation(cligenStation.elevation);
}
// populate cli gen station parameters in weps.run file
wmr.setCliStationLong(cligenStation.stationX);
wmr.setCliStationLat(cligenStation.stationY);
wmr.setCliStationStateFips(cligenStation.state);
wmr.setCliStationC1(cligenStation.stationId);
wmr.setCliStationName(cligenStation.name);
wmr.setCliStationEleM(cligenStation.elevation);
// ProcessComponent pcCliGen = new ProcessComponent();
// pcCliGen.working_dir = getWorkspaceDir().toString();
// LOG.info("extract cligen to:/bin/" + Binaries.getArch());
// pcCliGen.exe = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/cligen", new File(binDir)).toString();
// LOG.info("extract climate db");
// String dbpath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/upd_US_cligen_stations.par", new File(binDir)).toString();
// pcCliGen.args = new String[]{"-S" + cligenStation.state, "-s" + cligenStation.stationId, "-i" + dbpath,
// "-t5", "-I3", "-F", "-b01", "-y" + simulationYears, "-o" + getWorkspaceDir().toString() + "/cli_gen.cli"};
// LOG.log(Level.INFO, "cligen args=" + pcCliGen.args.toString());
// pcCliGen.execute();
String dbpath = getResourceFile(STATION_PAR).toString();
Executable cligen = getResourceExe(CLIGEN);
cligen.setArguments("-S" + cligenStation.state, "-s" + cligenStation.stationId, "-i" + dbpath,
"-t5", "-I3", "-F", "-b01", "-y" + simulationYears, "-o" + getWorkspaceDir().toString() + "/cli_gen.cli");
int ret = cligen.exec();
if (ret != 0) {
throw new ServiceException("WEPS error: cligen execution failed :" + ret);
}
// prefer lat/long generated climates file for weps run
//wmr.cliFile = "cligen.cli";
} catch (Exception e) {
LOG.log(Level.SEVERE, "Error", e);
throw new ServiceException("WEPS error: error generating climate data:" + e.toString());
}
}
private void generateWindData() throws ServiceException {
try {
boolean bInterpolatedWind = false;
GIS_DB.County wepsCounty = null;
GIS_DB.StationResult windStationForWepsRunFile = null;
wmr.setWinFile("win_gen.win");
sWindgenStation = null;
// Always generate wind data for lat / long using wingen and possible interpolate program
double latitude = Double.parseDouble(wmr.getLat());
double longitude = Double.parseDouble(wmr.getLongitude());
// check if the field lat/long intersects any wind station geometries first- and use it if so
GIS_DB.StationResult windStation = db.windGeomIntersect(latitude, longitude);
if (windStation != null) {
LOG.info("The intersected windStation name is '" + windStation.name + "'");
// Check for Out or INT polygons - these are not wind stations, just filler polygons
if ((windStation.name.contentEquals("Out")) || (windStation.name.contentEquals("INT"))) {
sWindgenStation = null;
} else {
sWindgenStation = windStation.stationId.trim();
windStationForWepsRunFile = windStation;
// windDbPath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/" + DEFAULT_WIND_STATION_DB, new File(binDir)).toString();
windDbPath = getResourceFile(DEFAULT_WIND_STATION_DB).toString();
}
}
// Do we still need to populate the windgen station???
if (sWindgenStation == null) {
// next check if in the interpolation boundary shape, if so, interpolate 3 nearest wind stations
// to generate an interpolated station
LOG.log(Level.INFO, "Check if lat/long is in interpolation boundary");
if (db.IsInInterpolateBoundary(latitude, longitude)) {
LOG.log(Level.INFO, "YES! lat/long is in interpolation boundary");
// Generate wind station interpolation
wmr.setWinFile("interpolate.win");
// Generate weights file
// ProcessComponent pcInterpolate = new ProcessComponent();
// linux
// String exepath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/interpolate", new File(binDir)).toString();
// String dbpath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/wind_gen_his_upper_US_NRCS.idx", new File(binDir)).toString();
// String polygon = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/interpolation_boundary.pol", new File(binDir)).toString();
// Get the county centroid for wind interpolation
wepsCounty = db.countyCentroid(latitude, longitude);
// Generate shell script to invoke interpolate
// File interpolatesh = new File(getWorkspaceDir(), "interpolate.sh");
NumberFormat nf = DecimalFormat.getInstance();
int windInterpolationDecimalDigits = Config.getInt("weps.wind_interpolate_precision", 2);
nf.setMaximumFractionDigits(windInterpolationDecimalDigits);
nf.setMinimumFractionDigits(windInterpolationDecimalDigits);
nf.setRoundingMode(RoundingMode.HALF_UP);
double countyCentroidLat = Double.parseDouble(wepsCounty.county_centroid_Y);
double countyCentroidLon = Double.parseDouble(wepsCounty.county_centroid_X);
LOG.log(Level.INFO, "***county centroid lat=" + countyCentroidLat + " lon=" + countyCentroidLon);
// linux
// String invokeInterpolate = exepath + " -f " + dbpath + " -p " + polygon + " -lat " + nf.format(countyCentroidLat) + " -long " + nf.format(countyCentroidLon);
// FileUtils.writeStringToFile(interpolatesh, invokeInterpolate);
// interpolatesh.setExecutable(true);
// pcInterpolate.working_dir = getWorkspaceDir().toString();
// pcInterpolate.exe = "./interpolate.sh";
// pcInterpolate.args = new String[]{};
// pcInterpolate.execute();
String dbpath = getResourceFile(WINDGEN_IDX).toString();
String polygon = getResourceFile(BOUNDARY_POL).toString();
Executable interpolate = getResourceExe(INTERPOLATE);
interpolate.setArguments("-f", dbpath, "-p", polygon, "-lat", nf.format(countyCentroidLat), "-long", nf.format(countyCentroidLon));
int ret = interpolate.exec();
if (ret != 0) {
throw new ServiceException(" Interpolation execution failed: " + ret);
}
// Added small delay because occasionally the stdout was incomplete upon parsing
Thread.sleep(300);
bInterpolatedWind = true;
WeightsParser wp = new WeightsParser();
// wp.weightsFile = pcInterpolate.stdout;
wp.weightsFile = FileUtils.readFileToString(interpolate.stdout());
// wp.exitValue = pcInterpolate.exitValue;
wp.exitValue = ret;
// wp.weightsErr = pcInterpolate.stderr;
wp.weightsErr = FileUtils.readFileToString(interpolate.stderr());
// LOG.info("exit value from pcInterpolate execution=" + pcInterpolate.exitValue);
// must process this monstrosity
wp.parse();
if ((wp.station1 > 0) & (wp.station2 > 0) && (wp.station3 > 0)) {
// If there are wind stations then, generate interpolate wind station wdb file
// Note the interp_wdb program is ancient Fortran and can not handle file paths of any length
// therefore everything has to be extracted to the workdir and done locally there.
// This is BAD (inefficient) because it is extra work to always extract wind station wdb's for every model run!
// ProcessComponent pcInterpWdb = new ProcessComponent();
// linux
// exepath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/interp_wdb", new File(binDir)).toString();
// String station1Db = BinUtils.unpackResourceAbsolute("/bin/" + BinUtils.getArch() + "/windstations/" + wp.station1 + ".wdb", sessionWorkDir + "/" + wp.station1 + ".wdb").toString();
// String station2Db = BinUtils.unpackResourceAbsolute("/bin/" + BinUtils.getArch() + "/windstations/" + wp.station2 + ".wdb", sessionWorkDir + "/" + wp.station2 + ".wdb").toString();
// String station3Db = BinUtils.unpackResourceAbsolute("/bin/" + BinUtils.getArch() + "/windstations/" + wp.station3 + ".wdb", sessionWorkDir + "/" + wp.station3 + ".wdb").toString();
String station1Db = getWindStationFile(wp.station1);
String station2Db = getWindStationFile(wp.station2);
String station3Db = getWindStationFile(wp.station3);
// Generate shell script to invoke interpolate
// File interpwdbsh = new File(getWorkspaceDir(), "interpwdb.sh");
// interpwdbsh.setExecutable(true);
// windows
//String invokeInterpWdb = "wine " + exepath + " test.wdb" + " " + station1Db + wp.weight1 + " " + station2Db + wp.weight2 + " " + station3Db + wp.weight3;
// linux
// String invokeInterpWdb = exepath + " test.wdb" + " " + station1Db + wp.weight1 + " " + station2Db + wp.weight2 + " " + station3Db + wp.weight3;
// FileUtils.writeStringToFile(interpwdbsh, invokeInterpWdb);
// pcInterpWdb.working_dir = getWorkspaceDir().toString();
// pcInterpWdb.exe = "./interpwdb.sh";
// pcInterpWdb.args = new String[]{};
// pcInterpWdb.execute();
Executable interp_wdb = getResourceExe(INTERP_WDB);
interp_wdb.setArguments("test.wdb", station1Db, wp.weight1, station2Db, wp.weight2, station3Db, wp.weight3);
ret = interp_wdb.exec();
if (ret != 0) {
throw new ServiceException("Error executing interp_wdb " + ret);
}
windDbPath = "test.wdb";
sWindgenStation = "999999"; // this is the magic number indicating its an interpolated wind station!
}
// for wind interpolation, report the nearest wind gen station in the weps.run file for now
// check with Fred to verify if this is correct behavior for the weps gui
windStationForWepsRunFile = db.findWindgenStation(Double.parseDouble(wmr.getLat()), Double.parseDouble(wmr.getLongitude()));
// to do
// in this case, we are getting the wind gen station from the "wingen_stations" table which does not provide
// lat long values, so we are using the model run's coordinates. We will need to include wind gen station coordinate data
// in the database in order to provide it.
windStationForWepsRunFile.stationX = wmr.getLongitude();
windStationForWepsRunFile.stationY = wmr.getLat();
}
// otherwise, just use data from nearest wind station:
// If this is not using an interpolated wind station, then use the default closest one...
if (windDbPath.length() == 0) {
LOG.log(Level.INFO, "NO! lat/long is NOT in interpolation boundary");
// get wind generation station for this lat / long
LOG.info("FIND NEAREST WIND STATION!");
LOG.info("lat=" + wmr.getLat());
LOG.info("long=" + wmr.getLongitude());
GIS_DB.StationResult windgenStation = db.findWindgenStation(Double.parseDouble(wmr.getLat()), Double.parseDouble(wmr.getLongitude()));
LOG.info("windgen station is=" + windgenStation.stationId);
sWindgenStation = windgenStation.stationId.trim();
windStationForWepsRunFile = windgenStation;
// to do
// in this case, we are getting the wind gen station from the "wingen_stations" table which does not provide
// lat long values, so we are using the model run's coordinates. We will need to include wind gen station coordinate data
// in the database in order to provide it.
windStationForWepsRunFile.stationX = wmr.getLongitude();
windStationForWepsRunFile.stationY = wmr.getLat();
// windDbPath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/" + DEFAULT_WIND_STATION_DB, new File(binDir)).toString();
windDbPath = getResourceFile(DEFAULT_WIND_STATION_DB).toString();
}
}
// populate wind gen station parameters in the weps.run file
wmr.setWinWindLat(windStationForWepsRunFile.stationY);
wmr.setWinWindLong(windStationForWepsRunFile.stationX);
wmr.setWinWindStation(windStationForWepsRunFile.stationId);
wmr.setWinWindCountry(windStationForWepsRunFile.country);
wmr.setWinWindState(windStationForWepsRunFile.state);
wmr.setWinWindStationName(windStationForWepsRunFile.name);
wmr.setWinWindDescriptionString("|" + wmr.getWinWindStation() + "|" + wmr.getWinWindCountry() + "|" + wmr.getWinWindState() + "|" + wmr.getWinWindStationName());
// make adjustments if wind is interpolated in weps.run
if (bInterpolatedWind) {
wmr.setWinWindGenProgram("interpolated");
if (wepsCounty != null) {
wmr.setWinWindLat(wepsCounty.county_centroid_Y);
wmr.setWinWindLong(wepsCounty.county_centroid_X);
}
LOG.log(Level.INFO, "*******************************************WIND IS INTERPOLATED-SETTING DESC STRING TO EMPTY!");
wmr.setWinWindDescriptionString("");
}
// populate state and county code params in the weps.run file
GIS_DB.County cnty = db.findCounty(latitude, longitude);
wmr.setStateSite(cnty.st_abbr);
wmr.setCountySite(cnty.county_code);
LOG.log(Level.INFO, "*******************************************AS SET IN WMR county site=" + wmr.getCountySite());
LOG.log(Level.INFO, "*******************************************AS SET IN WMR state site=" + wmr.getStateSite());
// generate win file using this station (or interpolated one)
// ProcessComponent pcWindGen = new ProcessComponent();
// String winexepath = Binaries.unpackResource("/bin/win-x86/wind_gen4.exe", new File(binDir)).toString();
LOG.log(Level.INFO, "Using wind database:" + windDbPath);
// Generate shell script to invoke windgen
// File windgensh = new File(getWorkspaceDir(), "windgen.sh");
//String invokeWinGen = exepath + " -f " + windDbPath + " -b 01 -y " + simulationYears + " -o thewind.win -s " + sWindgenStation;
// String invokeWinGen = "wine " + winexepath + " -f " + windDbPath + " -b 01 -y " + simulationYears + " -o " + wmr.getWinFile() + " -s " + sWindgenStation;
// FileUtils.writeStringToFile(windgensh, invokeWinGen);
// windgensh.setExecutable(true);
// pcWindGen.working_dir = getWorkspaceDir().toString();
// String cmd = "./windgen.sh";
// pcWindGen.args = new String[]{};
// pcWindGen.exe = cmd;
// pcWindGen.execute();
Executable windgen = getResourceExe(WINDGEN);
// no need to set the wine argument. It is done in the resource definition.
windgen.setArguments("-f", windDbPath, "-b", "01", "-y", simulationYears, "-o", wmr.getWinFile(), "-s", sWindgenStation);
int ret = windgen.exec();
if (ret != 0) {
throw new ServiceException(" error executing windgen: " + ret);
}
//wmr.winFile = "thewind.win";
} catch (Exception e) {
throw new ServiceException("WEPS error: error generating wind data", e);
}
}
private String getWindStationFile(int windStationId) throws ServiceException {
String wepsdb = Config.getString("weps.db", "http://oms-db.engr.colostate.edu/weps");
String windStation = WIND_STATIONS_DIR + "/" + windStationId + WIND_STATION_FILE_EXT;
// Get wind station file and write to temp space
String fileToGet = wepsdb + "/" + windStation;
LOG.log(Level.INFO, "wind station file to get=" + fileToGet);
getFile(fileToGet, windStationId + WIND_STATION_FILE_EXT);
// Return file name of retrieved wind station
// An extra space is appended for interp_wdb.exe use on command line
wmr.setSoilFile(windStationId + WIND_STATION_FILE_EXT + " ");
return wmr.getSoilFile();
}
private void getSoilIfc() throws ServiceException {
String wepsdb = Config.getString("weps.db", "http://oms-db.engr.colostate.edu/weps");
GIS_DB.FileQryResult soil = null;
try {
// Use user provided soil key to look up and acquire soils file
LOG.log(Level.INFO, "WEPS soilkey=" + soilkey);
LOG.log(Level.INFO, "WEPS soilfile=" + soilfile);
if ((soilfile == null) || ((soilfile != null) && (soilfile.length() < 1))) {
LOG.log(Level.INFO, "Not using WEPS soilfile pointer for soil");
if (db != null) {
LOG.log(Level.INFO, "Get WEPS soils using database");
if ((soilkey != null) && (soilkey.length() > 0)) {
LOG.log(Level.INFO, "USING provided WEPS soil component key=" + soilkey);
soil = db.findSoilsWepsByCokey(soilkey, Double.parseDouble(wmr.getLongitude()));
} else {
LOG.log(Level.INFO, "Attempting to resolve WEPS soil by lat=" + wmr.getLat() + " and long=" + wmr.getLongitude());
soil = db.findSoilsWeps(Double.parseDouble(wmr.getLat()), Double.parseDouble(wmr.getLongitude()));
}
if (soil == null) {
LOG.log(Level.WARNING, "No soil for lat=" + wmr.getLat() + "\nfor long=" + wmr.getLongitude() + "\n");
soilPtr = "";
if ((soilkey != null) && (soilkey.length() > 0)) {
throw new ServiceException("WEPS error: no soil available for cokey");
} else {
throw new ServiceException("WEPS error: no soil available for provided lat/long coordinates");
}
} else {
soilPtr = soil.file_path + "/" + soil.file_name + SOIL_FILE_EXT;
}
}
} else {
// use provided soil file pointer
LOG.log(Level.INFO, "USING provided WEPS soil ptr=" + soilPtr);
soilPtr = soilfile + SOIL_FILE_EXT;
File soil_file = new File(soilfile);
soil = new FileQryResult();
soil.file_name = soil_file.getName();
soil.file_path = soil_file.getAbsolutePath();
}
// Get soil file and write to temp space
String fileToGet = wepsdb + "/" + soilPtr;
LOG.log(Level.INFO, "soils file to get=" + fileToGet);
LOG.log(Level.INFO, "soils file name=" + soil.file_name);
LOG.log(Level.INFO, "soils file path=" + soil.file_path);
getFile(fileToGet, soil.file_name + SOIL_FILE_EXT);
// Prefer lat/long retrieved soils file
wmr.setSoilFile(soil.file_name + SOIL_FILE_EXT);
} catch (Exception e) {
throw new ServiceException("WEPS error: error retrieiving soil data", e);
}
}
private void getFile(String url, String filename) throws ServiceException {
FileOutputStream fos = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
HttpResponse response = client.execute((HttpUriRequest) httpget);
byte[] soilData = IOUtils.toByteArray(response.getEntity().getContent());
fos = new FileOutputStream(new File(getWorkspaceDir(), filename));
fos.write(soilData);
} catch (IOException ie) {
LOG.log(Level.SEVERE, "ERROR GETTING SOILS IFC FILE!:" + ie.toString());
throw new ServiceException(ie);
} finally {
if (fos != null) {
try {
fos.close();
} catch (Exception fe) {
}
}
}
}
private String trimBrackets(String sText) {
return sText.substring(1, sText.length() - 1);
}
@Override
public JSONArray createResults() throws Exception {
LOG.info("Create the WEPS results...");
JSONArray results = new JSONArray();
String outUrl = Config.getString("m.results.url", "http://localhost:8084/csip/q/");
BufferedReader bfr = new BufferedReader(new FileReader(new File(getWorkspaceDir(), "sci_energy.out")));
String sciEnergyOut = "";
while (bfr.ready()) {
sciEnergyOut += bfr.readLine();
}
bfr.close();
wo = SciEnergyParser.parseSciEnergyFile(sciEnergyOut);
if (wo.bNaN) {
appendMetainfoWarning(WEPS_FOUND_NAN_IN_OUTPUT);
}
getAdvancedOutput(wo);
// Special unit conversions for Phacil
double dieselEnergy_gallonsPerAcre = Double.parseDouble(wo.dieselEnergy) * CONV_LITERHECTATRE_TO_GALLONACRE;
double averageBiomass_tonAcreYear = Double.parseDouble(wo.averageBiomass) * CONV_KGM2_TONACRE;
double windEros_tonAcreYear = Double.parseDouble(wo.windEros) * CONV_KGM2_TONACRE;
double waterEros_tonAcreYear = Double.parseDouble(wo.waterEros) * CONV_KGM2_TONACRE;
results.put(JSONUtils.dataDesc(WEPS_RES_SOIL_COND_INDEX, wo.soilConditioningIndex, "total SCI (soil conditioning index)"));
results.put(JSONUtils.dataDesc(WEPS_RES_SCI_OM_FACTOR, wo.sciOmFactor, "SCI Organic Matter subfactor"));
results.put(JSONUtils.dataDesc(WEPS_RES_SCI_ER_FACTOR, wo.sciErFactor, "SCI Erosion Rate subfactor"));
results.put(JSONUtils.dataDesc(WEPS_RES_SCI_FO_FACTOR, wo.sciFoFactor, "SCI Field Operations subfactor"));
results.put(JSONUtils.dataUnitDesc(WEPS_RES_DIESEL_ENERGY, dieselEnergy_gallonsPerAcre, "gallon(Diesel)/acre", "energy used by management operations, expressed as fuel consumption equivalent"));
results.put(JSONUtils.dataUnitDesc(WEPS_RES_AVG_BIOMASS, averageBiomass_tonAcreYear, "ton/acre/year", "Average biomass"));
results.put(JSONUtils.dataUnitDesc(WEPS_RES_WIND_EROS, windEros_tonAcreYear, "ton/acre/year", "Wind erosion (computed by WEPS)"));
results.put(JSONUtils.dataUnitDesc(WEPS_RES_WATER_EROS, waterEros_tonAcreYear, "ton/acre/year", "Water erosion (external input)"));
results.put(JSONUtils.dataDesc(WEPS_RES_AVG_ALL_STIR, wo.avgAllStir, "Average STIR"));
results.put(JSONUtils.data(WEPS_SALTATION, wo.saltation));
results.put(JSONUtils.data(WEPS_SUSPENSION, wo.suspension));
results.put(JSONUtils.data(WEPS_PM10, wo.pm10));
return results;
}
private void getAdvancedOutput(WepsOutput wOutput) throws JSONException, Exception {
JSONArray reportItems = new JSONArray();
JSONObject item = new JSONObject();
JSONArray report;
Map<String, JSONObject> reportValues;
JSONArray suspen;
JSONArray salt;
JSONArray pm10;
item.put("name", "output.suspen");
reportItems.put(item);
item = new JSONObject();
item.put("name", "output.crp_salt");
reportItems.put(item);
item = new JSONObject();
item.put("name", "output.pm10");
reportItems.put(item);
report = createReport(reportItems);
reportValues = JSONUtils.preprocess(report);
suspen = JSONUtils.getJSONArrayParam(reportValues, "output.suspen");
salt = JSONUtils.getJSONArrayParam(reportValues, "output.crp_salt");
pm10 = JSONUtils.getJSONArrayParam(reportValues, "output.pm10");
wo.suspension = suspen.getString(suspen.length() - 1);
wo.saltation = salt.getString(salt.length() - 1);
wo.pm10 = pm10.getString(pm10.length() - 1);
}
@Override
protected JSONArray createReport() throws Exception {
String workDir = getWorkspaceDir().toString();
File reportTemplate = getResourceFile(REPORT_JSON_ID);
String sReportJSON = FileUtils.readFileToString(reportTemplate);
//JSONObject reportObj = new JSONObject(sReportJSON);
//JSONArray reportItems = reportObj.getJSONArray("WEPSreport");
JSONArray reportItems = new JSONArray(sReportJSON);
WepsConnection con = new WepsConnection();
// Create an instance of this class to do the actual loading.
WepsReportData reportdata = new WepsReportData(con);
// Set the location of the folder to translate files in.
String sInputDirectory = workDir;
if (!reportdata.setInputDirectory(sInputDirectory)) {
// Print a usage message and quit
LOG.severe("error: WEPS reports input directory doesn't exist.");
throw new ServiceException("Error create WEPS reports. Report directory does not exist.");
}
// @todo set configuration options.
reportdata.m_sUnits = "US";
// Load the file data.
LOG.info("WorkingDir: " + getWorkspaceDir().toString());
//reportdata.loadFiles(getWorkspaceDir().toString());
reportdata.loadFiles(getWorkspaceDir().toString(), stdout.getName());
// // Dump the loaded data as text for debugging purposes.
// LOG.info("hash map output=" + con.toString());
//
// LOG.info("Original Report JSON obj=" + reportObj.toString());
HashMap<String, ArrayList<Object>> m_reportdata = con.getParamValues();
for (int i = 0; i < reportItems.length(); i++) {
JSONObject obj = (JSONObject) reportItems.get(i);
String itemName = obj.getString(REPORT_NAME);
//LOG.info("COMPARISON for scalars: itemname='" + itemName + "'");
//if (itemName.length() >= 5) LOG.info("COMPARISON for scalars: itemname 0,5='" + itemName.substring(0,5) + "'");
//if (itemName.length() >= 11) LOG.info("COMPARISON for scalars: itemname 0,11='" + itemName.substring(0,11) + "'");
LOG.info("Trying report value: " + itemName);
if ((itemName != null) && ((((itemName.length()) >= 5) && (itemName.substring(0, 5).contentEquals("runs.")))
|| (((itemName.length()) >= 11) && (itemName.substring(0, 11).contentEquals("sci_energy."))))) {
// Scalar values
//LOG.info("look up " + itemName + " in report hash table for scalar output.");
ArrayList<Object> scalar = m_reportdata.get(itemName);
if (scalar != null) {
//LOG.info("putting to jsonobj=" + scalar.get(0));
LOG.info("Scalar value: " + scalar.get(0));
obj.put(REPORT_VALUE, scalar.get(0));
reportItems.put(i, obj);
} else {
LOG.warning("WEPS report generatioin: Scalar parameter has no data in hashmap=" + itemName);
}
} else {
// Array values
//LOG.info("look up " + itemName + " in report hash table for array output.");
LinkedList coll = new LinkedList();
ArrayList<Object> array = m_reportdata.get(itemName);
if (array != null) {
for (int j = 0; j < array.size(); j++) {
coll.add(array.get(j));
}
obj.put(REPORT_VALUE, (Collection) coll);
reportItems.put(i, obj);
} else {
LOG.warning("WEPS report generation: Array parameter has no data in hashmap=" + itemName);
}
}
obj.remove(REPORT_TYPE);
}
//LOG.info("Updated Report JSON obj=" + reportObj.toString());
return reportItems;
}
/**
* This is an overloaded method for createReport that allows you to only
* query a set of item in a report
* @param reportItems items you want returned in the report
* @return The report data
* @throws Exception
*/
private JSONArray createReport(JSONArray reportItems) throws Exception {
String workDir = getWorkspaceDir().toString();
File reportTemplate = getResourceFile(REPORT_JSON_ID);
String sReportJSON = FileUtils.readFileToString(reportTemplate);
//JSONObject reportObj = new JSONObject(sReportJSON);
//JSONArray reportItems = reportObj.getJSONArray("WEPSreport");
if (reportItems == null || reportItems.length() == 0) {
reportItems = new JSONArray(sReportJSON);
}
WepsConnection con = new WepsConnection();
// Create an instance of this class to do the actual loading.
WepsReportData reportdata = new WepsReportData(con);
// Set the location of the folder to translate files in.
String sInputDirectory = workDir;
if (!reportdata.setInputDirectory(sInputDirectory)) {
// Print a usage message and quit
LOG.severe("error: WEPS reports input directory doesn't exist.");
throw new ServiceException("Error create WEPS reports. Report directory does not exist.");
}
// @todo set configuration options.
reportdata.m_sUnits = "US";
// Load the file data.
LOG.info("WorkingDir: " + getWorkspaceDir().toString());
//reportdata.loadFiles(getWorkspaceDir().toString());
reportdata.loadFiles(getWorkspaceDir().toString(), stdout.getName());
// // Dump the loaded data as text for debugging purposes.
// LOG.info("hash map output=" + con.toString());
//
// LOG.info("Original Report JSON obj=" + reportObj.toString());
HashMap<String, ArrayList<Object>> m_reportdata = con.getParamValues();
for (int i = 0; i < reportItems.length(); i++) {
JSONObject obj = (JSONObject) reportItems.get(i);
String itemName = obj.getString(REPORT_NAME);
//LOG.info("COMPARISON for scalars: itemname='" + itemName + "'");
//if (itemName.length() >= 5) LOG.info("COMPARISON for scalars: itemname 0,5='" + itemName.substring(0,5) + "'");
//if (itemName.length() >= 11) LOG.info("COMPARISON for scalars: itemname 0,11='" + itemName.substring(0,11) + "'");
if ((itemName != null) && ((((itemName.length()) >= 5) && (itemName.substring(0, 5).contentEquals("runs.")))
|| (((itemName.length()) >= 11) && (itemName.substring(0, 11).contentEquals("sci_energy."))))) {
// Scalar values
//LOG.info("look up " + itemName + " in report hash table for scalar output.");
ArrayList<Object> scalar = m_reportdata.get(itemName);
if (scalar != null) {
//LOG.info("putting to jsonobj=" + scalar.get(0));
obj.put(REPORT_VALUE, scalar.get(0));
reportItems.put(i, obj);
} else {
LOG.warning("WEPS report generatioin: Scalar parameter has no data in hashmap=" + itemName);
}
} else {
// Array values
//LOG.info("look up " + itemName + " in report hash table for array output.");
LinkedList coll = new LinkedList();
ArrayList<Object> array = m_reportdata.get(itemName);
if (array != null) {
for (int j = 0; j < array.size(); j++) {
coll.add(array.get(j));
}
obj.put(REPORT_VALUE, (Collection) coll);
reportItems.put(i, obj);
} else {
LOG.warning("WEPS report generation: Array parameter has no data in hashmap=" + itemName);
}
}
obj.remove(REPORT_TYPE);
}
//LOG.info("Updated Report JSON obj=" + reportObj.toString());
return reportItems;
}
}