From 59d429dbcae3a4554269d5acc47a88738f1cd802 Mon Sep 17 00:00:00 2001 From: Jiahui Zhuo <jiahui.zhuo@cern.ch> Date: Tue, 21 Jun 2022 09:58:05 +0200 Subject: [PATCH] Thor functors for MCTrackInfo --- .../tupling/example-tupling-mctrack-hlt.py | 116 ++++++++ .../tupling/example-tupling-mctrack-hlt.yaml | 18 ++ .../example-tupling-mctrack-mctuple-hlt.py | 125 +++++++++ .../example-tupling-mctrack-mctuple-hlt.yaml | 18 ++ .../test_davinci_tupling_mctrack_hlt.qmt | 72 +++++ ...st_davinci_tupling_mctrack_mctuple_hlt.qmt | 72 +++++ Phys/DaVinci/python/DaVinci/mc_track.py | 252 ++++++++++++++++++ Phys/DaVinci/python/DaVinci/truth_matching.py | 6 +- 8 files changed, 677 insertions(+), 2 deletions(-) create mode 100644 DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-hlt.py create mode 100644 DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-hlt.yaml create mode 100644 DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt.py create mode 100644 DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt.yaml create mode 100644 DaVinciExamples/tests/qmtest/tupling.qms/test_davinci_tupling_mctrack_hlt.qmt create mode 100644 DaVinciExamples/tests/qmtest/tupling.qms/test_davinci_tupling_mctrack_mctuple_hlt.qmt create mode 100644 Phys/DaVinci/python/DaVinci/mc_track.py diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-hlt.py b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-hlt.py new file mode 100644 index 000000000..1a2288053 --- /dev/null +++ b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-hlt.py @@ -0,0 +1,116 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +# Run this example in this diractory with: +# ../../../../run davinci \ +# --inputfiledb test_hlt1_trigger_decisions ../../../../Phys/DaVinci/options/DaVinciDB-Example.yaml \ +# --joboptfile example-tupling-mctrack-hlt.yaml \ +# --user_algorithms example-tupling-mctrack-hlt:main + +from FunTuple import FunctorCollection +import Functors as F +from FunTuple import FunTuple_Particles as Funtuple +from DaVinci import options +from DaVinci.truth_matching import configured_MCTruthAndBkgCatAlg +from DaVinci.algorithms import add_filter +from PyConf.components import force_location + +from DaVinci.mc_track import MCP2MCTrackInfo + + +def main(): + + # Input + B_data = force_location( + "/Event/HLT2/Hlt2B2OC_BdToDmPi_DmToPimPimKp_Line/Particles") + + # Filter + filter_Dpi = add_filter(options, "HDRFilter", + "HLT_PASS('Hlt2B2OC_BdToDmPi_DmToPimPimKp_Line')") + + # Truth matching + mctruth = configured_MCTruthAndBkgCatAlg( + inputs=B_data, + filter_MCP=True, + # output_level=1, + root_in_tes="/Event/HLT2") + MC_TRUTH = lambda func: F.MAP_INPUT(Functor=func, Relations=mctruth.MCAssocTable) + + # Tracks tools + MCP2MCTRACKINFO = MCP2MCTrackInfo(mctruth.TruthMatchedMCP, process='Hlt2') + + # Variables + variables_all = FunctorCollection({ + # REC + "P": + F.P, + "PT": + F.PT, + "PX": + F.PX, + "PY": + F.PY, + "PZ": + F.PZ, + "ENERGY": + F.ENERGY, + # TRUTH MATCHING + "TRUEP": + MC_TRUTH(F.P), + "TRUEPT": + MC_TRUTH(F.PT), + "TRUEPX": + MC_TRUTH(F.PX), + "TRUEPY": + MC_TRUTH(F.PY), + "TRUEPZ": + MC_TRUTH(F.PZ), + "TRUEENERGY": + MC_TRUTH(F.ENERGY), + # TRUE TRACK + "MC_HAST": + MC_TRUTH(MCP2MCTRACKINFO.HasT), + "MC_HASTT": + MC_TRUTH(MCP2MCTRACKINFO.HasTT), + "MC_HASVELO": + MC_TRUTH(MCP2MCTRACKINFO.HasVelo), + "MC_ACCT": + MC_TRUTH(MCP2MCTRACKINFO.AccT), + "MC_ACCTT": + MC_TRUTH(MCP2MCTRACKINFO.AccTT), + "MC_ACCVELO": + MC_TRUTH(MCP2MCTRACKINFO.AccVelo), + # RECONSTRUCTIBLE CATEGORY + "MC_RECONSTRUCTIBLE": + MC_TRUTH(MCP2MCTRACKINFO.Reconstructible) + }) + + variables = {'ALL': variables_all} + + # Define fields + fields = { + 'B0': '[[B0]CC -> (D- -> K+ pi- pi-) pi+]CC', + 'D': '[[B0]CC -> ^(D- -> K+ pi- pi-) pi+]CC', + 'pi': '[[B0]CC -> (D- -> K+ pi- pi-) ^pi+]CC', + 'Kplus': '[[B0]CC -> (D- -> ^K+ pi- pi-) pi+]CC', + 'piminus_1': '[[B0]CC -> (D- -> K+ ^pi- pi-) pi+]CC', + 'piminus_2': '[[B0]CC -> (D- -> K+ pi- ^pi-) pi+]CC' + } + + # Make tuple algorithm + tuple_Dpi = Funtuple( + name="Dpi", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=B_data) + + # Run + return {"KstG": [filter_Dpi, tuple_Dpi]}, [] diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-hlt.yaml b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-hlt.yaml new file mode 100644 index 000000000..724b96e8b --- /dev/null +++ b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-hlt.yaml @@ -0,0 +1,18 @@ +############################################################################### +# (c) Copyright 2020-2021 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### + +evt_max: 50 +annsvc_config: 'root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/hlt2_integration_B0_100.tck.json' +histo_file: 'DV_histo_example-tupling-mctrack-hlt.root' +ntuple_file: 'DV_tuple_example-tupling-mctrack-hlt.root' +lumi: false +print_freq: 1 +process: 'Hlt2' diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt.py b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt.py new file mode 100644 index 000000000..a4d1cd909 --- /dev/null +++ b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt.py @@ -0,0 +1,125 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +# Run this example in this diractory with: +# ../../../../run davinci \ +# --inputfiledb test_hlt1_trigger_decisions ../../../../Phys/DaVinci/options/DaVinciDB-Example.yaml \ +# --joboptfile example-tupling-mctrack-hlt.yaml \ +# --user_algorithms example-tupling-mctrack-hlt:main + +from FunTuple import FunctorCollection +import Functors as F +from FunTuple import FunTuple_MCParticles as MCFuntuple +from DaVinci import options +from DaVinci.algorithms import add_filter +from PyConf.components import force_location + +from DaVinci.mc_track import MCP2MCTrackInfo, MCP2Track + + +def main(): + + # Input + MC_data = force_location("/Event/HLT2/MC/Particles") + + # Filter + filter_Dpi = add_filter(options, "HDRFilter", + "HLT_PASS('Hlt2B2OC_BdToDmPi_DmToPimPimKp_Line')") + + # Tracks tools + MCP2MCTRACKINFO = MCP2MCTrackInfo(MC_data, process='Hlt2') + MCP2TRACK = MCP2Track(MC_data, process='Hlt2') + + # Variables + variables_all = FunctorCollection({ + # REC + "P": + F.P, + "PT": + F.PT, + "PX": + F.PX, + "PY": + F.PY, + "PZ": + F.PZ, + "ENERGY": + F.ENERGY, + # RECONSTRUCTED TRACK + "MC_RecoTrack_TYPE": + MCP2TRACK.Type, + "MC_RecoTrack_REF_X": + MCP2TRACK.ReferencePoint_X, + "MC_RecoTrack_REF_Y": + MCP2TRACK.ReferencePoint_Y, + "MC_RecoTrack_REF_Z": + MCP2TRACK.ReferencePoint_Z, + "MC_RecoTrack_NDOF": + MCP2TRACK.nDoF, + "MC_RecoTrack_GHOSTPROB": + MCP2TRACK.GhostProbability, + "MC_RecoTrack_FLAG": + MCP2TRACK.Flag, + "MC_RecoTrack_HAST": + MCP2TRACK.HasT, + "MC_RecoTrack_HASUT": + MCP2TRACK.HasUT, + "MC_RecoTrack_HASVELO": + MCP2TRACK.HasVelo, + "MC_RecoTrack_NHITS": + MCP2TRACK.nHits, + "MC_RecoTrack_NVPHITS": + MCP2TRACK.nVPHits, + "MC_RecoTrack_NUTHITS": + MCP2TRACK.nUTHits, + "MC_RecoTrack_NFTHITS": + MCP2TRACK.nFTHits, + # TRUE TRACK + "MC_HAST": + MCP2MCTRACKINFO.HasT, + "MC_HASTT": + MCP2MCTRACKINFO.HasTT, + "MC_HASVELO": + MCP2MCTRACKINFO.HasVelo, + "MC_ACCT": + MCP2MCTRACKINFO.AccT, + "MC_ACCTT": + MCP2MCTRACKINFO.AccTT, + "MC_ACCVELO": + MCP2MCTRACKINFO.AccVelo, + # RECONSTRUCTED CATEGORY AND RECONSTRUCTIBLE CATEGORY + "MC_RECONSTRUCTED": + MCP2TRACK.Reconstructed, + "MC_RECONSTRUCTIBLE": + MCP2MCTRACKINFO.Reconstructible, + }) + + variables = {'ALL': variables_all} + + # Define fields + fields = { + 'B0': '[[B0]CC -> (D- -> K+ pi- pi-) pi+]CC', + 'D': '[[B0]CC -> ^(D- -> K+ pi- pi-) pi+]CC', + 'pi': '[[B0]CC -> (D- -> K+ pi- pi-) ^pi+]CC', + 'Kplus': '[[B0]CC -> (D- -> ^K+ pi- pi-) pi+]CC', + 'piminus_1': '[[B0]CC -> (D- -> K+ ^pi- pi-) pi+]CC', + 'piminus_2': '[[B0]CC -> (D- -> K+ pi- ^pi-) pi+]CC' + } + + # Make tuple algorithm + tuple_Dpi = MCFuntuple( + name="DpiMC", + tuple_name="DecayTree", + fields=fields, + variables=variables, + inputs=MC_data) + + # Run + return {"KstG": [filter_Dpi, tuple_Dpi]}, [] diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt.yaml b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt.yaml new file mode 100644 index 000000000..70e503a65 --- /dev/null +++ b/DaVinciExamples/python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt.yaml @@ -0,0 +1,18 @@ +############################################################################### +# (c) Copyright 2020-2021 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### + +evt_max: 50 +annsvc_config: 'root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/hlt2_integration_B0_100.tck.json' +histo_file: 'DV_histo_example-tupling-mctrack-mctuple-hlt.root' +ntuple_file: 'DV_tuple_example-tupling-mctrack-mctuple-hlt.root' +lumi: false +print_freq: 1 +process: 'Hlt2' diff --git a/DaVinciExamples/tests/qmtest/tupling.qms/test_davinci_tupling_mctrack_hlt.qmt b/DaVinciExamples/tests/qmtest/tupling.qms/test_davinci_tupling_mctrack_hlt.qmt new file mode 100644 index 000000000..2adc0e0ec --- /dev/null +++ b/DaVinciExamples/tests/qmtest/tupling.qms/test_davinci_tupling_mctrack_hlt.qmt @@ -0,0 +1,72 @@ +<?xml version="1.0" ?> +<!-- +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +--> +<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<!-- +####################################################### +# SUMMARY OF THIS TEST +# ................... +# Author: Jiahui Zhuo +# Purpose: Test for MCTrack related functor in HLT2 process +# Prerequisites: None +# inputfiledb test_hlt1_trigger_decisions $DAVINCIROOT/options/DaVinciDB-Example.yaml +# user_algorithms ../../python/DaVinciExamples/tupling/example-tupling-mctrack-hlt:main +####################################################### +--> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"><text>davinci</text></argument> + <argument name="args"><set> + <text>--inputfiledb</text> + <text>test_hlt1_trigger_decisions</text> + <text>$DAVINCIROOT/options/DaVinciDB-Example.yaml</text> + <text>--joboptfile</text> + <text>../../python/DaVinciExamples/tupling/example-tupling-mctrack-hlt.yaml</text> + <text>--user_algorithms</text> + <text>../../python/DaVinciExamples/tupling/example-tupling-mctrack-hlt:main</text> + </set></argument> + <argument name="validator"><text> +findReferenceBlock(""" +RFileCnv INFO dumping contents of /NTUPLES/FILE1 +TFile: name=DV_tuple_example-tupling-mctrack-hlt.root, title=Gaudi Trees, option=CREATE +****************************************************************************** +*Tree :DecayTree : DecayTree * +""", stdout, result, causes, signature_offset = 0) + +import sys, os +from ROOT import TFile + +B_vars_stored =['B0_ENERGY', 'B0_MC_ACCT', 'B0_MC_ACCTT', 'B0_MC_ACCVELO', 'B0_MC_HAST', 'B0_MC_HASTT', 'B0_MC_HASVELO', 'B0_MC_RECONSTRUCTIBLE', 'B0_P', 'B0_PT', 'B0_PX', 'B0_PY', 'B0_PZ', 'B0_TRUEENERGY', 'B0_TRUEP', 'B0_TRUEPT', 'B0_TRUEPX', 'B0_TRUEPY', 'B0_TRUEPZ', 'D_ENERGY', 'D_MC_ACCT', 'D_MC_ACCTT', 'D_MC_ACCVELO', 'D_MC_HAST', 'D_MC_HASTT', 'D_MC_HASVELO', 'D_MC_RECONSTRUCTIBLE', 'D_P', 'D_PT', 'D_PX', 'D_PY', 'D_PZ', 'D_TRUEENERGY', 'D_TRUEP', 'D_TRUEPT', 'D_TRUEPX', 'D_TRUEPY', 'D_TRUEPZ', 'Kplus_ENERGY', 'Kplus_MC_ACCT', 'Kplus_MC_ACCTT', 'Kplus_MC_ACCVELO', 'Kplus_MC_HAST', 'Kplus_MC_HASTT', 'Kplus_MC_HASVELO', 'Kplus_MC_RECONSTRUCTIBLE', 'Kplus_P', 'Kplus_PT', 'Kplus_PX', 'Kplus_PY', 'Kplus_PZ', 'Kplus_TRUEENERGY', 'Kplus_TRUEP', 'Kplus_TRUEPT', 'Kplus_TRUEPX', 'Kplus_TRUEPY', 'Kplus_TRUEPZ', 'pi_ENERGY', 'pi_MC_ACCT', 'pi_MC_ACCTT', 'pi_MC_ACCVELO', 'pi_MC_HAST', 'pi_MC_HASTT', 'pi_MC_HASVELO', 'pi_MC_RECONSTRUCTIBLE', 'pi_P', 'pi_PT', 'pi_PX', 'pi_PY', 'pi_PZ', 'pi_TRUEENERGY', 'pi_TRUEP', 'pi_TRUEPT', 'pi_TRUEPX', 'pi_TRUEPY', 'pi_TRUEPZ', 'piminus_1_ENERGY', 'piminus_1_MC_ACCT', 'piminus_1_MC_ACCTT', 'piminus_1_MC_ACCVELO', 'piminus_1_MC_HAST', 'piminus_1_MC_HASTT', 'piminus_1_MC_HASVELO', 'piminus_1_MC_RECONSTRUCTIBLE', 'piminus_1_P', 'piminus_1_PT', 'piminus_1_PX', 'piminus_1_PY', 'piminus_1_PZ', 'piminus_1_TRUEENERGY', 'piminus_1_TRUEP', 'piminus_1_TRUEPT', 'piminus_1_TRUEPX', 'piminus_1_TRUEPY', 'piminus_1_TRUEPZ', 'piminus_2_ENERGY', 'piminus_2_MC_ACCT', 'piminus_2_MC_ACCTT', 'piminus_2_MC_ACCVELO', 'piminus_2_MC_HAST', 'piminus_2_MC_HASTT', 'piminus_2_MC_HASVELO', 'piminus_2_MC_RECONSTRUCTIBLE', 'piminus_2_P', 'piminus_2_PT', 'piminus_2_PX', 'piminus_2_PY', 'piminus_2_PZ', 'piminus_2_TRUEENERGY', 'piminus_2_TRUEP', 'piminus_2_TRUEPT', 'piminus_2_TRUEPX', 'piminus_2_TRUEPY', 'piminus_2_TRUEPZ'] + +#sort the expected vars +B_vars_stored = sorted(B_vars_stored) + +#open the TFile and TTree +ntuple = './DV_tuple_example-tupling-mctrack-hlt.root' +if not os.path.isfile(ntuple): raise Exception(f"File: {ntuple} does not exist!") +f = TFile.Open(ntuple) +t_B = f.Get('Dpi/DecayTree') + +#sort the stores vars +b_names = sorted([b.GetName() for b in t_B.GetListOfLeaves()]) + +B_excluded_1 = set(B_vars_stored) - set(b_names) +B_excluded_2 = set(b_names) - set(B_vars_stored) +if len(B_excluded_1) != 0: raise Exception('Number of stored variables is less than what is expected. The extra variables expected are: ' , B_excluded_1) +if len(B_excluded_2) != 0: raise Exception('Number of stored variables is greater than what is expected. The extra variables stored are: ', B_excluded_2) + +f.Close() +print('Test successfully completed!') +os.system(f"rm {ntuple}") +countErrorLines({"FATAL":0, "ERROR":0}) + </text></argument> +</extension> diff --git a/DaVinciExamples/tests/qmtest/tupling.qms/test_davinci_tupling_mctrack_mctuple_hlt.qmt b/DaVinciExamples/tests/qmtest/tupling.qms/test_davinci_tupling_mctrack_mctuple_hlt.qmt new file mode 100644 index 000000000..15b584e42 --- /dev/null +++ b/DaVinciExamples/tests/qmtest/tupling.qms/test_davinci_tupling_mctrack_mctuple_hlt.qmt @@ -0,0 +1,72 @@ +<?xml version="1.0" ?> +<!-- +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +--> +<!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<!-- +####################################################### +# SUMMARY OF THIS TEST +# ................... +# Author: Jiahui Zhuo +# Purpose: Test for MCTrack related functor in HLT2 process and FunTuple_MCParticles +# Prerequisites: None +# inputfiledb test_hlt1_trigger_decisions $DAVINCIROOT/options/DaVinciDB-Example.yaml +# user_algorithms ../../python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt:main +####################################################### +--> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"><text>davinci</text></argument> + <argument name="args"><set> + <text>--inputfiledb</text> + <text>test_hlt1_trigger_decisions</text> + <text>$DAVINCIROOT/options/DaVinciDB-Example.yaml</text> + <text>--joboptfile</text> + <text>../../python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt.yaml</text> + <text>--user_algorithms</text> + <text>../../python/DaVinciExamples/tupling/example-tupling-mctrack-mctuple-hlt:main</text> + </set></argument> + <argument name="validator"><text> +findReferenceBlock(""" +RFileCnv INFO dumping contents of /NTUPLES/FILE1 +TFile: name=DV_tuple_example-tupling-mctrack-mctuple-hlt.root, title=Gaudi Trees, option=CREATE +****************************************************************************** +*Tree :DecayTree : DecayTree * +""", stdout, result, causes, signature_offset = 0) + +import sys, os +from ROOT import TFile + +B_vars_stored =['B0_ENERGY', 'B0_MC_ACCT', 'B0_MC_ACCTT', 'B0_MC_ACCVELO', 'B0_MC_HAST', 'B0_MC_HASTT', 'B0_MC_HASVELO', 'B0_MC_RECONSTRUCTED', 'B0_MC_RECONSTRUCTIBLE', 'B0_MC_RecoTrack_FLAG', 'B0_MC_RecoTrack_GHOSTPROB', 'B0_MC_RecoTrack_HAST', 'B0_MC_RecoTrack_HASUT', 'B0_MC_RecoTrack_HASVELO', 'B0_MC_RecoTrack_NDOF', 'B0_MC_RecoTrack_NFTHITS', 'B0_MC_RecoTrack_NHITS', 'B0_MC_RecoTrack_NUTHITS', 'B0_MC_RecoTrack_NVPHITS', 'B0_MC_RecoTrack_REF_X', 'B0_MC_RecoTrack_REF_Y', 'B0_MC_RecoTrack_REF_Z', 'B0_MC_RecoTrack_TYPE', 'B0_P', 'B0_PT', 'B0_PX', 'B0_PY', 'B0_PZ', 'D_ENERGY', 'D_MC_ACCT', 'D_MC_ACCTT', 'D_MC_ACCVELO', 'D_MC_HAST', 'D_MC_HASTT', 'D_MC_HASVELO', 'D_MC_RECONSTRUCTED', 'D_MC_RECONSTRUCTIBLE', 'D_MC_RecoTrack_FLAG', 'D_MC_RecoTrack_GHOSTPROB', 'D_MC_RecoTrack_HAST', 'D_MC_RecoTrack_HASUT', 'D_MC_RecoTrack_HASVELO', 'D_MC_RecoTrack_NDOF', 'D_MC_RecoTrack_NFTHITS', 'D_MC_RecoTrack_NHITS', 'D_MC_RecoTrack_NUTHITS', 'D_MC_RecoTrack_NVPHITS', 'D_MC_RecoTrack_REF_X', 'D_MC_RecoTrack_REF_Y', 'D_MC_RecoTrack_REF_Z', 'D_MC_RecoTrack_TYPE', 'D_P', 'D_PT', 'D_PX', 'D_PY', 'D_PZ', 'Kplus_ENERGY', 'Kplus_MC_ACCT', 'Kplus_MC_ACCTT', 'Kplus_MC_ACCVELO', 'Kplus_MC_HAST', 'Kplus_MC_HASTT', 'Kplus_MC_HASVELO', 'Kplus_MC_RECONSTRUCTED', 'Kplus_MC_RECONSTRUCTIBLE', 'Kplus_MC_RecoTrack_FLAG', 'Kplus_MC_RecoTrack_GHOSTPROB', 'Kplus_MC_RecoTrack_HAST', 'Kplus_MC_RecoTrack_HASUT', 'Kplus_MC_RecoTrack_HASVELO', 'Kplus_MC_RecoTrack_NDOF', 'Kplus_MC_RecoTrack_NFTHITS', 'Kplus_MC_RecoTrack_NHITS', 'Kplus_MC_RecoTrack_NUTHITS', 'Kplus_MC_RecoTrack_NVPHITS', 'Kplus_MC_RecoTrack_REF_X', 'Kplus_MC_RecoTrack_REF_Y', 'Kplus_MC_RecoTrack_REF_Z', 'Kplus_MC_RecoTrack_TYPE', 'Kplus_P', 'Kplus_PT', 'Kplus_PX', 'Kplus_PY', 'Kplus_PZ', 'pi_ENERGY', 'pi_MC_ACCT', 'pi_MC_ACCTT', 'pi_MC_ACCVELO', 'pi_MC_HAST', 'pi_MC_HASTT', 'pi_MC_HASVELO', 'pi_MC_RECONSTRUCTED', 'pi_MC_RECONSTRUCTIBLE', 'pi_MC_RecoTrack_FLAG', 'pi_MC_RecoTrack_GHOSTPROB', 'pi_MC_RecoTrack_HAST', 'pi_MC_RecoTrack_HASUT', 'pi_MC_RecoTrack_HASVELO', 'pi_MC_RecoTrack_NDOF', 'pi_MC_RecoTrack_NFTHITS', 'pi_MC_RecoTrack_NHITS', 'pi_MC_RecoTrack_NUTHITS', 'pi_MC_RecoTrack_NVPHITS', 'pi_MC_RecoTrack_REF_X', 'pi_MC_RecoTrack_REF_Y', 'pi_MC_RecoTrack_REF_Z', 'pi_MC_RecoTrack_TYPE', 'pi_P', 'pi_PT', 'pi_PX', 'pi_PY', 'pi_PZ', 'piminus_1_ENERGY', 'piminus_1_MC_ACCT', 'piminus_1_MC_ACCTT', 'piminus_1_MC_ACCVELO', 'piminus_1_MC_HAST', 'piminus_1_MC_HASTT', 'piminus_1_MC_HASVELO', 'piminus_1_MC_RECONSTRUCTED', 'piminus_1_MC_RECONSTRUCTIBLE', 'piminus_1_MC_RecoTrack_FLAG', 'piminus_1_MC_RecoTrack_GHOSTPROB', 'piminus_1_MC_RecoTrack_HAST', 'piminus_1_MC_RecoTrack_HASUT', 'piminus_1_MC_RecoTrack_HASVELO', 'piminus_1_MC_RecoTrack_NDOF', 'piminus_1_MC_RecoTrack_NFTHITS', 'piminus_1_MC_RecoTrack_NHITS', 'piminus_1_MC_RecoTrack_NUTHITS', 'piminus_1_MC_RecoTrack_NVPHITS', 'piminus_1_MC_RecoTrack_REF_X', 'piminus_1_MC_RecoTrack_REF_Y', 'piminus_1_MC_RecoTrack_REF_Z', 'piminus_1_MC_RecoTrack_TYPE', 'piminus_1_P', 'piminus_1_PT', 'piminus_1_PX', 'piminus_1_PY', 'piminus_1_PZ', 'piminus_2_ENERGY', 'piminus_2_MC_ACCT', 'piminus_2_MC_ACCTT', 'piminus_2_MC_ACCVELO', 'piminus_2_MC_HAST', 'piminus_2_MC_HASTT', 'piminus_2_MC_HASVELO', 'piminus_2_MC_RECONSTRUCTED', 'piminus_2_MC_RECONSTRUCTIBLE', 'piminus_2_MC_RecoTrack_FLAG', 'piminus_2_MC_RecoTrack_GHOSTPROB', 'piminus_2_MC_RecoTrack_HAST', 'piminus_2_MC_RecoTrack_HASUT', 'piminus_2_MC_RecoTrack_HASVELO', 'piminus_2_MC_RecoTrack_NDOF', 'piminus_2_MC_RecoTrack_NFTHITS', 'piminus_2_MC_RecoTrack_NHITS', 'piminus_2_MC_RecoTrack_NUTHITS', 'piminus_2_MC_RecoTrack_NVPHITS', 'piminus_2_MC_RecoTrack_REF_X', 'piminus_2_MC_RecoTrack_REF_Y', 'piminus_2_MC_RecoTrack_REF_Z', 'piminus_2_MC_RecoTrack_TYPE', 'piminus_2_P', 'piminus_2_PT', 'piminus_2_PX', 'piminus_2_PY', 'piminus_2_PZ'] + +#sort the expected vars +B_vars_stored = sorted(B_vars_stored) + +#open the TFile and TTree +ntuple = './DV_tuple_example-tupling-mctrack-mctuple-hlt.root' +if not os.path.isfile(ntuple): raise Exception(f"File: {ntuple} does not exist!") +f = TFile.Open(ntuple) +t_B = f.Get('DpiMC/DecayTree') + +#sort the stores vars +b_names = sorted([b.GetName() for b in t_B.GetListOfLeaves()]) + +B_excluded_1 = set(B_vars_stored) - set(b_names) +B_excluded_2 = set(b_names) - set(B_vars_stored) +if len(B_excluded_1) != 0: raise Exception('Number of stored variables is less than what is expected. The extra variables expected are: ' , B_excluded_1) +if len(B_excluded_2) != 0: raise Exception('Number of stored variables is greater than what is expected. The extra variables stored are: ', B_excluded_2) + +f.Close() +print('Test successfully completed!') +os.system(f"rm {ntuple}") +countErrorLines({"FATAL":0, "ERROR":0}) + </text></argument> +</extension> diff --git a/Phys/DaVinci/python/DaVinci/mc_track.py b/Phys/DaVinci/python/DaVinci/mc_track.py new file mode 100644 index 000000000..af1cc3abc --- /dev/null +++ b/Phys/DaVinci/python/DaVinci/mc_track.py @@ -0,0 +1,252 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### + +from Gaudi.Configuration import INFO +from Functors.grammar import BoundFunctor +from DaVinci.data_from_file import make_mc_track_info +from PyConf.components import force_location +from PyConf.Algorithms import MC2MCTrackInfoAlg, MC2TrackAlg +import Functors as F + + +class MCP2MCTrackInfo: + """ + MCP2MCTrackInfo helper class, will create all possible True TrackInfo related functors and can be + accessed as the standard python class member. + + Args: + mcparticles_input : MCParticle data handle (TES) + mc_track_info (optional) : MCTrackInfo handle (TES), default = make_mc_track_info() + process (optional) : Process type (Hlt2 or Spruce), default = 'Hlt2' + root_in_tes (optional) : Standard Gaudi Algorithm RootInTES location + output_level (optional) : Standard Gaudi Algorithm OutputLevel + + Example: + MC_TRINFO = MC_TrackInfo(MCParticles) + allvariables['HAST'] = MC_TRINFO.HasT + + """ + + # Copied definition from /LHCb/Event/MCEvent/include/Event/MCTrackInfo.h + class _Flag: + VeloR = 0x00000001 + VeloPhi = 0x00000002 + TT1 = 0x00000004 + TT2 = 0x00000008 + T1X = 0x00000010 + T1S = 0x00000020 + T2X = 0x00000040 + T2S = 0x00000080 + T3X = 0x00000100 + T3S = 0x00000200 + HasVelo = VeloR | VeloPhi + HasTT = TT1 | TT2 + HasT1 = T1X | T1S + HasT2 = T2X | T2S + HasT3 = T3X | T3S + HasT = HasT1 | HasT2 | HasT3 + HasVeloAndT = HasVelo | HasT + AccVeloR = 0x00000400 + AccVeloPhi = 0x00000800 + AccTT1 = 0x00001000 + AccTT2 = 0x00002000 + AccT1X = 0x00004000 + AccT1S = 0x00008000 + AccT2X = 0x00010000 + AccT2S = 0x00020000 + AccT3X = 0x00040000 + AccT3S = 0x00080000 + AccVelo = AccVeloR | AccVeloPhi + AccTT = AccTT1 | AccTT2 + AccT1 = AccT1X | AccT1S + AccT2 = AccT2X | AccT2S + AccT3 = AccT3X | AccT3S + AccT = AccT1 | AccT2 | AccT3 + AccVeloAndT = AccVelo | AccT + multVeloR = 20 + multVeloPhi = 25 + MultVeloR = 0x01F00000 + MultVeloPhi = 0x3E000000 + + def get_info(self, mc_property: int): + return F.MAP_INPUT( + Functor=F.MC_TRACKINFO(mc_property), Relations=self.MC2MCTrackInfo) + + def __init__(self, + mcparticles_input, + mc_track_info=make_mc_track_info(), + process='Spruce', + output_level=INFO): + + if process in ['Spruce', 'Turbo']: + raise ValueError( + "MCTrackInfo is not persisted in Spruce/Turbo at the moment, this will be fixed in the future, see: " + "https://gitlab.cern.ch/lhcb/Moore/-/issues/440") + elif process != 'Hlt2': + raise ValueError( + f"The specified 'process' {process} not recognised. Can only be 'Hlt2' or 'Spruce' or 'Turbo'." + ) + + # Load Algorithm + self.Algorithm = MC2MCTrackInfoAlg( + Input=mcparticles_input, + MCTrackInfo=mc_track_info, + OutputLevel=output_level) + + # Alias output of algorithm + self.MC2MCTrackInfo = self.Algorithm.MC2MCTrackInfo + self.MC2Reconstructible = self.Algorithm.MC2Reconstructible + + # Create functors for MC_TRACKINFO + self.VeloR = self.get_info(self._Flag.VeloR) + self.VeloPhi = self.get_info(self._Flag.VeloPhi) + self.TT1 = self.get_info(self._Flag.TT1) + self.TT2 = self.get_info(self._Flag.TT2) + self.T1X = self.get_info(self._Flag.T1X) + self.T1S = self.get_info(self._Flag.T1S) + self.T2X = self.get_info(self._Flag.T2X) + self.T2S = self.get_info(self._Flag.T2S) + self.T3X = self.get_info(self._Flag.T3X) + self.T3S = self.get_info(self._Flag.T3S) + self.HasVelo = self.get_info(self._Flag.HasVelo) + self.HasTT = self.get_info(self._Flag.HasTT) + self.HasT1 = self.get_info(self._Flag.HasT1) + self.HasT2 = self.get_info(self._Flag.HasT2) + self.HasT3 = self.get_info(self._Flag.HasT3) + self.HasT = self.get_info(self._Flag.HasT) + self.HasVeloAndT = self.get_info(self._Flag.HasVeloAndT) + self.AccVeloR = self.get_info(self._Flag.AccVeloR) + self.AccVeloPhi = self.get_info(self._Flag.AccVeloPhi) + self.AccTT1 = self.get_info(self._Flag.AccTT1) + self.AccTT2 = self.get_info(self._Flag.AccTT2) + self.AccT1X = self.get_info(self._Flag.AccT1X) + self.AccT1S = self.get_info(self._Flag.AccT1S) + self.AccT2X = self.get_info(self._Flag.AccT2X) + self.AccT2S = self.get_info(self._Flag.AccT2S) + self.AccT3X = self.get_info(self._Flag.AccT3X) + self.AccT3S = self.get_info(self._Flag.AccT3S) + self.AccVelo = self.get_info(self._Flag.AccVelo) + self.AccTT = self.get_info(self._Flag.AccTT) + self.AccT1 = self.get_info(self._Flag.AccT1) + self.AccT2 = self.get_info(self._Flag.AccT2) + self.AccT3 = self.get_info(self._Flag.AccT3) + self.AccT = self.get_info(self._Flag.AccT) + self.AccVeloAndT = self.get_info(self._Flag.AccVeloAndT) + self.multVeloR = self.get_info(self._Flag.multVeloR) + self.multVeloPhi = self.get_info(self._Flag.multVeloPhi) + self.MultVeloR = self.get_info(self._Flag.MultVeloR) + self.MultVeloPhi = self.get_info(self._Flag.MultVeloPhi) + + # UT alias + self.UT1 = self.TT1 + self.UT2 = self.TT2 + self.HasUT = self.HasTT + self.AccUT1 = self.AccTT1 + self.AccUT2 = self.AccTT2 + self.AccUT = self.AccTT + + # Create functors for MC_PROPERTY + self.Property = F.MAP_INPUT( + Functor=F.MC_PROPERTY, Relations=self.MC2MCTrackInfo) + + # Reconstructible + self.Reconstructible = F.MAP_INPUT( + Functor=F.MC_RECONSTRUCTIBLE, Relations=self.MC2Reconstructible) + + +class MCP2Track: + """ + MCP2Track helper class, will create all possible Reconstructed Track related functors and can be + accessed as the standard python class member, the member function Get(F) is a flexible + interface for future update. + + Args: + mcparticles_input : MCParticle data handle (TES) + relations_locs: TES locations to the pre-existing relations for charged and neutral particles. + default = ["Relations/ChargedPP2MCP", "Relations/NeutralPP2MCP"] + process (optional) : Process type (Hlt2 or Spruce), default = 'Hlt2' + root_in_tes (optional) : Standard Gaudi Algorithm RootInTES location + output_level (optional) : Standard Gaudi Algorithm OutputLevel + + Example: + # Create the helper + MC_TR = MC_Track(MCParticles) + + # Use predefined functor + allvariables['HAST'] = MC_TR.HasT + + # or use general interface, equivalent as above + allvariables['HAST'] = MC_TR.Get(F.TRACKHAST) + + """ + + # Flexible interface for possible update + def get_info(self, Functor: BoundFunctor): + return F.MAP_INPUT(Functor=Functor, Relations=self.MC2Track) + + def __init__(self, + mcparticles_input, + relations_locs=[ + "Relations/ChargedPP2MCP", "Relations/NeutralPP2MCP" + ], + process='Spruce', + root_in_tes=None, + output_level=INFO): + + if not root_in_tes: + if process == 'Spruce': + root_in_tes = '/Event/Spruce/HLT2' + elif process == 'Hlt2' or process == 'Turbo': + root_in_tes = '/Event/HLT2' + else: + raise ValueError( + f"The specified 'process' {process} not recognised. Can only be 'Hlt2' or 'Spruce' or 'Turbo'. Please check!" + ) + + if root_in_tes: + relations_locs = [ + f'{root_in_tes}/{table_loc}' for table_loc in relations_locs + ] + ChargedPP2MCP = force_location(relations_locs[0]) + NeutralPP2MCP = force_location(relations_locs[1]) + + # Load Algorithm + self.Algorithm = MC2TrackAlg( + Input=mcparticles_input, + ChargedPP2MCP=ChargedPP2MCP, + NeutralPP2MCP=NeutralPP2MCP, + OutputLevel=output_level) + + # Alias the outputs + self.MC2Reconstructed = self.Algorithm.MC2Reconstructed + self.MC2Track = self.Algorithm.MC2Track + + # Reconstructed + self.Reconstructed = F.MAP_INPUT( + Functor=F.MC_RECONSTRUCTED, Relations=self.MC2Reconstructed) + + # Predefined track related functor + self.ReferencePoint = self.get_info(F.REFERENCEPOINT) + self.ReferencePoint_X = self.get_info(F.REFERENCEPOINT_X) + self.ReferencePoint_Y = self.get_info(F.REFERENCEPOINT_Y) + self.ReferencePoint_Z = self.get_info(F.REFERENCEPOINT_Z) + self.nDoF = self.get_info(F.NDOF) + self.GhostProbability = self.get_info(F.GHOSTPROB) + self.Flag = self.get_info(F.TRACKFLAG) + self.Type = self.get_info(F.TRACKTYPE) + self.HasT = self.get_info(F.TRACKHAST) + self.HasUT = self.get_info(F.TRACKHASUT) + self.HasVelo = self.get_info(F.TRACKHASVELO) + self.nHits = self.get_info(F.NHITS) + self.nVPHits = self.get_info(F.NVPHITS) + self.nUTHits = self.get_info(F.NUTHITS) + self.nFTHits = self.get_info(F.NFTHITS) + self.History = self.get_info(F.TRACKHISTORY) diff --git a/Phys/DaVinci/python/DaVinci/truth_matching.py b/Phys/DaVinci/python/DaVinci/truth_matching.py index 089ae7e6f..905688f04 100644 --- a/Phys/DaVinci/python/DaVinci/truth_matching.py +++ b/Phys/DaVinci/python/DaVinci/truth_matching.py @@ -23,6 +23,7 @@ def configured_MCTruthAndBkgCatAlg( process='Spruce', root_in_tes=None, redo_neutral_assoc=False, + filter_MCP=True, output_level=INFO): """ Function to help configure the tools instantiated by the `MCTruthAndBkgCatAlg` algorithm. @@ -58,11 +59,11 @@ def configured_MCTruthAndBkgCatAlg( if not root_in_tes: if process == 'Spruce': root_in_tes = '/Event/Spruce/HLT2' - elif process == 'Hlt2': + elif process == 'Hlt2' or process == 'Turbo': root_in_tes = '/Event/HLT2' else: raise ValueError( - f"The specified 'process' {process} not recognised. Can only be 'Hlt2' or 'Spruce'. Please check!" + f"The specified 'process' {process} not recognised. Can only be 'Hlt2' or 'Spruce' or 'Turbo'. Please check!" ) # Tool used by DaVinciSmartAssociator @@ -95,6 +96,7 @@ def configured_MCTruthAndBkgCatAlg( mctruth = MCTruthAndBkgCatAlg( Input=inputs, + filter_MCP=filter_MCP, DaVinciSmartAssociator=dv_assc, MCMatchObjP2MCRelator=mcrel_assc, BackgroundCategory=bkg_cat, -- GitLab