diff --git a/TEST.sh b/TEST.sh new file mode 100644 index 00000000..b92c7314 --- /dev/null +++ b/TEST.sh @@ -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 diff --git a/qa-detectors/README.md b/qa-detectors/README.md index 39b98619..1171e499 100644 --- a/qa-detectors/README.md +++ b/qa-detectors/README.md @@ -12,9 +12,15 @@ 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`, each key-value pair separated by a space + - `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]$ + - runs outside of all `run_range` specifiers will use the default cuts (the one(s) without the `run_range` specifier) + - all cuts should have a default version with no `run_range` - 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` diff --git a/qa-detectors/cuts/cuts.txt b/qa-detectors/cuts/cuts.txt index 05e21e25..3664b645 100644 --- a/qa-detectors/cuts/cuts.txt +++ b/qa-detectors/cuts/cuts.txt @@ -1,8 +1,22 @@ 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 12 18 counts spec:sec3 color:red run_range:16128:17811 # RGC su22, fa22, wi23 +# ltcc ltcc_elec_nphe_sec 12 18 counts spec:sec5 color:blue run_range:16128:17811 # RGC su22, fa22, wi23 +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 @@ -20,12 +34,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 @@ -48,11 +62,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 diff --git a/qa-detectors/cuts/cuts_rga_fa18.txt b/qa-detectors/cuts/cuts_rga_fa18.txt deleted file mode 100644 index ab155d05..00000000 --- a/qa-detectors/cuts/cuts_rga_fa18.txt +++ /dev/null @@ -1,2 +0,0 @@ -ltcc ltcc_elec_nphe_sec 7 9 counts sec3 -ltcc ltcc_elec_nphe_sec 4 6 counts sec5 diff --git a/qa-detectors/cuts/cuts_rgc_su22.txt b/qa-detectors/cuts/cuts_rgc_su22.txt deleted file mode 100644 index e8e5e42e..00000000 --- a/qa-detectors/cuts/cuts_rgc_su22.txt +++ /dev/null @@ -1,2 +0,0 @@ -ltcc ltcc_elec_nphe_sec 12 18 counts sec3 -ltcc ltcc_elec_nphe_sec 12 18 counts sec5 diff --git a/qa-detectors/util/applyBounds.groovy b/qa-detectors/util/applyBounds.groovy index f9171cd1..7f1151f8 100644 --- a/qa-detectors/util/applyBounds.groovy +++ b/qa-detectors/util/applyBounds.groovy @@ -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; here in case we need it again ] ///////////////////////////////////////////////////// @@ -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.. + 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 -> @@ -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) } } @@ -156,7 +174,7 @@ cutsFileList.each { re, cutsFile -> println "=== TIMELINES =========================" println T.pPrint(B) -println "=======================================" +println "=== CUT LINES =========================" println T.pPrint(L) println "=======================================" @@ -164,8 +182,11 @@ 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) @@ -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}") @@ -213,10 +235,28 @@ 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) @@ -224,10 +264,14 @@ T.exeLeaves(B,{ } } + 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 @@ -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()