diff --git a/qa-detectors/README.md b/qa-detectors/README.md index 39b98619..7966781c 100644 --- a/qa-detectors/README.md +++ b/qa-detectors/README.md @@ -9,8 +9,8 @@ The specifications are specified by text files in [the `cuts` directory](cuts). - each line should have the following columns, delimited by spaces: - detector name - HIPO file name (_i.e._, the timeline name, with spaces changed to underscores) - - lower bound of QA cut - - upper bound of QA cut + - lower bound of QA cut; if there is no lower bound, write `NB`, which means "No Bound" + - upper bound of QA cut; if there is no upper bound, write `NB`, which means "No Bound" - units - (optional) additional specifier(s), _e.g._, specific sectors - comments can be added using the symbol `#`, which is useful for commenting out timelines, especially when debugging a particular timeline diff --git a/qa-detectors/cuts/cuts.txt b/qa-detectors/cuts/cuts.txt index a927ff49..dab5c4ab 100644 --- a/qa-detectors/cuts/cuts.txt +++ b/qa-detectors/cuts/cuts.txt @@ -1,59 +1,59 @@ rf rftime_electron_FD_mean -0.010 0.010 ns -rf rftime_electron_FD_sigma 0 0.070 ns +rf rftime_electron_FD_sigma NB 0.070 ns ltcc ltcc_elec_nphe_sec 11 14 counts sec3 ltcc ltcc_elec_nphe_sec 11 14 counts sec5 -htcc htcc_nphe_sec_npheMean 12.5 14.5 counts +htcc htcc_nphe_sec_npheMean 12.5 NB counts htcc htcc_nphe_sec_normFactor 0.9 1.1 unitless htcc htcc_vtimediff_sector_mean -1 1 ns -htcc htcc_vtimediff_sector_sigma 0 1 ns +htcc htcc_vtimediff_sector_sigma NB 1 ns ftof ftof_edep_p1a_midangles 8.75 10.75 MeV ftof ftof_edep_p1b_midangles 10.5 12.5 MeV ftof ftof_edep_p2 8.75 10.75 MeV ftof ftof_time_p1a_mean -0.030 0.030 ns -ftof ftof_time_p1a_sigma 0 0.135 ns +ftof ftof_time_p1a_sigma NB 0.135 ns ftof ftof_time_p1b_mean -0.020 0.020 ns -ftof ftof_time_p1b_sigma 0 0.075 ns +ftof ftof_time_p1b_sigma NB 0.075 ns ftof ftof_time_p2_mean -0.070 0.070 ns -ftof ftof_time_p2_sigma 0 0.350 ns +ftof ftof_time_p2_sigma NB 0.350 ns ft ftc_pi0_mass_mean 134 136 MeV -ft ftc_pi0_mass_sigma 0 5 MeV +ft ftc_pi0_mass_sigma NB 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_time_sigma NB 1.4 ns layer1 +ft fth_MIPS_time_sigma NB 1.2 ns layer2 ec ec_Sampling 0.23 0.26 unitless ec ec_gg_m_mean 0.129 0.133 GeV -ec ec_gg_m_sigma 0 0.015 GeV +ec ec_gg_m_sigma NB 0.015 GeV ec ec_elec_pcal_time_mean -0.150 0.150 ns -ec ec_elec_pcal_time_sigma 0.000 0.600 ns +ec ec_elec_pcal_time_sigma NB 0.600 ns ec ec_elec_ecin_time_mean -0.150 0.150 ns -ec ec_elec_ecin_time_sigma 0.000 0.600 ns +ec ec_elec_ecin_time_sigma NB 0.600 ns ec ec_elec_ecou_time_mean -0.150 0.150 ns -ec ec_elec_ecou_time_sigma 0.000 1.200 ns +ec ec_elec_ecou_time_sigma NB 1.200 ns ctof ctof_edep 5.6 6.4 MeV ctof ctof_time_mean -0.020 0.020 ns -ctof ctof_time_sigma 0 0.115 ns +ctof ctof_time_sigma NB 0.115 ns cnd cnd_dEdz_mean 1.75 2.25 MeV/cm -cnd cnd_dEdz_sigma 0 0.300 MeV/cm +cnd cnd_dEdz_sigma NB 0.300 MeV/cm cnd cnd_time_neg_vtP_mean -0.100 0.100 ns -cnd cnd_time_neg_vtP_sigma 0 0.300 ns +cnd cnd_time_neg_vtP_sigma NB 0.300 ns cnd cnd_zdiff_mean -0.4 0.4 cm -cnd cnd_zdiff_sigma 0 4 cm +cnd cnd_zdiff_sigma NB 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_sigma NB 0.0400 cm R1 +dc dc_residuals_sec_sl_sigma NB 0.0400 cm R2 +dc dc_residuals_sec_sl_sigma NB 0.0400 cm R3 -rich rich_time_fwhm_max 0 1 ns +rich rich_time_fwhm_max NB 1 ns diff --git a/qa-detectors/util/applyBounds.groovy b/qa-detectors/util/applyBounds.groovy index f9171cd1..eb77e892 100644 --- a/qa-detectors/util/applyBounds.groovy +++ b/qa-detectors/util/applyBounds.groovy @@ -76,14 +76,20 @@ cutsFileList.each { re, cutsFile -> } def det = tok[0] def timeline = tok[1] - def lbound = tok[2].toDouble() - def ubound = tok[3].toDouble() + def lbound = tok[2] + def ubound = tok[3] def units = tok[4] cutPath = [det, timeline] spec = tok.size()>5 ? tok[5] : '' if(spec!='') cutPath.add(spec) + // convert bounds to 'double' type, unless they are a string + def lboundCasted + def uboundCasted + try { lboundCasted = lbound.toDouble(); } catch(Exception ex) { lboundCasted = lbound.toString(); } + try { uboundCasted = ubound.toDouble(); } catch(Exception ex) { uboundCasted = ubound.toString(); } + // add cuts to graph def addCut = { graphN -> [ @@ -95,8 +101,8 @@ 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(lboundCasted) + T.getLeaf(tr, nodePath).add(uboundCasted) } } @@ -187,7 +193,23 @@ T.exeLeaves(B,{ // setup def graphPath = T.leafPath def fileN = indir+'/'+graphPath[0,-2].join('/') + ".hipo" - def bounds = T.leaf + def qaBounds = T.leaf + + // figure out the bound types + // FIXME: this just checks if `qaBounds` entries are Strings, and not whether they are set to + // "NB" or not; nonetheless, the documentation says to use "NB" + def qaBoundsClasses = qaBounds.collect{it.getClass().getSimpleName()} + def (kNone, kMin, kMax, kRange) = (0..3).collect{it} + def qaBoundsType = -1 + if(qaBoundsClasses[0] == "String" && qaBoundsClasses[1] == "String") { + qaBoundsType = kNone + } else if(qaBoundsClasses[0] == "String") { + qaBoundsType = kMax + } else if(qaBoundsClasses[1] == "String") { + qaBoundsType = kMin + } else { + qaBoundsType = kRange + } // read input timeline; do nothing if input timeline file // does not exist @@ -216,7 +238,13 @@ T.exeLeaves(B,{ // check QA bounds def run = gr.getDataX(i) def val = gr.getDataY(i) - def inbound = val>=bounds[0] && val<=bounds[1] + def inbound = false + switch(qaBoundsType) { + case kNone: inbound = true; break; + case kMin: inbound = val>=qaBounds[0]; break; + case kMax: inbound = val<=qaBounds[1]; break; + case kRange: inbound = val>=qaBounds[0] && val<=qaBounds[1]; break + } if(!inbound) { //T.printStatus("OB "+graphPath+" $run $val") T.getLeaf(TL,graphPath).addPoint(run,val,0,0) @@ -266,6 +294,9 @@ TL.each{ det, detTr -> // loop through detector directories // add cut lines outTdir.cd("/timelines") T.getLeaf(L,[det,hipoFile]).eachWithIndex{ num,idx -> + if(num.getClass().getSimpleName() == "String") { // skip "NB" (No Bound) values + return + } println "LINE: $det $hipoFile $num" def lineColor = 'black' if(hipoFile=="ltcc_elec_nphe_sec") {