V2_0.java [src/java/m/watershed/topography_index] 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.watershed.topography_index;

import csip.api.server.Executable;
import csip.ModelDataService;
import csip.api.server.ServiceException;
import csip.annotations.Resource;
import javax.ws.rs.Path;
import csip.annotations.*;
import java.io.*;
import java.util.logging.Level;
import static m.watershed.Functions.Python_zonal;
import m.watershed.Resources;
import static m.watershed.Resources.AREADINF;
import static m.watershed.Resources.CLEAN;
import static m.watershed.Resources.DINF;
import static m.watershed.Resources.GDAL;
import static m.watershed.Resources.GDALCALC;
import static m.watershed.Resources.GDALTRANSLATE;
import static m.watershed.Resources.LOCATION_MNT_DATA1;
import static m.watershed.Resources.MPI;
import static m.watershed.Resources.OGR;
import static m.watershed.Resources.PITREMOVE;
import static m.watershed.Resources.PYTHON;
import static m.watershed.Resources.ZONALSTATS;

/**
 * slope
 *
 * @author JK (using OD's template)
 */
@Name("topography_index")
@Description("Example of topography_index")
@Path("m/topography_index/2.0")
@Resource(from = Resources.class)

public class V2_0 extends ModelDataService {

    static final String BOUNDARY = "boundary";

    @Override
    protected void doProcess() throws Exception {

        LOG.info("===>  Processing ");

        if (attachments().hasFile(parameter().getString(BOUNDARY))) {

            String result_ID = parameter().getString("result_ID");

            int act_cores = Runtime.getRuntime().availableProcessors() / 2;
            int threads = act_cores + (act_cores / 2);

            String file1 = parameter().getString("boundary");
            File file_1 = attachments().getFile(file1);
            String boundary_path = file_1.getPath();

            run(threads, workspace().getDir(), boundary_path, result_ID);
        } else {
            throw new ServiceException("No Boundary input listet!");
        }
    }

