V1_0.java [src/java/m/cfa/errorstats] Revision: default  Date:
package m.cfa.errorstats;

import csip.ModelDataService;
import csip.api.server.PayloadParameter;
import csip.api.server.PayloadResults;
import csip.annotations.Description;
import csip.annotations.Name;
import csip.annotations.VersionInfo;
import java.io.IOException;
import javax.ws.rs.Path;
import m.cfa.DoubleArray;
import m.cfa.DoubleMath;

@Name("Error Statistics")
@Description("Time Series: Error Statistics for paired observation and modeled data")
@VersionInfo("1.0")
@Path("m/cfa/errorstats/1.0")
public class V1_0 extends ModelDataService {
    //Inputs
    private double[][] pairedData = new double[0][2];
    
    //Outputs
    private double mre = -1;     //Mean Relative Error (MRE)
    private double pbias = -1;   //Percent Bias (PBIAS)
    private double rSquare = -1; //Coefficient of Determination (R2)
    private double ns = -1;      //Nash-Sutcliffe Coefficient (NS)
    
    @Override
    protected void preProcess() throws Exception {
        PayloadParameter inputPayload = parameter();
        String pairedDataRaw = inputPayload.getString("paired_data");
        
        //If the list of points is of sufficient size and format, store it
        String[] rows = pairedDataRaw.split("\n");
        if(rows.length > 1){
            pairedData = new double[rows.length - 1][2];
            for(int i=1; i<rows.length; i++){//ignore header
                String[] columns = rows[i].split("\t");
                System.out.println(rows[i]);
                pairedData[i-1][0] = Double.parseDouble(columns[0]);
                pairedData[i-1][1] = Double.parseDouble(columns[1]);
            }
        }else{
            //if the list is empty or formatted wrong, thrown an error
            throw new IOException("The list of paired data provided is not in the expected tab-delimited format like: 'observed\tmodeled\n489\t550\n359\t320\n780\t790'");
        }
    }
    
    @Override
    protected void doProcess() throws Exception {
        double[] observedData = DoubleArray.getColumn(pairedData, 0);
        double[] modeledData = DoubleArray.getColumn(pairedData, 1);
        
        
        mre = DoubleMath.round(DoubleMath.MeanRelativeError(observedData, modeledData), 4);
        pbias = DoubleMath.round(DoubleMath.PercentBias(observedData, modeledData), 4);
        rSquare = DoubleMath.round(DoubleMath.Rsquare(observedData, modeledData), 4);
        ns = DoubleMath.round(DoubleMath.NashSutcliffe(observedData, modeledData), 4);
    }

    @Override
    protected void postProcess() throws Exception {
        PayloadResults resultPayload = results();
        // values
        resultPayload.put("len", pairedData.length);
        resultPayload.put("mre", mre, "Mean Relative Error statistic (MRE)", "");
        resultPayload.put("pbias", pbias, "Percent Bias error statistic (PBIAS)", "");
        resultPayload.put("r2", rSquare, "Coefficient of Determination (R2)", "");
        resultPayload.put("ns", ns, "Nash-Sutcliffe Model Efficieny Coefficient (NS)", "");
    }
}