Skip to content

Commit 0df2bb9

Browse files
committed
feat: draw detector QA cut lines for specific run ranges
1 parent 4e2784d commit 0df2bb9

File tree

5 files changed

+103
-46
lines changed

5 files changed

+103
-46
lines changed

TEST.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
# test this PR
3+
run-groovy $TIMELINE_GROOVY_OPTS qa-detectors/util/applyBounds.groovy ~/v/test-rgb-timeline/v29.43_org outfiles/test_rgb_qacuts |& tee outz
4+
bin/deploy-timelines.sh -i outfiles/test_rgb_qacuts -d rgb-ltcc-test -t dilks

qa-detectors/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ The specifications are specified by text files in [the `cuts` directory](cuts).
1212
- lower bound of QA cut
1313
- upper bound of QA cut
1414
- units
15-
- (optional) additional specifier(s), _e.g._, specific sectors
15+
- (optional) additional specifier(s), with the syntax `key:value`
16+
- `spec` key: apply the cut to a specific timeline _e.g._, sector or layer
17+
- `color` key: customize the cut line color
18+
- `run_range` key: apply to a specific run range, _e.g.,_, `run_range:5000:6000` will apply to runs $\in[5000,6000]$
1619
- comments can be added using the symbol `#`, which is useful for commenting out timelines, especially when debugging a particular timeline
1720
- other files in `cuts/` may override the default file
21+
- **this is a deprecated feature**; it is preferred to use `run_range` keywords (see above)
1822
- overrides are applied by comparing the input timeline path to a regular expression
1923
- see [`util/applyBounds.groovy`](util/applyBounds.groovy) for the mapping of regular expressions to overriding cuts file
2024
- for example, paths which match the regular expression `/rga.*fa18/` could use the file `cuts/cuts_rga_fa18.txt`

qa-detectors/cuts/cuts.txt

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
rf rftime_electron_FD_mean -0.010 0.010 ns
22
rf rftime_electron_FD_sigma 0 0.070 ns
33

4-
ltcc ltcc_elec_nphe_sec 11 14 counts sec3
5-
ltcc ltcc_elec_nphe_sec 11 14 counts sec5
4+
ltcc ltcc_elec_nphe_sec 7 9 counts spec:sec3 color:red run_range:5032:5666 # RGA fa18
5+
ltcc ltcc_elec_nphe_sec 4 6 counts spec:sec5 color:blue run_range:5032:5666 # RGA fa18
6+
# ltcc ltcc_elec_nphe_sec 10 16 counts spec:sec3 color:red run_range:11093:11283 # RGB fa19 outbending
7+
# ltcc ltcc_elec_nphe_sec 10 16 counts spec:sec5 color:blue run_range:11093:11283 # RGB fa19 outbending
8+
# ltcc ltcc_elec_nphe_sec 11 17 counts spec:sec3 color:red run_range:11284:11571 # RGB fa19 and wi20 inbending
9+
# ltcc ltcc_elec_nphe_sec 11 17 counts spec:sec5 color:blue run_range:11284:11571 # RGB fa19 and wi20 inbending
10+
ltcc ltcc_elec_nphe_sec 11 14 counts spec:sec3 color:red # all other runs
11+
ltcc ltcc_elec_nphe_sec 11 14 counts spec:sec5 color:blue # all other runs
12+
13+
# TEST
14+
ltcc ltcc_elec_nphe_sec 11 11.4 counts spec:sec3 color:red run_range:11093:11283 # RGB fa19 outbending
15+
ltcc ltcc_elec_nphe_sec 13 15 counts spec:sec5 color:blue run_range:11093:11283 # RGB fa19 outbending
16+
ltcc ltcc_elec_nphe_sec 13.5 13.8 counts spec:sec3 color:red run_range:11284:11571 # RGB fa19 and wi20 inbending
17+
ltcc ltcc_elec_nphe_sec 15 16 counts spec:sec5 color:blue run_range:11284:11571 # RGB fa19 and wi20 inbending
618

719
htcc htcc_nphe_sec 12.5 14.5 counts
820
htcc htcc_vtimediff_sector_mean -1 1 ns
@@ -20,12 +32,12 @@ ftof ftof_time_p2_sigma 0 0.350 ns
2032

2133
ft ftc_pi0_mass_mean 134 136 MeV
2234
ft ftc_pi0_mass_sigma 0 5 MeV
23-
ft fth_MIPS_energy 0.9 1.9 MeV layer1
24-
ft fth_MIPS_energy 2.3 3.3 MeV layer2
25-
ft fth_MIPS_time_mean -0.5 0.5 ns layer1
26-
ft fth_MIPS_time_mean -0.5 0.5 ns layer2
27-
ft fth_MIPS_time_sigma 0 1.4 ns layer1
28-
ft fth_MIPS_time_sigma 0 1.2 ns layer2
35+
ft fth_MIPS_energy 0.9 1.9 MeV spec:layer1 color:red
36+
ft fth_MIPS_energy 2.3 3.3 MeV spec:layer2 color:blue
37+
ft fth_MIPS_time_mean -0.5 0.5 ns spec:layer1
38+
ft fth_MIPS_time_mean -0.5 0.5 ns spec:layer2
39+
ft fth_MIPS_time_sigma 0 1.4 ns spec:layer1 color:red
40+
ft fth_MIPS_time_sigma 0 1.2 ns spec:layer2 color:blue
2941

