243 lines
6.5 KiB
Java
243 lines
6.5 KiB
Java
package org.gcube.dataanalysis.ecoengine.signals;
|
|
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.Arrays;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
|
|
import org.gcube.contentmanagement.graphtools.utils.DateGuesser;
|
|
import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration;
|
|
import org.gcube.dataanalysis.ecoengine.utils.Operations;
|
|
import org.gcube.dataanalysis.ecoengine.utils.Tuple;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
public class TimeSeries {
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(TimeSeries.class);
|
|
|
|
private double[] values;
|
|
private Date[] times;
|
|
private Date[] unsortedtimes;
|
|
private String[] timeLabels;
|
|
private long minimumtimegap = -1;
|
|
private String timepattern;
|
|
|
|
AlgorithmConfiguration config;
|
|
|
|
public TimeSeries(int timeLength, AlgorithmConfiguration config) {
|
|
values = new double[timeLength];
|
|
times = new Date[timeLength];
|
|
unsortedtimes = new Date[timeLength];
|
|
timeLabels = new String[timeLength];
|
|
this.config = config;
|
|
}
|
|
|
|
public TimeSeries(double[] values, Date[] time, String[] timeLabels, AlgorithmConfiguration config) {
|
|
this.values = values;
|
|
this.times = time;
|
|
this.unsortedtimes = Arrays.copyOf(time, time.length);
|
|
this.timeLabels = timeLabels;
|
|
this.config = config;
|
|
}
|
|
|
|
public void setValues(double[] values) {
|
|
this.values = values;
|
|
}
|
|
|
|
public void setTime(Date[] time) {
|
|
this.times = time;
|
|
}
|
|
|
|
public void setTimeLabels(String[] timeLabels) {
|
|
this.timeLabels = timeLabels;
|
|
}
|
|
|
|
public double[] getValues() {
|
|
return values;
|
|
}
|
|
|
|
public String[] getLabels() {
|
|
return timeLabels;
|
|
}
|
|
|
|
public Date[] getTime() {
|
|
return times;
|
|
}
|
|
|
|
|
|
public Date[] extendTime(int furtherPointsinTime){
|
|
Date[] time = new Date[times.length+furtherPointsinTime];
|
|
for (int i=0;i<times.length;i++){
|
|
time[i]=times[i];
|
|
}
|
|
|
|
long lastDate = times[times.length-1].getTime();
|
|
|
|
for (int i=times.length;i<(times.length+furtherPointsinTime);i++){
|
|
time[i]=new Date(lastDate+(i+1-times.length)*minimumtimegap);
|
|
}
|
|
|
|
return time;
|
|
}
|
|
|
|
public double[] getMillisecondsTimeline() {
|
|
double[] secondstimes = new double[times.length];
|
|
for (int i = 0; i < times.length; i++) {
|
|
long t = times[i].getTime();
|
|
secondstimes[i] = (double) t;
|
|
}
|
|
return secondstimes;
|
|
}
|
|
|
|
public long getMimimumTimeGapInMillisecs() {
|
|
if (minimumtimegap > -1)
|
|
return minimumtimegap;
|
|
|
|
long mintime = Long.MAX_VALUE;
|
|
for (int i = 1; i < times.length; i++) {
|
|
long t0 = times[i - 1].getTime();
|
|
long t1 = times[i].getTime();
|
|
long timediff = Math.abs(t1 - t0);
|
|
if (timediff < mintime && timediff > 0)
|
|
mintime = timediff;
|
|
}
|
|
minimumtimegap = mintime;
|
|
return mintime;
|
|
}
|
|
|
|
public void addElement(double value, Date date, String label, int index) {
|
|
values[index] = value;
|
|
times[index] = date;
|
|
unsortedtimes[index] = date;
|
|
timeLabels[index] = label;
|
|
}
|
|
|
|
public void sort() {
|
|
Arrays.sort(times);
|
|
double[] tempvalues = new double[values.length];
|
|
String[] temptimeLabels = new String[timeLabels.length];
|
|
List<Date> unsortedTimesList = Arrays.asList(unsortedtimes);
|
|
int i = 0;
|
|
for (Date time : times) {
|
|
int index = unsortedTimesList.indexOf(time);
|
|
tempvalues[i] = values[index];
|
|
temptimeLabels[i] = timeLabels[index];
|
|
i++;
|
|
}
|
|
values = null;
|
|
timeLabels = null;
|
|
values = tempvalues;
|
|
timeLabels = temptimeLabels;
|
|
unsortedtimes = Arrays.copyOf(times, times.length);
|
|
}
|
|
|
|
public double getValue(int index) {
|
|
return values[index];
|
|
}
|
|
|
|
public Date getDate(int index) {
|
|
return times[index];
|
|
}
|
|
|
|
public String getTimeLabel(int index) {
|
|
return timeLabels[index];
|
|
}
|
|
|
|
// each element in the list is Time,Quantity
|
|
public static TimeSeries buildFromSignal(List<Tuple<String>> lines, AlgorithmConfiguration config) throws Exception {
|
|
TimeSeries ts = new TimeSeries(lines.size(), config);
|
|
int counter = 0;
|
|
String timepattern = null;
|
|
SimpleDateFormat sdf = null;
|
|
for (Tuple<String> line : lines) {
|
|
|
|
String timel = line.getElements().get(0);
|
|
timel = timel.replace("time:", "");
|
|
Double quantity = Double.parseDouble(line.getElements().get(1));
|
|
|
|
Date time = null;
|
|
|
|
if (counter == 0) {
|
|
timepattern = DateGuesser.getPattern(timel);
|
|
ts.setTimepattern(timepattern);
|
|
logger.debug("Time pattern: " + timepattern);
|
|
sdf = new SimpleDateFormat(timepattern, Locale.ENGLISH);
|
|
}
|
|
try{
|
|
time = (Date) sdf.parse(timel);
|
|
}catch(Exception e){
|
|
logger.debug("Error in parsing...adjusting "+timel);
|
|
time = DateGuesser.convertDate(timel).getTime();
|
|
logger.debug("Error in parsing...adjusting "+timel+" in "+time);
|
|
}
|
|
|
|
if (counter == 0) {
|
|
logger.debug("Date detection: input " + timel + " output " + time);
|
|
}
|
|
|
|
ts.addElement(quantity, time, timel, counter);
|
|
counter++;
|
|
|
|
}
|
|
|
|
ts.sort();
|
|
|
|
return ts;
|
|
}
|
|
|
|
public void convertToUniformSignal(double samplingrate) throws Exception {
|
|
if (samplingrate <= 0) {
|
|
if (minimumtimegap < 0)
|
|
getMimimumTimeGapInMillisecs();
|
|
if (minimumtimegap > 0)
|
|
samplingrate = 1d / (double) minimumtimegap;
|
|
}
|
|
|
|
logger.debug("TimeSeries->Samplig rate: " + samplingrate + " minimum gap in time: " + minimumtimegap);
|
|
if (samplingrate == 0)
|
|
return;
|
|
|
|
double[] timeline = getMillisecondsTimeline();
|
|
logger.debug("TimeSeries->filling gaps");
|
|
double[] newvalues = SignalProcessing.fillTimeSeries(values, timeline, samplingrate, config);
|
|
|
|
if (newvalues.length != values.length) {
|
|
logger.debug("TimeSeries->filling also time values");
|
|
Date[] newtimeline = SignalProcessing.fillTimeLine(timeline, samplingrate, config);
|
|
|
|
values = null;
|
|
times = null;
|
|
unsortedtimes = null;
|
|
values = newvalues;
|
|
times = newtimeline;
|
|
unsortedtimes = newtimeline;
|
|
timeLabels = new String[times.length];
|
|
}
|
|
|
|
logger.debug("TimeSeries->Returning values");
|
|
timeLabels = new String[times.length];
|
|
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.ROOT);
|
|
for (int i = 0; i < times.length; i++) {
|
|
timeLabels[i] = sdf.format(times[i]);
|
|
}
|
|
|
|
}
|
|
|
|
public void normalize() throws Exception {
|
|
double max = Operations.getMax(values);
|
|
for (int i = 0; i < values.length; i++) {
|
|
values[i] = values[i] / max;
|
|
}
|
|
}
|
|
|
|
public String getTimepattern() {
|
|
return timepattern;
|
|
}
|
|
|
|
public void setTimepattern(String timepattern) {
|
|
this.timepattern = timepattern;
|
|
}
|
|
}
|