You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: detectors/src/main/java/org/jlab/clas/timeline/util/HistoUtil.groovy
+33-12Lines changed: 33 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -65,25 +65,46 @@ class HistoUtil {
65
65
if( !(hist.getEntries() >0) ||!(hist.integral() >0) ) { // `.getEntries()` can be nonzero for empty histograms, so be sure to check the integral too
66
66
return defIfEmpty
67
67
}
68
-
def hist_list = []
69
-
hist.getAxis().getNBins().times { bin->
70
-
def counts = hist.getBinContent(bin).toInteger() // FIXME: assumes the histogram is unweighted
68
+
def bins_list = []
69
+
def cum_counts_list = []
70
+
int sum =0
71
+
int nbins = hist.getAxis().getNBins()
72
+
nbins.times { bin->
73
+
int counts = hist.getBinContent(bin).toInteger() // FIXME: assumes the histogram is unweighted
71
74
def value = hist.getAxis().getBinCenter(bin)
72
-
counts.times { hist_list += value }
75
+
bins_list += value
76
+
sum += counts
77
+
cum_counts_list += sum
73
78
}
74
-
def listMedian = { d->
75
-
if(d.size()==0) {
79
+
def listMedian = { _sum, bins, cum_counts->
80
+
if(bins.size()==0|| cum_counts.size()==0) {
76
81
// this list may end up being empty if there are _few_ entries in the histogram, since this method
77
82
// is called to get the quartiles; in this case, just return `defIfEmpty`
78
83
return defIfEmpty
79
84
}
80
-
d.sort()
81
-
def m = d.size().intdiv(2)
82
-
d.size() %2? d[m] : (d[m-1]+d[m]) /2
85
+
// Compute the median using the fact that you have histogrammed data to do this slightly more efficiently
86
+
int mid_count = _sum.intdiv(2)
87
+
boolean is_even = (_sum%2==0)
88
+
if (is_even) mid_count +=1//NOTE: If you have an even length list there is no middle element and you will need to average the middle+1 and middle-1 elements.
89
+
for (int i=0; i<cum_counts.size(); i++) {
90
+
if (cum_counts[i]+1==mid_count && is_even) {
91
+
return [(bins[i]+bins[i+1])/2, i+1, mid_count]
92
+
}
93
+
if (cum_counts[i]>mid_count) {
94
+
return [bins[i], i, mid_count]
95
+
}
96
+
}
97
+
return [bins[bins.size()-1], bins.size()-1, mid_count] //NOTE: SHOULD NEVER REACH THIS POINT
0 commit comments