V1_2.java [src/java/m/sci] Revision: d4ff02193b608f80049ba417a9899ff3b5e17d27  Date: Wed Feb 03 16:01:46 MST 2016
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package m.sci;

import c.PostGIS;
import csip.Config;
import csip.ModelSession;
import csip.ServiceException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Callable;
import javax.ws.rs.*;
import oms3.annotations.*;
import org.apache.commons.io.IOUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.codehaus.jettison.json.JSONException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import csip.ModelDataService;
import static csip.ModelDataService.EXEC_FAILED;
import static csip.ModelDataService.EXEC_OK;
import static csip.ModelDataService.KEY_REQUEST_RESULTS;
import static csip.ModelDataService.KEY_STATUS;
import static csip.ModelDataService.KEY_SUUID;
import static csip.ModelDataService.KEY_TSTAMP;
import static csip.ModelDataService.SUBMITTED;
import csip.ModelDataService.Task;
import static csip.ModelDataService.VALUE;
import static util.ErosionConst.*;
import csip.utils.Dates;
import csip.utils.JSONUtils;
import static m.weps.SciEnergyParser.LOG;

//import services.Lmod2Rusle2;
/**
 * REST Web Service. Front end callable.
 *
 * @author wlloyd, od
 */
@Name("SCI")
@Description("IET / Phacil version of SCI")
@VersionInfo("1.2")
@Path("m/sci/1.2")
public class V1_2 extends ModelDataService {

    static final boolean PRODUCTION_MODE = true;
    //
    static final String R2_TMP_FILENAME = "r2";
    static final String R2_TMP_FILEEXT = ".rsh";
    static final String IO_TIMING_FILENAME = "/tmp/io-timing";
    static final String IO_TIMING_FILEEXT = ".txt";

    // kg/m^2/yr to tons/acre/yr
    static final Double WEPS_TO_R2_EROSION_CONVERSION_FACTOR = 4.46089561;

    // this is the 0.2 / 2.54 conversion, where 2.54 is ER-renner
    static final Double SCI_CONVERSION_FACTOR = .078740157;

    private String tz = "UTC";
    String cokey = "";
    JSONObject lmodweps = new JSONObject();
    /*
     * The R2 Run
     */
    final R2Run r2run = new R2Run();
    static final List<String> potResults = Collections.unmodifiableList(Arrays.asList(
            RES_SLOPE_DELIVERY,
            RES_SLOPE_T_VALUE,
            RES_SLOPE_DEGRAD,
            RES_SLOPE_EQUIV_DIESEL_USE_PER_AREA,
            RES_SOIL_COND_INDEX_STIR_VAL,
            RES_SOIL_COND_INDEX_RESULT));
    //
    String climate;
    String soil;
    String mgmt;
    String scitotal = "0.0";
    String sci_om = "0.0";
    String sci_fo = "0.0";
    String sci_er = "0.0";
    //

    @Override
    protected void preprocess() throws Exception {
        // check for requested output.

        try {
            JSONUtils.checkValidResultRequest(getMetainfo(), potResults);
        } catch (ServiceException se) {
            LOG.warning("No Rusle2 return parameters requested! Will use defaults: SLOPE_DELIVERY, SLOPE_T_VALUE, SLOPE_DEGRAD");
            List<String> params = new LinkedList<String>();
//            params.add(RES_SLOPE_DELIVERY);
//            params.add(RES_SLOPE_T_VALUE);
//            params.add(RES_SLOPE_DEGRAD);
//            params.add(RES_SOIL_COND_INDEX_RESULT);
//            params.add(RES_SOIL_COND_INDEX_OM_SUBFACTOR);
//            params.add(RES_SOIL_COND_INDEX_FO_SUBFACTOR);
//            params.add(RES_SOIL_COND_INDEX_ER_SUBFACTOR);
            getMetainfo().put(KEY_REQUEST_RESULTS, params);
        }

        // check if sufficient input is there.
        if (!(JSONUtils.checkKeyExistsB(getParamMap(), KEY_SOILS))
                && !(JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_SOIL))) {
            throw new ServiceException("Key not found :SCI SOIL");
        }

