Displaying differences for changeset
display as  

nbproject/build-impl.xml

@@ -1022,7 +1022,6 @@
         <copyfiles files="${file.reference.json-org.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.oms-all.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.jersey-media-multipart-2.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
-        <copyfiles files="${file.reference.Jama-1.0.2.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.apache-mime4j-0.6.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.commons-codec-1.9.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.commons-collections-3.2.1.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
@@ -1039,6 +1038,7 @@
         <copyfiles files="${file.reference.sac-1.3.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.xalan-2.7.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.xerces_2.9.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
+        <copyfiles files="${file.reference.commons-math-2.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
         <mkdir dir="${build.web.dir}/META-INF"/>
         <manifest file="${build.web.dir}/META-INF/MANIFEST.MF" mode="update"/>
     </target>
@@ -1059,7 +1059,6 @@
         <copyfiles files="${file.reference.json-org.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
         <copyfiles files="${file.reference.oms-all.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
         <copyfiles files="${file.reference.jersey-media-multipart-2.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
-        <copyfiles files="${file.reference.Jama-1.0.2.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
         <copyfiles files="${file.reference.apache-mime4j-0.6.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
         <copyfiles files="${file.reference.commons-codec-1.9.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
         <copyfiles files="${file.reference.commons-collections-3.2.1.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
@@ -1076,6 +1075,7 @@
         <copyfiles files="${file.reference.sac-1.3.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
         <copyfiles files="${file.reference.xalan-2.7.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
         <copyfiles files="${file.reference.xerces_2.9.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
+        <copyfiles files="${file.reference.commons-math-2.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
     </target>
     <target depends="init" if="dist.ear.dir" name="-clean-webinf-lib">
         <delete dir="${build.web.dir}/WEB-INF/lib"/>

nbproject/project.properties

@@ -41,6 +41,7 @@
 file.reference.commons-io-2.3.jar=../csip-core/lib/commons-io-2.3.jar
 file.reference.commons-lang-2.4.jar=lib/commons-lang-2.4.jar
 file.reference.commons-logging-1.1.1.jar=../csip-core/lib/commons-logging-1.1.1.jar
+file.reference.commons-math-2.0.jar=lib/commons-math-2.0.jar
 file.reference.commons-pool-1.6.jar=../csip-core/lib/commons-pool-1.6.jar
 file.reference.cssparser-0.9.5.jar=lib/cssparser-0.9.5.jar
 file.reference.htmlunit-2.8.jar=lib/htmlunit-2.8.jar
@@ -48,7 +49,6 @@
 file.reference.httpclient-4.1.3.jar=../csip-core/lib/httpclient-4.1.3.jar
 file.reference.httpcore-4.1.4.jar=../csip-core/lib/httpcore-4.1.4.jar
 file.reference.httpmime-4.2.5.jar=../csip-core/lib/httpmime-4.2.5.jar
-file.reference.Jama-1.0.2.jar=lib/Jama-1.0.2.jar
 file.reference.java-uuid-generator-3.1.3.jar=../csip-core/lib/java-uuid-generator-3.1.3.jar
 file.reference.javax.inject.jar=lib/javax.inject.jar
 file.reference.jcommon-1.0.16.jar=lib/jcommon-1.0.16.jar
@@ -87,7 +87,6 @@
     ${file.reference.json-org.jar}:\
     ${file.reference.oms-all.jar}:\
     ${file.reference.jersey-media-multipart-2.0.jar}:\
-    ${file.reference.Jama-1.0.2.jar}:\
     ${file.reference.apache-mime4j-0.6.jar}:\
     ${file.reference.commons-codec-1.9.jar}:\
     ${file.reference.commons-collections-3.2.1.jar}:\
@@ -103,7 +102,8 @@
     ${file.reference.nekohtml-1.9.9.jar}:\
     ${file.reference.sac-1.3.jar}:\
     ${file.reference.xalan-2.7.0.jar}:\
-    ${file.reference.xerces_2.9.0.jar}
+    ${file.reference.xerces_2.9.0.jar}:\
+    ${file.reference.commons-math-2.0.jar}
 # Space-separated list of extra javac options
 javac.compilerargs=
 javac.debug=true

nbproject/project.xml

@@ -76,10 +76,6 @@
                     <path-in-war>WEB-INF/lib</path-in-war>
                 </library>
                 <library dirs="200">
-                    <file>${file.reference.Jama-1.0.2.jar}</file>
-                    <path-in-war>WEB-INF/lib</path-in-war>
-                </library>
-                <library dirs="200">
                     <file>${file.reference.apache-mime4j-0.6.jar}</file>
                     <path-in-war>WEB-INF/lib</path-in-war>
                 </library>
@@ -143,6 +139,10 @@
                     <file>${file.reference.xerces_2.9.0.jar}</file>
                     <path-in-war>WEB-INF/lib</path-in-war>
                 </library>
+                <library dirs="200">
+                    <file>${file.reference.commons-math-2.0.jar}</file>
+                    <path-in-war>WEB-INF/lib</path-in-war>
+                </library>
             </web-module-libraries>
             <web-module-additional-libraries/>
             <source-roots>

src/java/datadownload/STORET_Data.java

@@ -30,7 +30,7 @@
 import java.util.zip.ZipFile;
 
 /**
-* Last Updated: 7-February-2013
+* Last Updated: 5-February-2014
 * @author Tyler Wible
 * @since 22-June-2012
 */
@@ -112,7 +112,7 @@
         while(listIterate.hasNext()){
             HtmlOption currentOption = listIterate.next();
             String optionText1 = currentOption.getText();
-//            System.out.println(optionText1);
+            System.out.println(optionText1);
             if(ctr > 1){//Skip the first two lines
                 String optionText = currentOption.getText();
 
@@ -124,14 +124,14 @@
                         optionTextClip = optionTextClip.trim();
                     }
                 }
-//                System.out.println(optionTextClip);
+                System.out.println(optionTextClip);
 
                 //If the current option is the desired one, select it
                 if(optionTextClip.toLowerCase().contains(name.toLowerCase())){
                     //If the current select option is the organization name, then select it and break the loop
                     String org_index = currentOption.getValueAttribute();
                     select.setSelectedAttribute(org_index, true);
-//                    System.out.println(listboxType + " selected");
+                    System.out.println(listboxType + " selected");
                     break;
                 }
             }
@@ -302,14 +302,14 @@
         //Selecct Search Type
         List<?> buttonList = (List<?>) mainPage.getByXPath("//input[@value='Organization and Station']");
         if(buttonList.size() == 1){
-//            System.out.println(buttonList.size());
+            System.out.println(buttonList.size());
             HtmlRadioButtonInput searchTypeRadioButton = (HtmlRadioButtonInput) buttonList.get(0);
             searchTypeRadioButton.focus();
             mainPage = searchTypeRadioButton.click();//onclick javascript function will check this radio button and uncheck the others
 //          searchTypeRadioButton.setChecked(true);
 
-//            System.out.println(searchTypeRadioButton.getValueAttribute());
-//            System.out.println(searchTypeRadioButton.getCheckedAttribute());
+            System.out.println(searchTypeRadioButton.getValueAttribute());
+            System.out.println(searchTypeRadioButton.getCheckedAttribute());
             System.out.println("Step 2: selected searchtype");
         }
 
@@ -571,7 +571,7 @@
         String zipfile = downloadUrl.substring(downloadUrl.indexOf("tmd"));
 
         //Download STORET data
-        System.out.println("Step 9a: Downloading Zip file");
+        System.out.println("Step 9: Downloading Zip file");
         String zipfile_location = downloadzip(downloadUrl, zipfile, mainFolder);
 
         //Close web interaction
