Skip to content

Commit 5106d24

Browse files
authored
Merge branch 'main' into issue_156
2 parents 907bbb3 + 65f97fa commit 5106d24

4 files changed

Lines changed: 62 additions & 55 deletions

File tree

bin/environ.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ groovy_classpath=(
4242
timeline_java_opts=(
4343
-DCLAS12DIR=$COATJAVA/
4444
-Djava.util.logging.config.file=$COATJAVA/etc/logging/$log_config.properties
45-
-Xmx1024m
45+
-Xmx1536m
4646
-XX:+UseSerialGC
4747
)
4848
timeline_groovy_opts=(

detectors/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
<dependency>
5252
<groupId>org.apache.groovy</groupId>
5353
<artifactId>groovy-all</artifactId>
54-
<version>4.0.25</version>
54+
<version>4.0.26</version>
5555
<type>pom</type>
5656
<exclusions>
5757
<exclusion>
@@ -64,7 +64,7 @@
6464
<dependency>
6565
<groupId>org.apache.groovy</groupId>
6666
<artifactId>groovy-dateutil</artifactId>
67-
<version>4.0.25</version>
67+
<version>4.0.26</version>
6868
</dependency>
6969
<!-- https://mvnrepository.com/artifact/org.codehaus.gpars/gpars -->
7070
<dependency>

detectors/src/main/java/org/jlab/clas/timeline/util/HistoUtil.groovy

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,25 +65,46 @@ class HistoUtil {
6565
if( !(hist.getEntries() > 0) || !(hist.integral() > 0) ) { // `.getEntries()` can be nonzero for empty histograms, so be sure to check the integral too
6666
return defIfEmpty
6767
}
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
7174
def value = hist.getAxis().getBinCenter(bin)
72-
counts.times { hist_list += value }
75+
bins_list += value
76+
sum += counts
77+
cum_counts_list += sum
7378
}
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) {
7681
// this list may end up being empty if there are _few_ entries in the histogram, since this method
7782
// is called to get the quartiles; in this case, just return `defIfEmpty`
7883
return defIfEmpty
7984
}
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
8398
}
84-
def mq = listMedian(hist_list)
85-
def lq = listMedian(hist_list.findAll{it<mq})
86-
def uq = listMedian(hist_list.findAll{it>mq})
99+
100+
def mq_list = listMedian(sum,bins_list,cum_counts_list)
101+
int mq_idx = mq_list[1]
102+
int mq_sum = mq_list[2]
103+
def lq_list = listMedian(mq_sum,bins_list.subList(0,mq_idx+1),cum_counts_list.subList(0,mq_idx+1))
104+
def lq = lq_list[0]
105+
def uq_list = listMedian(mq_sum*3,bins_list.subList(mq_idx,nbins),cum_counts_list.subList(mq_idx,nbins))
106+
def uq = uq_list[0]
107+
87108
return uq - lq
88109
}
89110
}

qa-physics/monitorPlot.groovy

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,19 @@ def buildMonAveGr = { tObj ->
143143
return gr
144144
}
145145