        if (!(JSONUtils.checkKeyExistsB(getParamMap(), KEY_MGMTS))
                && !(JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_MANAGEMENT))) {
            throw new ServiceException("Key not found :SCI MANAGEMENT");
        }

        // to do - fix
        // Currently the R2 rsh file must be created for both R2 & WEPS runs because
        // the lmodwepsobj is grabbed from actions of this method.
        File r2script = new File(getWorkspaceDir(), R2_TMP_FILENAME + R2_TMP_FILEEXT);
        createInputFile(r2script, getMetainfo(), getParamMap());
    }

    @Override
    protected Callable<String> createCallable() throws Exception {
        return new Callable<String>() {

            @Override
            public String call() throws Exception {

                int result = 0;
                double r2erosion = 0.0;
                double r2sci = 0.0;
                double r2sci_om = 0.0;
                double r2sci_fo = 0.0;
                double r2sci_er = 0.0;

                // if rusle 2 params
                if (JSONUtils.checkKeyExistsB(getParamMap(), KEY_LENGTH)
                        && JSONUtils.checkKeyExistsB(getParamMap(), KEY_STEEPNESS)) {
                    result = r2run.execute(new File(getWorkspaceDir(), R2_TMP_FILENAME + R2_TMP_FILEEXT));

                    if (result != 0) {
                        return EXEC_FAILED;
                    }

                    r2erosion = Double.parseDouble(r2run.getResult(RES_SLOPE_DEGRAD));
                    r2sci = Double.parseDouble(r2run.getResult(RES_SOIL_COND_INDEX_RESULT));
                    r2sci_om = Double.parseDouble(r2run.getResult(RES_SOIL_COND_INDEX_OM_SUBFACTOR));
                    r2sci_fo = Double.parseDouble(r2run.getResult(RES_SOIL_COND_INDEX_FO_SUBFACTOR));
                    r2sci_er = Double.parseDouble(r2run.getResult(RES_SOIL_COND_INDEX_ER_SUBFACTOR));

                    scitotal = Double.toString(r2sci);
                    sci_om = Double.toString(r2sci_om);
                    sci_fo = Double.toString(r2sci_fo);
                    sci_er = Double.toString(r2sci_er);
                }

                // Check if wind barriers (WEPS) tag exists, if so run weps, otherwise return...
                if (!JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_BARRIERS)) {
                    return EXEC_FAILED;
                }

                // Copy R2 soil cokey as weps parameter
                if (JSONUtils.checkKeyExistsB(getParamMap(), KEY_SOILS)) {
                    // only add if the weps soil has not been specified natively
                    if (!JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_SOIL)) {
                        JSONObject wepsSoil = JSONUtils.data(WEPS_KEY_SOIL, cokey);
                        getParamMap().put(WEPS_KEY_SOIL, wepsSoil);
                    }
                }

                LOG.info("The weps mgmt copied over from Rusle2 is");
                LOG.info(lmodweps.toString());

                // only add if the weps mgmt has not been specified natively
                if (!JSONUtils.checkKeyExistsB(getParamMap(), WEPS_KEY_MANAGEMENT)) {
                    JSONObject lmodwepsobj = JSONUtils.data(WEPS_KEY_MANAGEMENT, lmodweps);
                    getParamMap().put(WEPS_KEY_MANAGEMENT, lmodwepsobj);
                }

                // to do
                // only invoke weps if it is required!!!
                LOG.info("Trying to invoke WEPS for SCI");
                m.weps.V1_2 weps = new m.weps.V1_2();

                LOG.info("sci obj ssuid=" + getSUID());
                LOG.info("weps obj ssuid=" + weps.getAMSSUID());

                LOG.info("Copying SCI info to WEPS object");
                weps.setParamMap(getParamMap());
                weps.setRequest(getRequest());
                //weps.setMetainfo(getMetainfo());

                JSONObject metainfo_clone = JSONUtils.clone(getMetainfo());
                // Put polling info in obj before starting!
                if (getNextPoll() != -1) {  
                    metainfo_clone.put(KEY_NEXT_POLL, getNextPoll());
                }
                if (getFirstPoll() != -1) {
                    metainfo_clone.put(KEY_FIRST_POLL, getFirstPoll());
                }
                metainfo_clone.put(KEY_STATUS, SUBMITTED);
                // important, set the uuid to the weps id, not the sci one
                metainfo_clone.put(KEY_SUUID, weps.getAMSSUID());
                metainfo_clone.put(KEY_TSTAMP, Dates.nowISO(weps.getAMStz()));
                weps.setMetainfo(metainfo_clone);

                weps.setParam(getParam());

                // step 1 preprocess input
                LOG.info("SCI: weps preprocess");
                weps.preprocess();

                // step 2 create the model
                LOG.info("SCI: create the weps model");
                Callable<String> model = weps.createCallable();
                if (model == null) {
                    throw new ServiceException("No model to run.");
                }

                // step 3 create the model's thread
                LOG.info("SCI: create weps task obj");
                weps.mt = new Task(model);

                // step 4 execute the model's thread
                LOG.info("SCI: run weps");
                weps.mt.start();
                LOG.info("metadata for weps run=");
                LOG.info(weps.getAMSMetainfo().toString());
                while (weps.mt.isAlive()) {
                    weps.mt.join();
                }

                // step 5 force creation of output
                LOG.info("FORCED CALLING OF THE createResults() method for weps!!!");
                JSONArray results = weps.createResults();

                LOG.info("sci obj ssuid=" + getSUID());
                LOG.info("weps obj ssuid=" + weps.getAMSSUID());

                LOG.info("metadata for weps run=");
                LOG.info(weps.getAMSMetainfo().toString());
//                ModelSession session = Config.getSessionStore().getSession(weps.getAMSSUID());
//                if (session != null) {
//                    //LOG.info("The weps run output=" +  session. session.getResponse());
//                    LOG.info("The weps run output= can no longer be shown" );
//                } else {
//                    LOG.info("session is null!!!");
//                }

//                // Rusle 2 only parameter assignments
//                scitotal = Double.toString(r2sci);
//                sci_om = Double.toString(r2sci_om);
//                sci_fo = Double.toString(r2sci_fo);
//                sci_er = Double.toString(r2sci_er);
                double wepserosion = Double.parseDouble(weps.wo.windEros) * WEPS_TO_R2_EROSION_CONVERSION_FACTOR;
                double wepssci = Double.parseDouble(weps.wo.soilConditioningIndex);
                double wepssci_om = Double.parseDouble(weps.wo.sciOmFactor);
                double wepssci_fo = Double.parseDouble(weps.wo.sciFoFactor);
                double wepssci_er = Double.parseDouble(weps.wo.sciErFactor);

                LOG.info("r2 erosion=" + r2erosion);
                LOG.info("r2 sci=" + r2sci);
                LOG.info("r2 sci_om=" + r2sci_om);
                LOG.info("r2 sci_fo=" + r2sci_fo);
                LOG.info("r2 sci_er=" + r2sci_er);
                LOG.info("weps erosion=" + wepserosion);
                LOG.info("weps sci=" + wepssci);
                LOG.info("weps sci_om=" + wepssci_om);
                LOG.info("weps sci_fo=" + wepssci_fo);
                LOG.info("weps sci_er=" + wepssci_er);

                // if weps only
                if (!((JSONUtils.checkKeyExistsB(getParamMap(), KEY_LENGTH))
                        && (JSONUtils.checkKeyExistsB(getParamMap(), KEY_STEEPNESS)))) {
                    scitotal = Double.toString(wepssci);
                    sci_om = Double.toString(wepssci_om);
                    sci_fo = Double.toString(wepssci_fo);
                    sci_er = Double.toString(wepssci_er);
                    return EXEC_OK;
                }

                if (wepserosion > r2erosion) // if weps wind erosion is more than rusle2 soil erosion
                {
                    scitotal = Double.toString(wepssci - SCI_CONVERSION_FACTOR * r2erosion);
                    sci_er = Double.toString(wepssci_er + r2sci_er - 1);
                    sci_om = Double.toString(wepssci_om);
                    sci_fo = Double.toString(wepssci_fo);
                } else // if rusle2 soil erosion is more than weps wind erosion
                {
                    scitotal = Double.toString(r2sci - SCI_CONVERSION_FACTOR * wepserosion);
                    sci_om = Double.toString(r2sci_om);
                    sci_fo = Double.toString(r2sci_fo);
                    sci_er = Double.toString(wepssci_er + r2sci_er - 1);
                }

                return EXEC_OK;
            }
        };
    }

    @Override
    protected JSONArray createResults() throws Exception {
        JSONArray results = new JSONArray();
//      results.put(JSONUtils.data(KEY_SLOPE_DELIVERY, 3.0));
        for (String r : JSONUtils.getRequestedResults(getMetainfo())) {
            results.put(JSONUtils.data(r, r2run.getResult(r)));
        }

//        results.put(JSONUtils.data(KEY_CLIMATES, climate));
//        results.put(JSONUtils.data(KEY_SOILS, soil));
//        results.put(JSONUtils.data(KEY_MANAGEMENTS, mgmt));
// old rusle 2 only version        
//        results.put(JSONUtils.dataDesc(KEY_SCI_VALUE, r2run.getResult(RES_SOIL_COND_INDEX_RESULT), "The total SCI value." ));
//        results.put(JSONUtils.dataDesc(KEY_SCI_OM, r2run.getResult(RES_SOIL_COND_INDEX_OM_SUBFACTOR), "The SCI OM (Organic Matter) subfactor. This is 40% of the total SCI value." ));
//        results.put(JSONUtils.dataDesc(KEY_SCI_FO, r2run.getResult(RES_SOIL_COND_INDEX_FO_SUBFACTOR), "The SCI FO (Field Operations) subfactor.This is 40% of the total SCI value." ));
//        results.put(JSONUtils.dataDesc(KEY_SCI_ER, r2run.getResult(RES_SOIL_COND_INDEX_ER_SUBFACTOR), "The SCI ER (Erosion Rate) subfactor. This is 20% of the total SCI value."));
        results.put(JSONUtils.dataDesc(KEY_SCI_VALUE, scitotal, "The total SCI value."));
        results.put(JSONUtils.dataDesc(KEY_SCI_OM, sci_om, "The SCI OM (Organic Matter) subfactor. This is 40% of the total SCI value."));
        results.put(JSONUtils.dataDesc(KEY_SCI_FO, sci_fo, "The SCI FO (Field Operations) subfactor.This is 40% of the total SCI value."));
        results.put(JSONUtils.dataDesc(KEY_SCI_ER, sci_er, "The SCI ER (Erosion Rate) subfactor. This is 20% of the total SCI value."));

//      results.put(JSONUtils.data(KEY_ALT_R2DB, in_ALT_R2DB));
        return results;
    }

