oms3.dsl.cosu.Luca Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of oms Show documentation
Show all versions of oms Show documentation
Object Modeling System (OMS) is a pure Java object-oriented framework.
OMS v3.+ is a highly interoperable and lightweight modeling framework for component-based model and simulation development on multiple platforms.
/*
* $Id: Luca.java b658fd839d45 2016-05-13 [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.cosu;
import java.io.FileNotFoundException;
import oms3.dsl.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import ngmf.util.UnifiedParams;
import ngmf.util.cosu.luca.ExecutionHandle;
import ngmf.util.cosu.luca.SCE;
import oms3.ComponentAccess;
import oms3.ComponentException;
import oms3.Conversions;
import oms3.annotations.Execute;
import oms3.annotations.Finalize;
import oms3.annotations.Initialize;
import oms3.dsl.cosu.Step.Data;
import oms3.io.DataIO;
import oms3.io.CSProperties;
import ngmf.util.cosu.luca.ParameterData;
// initial parameter settings (reading)
// calibration date/time settings.
//
public class Luca extends AbstractSimulation {
protected List steps = new ArrayList<>();
//
Date calib_start; // Calibration start date
int startMonthOfYear = 1;
int rounds = 1; // number of rounds
String traceFileName = null;
Date startTime;
Date endTime;
List existingFiles = new ArrayList<>();
SummaryWriter summary = new SummaryWriter();
CollectOutput c;
boolean model_stdout = true;
boolean model_stderr = true;
@Override
public Buildable create(Object name, Object value) {
if (name.equals(Step.DSL_NAME)) {
Step step = new Step(steps.size() + 1);
steps.add(step);
return step;
} else if (name.equals("rounds")) {
rounds = (Integer) value;
if (rounds < 1) {
throw new ComponentException("Illegal 'rounds': " + rounds);
}
} else if (name.equals("calibration_start")) {
calib_start = Conversions.convert(value, Date.class);
} else if (name.equals("run_start")) {
startTime = Conversions.convert(value, Date.class);
} else if (name.equals("run_end")) {
endTime = Conversions.convert(value, Date.class);
} else if (name.equals("start_month_of_year")) {
startMonthOfYear = (Integer) value - 1;
if ((startMonthOfYear < 0) || (startMonthOfYear > 11)) {
throw new ComponentException("start_month_of_year must be between 1-12 for Jan-Dec.");
}
} else if (name.equals("summary_file")) {
String fname = value.toString();
summary.setFile(fname);
} else if (name.equals("trace_file")) {
traceFileName = value.toString();
} else if (name.equals("model_stdout")) {
model_stdout = (Boolean) value;
} else if (name.equals("model_stderr")) {
model_stderr = (Boolean) value;
} else if (name.equals("collect_output")) {
c = new CollectOutput();
return c;
} else {
return super.create(name, value);
}
return LEAF;
}
@Override
public Object run() throws Exception {
super.run();
if (calib_start == null) {
throw new ComponentException("missing 'calibration_start'");
}
if (steps.isEmpty()) {
throw new ComponentException("missing 'step' definition(s)");
}
ModelExecution exec = new ModelExecution();
if (startTime == null && endTime == null) {
Object start = exec.getParameter().getParamValue("startTime");
Object end = exec.getParameter().getParamValue("endTime");
if (start == null || end == null) {
throw new ComponentException("missing: run_start/run_end or model parameter startTime/endTime: ");
}
startTime = Conversions.convert(start, Date.class);
endTime = Conversions.convert(end, Date.class);
}
if (calib_start.after(endTime)) {
throw new ComponentException("illegal calibration_start: " + calib_start);
}
for (Step step : steps) {
step.init(exec, startMonthOfYear, calib_start, endTime, rounds);
}
// Send info to summary writer
String outFolder = steps.get(0).outFolder.getAbsolutePath();
summary.setModelInfo(rounds, steps.size(), getModelElement().getClassname(),
getModelElement().getParams(), calib_start, startTime, endTime, outFolder);
for (int s = 0; s < steps.size(); s++) {
Step step = steps.get(s);
Data stepData = step.round()[0];
SCE initSce = new SCE(exec, step, stepData, exec.lastFolder, traceFileName, false);
double origOF = initSce.getInitialOF();
stepData.setObjFuncValueOfBestPoint(origOF);
summary.writeInitialStep(s, step, stepData, origOF);
}
// Call SCE for each step of each round.
for (int r = 0; r < rounds; r++) {
for (int s = 0; s < steps.size(); s++) {
Step step = steps.get(s);
Data stepData = step.round()[r];
//
System.out.println("\n\n>>>>>>>>>>>>>> Round [" + (r + 1) + "] Step [" + step.getName() + "] <<<<<<<<<<<<<<");
SCE sce = new SCE(exec, step, stepData, exec.lastFolder, traceFileName, true);
double finalOF = sce.run(stepData.getObjFuncValueOfBestPoint());
int numIterations = sce.getNumIterations();
// Step step0 = steps.get(0);
summary.writeStep(r, s, step, stepData, finalOF, numIterations);
exec.writeParameterCopy(step, r);
postToSteps(s, r);
Runtime.getRuntime().gc();
}
for (int s = 0; s < steps.size(); s++) {
Step step = steps.get(s);
Data stepData = step.round()[r];
step.post(r, stepData);
}
}
summary.close();
return null;
}
void postToSteps(int s, int r) {
Step step = steps.get(s);
Data stepData = step.round()[r];
for (Step destStep : steps) {
Data otherStepData = destStep.round()[r];
// System.out.println("post Step " + step.getName() + "->" + destStep.getName());
Data.copyParamValuesDiffStepsSameRound(stepData, otherStepData);
}
}
// Model execution
//
final class ModelExecution implements ExecutionHandle {
File lastFolder;
UnifiedParams csParameter;
Logger logger; // reference to hold on to.
ModelExecution() throws IOException {
lastFolder = getOutputPath();
lastFolder.mkdirs();
csParameter = getModelElement().getParameter();
// write the initial parameter file (param-s0r0)
writeParameterCopy(null, -1);
// disable logging for all.
logger = Logger.getLogger("oms3.model");
logger.setLevel(Level.OFF);
logger.setUseParentHandlers(false);
}
UnifiedParams getParameter() {
return csParameter;
}
PrintStream nullOutStream = new PrintStream(new OutputStream() {
@Override
public void write(int b) {
}
});
PrintStream nullErrStream = new PrintStream(new OutputStream() {
@Override
public void write(int b) {
}
});
@Override
public void execute(Step s, Step.Data step, int it) throws Exception {
PrintStream save_out = null;
PrintStream save_err = null;
if (!model_stdout) {
System.out.flush();
save_out = System.out;
System.setOut(nullOutStream);
}
if (!model_stderr) {
System.err.flush();
save_err = System.err;
System.setErr(nullErrStream);
}
// Path
String libPath = getModelElement().getLibpath();
if (libPath != null) {
System.setProperty("jna.library.path", libPath);
if (log.isLoggable(Level.CONFIG)) {
log.config("Setting jna.library.path to " + libPath);
}
}
Object comp = getModelElement().newModelComponent();
writeParameterFile(step);
log.config("Init ...");
ComponentAccess.callAnnotated(comp, Initialize.class, true);
// setting the input data;
boolean success = getParameter().setInputData(comp, log);
if (!success) {
throw new RuntimeException("There are Parameter problems. Simulation exits.");
}
ComponentAccess.adjustOutputPath(lastFolder, comp, log);
for (Output e : getOut()) {
e.setup(comp, lastFolder, getName());
}
// execute phases and be done.
log.config("Exec ...");
ComponentAccess.callAnnotated(comp, Execute.class, false);
log.config("Finalize ...");
ComponentAccess.callAnnotated(comp, Finalize.class, true);
for (Output e : getOut()) {
e.done();
}
if (save_out != null) {
System.setOut(save_out);
}
if (save_err != null) {
System.setErr(save_err);
}
if (c != null) {
c.collect("# round: " + (step.getRound() + 1) + ", step: " + s.getNumber() + ", iter: " + it);
}
}
@Override
public void writeParameterFile(Step.Data step) {
ParameterData[] paramData = step.paramData;
for (int i = 0; i < paramData.length; i++) {
String name = paramData[i].getName();
// System.out.println("NAME " + name);
int calibType = paramData[i].getCalibrationType();
double[] val = paramData[i].getDataValue();
//if (name.equals("gwflow_coef")) {
// String a = Arrays.toString(val);
// System.out.println("\n write: gwflow_coef " + a.substring(0, 250));
//}
double[][] val2D = Conversions.unrollDoubleArray(val, paramData[i].getRowSize());
Object valSel = (paramData[i].getRowSize() > 1) ? val2D : val;
if (calibType == ParameterData.BINARY) {
int[] ival = Conversions.convert(val, int[].class);
csParameter.putParamValue(name, csParameter.toValueI(name, ival));
} else {
csParameter.putParamValue(name, csParameter.toValue(name, valSel));
}
}
}
void writeParameterCopy(Step step, int round) throws FileNotFoundException {
StringBuilder val = new StringBuilder();
String name = "0";
if (step != null) {
name = step.getName();
for (Param param : step.params.getParam()) {
val.append(" ").append(param.getName());
}
}
StringBuilder files = new StringBuilder();
for (Params param : getModelElement().getParams()) {
if (param.getFile() != null) {
files.append(" ").append(param.getFile());
}
}
File params = new File(lastFolder, "params-r" + (round + 1) + "s" + name + ".csv");
System.out.println(" Final parameter file: '" + params + "'");
PrintWriter pw = new PrintWriter(params);
CSProperties csp = csParameter.getParams();
csp.setName("Parameter");
csp.getInfo().put("round", Integer.toString(round + 1));
csp.getInfo().put("step", name);
csp.getInfo().put("step_params", val.toString().trim());
csp.getInfo().put("calibration_start", calib_start.toString());
csp.getInfo().put("luca_name", getName());
if (getModelElement().getClassname() != null) {
csp.getInfo().put("model_class", getModelElement().getClassname());
}
if (files.length() > 0) {
csp.getInfo().put("param_files", files.toString().trim());
}
DataIO.printWithTables(csp, pw);
pw.close();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy