oms3.dsl.esp.Esp Maven / Gradle / Ivy
/*
* $Id: Esp.java 98fef14c747e 2014-12-26 [email protected] $
*
* This file is part of the Object Modeling System (OMS),
* 2007-2012, Olaf David and others, Colorado State University.
*
* OMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1.
*
* OMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OMS. If not, see .
*/
package oms3.dsl.esp;
import java.io.File;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import ngmf.util.UnifiedParams;
import oms3.ComponentAccess;
import oms3.annotations.Execute;
import oms3.annotations.Finalize;
import oms3.annotations.Initialize;
import oms3.dsl.*;
import oms3.io.CSTable;
import oms3.io.CSVTableWriter;
import oms3.io.DataIO;
import oms3.util.Dates;
public class Esp extends AbstractSimulation {
String hist_years;
String esp_dates;
boolean timing = false;
@Override
public Buildable create(Object name, Object value) {
if (name.equals("historical_years")) {
hist_years = value.toString();
} else if (name.equals("esp_dates")) {
esp_dates = value.toString();
} else if (name.equals("timing")) {
timing = (Boolean) value;
} else {
return super.create(name, value);
}
return LEAF;
}
@Override
public Object run() throws Exception {
super.run();
if (hist_years == null) {
throw new IllegalArgumentException("missing 'historical_years'.");
}
if (esp_dates == null) {
throw new IllegalArgumentException("missing 'esp_dates'.");
}
int[] h_years = Dates.parseHistoricalYears(hist_years);
Date[] dates = Dates.parseESPDates(esp_dates);
final Calendar init_start = new GregorianCalendar();
init_start.setTime(dates[0]);
final Calendar init_end = new GregorianCalendar();
init_end.setTime(dates[1]);
init_end.add(Calendar.DATE, -1);
final Calendar fcst_end = new GregorianCalendar();
fcst_end.setTime(dates[2]);
final int fc = (int) Dates.diffDayPeriods(init_end, fcst_end);
if (fc > 365 || fc < 1) {
throw new IllegalArgumentException("adjust the dates, forecast days must be: 1..365");
}
// setup component logging
Logger.getLogger("oms3.model").setLevel(Level.OFF);
Logging l = getModelElement().getComponentLogging();
Map cl = l.getCompLevels();
for (String compname : cl.keySet()) {
String cll = cl.get(compname);
Level level = Level.parse(cll);
Logger logger = Logger.getLogger("oms3.model." + compname);
logger.setUseParentHandlers(false);
logger.setLevel(level);
ConsoleHandler ch = new ConsoleHandler();
ch.setLevel(level);
ch.setFormatter(new GenericBuilderSupport.CompLR());
logger.addHandler(ch);
}
final File lastFolder = getOutputPath();
lastFolder.mkdirs();
PrintWriter res = new PrintWriter(new File(lastFolder, "result.csv"));
res.println("@S, Result");
// setting parameter;
final UnifiedParams parameter = getModelElement().getParameter();
parameter.putNewParamValue("startTime", init_start);
parameter.putNewParamValue("endTime", fcst_end);
System.out.print("Running ESP Traces ");
long start = System.currentTimeMillis();
// create all input traces files
createTraces(h_years[0], h_years[1], lastFolder, parameter, init_start.getTime(), init_end.getTime(), fc);
// parallel
final CountDownLatch latch = new CountDownLatch(h_years[1] - h_years[0] + 1);
int th = Integer.getInteger("esp.threads", 2);
ExecutorService executor = Executors.newFixedThreadPool(Math.max(th, 1));
List> traces = new ArrayList>();
for (int year = h_years[0]; year <= h_years[1]; year++) {
final int y = year;
Future f = executor.submit(new Callable() {
@Override
public String call() {
try {
String fn = runTrace(y, lastFolder, parameter);
return y + ", \"" + fn + "\"";
} catch (Throwable ex) {
System.err.println("Error in ESP run in year : " + y + " (" + ex.getMessage() + ")");
return y + ", Error in ESP run (" + ex.getMessage() + ")";
} finally {
Runtime.getRuntime().gc();
latch.countDown();
}
}
});
traces.add(f);
}
latch.await();
long end = System.currentTimeMillis();
for (Future trace : traces) {
res.println(" trace." + trace.get());
}
executor.shutdown();
res.println(" " + DataIO.KEY_ESP_DATES + ", " + esp_dates);
res.println(" " + DataIO.KEY_HIST_YEARS + ", " + hist_years);
res.close();
System.out.println();
if (timing) {
System.out.println("Total ESP time: " + (double) (end - start) / 1000 + " seconds");
}
return null;
}
private void createTraces(int firstyear, int lastyear, final File lastFolder, UnifiedParams parameter,
final Date init_start, Date init_end, final int fc) throws Exception {
Object comp = getModelElement().newModelComponent();
Class comp_class = comp.getClass();
log.config("Init ...");
ComponentAccess.callAnnotated(comp, Initialize.class, true);
// boolean success = ComponentAccess.setInputData(parameter.getParams(), comp, log);
boolean success = parameter.setInputData(comp, log);
if (!success) {
throw new Exception("There are Parameter problems. Simulation exits.");
}
ComponentAccess.adjustOutputPath(lastFolder, comp, log);
final File input_file = (File) comp_class.getField("inputFile").get(comp);
final CSTable table = DataIO.table(input_file, "obs");
final int dateColumn = 1;
// Forecast start = end of initialzation + 1 day
Calendar fcStartCal = new GregorianCalendar();
fcStartCal.setTime(init_end);
fcStartCal.add(Calendar.DATE, 1);
final Date fcStart = fcStartCal.getTime();
// get the initialization period
int[] it = DataIO.sliceByTime(table, dateColumn, init_start, init_end);
final List iniRows = DataIO.extractRows(table, it[0], it[1]);
final Map table_meta = DataIO.columnMetaData(table);
final List table_col_names = DataIO.columnNames(table);
final CountDownLatch latch = new CountDownLatch(lastyear - firstyear + 1);
ExecutorService executor = Executors.newFixedThreadPool(Integer.getInteger("esp.numthreads", 2));
for (int y = firstyear; y <= lastyear; y++) {
final int year = y;
executor.submit(new Callable() {
@Override
public Void call() {
try {
DateFormat hfmt = DataIO.lookupDateFormat(table, dateColumn);
System.out.print(".");
System.out.flush();
// set the historical date to the forcast date, but use the
// historical year.
Calendar histStart = new GregorianCalendar();
histStart.setTime(fcStart);
histStart.set(Calendar.YEAR, year);
// get the historical data
int histStartRow = DataIO.findRowByDate(histStart.getTime(), dateColumn, table);
int histEndRow = histStartRow + (fc - 1);
List histRows = DataIO.extractRows(table, histStartRow, histEndRow);
Calendar fcCurrent = new GregorianCalendar();
fcCurrent.setTime(fcStart);
for (int i = 0; i <= (fc - 1); i++) {
histRows.get(i)[1] = hfmt.format(fcCurrent.getTime());
fcCurrent.add(Calendar.DATE, 1);
}
fcCurrent.add(Calendar.DATE, -1);
Map meta = new LinkedHashMap(table.getInfo());
meta.put(DataIO.DATE_START, hfmt.format(init_start));
meta.put(DataIO.KEY_FC_START, hfmt.format(fcStart));
meta.put(DataIO.KEY_FC_DAYS, Integer.toString(fc));
meta.put(DataIO.KEY_HIST_YEAR, Integer.toString(year));
meta.put(DataIO.DATE_END, hfmt.format(fcCurrent.getTime()));
File new_inputFile = new File(lastFolder, "esp-" + year + "-" + input_file.getName());
PrintWriter w = new PrintWriter(new_inputFile);
CSVTableWriter tw = new CSVTableWriter(w, table.getName(), meta);
tw.writeHeader(table_meta, table_col_names);
// historical date -> forecast date.
tw.writeRows(iniRows, 1);
tw.writeRows(histRows, 1);
w.close();
return null;
} catch (Throwable ex) {
System.err.println("Error Data year : " + year + " (" + ex.getMessage() + ")");
} finally {
latch.countDown();
}
return null;
}
});
}
latch.await();
executor.shutdown();
Runtime.getRuntime().gc();
}
/**
* Run a single trace.
*
* @param year
* @param lastFolder
* @param parameter
* @param init_start
* @param init_end
* @param fc
* @return
* @throws Exception
*/
private String runTrace(int year, File lastFolder, UnifiedParams parameter) throws Exception {
System.out.print(" " + year);
System.out.flush();
Object comp = getModelElement().newModelComponent();
Class comp_class = comp.getClass();
log.config("Init ...");
ComponentAccess.callAnnotated(comp, Initialize.class, true);
// boolean success = ComponentAccess.setInputData(parameter.getParams(), comp, log);
boolean success = parameter.setInputData(comp, log);
if (!success) {
throw new Exception("There are Parameter problems. Simulation exits.");
}
ComponentAccess.adjustOutputPath(lastFolder, comp, log);
File input_file = (File) comp_class.getField("inputFile").get(comp);
File out_file = (File) comp_class.getField("outFile").get(comp);
File new_outFile = new File(out_file.getParent(), "esp-" + year + "-" + out_file.getName());
File new_inputFile = new File(lastFolder, "esp-" + year + "-" + input_file.getName());
comp_class.getField("inputFile").set(comp, new_inputFile);
comp_class.getField("outFile").set(comp, new_outFile);
// execute phases and be done.
log.config("Exec ...");
ComponentAccess.callAnnotated(comp, Execute.class, false);
log.config("Finalize ...");
ComponentAccess.callAnnotated(comp, Finalize.class, true);
return new_outFile.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy