V1_0.java [src/java/d/crlmod/cropResidue] Revision: default Date:
/*
* Copyright 2020 sidereus.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package d.crlmod.cropResidue;
import crlmod.ServiceResources;
import static crlmod.ServiceResources.*;
import csip.ModelDataService;
import csip.api.server.ServiceException;
import csip.annotations.Description;
import csip.annotations.Name;
import csip.annotations.Resource;
import csip.annotations.VersionInfo;
import java.io.StringReader;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Path;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
/**
*
* @author sidereus
*/
@Name("sm crops")
@Description("sm crops")
@VersionInfo("1.0")
@Path("d/cropResidue/1.0")
@Resource(from = ServiceResources.class)
public class V1_0 extends ModelDataService {
@Override
protected void doProcess() throws Exception {
//does the user want param_sets, or just base data?
int crop_id = parameter().getInt("crop_id");
double cropYield = parameter().getDouble("crop_yield");
String harvest_date = parameter().getString("harvest_date");
String plant_date = parameter().getString("plant_date");
LocalDate harvest = LocalDate.parse(harvest_date);
LocalDate plant = LocalDate.parse(plant_date);
long residueInterval = ChronoUnit.DAYS.between(harvest, plant);
computeBiomassResidue(crop_id, cropYield, residueInterval);
}
private void computeBiomassResidue(int crop_id, double cropYield, long residueInterval) throws Exception {
DecimalFormat df = new DecimalFormat("0.00");
List<String> params = new ArrayList<>();
String query = "SELECT crop_id, crop_name, crop_yield, crop_yield_unit, \n"
+ "weps_crop_param_set, wepp_crop_param_set, rs_lbs_per_unit \n"
+ "FROM crops \n"
+ " LEFT JOIN weps_crops on (fk_weps_crop_id = weps_crop_id) \n"
+ " LEFT JOIN wepp_crops on (fk_wepp_crop_id = wepp_crop_id) \n"
+ " LEFT JOIN step_crop on (fk_step_crop_id = rs_crop_id) \n";
try (Connection connection = resources().getJDBC(getJDBCId())) {
try (Statement statement = connection.createStatement()) {
try (ResultSet resultSet = statement.executeQuery(query)) {
if (!resultSet.next()) {
String errors = "No crops found with ";
for (int i = 0; i < params.size(); i++) {
errors += params.get(i);
if (i < params.size() - 1)
errors += "and ";
}
throw new ServiceException(errors);
}
boolean found = false;
do {
BigDecimal cropID = resultSet.getBigDecimal("crop_id");
if (cropID.equals(new BigDecimal(crop_id))) {
double conversionFactor = resultSet.getInt("rs_lbs_per_unit");
String wepp_param_set = resultSet.getString("wepp_crop_param_set");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(wepp_param_set)));
XPathFactory xPf = XPathFactory.newInstance();
XPath xP = xPf.newXPath();
XPathExpression expr = xP.compile("//weppcrop/hi");
double wepp_hi = Double.parseDouble(expr.evaluate(doc)); // harvest index
expr = xP.compile("//weppcrop/oratea");
double wepp_oratea = Double.parseDouble(expr.evaluate(doc)); // daily residue decomposition rate
double cropResidue = computeBiomassResidue(cropYield, conversionFactor, wepp_hi, wepp_oratea, residueInterval);
results().put("cropResidue", df.format(cropResidue));
found = true;
break;
}
} while (resultSet.next());
if (!found)
throw new RuntimeException("Crop ID " + crop_id + " not in database.");
}
}
}
}
private double computeBiomassResidue(double cropYield, double conversionFactor,
double hi, double residueDecompositionRate, long residueInterval) {
double convertedCropYield = cropYield * conversionFactor;
double hi_denominator = (1 - hi) / hi;
double residue = Math.pow((1 - residueDecompositionRate), residueInterval);
return (convertedCropYield / hi_denominator) * residue;
}
protected String getJDBCId() {
return CR_LMOD_2019_STEP_ID;
}
@Override
protected Map<String, Object> getConfigInfo() {
return new LinkedHashMap<String, Object>() {
{
put(getJDBCId(), resources().getResolved(getJDBCId()));
}
};
}
}