STORET_Data.java [src/java/m/cfa] Revision: 8270e78a57e94b386f731fcde8b76e6c9ef568d9  Date: Thu Sep 15 13:55:14 MDT 2016
package m.cfa;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
* Last Updated: 13-September-2016
* @author Tyler Wible
* @since 22-June-2012
*/
public class STORET_Data {
    /**
     * Interfaces with the STORET download website and searches for the data for a specific station and 
     * read it out into a variable depending on what data was requested
     * @param mainFolder  file location to download the resulting STORET zip file into
     * @param resourceFile  the csip resource file for the python driver for the storet rest call
     * @param cfaFormat_FT  if true the internal csip-cfa data format is provided (date\twq_test\r\n1999-01-01\t34.2...), otherwise the STORET data download result file format is provided
     * @param organizationID  The ID for the supervising organization for the station within STORET
     * @param stationID  station ID of the current station, used to search the STORET databes
     * @param wq_test  The word 'flow' or the formatted name for the water quality test being used, Format is: '00600 Total nitrogen, water, unfiltered, milligrams per liter -- mg/L' = '5-digit-USGS-water-quality-test-code test-name -- units'
     * @param beginDate  the used defined begin date of search (yyyy-mm-dd)
     * @param endDate  the user defined end date of search (yyyy-mm-dd)
     * @return  if cfaFormat_TF is True, it returns a tab delimited result file containing flow or water quality data: column1 = date(yyyy-mm-dd), column2 = flowValue
     *   if cfaFormat_TF is False, it returns a tab-delimited result file containing the formated result file of STORET data from the web service query
     * @throws IOException
     * @throws InterruptedException 
     */
    public static File downloadSTORET(String mainFolder, 
                               File resourceFile,
                               boolean cfaFormat_FT,
                               String organizationID,
                               String stationID,
                               String wq_test,
                               String beginDate, 
                               String endDate) throws IOException, InterruptedException{
        //Setup directory/result file
        String file_name = "STORET_" + organizationID + "_" + stationID + "_results.txt";
        file_name = file_name.replace("/", "");
        File storetResultFile = new File(mainFolder, file_name);
        
        //Check dates
        if(!beginDate.equalsIgnoreCase("") && beginDate.compareToIgnoreCase("1900-01-01") < 0){
            //Artificial limit due to the properties of the STORET website
            beginDate = "1900-01-01";
        }else if(beginDate.equalsIgnoreCase("")){
            //Because python can't parse blank values as inputs very well
            beginDate = "-1";
        }
        
        if(!endDate.equalsIgnoreCase("") && endDate.compareToIgnoreCase("1900-01-01") < 0){
            //Artificial limit due to the properties of the STORET website
            endDate = "1900-01-01";
        }else if(endDate.equalsIgnoreCase("")){
            //Because python can't parse blank values as inputs very well
            endDate = "-1";
        }
        
        if(wq_test.equalsIgnoreCase("")){
            //Because python can't parse blank values as inputs very well
            wq_test = "-1";
        }
        
        //Setup inputs to python
        List<String> args = new ArrayList<>();
        args.add("python");
        args.add(resourceFile.getAbsolutePath());
        args.add(String.valueOf(cfaFormat_FT));
        args.add(organizationID);
        args.add(stationID);
        args.add(wq_test);
        args.add(beginDate);
        args.add(endDate);
        args.add(storetResultFile.getAbsolutePath());

        //Call service
        ProcessBuilder pb = new ProcessBuilder(args);
        Process p = pb.start();
        BufferedReader bfr_error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        int exitCode = p.waitFor();

        String line;
        String error_log = "";
        while ((line = bfr_error.readLine()) != null) {
            error_log += line + "\n";
            System.err.println(error_log);
        }
        String temp = (error_log.isEmpty()) ? null : error_log;
        
        return storetResultFile;
    }
    
    /**
     * Interfaces with the STORET download website and searches for the data for a specific station and 
     * read it out into a variable depending on what data was requested
     * @param mainFolder  file location to download the resulting STORET zip file into
     * @param resourceFile  the csip resource file for the python driver for the storet rest call
     * @param cfaFormat_FT  if true the internal csip-cfa data format is provided (date\twq_test\r\n1999-01-01\t34.2...), otherwise the STORET data download result file format is provided
     * @param organizationID  The ID for the supervising organization for the station within STORET
     * @param stationID  station ID of the current station, used to search the STORET databes
     * @param wq_test  The word 'flow' or the formatted name for the water quality test being used, Format is: '00600 Total nitrogen, water, unfiltered, milligrams per liter -- mg/L' = '5-digit-USGS-water-quality-test-code test-name -- units'
     * @param beginDate  the used defined begin date of search (yyyy-mm-dd)
     * @param endDate  the user defined end date of search (yyyy-mm-dd)
     * @return  a String[][] containing the flow or water quality data: column1 = date(yyyy-mm-dd), column2 = flowValue
     * @throws IOException
     */
    public static String[][] getSTORETdata(String mainFolder, 
                                           File resourceFile,
                                           boolean cfaFormat_FT,
                                           String organizationID,
                                           String stationID,
                                           String wq_test,
                                           String beginDate, 
                                           String endDate) throws IOException, InterruptedException{
        //Get storet data
        File storetResultFile = downloadSTORET(mainFolder, resourceFile, cfaFormat_FT, organizationID, stationID, wq_test, beginDate, endDate);
        
        //Read Result file
        FileReader fr = new FileReader(storetResultFile);
        BufferedReader textReader = new BufferedReader(fr);

        String storetData = "";
        String currentLine;
        while((currentLine = textReader.readLine()) !=null){
            if(!storetData.equalsIgnoreCase("")){
                //Convert WQ test values
                String[] columns = currentLine.split("\t");
                double conversion = getWQconversion(columns[2]);
                double value = Double.parseDouble(columns[1]) * conversion;
                storetData = storetData + "\n" + columns[0] + "\t" + String.valueOf(value);
            }else{
                storetData = currentLine;
            }
        }
        textReader.close();
        fr.close();
        
        //Parse result data
        String[][] stationData = User_Data.readUserFile("STORET", stationID, storetData, wq_test, beginDate, endDate);
        
        //add check here for wq vs flow data and make sure to parse/convert the storet data's units into usgs code units
        return stationData;
    }
    /**
     * @param units  the units of the current USGS water quality test.
     * @return a double with the correct conversion factor for the units.
     */
     private static double getWQconversion(String units){
         double conversion = -1.0;
         if(units.equalsIgnoreCase("g/l")){
             conversion = 1000.0;//convert to mg/l
         }else if(units.equalsIgnoreCase("mg/l")){
             conversion = 1.0;//convert to mg/l
         }else if(units.equalsIgnoreCase("ug/l")){
             conversion = 0.001;//convert to mg/l
         }else if(units.equalsIgnoreCase("ng/l")){
             conversion = (1.0/1000000.0);//convert to mg/l
         }else if(units.equalsIgnoreCase("pg/l")){
             conversion = (1.0/1000000000.0);//convert to mg/l
         }else if(units.equalsIgnoreCase("cfs")){
             conversion = 1.0;//convert to cfs
         }else if(units.equalsIgnoreCase("mgd")){
             conversion = 1.54722865;//convert to cfs
         }
         return conversion;
     }
}