Skip to content

Commit

Permalink
feat: draw detector QA cut lines for specific run ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
c-dilks committed Dec 5, 2023
1 parent 4e2784d commit 0df2bb9
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 46 deletions.
4 changes: 4 additions & 0 deletions TEST.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
# test this PR
run-groovy $TIMELINE_GROOVY_OPTS qa-detectors/util/applyBounds.groovy ~/v/test-rgb-timeline/v29.43_org outfiles/test_rgb_qacuts |& tee outz
bin/deploy-timelines.sh -i outfiles/test_rgb_qacuts -d rgb-ltcc-test -t dilks
6 changes: 5 additions & 1 deletion qa-detectors/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ The specifications are specified by text files in [the `cuts` directory](cuts).
- lower bound of QA cut
- upper bound of QA cut
- units
- (optional) additional specifier(s), _e.g._, specific sectors
- (optional) additional specifier(s), with the syntax `key:value`
- `spec` key: apply the cut to a specific timeline _e.g._, sector or layer
- `color` key: customize the cut line color
- `run_range` key: apply to a specific run range, _e.g.,_, `run_range:5000:6000` will apply to runs $\in[5000,6000]$
- comments can be added using the symbol `#`, which is useful for commenting out timelines, especially when debugging a particular timeline
- other files in `cuts/` may override the default file
- **this is a deprecated feature**; it is preferred to use `run_range` keywords (see above)
- overrides are applied by comparing the input timeline path to a regular expression
- see [`util/applyBounds.groovy`](util/applyBounds.groovy) for the mapping of regular expressions to overriding cuts file
- for example, paths which match the regular expression `/rga.*fa18/` could use the file `cuts/cuts_rga_fa18.txt`
Expand Down
40 changes: 26 additions & 14 deletions qa-detectors/cuts/cuts.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
rf rftime_electron_FD_mean -0.010 0.010 ns
rf rftime_electron_FD_sigma 0 0.070 ns

ltcc ltcc_elec_nphe_sec 11 14 counts sec3
ltcc ltcc_elec_nphe_sec 11 14 counts sec5
ltcc ltcc_elec_nphe_sec 7 9 counts spec:sec3 color:red run_range:5032:5666 # RGA fa18
ltcc ltcc_elec_nphe_sec 4 6 counts spec:sec5 color:blue run_range:5032:5666 # RGA fa18
# ltcc ltcc_elec_nphe_sec 10 16 counts spec:sec3 color:red run_range:11093:11283 # RGB fa19 outbending
# ltcc ltcc_elec_nphe_sec 10 16 counts spec:sec5 color:blue run_range:11093:11283 # RGB fa19 outbending
# ltcc ltcc_elec_nphe_sec 11 17 counts spec:sec3 color:red run_range:11284:11571 # RGB fa19 and wi20 inbending
# ltcc ltcc_elec_nphe_sec 11 17 counts spec:sec5 color:blue run_range:11284:11571 # RGB fa19 and wi20 inbending
ltcc ltcc_elec_nphe_sec 11 14 counts spec:sec3 color:red # all other runs
ltcc ltcc_elec_nphe_sec 11 14 counts spec:sec5 color:blue # all other runs

# TEST
ltcc ltcc_elec_nphe_sec 11 11.4 counts spec:sec3 color:red run_range:11093:11283 # RGB fa19 outbending
ltcc ltcc_elec_nphe_sec 13 15 counts spec:sec5 color:blue run_range:11093:11283 # RGB fa19 outbending
ltcc ltcc_elec_nphe_sec 13.5 13.8 counts spec:sec3 color:red run_range:11284:11571 # RGB fa19 and wi20 inbending
ltcc ltcc_elec_nphe_sec 15 16 counts spec:sec5 color:blue run_range:11284:11571 # RGB fa19 and wi20 inbending

htcc htcc_nphe_sec 12.5 14.5 counts
htcc htcc_vtimediff_sector_mean -1 1 ns
Expand All @@ -20,12 +32,12 @@ ftof ftof_time_p2_sigma 0 0.350 ns

