RhemModel.java [src/java/m/rhem/model] Revision: default Date:
package m.rhem.model;
import csip.api.server.ServiceException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.apache.commons.io.FileUtils;
import static rhem.utils.RHEMUtils.formatDouble;
/**
*
* @author rumpal
*/
public class RhemModel {
static final List<String> INTL = Arrays.asList("INTL_AF", "INTL_SA");
String scenarioName;
File workSpaceDir;
String parameterFileName;
String stormFileName;
String runFileName;
String summaryFileName;
double avgSoilLoss;
public RhemModel(String scenarioName, File workSpaceDir, String parameterFileName,
String stormFileName, String runFileName, String summaryFileName) {
this.scenarioName = scenarioName;
this.workSpaceDir = workSpaceDir;
this.parameterFileName = parameterFileName;
this.stormFileName = stormFileName;
this.runFileName = runFileName;
this.summaryFileName = summaryFileName;
}
public void generateParamFile(Parameter param) throws ServiceException {
try ( PrintWriter w = new PrintWriter(new File(workSpaceDir, parameterFileName))) {
String now = new SimpleDateFormat("MMMM dd, YYYY, hh:mm a").format(new Date());
w.println("! Parameter file for scenario: " + scenarioName);
w.println("! Date built: " + now + " (Version 2.3)");
w.println("! Parameter units: DIAMS(mm), DENSITY(g/cc),TEMP(deg C)");
w.println("BEGIN GLOBAL");
w.println(String.format(" %-8s= %s", "CLEN", param.clen));
w.println(String.format(" %-8s= %s", "UNITS", "metric"));
w.println(String.format(" %-8s= %s", "DIAMS", param.diams));
w.println(String.format(" %-8s= %s", "DENSITY", param.density));
w.println(String.format(" %-8s= %s", "TEMP", 40));
w.println(String.format(" %-8s= %s", "NELE", 1));
w.println("END GLOBAL");
w.println("BEGIN PLANE");
w.println(String.format(" %-8s= %s", "ID", 1));
w.println(String.format(" %-8s= %s", "LEN", param.len));
w.println(String.format(" %-8s= %s", "WIDTH", 1.0));
w.println(String.format(" %-8s= %s", "CHEZY", param.chezy));
w.println(String.format(" %-8s= %s", "RCHEZY", param.rchezy));
w.println(String.format(" %-8s= %s", "SL", param.sl));
w.println(String.format(" %-8s= %s", "SX", param.sx));
w.println(String.format(" %-8s= %s", "CV", param.cv));
w.println(String.format(" %-8s= %s", "SAT", param.sat));
w.println(String.format(" %-8s= %s", "PR", 1));
w.println(String.format(" %-8s= %s", "KSS", param.kss));
w.println(String.format(" %-8s= %s", "KOMEGA", param.komega));
w.println(String.format(" %-8s= %s", "KCM", param.kcm));
w.println(String.format(" %-8s= %s", "CA", 1.0));
w.println(String.format(" %-8s= %s", "IN", 0.0));
w.println(String.format(" %-8s= %s", "KE", param.ke));
w.println(String.format(" %-8s= %s", "G", param.g));
w.println(String.format(" %-8s= %s", "DIST", param.dist));
w.println(String.format(" %-8s= %s", "POR", param.por));
w.println(String.format(" %-8s= %s", "ROCK", 0.00));
w.println(String.format(" %-8s= %s", "SMAX", param.smax));
w.println(String.format(" %-8s= %s", "ADF", param.adf));
w.println(String.format(" %-8s= %s", "ALF", param.alf));
w.println(String.format(" %-8s= %s", "BARE", param.bare));
w.println(String.format(" %-8s= %s", "RSP", 1.0));
w.println(String.format(" %-8s= %s", "SPACING", 1.0));
w.println(String.format(" %-8s= %s", "FRACT", param.fract));
w.println("END PLANE");
} catch (IOException E) {
throw new ServiceException("Problem in generating the parameter file.", E);
}
}
public void generateStormFile(String cligen_db, double Ke, String stateId, String climatestationId)
throws ServiceException, URISyntaxException {
try {
String pref = getLocPrefix(stateId);
if (isIntl(stateId)) {
// International stations
Path cs = Paths.get(cligen_db, pref, climatestationId + ".txt");
if (!Files.exists(cs))
throw new ServiceException("International climate station not found: " + climatestationId + ".txt for " + stateId);
try {
Files.createSymbolicLink(Paths.get(workSpaceDir.toString(), stormFileName), cs);
} catch (IOException E) {
throw new ServiceException("Error creating workspace link for: " + cs.toString(), E);
}
return;
}
// US stations
Path f = Paths.get(cligen_db, pref, "300yr", pref + "_" + climatestationId + "_300yr.out");
if (!Files.exists(f))
throw new ServiceException("US climate station not found: " + climatestationId + "_300yr.out for " + stateId);
long counter = 0;
try ( BufferedReader r = new BufferedReader(new FileReader(f.toFile()))) {
File tempFile = new File(workSpaceDir, "tempSummaryFile.pre");
try ( PrintWriter w = new PrintWriter(tempFile)) {
for (int i = 0; i <= 17; i++) {
r.readLine();
}
String line;
while ((line = r.readLine()) != null) {
String[] test = line.split("\\s+");
double keComparison = Double.parseDouble(test[8]) * (Double.parseDouble(test[5]) / Double.parseDouble(test[6]));
if (Ke < keComparison && test.length > 8) {
counter++;
w.println(String.format(" %-5s %-5s %-5s %-5s %-5s %-6s %-6s %-6s",
counter, test[2], test[3], test[4], test[5], test[6], test[7], test[8]));
}
}
}
appendInfo(tempFile, counter, stateId, climatestationId);
tempFile.delete();
}
} catch (IOException E) {
throw new ServiceException("Problem generating the storm file.", E);
}
}
void appendInfo(File tempFile, long counter, String stateId, String climatestationId) throws ServiceException {
try ( PrintWriter w = new PrintWriter(new File(workSpaceDir, stormFileName))) {
String now = new SimpleDateFormat("MMMM dd, YYYY, hh:mm a").format(new Date());
w.println("# Storm file for scenario: " + scenarioName);
w.println("# Date built: " + now + " (Version 2.3)");
w.println("# State: " + stateId);
w.println("# Climate Station: " + climatestationId);
w.println(counter + " # The number of rain events");
w.println("0 # Breakpoint data? (0 for no, 1 for yes)");
w.println("# id day month year Rain Dur Tp Ip");
w.println("# (mm) (h)");
try ( BufferedReader r = new BufferedReader(new FileReader(tempFile))) {
String line;
while ((line = r.readLine()) != null) {
w.println(line);
}
}
} catch (IOException E) {
throw new ServiceException("Problem in generating the storm file.", E);
}
}
public void generateRunFile() throws ServiceException, IOException {
FileUtils.writeStringToFile(new File(workSpaceDir, runFileName),
parameterFileName + ", " + stormFileName + ", "
+ summaryFileName + ", \"" + scenarioName + "\", 0, 2, y, y, n, n, y");
}
public void appendToSumFile(double avgYearlyPrecip) throws ServiceException {
DecimalFormat df = new DecimalFormat("#.#####");
File summaryFile = new File(workSpaceDir, summaryFileName);
File tempSummaryFile = new File(workSpaceDir, "temp_" + summaryFileName);
try ( PrintWriter w = new PrintWriter(tempSummaryFile)) {
w.println(" -ANNUAL-AVERAGES-");
w.println();
w.println(" Avg. Precipitation(mm/year)= " + df.format(avgYearlyPrecip));
try ( BufferedReader r = new BufferedReader(new FileReader(summaryFile))) {
for (int i = 0; i < 3; i++) {
r.readLine();
}
String line;
while ((line = r.readLine()) != null) {
if (line.toLowerCase().contains("variable")) {
int c = 0;
while (c < 6) {
if (c != 0)
line = r.readLine();
String[] test = line.split("\\s+");
if (c == 2) {
w.print(String.format("%-25s", test[1] + test[2]));
for (int i = 3; i < test.length; i++) {
w.print(String.format("%-25s", test[i]));
}
} else {
for (int i = 1; i < test.length; i++) {
w.print(String.format("%-25s", test[i]));
}
}
w.println();
c++;
}
} else {
if (line.contains("Avg-Soil-Loss")) {
String asl = line.substring(line.indexOf('=') + 1);
avgSoilLoss = Double.parseDouble(asl.trim());
}
w.print(line);
w.println();
}
}
}
} catch (IOException E) {
throw new ServiceException("Problem in editing the summary file.", E);
}
summaryFile.delete();
tempSummaryFile.renameTo(summaryFile);
}
public String getTDS() {
return formatDouble((2.36 * (avgSoilLoss * 1000) + 0.99) / 1000.0);
}
public String getTDS(double asl) {
return formatDouble((2.36 * (asl * 1000) + 0.99) / 1000.0);
}
public boolean isIntl(String locId) {
return locId.toUpperCase().startsWith("INTL");
}
public String getLocPrefix(String locId) {
locId = locId.toUpperCase();
if (INTL.contains(locId))
return locId; // as is
if (!isIntl(locId))
return locId; // US: as is
return "INTL";
}
}