V1_0.java [src/java/m/wrfhydro] Revision: 2532a991f3ba9072120ca4052801b6ddbf90e419  Date: Wed Apr 03 13:12:18 MDT 2019
/*
 * 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.wrfhydro;

import csip.Config;
import csip.Executable;
import csip.ModelDataService;
import csip.ServiceException;
import csip.annotations.Category;
import csip.annotations.Description;
import csip.annotations.Documentation;
import csip.annotations.Name;
import csip.annotations.Resource;
import static csip.annotations.ResourceType.*;
import csip.annotations.State;
import csip.annotations.VersionInfo;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Level;
import javax.ws.rs.Path;
import static m.wrfhydro.V1_0.*;
import org.apache.commons.io.FileUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;

/**
 * WRF-Hydro model.
 *
 * @author od
 */
@Name("WRF-Hydro")
@Description("WRF-Hydro is a model for flash flood prediction, "
    + "regional hydroclimate impacts assessment, seasonal forecasting "
    + "of water resources, and land-atmosphere coupling studies.")
@Documentation("https://ral.ucar.edu/projects/wrf_hydro/overview")
@State(State.STABLE)
@VersionInfo("$Id$")
@Category("Hydrology")
@Path("m/NoahMP/5.0.3")
@Resource(file = MPIRUN, type = REFERENCE, id = MPIRUN)
@Resource(file = "diag_hydro.* *stdout.txt *stderr.txt", type = OUTPUT)
public class V1_0 extends ModelDataService {

  public static final String MPIRUN = "mpirun";

  // in case the exe path needs adjustment.
  static String noahMP = Config.getString("wrf.hydro.noahMP.exe",
      "/usr/local/tomcat/WRF/wrf_hydro_NoahMP.exe");

  static VelocityEngine velocity = new VelocityEngine();

  static final String NAMELIST_HRLDAS = "namelist.hrldas";
  static final String NAMELIST_HRLDAS_VM = "m/wrfhydro/namelist.hrldas.vm";
  static final String MPIRUN_NP = "mpirun.np";

  String outdir;
  String indir;
  Calendar cal = Calendar.getInstance();
  SimpleDateFormat df = new SimpleDateFormat("YYYY-MM-dd HH:mm");

  String kday_or_hour;


  @Override
  protected void preProcess() throws Exception {
    outdir = parameter().getString("OUTDIR", "./");
    indir = parameter().getString("INDIR", "./FORCING");
    String start = parameter().getString("START", "2011-08-26 00:00");
    cal.setTime(df.parse(start));

    int kday = parameter().getInt("KDAY", -1);
    int khour = parameter().getInt("KHOUR", -1);

    if (kday == -1) {
      if (khour == -1) {
        throw new ServiceException("KHOUR or KDAY expected.");
      }
      kday_or_hour = "KHOUR = " + khour;
    } else {
      kday_or_hour = "KDAY = " + kday;
    }
  }


  @Override
  protected void doProcess() throws Exception {
    if (!new File(noahMP).exists()) {
      throw new ServiceException("Not found: " + noahMP);
    }

    createNamelist();

    // allow for np configuration
    int np = metainfo().getInt(MPIRUN_NP, 2);
    np = Config.getInt(MPIRUN_NP, np);

    Executable mpirun = resources().getExe(MPIRUN);
    mpirun.addArguments(
        "-wdir", getWorkspaceDir(),
        "-np", np,
        noahMP
    );

    int ret = mpirun.exec();
    if (ret != 0) {
      throw new ServiceException("Error running mpi wrf_hydro: " + ret);
    }
  }


  private String createNamelist() throws IOException {
    VelocityContext context = new VelocityContext();
    context.put("service", this);
    FileWriter w = new FileWriter(getWorkspaceFile(NAMELIST_HRLDAS));
    velocity.getTemplate(NAMELIST_HRLDAS_VM, "utf-8").merge(context, w);
    w.close();
    if (LOG.isLoggable(Level.INFO)) {
      LOG.info("Created: " + NAMELIST_HRLDAS);
      LOG.info(FileUtils.readFileToString(getWorkspaceFile(NAMELIST_HRLDAS)));
    }
    return NAMELIST_HRLDAS;
  }


  public static void onContextInit() {
    velocity.setProperty("file.resource.loader.class",
        ClasspathResourceLoader.class.getName());
    velocity.init();
  }


  // public properties for velocity
  public String getOutdir() {
    return outdir;
  }


  public String getIndir() {
    return indir;
  }


  public int getStartyear() {
    return cal.get(Calendar.YEAR);
  }


  public int getStartmonth() {
    return cal.get(Calendar.MONTH) + 1;
  }


  public int getStartday() {
    return cal.get(Calendar.DAY_OF_MONTH);
  }


  public int getStarthour() {
    return cal.get(Calendar.HOUR_OF_DAY);
  }


  public int getStartmin() {
    return cal.get(Calendar.MINUTE);
  }


  public String getkinfo() {
    return kday_or_hour;
  }

}