@@ -6,7 +6,7 @@ |
import java.util.Calendar; |
|
/** |
-* Last Updated: 20-January-2015 |
+* Last Updated: 30-January-2015 |
* @author Tyler Wible |
* @since 16-December-2014 |
*/ |
@@ -370,15 +370,87 @@ |
public double CDPHE_HumanHealth(String[][] flowData) throws IOException, ParseException{ |
DoubleMath doubleMath = new DoubleMath(); |
|
+ //Calculate design flows |
+ double[] flowOnlyData = convertSecondColumn(flowData); |
+ double designFlow = doubleMath.round(doubleMath.meanHarmonic(flowOnlyData), 3); |
+ |
+ return designFlow; |
+ } |
+ /** |
+ * Convert a string[][] array's second column to a double[] array, |
+ * aka pull out the flow values from flowData |
+ * @param flowData flow data, column1 = dates (format yyyy-mm-dd), column2 = flow values |
+ * @return |
+ */ |
+ private double[] convertSecondColumn(String[][] flowData){ |
//Pull data |
double[] flowOnlyData = new double[flowData.length]; |
for(int i=0; i<flowData.length; i++){ |
flowOnlyData[i] = Double.parseDouble(flowData[i][1]); |
} |
|
- //Calculate design flows |
- double designFlow = doubleMath.round(doubleMath.meanHarmonic(flowOnlyData), 3); |
+ return flowOnlyData; |
+ } |
+ /** |
+ * |
+ * @param flowData a String[][] of flow data, column1 = dates (format yyyy-mm-dd), column2 = flow values |
+ * @return |
+ * @throws IOException |
+ * @throws ParseException |
+ */ |
+ public String CDPHE_REG31(String[][] flowData) throws IOException, ParseException{ |
+ //Calculate acute biologically based low flows (1-day 3-year) |
+ System.out.println("Calcualting Reg. 31 1E3 Acute Monthly Low Flows..."); |
+ double[] monthlyBiologically_1day = CDPHE_Biological(flowData, 1, 3, 120, 5); |
|
- return designFlow; |
+ //Calculate chronic biologically based low flows (7-day 3-year) |
+ System.out.println("Calcualting Reg. 31 7E3 Chronic Monthly Low Flows..."); |
+ double[] monthlyBiologically_7day = CDPHE_Biological(flowData, 7, 3, 120, 5); |
+ |
+ //Calculate chronic biologically based low flows (30-day 3-year) |
+ System.out.println("Calcualting Reg. 31 30E3 Chronic Monthly Low Flows..."); |
+ double[] monthlyBiologically_30day = CDPHE_Biological(flowData, 30, 3, 120, 5); |
+ |
+ //Calculate annual median of data with a 5-year return period |
+ System.out.println("Calcualting Reg. 31 1E5 Annual Median of Daily Average Flows..."); |
+ double median_R_yearFlow = annualMedianReturnPeriod(flowData, 5); |
+ |
+ //Format the results into a summary table |
+ String summaryTable = "Month\t1E3 Acute Monthly Low Flows\t7E3 Chronic Monthly Low Flows\t30E3 Chronic Monthly Low Flows"; |
+ String[] months = {"Entire Record", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; |
+ for(int i=0; i<13; i++){ |
+ summaryTable = summaryTable + "\r\n" + months[i] + "\t" + monthlyBiologically_1day[i] + "\t" + monthlyBiologically_7day[i] + "\t" + monthlyBiologically_30day[i]; |
+ } |
+ summaryTable = summaryTable + "\r\n" + median_R_yearFlow; |
+ |
+ return summaryTable; |
+ } |
+ private double annualMedianReturnPeriod(String[][] flowData, int R){ |
+ //Calculate the annual median of daily average flow values with a recurrance intervale of 1 in "R" years |
+ DoubleArray doubleArray = new DoubleArray(); |
+ DoubleMath doubleMath = new DoubleMath(); |
+ |
+ //Calculate mediant for each year in time period |
+ ArrayList<Double> medianFlows = new ArrayList<Double>(); |
+ boolean moreYears = flowData.length > 0; |
+ String currentYear = flowData[0][0].substring(0,4); |
+ String finalYear = flowData[flowData.length - 1][0].substring(0,4); |
+ while(moreYears){ |
+ //Get current year's data and calculate it's statistics |
+ String[][] partialData = doubleArray.getYearsData(flowData, currentYear); |
+ double[] flowOnlyData = convertSecondColumn(partialData); |
+ medianFlows.add(doubleMath.Median(flowOnlyData)); |
+ |
+ int nextYear = Integer.parseInt(currentYear) + 1; |
+ if(finalYear.compareToIgnoreCase(String.valueOf(nextYear)) >= 0){ |
+ currentYear = String.valueOf(nextYear); |
+ }else{ |
+ moreYears = false; |
+ } |
+ } |
+ |
+ //Calculate return period of data |
+ double median_RyearFlow = doubleArray.calculateReturnPeriod(medianFlows, R); |
+ return median_RyearFlow; |
} |
} |
@@ -49,7 +49,7 @@ |
} |
} |
/** |
-* Last Updated: 6-January-2015 |
+* Last Updated: 29-January-2015 |
* @author Tyler Wible |
* @since 21-June-2012 |
*/ |
@@ -899,6 +899,48 @@ |
return SeasonalData; |
} |
/** |
+ * Calculate the flow associated with the n-year return period from the set of annual data |
+ * @param nYearFlows a list of annual flow values (aka one value per year) |
+ * @param n the n-year return period for the desired flow |
+ * @return |
+ */ |
+ public double calculateReturnPeriod(ArrayList<Double> nYearFlows, int n){ |
+ DoubleArray doubleArray = new DoubleArray(); |
+ |
+ //Remove non-values |
+ int ctr = 0; |
+ for(int i=0; i<nYearFlows.size(); i++){ |
+ if(nYearFlows.get(i) != Double.NaN){ |
+ ctr++; |
+ } |
+ } |
+ String[][] nYearData = new String[ctr][2]; |
+ ctr=0; |
+ for(int i=0; i<nYearFlows.size(); i++){ |
+ if(nYearFlows.get(i) != Double.NaN){ |
+ nYearData[ctr][0] = String.valueOf(ctr); |
+ nYearData[ctr][1] = String.valueOf(nYearFlows.get(i)); |
+ ctr++; |
+ } |
+ } |
+ |
+ //Get ranks for remaining annual data |
+ double[][] nYearRanks = doubleArray.weibullPlottingPosition(nYearData); |
+ |
+ //Find the "n" recurrence interval and return its corresponding flow as the n-year Flow |
+ double n_yearFlow = 0; |
+ double target = (double) n/10; |
+ for(int i=0; i<(nYearRanks.length - 1); i++){ |
+ if(n < nYearRanks[i][0] && n > nYearRanks[i+1][0]){ |
+ //Linear interpolation for flow value for "n" recurrence interval |
+ n_yearFlow = ((target - nYearRanks[i+1][0])/(nYearRanks[i][0] - nYearRanks[i+1][0]))*(nYearRanks[i][1] - nYearRanks[i+1][1]) + nYearRanks[i+1][1]; |
+ }else if(n == nYearRanks[i][0]){ |
+ n_yearFlow = nYearRanks[i][1]; |
+ } |
+ } |
+ return n_yearFlow; |
+ } |
+ /** |
* |
* @param sortedData the String[][] containing sorted data for the time series |
* (column 1 = dates (yyyy-mm-dd format) column 2 = value |
@@ -13,7 +13,7 @@ |
import java.util.GregorianCalendar; |
|
/** |
-* Last Updated: 6-January-2015 |
+* Last Updated: 29-January-2015 |
* @author Tyler Wible |
* @since 29-June-2011 |
*/ |
@@ -418,33 +418,7 @@ |
//Calculate mQn (7Q10) Statistics |
double mQnFlow = 0; |
if(m != 0 && n != 0){ |
- int ctr = 0; |
- for(int i=0; i<mQnFlows.size(); i++){ |
- if(mQnFlows.get(i) != Double.NaN){ |
- ctr++; |
- } |
- } |
- String[][] mQnData = new String[ctr][2]; |
- ctr=0; |
- for(int i=0; i<mQnFlows.size(); i++){ |
- if(mQnFlows.get(i) != Double.NaN){ |
- mQnData[ctr][0] = String.valueOf(ctr); |
- mQnData[ctr][1] = String.valueOf(mQnFlows.get(i)); |
- ctr++; |
- } |
- } |
- double[][] mQnRanks = doubleArray.weibullPlottingPosition(mQnData); |
- |
- //Find the "n" recurrence interval and return its corresponding flow as the mQnFlow |
- double target = (double) n/10; |
- for(int i=0; i<(mQnRanks.length - 1); i++){ |
- if(n < mQnRanks[i][0] && n > mQnRanks[i+1][0]){ |
- //Linear interpolation for flow value for "n" recurrence interval |
- mQnFlow = ((target - mQnRanks[i+1][0])/(mQnRanks[i][0] - mQnRanks[i+1][0]))*(mQnRanks[i][1] - mQnRanks[i+1][1]) + mQnRanks[i+1][1]; |
- }else if(n == mQnRanks[i][0]){ |
- mQnFlow = mQnRanks[i][1]; |
- } |
- } |
+ mQnFlow = doubleArray.calculateReturnPeriod(mQnFlows, n); |
} |
String errorMessage = ""; |
if(mQnFlow == 0){ |
@@ -40,7 +40,7 @@ |
import org.jfree.data.xy.XYSeriesCollection; |
|
/** |
-* Last Updated: 26-January-2015 |
+* Last Updated: 30-January-2015 |
* @author Tyler Wible |
* @since 24-June-2011 |
*/ |
@@ -72,7 +72,7 @@ |
boolean showMonthlyStatsTF = false; |
boolean calcFlowStatisticsFileTF = true; |
boolean calcCDPHElowflowTF = true; |
- String CDPHE_lowFlowType = "all";//"extreme-value";//"biological";//"human-health";// |
+ String CDPHE_lowFlowType = "all";//"extreme-value";//"biological";//"human-health";//"reg31";// |
int CDPHE_m = 4;//m-day average //only used if CDPHE_lowFlowType == "all" or "extreme-value" or "biological" |
int CDPHE_R = 10;//R-year return period for cdphe flows //only used if CDPHE_lowFlowType == "all" or "extreme-value" or "biological" |
String CDPHE_waterYearBegin = "04-01";//"MM-dd" //only used if CDPHE_lowFlowType == "all" or "extreme-value" |
@@ -105,6 +105,7 @@ |
double biologicalDFLOW_nov = -1; |
double biologicalDFLOW_dec = -1; |
double humanHealthDFLOW = -1; |
+ String reg31DFLOWsummary = "?"; |
double max = -1; |
double min = -1; |
double upperQuartile = -1; |
@@ -275,6 +276,9 @@ |
public String getCDPHE_HumanHealthDFLOW(){ |
return String.valueOf(humanHealthDFLOW); |
} |
+ public String getCDPHE_Reg31DFLOWsummary(){ |
+ return String.valueOf(reg31DFLOWsummary); |
+ } |
public String getMax(){ |
return String.valueOf(max); |
} |
@@ -1991,8 +1995,12 @@ |
//Calculate the Human-health based design flow: |
this.humanHealthDFLOW = cdphe_lowflow.CDPHE_HumanHealth(sortedData_combined); |
|
+ }else if(CDPHE_lowFlowType.equalsIgnoreCase("reg31")){ |
+ //Calcualte the Regulation 31 summary of design flows: |
+ this.reg31DFLOWsummary = cdphe_lowflow.CDPHE_REG31(sortedData_combined); |
+ |
}else if(CDPHE_lowFlowType.equalsIgnoreCase("all")){ |
- //Calculate all 3 design flows |
+ //Calculate all design flows |
this.extremeValueDFLOW = cdphe_lowflow.CDPHE_ExtremeValue(sortedData_combined, CDPHE_m, CDPHE_R, CDPHE_waterYearBegin); |
double[] biologial_flows = cdphe_lowflow.CDPHE_Biological(sortedData_combined, CDPHE_m, CDPHE_R, CDPHE_clusterLength, CDPHE_clusterCountMax); |
this.biologicalDFLOW_all = biologial_flows[0]; |
@@ -2009,6 +2017,7 @@ |
this.biologicalDFLOW_nov = biologial_flows[11]; |
this.biologicalDFLOW_dec = biologial_flows[12]; |
this.humanHealthDFLOW = cdphe_lowflow.CDPHE_HumanHealth(sortedData_combined); |
+ this.reg31DFLOWsummary = cdphe_lowflow.CDPHE_REG31(sortedData_combined); |
} |
} |
}else{ |