V1_0.java [src/java/m/wqm/NutrientSLP] Revision: 5e7ef55df081c99fabaf55d5297a331309a264ea  Date: Sat Sep 26 12:01:56 MDT 2015
package m.wqm.NutrientSLP;

import csip.ModelDataService;
import csip.ServiceException;
import java.util.ArrayList;
import javax.ws.rs.Path;
import oms3.annotations.Description;
import oms3.annotations.Name;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import csip.utils.JSONUtils;
import java.util.Map;
import org.codehaus.jettison.json.JSONException;

/**
 *
 * @ Srinivas
 * @author Rumpal Sidhu
 */
@Name("WQM-05: Nutrient Soil Leaching Potential (NutrientSLP)")
@Description("This service computes nutrient soil leaching potential for soil components in an area of analysis, and then computes nutrient soil leaching potential representing the area of analysis (AoA). The service primarily will consume data from the WQM-02 WQMSoilAttributes service to compute nutrient soil leaching potentials used later by the WQM-13 service to compute threshold treatment level scores.")
@Path("m/nutrient_slp/1.0")

public class V1_0 extends ModelDataService {

    private final String[] nslpList = new String[]{"LOW", "MODERATE", "MODERATELY HIGH", "HIGH"};
    //Request
    private int aoaId;
    private ArrayList<SoilComponent> soilComponentList;
    //Result
    private String aoaNslp;
    private String error_msg;

    @Override
    protected void preProcess() throws Exception {
        soilComponentList = new ArrayList<>();
        this.error_msg = "";
        try {
            aoaId = getIntParam("AoAId");
            JSONArray groups = getJSONArrayParam("soilcomponents");
            for (int i = 0; i < groups.length(); i++) {
                Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
                SoilComponent input = new SoilComponent(
                        JSONUtils.getStringParam(group, "cokey", "err"),
                        JSONUtils.getDoubleParam(group, "aoa_comp_area", 0),
                        JSONUtils.getStringParam(group, "aoa_comp_hsg", "err"),
                        JSONUtils.getStringParam(group, "aoa_comp_taxorder", "err"),
                        JSONUtils.getDoubleParam(group, "aoa_comp_kfact", 0),
                        JSONUtils.getDoubleParam(group, "aoa_comp_slope", 0),
                        JSONUtils.getDoubleParam(group, "aoa_comp_coarse_frag", 0),
                        JSONUtils.getBooleanParam(group, "aoa_comp_drained", false),
                        JSONUtils.getStringParam(group, "aoa_comp_wtbl", "err"),
                        JSONUtils.getBooleanParam(group, "aoa_comp_hwt_lt_24", false));
                soilComponentList.add(input);
            }
        } catch (ServiceException | JSONException ex) {
            this.error_msg += "  " + ex.getMessage() + ". ";
        }
    }

    @Override
    protected String process() throws Exception {
        try {
            if (this.error_msg.isEmpty()) {
                this.computeNSLP();
            }
            if (this.error_msg.isEmpty()) {
                this.computeAoaNSLP();
            }
        } catch (Exception ex) {
            LOG.info(ex.getMessage());
            this.error_msg += ex.getMessage();
        }
        return (this.error_msg.isEmpty() ? EXEC_OK : this.error_msg);
    }

    @Override
    protected void postProcess() throws Exception {
        putResult("aoa_id", aoaId, "Area of analysis identifier");
        putResult("aoa_nslp", aoaNslp, "Soil leaching potential of the area of analysis");
        JSONArray resultArr = new JSONArray();
        for (SoilComponent sc : soilComponentList) {
            JSONArray array = new JSONArray();
            array.put(JSONUtils.dataDesc("cokey", sc.getCokey(), "Soil component key"));
            array.put(JSONUtils.dataDesc("comp_nslp", sc.getNslp(), "Soil leaching potential of the soil component"));
            resultArr.put(JSONUtils.dataDesc("soil_component", array, "Soil Component"));
        }
        putResult("soil_components", resultArr, "List of Soil Components");
    }

