oms3.io.DatedData Maven / Gradle / Ivy
/*
* $Id:$
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
package oms3.io;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class DatedData {
// holds date and data arrays so can fill from data then compute things
// like mean monthly based on date
// Data TimeSteps
// kmolson TODO- move to SimConst?
public static final int Daily = 0;
public static final int MeanMonthly = 1;
public static final int MonthlyMean = 2;
public static final int AnnualMean = 3;
public static final int PeriodMedian = 4;
public static final int PeriodStandardDeviation = 5;
public static final int PeriodMininum = 6;
public static final int PeriodMaximum = 7;
private List dates = new ArrayList();
private List datas = new ArrayList();
public DatedData() {
}
public DatedData(Date date, Double data){
dates.add(date);
datas.add(data);
}
public void add(Date date, Double data) {
dates.add(date);
datas.add(data);
}
public void addDate(Date date){
dates.add(date);
}
public void addData(Double data){
datas.add(data);
}
public Date getDate(int i) {
return dates.get(i);
}
public Double getData(int i) {
return datas.get(i);
}
public int getNumDates() {
return dates.size();
}
public int getNumData() {
return datas.size();
}
public void writeDate(int i, Date date) {
dates.set(i, date);
}
public void writeData(int i, Double data) {
datas.set(i, data);
}
// ---------------------------------------------
// TimeStep functions for data
// ---------------------------------------------
// ---------------------------------------------
public double[] getMeanMonthly () {
// ---------------------------------------------
// Provides a per-month mean of data (across all years for that month).
// e.g. 12 means returned- one for all days in January in all years,
// one for all dats in Feb in all years, etc.
// Advance through all data, and sum each month's value.
int monthlyCount[]; //the number of entries per month
double monthlySum[]; //the sum of the data per month
double meanMonthly[]; // The mean value per month
monthlyCount = new int[12]; // Just need count and sum for 12 months
monthlySum = new double[12];
meanMonthly = new double[12];
// Init data to clear.
for (int i=0; i<12; i++) {
monthlyCount[i] = 0;
monthlySum[i] = 0;
meanMonthly[i] = 0;
}
int totalCount = 0;
for (int i=0; i this.getNumDates()) {throw new IllegalArgumentException("No date for data #" + i);}
// Get month data out of date.
month = date.getMonth();
if (month > 11) {throw new IllegalArgumentException("Month number data out of range: " + month);}
// Add to appropriate sum.
monthlyCount[month]++;
monthlySum[month] +=data;
totalCount++;
}
if (totalCount == 0) {throw new IllegalArgumentException("No data used in Mean Montly calculation.");}
for (int i=0; i<12; i++) {
meanMonthly[i] = monthlySum[i]/monthlyCount[i];
}
return meanMonthly;
}
// ---------------------------------------------
public double[] getMonthlyMean () {
// ---------------------------------------------
// Provides a mean for days in each month/year pair. (12 months x N years of data)
// e.g. (12 x N years) of means returned- one for all days in January in 1990,
// one for all dats in Feb in 1990, ... one for all days in January 1991, etc.
//
// Sum the daily data until the month/year changes then
// store the mean.
List monthlyMean = new ArrayList();
int totalCount = 0;
int previousYear = -1;
int previousMonth = -1;
boolean currentValid = false;
for (int i=0; i this.getNumDates()) {throw new IllegalArgumentException("No matching date info for data #" + i);}
// Get month data out of date.
month = date.getMonth(); // kmolson TODO- use calendar instead?
year = date.getYear();
if (month > 11) {throw new IllegalArgumentException("Month number data out of range: " + month);}
// Check if month or year advances.
// This assumes data is in Chronological order. If not, we need to save and
// scan back for matching month/year pairs already written.
// Could add min and max year to data fields of DatedData class and allocate based on that.
// I was just worried about access efficiency... if data is in Chronological order,
// we don't need to worry about it, not keeping track is faster.
boolean sameMonthYear = (month == previousMonth) && (year==previousYear);
if (sameMonthYear) {
// Same month/year pair, so update current entry.
currentSum += data;
currentCount++;
currentValid = true;
}
boolean isLastData = i==(this.getNumData()-1);
if (currentValid && (!sameMonthYear || isLastData)) {
// If moving to new month or year, or it is the last data, add the mean to the result array.
if (currentValid) {
double currentMean = currentSum/currentCount;
monthlyMean.add(currentMean);
}
// Set current to new data and a count of 1
currentCount = 1;
currentSum = data;
}
previousMonth = month;
previousYear = year;
// Add to appropriate sum
totalCount++;
}
if (totalCount == 0) {throw new IllegalArgumentException("No data used in Mean Monthly calculation.");}
// Assign MonthlyMean data to output array.
double[] arr = new double[monthlyMean.size()];
for (int i=0; i < monthlyMean.size(); i++) {
arr[i] = monthlyMean.get(i);
}
return arr;
}
public double[] getOriginalData() {
// Get source data as is, without any date-based computation.
double[] originalData = new double[this.datas.size()];
return originalData;
}
public double[] getDailyData(){
// kmoson TODO- Do we want to take the mean of the
// subdaily data if there is any, or is daily the mininum granularity?
double[] originalData = new double[this.datas.size()];
return originalData;
}
public double[] computeData(int TimeStep) {
// kmolson- timestep originally comes from OF timestep in .luca file.
switch (TimeStep) {
case Daily : { return this.getDailyData(); }
case MeanMonthly : { return this.getMeanMonthly(); }
case MonthlyMean : { return this.getMonthlyMean(); }
default : return this.getOriginalData(); }
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy