GeneralFunctions.java [src/java/hydraulics] Revision:   Date:
package hydraulics;

import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.XYPlot;

class sort1_smallToLargeDoubleMath implements Comparator<double[]>{
    //Compares the first entry and sorts smallest to largest
    public int compare(final double[] entry1, final double[] entry2) {
        double value1 = entry1[0];
        double value2 = entry2[0];

        //Compare and return the second entries
        return Double.compare(value1,value2);
    }
}
/**
 * Borrowed from csip-cfa/DoubleArray
 * Borrowed from csip-cfa/DoubleMath
 * Borrowed from csip-cfa/Graphing
 * Last Updated: 5-February-2016
 * @author Tyler Wible
 * @since 5-August-2012
 */
public class GeneralFunctions {
    private String fontFamily = "SansSerif";
    public Font titleFont = new Font(fontFamily, Font.BOLD, 30);
    public Font masterFont = new Font(fontFamily, Font.PLAIN, 22);
    public Font DClabelFont = new Font(fontFamily, Font.ITALIC, 20);
    public Font floodLabelFont = new Font(fontFamily, Font.PLAIN, 18);
    /**
     * Creates a double[] array of the elements in dataArray[all][column]
     * @param dataArray  the double[][] data array
     * @param column  the desired column from data array (zero based)
     * @return  a double[] array of the elements in dataArray[all][column]
     */
    public double[] getColumn(double[][] dataArray, int column){
        //Gets the values of dataArray[all][column] in a double[]
        double[] currentElements = new double[dataArray.length];

        for(int i=0; i<dataArray.length; i++){
            currentElements[i] = dataArray[i][column];
        }
        return currentElements;
    }
    /**
     * Writes out the formatted output file as expected by eRAMS to be used for a JHighchart XY
     * @param mainFolder
     * @param data
     * @param outputFileName
     * @throws IOException 
     */
    public void writeXYseries(String mainFolder, String[][] data, String outputFileName) throws IOException {
        //open the file writer and set path
        String path = mainFolder + File.separator + outputFileName;
        FileWriter writer =  new FileWriter(path, false);
        PrintWriter print_line = new PrintWriter(writer);
        
        //Print the needed values
        for(int i=0; i<data.length; i++){
            String currentLine = data[i][0];
            for(int j=1; j<data[i].length; j++){
                currentLine = currentLine + "\t" + data[i][j];
            }
            print_line.printf("%s" + "\r\n", currentLine);
        }
      
        // Close the file writer 
        print_line.close();
        writer.close();
        System.out.println("Text File located at:\t" + path);
    }
    /**
     * Performs a linear interpolation and computes a y value using the Xarray and Yarray evaluated at the xValue point 
     * @param Xarray  a double[] array of existing X points
     * @param Yarray  a double[] array of existing Y points corresponding to the above Xarray
     * @param xValue  a double x point for which y point is desired
     * @return  a double y point corresponding to the x point of the xValue after a linear interpolation between Xarray and Yarray
     */
    public double linearInterpolation(double[] Xarray, double[] Yarray, double xValue){
        double yValue = 0;

        //Sort the Xarray based on values as to properly interpolate between points
        double[][] tempMatrix = new double[Xarray.length][3];
        for(int i=0; i<Xarray.length; i++){
                tempMatrix[i][0] = Xarray[i];
                tempMatrix[i][1] = Yarray[i];
                tempMatrix[i][2] = i;
        }
        Arrays.sort(tempMatrix, new sort1_smallToLargeDoubleMath());
        Xarray = getColumn(tempMatrix, 0);
        Yarray = getColumn(tempMatrix, 1);

        //Interpolate bewtween the arrays
        for(int i=0; i<Xarray.length; i++){
            if(i == 0 && xValue < Xarray[0]){
                //If xValue is smaller than the first Xarray value, extrapolate based on the slope bewteen the first two points in Xarray and Yarray
                yValue = ((Yarray[i+1] - Yarray[i])/(Xarray[i+1] - Xarray[i]))*(xValue - Xarray[i]) + Yarray[i];
                System.err.println("The x value: " + xValue + " is smaller than the smallest provided X value:" + Xarray[0] + ". Therefore it's corresponding y value: " + yValue + " was extrapolated from the dataset.");
                break;

            }else if(xValue == Xarray[i]){
                yValue = Yarray[i];
                break;

            }else if(i != 0 && Xarray[i-1] < xValue && xValue < Xarray[i]){
                yValue = ((xValue - Xarray[i-1])/(Xarray[i] - Xarray[i-1]))*(Yarray[i] - Yarray[i-1]) + Yarray[i-1];
                break;

            }else if(i == (Xarray.length-1) && xValue > Xarray[i]){
                //If xValue is larger than the last Xarray value, extrapolate based on the slope bewteen the last two points in Xarry and Yarray
               yValue = ((Yarray[i-1] - Yarray[i])/(Xarray[i-1] - Xarray[i]))*(xValue - Xarray[i]) + Yarray[i];
               System.err.println("The x value: " + xValue + " is larger than the largest provided X value: " + Xarray[i] + ". Therefore it's corresponding y value: " + yValue + " was extrapolated from the dataset.");
               break;
            }
        }

        return yValue;
    }
    /**
     * Finds the maximum value of a double[] array
     * @param array  the double[] array
     * @return  the maximum of the above array as a double
     */
    public double max(double[] array){
        double maximum = -9999;
        for(int i=0; i<array.length; i++){
            if(i == 0){
                maximum = array[i];
            }else{
                if(Double.compare(maximum, array[i]) < 0){
                    maximum = array[i];
                }
            }
        }
        return maximum;
    }
    /**
     * Finds the minimum value of a double[] array
     * @param array  the double[] array
     * @return  the minimum of the above array as a double
     */
    public double min(double[] array){
        double minimum = -9999;
        for(int i=0; i<array.length; i++){
            if(i == 0){
                minimum = array[i];
            }else{
                if(Double.compare(minimum, array[i]) > 0){
                    minimum = array[i];
                }
            }
        }
        return minimum;
    }
    /**
     * Calculates the sum of a double[] array
     * @param dataArray  the array to be summed
     * @return the sum of the array
     */
    public double sum(double[] dataArray){
        double sum = 0;
        //Calculate the sum of the array
        for(int i=0; i<dataArray.length; i++){
            sum = sum + dataArray[i];
        }
        return sum;
    }
    /**
     * Rounds the double to the number of decimal places "n" where roundingValue = 10^n  
     * For example if the roundingValue is equal to 10, then the returned value would have 1 decimal place 
     * @param originalValue  the original double value to be rounded
     * @param decimalPlaces  is equal to the number of decimal places desired
     * @return  a double rounded value of the orignal data
     */
    public double round(double originalValue, double decimalPlaces){
        double decimals = Math.pow(10, decimalPlaces);
        double roundedValue = Math.round(originalValue*decimals);
        roundedValue = roundedValue/decimals;

        return roundedValue;
    }
    /**
     * This subfunction takes the provided plot and changes the fonts of the axis to a standardized new font
     * @param plot  the XYPlot containing the graph on which the fonts will be changed
     * @return the original plot with the modifications to the axis fonts
     */
    public XYPlot setAxisPreferences(XYPlot plot){
        //Set Y axis fonts
        ValueAxis yAxis = plot.getRangeAxis();
        yAxis.setLabelFont(masterFont);
        yAxis.setTickLabelFont(masterFont);

        //Set X axis fonts
        ValueAxis xAxis = plot.getDomainAxis();
        xAxis.setLabelFont(masterFont);
        xAxis.setTickLabelFont(masterFont);	
        
        //Set extra plot preferences
        plot.setOutlinePaint(Color.black);
        plot.setDomainGridlinePaint(Color.black);
        plot.setRangeGridlinePaint(Color.black);
        plot.setRangeMinorGridlinesVisible(true);
        plot.setRangeMinorGridlinePaint(Color.gray);
        
        return plot;
    }
    /**
     * This subfunction takes the provided plot and changes the fonts of the axis to a standardized new font
     * @param plot  the CategoryPlot containing the graph on which the fonts will be changed
     * @return the original plot with the modifications to the axis fonts
     */
    public CategoryPlot setCategoryAxisPreferences(CategoryPlot plot){
        //Set Y axis fonts
        ValueAxis yAxis = plot.getRangeAxis();
        yAxis.setLabelFont(masterFont);
        yAxis.setTickLabelFont(masterFont);

        //Set X axis fonts
        CategoryAxis xAxis = plot.getDomainAxis();
        xAxis.setLabelFont(masterFont);
        xAxis.setTickLabelFont(masterFont);	
        
        //Set extra plot preferences
        plot.setOutlinePaint(Color.black);
        plot.setDomainGridlinePaint(Color.black);
        plot.setDomainGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.black);
        plot.setRangeMinorGridlinesVisible(true);
        plot.setRangeMinorGridlinePaint(Color.gray);
        
        return plot;
    }
}