//    @Override
//    protected JSONObject describe() throws JSONException {
//        try {
//            // use this from version 1.1
//            String tmpl = IOUtils.toString(V1_2.class.getResource("/src/m/sci/V1_2Req.json"));
//            JSONObject model = new JSONObject(tmpl);
//            return model;
//        } catch (IOException ex) {
//            throw new RuntimeException("tmpl");
//        }
//    }

    @Override
    protected long getNextPoll() {
        return 1000;
    }

    @Override
    protected long getFirstPoll() {
        return 1000;
    }

//    @Override
//    public String getModelName() {
//        return "sci/1.2";
//    }
    private void createInputFile(File file, JSONObject metainfo, Map<String, JSONObject> param)
            throws Exception {

        String managementFormalName[] = new String[]{};

//        String mgmtPtr = JSONUtils.getStringParam(param, KEY_MANAGEMENTS, "");
//        if (!mgmtPtr.startsWith("managements\\")) {
//            mgmtPtr = "managements\\" + mgmtPtr;
//        }
        // management conversion
        // Make file line separator unix compatible. ???? not sure if needed.
        System.setProperty("line.separator", "\n");
        //

        JSONArray managements;
        if (JSONUtils.checkKeyExistsB(param, KEY_MGMTS)) {
            managements = JSONUtils.getJSONArrayParam(param, KEY_MGMTS);
        } else {
            JSONObject mgmt = JSONUtils.getJSONObjectParam(param, WEPS_KEY_MANAGEMENT);
            managements = new JSONArray();
            managements.put(mgmt);
        }

        LOG.info("managements array=" + managements.toString());
        managementFormalName = new String[managements.length()];

        for (int i = 0; i < managements.length(); i++) {
            LOG.info("management #" + i);

            JSONObject lmod = (JSONObject) managements.get(i);
            LOG.info(lmod.toString());

            lmod2rusle2.Rusle2Translator translator = new lmod2rusle2.Rusle2Translator();
            translator.readJsonString(lmod.toString());
            translator.Translate();

//            // extract the element as JSON
//            Document lmod_xml = Lmod2Rusle2.readJSON(lmod, false);
//            // Translate the file into RUSLE2 format
//            Document r2_xml = Lmod2Rusle2.LmodXmlToRusle2Xml(lmod_xml, "F");
            Document r2_xml = translator.getDocument();

            //LOG.info("R2 XML FILE:\n\n" + r2_xml.toString());
            LOG.info("R2 XML FILE:\n\n" + translator.getRusle2Xml());

            //LOG.info("LMOD XML FILE:\n\n" + lmod_xml.getTextContent());
//            if ((lmod_xml != null) && (lmod_xml.getElementById("Filename") != null))
//                managementFormalName[i] = lmod_xml.getElementById("Filename").getTextContent();
            if ((r2_xml != null) && (r2_xml.getElementsByTagName("Filename") != null)) {
                NodeList nl = r2_xml.getElementsByTagName("Filename");
                for (int ii = 0; ii < nl.getLength(); ii++) {
                    LOG.info("filename node=" + nl.item(ii).getTextContent());
                    managementFormalName[i] = nl.item(ii).getTextContent();
                }
            }

            // write it out to the workspace as single file.
            translator.writeRusle2Xml(getWorkspaceDir().toString(), "lmod_file.xml");

        }
        // Always use the 1st mgmt for the weps lmod obj
        lmodweps = (JSONObject) managements.get(0);

        // if rusle2 call
        if (!((JSONUtils.checkKeyExistsB(getParamMap(), KEY_LENGTH))
                && (JSONUtils.checkKeyExistsB(getParamMap(), KEY_STEEPNESS)))) {
            return;
        }

        double steepness = JSONUtils.getDoubleParam(param, KEY_STEEPNESS, 0.0);
        double length = JSONUtils.getDoubleParam(param, KEY_LENGTH, 0.0);
        boolean resolveLoc = JSONUtils.getBooleanParam(param, KEY_RESOLVE_LOCATION, false);
        double latitude = JSONUtils.getDoubleParam(param, KEY_LATITUDE, 0.0);
        double longitude = JSONUtils.getDoubleParam(param, KEY_LONGITUDE, 0.0);

        String climatePtr = JSONUtils.getStringParam(param, KEY_CLIMATES, "");
        String soilPtr = JSONUtils.getStringParam(param, KEY_SOILS, "");

        String altR2db = null;
        if (param.get(KEY_ALT_R2DB) != null) {
            altR2db = param.get(KEY_ALT_R2DB).getString(VALUE);
        }

        PostGIS db = PostGIS.singleton();

        // If this is a Lat/Lng request, then we need to make a DB lookup
        // to obtain the Climate and Soil information and ignore whatever
        // may have been passed in
        LOG.info("Rulse 2 model request resolveLocation=" + resolveLoc);
        //if (resolveLoc) {

        if (db != null) {
            PostGIS.FileQryResult climate = db.findClimate(latitude, longitude);
            if (climate == null) {
                LOG.warning("no climate for lat=" + latitude + "\nfor long=" + longitude + "\n");
                climatePtr = "";
            } else {
                climatePtr = climate.file_path + "\\" + climate.file_name;
            }

            // to do
            // use only the first soil for now - later we need to use all of them
            cokey = soilPtr.replace(",", " ");
            // strip first and last char
            String t2 = cokey.substring(1, cokey.length() - 1);
            String delims = "\"";
            String tokens[] = t2.split(delims);
            LinkedList<String> lst = new LinkedList();
            for (String token : tokens) {
                if (token.trim().length() > 0) {
                    lst.add(token);
                }
            }
            cokey = lst.get(0);  // first soil only for now
            PostGIS.FileQryResult soil = db.findSoilsByCokey(cokey, longitude);
            if (soil == null) {
                LOG.warning("No soil for lat=" + latitude + "\nfor long=" + longitude + "\n");
                soilPtr = "";
            } else {
                soilPtr = soil.file_path + "\\" + soil.file_name;
            }
        } else {
            LOG.warning("WARNING: Unable to access database to resolve the climate and soil information for this lat/long driven rusle2 model run.  Using deafults.");
        }
        //}

        FileOutputStream fos = new FileOutputStream(file);

        // to enable/disable romeconsole logging
        if (!PRODUCTION_MODE) {
            fos.write("Log ON\n".getBytes());
        }
        fos.write("RomeInit\n".getBytes());

        if (!PRODUCTION_MODE) {
            String timingFilename = IO_TIMING_FILENAME + getFilenumber(file.getName()) + IO_TIMING_FILEEXT;
            fos.write(("RomeSetTitle \"App.Files.IoLogging\" \"" + timingFilename + "\"\n").getBytes());
        }

        String r2db = Config.getString("r2.db", "http://oms-db.engr.colostate.edu/r2");
        if (altR2db == null) {
            fos.write(("DatabaseOpen \"" + r2db + "\"\n").getBytes());
        } else {
            String altr2db = r2db.substring(0, r2db.lastIndexOf("/")) + "/model-data/" + altR2db;
            fos.write(("DatabaseOpen \"" + altr2db + "\"\n").getBytes());
        }

        fos.write("FilesOpen profiles\\#ENTRY_MODEL PRIVATE\n".getBytes());
        fos.write("Activate profiles\\model\n".getBytes());

        fos.write(("RomeFileSetAttrValue CLIMATE_PTR \"" + climatePtr + "\"\n").getBytes());

        // climate stub if needed
        //fos.write("RomeFileSetAttrValue CLIMATE_PTR \"climates\\USA\\Idaho\\Power County\\ID_Power_R_11\"\n".getBytes());
        // soil stub if needed
        //fos.write("RomeFileSetAttrValue SOIL_PTR \"soils\\Power County Area, Idaho\\40 Neeley silt loam, 2 to 4 percent slopes\\Neeley  silt loam 90%\"\n".getBytes());
//        fos.write(("RomeFileSetAttrValue MAN_BASE_PTR \"" + mgmtPtr + "\"\n").getBytes());
        // multiple managements
// to do
// Don't worry about multiple mgmts for now
//        for (int i = 0; i < managements.length(); i++) {
//            //reference the lmod file(s)
//            fos.write(("RomeFileSetAttrValue MAN_PTR \"" + new File(getWorkspace(), "lmod_file" + i + ".xml" + "\"\n")).getBytes());
//        }
        if ((managements != null) && (managements.length() >= 1)) {
            fos.write(("FilesOpen \"#XML:" + new File(getWorkspaceDir(), "lmod_file.xml" + "\"\n")).getBytes());
            // fos.write(("Activate \"" + managementFormalName[0] + "\"\n").getBytes());
            fos.write(("RomeFileSetAttrValue MAN_BASE_PTR \"" + managementFormalName[0] + "\"\n").getBytes());
            mgmt = managementFormalName[0];
        }

        // to do 
        // commented out - using default for now
        fos.write(("RomeFileSetAttrValue SOIL_PTR \"" + soilPtr + "\"\n").getBytes());

        fos.write(("RomeFileSetAttrValue SLOPE_HORIZ \"" + length + "\"\n").getBytes());
        fos.write(("RomeFileSetAttrValue SLOPE_STEEP \"" + steepness + "\"\n").getBytes());

        fos.write("RomeEngineRun\n".getBytes());
        for (String r : JSONUtils.getRequestedResults(metainfo)) {
            fos.write(("RomeFileGetAttrValue " + r + "\n").getBytes());
        }

        fos.write(("RomeFileGetAttrValue " + RES_SLOPE_DEGRAD + "\n").getBytes());
        fos.write(("RomeFileGetAttrValue " + RES_SOIL_COND_INDEX_RESULT + "\n").getBytes());
        fos.write(("RomeFileGetAttrValue " + RES_SOIL_COND_INDEX_OM_SUBFACTOR + "\n").getBytes());
        fos.write(("RomeFileGetAttrValue " + RES_SOIL_COND_INDEX_FO_SUBFACTOR + "\n").getBytes());
        fos.write(("RomeFileGetAttrValue " + RES_SOIL_COND_INDEX_ER_SUBFACTOR + "\n").getBytes());

        fos.write("RomeExit\n".getBytes());
        fos.write("Exit\n".getBytes());
        fos.close();

        climate = climatePtr;
        soil = soilPtr;
//        mgmt = mgmtPtr;

        LOG.info("R2 script: " + file.toString());
    }

    private String getFilenumber(String filename) {
        return filename.substring(R2_TMP_FILENAME.length(), filename.length() - R2_TMP_FILEEXT.length());
    }

}