@@ -662,7 +662,7 @@
                 }
                 if(Characteristic.equals("Flow")){
                     //Correct units of flow values
-                    if(f[24].equalsIgnoreCase("cm3/sec")){//convert from cm3/sec to cfs
+                    if(f[18].equalsIgnoreCase("Flow") && (f[24].equalsIgnoreCase("cm3/sec") || f[24].equalsIgnoreCase("m3/sec")) ){//convert from cm3/sec to cfs
                         temp = Double.parseDouble(f[23])*(1/0.0283168466);
                         f[24] = "cfs";
                         f[23] = String.valueOf(temp);
@@ -822,13 +822,13 @@
 
             //Extract "reg_results" file and extract data WQ from this combined file
             results = OpenWQFile(partialPath, data_location, characteristic);
+            
         }else{
             //If the characteristic is flow, then unzip the file and delete it once finished
             System.out.println("Reading STORET result file for Flow characteristic");
 
             //Extract "reg_results" file and extract flow data from this combined file
             results = OpenWQFile(partialPath, data_location, "Flow");
-            
         }
 
         if(deleteTrue){

src/java/datadownload/USGS_Data.java

@@ -1,62 +1,22 @@
 package datadownload;
 
-import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
-import com.gargoylesoftware.htmlunit.TextPage;
-import com.gargoylesoftware.htmlunit.WebClient;
-import com.gargoylesoftware.htmlunit.WebWindow;
-import com.gargoylesoftware.htmlunit.WebWindowEvent;
-import com.gargoylesoftware.htmlunit.WebWindowListener;
-import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
-import com.gargoylesoftware.htmlunit.html.HtmlSelect;
-import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
-import com.gargoylesoftware.htmlunit.html.HtmlTextArea;
 import java.io.BufferedReader;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.net.MalformedURLException;
+import java.net.SocketException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
 
 /**
-* Last Updated: 2-November-2012
+* Last Updated: 3-September-2014
 * @author Tyler Wible
 * @since 21-June-2012
 */
 public class USGS_Data {
     /**
-     * Opens a web connection to USGS and returns the contents of a search for all flow data for the specific station and date range
-     * @param stationID  the USGS station ID for the current station
-     * @param beginDate  the user specified begin date for the station (yyyy-mm-dd format)
-     * @param endDate  the user specified end date for the station (yyyy-mm-dd format)
-     * @return an ArrayList<String> containing the results of the search for flow data using the above inputs
-     * @throws IOException
-     */
-    public ArrayList<String> DownloadFlowWebpage(String stationID, String beginDate, String endDate) throws IOException {
-        //Specify flow website from inputs
-        String flowWebsite = "http://waterdata.usgs.gov/nwis/dv?cb_00060=on&format=rdb&begin_date=" + 
-                beginDate + "&end_date=" + endDate + "&site_no=" + stationID + "&referred_module=sw";
-
-        //Open the provided website
-        URL webpage = new URL(flowWebsite);
-        URLConnection yc = webpage.openConnection();
-        BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
-        //Read out all of the webpage out into an ArrayList<String>
-        String inputLine;
-        ArrayList<String> pageData = new ArrayList<String>( );
-
-        while((inputLine = in.readLine()) != null){
-            pageData.add(inputLine);
-        }
-        in.close();
-
-        return pageData;
-    }
-    /**
      * Get the flow webpage and loop through and pull out the flow data for the current station
      * @param stationID  the USGS station ID for the current station
      * @param beginDate  the user specified begin date for the station (yyyy-mm-dd format)
@@ -64,10 +24,10 @@
      * @return  a String[][] containing column1 = date(yyyy-mm-dd), column2 = flowValue
      * @throws IOException
      */
-    public String[][] USGS_read_FDC(String stationID, String beginDate, String endDate) throws IOException{
+    public Object[] getUSGSflowData(String stationID, String beginDate, String endDate) throws IOException{
         //Get the webpage of data for the USGS flow station
         ArrayList<String> webpageAll = DownloadFlowWebpage(stationID, beginDate, endDate);
-
+        
         //Pull out new arraylist of only the desired data from the arraylist to return as the web page result
         Iterator<String> iterate = webpageAll.iterator( );
         ArrayList<String> textData = new ArrayList<String>();
@@ -105,23 +65,33 @@
             stringArray[i][0] = currentColumns[1];
             stringArray[i][1] = currentColumns[2];
         }
-
-
-        return stringArray;
-}
+        
+        //Save analysis results
+        String start = "-1";
+        String end = "-1";
+        if(stringArray.length > 0){
+            start = stringArray[0][0];
+            end = stringArray[stringArray.length - 1][0];
+        }
+        
+        Object[] returnArray = {webpageAll, stringArray, start, end};
+        return returnArray;
+    }
     /**
-     * Opens a web connection to USGS and returns the contents of a search for all peak flow data for the specific station
+     * Opens a web connection to USGS and returns the contents of a search for all flow data for the specific station and date range
      * @param stationID  the USGS station ID for the current station
+     * @param beginDate  the user specified begin date for the station (yyyy-mm-dd format)
+     * @param endDate  the user specified end date for the station (yyyy-mm-dd format)
      * @return an ArrayList<String> containing the results of the search for flow data using the above inputs
      * @throws IOException
      */
-    public ArrayList<String> DownloadPeakFlowWebpage(String stationID) throws IOException {
+    public ArrayList<String> DownloadFlowWebpage(String stationID, String beginDate, String endDate) throws IOException {
         //Specify flow website from inputs
-        String peakWebsite = "http://nwis.waterdata.usgs.gov/nwis/peak?site_no=" + stationID + "&agency_cd=USGS&format=rdb";
-
-
+        String flowWebsite = "http://waterdata.usgs.gov/nwis/dv?cb_00060=on&format=rdb&begin_date=" + 
+                beginDate + "&end_date=" + endDate + "&site_no=" + stationID + "&referred_module=sw";
+        
         //Open the provided website
-        URL webpage = new URL(peakWebsite);
+        URL webpage = new URL(flowWebsite);
         URLConnection yc = webpage.openConnection();
         BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
         //Read out all of the webpage out into an ArrayList<String>
@@ -131,6 +101,7 @@
         while((inputLine = in.readLine()) != null){
             pageData.add(inputLine);
         }
+        in.close();
 
         return pageData;
     }
@@ -142,7 +113,7 @@
      * @return  an ArrayList<String> containing the flow results tab deliminated (stationID \t date \t flowValue)
      * @throws IOException
      */
-    public ArrayList<String> getUSGSPeakData(String stationID) throws IOException{
+    public Object[] getUSGSPeakData(String stationID, String beginDate, String endDate) throws IOException{
         //Get peak flow data
         ArrayList<String> peakWebPage = DownloadPeakFlowWebpage(stationID);
 
@@ -171,29 +142,269 @@
                 }
             }
         }
+        
+        //Convert the array into a double array and remove data not within the date range provided
+        double[][] doubleData = convertUSGSpeakData(textData, beginDate, endDate);
+        
+        //Save analysis results
+        double start = -1;
+        double end = -1;
+        if(doubleData.length > 0){
+            start = doubleData[0][0];
+            end = doubleData[doubleData.length - 1][0];
+        }
+        
+        Object[] returnArray = {peakWebPage, doubleData, start, end};
+        return returnArray;
+    }
+        /**
+     * Opens a web connection to USGS and returns the contents of a search for all peak flow data for the specific station
+     * @param stationID  the USGS station ID for the current station
+     * @return an ArrayList<String> containing the results of the search for flow data using the above inputs
+     * @throws IOException
+     */
+    public ArrayList<String> DownloadPeakFlowWebpage(String stationID) throws IOException {
+        //Specify flow website from inputs
+        String peakWebsite = "http://nwis.waterdata.usgs.gov/nwis/peak?site_no=" + stationID + "&agency_cd=USGS&format=rdb";
 
-        return textData;
+
+        //Open the provided website
+        URL webpage = new URL(peakWebsite);
+        URLConnection yc = webpage.openConnection();
+        BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
+        //Read out all of the webpage out into an ArrayList<String>
+        String inputLine;
+        ArrayList<String> pageData = new ArrayList<String>( );
+
+        while((inputLine = in.readLine()) != null){
+            pageData.add(inputLine);
+        }
+
+        return pageData;
     }
     /**
-     * Checks if the webpage contains the search keyword of not, usually used to find a webpage error and return a false value
-     * @param in  the BufferedReader for the webpage
-     * @param keyword  the String keyword that is looked for in the webpage
-     * @return  returns true if the webpage contains the keyword, false otherwise
+     * Converts the string array into a double array.  First it substrings the year from the 
+     * first column (the date of the flows) and then only converts the year into a double.  
+     * Then converts the flow values into doubles. It also only keeps data within the provided date range
+     * @param stringData  The ArrayList<String> array containing dates (YYYY-mm-dd) in the first column 
+     * and flow values (cfs) in the second column
+     * @param beginDate  the user defined begin date
+     * @param endDate  the user defined end date
+     * @return returns a double[][] array the same size as the provided string array containing 
+     * the first column of years and the second column of flow values
+     */
+    public double[][] convertUSGSpeakData(ArrayList<String> stringData, String beginDate, String endDate){
+        String beginYear = beginDate.substring(0,4);
+        String endYear = endDate.substring(0,4);
+        int ctr = 0;
+
+        for(int i=0; i<stringData.size(); i++){
+            String[] f = stringData.get(i).split("\t");
+            String year = f[0].substring(0,4);
+
+            //Only keep flood data years within the user defined date range
+            if(year.compareToIgnoreCase(beginYear) >=0 && year.compareToIgnoreCase(endYear) <= 0){
+                ctr++;
+            }
+        }
+        if(ctr == 1){
+            System.out.println("There is " + ctr + " flood year in the current analysis");
+        }else{
+            System.out.println("There are " + ctr + " flood years in the current analysis");
+        }
+
+        //Initialize the return array
+        double[][] doubleData = new double[ctr][2];
+        ctr = 0;
+
+        for(int i=0; i<stringData.size(); i++){
+            String[] f = stringData.get(i).split("\t");
+            String year = f[0].substring(0,4);
+
+            //Only keep flood data years within the user defined date range
+            if(year.compareToIgnoreCase(beginYear) >=0 && year.compareToIgnoreCase(endYear) <= 0){
+                //convert the strings into doubles
+                doubleData[ctr][0] = Double.valueOf(year);//year
+                doubleData[ctr][1] = Double.valueOf(f[1]);//flow value
+                ctr++;
+            }
+        }
+
+        return doubleData;
+    }
+    /**
+     * Get the 15 minute flow webpage and loop through and pull out the flow data for the current station
+     * @param stationID  the USGS station ID for the current station
+     * @param beginDate  the user specified begin date for the station (yyyy-mm-dd format)
+     * @param endDate  the user specified end date for the station (yyyy-mm-dd format)
+     * @return  a String[][] containing column1 = date(yyyy-mm-dd), column2 = flowValue
      * @throws IOException
      */
-    public boolean getWQPage(BufferedReader in, String keyword) throws IOException{
-        String inputLine = "";
+    public Object[] getUSGS15minFlowData(String stationID, String beginDate, String endDate) throws IOException{
+        //Artificial limit due to the current status of USGS's Instantaneous Data Archive transition to NWIS
+        if(beginDate.compareToIgnoreCase("2007-10-01") < 0){
+            beginDate = "2007-10-01";
+        }
+        if(endDate.compareToIgnoreCase("2007-10-01") < 0){
+            endDate = "2007-10-01";
+        }
+        
+        //Get the webpage of data for the USGS flow station
+        ArrayList<String> webpageAll = Download15minFlowWebpage(stationID, beginDate, endDate);
+        
+        //Pull out new arraylist of only the desired data from the arraylist to return as the web page result
+        Iterator<String> iterate = webpageAll.iterator( );
+        ArrayList<String> textData = new ArrayList<String>();
 
-        boolean containsKeyword = false;
-//        System.out.println("Current webpage: \n");
-        while((inputLine = in.readLine()) != null) {
-            if(inputLine.contains(keyword)){
-//                System.out.println(inputLine);
-                containsKeyword = true;
-                break;
+        while(iterate.hasNext()){
+            String temp_pageData = (String) iterate.next();
+            String[] f = temp_pageData.split("\t");
+
+            if ((f.length >= 4) && ("USGS".equals(f[0]))) {
+                boolean Ice = f[4].equalsIgnoreCase("Ice");
+                boolean Ssn = f[4].equalsIgnoreCase("Ssn");
+                boolean Dis = f[4].equalsIgnoreCase("Dis");
+                boolean rat = f[4].equalsIgnoreCase("Rat");
+                boolean eqp = f[4].equalsIgnoreCase("Eqp");
+                boolean other = f[4].equalsIgnoreCase("***");
+                boolean blank = f[4].equalsIgnoreCase("");
+                if (!Ice && !Ssn && !Dis && !rat && !eqp && !other && !blank) {
+                    //Pull out only the data needed to pass between sub-functions
+
+                    //f[1] = StationID
+                    //f[2] = Date
+                    //f[3] = time location (ex. MDT = mountain daylight time)
+                    //f[4] = FlowValue
+                    textData.add(f[1] + "\t" + f[2] + "\t" + f[3] + "\t" + f[4]);
+                }
             }
         }
-        return containsKeyword;
+
+        //convert Array list into String[][] array (column1 = date, column2 = value)
+        String[][] stringArray = new String[textData.size()][2];
+        for(int i=0; i<stringArray.length; i++){
+            String[] currentColumns = textData.get(i).split("\t");
+            //currentColumns[0] = stationID
+            //currentColumns[1] = date (yyyy-MM-dd hh:mm)
+            //currentColumns[2] = time location
+            //currentColumns[3] = value
+            stringArray[i][0] = currentColumns[1];
+            stringArray[i][1] = currentColumns[3];
+        }
+        
+        //Save analysis results
+        String start = "-1";
+        String end = "-1";
+        if(stringArray.length > 0){
+            start = stringArray[0][0];
+            end = stringArray[stringArray.length - 1][0];
+        }
+        
+        Object[] returnArray = {webpageAll, stringArray, start, end};
+        return returnArray;
+    }
+    /**
+     * Opens a web connection to USGS and returns the contents of a search for 15 minute flow data for the specific station and date range
+     * @param stationID  the USGS station ID for the current station
+     * @param beginDate  the user specified begin date for the station (yyyy-mm-dd format)
+     * @param endDate  the user specified end date for the station (yyyy-mm-dd format)
+     * @return an ArrayList<String> containing the results of the search for 15 minute flow data using the above inputs
+     * @throws IOException
+     */
+    public ArrayList<String> Download15minFlowWebpage(String stationID, String beginDate, String endDate) throws IOException {
+        //Specify flow website from inputs
+        String flowWebsite = "http://nwis.waterdata.usgs.gov/nwis/uv?cb_00060=on&format=rdb&site_no=" + stationID + 
+                             "&period=&begin_date=" + beginDate + "&end_date=" + endDate;
+        //Instantaneous Data Archive (IDA) website (to be discontinued in 2015) = "http://ida.water.usgs.gov/ida/available_records.cfm?sn=" + stationID;
+        
+        //Open the provided website
+        URL webpage = new URL(flowWebsite);
+        URLConnection yc = webpage.openConnection();
+        BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
+        //Read out all of the webpage out into an ArrayList<String>
+        ArrayList<String> pageData = new ArrayList<String>( );
+        boolean moreLines = true;
+        while(moreLines){
+            try{
+                String inputLine = in.readLine();
+                if(inputLine != null){
+                    pageData.add(inputLine);
+                }else{
+                    moreLines = false;
+                }
+            }catch(SocketException e){
+                //The webpage is angry for some reason so quit out
+                moreLines = false;
+            }
+        }
+        in.close();
+
+        return pageData;
+    }
+    /**
+     * Get the water quality webpage and loop through and pull out the water quality data for the current station
+     * @param stationID  the USGS station ID for the current station
+     * @return  a String[][] containing column1 = date(yyyy-mm-dd), column2 = flowValue
+     * @throws IOException
+     * @throws InterruptedException
+     */
+    public Object[] getUSGSwqData(String stationID) throws IOException, InterruptedException{
+
+        //Get the webpage of data for the USGS flow station
+        ArrayList<String> webpageAll = DownloadWQwebpage(stationID);
+//      ArrayList<String> webpageAll = DownloadWQwebpage_HtmlUnit(stationID, wqTestCode);
+    
+        //Pull out new arraylist of only the desired data from the arraylist to return as the web page result
+        Iterator<String> iterate = webpageAll.iterator( );
+        ArrayList<String> textData = new ArrayList<String>();
+        while(iterate.hasNext()){
+            String temp_pageData = (String) iterate.next();
+            String[] f = temp_pageData.split("\t");
+
+            if ( (f.length >= 15) && (f[0].equals("USGS")) ) {
+                String WQSample_code = f[12];
+                String WQSample_result = f[14];
+                boolean A = WQSample_code.equals("");
+                boolean B = WQSample_result.equals("");
+                if (!A && !B){
+                    //Count only the rows which contain the desired values of "agency_cd    site_no    sample_dt...    
+                    //    sample_tm    sample_end_dt    sample_end_tm    sample_start_time_datum_cd    tm_datum_rlbty_cd...    
+                    //    coll_ent_cd    medium_cd    tu_id    body_part_id    parm_cd    remark_cd    result_va"
+
+                    //Pull out only the data needed to pass between sub-functions
+                    //f[1] = stationID
+                    //f[2] = date
+                    //f[12] = water quality test code
+                    //f[14] = water quality test value
+                    textData.add(f[1] + "\t" + f[2] + "\t" + f[12] + "\t" + f[14]);
+                }
+            }
+        }
+
+        //convert Array list into String[][] array (column1 = date, column2 = value)
+        String[][] stringArray = new String[textData.size()][3];
+        for(int i=0; i<textData.size(); i++){
+            String[] currentColumns = textData.get(i).split("\t");
+            //currentColumns[0] = stationID
+            //currentColumns[1] = date
+            //currentColumns[2] = water quality test code
+            //currentColumns[3] = water quality test value
+
+            stringArray[i][0] = currentColumns[1];//date
+            stringArray[i][1] = currentColumns[2];//test code
+            stringArray[i][2] = currentColumns[3];//value
+        }
+        
+        //Save analysis results
+        String start = "-1";
+        String end = "-1";
+        if(stringArray.length > 0){
+            start = stringArray[0][0];
+            end = stringArray[stringArray.length - 1][0];
+        }
+        
+        Object[] returnArray = {webpageAll, stringArray, start, end};
+        return returnArray;
     }
     /**
      * Opens a web connection to USGS and returns the contents of a search for all water quality data for the specific station
@@ -234,11 +445,31 @@
         ArrayList<String> pageData = new ArrayList<String>( );
         while((inputLine = in.readLine()) != null){
             pageData.add(inputLine);
-//            System.out.println(inputLine);
         }
         return pageData;
     }
     /**
+     * Checks if the webpage contains the search keyword of not, usually used to find a webpage error and return a false value
+     * @param in  the BufferedReader for the webpage
+     * @param keyword  the String keyword that is looked for in the webpage
+     * @return  returns true if the webpage contains the keyword, false otherwise
+     * @throws IOException
+     */
+    public boolean getWQPage(BufferedReader in, String keyword) throws IOException{
+        String inputLine = "";
+
+        boolean containsKeyword = false;
+//        System.out.println("Current webpage: \n");
+        while((inputLine = in.readLine()) != null) {
+            if(inputLine.contains(keyword)){
+//                System.out.println(inputLine);
+                containsKeyword = true;
+                break;
+            }
+        }
+        return containsKeyword;
+    }
+    /**
      * Opens a web connection to USGS and returns the contents of a search for all water quality data for the specific station
      * @param stationID  the USGS station ID for the current station
      * @param wqTest  the 5 digit USGS water qualiyt (WQ) test code that the user has requested for download
@@ -246,7 +477,7 @@
      * @throws IOException
      * @throws InterruptedException
      */
-    public ArrayList<String> DownloadPartialWQwebpage(String stationID, String wqTest) throws IOException, InterruptedException {
+    public ArrayList<String> getUSGSwqData_partial(String stationID, String wqTest) throws IOException, InterruptedException {
 
         //Specify flow website from inputs
 //      String WQWebsite = "http://waterdata.usgs.gov/nwis/nwisman/?site_no=" + stationID + "&agency_cd=USGS";
@@ -299,110 +530,6 @@
         return pageData;
     }
     /**
-     * Opens a web connection to USGS and returns the contents of a search for all water quality data for the specific station.
-     * Note, this function uses HtmlUnit because the above DownloadWQwebpage stopped working recently
-     * @param stationID  the USGS station ID for the current station
-     * @return an ArrayList<String> containing the results of the search for water quality data using the above input
-     * @throws IOException
-     */
-    public ArrayList<String> DownloadWQwebpage_HtmlUnit(String stationID, String wqTestCode) throws IOException, InterruptedException {
-        //Specify flow website from inputs
-        String WQWebsite = "http://waterdata.usgs.gov/nwis/nwisman/?site_no=" + stationID + "&agency_cd=USGS";
-
-        //Create Webclient with specific properties for STORET webpage
-        final LinkedList<WebWindow> windows =  new LinkedList<WebWindow>();
-        WebClient webClient = new WebClient();
-        webClient.setThrowExceptionOnScriptError(false);
-        webClient.addWebWindowListener(new WebWindowListener(){
-            public void webWindowClosed(WebWindowEvent event){
-            }
-            public void webWindowContentChanged(WebWindowEvent event){
-            }
-            public void webWindowOpened(WebWindowEvent event){
-                windows.add(event.getWebWindow());
-            }
-        });
-        //Get webpage
-        HtmlPage mainPage = null;
-        try {
-            mainPage = webClient.getPage(WQWebsite);
-        }catch (FailingHttpStatusCodeException e) {
-            e.printStackTrace();
-        }catch (MalformedURLException e) {
-            e.printStackTrace();
-        }catch (IOException e) {
-            e.printStackTrace();
-        }
-        if(mainPage == null){
-            ArrayList<String> errorMessage = new ArrayList<String>();
-            errorMessage.add("Error: USGS_readWQData_0001\n Error retriving webpage: " + WQWebsite + "");
-            return errorMessage;
-        }
-
-        HtmlPage wqPage = null;
-        List<?> linkList1 = (List<?>) mainPage.getByXPath("//a[@href='/nwis/qwdata/?site_no=" + stationID + "']");
-        try{
-            if(linkList1.size() == 1){
-                HtmlAnchor selectAll = (HtmlAnchor) linkList1.get(0);
-                selectAll.focus();
-                wqPage = selectAll.click();
-            }else{
-                ArrayList<String> errorMessage = new ArrayList<String>();
-                errorMessage.add("Error: USGS_readWQData_0002\n There are no " + wqTestCode + " water quality tests for station: " + stationID);
-                return errorMessage;
-            }
-        }catch(IOException e){
-            ArrayList<String> errorMessage = new ArrayList<String>();
-            errorMessage.add("Error: USGS_readWQData_0003\n");
-            errorMessage.add(e.toString());
-            System.out.println(e.toString());
-            return errorMessage;
-        }
-
-//        System.out.println(wqPage.asXml());
-        //Enter parameter code for data search
-        HtmlTextArea wqCodeSearch = (HtmlTextArea) wqPage.getElementById("radio_multiple_parm_cds");
-        //Set focus on this element to allow the webpage's javascript to check the radio button corresponding to this element
-        wqCodeSearch.focus();
-        wqCodeSearch.setText(wqTestCode);
-
-
-        //Change the data format to a better format
-        HtmlSelect dataFormat = (HtmlSelect) wqPage.getElementById("qw_sample_wide");
-        //Set focus on this element to allow the webpage's javascript to check the radio button corresponding to this element
-        dataFormat.focus();
-        dataFormat.setSelectedAttribute("One result per row", true);
-
-
-        //Change the download to display in browser
-        HtmlSelect downloadType = (HtmlSelect) wqPage.getElementById("rdb_compr_id");
-        downloadType.setSelectedAttribute("Display in browser", true);
-
-        //Get the result page
-        TextPage resultPage = null;
-        List<?> submitList = (List<?>) wqPage.getByXPath("//input[@value='Submit']");
-        HtmlSubmitInput submitButton = (HtmlSubmitInput) submitList.get(0);
-        resultPage = submitButton.click();
-
-
-
-        //Extract data from result page
-        String resultPageContents = resultPage.getContent();
-        if(resultPageContents.contains("No valid parameter codes")){
-            ArrayList<String> errorMessage = new ArrayList<String>();
-            errorMessage.add("Error: USGS_readWQData_0004\n There are no " + wqTestCode + " water quality tests for station: " + stationID);
-            return errorMessage;
-        }
-        String[] resultPageRows = resultPageContents.split("\n");
-        ArrayList<String> pageData = new ArrayList<String>();
-
-        for(int i=0; i<resultPageRows.length; i++){
-            pageData.add(resultPageRows[i]);
-        }
-
-        return pageData;
-    }
-    /**
      * Reduces all water quality data to just that of the requested parameter
      * @param allData  all water quality data for the earlier provided date range and station ID (column1 = date, column2 = wqTestcode, column3 = value)
      * @param wqTestCode  the requested water quality parameter
@@ -438,82 +565,238 @@
         return reducedData;
     }
     /**
-     * Merges the two arrays into a single array of returnArray.length = (array1.length + array2.length).  
-     * Note that this only combines the output array of "minimizeUSGSWQdata" which is a 2 column String[][] 
-     * with dates in the first column and values in the second, which matches the output format
-     * @param array1  first String[][] array to be combined column1 = dates, column2 = values
-     * @param array2  second String[][] array to be combined column1 = dates, column2 = values
-     * @return a combined array of array1 and array2 with the same number of columns and returnArray.length = (array1.length + array2.length)
+     * @param parameterCode  USGS parameter code for a specific water quality test.
+     * @return a string with the type of units for the current test.
      */
-    public String[][] mergeMinimizedWQdata(String[][] array1, String[][] array2){
-        String[][] newArray = new String[array1.length + array2.length][2];
+     public String getUSGSwqUnits(String parameterCode) throws IOException{
+         URL webpage = new URL("http://nwis.waterdata.usgs.gov/usa/nwis/pmcodes?radio_pm_search=param_group&pm_group=All+--+include+all+parameter+groups&pm_search=&casrn_search=&srsname_search=&format=rdb&show=parameter_group_nm&show=parameter_nm&show=casrn&show=srsname&show=parameter_units");
+         URLConnection yc = webpage.openConnection();
+         BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
+         String inputLine;
+         int line_length = 0;
+         String units = "0";
+         //Find the units of the specified test
+         while ((inputLine = in.readLine()) != null) {
+             String[] f = inputLine.split("\t");
+             line_length = f.length;
+             if((line_length >= 6) && (f[0].length() == 5)){
+                 if(f[0].equals(parameterCode)){
+                     units = f[5];
+                 }
+             }
+         }
+         return units;
+     }
+     /**
+     * @param units  the units of the current USGS water quality test.
+     * @return a double with the correct conversion factor for the units.
+     */
+     public double getUSGSwqConversion(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 String getUSGSwqEndUnits(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;
+     }
+    /**
+     * Extract the USGS water quality tests of 00061 (discharge in cfs) and 30209 (discharge in cms) and combine them
+     * with the provided flow data set within the provided date range
+     * @param flowData  existing stream flow data (column 1 =  dates, column 2 = flow values)
+     * @param allWQdata  all existing stream water quality data (column 1 =  dates, column 2 = flow values)
+     * @param beginDate  the start of the desired data date range
+     * @param endDate  the end of the desired data date range
+     * @return
+     * @throws IOException 
+     */
+    public String[][] getUSGSwqFlowData(String[][] flowData, String[][] allWQdata, String beginDate, String endDate) throws IOException{
+        DoubleArray doubleArray = new DoubleArray();
+        
+        //Extract USGS water quality code 00061 for dischage in cfs
+        String[][] WQFlow1 = minimizeUSGSWQdata(allWQdata, "00061", beginDate, endDate);
+        //Extract USGS water quality code 30209 for discharge test in m^3/s (cms)
+        String[][] WQFlow2 = minimizeUSGSWQdata(allWQdata, "30209", beginDate, endDate);
 
-        for(int i=0; i<newArray.length; i++){
-            if(i<array1.length){
-                newArray[i][0] = array1[i][0];
-                newArray[i][1] = array1[i][1];
-            }else{
-                newArray[i][0] = array1[i-array1.length][0];
-                newArray[i][1] = array1[i-array1.length][1];
-            }
+        //Convert the m^3 to ft^3/s
+        for(int i=0; i<WQFlow2.length; i++){
+            WQFlow2[i][1] = Double.toString((Double.parseDouble(WQFlow2[i][1])*(3.2808399*3.2808399*3.2808399)));
         }
 
-        return newArray;
+        //combine the WQ flows (cfs and the converted cms data) into a single variable to then combine with the Flowdata
+        String[][] WQDataflows = doubleArray.mergeData(WQFlow1, WQFlow2, "public");//The "public" attribute keeps the first dataset in case of duplicates
+
+        //Combine flow data and WQ flow data into a variable of dates and flow values to be sorted
+        flowData = doubleArray.mergeData(flowData, WQDataflows, "public");//The "public" attribute keeps the first dataset in case of duplicates
+        
+        return flowData;
     }
     /**
-     * Get the water quality webpage and loop through and pull out the water quality data for the current station
+     * Get the rating curve (stage-discharge relationship) data for use by the user
      * @param stationID  the USGS station ID for the current station
-     * @return  a String[][] containing column1 = date(yyyy-mm-dd), column2 = flowValue
+     * @return  a double[][] containing column1 = discharge(ft3/s), column2 = depth(ft)
      * @throws IOException
-     * @throws InterruptedException
      */
-    public String[][] USGS_read_LDC(String stationID) throws IOException, InterruptedException{
-
+    public Object[] getUSGSratingCurve(String stationID) throws IOException{
         //Get the webpage of data for the USGS flow station
-        ArrayList<String> webpageAll = DownloadWQwebpage(stationID);
-//      ArrayList<String> webpageAll = DownloadWQwebpage_HtmlUnit(stationID, wqTestCode);
-    
+        ArrayList<String> webpageAll = DownloadRatingCurveWebpage(stationID);
+        
         //Pull out new arraylist of only the desired data from the arraylist to return as the web page result
         Iterator<String> iterate = webpageAll.iterator( );
         ArrayList<String> textData = new ArrayList<String>();
+
         while(iterate.hasNext()){
             String temp_pageData = (String) iterate.next();
             String[] f = temp_pageData.split("\t");
-
-            if ( (f.length >= 15) && (f[0].equals("USGS")) ) {
-                String WQSample_code = f[12];
-                String WQSample_result = f[14];
-                boolean A = WQSample_code.equals("");
-                boolean B = WQSample_result.equals("");
-                if (!A && !B){
-                    //Count only the rows which contain the desired values of "agency_cd    site_no    sample_dt...    
-                    //    sample_tm    sample_end_dt    sample_end_tm    sample_start_time_datum_cd    tm_datum_rlbty_cd...    
-                    //    coll_ent_cd    medium_cd    tu_id    body_part_id    parm_cd    remark_cd    result_va"
-
-                    //Pull out only the data needed to pass between sub-functions
-                    //f[1] = stationID
-                    //f[2] = date
-                    //f[12] = water quality test code
-                    //f[14] = water quality test value
-                    textData.add(f[1] + "\t" + f[2] + "\t" + f[12] + "\t" + f[14]);
+            try{
+                String text1 = temp_pageData.substring(0,1);
+                if((f.length >= 3) && (!"#".equals(text1))){
+                    try{
+                        double depth = Double.parseDouble(f[0]);
+                        double shift = Double.parseDouble(f[1]);
+                        double discharge = Double.parseDouble(f[2]);
+                        textData.add(f[0] + "\t" + f[1] + "\t" + f[2]);
+                    }catch(NumberFormatException e){
+                        //Skip this entry and move on to the next line in the file
+                    }
                 }
+                
+            }catch(IndexOutOfBoundsException e){
+                //Move on to the next line in the file
             }
+            
         }
 
-        //convert Array list into String[][] array (column1 = date, column2 = value)
-        String[][] stringArray = new String[textData.size()][3];
-        for(int i=0; i<textData.size(); i++){
+        //convert Array list into double[][] array (column1 = depth, column2 = discharge)
+        double[][] ratingCurveData = new double[textData.size()][2];
+        for(int i=0; i<ratingCurveData.length; i++){
             String[] currentColumns = textData.get(i).split("\t");
-            //currentColumns[0] = stationID
-            //currentColumns[1] = date
-            //currentColumns[2] = water quality test code
-            //currentColumns[3] = water quality test value
+            //currentColumns[0] = depth
+            //currentColumns[1] = shift
+            //currentColumns[2] = discharge
+            ratingCurveData[i][0] = Double.parseDouble(currentColumns[2]);
+            ratingCurveData[i][1] = Double.parseDouble(currentColumns[0]);
+        }
+        
+        Object[] returnArray = {webpageAll, ratingCurveData};
+        return returnArray;
+    }
+    /**
+     * Opens a web connection to USGS and returns the contents of a search for 15 minute flow data for the specific station and date range
+     * @param stationID  the USGS station ID for the current station
+     * @return an ArrayList<String> containing the results of the search for 15 minute flow data using the above inputs
+     * @throws IOException
+     */
+    public ArrayList<String> DownloadRatingCurveWebpage(String stationID) throws IOException {
+        //Specify rating curve website from inputs
+        String ratingCurveWebsite = "http://nwis.waterdata.usgs.gov/nwisweb/data/ratings/exsa/USGS." + stationID + ".exsa.rdb";
+        //"http://nwis.waterdata.usgs.gov/nwisweb/data/ratings/exsa/USGS.06741510.exsa.rdb"
+        
+        //Open the provided website
+        URL webpage = new URL(ratingCurveWebsite);
+        URLConnection yc = webpage.openConnection();
+        ArrayList<String> pageData = new ArrayList<String>();
+        try{
+            BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
+            //Read out all of the webpage out into an ArrayList<String>
+            String inputLine;
 
-            stringArray[i][0] = currentColumns[1];//date
-            stringArray[i][1] = currentColumns[2];//test code
-            stringArray[i][2] = currentColumns[3];//value
+            while((inputLine = in.readLine()) != null){
+                pageData.add(inputLine);
+            }
+            in.close();
+
+            return pageData;
+        }catch(FileNotFoundException e){
+            //This station has no rating curve data, so return nothing
+            return pageData;
         }
-
-        return stringArray;
     }
 }
\ No newline at end of file

src/java/datadownload/guiDataDownloads.java

@@ -6,9 +6,14 @@
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.DateFormat;
 import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.zip.Deflater;
@@ -22,36 +27,35 @@
 */
 public class guiDataDownloads {
     //Inputs
-    String mainFolder          = "C:/Projects/TylerWible/CodeDirectories/NetBeans/CSIP/data/DataDownloads";
-    String beginDate           = "";//user defined begin date
-    String endDate             = "";//user defined end date
-    boolean USGSflowTrue       = true;//if true then water quality data will be downloaded for USGS stations
-    boolean USGSwqTrue         = true;//if true then water quality data will be downloaded for USGS stations
-    boolean USGSWellsDepthTrue = true;//if true then well depth data will be downloaded for USGSwell stations
-    boolean USGSWellsWQtrue    = true;//if true then water quality data will be downloaded for USGSwell stations
-    boolean STORETflowTrue     = false;//if true then flow data will be downloaded for STORET stations
-    boolean STORETwqTrue       = true;//if true then water quality data will be downloaded for STORET stations
-    String SNOTELcontent       = "Standard SNOTEL";//one from list of Content_CB
-    String SNOTELtimeseries    = "Daily";//one from the list of Timeseries_CB
-    String NCDCelement         = "GHCND";//NCDC download type
-    String attributeFile       = "Database\tOrg\tStaID\tStaName\tLatitude\tLongitude\tCounty\tState\tCountry\tHUCNumber\tDrainArea\tElev\tElevUnits\tElevDatum\tBeginDate\tEndDate\tCoop_ID\tWBAN_ID\n" + 
-                                 "USGS\tUSGS\t07369654\tCoon Bayou Tributary near Tillar\t33.74982893\t-91.4115096\tDesha County\tARKANSAS\tUnited States\t8050002\t0.02\t145\tft\tNGVD29\t1995-03-05\t1996-12-16\tn/a\tn/a\n" + 
-                                 "USGSWells\tUSGS\t332432091031501\tD0016  WASHINGTON\t33.409005\t-91.0542732\tWashington County\tMISSISSIPPI\tUnited States\t8030209\t\t125\tft\tNGVD29\t\t\tn/a\tn/a\n" + 
-                                 "SNOTEL\tSNOTEL\t330\tBeaver Divide\t40.61666667\t-111.1\tWasatch\tUTAH\tUnited States\t\t\t8280\tfeet\t\t1978-10-01\t\tn/a\tn/a\n" +
-                                 "STORET\tNational Park Service Water Resources Division\tCRLA_GSFRA_52\tPothole Creek (No.52 in GS report)\t42.936853\t-121.949314\tKLAMATH\tOREGON\t\t18010201\t--\t0\t\tNAD83\t\t\tn/a\tn/a\n" + 
-                                 "NCDC\tNCDC\t12002175\tMILLIKIN\t32.96666667\t-91.23333333\tEAST CARROLL\tLOUISIANA\tUNITED STATES\t\t\t-99999\tft\t\t1904-07-05\t1905-03-31\t166212\tn/a";//the contents of a tab-delimited input file
-    
+    String mainFolder              = "C:/Projects/TylerWible/CodeDirectories/NetBeans/CSIP/data/DataDownloads";
+    String beginDate               = "";//user defined begin date
+    String endDate                 = "";//user defined end date
+    boolean USGSflowTrue           = true;//if true then flow data will be downloaded for USGS stations
+    boolean USGSwqTrue             = true;//if true then water quality data will be downloaded for USGS stations
+    boolean USGSfloodTrue          = true;//if true then flood data will be downloaded for USGS stations
+    boolean USGSstageDischargeTrue = true;//if true then stage-discharge data will be downloaded for USGS stations
+    boolean USGSWellsDepthTrue     = true;//if true then well depth data will be downloaded for USGSwell stations
+    boolean USGSWellsWQtrue        = true;//if true then water quality data will be downloaded for USGSwell stations
+    boolean STORETflowTrue         = false;//if true then flow data will be downloaded for STORET stations
+    boolean STORETwqTrue           = false;//if true then water quality data will be downloaded for STORET stations
+    String NCDCelement             = "GHCND";//NCDC download type
+    boolean CDWRflowTrue           = true;//if true then flow data will be downloaded for CDWR stations
+    boolean CDWRstageDischargeTrue = true;//if true then stage-discharge data will be downloaded for CDWR stations
+    String attributeFile           = "Database\tOrg\tStaID\tStaName\tLatitude\tLongitude\tCounty\tState\tCountry\tHUCNumber\tDrainArea\tElev\tElevUnits\tElevDatum\tBeginDate\tEndDate\tCoop_ID\tWBAN_ID\n" + 
+                                     "USGS\tUSGS\t07369654\tCoon Bayou Tributary near Tillar\t33.74982893\t-91.4115096\tDesha County\tARKANSAS\tUnited States\t8050002\t0.02\t145\tft\tNGVD29\t1995-03-05\t1996-12-16\tn/a\tn/a\n" + 
+                                     "USGSWells\tUSGS\t332432091031501\tD0016  WASHINGTON\t33.409005\t-91.0542732\tWashington County\tMISSISSIPPI\tUnited States\t8030209\t\t125\tft\tNGVD29\t\t\tn/a\tn/a\n" + 
+                                     "SNOTEL\tSNOTEL\t330\tBeaver Divide\t40.61666667\t-111.1\tWasatch\tUTAH\tUnited States\t\t\t8280\tfeet\t\t1978-10-01\t\tn/a\tn/a\n" + 
+                                     //"STORET\tNational Park Service Water Resources Division\tCRLA_GSFRA_52\tPothole Creek (No.52 in GS report)\t42.936853\t-121.949314\tKLAMATH\tOREGON\t\t18010201\t--\t0\t\tNAD83\t\t\tn/a\tn/a\n" + 
+                                     //"NCDC\tNCDC\t12002175\tMILLIKIN\t32.96666667\t-91.23333333\tEAST CARROLL\tLOUISIANA\tUNITED STATES\t\t\t-99999\tft\t\t1904-07-05\t1905-03-31\t166212\tn/a" + 
+                                     "CDWR\tCooperative Program of CDWR, NCWCD & LSPWCD\tDEUDITCO\tDEUEL SNYDER CANAL\t40.282657\t-103.848246\t\tColorado\tUnited States\t\t\t\t\t\t2008-03-31\t2014-09-25\tn/a\tn/a";//the contents of a tab-delimited input file
+                                     
+                                     
     //Outputs
-    String modelRunTime = "-1";//How long the model took to run in milliseconds
-    
     
     //Gets
     public File getResults() {
         return new File(mainFolder, "downloadData.zip");
     }
-    public String getRunTime() {
-        return modelRunTime;
-    }
     
     
     //Sets
@@ -73,6 +77,12 @@
     public void setUSGSwqTrue(boolean USGSwqTrue) {
         this.USGSwqTrue = USGSwqTrue;
     }
+    public void setUSGSfloodTrue(boolean USGSfloodTrue) {
+        this.USGSfloodTrue = USGSfloodTrue;
+    }
+    public void setUSGSstageDischargeTrue(boolean USGSstageDischargeTrue) {
+        this.USGSstageDischargeTrue = USGSstageDischargeTrue;
+    }
     public void setUSGSWellsDepthTrue(boolean USGSWellsDepthTrue) {
         this.USGSWellsDepthTrue = USGSWellsDepthTrue;
     }
@@ -85,15 +95,15 @@
     public void setSTORETwqTrue(boolean STORETwqTrue) {
         this.STORETwqTrue = STORETwqTrue;
     }
-    public void setSNOTELcontent(String SNOTELcontent) {
-        this.SNOTELcontent = SNOTELcontent;
-    }
-    public void setSNOTELtimeseries(String SNOTELtimeseries) {
-        this.SNOTELtimeseries = SNOTELtimeseries;
-    }
     public void setNCDCelement(String NCDCelement) {
         this.NCDCelement = NCDCelement;
     }
+    public void setCDWRflowTrue(boolean CDWRflowTrue) {
+        this.CDWRflowTrue = CDWRflowTrue;
+    }
+    public void setCDWRstageDischargeTrue(boolean CDWRstageDischargeTrue) {
+        this.CDWRstageDischargeTrue = CDWRstageDischargeTrue;
+    }
             
     
     /**
@@ -177,23 +187,50 @@
             }
         }
     }
-    public void run() throws IOException, ParseException, InterruptedException {
-        //Inputs
-//        assert args.length > 0;
-//        String mainFolder      = args[0]; //downloaded data output location and where the file containing the inputs is
-//        String attributeFileName   = args[1]; //the name of the file containing the inputs
-//        String beginDate           = args[2]; //user defined begin date
-//        String endDate             = args[3]; //user defined end date
-//        boolean USGSflowTrue       = Boolean.parseBoolean(args[4]); //if true then flow data will be downloaded for USGS stations
-//        boolean USGSwqTrue         = Boolean.parseBoolean(args[5]); //if true then water quality data will be downloaded for USGS stations
-//        boolean USGSWellsDepthTrue = Boolean.parseBoolean(args[6]); //if true then well depth data will be downloaded for USGSwell stations
-//        boolean USGSWellsWQtrue    = Boolean.parseBoolean(args[7]); //if true then water quality data will be downloaded for USGSwell stations
-//        boolean STORETflowTrue     = Boolean.parseBoolean(args[8]); //if true then flow data will be downloaded for STORET stations
-//        boolean STORETwqTrue       = Boolean.parseBoolean(args[9]); //if true then water quality data will be downloaded for STORET stations
-//        String SNOTELcontent       = args[10]; //one from list of Content_CB
-//        String SNOTELtimeseries    = args[11]; //one from the list of Timeseries_CB
-//        String NCDCelement         = args[12]; //NCDC download type
+    /**
+     * 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 contents of the data query to a text file
+     * @param textData  string array to be written as each line of the text file
+     * @param fileName  the name of the output file to be written
+     * @throws IOException
+     */
+    public ArrayList<String> writeOutputFile(ArrayList<String> textData, ArrayList<String> fileNameList, String fileName) throws IOException{
+        String path = mainFolder + "/" + fileName;
+        FileWriter write =  new FileWriter(path, false);
+        PrintWriter print_line = new PrintWriter(write);
 
+        //Output data to text file
+        for(int i = 0; i < textData.size(); i++) {
+            print_line.printf("%s" + "%n", textData.get(i));
+        }
+        print_line.close();
+        System.out.println("Text File located at:\t" + path);
+        fileNameList.add(fileName);
+        return fileNameList;
+    }
+    public void run() throws IOException, ParseException, InterruptedException, Exception {
+        //If no date input, make it the maximum of available data
+        if(beginDate == null || beginDate.equalsIgnoreCase("")){
+            beginDate = "1850-01-01";
+        }
+        if(endDate == null || endDate.equalsIgnoreCase("")){
+            // Pull current date for upper limit of data search
+            DateFormat desiredDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+            Date currentDate = new Date();
+            endDate = desiredDateFormat.format(currentDate);
+        }
         
         //Pull data out into a string array
         long startTime = System.currentTimeMillis();
@@ -206,85 +243,78 @@
             String database = currentAttributes[0];
             //Call Download function for current database
             if(database.equalsIgnoreCase("USGS")){
-                //Make list of USGS flow inputs
-                String[] inputs = new String[7];
-                inputs[0] = mainFolder;            //outputLocation
-                inputs[1] = currentAttributes[2] + "_FlowData.txt";//file name
-                inputs[2] = currentAttributes[2];      //Station_ID
-                inputs[3] = "flow";                    //WQ_test
-                inputs[4] = beginDate;                 //begin_date
-                inputs[5] = endDate;                   //end_date
-
-
+                USGS_Data usgs_data = new USGS_Data();
                 //If the user desires it then get USGS flow data
                 if(USGSflowTrue){
                     //Download USGS flow data
-                    USGS_download_Data.main(inputs);
-                    fileNameList.add(inputs[1]);
+                    Object[] returnArray = usgs_data.getUSGSflowData(currentAttributes[2], beginDate, endDate);
+                    ArrayList<String> textData = (ArrayList<String>) returnArray[0];
+                    //String[][] flowData = (String[][]) returnArray[1];
+                    //String start = (String) returnArray[2];
+                    //String end = (String) returnArray[3];
+                    fileNameList = writeOutputFile(textData, fileNameList, "USGS_" + currentAttributes[2] + "_FlowData.txt");
                 }
-
                 //If the user desires it then get USGS WQ data
                 if(USGSwqTrue){
                     //Make changes for WQ inputs
-                    inputs[1] = currentAttributes[2] + "_WQData.txt";//file name
-                    inputs[3] = "all";                 //water quality test
-                    //Download USGS WQ data
-                    USGS_download_Data.main(inputs);
-                    fileNameList.add(inputs[1]);
+                    Object[] returnArray = usgs_data.getUSGSwqData(currentAttributes[2]);
+                    ArrayList<String> textData = (ArrayList<String>) returnArray[0];
+                    //String[][] allWQdata = (String[][]) returnArray1[1];
+                    //String start = (String) returnArray[2];
+                    //String end = (String) returnArray[3];
+                    fileNameList = writeOutputFile(textData, fileNameList, "USGS_" + currentAttributes[2] + "_WQData.txt");
+                }
+                //If the user desires it then get USGS flood data
+                if(USGSfloodTrue){
+                    //Download USGS flow data
+                    Object[] returnArray = usgs_data.getUSGSPeakData(currentAttributes[2], beginDate, endDate);
+                    ArrayList<String> textData = (ArrayList<String>) returnArray[0];
+                    //double[][] floodData = (double[][]) returnArray[1];
+                    //String start = String.valueOf((double) returnArray[2]);
+                    //String end = String.valueOf((double) returnArray[3]);
+                    fileNameList = writeOutputFile(textData, fileNameList, "USGS_" + currentAttributes[2] + "_FloodData.txt");
+                }
+                //If the user desires it then get USGS stage-discharge data (if any) data
+                if(USGSstageDischargeTrue){
+                    //Download USGS flow data
+                    Object[] returnArray = usgs_data.getUSGSratingCurve(currentAttributes[2]);
+                    ArrayList<String> textData = (ArrayList<String>) returnArray[0];
+                    //double[][] ratingCurve = (double[][]) returnArray[1];
+                    fileNameList = writeOutputFile(textData, fileNameList, "USGS_" + currentAttributes[2] + "_StageDischargeData.txt");
                 }
 
             }else if(database.equalsIgnoreCase("STORET")){
-                //Make list of STORET flow inputs
-                String[] inputs = new String[7];
-                inputs[0] = mainFolder;            //outputLocation
-                inputs[1] = currentAttributes[2] + "_FlowData.txt";//file name
-                inputs[2] = currentAttributes[1];      //supervising agency
-                inputs[3] = currentAttributes[2];      //Station_ID
-                inputs[4] = "flow";                    //WQ_test
-                inputs[5] = beginDate;                 //begin_date
-                inputs[6] = endDate;                   //end_date
-
-
+                STORET_Data storet_data = new STORET_Data();
                 //If the user desires it then get STORET flow data
                 if(STORETflowTrue){
                     //Download STORET flow data
-                    STORET_download_Data.main(inputs);
-                    fileNameList.add(inputs[1]);
+                    String zip_location = storet_data.downloadSTORET(mainFolder, currentAttributes[1], currentAttributes[2], "flow", beginDate, endDate);
+                    ArrayList<String> textData = storet_data.Unzip_STORETDownloadFilesAll(zip_location);
+                    fileNameList = writeOutputFile(textData, fileNameList, "STORET_" + currentAttributes[2] + "_FlowData.txt");
                 }
-
                 //If the user desires it then get STORET WQ data
                 if(STORETwqTrue){
-                    //Make changes for WQ inputs
-                    inputs[1] = currentAttributes[2] + "_WQData.txt";//file name
-                    inputs[4] = "all";                 //water quality test
-                    //Download STORET WQ data
-                    STORET_download_Data.main(inputs);
-                    fileNameList.add(inputs[1]);
+                    //Download STORET wq data
+                    String zip_location = storet_data.downloadSTORET(mainFolder, currentAttributes[1], currentAttributes[2], "all", beginDate, endDate);
+                    ArrayList<String> textData = storet_data.Unzip_STORETDownloadFilesAll(zip_location);
+                    fileNameList = writeOutputFile(textData, fileNameList, "STORET_" + currentAttributes[2] + "_WQData.txt");
                 }
                     
             }else if(database.equalsIgnoreCase("SNOTEL")){
-                //Make list of SNOTEL inputs
-                String[] inputs = new String[11];
-                inputs[0] = mainFolder;            //outputLocation
-                inputs[1] = currentAttributes[7] + "_" + currentAttributes[2] + ".csv";    //file name (State_StationID.csv)
-                inputs[2] = currentAttributes[3];      //Site name
-                inputs[3] = currentAttributes[2];      //Site ID number
-                inputs[4] = currentAttributes[7];      //state
-                inputs[5] = SNOTELcontent;             //one from list of Content_CB
-                inputs[6] = SNOTELtimeseries;          //one from the list of Timeseries_CB
-                inputs[7] = currentAttributes[14];     //begin date from attribute table
-                inputs[8] = currentAttributes[15];     //end date from attribute table
-                inputs[9] = beginDate;                 //begin date from GUI
-                inputs[10] = endDate;                  //end date from GUI
-                //Download all SNOTEL data
-                SNOTEL_download_Data.main(inputs);
-                fileNameList.add(inputs[1]);
+                //Download SNOTEL data
+                SNOTEL_Data snotel_data = new SNOTEL_Data();
+                Object[] returnArray = snotel_data.getSNOTELdata(currentAttributes[2], currentAttributes[7], "snow");
+                ArrayList<String> textData = (ArrayList<String>) returnArray[0];
+                //String[][] flowData = (String[][]) returnArray[1];
+                //String start = (String) returnArray[2];
+                //String end = (String) returnArray[3];
+                fileNameList = writeOutputFile(textData, fileNameList, "SNOTEL_" + currentAttributes[7] + "_" + currentAttributes[2] + ".csv");
                 
             }else if(database.equalsIgnoreCase("NCDC")){
                 //Make list of NCDC inputs
                 String[] inputs = new String[11];
                 inputs[0] = mainFolder;        //outputLocation
-                inputs[1] = "NCDC" + currentAttributes[2] + "_AllData_" + currentAttributes[14] + "_" + currentAttributes[15] + ".csv";   //file name (NCDC_10000001_AllData.txt)
+                inputs[1] = "NCDC_" + currentAttributes[2] + "_AllData_" + currentAttributes[14] + "_" + currentAttributes[15] + ".csv";   //file name (NCDC_10000001_AllData.txt)
                 inputs[2] = currentAttributes[2];  //Site ID number
 
                 //Check for "n/a" WBAN IDs and replace them with ""
@@ -304,31 +334,54 @@
 //                String fileName = NCDC_download_Data.main(inputs);
 //                fileNameList.add(fileName);
                 
+            }else if(database.equalsIgnoreCase("CDWR")){
+                CDWR_Data cdwr_data = new CDWR_Data();
+                //Download CDWR flow data
+                if(CDWRflowTrue){
+                    Object[] returnArray = cdwr_data.getCDWRflowData(currentAttributes[2], beginDate, endDate, "Daily");
+                    ArrayList<String> textData = (ArrayList<String>) returnArray[0];
+                    //String[][] flowData = (String[][]) returnArray[1];
+                    //String start = (String) returnArray[2];
+                    //String end = (String) returnArray[3];
+                    if(textData.size() == 1){
+                        //If only the headers and no data, replace with an error 
+                        textData.set(0, "There is no available flow data in the CDWR database for station '" + currentAttributes[2] + "' and the specified date range.");
+                        textData.add("The CDWR database is sensitive to the begin date used, try specifying a later begin date");
+                    }
+                    fileNameList = writeOutputFile(textData, fileNameList, "CDWR_" + currentAttributes[2] + "_FlowData.csv");
+                }
+                //Download CDWR stage-discharge data
+                if(CDWRstageDischargeTrue){
+                    Object[] returnArray = cdwr_data.getCDWRratingCurve(currentAttributes[2]);
+                    ArrayList<String> textData = (ArrayList<String>) returnArray[0];
+                    //double[][] ratingCurve = (double[][]) returnArray[1];
+                    if(textData.size() == 1){
+                        //If only the headers and no data, replace with an error 
+                        textData.set(0, "There is no available flow data in the CDWR database for station '" + currentAttributes[2] + "' and the specified date range.");
+                        textData.add("The CDWR database is sensitive to the begin date used, try specifying a later begin date");
+                    }
+                    fileNameList = writeOutputFile(textData, fileNameList, "CDWR_" + currentAttributes[2] + "_StageDischargeData.csv");
+                }
+                
             }else if(database.equalsIgnoreCase("USGSWells")){
-                //Make list of USGSWells depth inputs
-                String[] inputs = new String[6];
-                inputs[0] = mainFolder;                //outputLocation
-                inputs[1] = "Water";                       //data type
-                inputs[2] = currentAttributes[2];          //station ID
-                inputs[3] = beginDate;                     //begin date
-                inputs[4] = endDate;                       //end date
-                inputs[5] = currentAttributes[2] + "_DepthData.txt";//file name
-
-                //If the user desires it then get USGSWells depth data
+                USGSwell_Data usgsWell_data = new USGSwell_Data();
+                //Download USGS Well height data
                 if(USGSWellsDepthTrue){
-                    //Download USGSWells depth data
-                    USGSwells_Download_Data.main(inputs);
-                    fileNameList.add(inputs[5]);
+                    Object[] returnArray = usgsWell_data.getUSGSwellHeightData(currentAttributes[2], beginDate, endDate);
+                    ArrayList<String> textData = (ArrayList<String>) returnArray[0];
+                    //String[][] flowData = (String[][]) returnArray[1];
+                    //String start = (String) returnArray[2];
+                    //String end = (String) returnArray[3];
+                    fileNameList = writeOutputFile(textData, fileNameList, "USGSwells_" + currentAttributes[2] + "_HeightData.csv");
                 }
-
-                //If the user desires it then get USGSWells WQ data
+                //Download USGS Well water quality data
                 if(USGSWellsWQtrue){
-                    //Make changes for WQ inputs
-                    inputs[1] = "WaterQuality";                        //data type
-                    inputs[5] = currentAttributes[2] + "_WQData.txt";  //file name
-                    //Download USGSWells WQ data
-                    USGSwells_Download_Data.main(inputs);
-                    fileNameList.add(inputs[5]);
+                    Object[] returnArray = usgsWell_data.getUSGSwellWQdata(currentAttributes[2]);
+                    ArrayList<String> textData = (ArrayList<String>) returnArray[0];
+                    //String[][] allWQdata = (String[][]) returnArray1[1];
+                    //String start = (String) returnArray[2];
+                    //String end = (String) returnArray[3];
+                    fileNameList = writeOutputFile(textData, fileNameList, "USGSwells_" + currentAttributes[2] + "_WQData.csv");
                 }
             }
         }
@@ -346,7 +399,6 @@
         System.out.println("Finished.  all models took: " + (endTime - startTime) + 
                 " millseconds (" + ((endTime - startTime)/1000) + " seconds)(" +  (((endTime - startTime)/1000)/60) + " minutes) to run");
         System.out.println("");
-        modelRunTime = String.valueOf(endTime-startTime);
         
         //Location of Attributes (just for reference)
         //    Database     = 0
@@ -368,7 +420,7 @@
         //    Coop_ID        = 16
         //    WBAN_ID        = 17
     }
-    public static void main(String[] args) throws IOException, ParseException, InterruptedException{
+    public static void main(String[] args) throws IOException, Exception{
         guiDataDownloads model = new guiDataDownloads();
         
         //Run model

src/java/m/datadownload/DataDownload_V1_0.java

@@ -1,7 +1,6 @@
 package m.datadownload;
 
 import datadownload.guiDataDownloads;
-import java.io.IOException;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import javax.ws.rs.Path;
@@ -9,16 +8,15 @@
 import oms3.annotations.Description;
 import oms3.annotations.Name;
 import oms3.annotations.VersionInfo;
-import org.apache.commons.io.IOUtils;
 import org.codehaus.jettison.json.*;
 import csip.utils.JSONUtils;
 import csip.utils.Services;
 import java.io.File;
 
-@Name("data download")
-@Description("USGS, USGS wells, STORET, SNOTEL, NCDC data download")
+@Name("datadownload")
+@Description("USGS, USGS wells, STORET, SNOTEL, CDWR, NCDC data download")
 @VersionInfo("1.0")
-@Path("m/datadownload/1.0")
+@Path("m/datadownload/datadownload/1.0")
 public class DataDownload_V1_0 extends AbstractModelService {
 
     guiDataDownloads model = new guiDataDownloads();
@@ -36,13 +34,15 @@
                 model.setEndDate(m.get("end_date").getString(VALUE));
                 model.setUSGSflowTrue(m.get("USGS_flow_true").getBoolean(VALUE));
                 model.setUSGSwqTrue(m.get("USGS_wq_true").getBoolean(VALUE));
+                model.setUSGSfloodTrue(m.get("USGS_flood_true").getBoolean(VALUE));
+                model.setUSGSstageDischargeTrue(m.get("USGS_stagedischarge_true").getBoolean(VALUE));
                 model.setUSGSWellsDepthTrue(m.get("USGSwells_depth_true").getBoolean(VALUE));
                 model.setUSGSWellsWQtrue(m.get("USGSwells_wq_true").getBoolean(VALUE));
                 model.setSTORETflowTrue(m.get("STORET_flow_true").getBoolean(VALUE));
                 model.setSTORETwqTrue(m.get("STORET_wq_true").getBoolean(VALUE));
-                model.setSNOTELcontent(m.get("SNOTEL_content").getString(VALUE));
-                model.setSNOTELtimeseries(m.get("SNOTEL_timeseries").getString(VALUE));
                 model.setNCDCelement(m.get("NCDC_element").getString(VALUE));
+                model.setCDWRflowTrue(m.get("CDWR_flow_true").getBoolean(VALUE));
+                model.setCDWRstageDischargeTrue(m.get("CDWR_stagedischarge_true").getBoolean(VALUE));
 
                 model.run();
                 return AbstractModelService.EXEC_OK;
@@ -59,7 +59,6 @@
     protected JSONArray createResults() throws Exception {
         JSONArray result = new JSONArray();
         result.put(JSONUtils.data("output", "Output successfully created"));
-        result.put(JSONUtils.data("download_time_ms", "The download took: " + model.getRunTime() + " milliseconds to finish"));
         result.put(JSONUtils.data("output_location", model.getResults().getName()));
         return result;
     }

src/java/m/datadownload/DataDownload_V1_0Req.json

@@ -4,7 +4,7 @@
     {
       "name": "attribute_file",
       "description": "the contents of a tab-delimited file as a string which contain the attributes of the stations to be searched for, including a header on the first line which is not read in as an example template",
-      "value": "Database\tOrg\tStaID\tStaName\tLatitude\tLongitude\tCounty\tState\tCountry\tHUCNumber\tDrainArea\tElev\tElevUnits\tElevDatum\tBeginDate\tEndDate\tCoop_ID\tWBAN_ID\nUSGS\tUSGS\t07369654\tCoon Bayou Tributary near Tillar\t33.74982893\t-91.4115096\tDesha County\tARKANSAS\tUnited States\t8050002\t0.02\t145\tft\tNGVD29\t1995-03-05\t1996-12-16\tn/a\tn/a\nUSGSWells\tUSGS\t332432091031501\tD0016  WASHINGTON\t33.409005\t-91.0542732\tWashington County\tMISSISSIPPI\tUnited States\t8030209\t\t125\tft\tNGVD29\t\t\tn/a\tn/a\nSNOTEL\tSNOTEL\t330\tBeaver Divide\t40.61666667\t-111.1\tWasatch\tUTAH\tUnited States\t\t\t8280\tfeet\t\t1978-10-01\t\tn/a\tn/a\nSTORET\tNational Park Service Water Resources Division\tCRLA_GSFRA_52\tPothole Creek (No.52 in GS report)\t42.936853\t-121.949314\tKLAMATH\tOREGON\t\t18010201\t--\t0\t\tNAD83\t\t\tn/a\tn/a\nNCDC\tNCDC\t12002175\tMILLIKIN\t32.96666667\t-91.23333333\tEAST CARROLL\tLOUISIANA\tUNITED STATES\t\t\t-99999\tft\t\t1904-07-05\t1905-03-31\t166212\tn/a"
+      "value": "Database\tOrg\tStaID\tStaName\tLatitude\tLongitude\tCounty\tState\tCountry\tHUCNumber\tDrainArea\tElev\tElevUnits\tElevDatum\tBeginDate\tEndDate\tCoop_ID\tWBAN_ID\nUSGS\tUSGS\t07369654\tCoon Bayou Tributary near Tillar\t33.74982893\t-91.4115096\tDesha County\tARKANSAS\tUnited States\t8050002\t0.02\t145\tft\tNGVD29\t1995-03-05\t1996-12-16\tn/a\tn/a\nUSGSWells\tUSGS\t332432091031501\tD0016  WASHINGTON\t33.409005\t-91.0542732\tWashington County\tMISSISSIPPI\tUnited States\t8030209\t\t125\tft\tNGVD29\t\t\tn/a\tn/a\nSNOTEL\tSNOTEL\t330\tBeaver Divide\t40.61666667\t-111.1\tWasatch\tUTAH\tUnited States\t\t\t8280\tfeet\t\t1978-10-01\t\tn/a\tn/a\nSTORET\tNational Park Service Water Resources Division\tCRLA_GSFRA_52\tPothole Creek (No.52 in GS report)\t42.936853\t-121.949314\tKLAMATH\tOREGON\t\t18010201\t--\t0\t\tNAD83\t\t\tn/a\tn/a\nNCDC\tNCDC\t12002175\tMILLIKIN\t32.96666667\t-91.23333333\tEAST CARROLL\tLOUISIANA\tUNITED STATES\t\t\t-99999\tft\t\t1904-07-05\t1905-03-31\t166212\tn/a\nCDWR\tCooperative Program of CDWR, NCWCD & LSPWCD\tDEUDITCO\tDEUEL SNYDER CANAL\t40.282657\t-103.848246\t\tColorado\tUnited States\t\t\t\t\t\t2008-03-31\t2014-09-25\tn/a\tn/a"
     },
     {
       "name": "begin_date",
@@ -27,6 +27,16 @@
       "value": true
     },
     {
+      "name": "USGS_flood_true",
+      "description": "Whether flood data from USGS streamflow stations is desired to be downloaded (True | False)",
+      "value": true
+    },
+    {
+      "name": "USGS_stagedischarge_true",
+      "description": "Whether stage-discharge data from USGS streamflow stations is desired to be downloaded (True | False)",
+      "value": true
+    },
+    {
       "name": "USGSwells_depth_true",
       "description": "Whether depth data from USGS well monitoring stations is desired to be downloaded (True | False)",
       "value": true
@@ -47,19 +57,19 @@
       "value": false
     },
     {
-      "name": "SNOTEL_content",
-      "description": " One of the values from the SNOTEL content list to determine what is downloaded: (Standard SNOTEL | All Sensors | Soil Moisture & Temperature | Soil Moisture & Precipitation | Soil & Air Temperature | Accumulated Precipitation | Accumulated Precipitation & Snow | Solar | Air Temperature | Precipitation Accumulation | Relative Humidity | Snow Depth | Snow Water Equivalent | Soil Moisture Percent | Soil Temperature | Solar Radiation - Total | Wind | Wind Direction | Wind Speed | Barometric Pressure | Conductivity | Water Temperature | Ground Surf Inter Temp | Precipitation Increment | Pulse Line Monitor-eti Guage | Well Depth | Fuel Moisture | Fuel Temperature Internal | Diagnostics | Relative Humidity Enclosure | Wind Movement | Solar Radiation - Accumulated | Dew Point Temperature | Vapor Pressure - Partial | Vapor Pressure - Saturated | Snow Temperature | Stream Flow | Stream Stage | Solar Radiation - Net)",
-      "value": "Standard SNOTEL"
-    },
-    {
-      "name": "SNOTEL_timeseries",
-      "description": "One of the values from the SNOTEL timeseries list to determine what timestep of data is downloaded (Daily | Hourly | 12:00 AM | 3:00 AM | 6:00 AM | 9:00 AM | 12:00 PM | 3:00 PM | 6:00 PM | 9:00 PM)",
-      "value": "Daily"
-    },
-    {
       "name": "NCDC_element",
       "description": "The download option for NCDC stations ('GHCND' is a Daily GHCND download | 'GHCNDMS' is a Monthly Summary GHCND)",
       "value": "GHCND"
+    },
+    {
+      "name": "CDWR_flow_true",
+      "description": "Whether flow data from CDWR streamflow stations is desired to be downloaded (True | False)",
+      "value": true
+    },
+    {
+      "name": "CDWR_stagedischarge_true",
+      "description": "Whether water quality data from CDWR streamflow stations is desired to be downloaded (True | False)",
+      "value": true
     }
   ]
 }
\ No newline at end of file