    private void run(Integer threads, File outputDir, String boundary_path, String result_ID) throws Exception {

        File ws = workspace().getDir();
        String wd = ws.toString();

        try {
            StringWriter err = new StringWriter();
            StringWriter output = new StringWriter();

            Executable ep = resources().getExe(PYTHON);
            File e1 = resources().getFile(CLEAN);

            if (LOG.isLoggable(Level.INFO)) {
                LOG.info(" #Cores : " + threads);
                LOG.info(" e4_path: " + e1.getPath());
            }

            ep.addArguments(e1.getAbsolutePath(),
                    boundary_path,
                    workspace().getFile("geometry_validated.shp")
            );
//            ep.redirectError(err);
//            ep.redirectOutput(output);
//            ep.redirectDefaults();

            if (LOG.isLoggable(Level.INFO)) {
                LOG.info(output.toString());
            }
            if (LOG.isLoggable(Level.SEVERE)) {
                LOG.severe(err.toString());
                ep.redirectError(err);
                ep.redirectOutput(output);
                ep.redirectDefaults();
            }

            int retee = ep.exec();

            if (retee != 0) {
                throw new ServiceException(" python validation Error : " + err);
            }
        } catch (ServiceException et) {
            LOG.info(" went wrong");
        } finally {
            LOG.info(" woohoo worked ;-) ");
        }

        try {
            Executable e = resources().getExe(OGR);
            e.addArguments("-t_srs",
                    "EPSG:5070",
                    workspace().getFile("boundary.shp"),
                    workspace().getFile("geometry_validated.shp")
            );
            e.exec();
        } catch (ServiceException | IOException et) {
            LOG.info(" went wrong");
        } finally {
            LOG.info(" woohoo worked ;-) ");
        }

        try {

            StringWriter err = new StringWriter();
            StringWriter output = new StringWriter();

            Executable e = resources().getExe(OGR);
            e.addArguments("-update",
                    "-append",
                    "-dialect",
                    "sqlite",
                    "-sql",
                    "select extent(geometry) from boundary",
                    workspace().getFile("index.shp"),
                    workspace().getFile("boundary.shp")
            );

            if (LOG.isLoggable(Level.INFO)) {
                LOG.info(output.toString());
            }
            if (LOG.isLoggable(Level.SEVERE)) {
                LOG.severe(err.toString());
                e.redirectError(err);
                e.redirectOutput(output);
                e.redirectDefaults();
            }

            int retee = e.exec();

            if (retee != 0) {
                throw new ServiceException("OGR 2 Error : " + err);
            }
        } catch (ServiceException et) {
            LOG.info(" went wrong");
        } finally {
            LOG.info(" woohoo worked ;-) ");
        }

        try {
            StringWriter err = new StringWriter();
            StringWriter output = new StringWriter();

            Executable e = resources().getExe(GDAL);
            e.addArguments(LOCATION_MNT_DATA1 + "/DEM.vrt",
                    workspace().getFile("DEM_clip.tif"),
                    "-crop_to_cutline",
                    "-cutline",
                    workspace().getFile("index.shp"),
                    //workspace().getFile("boundary.shp")
                    "-multi",
                    "-ot", "Float32",
                    "-co", "NUM_THREADS=" + threads + "",
                    "-wo", "NUM_THREADS=" + threads + "",
                    "--config",
                    "GDAL_CACHEMAX", "1000",
                    "-wm", "1000"
            );

            if (LOG.isLoggable(Level.INFO)) {
                LOG.info(output.toString());
            }
            if (LOG.isLoggable(Level.SEVERE)) {
                LOG.severe(err.toString());
                e.redirectError(err);
                e.redirectOutput(output);
                e.redirectDefaults();
            }

            int retee = e.exec();

            if (retee != 0) {
                throw new ServiceException("Error : " + err);
            }
        } catch (ServiceException | IOException et) {
            LOG.info(" went wrong");
        } finally {
            LOG.info(" woohoo worked ;-) ");
        }

        try {
            Executable ee1 = resources().getExe(MPI);
            File e2 = resources().getFile(PITREMOVE);

            ee1.addArguments("--allow-run-as-root",
                    "--path", e2.getParent(),
                    "-wdir", workspace().getDir(),
                    "--oversubscribe",
                    "-np", threads,
                    e2.getName(),
                    "-z", workspace().getFile("DEM_clip.tif"),
                    "-fel", workspace().getFile("dem_fill.tif")
            );

            StringWriter err = new StringWriter();
            StringWriter output = new StringWriter();

            int retee = ee1.exec();

            if (LOG.isLoggable(Level.INFO)) {
                LOG.info(output.toString());
            }
            if (LOG.isLoggable(Level.SEVERE)) {
                LOG.severe(err.toString());
                ee1.redirectError(err);
                ee1.redirectOutput(output);
                ee1.redirectDefaults();
            }

            if (retee != 0) {
                throw new ServiceException("Error pitremove: " + err.toString());
            }
        } catch (ServiceException | IOException et) {
            LOG.info(" went wrong");
        } finally {
            LOG.info(" woohoo worked ;-) ");
        }

        try {
            Executable ee2 = resources().getExe(MPI);
            File e3 = resources().getFile(DINF);

            ee2.addArguments("--allow-run-as-root",
                    "--path", e3.getParent(),
                    "-wdir", workspace().getDir(),
                    "--oversubscribe",
                    "-np", threads,
                    e3.getName(),
                    "-fel", workspace().getFile("dem_fill.tif"),
                    "-slp", workspace().getFile("slp.tif"),
                    "-ang", workspace().getFile("ang.tif")
            );
            StringWriter err = new StringWriter();
            StringWriter output = new StringWriter();

            int retee = ee2.exec();

            if (LOG.isLoggable(Level.INFO)) {
                LOG.info(output.toString());
            }
            if (LOG.isLoggable(Level.SEVERE)) {
                LOG.severe(err.toString());
                ee2.redirectError(err);
                ee2.redirectOutput(output);
                ee2.redirectDefaults();
            }

            if (retee != 0) {
                throw new ServiceException("Error D_infinity: " + err.toString());
            }
        } catch (ServiceException | IOException et) {
            LOG.info(" went wrong");
        } finally {
            LOG.info(" woohoo worked ;-) ");
        }

        try {

            Executable ee3 = resources().getExe(MPI);

            File e4 = resources().getFile(AREADINF);
            ee3.addArguments("--allow-run-as-root",
                    "--path", e4.getParent(),
                    "-wdir", workspace().getDir(),
                    "--oversubscribe",
                    "-np", threads,
                    e4.getName(),
                    "-ang", workspace().getFile("ang.tif"),
                    "-sca", workspace().getFile("sca.tif"),
                    "-nc"
            );
            StringWriter err = new StringWriter();
            StringWriter output = new StringWriter();
            ee3.redirectError(err);
            ee3.redirectOutput(output);
            ee3.redirectDefaults();

            int retee = ee3.exec();

            if (LOG.isLoggable(Level.INFO)) {
                LOG.info(output.toString());
            }
            if (LOG.isLoggable(Level.SEVERE)) {
                LOG.severe(err.toString());
            }

            if (retee != 0) {
                throw new ServiceException("Error DArea_infinity: " + err.toString());
            }
        } catch (ServiceException | IOException et) {
            LOG.info(" went wrong");
        } finally {
            LOG.info(" woohoo worked ;-) ");
        }

        Executable e = resources().getExe(GDALCALC);
        e.addArguments("-A",
                workspace().getFile("slp.tif"),
                "--outfile=" + workspace().getFile("slope.tif"),
                "--overwrite",
                "--calc",
                "0.0001*(A==0)+A*(A>0)",
                "--NoDataValue=0"
        );
        e.exec();

        try {
            StringWriter err = new StringWriter();
            StringWriter output = new StringWriter();

            e = resources().getExe(GDALTRANSLATE);
            e.addArguments("-of",
                    "GTiff",
                    workspace().getFile("sca.tif"),
                    workspace().getFile("sca_2.tif"),
                    "-co", "NUM_THREADS=" + threads + "",
                    "--config",
                    "GDAL_CACHEMAX", "1000",
                    "-a_nodata",
                    "-32768"
            );

            if (LOG.isLoggable(Level.INFO)) {
                LOG.info(output.toString());
            }
            if (LOG.isLoggable(Level.SEVERE)) {
                LOG.severe(err.toString());
                e.redirectError(err);
                e.redirectOutput(output);
                e.redirectDefaults();
            }

            int retee = e.exec();

            if (retee != 0) {
                throw new ServiceException("gdal_translate 1 Error : " + err);
            }
        } catch (ServiceException et) {
            LOG.info(" went wrong");
        } finally {
            LOG.info(" woohoo worked ;-) ");
        }

        e = resources().getExe(GDALCALC);
        e.addArguments("-A",
                workspace().getFile("sca_2.tif"),
                "--outfile=" + workspace().getFile("acc.tif"),
                "--overwrite",
                "--calc",
                "1*(A<=0)+(A+1)*(A>0)",
                "--NoDataValue=0"
        );
        e.exec();

        e = resources().getExe(GDALCALC);
        e.addArguments(
                "-A", workspace().getFile("acc.tif"),
                "-B", workspace().getFile("slope.tif"),
                "--outfile=" + workspace().getFile("TI.tif"),
                "--overwrite",
                "--calc",
                // 900 is the area of the pixel of NHDPlusV2.0 DEM because the x, y size is each 30m. If difference DEM is used, please update the area of pixel.
                "1*(A==0)+log(900*A/B)*(A>0)",
                "--NoDataValue=-32768"
        );
        e.exec();

        boolean Python_zonal = Python_zonal(resources().getExe(PYTHON),
                resources().getFile(ZONALSTATS),
                workspace().getFile("boundary.shp"),
                workspace().getFile("TI.tif"),
                result_ID,
                "TI_",
                "False",
                LOG
        );

    }

    // 3) provide the temperature as a result.
    @Override
    protected void postProcess() throws Exception {

        File ws = workspace().getDir();
//        results().put(new File(ws, "TI.tif"), "Topography index");
//        results().put(new File(ws, "results.csv"), "result");

    }

}