3042
ec ec_Sampling 0.23 0.26 unitless
3143
ec ec_gg_m_mean 0.129 0.133 GeV
@@ -48,11 +60,11 @@ cnd cnd_time_neg_vtP_sigma 0 0.300 ns
4860
cnd cnd_zdiff_mean -0.4 0.4 cm
4961
cnd cnd_zdiff_sigma 0 4 cm
5062

51-
dc dc_residuals_sec_sl_mean -0.010 0.010 cm R1
52-
dc dc_residuals_sec_sl_mean -0.010 0.010 cm R2
53-
dc dc_residuals_sec_sl_mean -0.010 0.010 cm R3
54-
dc dc_residuals_sec_sl_sigma 0 0.0400 cm R1
55-
dc dc_residuals_sec_sl_sigma 0 0.0400 cm R2
56-
dc dc_residuals_sec_sl_sigma 0 0.0400 cm R3
63+
dc dc_residuals_sec_sl_mean -0.010 0.010 cm spec:R1
64+
dc dc_residuals_sec_sl_mean -0.010 0.010 cm spec:R2
65+
dc dc_residuals_sec_sl_mean -0.010 0.010 cm spec:R3
66+
dc dc_residuals_sec_sl_sigma 0 0.0400 cm spec:R1
67+
dc dc_residuals_sec_sl_sigma 0 0.0400 cm spec:R2
68+
dc dc_residuals_sec_sl_sigma 0 0.0400 cm spec:R3
5769

5870
rich rich_time_fwhm_max 0 1 ns

qa-detectors/cuts/cuts_rga_fa18.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

qa-detectors/util/applyBounds.groovy

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ Tools T = new Tools()
1616
*/
1717
def cutsFileList = [
1818
[ /./, "cuts.txt"], // default file
19-
[ /rga.*fa18/, "cuts_rga_fa18.txt"], // RGA Fall 2018
20-
[ /rgc/, "cuts_rgc_su22.txt"], // RGC
19+
// [ /rga.*fa18/, "cuts_rga_fa18.txt"], // RGA Fall 2018 // DEPRECATED, replaced with run_range feature
2120
]
2221
/////////////////////////////////////////////////////
2322

@@ -80,9 +79,29 @@ cutsFileList.each { re, cutsFile ->
8079
def ubound = tok[3].toDouble()
8180
def units = tok[4]
8281
cutPath = [det, timeline]
83-
spec = tok.size()>5 ? tok[5] : ''
84-
if(spec!='')
85-
cutPath.add(spec)
82+
spec = ''
83+
cutBound = [
84+
"runRange": [0,0],
85+
"bounds": [lbound, ubound],
86+
"used": false,
87+
"color": "black",
88+
]
89+
if(tok.size()>5) {
90+
(5..<tok.size()).each { tokId ->
91+
def optName = tok[tokId].tokenize(':')[0]
92+
def optVals = tok[tokId].tokenize(':')[1..-1]
93+
if(optName=="spec") {
94+
spec = optVals[0]
95+
cutPath.add(spec)
96+
} else if(optName=="run_range") {
97+
cutBound.runRange = optVals.collect{it.toInteger()}
98+
} else if(optName=="color") {
99+
cutBound.color = optVals[0]
100+
} else {
101+
throw new Exception("unknown custom option '$optName'")
102+
}
103+
}
104+
}
86105

87106
// add cuts to graph
88107
def addCut = { graphN ->
@@ -95,8 +114,7 @@ cutsFileList.each { re, cutsFile ->
95114
T.getLeaf(tr, nodePath).clear()
96115
clearedLeaves.add(nodePath)
97116
}
98-
T.getLeaf(tr, nodePath).add(lbound)
99-
T.getLeaf(tr, nodePath).add(ubound)
117+
T.getLeaf(tr, nodePath).add(cutBound)
100118
}
101119
}
102120

