Data.java [src/java/m/cfa] Revision: 6b58cc57283496d8dcd336490b705c8a4da969a9  Date: Wed May 31 11:22:27 MDT 2017
package m.cfa;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import org.codehaus.jettison.json.JSONException;

/**
* Last Updated: 31-May-2017
* @author Tyler Wible
* @since 25-January-2014
*/
public class Data {
    /**
     * Main Data extraction for daily flow data from the various databases that this tool can access
     * @param directory  the output file location (used by STORET Data extraction)
     * @param resourceFile  the csip resource file for the python driver for the storet rest call
     * @param database  the database from which to extract daily flow data (USGS, UserData, STORET, or CDWR)
     * @param organizationID  the organization which provided the data to the database (used by STORET Data extraction)
     * @param stationID  the station ID for which flow data is desired
     * @param beginDate  the begin date of desired flow data (yyyy-MM-dd)
     * @param endDate  the end date of desired flow data (yyyy-MM-dd)
     * @param userData  a concatenated string of User data (tab-delimited) to extract flow data from (column1 = date, column2 = value)
     * @return  a String[][] of all the flow data available for the specified period (column1 = date yyyy-MM-dd format, column2 = value)
     * @throws IOException
     * @throws InterruptedException
     * @throws Exception 
     */
    public static String[][] extractFlowData(String directory,
                                             File resourceFile,
                                             String database,
                                             String organizationID,
                                             String stationID,
                                             String beginDate,
                                             String endDate,
                                             String userData) throws IOException, InterruptedException, Exception{
        //Depending on the provided inputs, search for and return flow data
        String[][] flowData = new String[0][2];
        if(database.equalsIgnoreCase("USGS")){
            //Search for USGS flow data
            Object[] returnArray = USGS_Data.getUSGSflowData(stationID, beginDate, endDate);
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray[0];
            flowData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];
            
            //If there is minimal flow data, extract discharge data from the water quality database
            if(flowData.length < 10){
                //Retrieve all WQ data from USGS website
                Object[] returnArray1 = USGS_Data.getUSGSwqData(stationID);
                //ArrayList<String> webpageAll = (ArrayList<String>) returnArray1[0];
                String[][] allWQdata = (String[][]) returnArray1[1];
                //String start = (String) returnArray1[2];
                //String end = (String) returnArray1[3];
                
                //Extract and combine USGS discharge water quality codes with the flow dataset
                flowData = USGS_Data.getUSGSwqFlowData(flowData, allWQdata, beginDate, endDate);
            }

        }else if(database.equalsIgnoreCase("UserData")){
            //Find the user uploaded data file and uses this for a timeseries graph
            flowData = User_Data.readUserFile(database, stationID, userData, "flow", beginDate, endDate);

        }else if(database.equalsIgnoreCase("STORET")){
            //Search STORET database using new rest service (fast)
            flowData = STORET_Data.getSTORETdata(directory, resourceFile, true, organizationID, stationID, "flow", beginDate, endDate);
            
        }else if(database.equalsIgnoreCase("CDWR")){
            //Search for CDWR flow data
            Object[] returnArray = CDWR_Data.getCDWRflowData(stationID, beginDate, endDate, "Daily");
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray[0];
            flowData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];
        }else if(database.equalsIgnoreCase("CDSN")){
            //Search for CDWR flow data
            Object[] returnArray = CDSN_Data.getCDSNdata(organizationID, stationID, "flow", beginDate, endDate);
            //ArrayList<String> resultFileContents = (ArrayList<String>) returnArray[0];
            flowData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];
        }
        
        return flowData;
    }
    /**
     * Main Data extraction for water quality data from the various databases that this tool can access
     * @param directory  the output file location (used by STORET Data extraction)
     * @param resourceFile  the csip resource file for the python driver for the storet rest call
     * @param database  the database from which to extract water quality data (USGS, UserData, STORET, or CDWR)
     * @param organizationID  the organization which provided the data to the database (used by STORET Data extraction)
     * @param stationID  the station ID for which water quality data is desired
     * @param beginDate  the begin date of desired water quality data (yyyy-MM-dd)
     * @param endDate  the end date of desired water quality data (yyyy-MM-dd)
     * @param wqTest  the water quality test desired "00600 Total nitrogen, water, unfiltered, milligrams per liter -- mg/L" (format: "5-digit test-name -- units") or "flow"
     * @param userData  a concatenated string of User data (tab-delimited) to extract water quality data from (column1 = date, column2 = value)
     * @return  a String[][] of all the specified water quality data available for the specified period (column1 = date yyyy-MM-dd format, column2 = value)
     * @throws IOException 
     * @throws InterruptedException 
     * @throws java.text.ParseException 
     * @throws org.codehaus.jettison.json.JSONException 
     */
    public static Object[] extractWQdata(String directory,
                                         File resourceFile,
                                         String database,
                                         String organizationID,
                                         String stationID,
                                         String beginDate,
                                         String endDate,
                                         String wqTest,
                                         String userData) throws IOException, InterruptedException, ParseException, JSONException{
        String[][] wqData = new String[0][2];
        String wqLabel = "??", wqUnits = "??";
        if(database.equalsIgnoreCase("USGS")){
            String[] resultArray = getWQtestDataInfo(wqTest, database);
            String wqCode = resultArray[0];
            wqLabel = resultArray[1];
            wqUnits = resultArray[2];
            //double loadConversion = Double.parseDouble(resultArray[3]);
            //String endLoadUnits = resultArray[4];
            
            //Retrieve all WQ data from USGS website
            Object[] returnArray1 = USGS_Data.getUSGSwqData(stationID);
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray1[0];
            String[][] allWQdata = (String[][]) returnArray1[1];
            //String start = (String) returnArray1[2];
            //String end = (String) returnArray1[3];
            
            //Extract USGS water quality code for current wqTest only (5-digit code)
            wqData = USGS_Data.minimizeUSGSWQdata(allWQdata, wqCode, beginDate, endDate);

        }else if(database.equalsIgnoreCase("UserData")){
            String[] resultArray = getWQtestDataInfo(wqTest, database);
            //String wqCode = resultArray[0];
            wqLabel = resultArray[1];
            wqUnits = resultArray[2];
            //double loadConversion = Double.parseDouble(resultArray[3]);
            //String endLoadUnits = resultArray[4];
            
            //Find the user uploaded data file and uses this for a timeseries graph
            wqData = User_Data.readUserFile(database, stationID, userData, wqTest, beginDate, endDate);
            
        }else if(database.equalsIgnoreCase("STORET")){
            String[] resultArray = getWQtestDataInfo(wqTest, database);
            //String wqCode = resultArray[0];
            wqLabel = resultArray[1];
            wqUnits = resultArray[2];
            //double loadConversion = Double.parseDouble(resultArray[3]);
            //String endLoadUnits = resultArray[4];
            
            //Search STORET database using new rest service (fast)
            wqData = STORET_Data.getSTORETdata(directory, resourceFile, true, organizationID, stationID, wqTest, beginDate, endDate);
            
        }else if(database.equalsIgnoreCase("CDWR")){
            ArrayList<String> errorMessage = new ArrayList<>();
            errorMessage.add("There is no available water quality data available for the CDWR database. This feature is only available for stations in the USGS or STORET databases.");
            writeError(errorMessage);
        }else if(database.equalsIgnoreCase("CDSN")){
            String[] resultArray = getWQtestDataInfo(wqTest, database);
            //String wqCode = resultArray[0];
            wqLabel = resultArray[1];
            wqUnits = resultArray[2];
            //double loadConversion = Double.parseDouble(resultArray[3]);
            //String endLoadUnits = resultArray[4];
            
            //Search for CDWR flow data
            Object[] returnArray = CDSN_Data.getCDSNdata(organizationID, stationID, wqTest, beginDate, endDate);
            //ArrayList<String> resultFileContents = (ArrayList<String>) returnArray[0];
            wqData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];
        }
        
        Object[] returnArray = {wqData, wqUnits, wqLabel};
        return returnArray;
    }
    /**
     * Main Data extraction for daily flow and water quality data from the various databases that this tool can access (used for LDC and LOADEST)
     * @param directory  the output file location (used by STORET Data extraction)
     * @param resourceFile  the csip resource file for the python driver for the storet rest call
     * @param database  the database from which to extract water quality data (USGS, UserData, STORET, or CDWR)
     * @param organizationID  the organization which provided the data to the database (used by STORET Data extraction)
     * @param stationID  the station ID for which flow and water quality data is desired
     * @param beginDate  the begin date of desired flow and water quality data (yyyy-MM-dd)
     * @param endDate  the end date of desired flow and water quality data (yyyy-MM-dd)
     * @param wqTest  the water quality test desired "00600 Total nitrogen, water, unfiltered, milligrams per liter -- mg/L" (format: "5-digit test-name -- units")
     * @param userData  a concatenated string of User Data (tab-delimited) to extract flow (column1 = date, column2 = value) 
     * and water quality data (column1 = date, column2 = value) with a "$$" delimiter between the two types of data
     * @return  a String[][] of all the specified water quality data available for the specified period (column1 = date yyyy-MM-dd format, column2 = value)
     * @throws IOException 
     * @throws InterruptedException 
     * @throws java.text.ParseException 
     * @throws org.codehaus.jettison.json.JSONException 
     */
    public static Object[] extractFlow_and_WQdata(String directory,
                                                  File resourceFile,
                                                  String database,
                                                  String organizationID,
                                                  String stationID,
                                                  String beginDate,
                                                  String endDate,
                                                  String wqTest,
                                                  String userData) throws IOException, InterruptedException, ParseException, JSONException{
        String[][] flowData = new String[0][2];
        String[][] wqData = new String[0][2];
        if(database.equalsIgnoreCase("USGS")){
            String[] resultArray = getWQtestDataInfo(wqTest, database);
            String wqCode = resultArray[0];
            //String wqLabel = resultArray[1];
            //String wqUnits = resultArray[2];
            //double loadConversion = Double.parseDouble(resultArray[3]);
            //String endLoadUnits = resultArray[4];
            
            //Search for USGS flow data
            Object[] returnArray = USGS_Data.getUSGSflowData(stationID, beginDate, endDate);
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray[0];
            flowData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];
            
            //Retrieve all WQ data from USGS website
            Object[] returnArray1 = USGS_Data.getUSGSwqData(stationID);
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray1[0];
            String[][] allWQdata = (String[][]) returnArray1[1];
            //String start = (String) returnArray1[2];
            //String end = (String) returnArray1[3];
            
            //Extract USGS water quality code for current wqTest only
            wqData = USGS_Data.minimizeUSGSWQdata(allWQdata, wqCode, beginDate, endDate);
            
            //Extract and combine USGS discharge water quality codes with the flow dataset
            flowData = USGS_Data.getUSGSwqFlowData(flowData, allWQdata, beginDate, endDate);

        }else if(database.equalsIgnoreCase("UserData")){
            //Find the user uploaded data file and uses this for a timeseries graph
            Object[] returnArray = User_Data.readUserFileLDC(database, stationID, userData, wqTest, beginDate, endDate);
            flowData = (String[][]) returnArray[0];
            wqData = (String[][]) returnArray[1];
            
        }else if(database.equalsIgnoreCase("STORET")){
            //Search STORET database using new rest service (fast)
            flowData = STORET_Data.getSTORETdata(directory, resourceFile, true, organizationID, stationID, "flow", beginDate, endDate);
            wqData = STORET_Data.getSTORETdata(directory, resourceFile, true, organizationID, stationID, wqTest, beginDate, endDate);
            
        }else if(database.equalsIgnoreCase("UserData")){
            ArrayList<String> errorMessage = new ArrayList<>();
            errorMessage.add("There is no available water quality data available for the CDWR database. This feature is only available for stations in the USGS or STORET databases.");
            writeError(errorMessage);
        }else if(database.equalsIgnoreCase("CDSN")){
            //Search for CDWR flow data
            Object[] returnArray = CDSN_Data.getCDSNdata(organizationID, stationID, "flow", beginDate, endDate);
            //ArrayList<String> resultFileContents = (ArrayList<String>) returnArray[0];
            flowData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];
            
            returnArray = CDSN_Data.getCDSNdata(organizationID, stationID, wqTest, beginDate, endDate);
            //ArrayList<String> resultFileContents = (ArrayList<String>) returnArray[0];
            wqData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];
        }
        
        Object[] returnArray = {flowData, wqData};
        return returnArray;
    }
    /**
     * Main Data extraction for flood flow data from the various databases that this tool can access
     * @param directory  the output file location (used by STORET Data extraction)
     * @param resourceFile  the csip resource file for the python driver for the storet rest call
     * @param database  the database from which to extract daily flow data (USGS, UserData, STORET, or CDWR)
     * @param organizationID  the organization which provided the data to the database (used by STORET Data extraction)
     * @param stationID  the station ID for which flow data is desired
     * @param beginDate  the begin date of desired flow data (yyyy-MM-dd)
     * @param endDate  the end date of desired flow data (yyyy-MM-dd)
     * @param userData  a concatenated string of User data (tab-delimited) to extract flow data from (column1 = date, column2 = value)
     * @return  a String[][] of all the flow data available for the specified period (column1 = date yyyy-MM-dd format, column2 = value)
     * @throws IOException 
     * @throws Exception 
     */
    public static double[][] extractFloodData(String directory,
                                              File resourceFile,
                                              String database,
                                              String organizationID,
                                              String stationID,
                                              String beginDate,
                                              String endDate,
                                              String userData) throws IOException, Exception{
        double[][] peakFlowData = new double[0][0];
        if(database.equalsIgnoreCase("USGS")){
            //Search for USGS peak flow data
            Object[] returnArray = USGS_Data.getUSGSPeakData(stationID, beginDate, endDate);
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray[0];
            peakFlowData = (double[][]) returnArray[1];
            //double start = (double) returnArray[2];
            //double end = (double) returnArray[3];

        }else if(database.equalsIgnoreCase("UserData")){
            //Find the user uploaded data file and uses this for a timeseries graph
            String[][] flowData = User_Data.readUserFile(database, stationID, userData, "flow", beginDate, endDate);

            //Removed duplicate dates
            flowData = DoubleArray.removeDuplicateDates(flowData);

            //Convert into an annual peak time series
            peakFlowData = DoubleArray.convertSTORETpeakData(flowData);

        }else if(database.equalsIgnoreCase("STORET")){
            //Search STORET database using new rest service (fast)
            String[][] flowData = STORET_Data.getSTORETdata(directory, resourceFile, true, organizationID, stationID, "flow", beginDate, endDate);
            
            //Removed duplicate dates
            flowData = DoubleArray.removeDuplicateDates(flowData);

            //Convert into an annual peak time series
            peakFlowData = DoubleArray.convertSTORETpeakData(flowData);
            
        }else if(database.equalsIgnoreCase("CDWR")){
            //Search for CDWR flow data
            Object[] returnArray = CDWR_Data.getCDWRflowData(stationID, beginDate, endDate, "Daily");
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray[0];
            String[][] flowData = (String[][]) returnArray[1];
            //double start = (double) returnArray[2];
            //double end = (double) returnArray[3];
            
            //Removed duplicate dates
            flowData = DoubleArray.removeDuplicateDates(flowData);

            //Convert into an annual peak time series
            peakFlowData = DoubleArray.convertSTORETpeakData(flowData);
        }else if(database.equalsIgnoreCase("CDSN")){
            //Search for CDWR flow data
            Object[] returnArray = CDSN_Data.getCDSNdata(organizationID, stationID, "flow", beginDate, endDate);
            //ArrayList<String> resultFileContents = (ArrayList<String>) returnArray[0];
            String[][] flowData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];
            
            //Removed duplicate dates
            flowData = DoubleArray.removeDuplicateDates(flowData);

            //Convert into an annual peak time series
            peakFlowData = DoubleArray.convertSTORETpeakData(flowData);
        }
        
        return peakFlowData;
    }
    /**
     * Extracts 15 minute data from USGS and/or User data or hourly data from CDWR (as long as the date is formatted properly) returns an error otherwise
     * @param directory  the output file location (used by STORET Data extraction)
     * @param database  the database from which to extract water quality data (USGS, UserData, STORET, or CDWR)
     * @param stationID  the station ID for which flow and water quality data is desired
     * @param beginDate  the begin date of desired flow and water quality data (yyyy-MM-dd)
     * @param endDate  the end date of desired flow and water quality data (yyyy-MM-dd)
     * @param userData  a concatenated string of User Data (tab-delimited) to extract flow (column1 = date, column2 = value)
     * @return  a String[][] of all the specified 15-minute flow data available for the specified period (column1 = date yyyy-MM-dd HH:mm format, column2 = value)
     * @throws IOException
     * @throws Exception
     */
    public static String[][] extractInstantaneousFlowData(String directory,
                                                          String database,
                                                          String stationID,
                                                          String beginDate,
                                                          String endDate,
                                                          String userData) throws IOException, Exception{
        //Depending on the provided inputs, search for and return flow data
        String[][] flowData = new String[0][2];
        if(database.equalsIgnoreCase("USGS")){
            //Search for USGS flow data
            Object[] returnArray = USGS_Data.getUSGS15minFlowData(stationID, beginDate, endDate);
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray[0];
            flowData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];

        }else if(database.equalsIgnoreCase("UserData")){
            //Find the user uploaded data file and uses this for a timeseries graph
            flowData = User_Data.read15minUserFile(userData, "flow", beginDate + " 00:00", endDate + " 23:00");

        }else if(database.equalsIgnoreCase("STORET")){
            ArrayList<String> errorMessage = new ArrayList<>();
            errorMessage.add("There is no available 15-minute flow data available for the STORET database. This feature is only available for stations in the USGS-NWIS or CDWR databases.");
            writeError(errorMessage);
            
        }else if(database.equalsIgnoreCase("CDWR")){
            //Search for CDWR flow data
            Object[] returnArray = CDWR_Data.getCDWRflowData(stationID, beginDate, endDate, "15-min");
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray[0];
            flowData = (String[][]) returnArray[1];
            //String start = (String) returnArray[2];
            //String end = (String) returnArray[3];
        }else if(database.equalsIgnoreCase("CDSN")){
            ArrayList<String> errorMessage = new ArrayList<>();
            errorMessage.add("There is no available 15-minute flow data available for the CDSN database. This feature is only available for stations in the USGS-NWIS or CDWR databases.");
            writeError(errorMessage);
        }
        
        return flowData;
    }
    /**
     * Main Data extraction for stage-discharge relationship data from the various databases that this tool can access
     * @param database  the database from which to extract data (USGS, UserData, STORET, or CDWR)
     * @param stationID  the station ID for which data is desired
     * @return
     * @throws IOException 
     */
    public static double[][] extractStageDischarge(String database, String stationID) throws IOException, Exception{
        //Depending on the provided inputs, search for and return flow data
        double[][] ratingCurve = new double[0][2];
        if(database.equalsIgnoreCase("USGS")){
            //Search for USGS flow data
            Object[] returnArray = USGS_Data.getUSGSratingCurve(stationID);
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray[0];
            ratingCurve = (double[][]) returnArray[1];

        }else if(database.equalsIgnoreCase("STORET")){
            ArrayList<String> errorMessage = new ArrayList<>();
            errorMessage.add("There is no rating curve data available for STORET stations.");
            writeError(errorMessage);
            
        }else if(database.equalsIgnoreCase("CDWR")){
            //Search for USGS flow data
            Object[] returnArray = CDWR_Data.getCDWRratingCurve(stationID);
            //ArrayList<String> webpageAll = (ArrayList<String>) returnArray[0];
            ratingCurve = (double[][]) returnArray[1];
        }else if(database.equalsIgnoreCase("CDSN")){
            ArrayList<String> errorMessage = new ArrayList<>();
            errorMessage.add("There is no rating curve data available for CDSN stations.");
            writeError(errorMessage);
        }
        
        return ratingCurve;
    }
    /**
     * @param wqTest  the water quality test desired "00600 Total nitrogen, water, unfiltered, milligrams per liter -- mg/L" (format: "5-digit test-name -- units") or "flow"
     * @param database
     * @return a string with the type of units for the current test.
     * @throws java.io.IOException
     */
     public static String[] getWQtestDataInfo(String wqTest, String database) throws IOException{
        String wqCode = "??", wqLabel = "??", wqUnits = "??";
        if(wqTest.equalsIgnoreCase("flow")){
            wqCode = "flow";
            wqLabel = "flow";
            wqUnits = "cfs";
        }else{
            wqCode = wqTest.substring(0,5);//pull just the 5 digit USGS WQ code
            wqLabel = wqTest.substring(6,wqTest.lastIndexOf("--")-1);//cut off the "98335" the test name and the "mg/L" units after the name
            if(database.equalsIgnoreCase("USGS")){
                //Get Units for current WQ test (5-digit code)
                wqUnits = USGS_Data.getUSGSwqUnits(wqCode);
            }else{
                wqUnits = wqTest.substring(wqTest.lastIndexOf("--") + 3);//keep the "mg/L" units after the name
            }
        }
        
        //Determine load calculation info. (wqUnits * flow * conversion = endUnits)
        double conversion = getWQconversion(wqUnits);
        String endUnits = getWQendUnits(wqUnits);
        
        String[] resultArray = {wqCode, wqLabel, wqUnits, String.valueOf(conversion), endUnits};
        return resultArray;
     }
     /**
     * @param units  the units of the current USGS water quality test.
     * @return a double with the correct conversion factor for the units.
     */
     public static double getWQconversion(String units){
         double conversion = 0;
         if(units.equalsIgnoreCase("#/l")){
             conversion = (1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("#/m3")){
             conversion = (java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("#/ml")){
             conversion = (1000)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("MPN/100 ml")){
             conversion = (1.0/100.0)*(1000)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("MPN/100L")){
             conversion = (1.0/100.0)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("cfu/100ml")){
             conversion = (1.0/100.0)*(1000)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("cfu/mL")){
             conversion = (1000)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("col/mL")){
             conversion = (1000)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("cysts/100L")){
             conversion = (1.0/100.0)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("cysts/10L")){
             conversion = (1.0/10.0)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("g/cm3") || units.equalsIgnoreCase("g/mL @ 20C")){
             conversion = (java.lang.Math.pow(10,-6))*(1/1)*(1000)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("g/m3")){
             conversion = (java.lang.Math.pow(10,-6))*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("mg/l") || units.equalsIgnoreCase("mg/l CaCO3") || units.equalsIgnoreCase("mg/l NH4") || 
                     units.equalsIgnoreCase("mg/l NO3") || units.equalsIgnoreCase("mg/l PO4") || units.equalsIgnoreCase("mg/l SiO2") || 
                     units.equalsIgnoreCase("mg/l as H") || units.equalsIgnoreCase("mg/l as N") || units.equalsIgnoreCase("mg/l as Na") || 
                     units.equalsIgnoreCase("mg/l as P") || units.equalsIgnoreCase("mg/l as S") || units.equalsIgnoreCase("mgC3H6O2/L")){
             conversion = (java.lang.Math.pow(10,-6))*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("mg/mL @25C")){
             conversion = (java.lang.Math.pow(10,-6))*(1000)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("ml/l")){
             conversion = (1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("ng/l") || units.equalsIgnoreCase("pg/mL")){
             conversion = (java.lang.Math.pow(10,-12))*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("ng/m3") || units.equalsIgnoreCase("pg/l")){
             conversion = (java.lang.Math.pow(10,-12))*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("ocyst/100L")){
             conversion = (1.0/100.0)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("oocyst/10L")){
             conversion = (1.0/10.0)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("pfu/100L")){
             conversion = (1.0/100.0)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("pfu/100ml")){
             conversion = (1.0/100.0)*(1000)*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("pg/m3")){
             conversion = (java.lang.Math.pow(10,-15))*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("ug/L 2,4-D") || units.equalsIgnoreCase("ug/L U3O8") || units.equalsIgnoreCase("ug/L as As") || 
                     units.equalsIgnoreCase("ug/L as Cl") || units.equalsIgnoreCase("ug/L as N") || units.equalsIgnoreCase("ug/L as P") || 
                     units.equalsIgnoreCase("ug/l") || units.equalsIgnoreCase("ugAtrazn/L")){
             conversion = (java.lang.Math.pow(10,-9))*(1000)*(java.lang.Math.pow(0.3048,3))*(86400);
         }else if(units.equalsIgnoreCase("ug/m3")){
             conversion = (java.lang.Math.pow(10,-9))*(java.lang.Math.pow(0.3048,3))*(86400);
         }
         return conversion;
     }
     /**
     * @param units  the units of the current USGS water quality test.
     * @return a string with the end result units of the conversion.
     */
     public static String getWQendUnits(String units){
         String endUnits = "No Units";
         if(units.equalsIgnoreCase("#/l") || units.equalsIgnoreCase("#/m3") || units.equalsIgnoreCase("#/ml")){
             endUnits = "#/day";
         }else if(units.equalsIgnoreCase("MPN/100 ml") || units.equalsIgnoreCase("MPN/100L")){
             endUnits = "MPN/day";
         }else if(units.equalsIgnoreCase("cfu/100ml") || units.equalsIgnoreCase("cfu/mL")){
             endUnits = "cfu/day";
         }else if(units.equalsIgnoreCase("col/mL")){
             endUnits = "col/day";
         }else if(units.equalsIgnoreCase("cysts/100L") || units.equalsIgnoreCase("cysts/10L")){
             endUnits = "cysts/day";//= cysts/100L*cfs
         }else if(units.equalsIgnoreCase("mg/l") || units.equalsIgnoreCase("mg/l CaCO3") || units.equalsIgnoreCase("mg/l NH4") || 
                 units.equalsIgnoreCase("mg/l NO3") || units.equalsIgnoreCase("mg/l PO4") || units.equalsIgnoreCase("mg/l SiO2") || 
                 units.equalsIgnoreCase("mg/l as H") || units.equalsIgnoreCase("mg/l as N") || units.equalsIgnoreCase("mg/l as Na") || 
                 units.equalsIgnoreCase("mg/l as P") || units.equalsIgnoreCase("mg/l as S") || units.equalsIgnoreCase("mgC3H6O2/L") || 
                 units.equalsIgnoreCase("g/cm3") || units.equalsIgnoreCase("g/mL @ 20C") || units.equalsIgnoreCase("g/m3") || 
                 units.equalsIgnoreCase("mg/mL @25C") || units.equalsIgnoreCase("ng/l") || units.equalsIgnoreCase("pg/mL") ||
                 units.equalsIgnoreCase("ng/m3") || units.equalsIgnoreCase("pg/l") || units.equalsIgnoreCase("pg/m3") || 
                 units.equalsIgnoreCase("ug/L 2,4-D") || units.equalsIgnoreCase("ug/L U3O8") || units.equalsIgnoreCase("ug/L as As") || 
                 units.equalsIgnoreCase("ug/L as Cl") || units.equalsIgnoreCase("ug/L as N") || units.equalsIgnoreCase("ug/L as P") || 
                 units.equalsIgnoreCase("ug/l") || units.equalsIgnoreCase("ugAtrazn/L") || units.equalsIgnoreCase("ug/m3")){
             endUnits = "kg/day";//= mg/l*cfs
         }else if(units.equalsIgnoreCase("ml/l")){
             endUnits = "ml/day";//= mg/l*cfs
         }else if(units.equalsIgnoreCase("pfu/100L") || units.equalsIgnoreCase("pfu/100ml")){
             endUnits = "pfu/day";
         }else if(units.equalsIgnoreCase("ocyst/100L")){
             endUnits = "ocyst/day";
         }else if(units.equalsIgnoreCase("oocyst/10L")){
             endUnits = "oocyst/day";
         }
         return endUnits;
     }
    /**
     * 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 static 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);
    }
}