guiStageDischarge_Model.java [src/java/m/cfa/stagedischarge] Revision:   Date:
package m.cfa.stagedischarge;

import WaterData.WaterData;
import WaterData.WaterDataInterface;
import m.cfa.Graphing;
import java.awt.Color;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;

/**
* Last Updated: 9-April-2019
* @author Tyler Wible
* @since 24-June-2014
*/
public class guiStageDischarge_Model{
    String directory = "E:/Projects/TylerWible_repos/NetBeans/data/CFA/Timeseries";
    String database = "USGS";//"CDWR";//
    String stationId = "06752260";//"CLAGRECO";//
    String stationName = "CACHE LA POUDRE RIVER AT FORT COLLINS, CO";//"Cache La Poudre Near Greeley";//
    
    //Outputs
    String dataSource = "?";
    String ratingWarning = "?";
    
    //Gets
    public String getStageDischargeGraph(){ return "stageDischarge_graph.jpg"; }
    public File getStageDischargeOutput(){ return new File(directory, "stageDischarge_graph.out"); }//for use with JSHighCharts
    public String getDataSource(){ return dataSource; }
    public String getWarning(){ return ratingWarning; }
    //Sets
    public void setDirectory(String directory_str){ directory = directory_str; }
    public void setDatabase(String database_str){ database = database_str; }
    public void setStationName(String stationName_str){ stationName = stationName_str; }
    public void setStationId(String stationId_str){ stationId = stationId_str; }
    /**
     * Graphs the stage-discharge data as a rating curve
     * @param ratingCurveData  the stage-discharge data (column1 = stage (ft), column2 = discharge (cfs))
     */
    private void graphStageDischarge(double[][] ratingCurveData){
        //Graph ratingCurveData
        XYPlot plot = new XYPlot();
        plot = Graphing.addXYSeries(plot, ratingCurveData, Color.darkGray, 0);
        
        //Create Y Axis
        ValueAxis rangeAxis = new NumberAxis("Stage [ft]");
        plot.setRangeAxis(0, rangeAxis);
        
        //Create X Axis
        NumberAxis domainAxis = new NumberAxis("Discharge [cfs]");
        plot.setDomainAxis(0, domainAxis);
        
        //Set extra plot preferences
        plot = Graphing.setAxisPreferences(plot);

        //Create the charts out of the plots
        String graph_title = "Stage-Discharge Rating Curve for Station: " + stationId + "; " + stationName;
        JFreeChart chart = new JFreeChart(graph_title, Graphing.titleFont, plot, false);
        
        //Save monthly timeseries graph for use later
        try{
            String path = directory + File.separator + getStageDischargeGraph();
            ChartUtilities.saveChartAsJPEG(new File(path), chart, 1280, 800);
            System.out.println("JFreeChart created properly at: " + path);

        }catch(IOException e){
            System.err.println("A problem occurred while trying to creating the chart.");
        }
    }
    /**
     * Writes out the error message, if any, for finding the file and then exits the program
     * @param error  string array to be written as each line of an error message
     * @throws IOException
     */
    public void writeError(ArrayList<String> error) throws IOException{
        //Output data to text file
        String errorContents = error.get(0);
        for(int i=1; i<error.size(); i++){
            errorContents = errorContents + "\n" + error.get(i);
        }
        throw new IOException("Error encountered. Please see the following message for details: \n" + errorContents);
    }
    /**
     * Writes out the stage discharge relationship to a result file
     * @param ratingCurveData
     * @throws IOException 
     */
    private void writeOutput(double[][] ratingCurveData) throws IOException{
        //Open a file writer for the summary of the flow statistcs per year
        String path = directory + File.separator + getStageDischargeOutput().getName();
        FileWriter newFile =  new FileWriter(path, false);
        PrintWriter writer = new PrintWriter(newFile);
        
        for(int i=0; i<ratingCurveData.length; i++){
            String currentLine = String.valueOf(ratingCurveData[i][0]);
            for(int j=1; j<ratingCurveData[i].length; j++){
                currentLine = currentLine + "\t" + String.valueOf(ratingCurveData[i][j]);
            }
            writer.printf("%s" + "\r\n", currentLine);
        }
        
        //Close file writer
        newFile.close();
        writer.close();
        System.out.println("Text File located at:\t" + path);
    }
    public void run() throws IOException, Exception{
        //Get stage-discharge data
        WaterDataInterface waterLib = WaterData.getNewWaterDataInterface(database, "");
        double[][] stageDischargeData = waterLib.extractStageDischarge_formatted(stationId);
        dataSource = waterLib.getDataSourceCitation();
        
        //Check if any rating curve data exists
        if(stageDischargeData.length == 0){
            ArrayList<String> errorMessage = new ArrayList<>();
            errorMessage.add("There is no available stage-discharge/rating curve data in the " + database +  " database for station '" + stationId + "'.");
            writeError(errorMessage);
        }
        
        //Graph stage-discharge relationship
        graphStageDischarge(stageDischargeData);
        
        //Get today's date for the source reference
        Date currentDate = new Date();
        SimpleDateFormat desiredDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String today = desiredDateFormat.format(currentDate);
        if(database.equalsIgnoreCase("USGS")){
            ratingWarning = "The stage-discharge rating provided in this file should be" +
                " considered provisional and subject to change until published by USGS. Stage-discharge" +
                " ratings change over time as the channel features that control" +
                " the relation between stage and discharge vary. Users are" +
                " cautioned to consider carefully the applicability of this" +
                " rating before using it for decisions that concern personal or" +
                " public safety or operational consequences.";
        }else if(database.equalsIgnoreCase("CDWR")){
            ratingWarning = "All data presented on the Colorado Division of Water Resources"
                    + " ColoradoWaterSMS web service are provisional and subject to revision. These"
                    + " data include water levels in lakes and reservoirs, and in streams, rivers,"
                    + " and other water courses; computed stream discharges; and various weather parameters"
                    + " (temperature, precipitation, etc.). Most data relayed by satellite or other"
                    + " telemetry have received little or no review prior to being exposed by this web"
                    + " service. State of Colorado Hydrographic Program Staff visit satellite monitoring"
                    + " gaging stations on a frequent basis to maintain equipment and ensure correct"
                    + " operation. They also perform discharge measurements for purposes of calibrating"
                    + " the stage-discharge relationship at a gage, as well as take note of physical"
                    + " factors present at the gage which may be affecting the stage-discharge relationship."
                    + " Nevertheless, inaccuracies in the data may occur because of instrument malfunctions"
                    + " or physical changes at the measurement site. Subsequent review may result in"
                    + " significant revisions to the data.  Data users are cautioned to consider carefully"
                    + " the provisional nature of the information before using it for decisions that"
                    + " concern personal or public safety or the conduct of business that involves"
                    + " substantial monetary or operational consequences.";
        }
        
        //Save stage/discharge data for JHighCharts
        writeOutput(stageDischargeData);
    }
    public static void main(String[] args) throws IOException, Exception{
        guiStageDischarge_Model model = new guiStageDischarge_Model();
        
        model.run();
    }
}