ft ftc_pi0_mass_mean 134 136 MeV
ft ftc_pi0_mass_sigma 0 5 MeV
ft fth_MIPS_energy 0.9 1.9 MeV layer1
ft fth_MIPS_energy 2.3 3.3 MeV layer2
ft fth_MIPS_time_mean -0.5 0.5 ns layer1
ft fth_MIPS_time_mean -0.5 0.5 ns layer2
ft fth_MIPS_time_sigma 0 1.4 ns layer1
ft fth_MIPS_time_sigma 0 1.2 ns layer2
ft fth_MIPS_energy 0.9 1.9 MeV spec:layer1 color:red
ft fth_MIPS_energy 2.3 3.3 MeV spec:layer2 color:blue
ft fth_MIPS_time_mean -0.5 0.5 ns spec:layer1
ft fth_MIPS_time_mean -0.5 0.5 ns spec:layer2
ft fth_MIPS_time_sigma 0 1.4 ns spec:layer1 color:red
ft fth_MIPS_time_sigma 0 1.2 ns spec:layer2 color:blue

ec ec_Sampling 0.23 0.26 unitless
ec ec_gg_m_mean 0.129 0.133 GeV
Expand All @@ -48,11 +60,11 @@ cnd cnd_time_neg_vtP_sigma 0 0.300 ns
cnd cnd_zdiff_mean -0.4 0.4 cm
cnd cnd_zdiff_sigma 0 4 cm

dc dc_residuals_sec_sl_mean -0.010 0.010 cm R1
dc dc_residuals_sec_sl_mean -0.010 0.010 cm R2
dc dc_residuals_sec_sl_mean -0.010 0.010 cm R3
dc dc_residuals_sec_sl_sigma 0 0.0400 cm R1
dc dc_residuals_sec_sl_sigma 0 0.0400 cm R2
dc dc_residuals_sec_sl_sigma 0 0.0400 cm R3
dc dc_residuals_sec_sl_mean -0.010 0.010 cm spec:R1
dc dc_residuals_sec_sl_mean -0.010 0.010 cm spec:R2
dc dc_residuals_sec_sl_mean -0.010 0.010 cm spec:R3
dc dc_residuals_sec_sl_sigma 0 0.0400 cm spec:R1
dc dc_residuals_sec_sl_sigma 0 0.0400 cm spec:R2
dc dc_residuals_sec_sl_sigma 0 0.0400 cm spec:R3

rich rich_time_fwhm_max 0 1 ns
2 changes: 0 additions & 2 deletions qa-detectors/cuts/cuts_rga_fa18.txt

This file was deleted.

97 changes: 68 additions & 29 deletions qa-detectors/util/applyBounds.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ Tools T = new Tools()
*/
def cutsFileList = [
[ /./, "cuts.txt"], // default file
[ /rga.*fa18/, "cuts_rga_fa18.txt"], // RGA Fall 2018
[ /rgc/, "cuts_rgc_su22.txt"], // RGC
// [ /rga.*fa18/, "cuts_rga_fa18.txt"], // RGA Fall 2018 // DEPRECATED, replaced with run_range feature
]
/////////////////////////////////////////////////////

Expand Down Expand Up @@ -80,9 +79,29 @@ cutsFileList.each { re, cutsFile ->
def ubound = tok[3].toDouble()
def units = tok[4]
cutPath = [det, timeline]
spec = tok.size()>5 ? tok[5] : ''
if(spec!='')
cutPath.add(spec)
spec = ''
cutBound = [
"runRange": [0,0],
"bounds": [lbound, ubound],
"used": false,
"color": "black",
]
if(tok.size()>5) {
(5..<tok.size()).each { tokId ->
def optName = tok[tokId].tokenize(':')[0]
def optVals = tok[tokId].tokenize(':')[1..-1]
if(optName=="spec") {
spec = optVals[0]
cutPath.add(spec)
} else if(optName=="run_range") {
cutBound.runRange = optVals.collect{it.toInteger()}
} else if(optName=="color") {
cutBound.color = optVals[0]
} else {
throw new Exception("unknown custom option '$optName'")
}
}
}

// add cuts to graph
def addCut = { graphN ->
Expand All @@ -95,8 +114,7 @@ cutsFileList.each { re, cutsFile ->
T.getLeaf(tr, nodePath).clear()
clearedLeaves.add(nodePath)
}
T.getLeaf(tr, nodePath).add(lbound)
T.getLeaf(tr, nodePath).add(ubound)
T.getLeaf(tr, nodePath).add(cutBound)
}
}

