All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oms3.dsl.cosu.ObjFunc Maven / Gradle / Ivy

There is a newer version: 0.8.1
Show newest version
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package oms3.dsl.cosu;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import ngmf.util.cosu.luca.of.AbsoluteDifference;
import ngmf.util.cosu.luca.of.AbsoluteDifferenceLog;
import ngmf.util.cosu.luca.of.NashSutcliffe;
import ngmf.util.cosu.luca.of.NormalizedRMSE;
import ngmf.util.cosu.luca.of.PearsonsCorrelation;
import oms3.ObjectiveFunction;
import oms3.SimConst;
import oms3.dsl.Buildable;
import oms3.io.CSTable;
import oms3.io.DataIO;

/** Objective function handling. 
 *
 * @author od
 */
public class ObjFunc implements Buildable {

    double weight = Double.NaN;
    String timestep = SimConst.DAILY;
    ObjectiveFunction of;
    //
    CSVColumn sim;
    CSVColumn obs;

    public CSVColumn getSimulated() {
        if (sim == null) {
            throw new IllegalArgumentException("Missing 'sim' argument");
        }
        return sim;
    }

    public CSVColumn getObserved() {
        if (obs == null) {
            throw new IllegalArgumentException("Missing 'obs' argument");
        }
        return obs;
    }

    @Override
    public Buildable create(Object name, Object value) {
        if (name.equals("sim")) {
            return sim = new CSVColumn();
        } else if (name.equals("obs")) {
            return obs = new CSVColumn();
        }
        throw new IllegalArgumentException(name.toString());
    }

    public void setMethod(String method) {
        if (method.equals(SimConst.NS)) {
            of = new NashSutcliffe();
        } else if (method.equals(SimConst.RMSE)) {
            of = new NormalizedRMSE();
        } else if (method.equals(SimConst.ABSDIF)) {
            of = new AbsoluteDifference();
        } else if (method.equals(SimConst.LOGABSDIF)) {
            of = new AbsoluteDifferenceLog();
        } else if (method.equals(SimConst.PMCC)) {
            of = new PearsonsCorrelation();
        } else {
            try {
                // load this as a class name from default classpath
                Class c = Class.forName(method);
                of = (ObjectiveFunction) c.newInstance();
            } catch (Exception E) {
                throw new IllegalArgumentException("No such method: " + method);
            }
        }
    }

    public void setTimestep(String timestep) {
        if ((!timestep.equals(SimConst.DAILY)) && 
            (!timestep.equals(SimConst.DAILY_MEAN)) && 
            (!timestep.equals(SimConst.MONTHLY_MEAN)) &&
            (!timestep.equals(SimConst.MEAN_MONTHLY)) &&
            (!timestep.equals(SimConst.PERIOD_MAXIMUM)) &&
            (!timestep.equals(SimConst.PERIOD_MAXIMUM)) &&
            (!timestep.equals(SimConst.PERIOD_MININUM)) &&
            (!timestep.equals(SimConst.PERIOD_MEDIAN)) &&
            (!timestep.equals(SimConst.PERIOD_STANDARD_DEVIATION))
                )
           {
            throw new IllegalArgumentException("SetTimeStep:  Illegal timestep: " + timestep);
        }
        this.timestep = timestep;
    }

    public void setWeight(double weight) {
        if (weight <= 0 || weight > 1) {
            throw new IllegalArgumentException("of weight out of range: " + weight);
        }
        this.weight = weight;
    }

    String getTimestep() {
        return timestep;
    }

    double getWeight() {
        return weight;
    }

    ObjectiveFunction getOF() {
        if (of == null) {
            throw new IllegalArgumentException("No Objective function method defined.");
        }
        return of;
    }

    // static 
    public static boolean isInc(List ofs) {
        if (ofs.isEmpty()) {
            throw new IllegalArgumentException("No Objective function(s) defined. ");
        }
        boolean inc = ofs.get(0).getOF().positiveDirection();
        for (ObjFunc of : ofs) {
            if (of.getOF().positiveDirection() != inc) {
                throw new IllegalArgumentException("Objective function(s) optimization direction mismatch!");
            }
        }
        return inc;
    }

    public static void adjustWeights(List ofs) {
        int noOf = ofs.size();
        for (ObjFunc of : ofs) {
            if (Double.isNaN(of.getWeight())) {
                of.setWeight((double) 1 / noOf);
            }
        }
    }

    public static double calculateObjectiveFunctionValue(List ofs, Date start, Date end, File folder) {
        try {
            if (ofs.isEmpty()) {
                throw new IllegalArgumentException("No Objective function(s) defined. ");
            }
            double val = 0.0;
            double weight = 0.0;
            adjustWeights(ofs);

            for (ObjFunc of : ofs) {
                CSVColumn obs = of.getObserved();
                String timeStepString = of.getTimestep();
                int timeStep = DataIO.DAILY;
                if(timeStepString.equals(SimConst.DAILY)) timeStep = DataIO.DAILY;
                else if(timeStepString.equals(SimConst.MEAN_MONTHLY)) timeStep = DataIO.MEAN_MONTHLY;
                else if(timeStepString.equals(SimConst.MONTHLY_MEAN)) timeStep = DataIO.MONTHLY_MEAN;
                else if(timeStepString.equals(SimConst.ANNUAL_MEAN)) timeStep = DataIO.ANNUAL_MEAN;
                else if(timeStepString.equals(SimConst.PERIOD_MEAN)) timeStep = DataIO.PERIOD_MEAN;              
                else if(timeStepString.equals(SimConst.PERIOD_MEDIAN)) timeStep = DataIO.PERIOD_MEDIAN;
                else if(timeStepString.equals(SimConst.PERIOD_MININUM)) timeStep = DataIO.PERIOD_MIN;
                else if(timeStepString.equals(SimConst.PERIOD_MAXIMUM)) timeStep = DataIO.PERIOD_MAX;
                else if(timeStepString.equals(SimConst.PERIOD_STANDARD_DEVIATION)) timeStep = DataIO.PERIOD_STANDARD_DEVIATION;
                else throw new IllegalArgumentException("TimeStep " + timeStepString + "unknown.");
                
                CSTable tobs = DataIO.table(resolve(obs.getFile(), folder), obs.getTable());
                double[] obsval = DataIO.getColumnDoubleValuesInterval(start, end, tobs, obs.getColumn(), timeStep);
                
                CSVColumn sim = of.getSimulated();
                CSTable tsim = DataIO.table(resolve(sim.getFile(), folder), sim.getTable());
                double[] simval = DataIO.getColumnDoubleValuesInterval(start, end, tsim, sim.getColumn(), timeStep);

                weight += of.getWeight();
                val += of.getOF().calculate(obsval, simval, -90.0) * of.getWeight();
            }
            if (weight != 1.0) {
                throw new IllegalArgumentException("sum of of weights != 1.0");
            }
            return val;
        } catch (IOException E) {
            throw new RuntimeException(E);
        }
    }

    private static File resolve(String file, File out) {
        File f = new File(file);
        if (!(f.isAbsolute() && f.exists())) {
            f = new File(out, file);
        }
        if (!f.exists()) {
            throw new IllegalArgumentException("File not found: " + file);
        }
        return f;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy