V1_0.java [src/java/m/ipat] Revision: default 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.ipat;
import csip.ModelDataService;
import csip.ServiceException;
import csip.annotations.Description;
import csip.annotations.Name;
import csip.annotations.Resource;
import database.ipat.IPAT_Db;
import database.nrt.NRT_DB;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.Path;
import static m.ipat.Crops.APPLIATION_DEPTH;
import static m.ipat.IpatInput.IRRIGATION_LAND_UNITS;
import static m.ipat.IpatInput.WELL_LIFT;
import m.ipat.IpatOutput.LandUnits;
import static m.ipat.LandUnit.ROTATION_CROPS;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import utils.EvalResult;
/**
*
* @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
*/
@Name("iPAT")
@Description("iPAT")
@Path("m/ipat/1.0")
@Resource(from = database.DBResources.class)
public class V1_0 extends ModelDataService {
IpatInput ipat;
IpatOutput ipat_output;
@Override
public void preProcess() throws ServiceException, JSONException, SQLException {
ipat = new IpatInput();
ipat_output = new IpatOutput((name, val, descr, unit) -> this.putResult(name, val, descr, unit));
ipat.readValuesFromJSON(getParam());
ipat.setRowFirst();
try (NRT_DB nrt_db = new NRT_DB(getClass(), LOG)) {
ipat.setString(IpatInput.STATE_NUMBER, nrt_db.findStateCode(ipat.getGeometry(IpatInput.LOCATION)));
}
}
@Override
public void doProcess() throws ServiceException, SQLException {
try (IPAT_Db ipat_db = new IPAT_Db(this.getClass(), LOG)) {
getIPATCrops(ipat_db); // Also validates that the CRLMOD crop id provided is valid for irrigation calculations.
computeIrrigationEnergyConsumptionResults(ipat_db);
}
}
@Override
public void postProcess() throws ServiceException, JSONException {
JSONArray outArray = new JSONArray();
ipat.toJSONAll(outArray);
if (null != ipat_output) {
ipat_output.putResult();
}
}
protected void getIPATCrops(IPAT_Db ipat_db) throws ServiceException {
LandUnit landUnits = (LandUnit) ipat.getValue(IRRIGATION_LAND_UNITS);
for (int i = 0; i < landUnits.rowCount(); i++) {
Crops crops = (Crops) landUnits.getValue(i, ROTATION_CROPS);
for (int j = 0; j < crops.rowCount(); j++) {
crops.setInteger(j, Crops.CROP_ID, ipat_db.getCropId(crops.getInteger(j, Crops.CRLMOD_CROP_ID)));
}
}
}
protected void computeIrrigationEnergyConsumptionResults(IPAT_Db ipat_db) throws ServiceException {
double totalSystemEfficiency = 0.0;
double maxTotalSystemEfficiency = 0.0;
double costFactors = 0.0; // = 1.3715 * ((well_lift + pressure * 2.31) / unit_ppe / unit_hp_hr)
double waterUse = 0.0; // = crop_acres * water_applied_gross_feet
int wellLift = ipat.getInteger(WELL_LIFT);
double energyCost = ipat.getDouble(IpatInput.ENERGY_COST_RATE);
int systemPressure = ipat.getInteger(IpatInput.SYSTEM_PRESSURE);
LandUnit landUnits = (LandUnit) ipat.getValue(IRRIGATION_LAND_UNITS);
// AKA "System Efficiency" in original software
// double irrigEfficiency = ipat_db.irrigationEfficiency(ipat.getInteger(IpatInput.IRRIGATION_SYSTEM)); //Also validates the id exists...
PowerPlant powerPlant = ipat_db.getPowerSource(ipat.getInteger(IpatInput.POWER_SOURCE)); //Also validates the id exists...
// User specified system mods
// double flowMeterEfficiency = ipat_db.getFlowMeterEfficiency(ipat.getBoolean(IpatInput.FLOW_METER));
// double irrigScheduleEfficiency = ipat_db.getIrrigScheduleEfficiency(ipat.getBoolean(IpatInput.IRRIGATION_SCHEDULING));
// double mtnUpgradeEfficiency = ipat_db.getMtnUpgradeEfficiency(ipat.getBoolean(IpatInput.MAINTENANCE_UPGRADES));
//
// // Database supplied maximum system mods
// double maxFlowMeterEfficiency = ipat_db.getFlowMeterEfficiency(true);
// double maxIrrigScheduleEfficiency = ipat_db.getIrrigScheduleEfficiency(true);
// double maxMtnUpgradeEfficiency = ipat_db.getMtnUpgradeEfficiency(true);
if (EvalResult.testDefaultInteger(wellLift)) {
wellLift = ipat_db.getWellLift(ipat.getString(IpatInput.STATE_NUMBER));
}
// totalSystemEfficiency = irrigEfficiency + flowMeterEfficiency + irrigScheduleEfficiency + mtnUpgradeEfficiency;
// maxTotalSystemEfficiency = irrigEfficiency + maxFlowMeterEfficiency + maxIrrigScheduleEfficiency + maxMtnUpgradeEfficiency;
// Assuming, now, that all adjustments are made in the GUI and no longer need to be accounted for here...
totalSystemEfficiency = 1.0;
//Per crop we have to re-do all calculations....
for (int i = 0; i < landUnits.rowCount(); i++) {
Crops crops = (Crops) landUnits.getValue(i, ROTATION_CROPS);
double lWaterUse = 0.0;
double actual_water_applied = 0.0;
double assumed_water_applied = 0.0;
double irr_acres = landUnits.getDouble(i, LandUnit.IRRIGATED_ACRES);
for (int j = 0; j < crops.rowCount(); j++) {
double water_applied_gross_inches = crops.getInteger(j, APPLIATION_DEPTH);
double water_applied_gross_feet = water_applied_gross_inches / 12;
double tWater_applied = water_applied_gross_feet * totalSystemEfficiency;
actual_water_applied += tWater_applied;
assumed_water_applied += water_applied_gross_feet;
double cWaterUse = irr_acres * water_applied_gross_feet;
lWaterUse += cWaterUse; // Should be this?? (water_applied_gross_feet * (1.0 + (1.0 - totalSystemEfficiency)));
crops.setDouble(j, Crops.WATER_REQUIREMENT, cWaterUse);
crops.setDouble(j, Crops.WATER_USE, tWater_applied);
}
waterUse += lWaterUse;
ipat_output.addLandUnit(landUnits.getString(i, LandUnits.LAND_UNIT_ID), lWaterUse, assumed_water_applied * 12.0);
}
costFactors = 1.3715 * ((wellLift + systemPressure * 2.31) / powerPlant.eval_gain / powerPlant.hp_hr_per_energy_unit);
double seasonalIrrCost = energyCost * waterUse * costFactors; //Per the original software. [energyCost is called unit_cost in the original software]
Map<String, Object> row = new HashMap<>();
row.put(IpatOutput.IRRIG_SYS_WATER_USE, waterUse);
row.put(IpatOutput.IRRIG_SYS_COST, seasonalIrrCost);
ipat_output.appendRow(row);
}
}