146-
// build monitor 'average X' distribution
147-
def buildMonAveDist = { tObj,nb,lb,ub ->
146+
// build monitor 'runSum' distribution (sum of bins' distribtions for a run)
147+
def buildMonRunSumDist = { tObj ->
148148
def histN = objToMonName(tObj.getName())
149149
def histT = objToMonTitle(tObj.getTitle())
150-
histN = histN + "_aveDist"
151-
histT = "average " + histT
150+
histN = histN + "_runSumDist"
152151
histT = histT.replaceAll(/$/,' distribution')
153152
histT = appendLegend(histT)
154-
def hist = new H1F(histN,histT,nb,lb,ub)
153+
def hist = new H1F(
154+
histN,
155+
histT,
156+
tObj.getAxis().getNBins(),
157+
tObj.getAxis().min(),
158+
tObj.getAxis().max())
155159
if(histN.contains("_hm_")) { hist.setLineColor(2); }
156160
return hist
157161
}
@@ -206,8 +210,6 @@ def objList
206210
def part
207211
def hel
208212
def varStr
209-
def varNB
210-
def varLB,varUB
211213
def runnum
212214
def timeBinNum
213215
def obj
@@ -245,8 +247,8 @@ inList.each { inFile ->
245247
T.addLeaf(monTree,[runnum,'helic','sinPhi',part,hel,'aveGr'],{
246248
buildMonAveGr(obj)
247249
})
248-
T.addLeaf(monTree,[runnum,'helic','sinPhi',part,hel,'aveDist'],{
249-
buildMonAveDist(obj,100,-0.25,0.25)
250+
T.addLeaf(monTree,[runnum,'helic','sinPhi',part,hel,'runSumDist'],{
251+
buildMonRunSumDist(obj)
250252
})
251253

252254
// instantiate sinPhi dists binned for an asymmetry, denoted "asymGrid" (if not
@@ -267,7 +269,7 @@ inList.each { inFile ->
267269
aveXerr = obj.getRMS() / Math.sqrt(ent)
268270
monTree[runnum]['helic']['sinPhi'][part][hel]['aveGr'].addPoint(
269271
timeBinNum, aveX, 0, aveXerr )
270-
monTree[runnum]['helic']['sinPhi'][part][hel]['aveDist'].fill(aveX)
272+
monTree[runnum]['helic']['sinPhi'][part][hel]['runSumDist'].add(obj)
271273
// add rebinned <sinPhi> distribution to asymGrid
272274
obj.getAxis().getNBins().times { bin ->
273275
def counts = obj.getBinContent(bin)
@@ -292,10 +294,10 @@ inList.each { inFile ->
292294
return g
293295
})
294296
T.addLeaf(monTree,[runnum,'helic','dist','heldef','heldefDist'],{
295-
def h = buildMonAveDist(obj,50,0,1)
296-
def hN = h.getName().replaceAll(/_aveDist$/,'_heldefDist')
297-
h.setName(hN)
298-
h.setTitle('average defined helicity fraction distribution')
297+
def histN = objToMonName(obj.getName()) + "_heldefDist"
298+
def histT = appendLegend('average defined helicity fraction distribution')
299+
def h = new H1F(histN, histT, 50, 0, 1)
300+
if(histN.contains("_hm_")) { h.setLineColor(2); }
299301
return h
300302
})
301303
ent = obj.integral()
@@ -324,10 +326,10 @@ inList.each { inFile ->
324326
return g
325327
})
326328
T.addLeaf(monTree,[runnum,'helic','dist','rellum','rellumDist'],{
327-
def h = buildMonAveDist(obj,50,0.9,1.1)
328-
def hN = h.getName().replaceAll(/_aveDist$/,'_rellumDist')
329-
h.setName(hN)
330-
h.setTitle('average n+/n- distribution')
329+
def histN = objToMonName(obj.getName()) + "_rellumDist"
330+
def histT = appendLegend('average n+/n- distribution')
331+
def h = new H1F(histN, histT, 50, 0.9, 1.1)
332+
if(histN.contains("_hm_")) { h.setLineColor(2); }
331333
return h
332334
})
333335
if(obj.integral()>0) {
@@ -379,13 +381,7 @@ inList.each { inFile ->
379381
varStr = tok[1]
380382

381383
T.addLeaf(monTree,[runnum,'DIS',varStr,'aveGr'],{buildMonAveGr(obj)})
382-
T.addLeaf(monTree,[runnum,'DIS',varStr,'aveDist'],{
383-
varNB = 100
384-
if(varStr=="Q2") { varLB=0; varUB=12; }
385-
else if(varStr=="W") { varLB=0; varUB=6; }
386-
else { varLB=0; varUB=1; }
387-
buildMonAveDist(obj,varNB,varLB,varUB)
388-
})
384+
T.addLeaf(monTree,[runnum,'DIS',varStr,'runSumDist'],{buildMonRunSumDist(obj)})
389385

390386
// add <varStr> point to the monitors
391387
ent = obj.integral()
@@ -394,7 +390,7 @@ inList.each { inFile ->
394390
aveXerr = obj.getRMS() / Math.sqrt(ent)
395391
monTree[runnum]['DIS'][varStr]['aveGr'].addPoint(
396392
timeBinNum, aveX, 0, aveXerr )
397-
monTree[runnum]['DIS'][varStr]['aveDist'].fill(aveX)
393+
monTree[runnum]['DIS'][varStr]['runSumDist'].add(obj)
398394
}
399395
}
400396
}
@@ -405,24 +401,14 @@ inList.each { inFile ->
405401
part = tok[1]
406402
varStr = tok[2]
407403
T.addLeaf(monTree,[runnum,'inclusive',part,varStr,'aveGr'],{buildMonAveGr(obj)})
408-
T.addLeaf(monTree,[runnum,'inclusive',part,varStr,'aveDist'],{
409-
varNB = 100
410-
varLB = 0
411-
varUB = 0
412-
if(varStr=='p') { varLB=0; varUB=10 }
413-
else if(varStr=='pT') { varLB=0; varUB=4 }
414-
else if(varStr=='z') { varLB=0; varUB=1 }
415-
else if(varStr=='theta') { varLB=0; varUB=Math.toRadians(90.0) }
416-
else if(varStr=='phiH') { varLB=-3.15; varUB=3.15 }
417-
buildMonAveDist(obj,varNB,varLB,varUB)
418-
})
404+
T.addLeaf(monTree,[runnum,'inclusive',part,varStr,'runSumDist'],{buildMonRunSumDist(obj)})
419405
ent = obj.integral()
420406
if(ent>0) {
421407
aveX = obj.getMean()
422408
aveXerr = obj.getRMS() / Math.sqrt(ent)
423409
monTree[runnum]['inclusive'][part][varStr]['aveGr'].addPoint(
424410
timeBinNum, aveX, 0, aveXerr )
425-
monTree[runnum]['inclusive'][part][varStr]['aveDist'].fill(aveX)
411+
monTree[runnum]['inclusive'][part][varStr]['runSumDist'].add(obj)
426412
}
427413
}
428414

@@ -470,7 +456,7 @@ inList.each { inFile ->
470456
// build timelines
471457
//---------------------
472458

473-
// loop through 'aveDist' monitors: for each one, add its mean to the timeline
459+
// loop through monitors: for each one, add its mean to the timeline
474460
def timelineTree = [:]
475461
T.exeLeaves(monTree,{
476462
if(T.key.contains('Dist') || T.key.contains('Graph')) {
@@ -552,7 +538,7 @@ T.exeLeaves(monTree,{
552538
}
553539

554540
// add this run's <X> to the timeline (and stddev to the stddev timelines)
555-
if(T.key=='aveDist') {
541+
if(T.key=='runSumDist') {
556542
aveX = T.leaf.getMean()
557543
stddevX = T.leaf.getRMS()
558544
aveXerr = stddevX / Math.sqrt(T.leaf.integral())

0 commit comments

Comments
 (0)