diff --git a/DaVinciTests/tests/options/TurboMC_2015.py b/DaVinciTests/tests/options/TurboMC_2015.py new file mode 100644 index 0000000000000000000000000000000000000000..4595df200ab4e0e124b51fefcf69ce3ed0222ff5 --- /dev/null +++ b/DaVinciTests/tests/options/TurboMC_2015.py @@ -0,0 +1,41 @@ +from Configurables import DaVinci, DecayTreeTuple +from DecayTreeTuple import Configuration +from GaudiConf import IOHelper +from PhysConf.Filters import LoKi_Filters +from TeslaTools import TeslaTruthUtils + +hlt2_line = 'Hlt2CharmHadDstp2D0Pip_D02KmPipTurbo' + +dtt = DecayTreeTuple('TupleDstToD0pi_D0ToKpi') +dtt.Inputs = ['{0}/Particles'.format(hlt2_line)] +dtt.Decay = '[D*(2010)+ -> ^(D0 -> ^K- ^pi+) ^pi+]CC' +dtt.addBranches({ + 'Dst': '[D*(2010)+ -> (D0 -> K- pi+) pi+]CC', + 'D0': '[D*(2010)+ -> ^(D0 -> K- pi+) pi+]CC', + 'D0_K': '[D*(2010)+ -> (D0 -> ^K- pi+) pi+]CC', + 'D0_pi': '[D*(2010)+ -> (D0 -> K- ^pi+) pi+]CC', + 'Dst_pi': '[D*(2010)+ -> (D0 -> K- pi+) ^pi+]CC' +}) +dtt.ToolList += [ + 'TupleToolMCBackgroundInfo', + 'TupleToolMCTruth' +] +relations = [TeslaTruthUtils.getRelLoc('')] +mc_tools = [ + 'MCTupleToolKinematic' +] +TeslaTruthUtils.makeTruth(dtt, relations, mc_tools) + +trigger_filter = LoKi_Filters( + HLT2_Code="HLT_PASS_RE('^{0}Decision$')".format(hlt2_line) +) + +DaVinci().EventPreFilters = trigger_filter.filters('TriggerFilters') +DaVinci().UserAlgorithms = [dtt] +DaVinci().TupleFile = 'TurboMC_2015.root' +DaVinci().EvtMax = 1000 + +# Found with `lb-run LHCbDirac dirac-dms-lfn-accessURL --Protocol=xroot /lhcb/MC/2015/DST/00064085/0000/00064085_00000001_1.dst` +IOHelper().inputFiles([ + 'root://eoslhcb.cern.ch//eos/lhcb/grid/prod/lhcb/swtest/lhcb/MC/2015/DST/00064085/0000/00064085_00000001_1.dst' +]) diff --git a/DaVinciTests/tests/options/TurboMC_2016.py b/DaVinciTests/tests/options/TurboMC_2016.py new file mode 100644 index 0000000000000000000000000000000000000000..f89eea0041321412cd1612fd0066961f66fe1641 --- /dev/null +++ b/DaVinciTests/tests/options/TurboMC_2016.py @@ -0,0 +1,40 @@ +from Configurables import DaVinci, DecayTreeTuple +from DecayTreeTuple import Configuration +from GaudiConf import IOHelper +from PhysConf.Filters import LoKi_Filters +from TeslaTools import TeslaTruthUtils + +hlt2_line = 'Hlt2CharmHadDstp2D0Pip_D02KmPipTurbo' + +dtt = DecayTreeTuple('TupleDstToD0pi_D0ToKpi') +dtt.Inputs = ['{0}/Particles'.format(hlt2_line)] +dtt.Decay = '[D*(2010)+ -> ^(D0 -> ^K- ^pi+) ^pi+]CC' +dtt.addBranches({ + 'Dst': '[D*(2010)+ -> (D0 -> K- pi+) pi+]CC', + 'D0': '[D*(2010)+ -> ^(D0 -> K- pi+) pi+]CC', + 'D0_K': '[D*(2010)+ -> (D0 -> ^K- pi+) pi+]CC', + 'D0_pi': '[D*(2010)+ -> (D0 -> K- ^pi+) pi+]CC', + 'Dst_pi': '[D*(2010)+ -> (D0 -> K- pi+) ^pi+]CC' +}) +dtt.ToolList += [ + 'TupleToolMCBackgroundInfo', + 'TupleToolMCTruth' +] +relations = [TeslaTruthUtils.getRelLoc('')] +mc_tools = [ + 'MCTupleToolKinematic' +] +TeslaTruthUtils.makeTruth(dtt, relations, mc_tools) + +trigger_filter = LoKi_Filters( + HLT2_Code="HLT_PASS_RE('^{0}Decision$')".format(hlt2_line) +) + +DaVinci().EventPreFilters = trigger_filter.filters('TriggerFilters') +DaVinci().UserAlgorithms = [dtt] +DaVinci().TupleFile = 'TurboMC_2016.root' + +# Found with `lb-run LHCbDirac dirac-dms-lfn-accessURL --Protocol=xroot /lhcb/MC/2016/DST/00066623/0000/00066623_00000001_1.dst` +IOHelper().inputFiles([ + 'root://eoslhcb.cern.ch//eos/lhcb/grid/prod/lhcb/swtest/lhcb/MC/2016/DST/00066623/0000/00066623_00000001_1.dst' +]) diff --git a/DaVinciTests/tests/options/TurboMC_2016_uDST.py b/DaVinciTests/tests/options/TurboMC_2016_uDST.py new file mode 100644 index 0000000000000000000000000000000000000000..a5187918f76be9db83da149a9092f89ccbee3331 --- /dev/null +++ b/DaVinciTests/tests/options/TurboMC_2016_uDST.py @@ -0,0 +1,95 @@ +from Configurables import DaVinci, DecayTreeTuple, GaudiSequencer +from DecayTreeTuple import Configuration +from GaudiConf import IOHelper +from PhysConf.Filters import LoKi_Filters +from PhysSelPython.Selections import ( + AutomaticData, + CombineSelection, + RebuildSelection, + SelectionSequence +) +from StandardParticles import StdAllLooseANNPions +from TeslaTools import TeslaTruthUtils + +hlt2_line = 'Hlt2CharmHadLcpToPpKmPipTurbo' + +dtt = DecayTreeTuple('TupleLcTopKpi') +dtt.Inputs = ['{0}/Particles'.format(hlt2_line)] +dtt.Decay = '[Lambda_c+ -> ^p+ ^K- ^pi+]CC' +dtt.addBranches({ + 'Lc': '[Lambda_c+ -> p+ K- pi+]CC', + 'Lc_p': '[Lambda_c+ -> ^p+ K- pi+]CC', + 'Lc_K': '[Lambda_c+ -> p+ ^K- pi+]CC', + 'Lc_pi': '[Lambda_c+ -> p+ K- ^pi+]CC' +}) +dtt.ToolList += [ + 'TupleToolMCBackgroundInfo', + 'TupleToolMCTruth' +] +relations = [ + TeslaTruthUtils.getRelLoc(''), + # This location is required for truth-matching objects from Turbo++ + '/Event/Turbo/Relations/Hlt2/Protos/Charged' +] +mc_tools = [ + 'MCTupleToolKinematic' +] +TeslaTruthUtils.makeTruth(dtt, relations, mc_tools) + +# The Lcp line was a PersistReco line in 2016, so we have access to the whole +# HLT2 reconstruction here +combiner_sel = CombineSelection( + 'CombineLcpi', + inputs=[ + AutomaticData('{0}/Particles'.format(hlt2_line)), + RebuildSelection(StdAllLooseANNPions) + ], + DecayDescriptors=[ + '[Sigma_c++ -> Lambda_c+ pi+]cc', + '[Sigma_c0 -> Lambda_c+ pi-]cc' + ], + DaughtersCuts={ + 'pi+': 'PROBNNpi > 0.2' + }, + CombinationCut=( + 'in_range(0, (AM - AM1 - AM2), 170)' + ), + MotherCut=( + '(VFASPF(VCHI2PDOF) < 10) &' + 'in_range(0, (M - M1 - M2), 150)' + ) +) +selseq = SelectionSequence( + combiner_sel.name() + 'Sequence', + TopSelection=combiner_sel +) +sc_dtt = DecayTreeTuple('TupleScToLcpi_LcTopKpi') +sc_dtt.Inputs = [combiner_sel.outputLocation()] +sc_dtt.Decay = '[(Sigma_c++|Sigma_c0) -> ^(Lambda_c+ -> ^p+ ^K- ^pi+) ^X]CC' +sc_dtt.addBranches({ + 'Sc': '[Charm -> (Lambda_c+ -> p+ K- pi+) X]CC', + 'Lc': '[Charm -> ^(Lambda_c+ -> p+ K- pi+) X]CC', + 'Lc_p': '[Charm -> (Lambda_c+ -> ^p+ K- pi+) X]CC', + 'Lc_K': '[Charm -> (Lambda_c+ -> p+ ^K- pi+) X]CC', + 'Lc_pi': '[Charm -> (Lambda_c+ -> p+ K- ^pi+) X]CC', + 'Sc_pi': '[Charm -> (Lambda_c+ -> p+ K- pi+) ^X]CC' +}) +sc_dtt.ToolList += [ + 'TupleToolMCBackgroundInfo', + 'TupleToolMCTruth' +] +TeslaTruthUtils.makeTruth(sc_dtt, relations, mc_tools) +sc_seq = GaudiSequencer('SigmacSequence', Members=[selseq.sequence(), sc_dtt]) + +trigger_filter = LoKi_Filters( + HLT2_Code="HLT_PASS_RE('^{0}Decision$')".format(hlt2_line) +) + +DaVinci().EventPreFilters = trigger_filter.filters('TriggerFilters') +DaVinci().UserAlgorithms = [dtt, sc_seq] +DaVinci().TupleFile = 'TurboMC_2016_uDST.root' + +# Found with `lb-run LHCbDirac dirac-dms-lfn-accessURL --Protocol=xroot /lhcb/MC/2016/ALLSTREAMS.MDST/00063447/0000/00063447_00000001_7.AllStreams.mdst` +IOHelper().inputFiles([ + 'root://eoslhcb.cern.ch//eos/lhcb/grid/prod/lhcb/swtest/lhcb/MC/2016/ALLSTREAMS.MDST/00063447/0000/00063447_00000001_7.AllStreams.mdst' +]) diff --git a/DaVinciTests/tests/options/check_mc_output.py b/DaVinciTests/tests/options/check_mc_output.py new file mode 100644 index 0000000000000000000000000000000000000000..01b4427c7c05b38874a74bc9e0c391fc3eba0be6 --- /dev/null +++ b/DaVinciTests/tests/options/check_mc_output.py @@ -0,0 +1,39 @@ +"""Check ntuples made from Turbo MC input for correct truth-matching.""" +from __future__ import print_function +import sys + +import ROOT + +tree_branches = { + 'TupleDstToD0pi_D0ToKpi': (['Dst', 'D0'], ['D0_K', 'D0_pi', 'Dst_pi']), + 'TupleLcTopKpi': (['Lc'], ['Lc_p', 'Lc_K', 'Lc_pi']), + 'TupleScToLcpi_LcTopKpi': (['Sc', 'Lc'], ['Lc_p', 'Lc_K', 'Lc_pi', 'Sc_pi']) +} + +fname = sys.argv[-2] +tname = sys.argv[-1] +assert fname.endswith('.root'), 'Expected a ROOT file as input, got: ' + fname +assert tname in tree_branches, 'Cannot handle given tree, got: ' + tname +print('Looking at file {0!r}, tree {1!r}'.format(fname, tname)) + +composites, children = tree_branches[tname] + +f = ROOT.TFile(fname) +t = f.Get('{0}/DecayTree'.format(tname)) + +assert t.GetEntries() > 0, 'Expected non-zero number of entries' +print('Found {0} entries'.format(t.GetEntries())) + +# If the truth-matching fails, we'd see BKGCAT == 60 for all entries +for p in composites: + condition = '{0}_BKGCAT < 20'.format(p) + assert t.GetEntries(condition) > 0, \ + 'Expected non-zero number of entries with {0}'.format(condition) + print('OK: {0!r}'.format(condition)) +# If the truth-matching fails, we'd see TRUEID == 0 for all entries +for p in composites + children: + condition = '{0}_TRUEID != 0'.format(p) + assert t.GetEntries(condition) > 0, \ + 'Expected non-zero number of entries with {0}'.format(condition) + print('OK: {0!r}'.format(condition)) +f.Close() diff --git a/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2015_dst.qmt b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2015_dst.qmt new file mode 100644 index 0000000000000000000000000000000000000000..08841f02be630bbdd4339992d9b5d1ed7660675e --- /dev/null +++ b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2015_dst.qmt @@ -0,0 +1,16 @@ +<?xml version="1.0" ?> +<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"> + <text>gaudirun.py</text> + </argument> + <argument name="args"><set> + <text>../options/DV_Turbo_OK.py</text> + <text>../options/TurboMC_2015.py</text> + <text>$APPCONFIGOPTS/DaVinci/DataType-2015.py</text> + <text>$APPCONFIGOPTS/DaVinci/Simulation.py</text> + </set></argument> + <argument name="exit_code"> + <integer>0</integer> + </argument> +</extension> diff --git a/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2015_dst_read.qmt b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2015_dst_read.qmt new file mode 100644 index 0000000000000000000000000000000000000000..b5e06f2b0243cf4dc1326a592e140c907d018cd4 --- /dev/null +++ b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2015_dst_read.qmt @@ -0,0 +1,18 @@ +<?xml version="1.0" ?> +<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"> + <text>python</text> + </argument> + <argument name="args"><set> + <text>../options/check_mc_output.py</text> + <text>TurboMC_2015.root</text> + <text>TupleDstToD0pi_D0ToKpi</text> + </set></argument> + <argument name="exit_code"> + <integer>0</integer> + </argument> + <argument name="prerequisites"><set> + <tuple><text>davinci.davinci_turbo_mc_2015_dst</text><enumeral>PASS</enumeral></tuple> + </set></argument> +</extension> diff --git a/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_dst.qmt b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_dst.qmt new file mode 100644 index 0000000000000000000000000000000000000000..96747ea0edb5dc979c2c18a7972e22c453854cb1 --- /dev/null +++ b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_dst.qmt @@ -0,0 +1,16 @@ +<?xml version="1.0" ?> +<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"> + <text>gaudirun.py</text> + </argument> + <argument name="args"><set> + <text>../options/DV_Turbo_OK.py</text> + <text>../options/TurboMC_2016.py</text> + <text>$APPCONFIGOPTS/DaVinci/DataType-2016.py</text> + <text>$APPCONFIGOPTS/DaVinci/Simulation.py</text> + </set></argument> + <argument name="exit_code"> + <integer>0</integer> + </argument> +</extension> diff --git a/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_dst_read.qmt b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_dst_read.qmt new file mode 100644 index 0000000000000000000000000000000000000000..7b1866188f006169551b86a0d10954648d86ff4e --- /dev/null +++ b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_dst_read.qmt @@ -0,0 +1,18 @@ +<?xml version="1.0" ?> +<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"> + <text>python</text> + </argument> + <argument name="args"><set> + <text>../options/check_mc_output.py</text> + <text>TurboMC_2016.root</text> + <text>TupleDstToD0pi_D0ToKpi</text> + </set></argument> + <argument name="exit_code"> + <integer>0</integer> + </argument> + <argument name="prerequisites"><set> + <tuple><text>davinci.davinci_turbo_mc_2016_dst</text><enumeral>PASS</enumeral></tuple> + </set></argument> +</extension> diff --git a/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_udst.qmt b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_udst.qmt new file mode 100644 index 0000000000000000000000000000000000000000..d970816e8b768e53c2b1a154acaafb25dfa51894 --- /dev/null +++ b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_udst.qmt @@ -0,0 +1,16 @@ +<?xml version="1.0" ?> +<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"> + <text>gaudirun.py</text> + </argument> + <argument name="args"><set> + <text>../options/DV_Turbo_OK.py</text> + <text>../options/TurboMC_2016_uDST.py</text> + <text>$APPCONFIGOPTS/DaVinci/DataType-2016.py</text> + <text>$APPCONFIGOPTS/DaVinci/Simulation.py</text> + </set></argument> + <argument name="exit_code"> + <integer>0</integer> + </argument> +</extension> diff --git a/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_udst_read.qmt b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_udst_read.qmt new file mode 100644 index 0000000000000000000000000000000000000000..512b42b753e7a52a5f7da2e4d824bf3e4d2a4f2d --- /dev/null +++ b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_udst_read.qmt @@ -0,0 +1,18 @@ +<?xml version="1.0" ?> +<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"> + <text>python</text> + </argument> + <argument name="args"><set> + <text>../options/check_mc_output.py</text> + <text>TurboMC_2016_uDST.root</text> + <text>TupleLcTopKpi</text> + </set></argument> + <argument name="exit_code"> + <integer>0</integer> + </argument> + <argument name="prerequisites"><set> + <tuple><text>davinci.davinci_turbo_mc_2016_udst</text><enumeral>PASS</enumeral></tuple> + </set></argument> +</extension> diff --git a/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_udst_read_pr.qmt b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_udst_read_pr.qmt new file mode 100644 index 0000000000000000000000000000000000000000..de4e78eecc72cac3e7af12e2365e8c23ecaf183c --- /dev/null +++ b/DaVinciTests/tests/qmtest/davinci.qms/davinci_turbo_mc_2016_udst_read_pr.qmt @@ -0,0 +1,18 @@ +<?xml version="1.0" ?> +<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"> + <text>python</text> + </argument> + <argument name="args"><set> + <text>../options/check_mc_output.py</text> + <text>TurboMC_2016_uDST.root</text> + <text>TupleScToLcpi_LcTopKpi</text> + </set></argument> + <argument name="exit_code"> + <integer>0</integer> + </argument> + <argument name="prerequisites"><set> + <tuple><text>davinci.davinci_turbo_mc_2016_udst</text><enumeral>PASS</enumeral></tuple> + </set></argument> +</extension>