    private void computeNSLP() {
        int comp_nslp_number = -2;
        for (SoilComponent ip : soilComponentList) {
            if (ip.getTaxorder().equals("Histosols")) {
                comp_nslp_number = 3;
            } else if (ip.getWtbl().equals("Apparent") || ip.isHwt_lt_24()) {
                comp_nslp_number = 3;
            } else {
                switch (ip.getHsg()) {
                    case "A":
                        comp_nslp_number = this.computeNSLPHsgA(ip);
                        break;
                    case "B":
                        comp_nslp_number = this.computeNSLPHsgB(ip);
                        break;
                    case "C":
                        comp_nslp_number = this.computeNSLPHsgC(ip);
                        break;
                    case "D":
                        comp_nslp_number = this.computeNSLPHsgD(ip);
                        break;
                    case "A/D":
                        if (ip.isDrained()) {
                            comp_nslp_number = this.computeNSLPHsgA(ip);
                        } else {
                            comp_nslp_number = this.computeNSLPHsgD(ip);
                        }
                        break;
                    case "B/D":
                        if (ip.isDrained()) {
                            comp_nslp_number = this.computeNSLPHsgB(ip);
                        } else {
                            comp_nslp_number = this.computeNSLPHsgD(ip);
                        }
                        break;
                    case "C/D":
                        if (ip.isDrained()) {
                            comp_nslp_number = this.computeNSLPHsgC(ip);
                        } else {
                            comp_nslp_number = this.computeNSLPHsgD(ip);
                        }
                        break;
                }
            }
            if (comp_nslp_number != -1 && comp_nslp_number != -2) {
                ip.setNslpNumber(comp_nslp_number);
                ip.setNslp(nslpList[comp_nslp_number]);
            } else {
                error_msg = "Error.";
            }
        }
    }

    private int computeNSLPHsgA(SoilComponent ip) {
        int nslpNumber = -1;
        if (ip.getSlope() > 12) {
            if (ip.getCoarseFrag() > 10) {
                nslpNumber = 3;
            } else {
                nslpNumber = 2;
            }
        } else if (ip.getSlope() <= 12) {
            nslpNumber = 3;
        }
        return nslpNumber;
    }

    private int computeNSLPHsgB(SoilComponent ip) {
        int nslpNumber = -1;
        if ((ip.getSlope() <= 12 && ip.getKfact() >= 0.24) || (ip.getSlope() > 12)) {
            if (ip.getCoarseFrag() > 10 && ip.getCoarseFrag() <= 30) {
                nslpNumber = 2;
            } else if (ip.getCoarseFrag() > 30) {
                nslpNumber = 3;
            } else {
                nslpNumber = 1;
            }
        } else if (ip.getSlope() >= 3 && ip.getSlope() <= 12 && ip.getKfact() < 0.24) {
            if (ip.getCoarseFrag() > 10) {
                nslpNumber = 3;
            } else {
                nslpNumber = 2;
            }
        } else if (ip.getSlope() < 3 && ip.getKfact() < 0.24) {
            nslpNumber = 3;
        }
        return nslpNumber;
    }

    private int computeNSLPHsgC(SoilComponent ip) {
        int nslpNumber;
        if (ip.getCoarseFrag() > 30) {
            nslpNumber = 3;
        } else if (ip.getCoarseFrag() > 10 && ip.getCoarseFrag() <= 30) {
            nslpNumber = 2;
        } else {
            nslpNumber = 1;
        }
        return nslpNumber;
    }

    private int computeNSLPHsgD(SoilComponent ip) {
        int nslpNumber;
        if (ip.getCoarseFrag() > 30) {
            nslpNumber = 2;
        } else if (ip.getCoarseFrag() > 10 && ip.getCoarseFrag() <= 30) {
            nslpNumber = 1;
        } else {
            nslpNumber = 0;
        }
        return nslpNumber;
    }

    //Compute weighted average nutrient soil leaching potential for the AoA
    private void computeAoaNSLP() {
        double cumNslpProduct = 0;
        double aoaArea = 0;

        for (SoilComponent sc : soilComponentList) {
            cumNslpProduct += (sc.getNslpNumber() * sc.getArea());
            aoaArea += sc.getArea();
        }
        double aoaNslpFract = cumNslpProduct / aoaArea;
        if (aoaNslpFract <= 0.50) {
            aoaNslp = "LOW";
        } else if (aoaNslpFract > 0.50 && aoaNslpFract <= 1.50) {
            aoaNslp = "MODERATE";
        } else if (aoaNslpFract > 1.50 && aoaNslpFract <= 2.50) {
            aoaNslp = "MODERATELY HIGH";
        } else {
            aoaNslp = "HIGH";
        }
    }
}