This repository has been archived by the owner on Feb 27, 2021. It is now read-only.
/
Filter.java
124 lines (113 loc) · 4.75 KB
/
Filter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package endafarrell.orla.service;
import endafarrell.orla.service.data.Event;
import endafarrell.orla.service.data.Unit;
import org.apache.commons.math.stat.descriptive.rank.Percentile;
import org.joda.time.DateTime;
import org.joda.time.ReadablePeriod;
import java.util.*;
public final class Filter {
public static List<Event> last(final List<Event> events, final ReadablePeriod period, boolean includePreceding) {
if (events == null) return null;
if (events.size() == 0) return null;
Collections.sort(events);
ArrayList<Event> last = new ArrayList<Event>(events.size());
DateTime end = new DateTime(events.get(events.size() - 1).getStartTime());
DateTime start = end.minus(period);
Event preceding = null;
for (Event e : events) {
if (e.getStartTime().isAfter(start)) {
last.add(e);
} else {
preceding = e;
}
}
if (preceding != null && includePreceding) {
last.add(0, preceding);
}
last.trimToSize();
return last;
}
public static List<Event> subList(List<Event> events, DateTime from, DateTime to, boolean includePreceding) {
String today = OrlaDateTimeFormat.PRETTY_yyyyMMdd.print(DateTime.now());
if (events == null) return null;
if (events.size() == 0) return null;
Collections.sort(events);
ArrayList<Event> subList = new ArrayList<Event>(events.size());
DateTime end = to.plusDays(1);
Event preceding = null;
for (Event e : events) {
if (e.getStartTime().isAfter(from)) {
if (e.getStartTime().isBefore(end)) {
subList.add(e);
}
} else {
preceding = e;
}
}
if (preceding != null && includePreceding) {
subList.add(0, preceding);
}
subList.trimToSize();
return subList;
}
public static List<Event> percentiles(Collection<Event> events, int lower, int higher) {
// Get the raw values
List<Double> values = new ArrayList<Double>(events.size());
for (Event e : events) {
values.add(e.getValue().doubleValue());
}
// Get the lower-th percentile
Percentile percentile = new Percentile(lower);
percentile.setData(Convert.todoubleArray(values));
double lowerPercentile = percentile.evaluate();
// Get the higher-th percentile
percentile = new Percentile(higher);
percentile.setData(Convert.todoubleArray(values));
double higherPercentile = percentile.evaluate();
// Now return the glucose readings between these percentiles
ArrayList<Event> percentiles = new ArrayList<Event>(events.size());
for (Event e : events) {
if (e.getValue().doubleValue() > lowerPercentile && e.getValue().doubleValue() < higherPercentile) {
percentiles.add(e);
}
}
percentiles.trimToSize();
return percentiles;
}
public static Map<Integer, Double> percentiles(List<Double> values, Set<Integer> percentiles) {
double[] vals = Convert.todoubleArray(values);
Map<Integer, Double> ps = new HashMap<Integer, Double>(percentiles.size());
Percentile percentile = new Percentile();
percentile.setData(vals);
for (Integer percentileLevel : percentiles) {
ps.put(percentileLevel, percentile.evaluate(percentileLevel));
}
return ps;
}
public static List<Event> only(Collection<Event> events, Unit unit) {
ArrayList<Event> eventList = new ArrayList<Event>(events.size());
for (Event event : events) {
if (event.getUnit() == unit) {
eventList.add(event);
}
}
eventList.trimToSize();
return eventList;
}
@SuppressWarnings({"unchecked"})
public static <T extends Event> ArrayList<T> only(Collection<Event> events, Class<T> clazz) {
ArrayList<T> eventList = new ArrayList<T>(events.size());
for (Event event : events) {
// There is a "noinspection unchecked" here which is used to suppress (in this IDE anyway)
// compiler warnings - this time about Unchecked casts. Here you can see that we are checking
// the canonical name of T which extends BaseEvent and of course that the Class<T> class is a
// subclass of BaseEvent in the first place. So: we can suppress the warning as it has been
// checked.
if (event.getClass().getCanonicalName().equals(clazz.getCanonicalName())) {
eventList.add((T) event);
}
}
eventList.trimToSize();
return eventList;
}
}