@@ -156,16 +174,19 @@ cutsFileList.each { re, cutsFile ->
156174

157175
println "=== TIMELINES ========================="
158176
println T.pPrint(B)
159-
println "======================================="
177+
println "=== CUT LINES ========================="
160178
println T.pPrint(L)
161179
println "======================================="
162180

163181

164182
// closure for creating lines for the front end graphs
165183
// - lineTitle* must be set before calling this
166184
def lineTitle, lineTitleX, lineTitleY
167-
def buildLine = { v,color ->
168-
def graphLine = new GraphErrors(['plotLine','horizontal',v,color].join(':'))
185+
def buildLine = { v,color,xRange ->
186+
lineName = ['plotLine', 'horizontal', v, color]
187+
if(xRange!=[0,0]) lineName += xRange
188+
println " DRAW LINE: $lineName"
189+
def graphLine = new GraphErrors(lineName.join(':'))
169190
graphLine.setTitle(lineTitle)
170191
graphLine.setTitleX(lineTitleX)
171192
graphLine.setTitleY(lineTitleY)
@@ -187,15 +208,16 @@ T.exeLeaves(B,{
187208
// setup
188209
def graphPath = T.leafPath
189210
def fileN = indir+'/'+graphPath[0,-2].join('/') + ".hipo"
190-
def bounds = T.leaf
211+
def boundMaps = T.leaf
191212

192213
// read input timeline; do nothing if input timeline file
193214
// does not exist
194215
def graphN = graphPath[-1]
195-
T.printStatus("open file=\"$fileN\" graph=\"$graphN\"")
216+
T.printStatus("check for file=\"$fileN\" graph=\"$graphN\"")
196217
def inTdir = new TDirectory()
197218
inTdirFile = new File(fileN)
198219
if(inTdirFile.exists()) {
220+
T.printStatus("file exists; reading")
199221
inTdir.readFile(fileN)
200222
gr = inTdir.getObject("/timelines/${graphN}")
201223

@@ -213,21 +235,43 @@ T.exeLeaves(B,{
213235
// loop over runs
214236
gr.getDataSize(0).times { i ->
215237

216-
// check QA bounds
238+
// read timeline point
217239
def run = gr.getDataX(i)
218240
def val = gr.getDataY(i)
219-
def inbound = val>=bounds[0] && val<=bounds[1]
241+
242+
// first, check if any specific run ranges contain this run
243+
def boundMap = boundMaps.find{ run>=it.runRange[0] && run<=it.runRange[1] }
244+
// otherwise, use the default values (runRange == [0,0])
245+
if(boundMap==null) {
246+
boundMap = boundMaps.find{ it.runRange==[0,0] }
247+
}
248+
249+
// get the QA bounds
250+
def valBounds = []
251+
if(boundMap!=null) {
252+
valBounds = boundMap.bounds
253+
boundMap.used = true
254+
} else {
255+
throw new Exception("cannot find boundMap for $graphPath")
256+
}
257+
258+
// check QA bounds
259+
def inbound = val>=valBounds[0] && val<=valBounds[1]
220260
if(!inbound) {
221261
//T.printStatus("OB "+graphPath+" $run $val")
222262
T.getLeaf(TL,graphPath).addPoint(run,val,0,0)
223263
}
224264

225265
}
226266
}
267+
else {
268+
T.printStatus("file does not exist; skipping")
269+
}
227270
})
228271

229272

230273
// write output timelines
274+
T.printStatus("write output timelines")
231275
TL.each{ det, detTr -> // loop through detector directories
232276
detTr.each{ hipoFile, graphTr -> // loop through timeline hipo files
233277

@@ -265,26 +309,21 @@ TL.each{ det, detTr -> // loop through detector directories
265309

266310
// add cut lines
267311
outTdir.cd("/timelines")
268-
T.getLeaf(L,[det,hipoFile]).eachWithIndex{ num,idx ->
269-
println "LINE: $det $hipoFile $num"
270-
def lineColor = 'black'
271-
if(hipoFile=="ltcc_elec_nphe_sec") {
272-
def lineColors = ['red','red','blue','blue']
273-
lineColor = lineColors[idx]
274-
}
275-
else if(hipoFile=="fth_MIPS_energy") {
276-
def lineColors = ['red','red','blue','blue']
277-
lineColor = lineColors[idx]
278-
}
279-
else if(hipoFile=="fth_MIPS_time_sigma") {
280-
def lineColors = ['black','red','blue']
281-
lineColor = lineColors[idx]
312+
T.getLeaf(L,[det,hipoFile]).each{ boundMap ->
313+
println "CUT: $det $hipoFile $boundMap"
314+
if(boundMap.used==true) {
315+
boundMap.bounds.each{ num ->
316+
outTdir.addDataSet(buildLine(num, boundMap.color, boundMap.runRange))
317+
}
318+
} else {
319+
println " NOT USED: do not draw line"
282320
}
283-
outTdir.addDataSet(buildLine(num,lineColor))
284321
}
285322

286323
// create output hipo file
287324
def outHipoDir = "${outdir}/${det}"
325+
def outHipoDirHandle = new File(outHipoDir)
326+
if(!outHipoDirHandle.exists()) outHipoDirHandle.mkdirs()
288327
def outHipoN = "${outHipoDir}/${hipoFile}_QA.hipo"
289328
File outHipoFile = new File(outHipoN)
290329
if(outHipoFile.exists()) outHipoFile.delete()

0 commit comments

Comments
 (0)