V1_0.java [src/java/m/wrfhydro] Revision: 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.wrfhydro;
import csip.Config;
import csip.api.server.Executable;
import csip.ModelDataService;
import csip.api.server.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.HashMap;
import java.util.Map;
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 {
static final Map<String, String> def = new HashMap<String, String>() {
private static final long serialVersionUID = 1L;
{
put("HRLDAS_SETUP_FILE", "./DOMAIN/wrfinput_d01.nc");
put("INDIR", "./FORCING");
put("SPATIAL_FILENAME", "./DOMAIN/soil_properties.nc");
put("OUTDIR", "./");
put("RESTART_FILENAME_REQUESTED", "RESTART/RESTART.2011082600_DOMAIN1");
put("DYNAMIC_VEG_OPTION", "4");
put("CANOPY_STOMATAL_RESISTANCE_OPTION", "1");
put("BTR_OPTION", "1");
put("RUNOFF_OPTION", "3");
put("SURFACE_DRAG_OPTION", "1");
put("FROZEN_SOIL_OPTION", "1");
put("SUPERCOOLED_WATER_OPTION", "1");
put("RADIATIVE_TRANSFER_OPTION", "3");
put("SNOW_ALBEDO_OPTION", "2");
put("PCP_PARTITION_OPTION", "1");
put("TBOT_OPTION", "2");
put("TEMP_TIME_SCHEME_OPTION", "3");
put("GLACIER_OPTION", "2");
put("SURFACE_RESISTANCE_OPTION", "4");
put("FORCING_TIMESTEP", "3600");
put("NOAH_TIMESTEP", "3600");
put("OUTPUT_TIMESTEP", "3600");
put("RESTART_FREQUENCY_HOURS", "24");
put("SPLIT_OUTPUT_COUNT", "1");
put("SOIL_THICK_INPUT_1", "0.10");
put("SOIL_THICK_INPUT_2", "0.30");
put("SOIL_THICK_INPUT_3", "0.60");
put("SOIL_THICK_INPUT_4", "1.00");
put("ZLVL", "10.0");
put("rst_bi_in", "0");
put("rst_bi_out", "0");
put("FORC_TYP", "1");
}
};
public class Option {
public String get(String option) throws ServiceException {
return parameter().getString(option, def.get(option));
}
}
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";
Calendar cal = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("YYYY-MM-dd HH:mm");
String kday_or_hour;
@Override
protected void preProcess() throws Exception {
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", workspace().getDir(),
"-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);
context.put("option", new Option());
FileWriter w = new FileWriter(workspace().getFile(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(workspace().getFile(NAMELIST_HRLDAS)));
}
return NAMELIST_HRLDAS;
}
public static void onContextInit() {
velocity.setProperty("file.resource.loader.class",
ClasspathResourceLoader.class.getName());
velocity.init();
}
public int getSTART_YEAR() {
return cal.get(Calendar.YEAR);
}
public int getSTART_MONTH() {
return cal.get(Calendar.MONTH) + 1;
}
public int getSTART_DAY() {
return cal.get(Calendar.DAY_OF_MONTH);
}
public int getSTART_HOUR() {
return cal.get(Calendar.HOUR_OF_DAY);
}
public int getSTART_MIN() {
return cal.get(Calendar.MINUTE);
}
public String getKINFO() {
return kday_or_hour;
}
}