DroughtProperties.java [src/java/m/cfa/drought] Revision: Date:
package m.cfa.drought;
import java.io.IOException;
import java.util.ArrayList;
/**
* Last Updated: 13-September-2016
* @author Tyler Wible
* @since 11-July-2012
*/
public class DroughtProperties{
/**
* A list of the deficits of each drought for the current drought analysis
*/
private ArrayList<Double> deficit = null;
/**
* A list of the durations of each drought for the current drought analysis
*/
private ArrayList<Integer> duration = null;
/**
* A list of the intensities of each drought for the current drought analysis
*/
private ArrayList<Double> intensity = null;
/**
* A list containing the end years of each drought for the current drought analysis
*/
private ArrayList<Integer> endYearOfDrought = null;
/**
* Creates a new DroughtProperties analysis and calculates the properties of the
* droughts given the provided annual flow data and annual water demand
* @param annualData a double[][] consisting of column1 = years,
* column2 = annual flow values
* @param waterDemand the drought threshold, if column2 of annualData < waterDemand
* then that year is a drought
*/
public DroughtProperties(double[][] annualData, double waterDemand){
ArrayList<Double> newDeficit = new ArrayList<>();
ArrayList<Integer> newDuration = new ArrayList<>();
ArrayList<Double> newIntensity = new ArrayList<>();
ArrayList<Integer> newEndYearOfDrought = new ArrayList<>();
int droughtCtr = -1;
for(int i=0; i<annualData.length; i++){
//Check if the current year is a drought or surplus
double currentDeficit = waterDemand - annualData[i][1];
//check if this is a drought or not and if it is the first drought on record
if(currentDeficit > 0 && newDeficit.size() > 0){
//If this is not the first drought of record check if it is a continued or new drought
if(newEndYearOfDrought.get(droughtCtr) == (annualData[i][0] - 1)){
//If the previous year was also a drought, this is a continued drought not a new one
//Therefore change the properties of the current drought to reflect the continuation
double totalDeficit = newDeficit.get(droughtCtr);
int totalDuration = newDuration.get(droughtCtr);
//Set properties of drought
newDeficit.set(droughtCtr, currentDeficit + totalDeficit);
newDuration.set(droughtCtr, totalDuration + 1);
newEndYearOfDrought.set(droughtCtr, (int) annualData[i][0]);
double totalIntensity = newDeficit.get(droughtCtr)/newDuration.get(droughtCtr);
newIntensity.set(droughtCtr, totalIntensity);
}else{
//If the previous year was not a drought, this is a new drought so add it to the drought list
droughtCtr++;
newDeficit.add(currentDeficit);
newDuration.add(1);
newIntensity.add(currentDeficit/1);
newEndYearOfDrought.add((int) annualData[i][0]);
}
}else if(currentDeficit > 0){
//If this is the first drought of record add it to the drought list
droughtCtr++;
newDeficit.add(currentDeficit);
newDuration.add(1);
newIntensity.add(currentDeficit/1);
newEndYearOfDrought.add((int) annualData[i][0]);
}else{
//If it is not a drought then do nothing
}
}
deficit = newDeficit;
duration = newDuration;
intensity = newIntensity;
endYearOfDrought = newEndYearOfDrought;
}
//Listed below are the getters for DroughtProperties
/**
* Gets the deficit for the specified drought in the drought list
* @param index index of the drought to be queried
* @return the value of the deficit for the current drought
*/
public double getDeficit(int index){
return deficit.get(index);
}
/**
* Gets the duration for the specified drought in the drought list
* @param index index of the drought to be queried
* @return the value of the duration for the current drought
*/
public int getDuration(int index){
return duration.get(index);
}
/**
* Gets the intensity for the specified drought in the drought list
* @param index index of the drought to be queried
* @return the value of the intensity for the current drought
*/
public double getIntensity(int index){
return intensity.get(index);
}
/**
* Gets the end year of the drought for the specified drought in the drought list
* @param index index of the drought to be queried
* @return the value of the end year of the current drought
*/
public int getEndYear(int index){
return endYearOfDrought.get(index);
}
/**
* Gets the total number of droughts in the current drought analysis
* @return the number of droughts contained in the current drought analysis
*/
public int numberOfDroughts(){
return deficit.size();
}
//Listed below are the modifiers and setters for DroughtStats
/**
* Creates a new drought of deficit 0, duration 1, and intensity 0, lambda = 0
* @param endYear the end year of the new drought to be created
*/
public void addNewDrought(int endYear){
deficit.add(0.0);
duration.add(1);
intensity.add(0.0);
endYearOfDrought.add(endYear);
}
/**
* Creates a new drought from the specified deficit, duration, and drought end year, auto-calculates the drought intensity based on the deficit and duration provided
* @param newDeficit the deficit of the new drought
* @param newDuration the duration of the new drought, zero and negative not permitted
* @param endYear the end year of the new drought, zero not permitted
* @throws IOException
*/
public void addNewDrought(double newDeficit, int newDuration, int endYear) throws IOException{
if(newDuration <=0){
throw(new IOException("Duration of the drought must be a positive non-zero value"));
}
deficit.add(newDeficit);
duration.add(newDuration);
intensity.add(newDeficit/newDuration);
endYearOfDrought.add(endYear);
}
/**
* Removes the specified drought from the list of droughts
* @param index the index of the current drought to be modified
*/
public void removeDrought(int index){
deficit.remove(index);
duration.remove(index);
intensity.remove(index);
endYearOfDrought.remove(index);
}
/**
* Sets the deficit value of the current drought, re-calculates the intensity for the current drought based on the new deficit
* @param index index of the current drought to be modified
* @param newDeficit the new value of the deficit for the current drought
*/
public void setDeficit(int index, double newDeficit){
deficit.set(index, newDeficit);
//re-calculate the intensity based on the new deficit to ensure accurate intensities
setIntensity(index, newDeficit, getDuration(index));
}
/**
* Sets the duration value of the current drought, re-calculates the intensity for the current drought based on the new duration
* @param index index of the current drought to be modified
* @param newDuration the new value of the duration for the current drought, zero and negative not permitted
* @throws IOException
*/
public void setDuration(int index, int newDuration) throws IOException{
if(newDuration <=0){
throw(new IOException("Duration of the drought must be a positive non-zero value"));
}
duration.set(index, newDuration);
//re-calculate the intensity based on the new deficit to ensure accurate intensities
setIntensity(index, getDeficit(index), newDuration);
}
/**
* Sets the intensity value of the current drought
* @param index index of the current drought to be modified
* @param newIntensity the new value of the intensity for the current drought
*/
public void setIntensity(int index, double newIntensity){
intensity.set(index, newIntensity);
}
/**
* Calculates and sets the intensity value of the current drought based on the provided deficit and duration
* @param index index of the current drought to be modified
* @param newDeficit the new value of the newDeficit for the current drought
* @param newDuration the new value of the duration for the current drought, zero not permitted
*/
public void setIntensity(int index, double newDeficit, int newDuration){
//Calculated
double newIntensity = newDeficit/newDuration;
setIntensity(index, newIntensity);
}
/**
* Sets the end year of the current drought
* @param index index of the current drought to be modified
* @param newEndYear the new value of the end year for the current drought, zero not permitted
*/
public void setEndYear(int index, int newEndYear){
endYearOfDrought.set(index, newEndYear);
}
/**
* Set the duration, deficit, drought end year, and calculates and sets the intensity value of the current drought based on the provided deficit and duration and end year
* @param index index of the current drought to be modified
* @param newDeficit the new value of the deficit for the current drought
* @param newDuration the new value of the duration for the current drought, zero not permitted
* @param newEndYear the new value of the end year for the current drought, zero not permitted
* @throws IOException
*/
public void setDrought(int index, double newDeficit, int newDuration, int newEndYear) throws IOException{
if(newDuration <=0){
throw(new IOException("Duration of the drought must be a positive non-zero value"));
}
//Set the duration and deficit of the drought
setDeficit(index, newDeficit);
setDuration(index, newDuration);
setEndYear(index, newEndYear);
//Calculate new intensity for drought
double newIntensity = newDeficit/newDuration;
setIntensity(index, newIntensity);
}
}