Expand Down Expand Up @@ -156,16 +174,19 @@ cutsFileList.each { re, cutsFile ->

println "=== TIMELINES ========================="
println T.pPrint(B)
println "======================================="
println "=== CUT LINES ========================="
println T.pPrint(L)
println "======================================="


// closure for creating lines for the front end graphs
// - lineTitle* must be set before calling this
def lineTitle, lineTitleX, lineTitleY
def buildLine = { v,color ->
def graphLine = new GraphErrors(['plotLine','horizontal',v,color].join(':'))
def buildLine = { v,color,xRange ->
lineName = ['plotLine', 'horizontal', v, color]
if(xRange!=[0,0]) lineName += xRange
println " DRAW LINE: $lineName"
def graphLine = new GraphErrors(lineName.join(':'))
graphLine.setTitle(lineTitle)
graphLine.setTitleX(lineTitleX)
graphLine.setTitleY(lineTitleY)
Expand All @@ -187,15 +208,16 @@ T.exeLeaves(B,{
// setup
def graphPath = T.leafPath
def fileN = indir+'/'+graphPath[0,-2].join('/') + ".hipo"
def bounds = T.leaf
def boundMaps = T.leaf

// read input timeline; do nothing if input timeline file
// does not exist
def graphN = graphPath[-1]
T.printStatus("open file=\"$fileN\" graph=\"$graphN\"")
T.printStatus("check for file=\"$fileN\" graph=\"$graphN\"")
def inTdir = new TDirectory()
inTdirFile = new File(fileN)
if(inTdirFile.exists()) {
T.printStatus("file exists; reading")
inTdir.readFile(fileN)
gr = inTdir.getObject("/timelines/${graphN}")

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

// check QA bounds
// read timeline point
def run = gr.getDataX(i)
def val = gr.getDataY(i)
def inbound = val>=bounds[0] && val<=bounds[1]

// first, check if any specific run ranges contain this run
def boundMap = boundMaps.find{ run>=it.runRange[0] && run<=it.runRange[1] }
// otherwise, use the default values (runRange == [0,0])
if(boundMap==null) {
boundMap = boundMaps.find{ it.runRange==[0,0] }
}

// get the QA bounds
def valBounds = []
if(boundMap!=null) {
valBounds = boundMap.bounds
boundMap.used = true
} else {
throw new Exception("cannot find boundMap for $graphPath")
}

// check QA bounds
def inbound = val>=valBounds[0] && val<=valBounds[1]
if(!inbound) {
//T.printStatus("OB "+graphPath+" $run $val")
T.getLeaf(TL,graphPath).addPoint(run,val,0,0)
}

}
}
else {
T.printStatus("file does not exist; skipping")
}
})


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

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

// add cut lines
outTdir.cd("/timelines")
T.getLeaf(L,[det,hipoFile]).eachWithIndex{ num,idx ->
println "LINE: $det $hipoFile $num"
def lineColor = 'black'
if(hipoFile=="ltcc_elec_nphe_sec") {
def lineColors = ['red','red','blue','blue']
lineColor = lineColors[idx]
}
else if(hipoFile=="fth_MIPS_energy") {
def lineColors = ['red','red','blue','blue']
lineColor = lineColors[idx]
}
else if(hipoFile=="fth_MIPS_time_sigma") {
def lineColors = ['black','red','blue']
lineColor = lineColors[idx]
T.getLeaf(L,[det,hipoFile]).each{ boundMap ->
println "CUT: $det $hipoFile $boundMap"
if(boundMap.used==true) {
boundMap.bounds.each{ num ->
outTdir.addDataSet(buildLine(num, boundMap.color, boundMap.runRange))
}
} else {
println " NOT USED: do not draw line"
}
outTdir.addDataSet(buildLine(num,lineColor))
}

// create output hipo file
def outHipoDir = "${outdir}/${det}"
def outHipoDirHandle = new File(outHipoDir)
if(!outHipoDirHandle.exists()) outHipoDirHandle.mkdirs()
def outHipoN = "${outHipoDir}/${hipoFile}_QA.hipo"
File outHipoFile = new File(outHipoN)
if(outHipoFile.exists()) outHipoFile.delete()
Expand Down

0 comments on commit 0df2bb9

Please sign in to comment.