package org.gcube.contentmanagement.graphtools.data.conversions; import java.util.ArrayList; import java.util.List; import org.gcube.contentmanagement.graphtools.abstracts.SamplesTable; import org.gcube.contentmanagement.graphtools.utils.MathFunctions; import org.gcube.portlets.user.timeseries.charts.support.types.GraphData; import org.gcube.portlets.user.timeseries.charts.support.types.GraphGroups; import org.gcube.portlets.user.timeseries.charts.support.types.Point; import org.gcube.portlets.user.timeseries.charts.support.types.ValueEntry; /* * Performs Operations on Lists of Points * Helps in transforming a SamplesTable to a GraphData */ public class GraphConverter2D { private static Point searchPoint(Point x, List> samples) { Point novelpoint = null; for (Point point : samples) { // if (point.getValue().equals(x.getValue())) { if (point.getLabel().equals(x.getLabel())) { novelpoint = point; break; } } return novelpoint; } // optimizes the dimensions of the sample table, ordering the x and y entries @SuppressWarnings({ "rawtypes", "unchecked" }) public static List> reduceDimension(List> samples) { ArrayList> novelSamples = new ArrayList>(); int novelCounter = 0; try { for (Point pointsample : samples) { // search the current point in the new built list Point novelPoint = searchPoint(pointsample, novelSamples); int index = 0; ValueEntry pointValue = null; // if it is not the first insertion then find the optimal index for the y value of the current point // that is: find the column to insert the value if (novelCounter > 0) { // find column index pointValue = pointsample.getEntries().get(0); List referencevalues = novelSamples.get(0).getEntries(); int i = 0; index = referencevalues.size(); // get the best column for (Object val : referencevalues) { if (((ValueEntry) val).getLabel().equals(pointValue.getLabel())) { index = i; break; } i++; } } // if the point has not been inserted yet (there isn't another point with the same label previously inserted) if (novelPoint == null) { // generate a new y ValueEntry ve = new ValueEntry(pointsample.getEntries().get(0).getLabel(), pointsample.getEntries().get(0).getValue()); // generate a new (x,y) novelPoint = new Point(pointsample.getLabel(), pointsample.getValue()); // the number of columns to fill with 0s corresponds to all the columns int numofcolumns = index; if (novelCounter > 0) numofcolumns = novelSamples.get(0).getEntries().size(); // fill all the columns with 0s for (int j = 0; j < numofcolumns; j++) { novelPoint.getEntries().add(j, new ValueEntry(novelSamples.get(0).getEntries().get(j).getLabel(), Double.valueOf(0))); } // add the y at the right column according to the calculated index if (index >= novelPoint.getEntries().size()) novelPoint.getEntries().add(index, ve); else novelPoint.getEntries().set(index, ve); // add the new point in the list novelSamples.add(novelPoint); novelCounter++; } else { // if we found a previous element update it if (index >= novelPoint.getEntries().size()) // if the index is higher than the y size, add the column at the end novelPoint.getEntries().add(index, pointValue); else // otherwise substitute the current index value novelPoint.getEntries().set(index, pointValue); } } } catch (Exception e) { e.printStackTrace(); } return novelSamples; } // converts a bidimensional sampleTable to a list of bidimensional Points @SuppressWarnings("unchecked") public static List> convert(SamplesTable sampleTable) { ArrayList> pointsList = new ArrayList>(); try { // every point has a label and a list of associated y points int rows = sampleTable.getNumOfDataRows(); for (int rowIndex = 0; rowIndex < rows; rowIndex++) { // take the label: it is separated in two parts separated by ';' String label = sampleTable.getClassification(rowIndex); int commaIndex = label.indexOf(";"); String xlabel = label; String ylabel = ""; if (commaIndex > 0) { xlabel = label.substring(0, commaIndex); ylabel = label.substring(commaIndex + 1); } double x = sampleTable.getValue(rowIndex, 0); double y = sampleTable.getValue(rowIndex, 1); ValueEntry ve = new ValueEntry(ylabel, y); Point p = new Point(xlabel, x, ve); pointsList.add(p); } } catch (Exception e) { e.printStackTrace(); } return pointsList; } @SuppressWarnings("rawtypes") public static List> deleteHeaders(List> samples) { int size = samples.size(); for (int i = 0; i < size; i++) { Point p = samples.get(i); if (p.getLabel().equals("header")) { samples.remove(i); size--; i--; } } return samples; } // performs a complete transformation public static List> transformTable(SamplesTable sampleTable) { List> singlegraph = convert(sampleTable); singlegraph = reduceDimension(singlegraph); singlegraph = deleteHeaders(singlegraph); return singlegraph; } @SuppressWarnings({ "rawtypes", "unchecked" }) public static List> reorder(List> samples) { List> orderedsamples = new ArrayList>(); // check and reorder points for (Point p : samples) { int index = 0; for (Point ordP : orderedsamples) { if (ordP.getValue().doubleValue() > p.getValue().doubleValue()) { break; } index++; } orderedsamples.add(index, p); } // re-enumerate x dimension int i = 0; for (Point ordP : orderedsamples) { try { ordP.setValue(Double.valueOf(i)); } catch (Exception e) { } i++; } return orderedsamples; } @SuppressWarnings({ "rawtypes", "unchecked" }) public static List> filterXRange(List> samples, String minX, String maxX) { List> filteredsamples = new ArrayList>(); boolean copy = false; for (Point p : samples) { if (p.getLabel().equals(minX)) { copy = true; } if (copy) { filteredsamples.add(p); } if (p.getLabel().equals(maxX)) { break; } } return filteredsamples; } public static final String SPIKE = "STATIONARY"; public static void anotateStationaryPoints(GraphGroups gg) { for (String key : gg.getGraphs().keySet()) { GraphData graph = gg.getGraphs().get(key); // for each series int trends = graph.getData().size(); int yvalues = graph.getData().get(0).getEntries().size(); // System.out.println("yvalues "+yvalues); // System.out.println("trends "+trends); for (int i = 0; i < trends; i++) { double[] points = MathFunctions.points2Double(graph.getData(), i, yvalues); double[] derivative = MathFunctions.derivative(points); boolean[] spikes = MathFunctions.findSpikes(derivative, threshold); for (int k = 0; k < yvalues; k++) { if (spikes[k]) { String label = graph.getData().get(i).getEntries().get(k).getLabel(); String newLabel = label + ";" + SPIKE; graph.getData().get(i).getEntries().get(k).setLabel(newLabel); } } } } // return gg; } private static double threshold = 0.001; public static void anotateStationaryPoints(GraphGroups gg, List lables) { for (String key : gg.getGraphs().keySet()) { GraphData graph = gg.getGraphs().get(key); // for each series int trends = graph.getData().size(); int yvalues = graph.getData().get(0).getEntries().size(); int spikeslablessize = lables.size(); // System.out.println("yvalues "+yvalues); // System.out.println("trends "+trends); for (int i = 0; i < trends; i++) { double[] points = MathFunctions.points2Double(graph.getData(), i, yvalues); double[] derivative = MathFunctions.derivative(points); boolean[] spikes = MathFunctions.findSpikes(derivative, threshold); int spikecounter = 0; for (int k = 0; k < yvalues; k++) { if (spikes[k]) { String label = graph.getData().get(i).getEntries().get(k).getLabel(); String spikelable = SPIKE; if (spikecounter < spikeslablessize) spikelable = lables.get(spikecounter); String newLabel = label + ";" + spikelable; graph.getData().get(i).getEntries().get(k).setLabel(newLabel); spikecounter++; } } } } // return gg; } public static void anotatePoints(GraphGroups gg, List pointsIndexes, List lables) { for (String key : gg.getGraphs().keySet()) { GraphData graph = gg.getGraphs().get(key); // for each series int trends = graph.getData().size(); for (int i = 0; i < trends; i++) { int progressive = 0; for (Integer index : pointsIndexes) { String label = graph.getData().get(i).getEntries().get(index.intValue()).getLabel(); String addinglabel = lables.get(progressive); String newLabel = label; if (addinglabel != null) newLabel += ";" + addinglabel; graph.getData().get(i).getEntries().get(index.intValue()).setLabel(newLabel); progressive++; } } } // return gg; } // works a single trend in the graph public static List getStationaryPoints(GraphData graph) throws Exception { List st = new ArrayList(); Point p = graph.getData().get(0); st.add(new Point(p.getLabel(), p.getValue())); int yvalues = graph.getData().get(0).getEntries().size(); double[] points = MathFunctions.points2Double(graph.getData(), 0, yvalues); double[] derivative = MathFunctions.derivative(points); boolean[] spikes = MathFunctions.findSpikes(derivative, threshold); for (int k = 0; k < yvalues; k++) { if (spikes[k]) { String label = graph.getData().get(0).getEntries().get(k).getLabel(); Double val = points[k]; ValueEntry v = new ValueEntry(label, val); st.get(0).addEntry(v); } } return st; } // works a single trend in the graph public static List getLablesFromPoints(Point points) throws Exception { List lables = new ArrayList(); for (Object v : points.getEntries()) { lables.add(((ValueEntry) v).getLabel()); } return lables; } // works the first trend in the graph: takes a list of points according to a list of indexes public static List getLabelsfromIndexes(List> points, List indexes) throws Exception { List lables = new ArrayList(); int size = indexes.size(); for (Integer index : indexes) { Object v = points.get(0).getEntries().get(index); lables.add(((ValueEntry) v).getLabel()); } return lables; } // works the first trend in the graph: takes a list of points according to a list of indexes public static void sampleAnotationBySameFollower(List> samples) throws Exception { String previousLabel = null; // check and reorder points for (Point p : samples) { for (Object v : p.getEntries()) { String label = ((ValueEntry) v).getLabel(); int indexcomma = label.indexOf(";"); if (indexcomma >= 0) { String labelcountry = label.substring(indexcomma + 1); // AnalysisLogger.getLogger().debug("sampleAnotationBySameFollower-> comparing "+labelcountry+" vs "+previousLabel+" ORIGINAL "+label); if ((previousLabel != null) && (labelcountry.equals(previousLabel))) { label = label.substring(0, indexcomma); // AnalysisLogger.getLogger().debug("sampleAnotationBySameFollower-> ELIMINATING LABEL!!!"); ((ValueEntry) v).setLabel(label); } else previousLabel = labelcountry; } } } } // works the first trend in the graph: takes a list of points according to a list of indexes public static void sampleAnotationByRange(List> samples, int range) throws Exception { if (range > 0) { // check and reorder points for (Point p : samples) { int partialCounter = 0; for (Object v : p.getEntries()) { String label = ((ValueEntry) v).getLabel(); int indexcomma = label.indexOf(";"); if (indexcomma >= 0) { //if not enough time has passed delete the label otherwise reset counter if (partialCounter <= range) { String labelcountry = label.substring(indexcomma + 1); // AnalysisLogger.getLogger().debug("sampleAnotationByRange-> partial counter "+partialCounter+ " label "+ label); label = label.substring(0, indexcomma); // AnalysisLogger.getLogger().debug("sampleAnotationByRange-> ELIMINATING LABEL!!!"); ((ValueEntry) v).setLabel(label); } else{ partialCounter = 0; } } partialCounter++; } } } } }