From a5c99ffc2fed603037dd203c8db63ebbed40236d Mon Sep 17 00:00:00 2001 From: Zihan Gao <zihan.gao@cern.ch> Date: Wed, 11 Sep 2024 21:36:01 +0200 Subject: [PATCH 01/12] fix truth match and add track cov --- ...allen_mc_hlt1_pp_matching_no_ut_1000KHz.py | 6 + QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py | 29 + QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py | 39 ++ QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py | 30 + QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py | 28 + QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py | 29 + QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py | 29 + QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py | 29 + QuarkoniaToMuMu2024/helpers/dv_mctree.py | 136 +++++ QuarkoniaToMuMu2024/helpers/dv_tree.py | 511 ++++++++++++++++++ QuarkoniaToMuMu2024/info.yaml | 107 ++++ QuarkoniaToMuMu2024/moore_mc_turbo.py | 44 ++ QuarkoniaToMuMu2024/spruce_turbo.py | 53 ++ 13 files changed, 1070 insertions(+) create mode 100644 QuarkoniaToMuMu2024/allen_mc_hlt1_pp_matching_no_ut_1000KHz.py create mode 100644 QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py create mode 100644 QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py create mode 100644 QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py create mode 100644 QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py create mode 100644 QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py create mode 100644 QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py create mode 100644 QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py create mode 100644 QuarkoniaToMuMu2024/helpers/dv_mctree.py create mode 100644 QuarkoniaToMuMu2024/helpers/dv_tree.py create mode 100644 QuarkoniaToMuMu2024/info.yaml create mode 100644 QuarkoniaToMuMu2024/moore_mc_turbo.py create mode 100644 QuarkoniaToMuMu2024/spruce_turbo.py diff --git a/QuarkoniaToMuMu2024/allen_mc_hlt1_pp_matching_no_ut_1000KHz.py b/QuarkoniaToMuMu2024/allen_mc_hlt1_pp_matching_no_ut_1000KHz.py new file mode 100644 index 0000000000..affdbe1228 --- /dev/null +++ b/QuarkoniaToMuMu2024/allen_mc_hlt1_pp_matching_no_ut_1000KHz.py @@ -0,0 +1,6 @@ +from Moore import options, Options +from Moore.production import hlt1 + +def main(options: Options): + return hlt1(options, "--sequence=hlt1_pp_matching_no_ut_1000KHz", "--flagging") + diff --git a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py new file mode 100644 index 0000000000..b83f4336a1 --- /dev/null +++ b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py @@ -0,0 +1,29 @@ +import os +import sys +sys.path.append(os.path.join( + os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) +from helpers import dv_tree, dv_mctree +from DaVinci import Options, make_config + +def main(options: Options): + decay_descriptor = { + "QQbar": "J/psi(1S) -> mu+ mu-", + "mup": "J/psi(1S) -> ^mu+ mu-", + "mum": "J/psi(1S) -> mu+ ^mu-", + } + decay_descriptor_mctree = { + "QQbar": "J/psi(1S) ==> mu+ mu-", + "mup": "J/psi(1S) ==> ^mu+ mu-", + "mum": "J/psi(1S) ==> mu+ ^mu-", + } + + line_name = 'Hlt2_JpsiToMuMu' + my_filter = dv_tree.line_prefilter(line_name) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) + user_algorithms = { + 'Alg_tuple': [my_filter, my_tuple], + 'Alg_mctuple': [my_mctuple], + } + return make_config(options, user_algorithms) + diff --git a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py new file mode 100644 index 0000000000..c23b8ff27f --- /dev/null +++ b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py @@ -0,0 +1,39 @@ +import os +import sys +sys.path.append(os.path.join( + os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) +from helpers import dv_tree, dv_mctree +from DaVinci import Options, make_config + +def main(options: Options): + decay_descriptor = { + "QQbar": "J/psi(1S) -> mu+ mu-", + "mup": "J/psi(1S) -> ^mu+ mu-", + "mum": "J/psi(1S) -> mu+ ^mu-", + } + + decay_descriptor_mctree = { + "QQbar": "J/psi(1S) ==> mu+ mu-", + "mup": "J/psi(1S) ==> ^mu+ mu-", + "mum": "J/psi(1S) ==> mu+ ^mu-", + } + + + line_name0 = 'Hlt2QEE_DiMuonNoIP_massRange5' + my_tuple0 = dv_tree.tree_template(decay_descriptor, line_name0, True, []) + my_filter0 = dv_tree.line_prefilter(line_name0) + line_name1 = 'Hlt2QEE_DiMuonNoIP_massRange4' + my_tuple1 = dv_tree.tree_template(decay_descriptor, line_name1, True, []) + my_filter1 = dv_tree.line_prefilter(line_name1) + line_name2 = 'Hlt2QEE_DiMuonNoIP_massRange3' + my_tuple2 = dv_tree.tree_template(decay_descriptor, line_name2, True, []) + my_filter2 = dv_tree.line_prefilter(line_name2) + my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) + user_algorithms = { + "Alg_massRange5": [my_filter0, my_tuple0], + "Alg_massRange4": [my_filter1, my_tuple1], + "Alg_massRange3": [my_filter2, my_tuple2], + 'Alg_mctuple': [my_mctuple], + } + return make_config(options, user_algorithms) + diff --git a/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py b/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py new file mode 100644 index 0000000000..e779f100ba --- /dev/null +++ b/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py @@ -0,0 +1,30 @@ +import os +import sys +sys.path.append(os.path.join( + os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) +from helpers import dv_tree, dv_mctree +from DaVinci import Options, make_config + +def main(options: Options): + decay_descriptor = { + "QQbar": "psi(2S) -> mu+ mu-", + "mup": "psi(2S) -> ^mu+ mu-", + "mum": "psi(2S) -> mu+ ^mu-", + } + + decay_descriptor_mctree = { + "QQbar": "psi(2S) ==> mu+ mu-", + "mup": "psi(2S) ==> ^mu+ mu-", + "mum": "psi(2S) ==> mu+ ^mu-", + } + + line_name = 'Hlt2_Psi2SToMuMu' + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_filter = dv_tree.line_prefilter(line_name) + my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) + user_algorithms = { + 'Alg_tuple': [my_filter, my_tuple], + 'Alg_mctuple': [my_mctuple], + } + return make_config(options, user_algorithms) + diff --git a/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py b/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py new file mode 100644 index 0000000000..c662b904e3 --- /dev/null +++ b/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py @@ -0,0 +1,28 @@ +import os +import sys +sys.path.append(os.path.join( + os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) +from helpers import dv_tree, dv_mctree +from DaVinci import Options, make_config + +def main(options: Options): + decay_descriptor = { + "QQbar": "J/psi(1S) -> mu+ mu-", + "mup": "J/psi(1S) -> ^mu+ mu-", + "mum": "J/psi(1S) -> mu+ ^mu-", + } + decay_descriptor_mctree = { + "QQbar": "psi(2S) ==> mu+ mu-", + "mup": "psi(2S) ==> ^mu+ mu-", + "mum": "psi(2S) ==> mu+ ^mu-", + } + + line_name = 'Hlt2QEE_DiMuonNoIP_massRange5' + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_filter = dv_tree.line_prefilter(line_name) + my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) + user_algorithms = { + 'Alg_tuple': [my_filter, my_tuple], + 'Alg_mctuple': [my_mctuple], + } + return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py new file mode 100644 index 0000000000..69ae7b831f --- /dev/null +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py @@ -0,0 +1,29 @@ +import os +import sys +sys.path.append(os.path.join( + os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) +from helpers import dv_tree, dv_mctree +from DaVinci import Options, make_config + +def main(options: Options): + decay_descriptor = { + "QQbar": "Upsilon(1S) -> mu+ mu-", + "mup": "Upsilon(1S) -> ^mu+ mu-", + "mum": "Upsilon(1S) -> mu+ ^mu-", + } + decay_descriptor_mctree = { + "QQbar": "Upsilon(1S) ==> mu+ mu-", + "mup": "Upsilon(1S) ==> ^mu+ mu-", + "mum": "Upsilon(1S) ==> mu+ ^mu-", + } + + line_name = 'Hlt2BandQ_UpsilonToMuMuEMTF' + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_filter = dv_tree.line_prefilter(line_name) + + my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) + user_algorithms = { + 'Alg_tuple': [my_filter, my_tuple], + 'Alg_mctuple': [my_mctuple], + } + return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py new file mode 100644 index 0000000000..0212d0d8a4 --- /dev/null +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py @@ -0,0 +1,29 @@ +import os +import sys +sys.path.append(os.path.join( + os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) +from helpers import dv_tree, dv_mctree +from DaVinci import Options, make_config + +def main(options: Options): + decay_descriptor = { + "QQbar": "Upsilon(1S) -> mu+ mu-", + "mup": "Upsilon(1S) -> ^mu+ mu-", + "mum": "Upsilon(1S) -> mu+ ^mu-", + } + decay_descriptor_mctree = { + "QQbar": "Upsilon(2S) ==> mu+ mu-", + "mup": "Upsilon(2S) ==> ^mu+ mu-", + "mum": "Upsilon(2S) ==> mu+ ^mu-", + } + + line_name = 'Hlt2BandQ_UpsilonToMuMuEMTF' + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_filter = dv_tree.line_prefilter(line_name) + + my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) + user_algorithms = { + 'Alg_tuple': [my_filter, my_tuple], + 'Alg_mctuple': [my_mctuple], + } + return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py new file mode 100644 index 0000000000..4c2b84a3f0 --- /dev/null +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py @@ -0,0 +1,29 @@ +import os +import sys +sys.path.append(os.path.join( + os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) +from helpers import dv_tree, dv_mctree +from DaVinci import Options, make_config + +def main(options: Options): + decay_descriptor = { + "QQbar": "Upsilon(1S) -> mu+ mu-", + "mup": "Upsilon(1S) -> ^mu+ mu-", + "mum": "Upsilon(1S) -> mu+ ^mu-", + } + decay_descriptor_mctree = { + "QQbar": "Upsilon(3S) ==> mu+ mu-", + "mup": "Upsilon(3S) ==> ^mu+ mu-", + "mum": "Upsilon(3S) ==> mu+ ^mu-", + } + + line_name = 'Hlt2BandQ_UpsilonToMuMuEMTF' + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_filter = dv_tree.line_prefilter(line_name) + + my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) + user_algorithms = { + 'Alg_tuple': [my_filter, my_tuple], + 'Alg_mctuple': [my_mctuple], + } + return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/helpers/dv_mctree.py b/QuarkoniaToMuMu2024/helpers/dv_mctree.py new file mode 100644 index 0000000000..2eaeb70d25 --- /dev/null +++ b/QuarkoniaToMuMu2024/helpers/dv_mctree.py @@ -0,0 +1,136 @@ +############################################################################### +# (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. # +############################################################################### +""" +Read and process a .xgen file with the new DaVinci configuration. +rst_title: Run on XGEN files +rst_description: This example reads and process a `.xgen` file. +rst_running: lbexec DaVinciExamples.tupling.option_davinci_tupling_from_xgen:main $DAVINCIEXAMPLESROOT/example_data/Gauss_12143001_xgen.yaml +rst_yaml: ../DaVinciExamples/example_data/Gauss_12143001_xgen.yaml +""" +import Functors as F +import FunTuple.functorcollections as FC +from FunTuple import FunctorCollection, FunTuple_MCParticles as FuntupleMC +from PyConf.reading import get_particles, get_pvs, get_rec_summary +from PyConf.Algorithms import PrintMCTree +from DaVinci import Options, make_config +from DaVinci.algorithms import create_lines_filter +from DaVinciMCTools import MCTruthAndBkgCat +from FunTuple.functorcollections import MCHierarchy, MCPrimaries, MCPromptDecay, Kinematics, SelectionInfo, HltTisTos, MCVertexInfo, MCKinematics, ParticleID, EventInfo +from PyConf.reading import get_mc_particles, get_mc_header +from PyConf.reading import get_odin # get_decreports, +from DecayTreeFitter import DecayTreeFitter + +def mctree_template(fields): + # FunTuple: define fields (branches) + #fields = { + # "QQbar": "J/psi(1S) ==> mu+ mu-", + # "mup": "J/psi(1S) ==> ^mu+ mu-", + # "mum": "J/psi(1S) ==> mu+ ^mu-", + #} + + # FunTuple: define input data + QQbar2mumu_line = get_mc_particles("/Event/HLT2/MC/Particles") + + pvs = get_pvs() + + #define event level variables + odin = get_odin() + rec_sum=get_rec_summary() + + event_info = FunctorCollection({ + "nPVs": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nPVs"), + "nTTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTTracks"), + "nLongTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nLongTracks"), + "nDownstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nDownstreamTracks"), + "nUpstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUpstreamTracks"), + "nVeloTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloTracks"), + "nBackTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nBackTracks"), + #"nGhosts": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nGhosts"), + "nRich1Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich1Hits"), + "nRich2Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich2Hits"), + #"nVeloClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloClusters"), + "nVPClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVPClusters"), + #"nITClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nITClusters"), + #"nTTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTTClusters"), + #"nUTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUTClusters"), + #"nOTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nOTClusters"), + "nFTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nFTClusters"), + #"nSPDhits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nSPDhits"), + "eCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"eCalTot"), + "hCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"hCalTot"), + "nEcalClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nEcalClusters"), + #"nMuonCoordsS0": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS0"), + #"nMuonCoordsS1": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS1"), + #"nMuonCoordsS2": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS2"), + #"nMuonCoordsS3": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS3"), + #"nMuonCoordsS4": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS4"), + #"nMuonTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonTracks"), + }) + + # FunTuple: define variables for the J/psi + composite_variables = FunctorCollection( + { + "ETA": F.ETA, + "PHI": F.PHI, + "TAU": F.MC_LIFETIME, + "ORIGIN_VX": F.ORIGIN_VX, + "ORIGIN_VY": F.ORIGIN_VY, + "ORIGIN_VZ": F.ORIGIN_VZ, + "END_VX": F.END_VX, + "END_VY": F.END_VY, + "END_VZ": F.END_VZ, + "M": F.MASS, + "FOURMOMENTUM": F.FOURMOMENTUM, + "PT": F.PT, + } + ) + + # FunTuple: define variables for the muon + basic_variables = FunctorCollection( + { + "ETA": F.ETA, + "PHI": F.PHI, + "ORIGIN_VX": F.ORIGIN_VX, + "ORIGIN_VY": F.ORIGIN_VY, + "ORIGIN_VZ": F.ORIGIN_VZ, + "M": F.MASS, + "FOURMOMENTUM": F.FOURMOMENTUM, + "PT": F.PT, + } + ) + + # FunTuple: associate functor collections to field (branch) name + variables = { + "QQbar": composite_variables + FC.Kinematics(), + "mup": basic_variables + FC.Kinematics(), + "mum": basic_variables + FC.Kinematics(), + } + + # FunTuple: define event-level variables using functor collections + mc_header = get_mc_header(extra_inputs=[QQbar2mumu_line]) + evt_vars = event_info + #evt_vars = FC.MCPrimaries(mc_header=mc_header) + event_info + + #printMC = PrintMCTree( + # MCParticles=QQbar2mumu_line, ParticleNames=["J/psi(1S)"], OutputLevel=4 + #) + + tuple_QQbar2mumu = FuntupleMC( + name="MCDecayTreeTuple", + tuple_name="MCDecayTree", + fields=fields, + variables=variables, + event_variables=evt_vars, + inputs=QQbar2mumu_line, + ) + + return tuple_QQbar2mumu + diff --git a/QuarkoniaToMuMu2024/helpers/dv_tree.py b/QuarkoniaToMuMu2024/helpers/dv_tree.py new file mode 100644 index 0000000000..3e0b84bbd6 --- /dev/null +++ b/QuarkoniaToMuMu2024/helpers/dv_tree.py @@ -0,0 +1,511 @@ +############################################################################### +# (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. # +############################################################################### +""" +Read an HLT2 file and create an ntuple with the new DaVinci configuration. +""" +import Functors as F +import FunTuple.functorcollections as FC +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.reading import get_particles, get_pvs, get_rec_summary +from DaVinci.algorithms import create_lines_filter +from DaVinciMCTools import MCTruthAndBkgCat +from FunTuple.functorcollections import MCHierarchy, MCPrimaries, MCPromptDecay, Kinematics, SelectionInfo, HltTisTos, MCVertexInfo, MCKinematics, ParticleID, EventInfo +from PyConf.reading import get_odin # get_decreports, +from DecayTreeFitter import DecayTreeFitter + +_basic = "basic" +_composite = "composite" +_toplevel = "toplevel" + +#def all_variables(pvs, dtf, mctruth, ptype, candidates=None, ftAlg=None): +def all_variables(pvs, mctruth, ptype, candidates=None, ftAlg=None): + """ + function that returns dictionary of functors that work. + + functors are listed in order of https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors_reference.html#module-Functo + """ + if ptype not in [_basic, _composite]: + Exception(f"I want {_basic} or {_composite}. Got {ptype}") + all_vars = FunctorCollection({}) + + comp = _composite == ptype or _toplevel == ptype # is composite + basic = _basic == ptype # is not composite + top = _toplevel == ptype # the B + + # First import everything that comes in functorcollections + all_vars += FC.Kinematics() + if basic: + all_vars += FC.ParticleID(extra_info=True) + all_vars += FC.MCKinematics(mctruth_alg=mctruth) + all_vars += FC.MCHierarchy(mctruth_alg=mctruth) + #all_vars += FC.MCPrimaryVertexInfo(mctruth_alg=mctruth) + #Hlt1_decisions = ["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"] + #if candidates: + #all_vars += FC.HltTisTos( + #selection_type="Hlt", trigger_lines=Hlt1_decisions, data=candidates + #) + #if comp: + # all_vars += FC.MCVertexInfo(mctruth_alg=mctruth) + #if top: + # all_vars += FC.MCPromptDecay(mctruth_alg=mctruth) + + # + # FTAlg not yet implemented + # For Track isolation see weightedrelations_trackvariables + # + # Now all other functors + + # ALL : Not useful for tupling + + if comp: + all_vars.update({"ALV": F.ALV(Child1=1, Child2=2)}) + + all_vars.update({"BKGCAT": mctruth.BkgCat}) + + if comp: # all these require a vertex + all_vars.update({"BPVCORRM": F.BPVCORRM(pvs)}) + all_vars.update({"BPVCORRMERR": F.BPVCORRMERR(pvs)}) + all_vars.update({"BPVDIRA": F.BPVDIRA(pvs)}) + all_vars.update({"BPVDLS": F.BPVDLS(pvs)}) + all_vars.update({"BPVETA": F.BPVETA(pvs)}) + all_vars.update({"BPVFD": F.BPVFD(pvs)}) + all_vars.update({"BPVFDCHI2": F.BPVFDCHI2(pvs)}) + all_vars.update({"BPVFDIR": F.BPVFDIR(pvs)}) + all_vars.update({"BPVFDVEC": F.BPVFDVEC(pvs)}) + + all_vars.update({"BPVIP": F.BPVIP(pvs)}) + all_vars.update({"BPVIPCHI2": F.BPVIPCHI2(pvs)}) + all_vars.update({"BPVX": F.BPVX(pvs)}) + all_vars.update({"BPVY": F.BPVY(pvs)}) + all_vars.update({"BPVZ": F.BPVZ(pvs)}) + # When storing variable length array one can + # give a custom branch name for the index. + # This can be achieved by enclosing custom index + # name within square brackets (see code below). + # The branch name ("nPV") will correspond to the + # index of the PV. If no index branch name given i.e. + # all_vars.update({ 'ALLPVX'] the default "indx" is used. + #all_vars.update({"ALLPVX[nPVs]": F.ALLPVX(pvs)}) + #all_vars.update({"ALLPVY[nPVs]": F.ALLPVY(pvs)}) + #all_vars.update({"ALLPVZ[nPVs]": F.ALLPVZ(pvs)}) + all_vars.update({"ALLPVX": F.ALLPVX(pvs)}) + all_vars.update({"ALLPVY": F.ALLPVY(pvs)}) + all_vars.update({"ALLPVZ": F.ALLPVZ(pvs)}) + + if comp: # all these require a vertex + #all_vars.update({"ALLPV_FD[nPVs]": F.ALLPV_FD(pvs)}) + #all_vars.update({"ALLPV_IP[nPVs]": F.ALLPV_IP(pvs)}) + all_vars.update({"ALLPV_FD": F.ALLPV_FD(pvs)}) + all_vars.update({"ALLPV_IP": F.ALLPV_IP(pvs)}) + all_vars.update({"BPVLTIME": F.BPVLTIME(pvs)}) + all_vars.update({"BPVVDRHO": F.BPVVDRHO(pvs)}) + all_vars.update({"BPVVDX": F.BPVVDX(pvs)}) + all_vars.update({"BPVVDY": F.BPVVDY(pvs)}) + all_vars.update({"BPVVDZ": F.BPVVDZ(pvs)}) + + all_vars.update({"CHARGE": F.CHARGE}) + all_vars.update({"CHI2": F.CHI2}) + all_vars.update({"CHI2DOF": F.CHI2DOF}) + if top: # apply this only to B + all_vars.update({"CHILD1_PT": F.CHILD(1, F.PT)}) # example of CHILD + all_vars.update({"Ds_END_VZ": F.CHILD(1, F.END_VZ)}) + all_vars.update({"Delta_END_VZ_DsB0": F.CHILD(1, F.END_VZ) - F.END_VZ}) + + # if basic: all_vars.update({ 'CLOSESTTOBEAM' : F.CLOSESTTOBEAM # 'Track__ClosestToBeamState' object has no attribute 'to_json' + # COMB + # if basic: all_vars.update({ 'COV' : F.COV # 'Track__Covariance' object has no attribute 'to_json' + + if comp: + all_vars.update({"DOCA": F.SDOCA(Child1=1, Child2=2)}) + all_vars.update({"DOCACHI2": F.SDOCACHI2(Child1=1, Child2=2)}) + all_vars.update({"END_VRHO": F.END_VRHO}) + all_vars.update({"END_VX": F.END_VX}) + all_vars.update({"END_VY": F.END_VY}) + all_vars.update({"END_VZ": F.END_VZ}) + + # duplicated from FC all_vars.update({"ENERGY" : F.ENERGY}) + all_vars.update({"ETA": F.ETA}) + all_vars.update({"FOURMOMENTUM": F.FOURMOMENTUM}) + all_vars.update({"ISBASIC": F.ISBASICPARTICLE}) + + if basic: + all_vars.update({"GHOSTPROB": F.GHOSTPROB}) + all_vars.update({"ISMUON": F.ISMUON}) + all_vars.update({"INMUON": F.INMUON}) + all_vars.update({"INECAL": F.INECAL}) + all_vars.update({"INHCAL": F.INHCAL}) + all_vars.update({"HASBREM": F.HASBREM}) + all_vars.update({"BREMENERGY": F.BREMENERGY}) + all_vars.update({"BREMBENDCORR": F.BREMBENDCORR}) + all_vars.update({"BREMPIDE": F.BREMPIDE}) + all_vars.update({"ECALPIDE": F.ECALPIDE}) + all_vars.update({"ECALPIDMU": F.ECALPIDMU}) + all_vars.update({"HCALPIDE": F.HCALPIDE}) + all_vars.update({"HCALPIDMU": F.HCALPIDMU}) + all_vars.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + all_vars.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + all_vars.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + all_vars.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + all_vars.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + all_vars.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + all_vars.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + all_vars.update({"ELECTRONID": F.ELECTRONID}) + all_vars.update({"HCALEOP": F.HCALEOP}) + # Note: the observables for the two functors below are (TRACK_MOM_X, TRACK_MOM_Y, TRACK_MOM_Z}) + # and (TRACK_POS_CLOSEST_TO_BEAM_X, TRACK_POS_CLOSEST_TO_BEAM_Y, TRACK_POS_CLOSEST_TO_BEAM_Z), + # which is why the trailing underscore in the name is added i.e. "TRACK_MOM_" and "TRACK_POS_CLOSEST_TO_BEAM_" + all_vars.update({"TRACK_MOM_": F.TRACK_MOMVEC}) + all_vars.update({"TRACK_POS_CLOSESTTOBEAM_": F.TRACK_POSVEC_CLOSESTTOBEAM}) + + all_vars.update({"IS_ABS_ID_pi": F.IS_ABS_ID("pi+")}) + all_vars.update({"IS_ID_pi": F.IS_ID("pi-")}) + all_vars.update({"PDG_MASS_pi": F.PDG_MASS("pi+")}) + all_vars.update({"SIGNED_DELTA_MASS_pi": F.SIGNED_DELTA_MASS("pi+")}) + all_vars.update({"ABS_DELTA_MASS_pi": F.ABS_DELTA_MASS("pi+")}) + all_vars.update({"IS_NOT_H": F.IS_NOT_H}) + all_vars.update({"IS_PHOTON": F.IS_PHOTON}) + + #if dtf: + # all_vars.update({"DTF_PT": dtf(F.PT)}) + # all_vars.update({"DTF_BPVIPCHI2": dtf(F.BPVIPCHI2(pvs))}) + + #if top and dtf: + # all_vars.update({"DTF_NITER": dtf.NITER}) + # all_vars.update({"DTF_CHI2": dtf.CHI2}) + # all_vars.update({"DTF_NDOF": dtf.NDOF}) + # all_vars.update({"DTF_CHI2DOF": dtf.CHI2DOF}) + + #if comp and dtf: + # all_vars.update({"DTF_MASS": dtf.MASS}) + # all_vars.update({"DTF_MASSERR": dtf.MASSERR}) + # all_vars.update({"DTF_P": dtf.P}) + # all_vars.update({"DTF_PERR": dtf.PERR}) + # all_vars.update({"DTF_TAU": dtf.TAU}) + # all_vars.update({"DTF_TAUERR": dtf.TAUERR}) + # all_vars.update({"DTF_FD": dtf.FD}) + # all_vars.update({"DTF_FDERR": dtf.FDERR}) + + all_vars.update({"MASS": F.MASS}) + #if top: # B + # all_vars.update({"MASSWITHHYPOTHESES": F.MASSWITHHYPOTHESES((939.0, 939.0))}) + #elif comp: # Ds + # all_vars.update( + # {"MASSWITHHYPOTHESES": F.MASSWITHHYPOTHESES((493.7, 493.7, 139.6))} + # ) + if comp: + all_vars.update({"MAXPT": F.MAX(F.PT)}) + all_vars.update({"MAXDOCA": F.MAXSDOCA}) + all_vars.update({"MAXDOCACHI2": F.MAXSDOCACHI2}) + # the above in cut versions. + + # duplicated from FC all_vars.update({ 'MC_MOTHER_ID' : F.VALUE_OR(0) @ mctruth( + # duplicated from FC F.MC_MOTHER(1, F.PARTICLE_ID))}) + + if comp: + all_vars.update({"MINPT": F.MIN(F.PT)}) + all_vars.update({"MINIP": F.MINIP(pvs)}) + all_vars.update({"MINIPCHI2": F.MINIPCHI2(pvs)}) + + if basic: + all_vars.update({"TRACKPT": F.TRACK_PT}) + all_vars.update({"TRACKHISTORY": F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK}) + all_vars.update({"QOVERP": F.QOVERP @ F.TRACK}) + all_vars.update({"NDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK}) + all_vars.update({"NFTHITS": F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK}) + all_vars.update({"NHITS": F.VALUE_OR(-1) @ F.NHITS @ F.TRACK}) + all_vars.update({"NUTHITS": F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK}) + all_vars.update({"NVPHITS": F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK}) + all_vars.update({"TRACKHASVELO": F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK}) + all_vars.update({"TRACKHASUT": F.VALUE_OR(-1) @ F.TRACKHASUT @ F.TRACK}) + + all_vars.update({"OBJECT_KEY": F.OBJECT_KEY}) + + # duplicated from FC all_vars.update({ 'ORIGIN_VX' : mctruth(F.ORIGIN_VX) }) + # duplicated from FC all_vars.update({ 'ORIGIN_VY' : mctruth(F.ORIGIN_VY) }) + # duplicated from FC all_vars.update({ 'ORIGIN_VZ' : mctruth(F.ORIGIN_VZ) }) + + # duplicated from FC all_vars.update({"P" : F.P}) + # duplicated from FC all_vars.update({"PARTICLE_ID" : F.PARTICLE_ID}) + all_vars.update({"PHI": F.PHI}) + + # duplicated from FC if basic: + # duplicated from FC all_vars.update({"PID_E" : F.PID_E}) + # duplicated from FC all_vars.update({"PID_K" : F.PID_K}) + # duplicated from FC all_vars.update({"PID_MU" : F.PID_MU}) + # duplicated from FC all_vars.update({"PID_P" : F.PID_P}) + # duplicated from FC all_vars.update({"PID_PI" : F.PID_PI}) + # duplicated from FC #all_vars.update({"PROBNN_D" : F.PROBNN_D}) + # duplicated from FC all_vars.update({"PROBNN_E" : F.PROBNN_E}) + # duplicated from FC all_vars.update({"PROBNN_GHOST" : F.PROBNN_GHOST}) + # duplicated from FC all_vars.update({"PROBNN_K" : F.PROBNN_K}) + # duplicated from FC all_vars.update({"PROBNN_MU" : F.PROBNN_MU}) + # duplicated from FC all_vars.update({"PROBNN_P" : F.PROBNN_P}) + # duplicated from FC all_vars.update({"PROBNN_PI" : F.PROBNN_PI}) + + # duplicated from FC all_vars.update({ 'PT' : F.PT }) + # duplicated from FC all_vars.update({ 'PX' : F.PX }) + # duplicated from FC all_vars.update({ 'PY' : F.PY }) + # duplicated from FC all_vars.update({ 'PZ' : F.PZ }) + all_vars.update({"ABS_PX": F.ABS @ F.PX}) + + all_vars.update({"REFERENCEPOINT_X": F.REFERENCEPOINT_X}) + all_vars.update({"REFERENCEPOINT_Y": F.REFERENCEPOINT_Y}) + all_vars.update({"REFERENCEPOINT_Z": F.REFERENCEPOINT_Z}) + + if comp: + all_vars.update({"SDOCA": F.SDOCA(1, 2)}) + all_vars.update({"SDOCACHI2": F.SDOCACHI2(1, 2)}) + if basic: + all_vars.update({"SHOWER_SHAPE": F.CALO_NEUTRAL_SHOWER_SHAPE}) + + if comp: + all_vars.update({"SUBCOMB12_MM": F.SUBCOMB(Functor=F.MASS, Indices=(1, 2))}) + all_vars.update({"SUMPT": F.SUM(F.PT)}) + + if basic: + all_vars.update({"TX": F.TX}) + all_vars.update({"TY": F.TY}) + + print(f"### For {ptype} returning variables {all_vars.functor_dict.keys()}") + return all_vars + + +def event_variables(PVs, ODIN, decreports, lines, hlt1lines): + """ + event variables + """ + + evt_vars = FunctorCollection({}) + evt_vars += FC.EventInfo() + + evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=lines) + evt_vars += FC.SelectionInfo(selection_type="Hlt1", trigger_lines=hlt1lines) + # duplicated from FC if ODIN: + # duplicated from FC evt_vars.update({ 'BUNCHCROSSING_ID' : F.BUNCHCROSSING_ID(ODIN) }) + # duplicated from FC evt_vars.update({ 'BUNCHCROSSING_TYPE' : F.BUNCHCROSSING_TYPE(ODIN) }) + + if decreports: + evt_vars.update( + { + "DECISIONS": F.DECISIONS( + Lines=[bd2dsk_line + "Decision"], DecReports=decreports + ) + } + ) + evt_vars.update( + { + "DECREPORTS_FILTER": F.DECREPORTS_FILTER( + Lines=[bd2dsk_line + "Decision"], DecReports=decreports + ) + } + ) + + if ODIN: + evt_vars.update({"EVENTTYPE": F.EVENTTYPE(ODIN)}) + + # duplicated from FC evt_vars.update({ 'GPSTIME' : F.GPSTIME(ODIN) }) + # duplicated from FC evt_vars.update({ 'ODINTCK' : F.ODINTCK(ODIN) }) + + evt_vars.update({"PV_SIZE": F.SIZE(PVs)}) + # duplicated from FC evt_vars.update({ 'GPSTIME' : F.GPSTIME(ODIN) }) + # duplicated from FC evt_vars.update({ 'ODINTCK' : F.ODINTCK(ODIN) }) + + if decreports: + evt_vars.update({"TCK": F.TCK(decreports)}) + + print(f"### For event returning variables {evt_vars.functor_dict.keys()}") + return evt_vars + + +def tree_template(decay_descriptor, line_name, isturbo, Hlt2_decisions): + evtpath_prefix = "/Event/Spruce/" + if isturbo: + evtpath_prefix = "/Event/HLT2/" + + QQbar2mumu_data = get_particles(evtpath_prefix+f"{line_name}/Particles") + + pvs = get_pvs() + + Hlt1_decisions = [ +# Global line + "Hlt1GlobalDecision", "Hlt1PhysDecision", +# Physics lines + "Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision", "Hlt1D2KKDecision", "Hlt1D2KPiDecision", "Hlt1D2PiPiDecision", "Hlt1Dst2D0PiDecision", "Hlt1KsToPiPiDecision", "Hlt1KsToPiPiDoubleMuonMisIDDecision", "Hlt1TwoTrackKsDecision", "Hlt1TwoKsDecision", "Hlt1LambdaLLDetachedTrackDecision", "Hlt1XiOmegaLLLDecision", "Hlt1SingleHighPtMuonDecision", "Hlt1SingleHighPtMuonNoMuIDDecision", "Hlt1DiMuonHighMassDecision", "Hlt1DiMuonDisplacedDecision", "Hlt1DiMuonSoftDecision", "Hlt1TrackMuonMVADecision", "Hlt1DiMuonNoIP_SSDecision", "Hlt1DiMuonDrellYan_VLowMassDecision", "Hlt1DiMuonDrellYan_VLowMass_SSDecision", "Hlt1DiMuonDrellYanDecision", "Hlt1DiMuonDrellYan_SSDecision", "Hlt1DetJpsiToMuMuPosTagLineDecision", "Hlt1DetJpsiToMuMuNegTagLineDecision", "Hlt1TrackElectronMVADecision", "Hlt1SingleHighPtElectronDecision", "Hlt1DiElectronDisplacedDecision", "Hlt1SingleHighEtDecision", "Hlt1DiPhotonHighMassDecision", "Hlt1Pi02GammaGammaDecision", "Hlt1DiElectronHighMass_SSDecision", "Hlt1DiElectronHighMassDecision", "Hlt1DiMuonNoIPDecision" +## alignment lines +# "Hlt1RICH1AlignmentDecision", "Hlt1RICH2AlignmentDecision", "Hlt1D2KPiAlignmentDecision", "Hlt1Dst2D0PiAlignmentDecision", "Hlt1MaterialVertexSeedsDownstreamzDecision", "Hlt1MaterialVertexSeeds_DWFSDecision", "Hlt1DiMuonHighMassAlignmentDecision", "Hlt1DiMuonJpsiMassAlignmentDecision", "Hlt1OneMuonTrackLineDecision", "Hlt1BeamGasDecision", +## smog2 lines +# "Hlt1SMOG2D2KpiDecision", "Hlt1VeloMicroBiasDecision", "Hlt1SMOG2etacToppDecision", "Hlt1SMOG2KsTopipiDecision", "Hlt1SMOG2etacToppDecision", "Hlt1SMOG2KsTopipiDecision", "Hlt1SMOG22BodyGenericDecision", "Hlt1SMOG22BodyGenericLowPtDecision", "Hlt1SMOG2SingleTrackVeryHighPtDecision", "Hlt1SMOG2SingleTrackHighPtDecision", "Hlt1SMOG2DiMuonHighMassDecision", "Hlt1SMOG2SingleMuonDecision", "Hlt1SMOG2L0ToppiDecision", +## bgi lines +# "Hlt1BGIPseudoPVsNoBeamDecision", "Hlt1BGIPseudoPVsBeamOneDecision", "Hlt1BGIPseudoPVsBeamTwoDecision", "Hlt1BGIPseudoPVsUpBeamBeamDecision", "Hlt1BGIPseudoPVsDownBeamBeamDecision", "Hlt1BGIPseudoPVsIRBeamBeamDecision", "Hlt1BGIPVsCylNoBeamDecision", "Hlt1BGIPVsCylBeamOneDecision", "Hlt1BGIPVsCylBeamTwoDecision", "Hlt1BGIPVsCylUpBeamBeamDecision", "Hlt1BGIPVsCylDownBeamBeamDecision", "Hlt1BGIPVsCylIRBeamBeamDecision", "Hlt1BGIVeloClustersMicroBiasDecision", "Hlt1BGICaloDigitsDecision", "Hlt1BGIPlumeActivityDecision", +## setup hlt1 nodes lines +# "Hlt1ODINCalibDecision", "Hlt1TAEPassthroughDecision", "Hlt1ErrorBankDecision", "Hlt1VeloMicroBiasVeloClosingDecision", "Hlt1GECPassthroughDecision", "Hlt1SMOG2BENoBiasDecision", "Hlt1SMOG2PassThroughLowMult5Decision", "Hlt1SMOG2BELowMultElectronsDecision", "Hlt1SMOG2MinimumBiasDecision", "Hlt1PassthroughPVinSMOG2Decision" + ] + + + composite_variables = FunctorCollection({ + #"ID": F.PARTICLE_ID, + #"KEY": F.OBJECT_KEY, + #"PT": F.PT, + #"PX": F.PX, + #"PY": F.PY, + #"PZ": F.PZ, + #"ENERGY": F.ENERGY, + #"P": F.P, + #"M": F.MASS, + #"ETA": F.ETA, + #"PHI": F.PHI, + #"ENDVERTEX_CHI2NDOF": F.CHI2DOF, + #"FOURMOMENTUM": F.FOURMOMENTUM, + #"BPVDIRA": F.BPVDIRA(pvs), + #"BPVX": F.BPVX(pvs), + #"BPVY": F.BPVY(pvs), + #"BPVZ": F.BPVZ(pvs), + #"END_VX": F.END_VX, + #"END_VY": F.END_VY, + #"END_VZ": F.END_VZ, + "END_VZ_ERR":F.SQRT @ F.CALL(2,2) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "END_VY_ERR":F.SQRT @ F.CALL(1,1) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "END_VX_ERR":F.SQRT @ F.CALL(0,0) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "BPVZ_ERR": F.SQRT @ F.CALL(2,2) @ F.POS_COV_MATRIX @ F.BPV(pvs), + "BPVY_ERR": F.SQRT @ F.CALL(1,1) @ F.POS_COV_MATRIX @ F.BPV(pvs), + "BPVX_ERR": F.SQRT @ F.CALL(0,0) @ F.POS_COV_MATRIX @ F.BPV(pvs), + #"TAU": F.BPVLTIME(pvs), + #"BPVFDCHI2": F.BPVFDCHI2(pvs), + #"BPVIPCHI2": F.BPVIPCHI2(pvs) + }) + + #composite_variables += Kinematics() + #composite_variables += ParticleID(extra_info=True) + composite_variables += HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=QQbar2mumu_data) + if not isturbo: + composite_variables += HltTisTos( selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=QQbar2mumu_data) + + daughter_variables = FunctorCollection({ + #"ID": F.PARTICLE_ID, + #"PT": F.PT, + #"PX": F.PX, + #"PY": F.PY, + #"PZ": F.PZ, + #"M": F.MASS, + #"ENERGY": F.ENERGY, + #"P": F.P, + #"ETA": F.ETA, + #"PHI": F.PHI, + #"Track_CHI2NDOF": F.CHI2DOF, + #"ProbNNmu": F.PROBNN_MU, + #"PIDmu": F.PID_MU, + #"IsMuon": F.ISMUON, + #"GhostProb": F.GHOSTPROB, + #"FOURMOMENTUM": F.FOURMOMENTUM, + "PERR": F.SQRT @ F.PERR2, + "PZERR": F.SQRT @ F.CALL(2,2) @ F.THREE_MOM_COV_MATRIX, + "TXERR": F.SQRT @ F.CALL(2,2) @ F.TRACK_COVARIANCE @ F.STATE_AT("FirstMeasurement")@ F.TRACK, + "TYERR": F.SQRT @ F.CALL(3,3) @ F.TRACK_COVARIANCE @ F.STATE_AT("FirstMeasurement")@ F.TRACK, + "COVTXTY": F.CALL(2,3) @ F.TRACK_COVARIANCE @ F.STATE_AT("FirstMeasurement")@ F.TRACK, + }) + + #daughter_variables += Kinematics() + #daughter_variables += ParticleID(extra_info=True) + +# line_prefilter = create_lines_filter(name=f"HLT_PASS{line_name}", lines=[line_name]) + + #define event level variables + odin = get_odin() + decreports = None + rec_sum=get_rec_summary() + event_info = event_variables(pvs, odin, decreports, [line_name], Hlt1_decisions) + FunctorCollection({ + "nPVs": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nPVs"), + "nTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTracks"), + "nLongTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nLongTracks"), + "nDownstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nDownstreamTracks"), + "nUpstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUpstreamTracks"), + "nVeloTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloTracks"), + "nBackTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nBackTracks"), + "nGhosts": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nGhosts"), + "nRich1Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich1Hits"), + "nRich2Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich2Hits"), + "nVeloClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloClusters"), + "nVPClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVPClusters"), + "nITClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nITClusters"), + "nTTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTTClusters"), + "nUTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUTClusters"), + "nOTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nOTClusters"), + "nFTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nFTClusters"), + "nSPDhits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nSPDhits"), + "eCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"eCalTot"), + "hCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"hCalTot"), + "nEcalClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nEcalClusters"), + "nMuonCoordsS0": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS0"), + "nMuonCoordsS1": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS1"), + "nMuonCoordsS2": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS2"), + "nMuonCoordsS3": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS3"), + "nMuonCoordsS4": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS4"), + "nMuonTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonTracks"), + "ALLPVX": F.ALLPVX(pvs), + "ALLPVY": F.ALLPVY(pvs), + "ALLPVZ": F.ALLPVZ(pvs), + }) + + # get trueid bkgcat info + MC_TRUTH = MCTruthAndBkgCat(QQbar2mumu_data, name='MCTruthAndBkgCat_'+line_name) + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MC_TRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MC_TRUTH(F.MC_MOTHER(n, F.OBJECT_KEY)) + + trueid_bkgcat_info = FunctorCollection({ + #"TRUEID": F.VALUE_OR(0) @ MC_TRUTH(F.PARTICLE_ID), + "TRUEKEY": F.VALUE_OR(-1) @ MC_TRUTH(F.OBJECT_KEY), + #"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), + #"TRUEP": MC_TRUTH(F.P), + "TRUEM": MC_TRUTH(F.MASS), + "TRUEETA": MC_TRUTH(F.ETA), + "TRUEPHI": MC_TRUTH(F.PHI), + "TRUEFOURMOMENTUM": MC_TRUTH(F.FOURMOMENTUM), + #"MC_MOTHER_ID": MCMOTHER_ID(1), + #"MC_MOTHER_KEY": MCMOTHER_KEY(1), + #"MC_GD_MOTHER_ID": MCMOTHER_ID(2), + #"MC_GD_MOTHER_KEY": MCMOTHER_KEY(2), + #"MC_GD_GD_MOTHER_ID": MCMOTHER_ID(3), + #"MC_GD_GD_MOTHER_KEY": MCMOTHER_KEY(3), + "TRUEORIGIN_VX": MC_TRUTH(F.ORIGIN_VX), + "TRUEORIGIN_VY": MC_TRUTH(F.ORIGIN_VY), + "TRUEORIGIN_VZ": MC_TRUTH(F.ORIGIN_VZ), + #"TRUEEND_VX": MC_TRUTH(F.END_VX), + #"TRUEEND_VY": MC_TRUTH(F.END_VY), + #"TRUEEND_VZ": MC_TRUTH(F.END_VZ), + "BKGCAT": MC_TRUTH.BkgCat, + }) + + variables = { + "QQbar": composite_variables + all_variables(pvs, MC_TRUTH, _composite) + trueid_bkgcat_info, + "mup": daughter_variables + all_variables(pvs, MC_TRUTH, _basic) + trueid_bkgcat_info, + "mum": daughter_variables + all_variables(pvs, MC_TRUTH, _basic) + trueid_bkgcat_info, + } + + #define FunTuple instance + my_tuple = Funtuple( + name=line_name, + tuple_name="DecayTree", + fields=decay_descriptor, + variables=variables, + event_variables=event_info, + store_multiple_cand_info = True, + inputs=QQbar2mumu_data) + + return my_tuple + +def line_prefilter(line_name): + return create_lines_filter(name=f"HLT_PASS{line_name}", lines=[line_name]) + diff --git a/QuarkoniaToMuMu2024/info.yaml b/QuarkoniaToMuMu2024/info.yaml new file mode 100644 index 0000000000..c1cc8e8943 --- /dev/null +++ b/QuarkoniaToMuMu2024/info.yaml @@ -0,0 +1,107 @@ +defaults: + application: DaVinci/v64r8 + wg: BandQ + inform: + - zihan.gao@cern.ch + - mengzhen.wang@cern.ch + - zehua.xu@cern.ch + +# mc configuration +{%- set entrypoints = [ + ("Jpsi_QEE", "Jpsi2mumu_QEE", "24142001", "turbo", "TurboPass"), + ("Psi2S_QEE", "Psi2S2mumu_QEE", "28142001", "turbo", "TurboPass"), + ("Jpsi", "Jpsi2mumu", "24142001", "turbo", "TurboPass"), + ("Psi2S", "Psi2S2mumu", "28142001", "turbo", "TurboPass"), + ("Upsilon1S", "Upsilon1S", "18112001", "turbo", "TurboPass"), + ("Upsilon2S", "Upsilon2S", "18112011", "turbo", "TurboPass"), + ("Upsilon3S", "Upsilon3S", "18112021", "turbo", "TurboPass"), +]%} + +{%- set MC_conditions = [ + ("MagDown", "MagDown", "7.6", "7_6", "dddb-20240427", "sim10-2024.Q1.2-v1.1-md100", "24Q12", "2024", "2024.Q1.2", "Sim10d"), + ("MagDown", "MagDown", "5.7", "5_7", "dddb-20240427", "sim10-2024.Q1.2-v1.1-md100", "24Q12", "2024", "2024.Q1.2", "Sim10d"), + ("MagDown", "MagDown", "4.3", "4_3", "dddb-20240427", "sim10-2024.Q1.2-v1.1-md100", "24Q12", "2024", "2024.Q1.2", "Sim10d"), + ("MagUp", "MagUp", "7.6", "7_6", "dddb-20240427", "sim10-2024.Q1.2-v1.1-mu100", "24Q12", "2024", "2024.Q1.2", "Sim10d"), +]%} + +{%- set hlt_conditions = [ + ("hlt1_pp_matching_no_ut_1000KHz", "hlt1v1"), +]%} + + + +{%- for module, channel, eventtype, fullturbo, dv_input_process in entrypoints %} + {%- for polarity_mc, polarity_mc_jobtitle, nu, n_u, dddb, conddb, mcversion_jobtitle, BKK_label1, BKK_label2, simversion in MC_conditions %} + {% for hlt1_condition, hlt1_condition_jobtitle in hlt_conditions %} + +MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_HLT1: + application: "Moore/v55r11@x86_64_v2-el9-gcc13+detdesc-opt" + input: + bk_query: "/MC/{{BKK_label1}}/Beam6800GeV-{{BKK_label2}}-{{ polarity_mc }}-Nu{{ nu }}-25ns-Pythia8/{{simversion}}/{{ eventtype }}/DIGI" + dq_flags: + - OK + keep_running: true + n_test_lfns: 1 + output: QQbar2mumu_MC24_HLT1.DST + options: + entrypoint: QuarkoniaToMuMu2024.allen_mc_{{hlt1_condition}}:main + extra_options: + input_raw_format: 0.5 + conddb_tag: {{ conddb }} + dddb_tag: {{ dddb }} + input_type: "ROOT" + output_type: "ROOT" + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + +MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_HLT2: + application: "Moore/v55r11@x86_64_v2-el9-gcc13+detdesc-opt" + input: + job_name: MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_HLT1 + output: QQbar2mumu_MC24_HLT2_{{fullturbo}}.DST + options: + entrypoint: QuarkoniaToMuMu2024.moore_mc_{{fullturbo}}:main + extra_options: + conddb_tag: {{ conddb }} + dddb_tag: {{ dddb }} + input_type: "ROOT" + input_raw_format: 0.5 + output_type: "ROOT" + simulation: True + data_type: "Upgrade" + scheduler_legacy_mode: False + compression: + algorithm: ZSTD + level: 1 + max_buffer_size: 1048576 + + +MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_ROOT: + application: "DaVinci/v64r8@x86_64_v2-el9-clang16+detdesc-opt" + input: + job_name: MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_HLT2 + output: QQbar2mumu_MC24_tuple.ROOT + options: + entrypoint: QuarkoniaToMuMu2024.dv_mc_{{channel}}:main + extra_options: + input_raw_format: 0.5 + conddb_tag: {{ conddb }} + dddb_tag: {{ dddb }} + input_type: ROOT + simulation: True + data_type: "Upgrade" + input_process: "Hlt2" + input_stream: "bandq" + + + {%- endfor %} + {%- endfor %} +{%- endfor %} + + + diff --git a/QuarkoniaToMuMu2024/moore_mc_turbo.py b/QuarkoniaToMuMu2024/moore_mc_turbo.py new file mode 100644 index 0000000000..48935ad0e9 --- /dev/null +++ b/QuarkoniaToMuMu2024/moore_mc_turbo.py @@ -0,0 +1,44 @@ +""" +Stolen and adapted from Hlt/Hlt2Conf/options/hlt2_pp_expected_24_without_UT.py from v55r11. + - Added @cburr's AgeLimit to reduce memory consumption + +Stolen from https://gitlab.cern.ch/lhcb-datapkg/AnalysisProductions/-/merge_requests/1111/diffs#a8f09cbd701214f19adade2f979fd46d7a824702 , 2024-07-22 +""" +from Moore import Options +from RecoConf.reconstruction_objects import reconstruction + +from Hlt2Conf.lines.mc.mc_lines import MC_HLT2_PASSTHROUGH_LINE_NAME +from Hlt2Conf.lines.qee.high_mass_dimuon import all_lines as qee_dimuon_lines # Full-stream lines to run over +from Hlt2Conf.lines.qee.quarkonia import all_lines as qee_quarkonia_lines # Turbo-stream lines to run over +from Hlt2Conf.lines.trackeff.ZTrackEfficiency import all_lines as z_trackeff_lines # Turbo-stream lines to run over + +from Hlt2Conf.lines.charmonium_to_dimuon import turbo_lines as bandq_psi_lines +from Hlt2Conf.lines.qee.dimuon_no_ip import turbo_lines as qee_psi_lines +from Hlt2Conf.lines.bandq.hlt2_bandq import turbo_lines as bandq_upsilon_lines + +def _make_regex(): + """Use some QEE lines for the sake of example.""" + # Here we 'brute-force' this regex via a regex of each individual line name we want to consider. + # A neater format is possible via knowing how the lines are named but this feels almost less robust. + lnames = [ + linename for line_dict in + [bandq_psi_lines, qee_psi_lines, bandq_upsilon_lines] + for linename in line_dict.keys() + ] + lnames.append(MC_HLT2_PASSTHROUGH_LINE_NAME) + return f"({'|'.join(lnames)})" + + +def main(options: Options): + with reconstruction.bind(from_file=False): + from Moore.production import hlt2 + # Rather than processing via Moore:run_moore, using Moore.production:hlt2 emulates MC centralised processing. + hlt2_extra_args = [ + '--flagging', # prescales+postscales removed + passthrough_line added + '--settings=hlt2_pp_2024', # Decides which settings to create the streams from + f'--lines-regex={_make_regex()}', # Filters the settings to only run the lines you wish + ] + # instantiates public_tools and run_moore + config = hlt2(options, '--velo-source=VPRetinaCluster') + config["Gaudi::IODataManager/IODataManager"].AgeLimit = 0 + return config diff --git a/QuarkoniaToMuMu2024/spruce_turbo.py b/QuarkoniaToMuMu2024/spruce_turbo.py new file mode 100644 index 0000000000..2c4da09b36 --- /dev/null +++ b/QuarkoniaToMuMu2024/spruce_turbo.py @@ -0,0 +1,53 @@ +############################################################################### +# (c) Copyright 2024 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 Moore import options, run_moore, Options +from RecoConf.reconstruction_objects import reconstruction +from Moore.streams import DETECTORS, Stream, Streams +from Moore.lines import PassLine + +# Input-specific options +#options.conddb_tag = "sim-20231017-vc-md100" +#options.dddb_tag = "dddb-20231017" +#options.input_files = ['hlt2_output__turbo.mdf'] +#options.input_type = 'MDF' +#options.input_raw_format = 0.5 +#options.simulation = True +#options.data_type = "Upgrade" + +# Output options +#options.output_file = 'spruce_pass_output__{stream}.dst' +#options.output_type = 'ROOT' +#options.output_manifest_file = 'sprucepass.tck.json' + + +# Misc options +#options.scheduler_legacy_mode = False +#options.input_process = 'Hlt2' +#options.evt_max = -1 + +WG = 'bandq' + + +def make_streams(): + streams = [ + Stream( + WG, + lines=[ + PassLine( + name=f"Pass_{WG}", hlt2_filter_code="Hlt2.*Decision") + ], + detectors=DETECTORS) + ] + return Streams(streams=streams) + +def main(options: Options): + with reconstruction.bind(from_file=True, spruce=True): + return run_moore(options, make_streams, public_tools=[]) -- GitLab From 95a170136dae46a1272c09bd1bcb465d48f57db8 Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus943.cern.ch> Date: Thu, 12 Sep 2024 05:15:22 +0200 Subject: [PATCH 02/12] add motherID for MC --- QuarkoniaToMuMu2024/helpers/dv_mctree.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/QuarkoniaToMuMu2024/helpers/dv_mctree.py b/QuarkoniaToMuMu2024/helpers/dv_mctree.py index 2eaeb70d25..8ecad3b62b 100644 --- a/QuarkoniaToMuMu2024/helpers/dv_mctree.py +++ b/QuarkoniaToMuMu2024/helpers/dv_mctree.py @@ -75,6 +75,10 @@ def mctree_template(fields): #"nMuonTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonTracks"), }) + + MC_MOTHER_ID = lambda gen: F.VALUE_OR(0) @ F.MC_MOTHER(gen, F.PARTICLE_ID) + MC_MOTHER_KEY = lambda gen: F.VALUE_OR(-1) @ F.MC_MOTHER(gen, F.OBJECT_KEY) + # FunTuple: define variables for the J/psi composite_variables = FunctorCollection( { @@ -104,6 +108,16 @@ def mctree_template(fields): "M": F.MASS, "FOURMOMENTUM": F.FOURMOMENTUM, "PT": F.PT, + "MC_MOTHER_ID": MC_MOTHER_ID(1), + "MC_MOTHER_KEY": MC_MOTHER_KEY(1), + "MC_GD_MOTHER_ID": MC_MOTHER_ID(2), + "MC_GD_MOTHER_KEY": MC_MOTHER_KEY(2), + "MC_GD_GD_MOTHER_ID": MC_MOTHER_ID(3), + "MC_GD_GD_MOTHER_KEY": MC_MOTHER_KEY(3), + "TAU": F.MC_LIFETIME, + "END_VX": F.END_VX, + "END_VY": F.END_VY, + "END_VZ": F.END_VZ, } ) -- GitLab From f19889e1a87d27dcdd584c72cfd3f67016d949d5 Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus955.cern.ch> Date: Thu, 12 Sep 2024 17:22:04 +0200 Subject: [PATCH 03/12] add MOTHERID to MCDecayTree Jpsi --- QuarkoniaToMuMu2024/helpers/dv_mctree.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/QuarkoniaToMuMu2024/helpers/dv_mctree.py b/QuarkoniaToMuMu2024/helpers/dv_mctree.py index 8ecad3b62b..ce332790c6 100644 --- a/QuarkoniaToMuMu2024/helpers/dv_mctree.py +++ b/QuarkoniaToMuMu2024/helpers/dv_mctree.py @@ -94,6 +94,12 @@ def mctree_template(fields): "M": F.MASS, "FOURMOMENTUM": F.FOURMOMENTUM, "PT": F.PT, + "MC_MOTHER_ID": MC_MOTHER_ID(1), + "MC_MOTHER_KEY": MC_MOTHER_KEY(1), + "MC_GD_MOTHER_ID": MC_MOTHER_ID(2), + "MC_GD_MOTHER_KEY": MC_MOTHER_KEY(2), + "MC_GD_GD_MOTHER_ID": MC_MOTHER_ID(3), + "MC_GD_GD_MOTHER_KEY": MC_MOTHER_KEY(3), } ) -- GitLab From 37f71d1dd5f25d031a21b3b686c83acc8ba17210 Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus922.cern.ch> Date: Thu, 31 Oct 2024 18:04:27 +0100 Subject: [PATCH 04/12] version one. pipeline fail expected as MC production not active yet --- ...allen_mc_hlt1_pp_matching_no_ut_1000KHz.py | 6 -- QuarkoniaToMuMu2024/info.yaml | 82 +++---------------- QuarkoniaToMuMu2024/moore_mc_turbo.py | 44 ---------- 3 files changed, 12 insertions(+), 120 deletions(-) delete mode 100644 QuarkoniaToMuMu2024/allen_mc_hlt1_pp_matching_no_ut_1000KHz.py delete mode 100644 QuarkoniaToMuMu2024/moore_mc_turbo.py diff --git a/QuarkoniaToMuMu2024/allen_mc_hlt1_pp_matching_no_ut_1000KHz.py b/QuarkoniaToMuMu2024/allen_mc_hlt1_pp_matching_no_ut_1000KHz.py deleted file mode 100644 index affdbe1228..0000000000 --- a/QuarkoniaToMuMu2024/allen_mc_hlt1_pp_matching_no_ut_1000KHz.py +++ /dev/null @@ -1,6 +0,0 @@ -from Moore import options, Options -from Moore.production import hlt1 - -def main(options: Options): - return hlt1(options, "--sequence=hlt1_pp_matching_no_ut_1000KHz", "--flagging") - diff --git a/QuarkoniaToMuMu2024/info.yaml b/QuarkoniaToMuMu2024/info.yaml index c1cc8e8943..ac838c3e60 100644 --- a/QuarkoniaToMuMu2024/info.yaml +++ b/QuarkoniaToMuMu2024/info.yaml @@ -1,90 +1,33 @@ defaults: - application: DaVinci/v64r8 + application: DaVinci/v64r12 wg: BandQ inform: - - zihan.gao@cern.ch - mengzhen.wang@cern.ch - zehua.xu@cern.ch # mc configuration {%- set entrypoints = [ - ("Jpsi_QEE", "Jpsi2mumu_QEE", "24142001", "turbo", "TurboPass"), - ("Psi2S_QEE", "Psi2S2mumu_QEE", "28142001", "turbo", "TurboPass"), - ("Jpsi", "Jpsi2mumu", "24142001", "turbo", "TurboPass"), - ("Psi2S", "Psi2S2mumu", "28142001", "turbo", "TurboPass"), - ("Upsilon1S", "Upsilon1S", "18112001", "turbo", "TurboPass"), - ("Upsilon2S", "Upsilon2S", "18112011", "turbo", "TurboPass"), - ("Upsilon3S", "Upsilon3S", "18112021", "turbo", "TurboPass"), + ("Jpsi", "Jpsi2mumu", "24142001", "Hlt2"), + ("Psi2S", "Psi2S2mumu", "28142001", "Hlt2"), + ("Upsilon1S", "Upsilon1S", "18112001", "Hlt2"), + ("Upsilon2S", "Upsilon2S", "18112011", "Hlt2"), + ("Upsilon3S", "Upsilon3S", "18112021", "Hlt2"), ]%} {%- set MC_conditions = [ - ("MagDown", "MagDown", "7.6", "7_6", "dddb-20240427", "sim10-2024.Q1.2-v1.1-md100", "24Q12", "2024", "2024.Q1.2", "Sim10d"), - ("MagDown", "MagDown", "5.7", "5_7", "dddb-20240427", "sim10-2024.Q1.2-v1.1-md100", "24Q12", "2024", "2024.Q1.2", "Sim10d"), - ("MagDown", "MagDown", "4.3", "4_3", "dddb-20240427", "sim10-2024.Q1.2-v1.1-md100", "24Q12", "2024", "2024.Q1.2", "Sim10d"), - ("MagUp", "MagUp", "7.6", "7_6", "dddb-20240427", "sim10-2024.Q1.2-v1.1-mu100", "24Q12", "2024", "2024.Q1.2", "Sim10d"), -]%} - -{%- set hlt_conditions = [ - ("hlt1_pp_matching_no_ut_1000KHz", "hlt1v1"), + ("MagUp", "MagUp", "6.3", "6_3", "dddb-20240427", "sim10-2024.Q3.4-v1.3-mu100", "24Block1_v1", "2024", "2024.W31.34", "Sim10d"), ]%} -{%- for module, channel, eventtype, fullturbo, dv_input_process in entrypoints %} +{%- for module, channel, eventtype, dv_input_process in entrypoints %} {%- for polarity_mc, polarity_mc_jobtitle, nu, n_u, dddb, conddb, mcversion_jobtitle, BKK_label1, BKK_label2, simversion in MC_conditions %} - {% for hlt1_condition, hlt1_condition_jobtitle in hlt_conditions %} - -MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_HLT1: - application: "Moore/v55r11@x86_64_v2-el9-gcc13+detdesc-opt" - input: - bk_query: "/MC/{{BKK_label1}}/Beam6800GeV-{{BKK_label2}}-{{ polarity_mc }}-Nu{{ nu }}-25ns-Pythia8/{{simversion}}/{{ eventtype }}/DIGI" - dq_flags: - - OK - keep_running: true - n_test_lfns: 1 - output: QQbar2mumu_MC24_HLT1.DST - options: - entrypoint: QuarkoniaToMuMu2024.allen_mc_{{hlt1_condition}}:main - extra_options: - input_raw_format: 0.5 - conddb_tag: {{ conddb }} - dddb_tag: {{ dddb }} - input_type: "ROOT" - output_type: "ROOT" - simulation: True - data_type: "Upgrade" - scheduler_legacy_mode: False - compression: - algorithm: ZSTD - level: 1 - max_buffer_size: 1048576 - -MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_HLT2: - application: "Moore/v55r11@x86_64_v2-el9-gcc13+detdesc-opt" - input: - job_name: MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_HLT1 - output: QQbar2mumu_MC24_HLT2_{{fullturbo}}.DST - options: - entrypoint: QuarkoniaToMuMu2024.moore_mc_{{fullturbo}}:main - extra_options: - conddb_tag: {{ conddb }} - dddb_tag: {{ dddb }} - input_type: "ROOT" - input_raw_format: 0.5 - output_type: "ROOT" - simulation: True - data_type: "Upgrade" - scheduler_legacy_mode: False - compression: - algorithm: ZSTD - level: 1 - max_buffer_size: 1048576 - -MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_ROOT: - application: "DaVinci/v64r8@x86_64_v2-el9-clang16+detdesc-opt" +MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_{{mcversion_jobtitle}}_ROOT: + application: "DaVinci/v64r12@x86_64_v2-el9-clang16+detdesc-opt" input: - job_name: MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcversion_jobtitle}}_{{hlt1_condition_jobtitle}}_HLT2 + bk_query: "/MC/{{BKK_label1}}/Beam6800GeV-{{BKK_label2}}-{{ polarity_mc }}-Nu{{ nu }}-25ns-Pythia8/{{simversion}}/{{ eventtype }}/DST" + keep_running: true output: QQbar2mumu_MC24_tuple.ROOT options: entrypoint: QuarkoniaToMuMu2024.dv_mc_{{channel}}:main @@ -99,7 +42,6 @@ MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_withUTHlt2_withTrackCOV_{{mcver input_stream: "bandq" - {%- endfor %} {%- endfor %} {%- endfor %} diff --git a/QuarkoniaToMuMu2024/moore_mc_turbo.py b/QuarkoniaToMuMu2024/moore_mc_turbo.py deleted file mode 100644 index 48935ad0e9..0000000000 --- a/QuarkoniaToMuMu2024/moore_mc_turbo.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -Stolen and adapted from Hlt/Hlt2Conf/options/hlt2_pp_expected_24_without_UT.py from v55r11. - - Added @cburr's AgeLimit to reduce memory consumption - -Stolen from https://gitlab.cern.ch/lhcb-datapkg/AnalysisProductions/-/merge_requests/1111/diffs#a8f09cbd701214f19adade2f979fd46d7a824702 , 2024-07-22 -""" -from Moore import Options -from RecoConf.reconstruction_objects import reconstruction - -from Hlt2Conf.lines.mc.mc_lines import MC_HLT2_PASSTHROUGH_LINE_NAME -from Hlt2Conf.lines.qee.high_mass_dimuon import all_lines as qee_dimuon_lines # Full-stream lines to run over -from Hlt2Conf.lines.qee.quarkonia import all_lines as qee_quarkonia_lines # Turbo-stream lines to run over -from Hlt2Conf.lines.trackeff.ZTrackEfficiency import all_lines as z_trackeff_lines # Turbo-stream lines to run over - -from Hlt2Conf.lines.charmonium_to_dimuon import turbo_lines as bandq_psi_lines -from Hlt2Conf.lines.qee.dimuon_no_ip import turbo_lines as qee_psi_lines -from Hlt2Conf.lines.bandq.hlt2_bandq import turbo_lines as bandq_upsilon_lines - -def _make_regex(): - """Use some QEE lines for the sake of example.""" - # Here we 'brute-force' this regex via a regex of each individual line name we want to consider. - # A neater format is possible via knowing how the lines are named but this feels almost less robust. - lnames = [ - linename for line_dict in - [bandq_psi_lines, qee_psi_lines, bandq_upsilon_lines] - for linename in line_dict.keys() - ] - lnames.append(MC_HLT2_PASSTHROUGH_LINE_NAME) - return f"({'|'.join(lnames)})" - - -def main(options: Options): - with reconstruction.bind(from_file=False): - from Moore.production import hlt2 - # Rather than processing via Moore:run_moore, using Moore.production:hlt2 emulates MC centralised processing. - hlt2_extra_args = [ - '--flagging', # prescales+postscales removed + passthrough_line added - '--settings=hlt2_pp_2024', # Decides which settings to create the streams from - f'--lines-regex={_make_regex()}', # Filters the settings to only run the lines you wish - ] - # instantiates public_tools and run_moore - config = hlt2(options, '--velo-source=VPRetinaCluster') - config["Gaudi::IODataManager/IODataManager"].AgeLimit = 0 - return config -- GitLab From 2f8c562d2cd2b9d3e6078f331ad004dde6caae50 Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus965.cern.ch> Date: Sun, 3 Nov 2024 10:42:08 +0100 Subject: [PATCH 05/12] prepare for production --- QuarkoniaToMuMu2024/info.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/QuarkoniaToMuMu2024/info.yaml b/QuarkoniaToMuMu2024/info.yaml index ac838c3e60..324fd1e0ec 100644 --- a/QuarkoniaToMuMu2024/info.yaml +++ b/QuarkoniaToMuMu2024/info.yaml @@ -24,9 +24,9 @@ defaults: {%- for polarity_mc, polarity_mc_jobtitle, nu, n_u, dddb, conddb, mcversion_jobtitle, BKK_label1, BKK_label2, simversion in MC_conditions %} MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_{{mcversion_jobtitle}}_ROOT: - application: "DaVinci/v64r12@x86_64_v2-el9-clang16+detdesc-opt" + application: "DaVinci/v64r12@x86_64_v3-el9-gcc13+detdesc-opt+g" input: - bk_query: "/MC/{{BKK_label1}}/Beam6800GeV-{{BKK_label2}}-{{ polarity_mc }}-Nu{{ nu }}-25ns-Pythia8/{{simversion}}/{{ eventtype }}/DST" + bk_query: "/MC/{{BKK_label1}}/Beam6800GeV-{{BKK_label2}}-{{ polarity_mc }}-Nu{{ nu }}-25ns-Pythia8/{{simversion}}/HLT2-2024.W31.34/{{ eventtype }}/DST" keep_running: true output: QQbar2mumu_MC24_tuple.ROOT options: -- GitLab From 8e4c337f6a0d0d475ed1b4784a609e73bd1159da Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus979.cern.ch> Date: Sun, 3 Nov 2024 17:58:04 +0100 Subject: [PATCH 06/12] remove unused files --- QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py | 39 --------------- QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py | 28 ----------- QuarkoniaToMuMu2024/spruce_turbo.py | 53 --------------------- 3 files changed, 120 deletions(-) delete mode 100644 QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py delete mode 100644 QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py delete mode 100644 QuarkoniaToMuMu2024/spruce_turbo.py diff --git a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py deleted file mode 100644 index c23b8ff27f..0000000000 --- a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu_QEE.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -sys.path.append(os.path.join( - os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree -from DaVinci import Options, make_config - -def main(options: Options): - decay_descriptor = { - "QQbar": "J/psi(1S) -> mu+ mu-", - "mup": "J/psi(1S) -> ^mu+ mu-", - "mum": "J/psi(1S) -> mu+ ^mu-", - } - - decay_descriptor_mctree = { - "QQbar": "J/psi(1S) ==> mu+ mu-", - "mup": "J/psi(1S) ==> ^mu+ mu-", - "mum": "J/psi(1S) ==> mu+ ^mu-", - } - - - line_name0 = 'Hlt2QEE_DiMuonNoIP_massRange5' - my_tuple0 = dv_tree.tree_template(decay_descriptor, line_name0, True, []) - my_filter0 = dv_tree.line_prefilter(line_name0) - line_name1 = 'Hlt2QEE_DiMuonNoIP_massRange4' - my_tuple1 = dv_tree.tree_template(decay_descriptor, line_name1, True, []) - my_filter1 = dv_tree.line_prefilter(line_name1) - line_name2 = 'Hlt2QEE_DiMuonNoIP_massRange3' - my_tuple2 = dv_tree.tree_template(decay_descriptor, line_name2, True, []) - my_filter2 = dv_tree.line_prefilter(line_name2) - my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) - user_algorithms = { - "Alg_massRange5": [my_filter0, my_tuple0], - "Alg_massRange4": [my_filter1, my_tuple1], - "Alg_massRange3": [my_filter2, my_tuple2], - 'Alg_mctuple': [my_mctuple], - } - return make_config(options, user_algorithms) - diff --git a/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py b/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py deleted file mode 100644 index c662b904e3..0000000000 --- a/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu_QEE.py +++ /dev/null @@ -1,28 +0,0 @@ -import os -import sys -sys.path.append(os.path.join( - os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree -from DaVinci import Options, make_config - -def main(options: Options): - decay_descriptor = { - "QQbar": "J/psi(1S) -> mu+ mu-", - "mup": "J/psi(1S) -> ^mu+ mu-", - "mum": "J/psi(1S) -> mu+ ^mu-", - } - decay_descriptor_mctree = { - "QQbar": "psi(2S) ==> mu+ mu-", - "mup": "psi(2S) ==> ^mu+ mu-", - "mum": "psi(2S) ==> mu+ ^mu-", - } - - line_name = 'Hlt2QEE_DiMuonNoIP_massRange5' - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) - my_filter = dv_tree.line_prefilter(line_name) - my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) - user_algorithms = { - 'Alg_tuple': [my_filter, my_tuple], - 'Alg_mctuple': [my_mctuple], - } - return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/spruce_turbo.py b/QuarkoniaToMuMu2024/spruce_turbo.py deleted file mode 100644 index 2c4da09b36..0000000000 --- a/QuarkoniaToMuMu2024/spruce_turbo.py +++ /dev/null @@ -1,53 +0,0 @@ -############################################################################### -# (c) Copyright 2024 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 Moore import options, run_moore, Options -from RecoConf.reconstruction_objects import reconstruction -from Moore.streams import DETECTORS, Stream, Streams -from Moore.lines import PassLine - -# Input-specific options -#options.conddb_tag = "sim-20231017-vc-md100" -#options.dddb_tag = "dddb-20231017" -#options.input_files = ['hlt2_output__turbo.mdf'] -#options.input_type = 'MDF' -#options.input_raw_format = 0.5 -#options.simulation = True -#options.data_type = "Upgrade" - -# Output options -#options.output_file = 'spruce_pass_output__{stream}.dst' -#options.output_type = 'ROOT' -#options.output_manifest_file = 'sprucepass.tck.json' - - -# Misc options -#options.scheduler_legacy_mode = False -#options.input_process = 'Hlt2' -#options.evt_max = -1 - -WG = 'bandq' - - -def make_streams(): - streams = [ - Stream( - WG, - lines=[ - PassLine( - name=f"Pass_{WG}", hlt2_filter_code="Hlt2.*Decision") - ], - detectors=DETECTORS) - ] - return Streams(streams=streams) - -def main(options: Options): - with reconstruction.bind(from_file=True, spruce=True): - return run_moore(options, make_streams, public_tools=[]) -- GitLab From 55f82db6d1e19cca70c77f9796c8e632b66b3d3b Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus922.cern.ch> Date: Tue, 5 Nov 2024 15:21:16 +0100 Subject: [PATCH 07/12] try to remove pidmu cuts in tupling from DST --- QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py | 5 +++-- QuarkoniaToMuMu2024/helpers/dv_tree.py | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py index b83f4336a1..4ba1eeb62a 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py +++ b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py @@ -18,11 +18,12 @@ def main(options: Options): } line_name = 'Hlt2_JpsiToMuMu' - my_filter = dv_tree.line_prefilter(line_name) +# my_filter = dv_tree.line_prefilter(line_name) my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [my_filter, my_tuple], + 'Alg_tuple': [ my_tuple], + #'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/helpers/dv_tree.py b/QuarkoniaToMuMu2024/helpers/dv_tree.py index 3e0b84bbd6..8126ec2e72 100644 --- a/QuarkoniaToMuMu2024/helpers/dv_tree.py +++ b/QuarkoniaToMuMu2024/helpers/dv_tree.py @@ -22,6 +22,9 @@ from FunTuple.functorcollections import MCHierarchy, MCPrimaries, MCPromptDecay, from PyConf.reading import get_odin # get_decreports, from DecayTreeFitter import DecayTreeFitter +from Hlt2Conf.lines.charmonium_to_dimuon import make_jpsi + + _basic = "basic" _composite = "composite" _toplevel = "toplevel" @@ -331,7 +334,8 @@ def tree_template(decay_descriptor, line_name, isturbo, Hlt2_decisions): if isturbo: evtpath_prefix = "/Event/HLT2/" - QQbar2mumu_data = get_particles(evtpath_prefix+f"{line_name}/Particles") + #QQbar2mumu_data = get_particles(evtpath_prefix+f"{line_name}/Particles") + QQbar2mumu_data = make_jpsi(minPIDmu=-999) pvs = get_pvs() -- GitLab From f29f97a9434bd7cdeb2be8c2f6636b95a6288cf3 Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus938.cern.ch> Date: Thu, 7 Nov 2024 13:28:56 +0100 Subject: [PATCH 08/12] test removing ismuon --- QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py | 11 +- QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py | 13 +- QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py | 13 +- QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py | 14 +- QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py | 13 +- QuarkoniaToMuMu2024/helpers/dv_tree.py | 5 +- .../helpers/private_combiners.py | 207 ++++++++++++++++++ 7 files changed, 254 insertions(+), 22 deletions(-) create mode 100644 QuarkoniaToMuMu2024/helpers/private_combiners.py diff --git a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py index 4ba1eeb62a..fcb6c4a4e8 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py +++ b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py @@ -2,8 +2,13 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree +from helpers import dv_tree, dv_mctree, private_combiners from DaVinci import Options, make_config +from RecoConf.event_filters import require_pvs + +from RecoConf.reconstruction_objects import make_pvs + + def main(options: Options): decay_descriptor = { @@ -19,10 +24,10 @@ def main(options: Options): line_name = 'Hlt2_JpsiToMuMu' # my_filter = dv_tree.line_prefilter(line_name) - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_jpsi()) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [ my_tuple], + 'Alg_tuple': [ require_pvs(make_pvs()), my_tuple], #'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } diff --git a/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py b/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py index e779f100ba..a81937cda0 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py +++ b/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py @@ -2,9 +2,13 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree +from helpers import dv_tree, dv_mctree, private_combiners from DaVinci import Options, make_config +from RecoConf.event_filters import require_pvs + +from RecoConf.reconstruction_objects import make_pvs + def main(options: Options): decay_descriptor = { "QQbar": "psi(2S) -> mu+ mu-", @@ -19,11 +23,12 @@ def main(options: Options): } line_name = 'Hlt2_Psi2SToMuMu' - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) - my_filter = dv_tree.line_prefilter(line_name) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_psi2s()) +# my_filter = dv_tree.line_prefilter(line_name) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [my_filter, my_tuple], + 'Alg_tuple': [require_pvs(make_pvs()), my_tuple], + #'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py index 69ae7b831f..d685b45b02 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py @@ -2,9 +2,13 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree +from helpers import dv_tree, dv_mctree, private_combiners from DaVinci import Options, make_config +from RecoConf.event_filters import require_pvs + +from RecoConf.reconstruction_objects import make_pvs + def main(options: Options): decay_descriptor = { "QQbar": "Upsilon(1S) -> mu+ mu-", @@ -18,12 +22,13 @@ def main(options: Options): } line_name = 'Hlt2BandQ_UpsilonToMuMuEMTF' - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) - my_filter = dv_tree.line_prefilter(line_name) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_upsilon()) +# my_filter = dv_tree.line_prefilter(line_name) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [my_filter, my_tuple], + 'Alg_tuple': [require_pvs(make_pvs()), my_tuple], + #'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py index 0212d0d8a4..9241ee7ca3 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py @@ -2,9 +2,14 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree +from helpers import dv_tree, dv_mctree, private_combiners from DaVinci import Options, make_config +from RecoConf.event_filters import require_pvs + +from RecoConf.reconstruction_objects import make_pvs + + def main(options: Options): decay_descriptor = { "QQbar": "Upsilon(1S) -> mu+ mu-", @@ -18,12 +23,13 @@ def main(options: Options): } line_name = 'Hlt2BandQ_UpsilonToMuMuEMTF' - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) - my_filter = dv_tree.line_prefilter(line_name) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_upsilon()) +# my_filter = dv_tree.line_prefilter(line_name) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [my_filter, my_tuple], + 'Alg_tuple': [require_pvs(make_pvs()), my_tuple], + #'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py index 4c2b84a3f0..de60f00f67 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py @@ -2,9 +2,13 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree +from helpers import dv_tree, dv_mctree, private_combiners from DaVinci import Options, make_config +from RecoConf.event_filters import require_pvs + +from RecoConf.reconstruction_objects import make_pvs + def main(options: Options): decay_descriptor = { "QQbar": "Upsilon(1S) -> mu+ mu-", @@ -18,12 +22,13 @@ def main(options: Options): } line_name = 'Hlt2BandQ_UpsilonToMuMuEMTF' - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) - my_filter = dv_tree.line_prefilter(line_name) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_upsilon()) +# my_filter = dv_tree.line_prefilter(line_name) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [my_filter, my_tuple], + #'Alg_tuple': [my_filter, my_tuple], + 'Alg_tuple': [require_pvs(make_pvs()), my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/helpers/dv_tree.py b/QuarkoniaToMuMu2024/helpers/dv_tree.py index 8126ec2e72..cd5222f457 100644 --- a/QuarkoniaToMuMu2024/helpers/dv_tree.py +++ b/QuarkoniaToMuMu2024/helpers/dv_tree.py @@ -22,7 +22,6 @@ from FunTuple.functorcollections import MCHierarchy, MCPrimaries, MCPromptDecay, from PyConf.reading import get_odin # get_decreports, from DecayTreeFitter import DecayTreeFitter -from Hlt2Conf.lines.charmonium_to_dimuon import make_jpsi _basic = "basic" @@ -329,13 +328,13 @@ def event_variables(PVs, ODIN, decreports, lines, hlt1lines): return evt_vars -def tree_template(decay_descriptor, line_name, isturbo, Hlt2_decisions): +def tree_template(decay_descriptor, line_name, isturbo, Hlt2_decisions, QQbar2mumu_data): evtpath_prefix = "/Event/Spruce/" if isturbo: evtpath_prefix = "/Event/HLT2/" #QQbar2mumu_data = get_particles(evtpath_prefix+f"{line_name}/Particles") - QQbar2mumu_data = make_jpsi(minPIDmu=-999) + #QQbar2mumu_data = make_jpsi(minPIDmu=-999) pvs = get_pvs() diff --git a/QuarkoniaToMuMu2024/helpers/private_combiners.py b/QuarkoniaToMuMu2024/helpers/private_combiners.py new file mode 100644 index 0000000000..fa0a5ad1c6 --- /dev/null +++ b/QuarkoniaToMuMu2024/helpers/private_combiners.py @@ -0,0 +1,207 @@ +# Copy from +# https://gitlab.cern.ch/lhcb/Moore/-/blob/2024-patches/Hlt/Hlt2Conf/python/Hlt2Conf/lines/charmonium_to_dimuon.py?ref_type=heads +# https://gitlab.cern.ch/lhcb/Moore/-/blob/2024-patches/Hlt/Hlt2Conf/python/Hlt2Conf/lines/bandq/builders/dimuon_lines.py?ref_type=heads +import Functors as F + +from Hlt2Conf.standard_particles import make_long_muons +from GaudiKernel.SystemOfUnits import MeV, GeV +from RecoConf.reconstruction_objects import make_pvs +from Hlt2Conf.algorithms_thor import ParticleFilter, ParticleCombiner + + +_JPSI_PDG_MASS_ = 3096.9 * MeV +_PSI2S_PDG_MASS_ = 3686.1 * MeV +_MASSWINDOW_LOW_JPSI_ = 150 * MeV +_MASSWINDOW_HIGH_JPSI_ = 150 * MeV +_MASSWINDOW_LOW_PSI2S_ = 150 * MeV +_MASSWINDOW_HIGH_PSI2S_ = 150 * MeV +_MASSMIN_JPSI = _JPSI_PDG_MASS_ - _MASSWINDOW_LOW_JPSI_ +_MASSMAX_JPSI = _JPSI_PDG_MASS_ + _MASSWINDOW_HIGH_JPSI_ +_MASSMIN_PSI2S = _PSI2S_PDG_MASS_ - _MASSWINDOW_LOW_PSI2S_ +_MASSMAX_PSI2S = _PSI2S_PDG_MASS_ + _MASSWINDOW_HIGH_PSI2S_ +_MASSMIN_UPSILON = 7900 * MeV +_MASSMAX_UPSILON = 12000 * MeV + + +_PIDMU_JPSI = -999. +_PIDMU_PSI2S = -999. +_PIDMU_UPSILON = -999. + +def make_charmonium_muons(make_particles=make_long_muons, + name='charmonium_muons_{hash}', + minPt_muon=None, + minP_muon=None, + minIPChi2_muon=None, + minIP_muon=None, + minPIDmu=None, + maxIPChi2_muon=None): + + pvs = make_pvs() + + code = F.require_all(F.ALL) + + if minPt_muon is not None: code &= (F.PT > minPt_muon) + if minP_muon is not None: code &= (F.P > minP_muon) + if minIPChi2_muon is not None: code &= (F.MINIPCHI2(pvs) > minIPChi2_muon) + if minIP_muon is not None: code &= (F.MINIP(pvs) > minIP_muon) + + # ignoring minPIDmu cut here, thus ignoring it in ALL lines in this file +# if not nopid_muons() and minPIDmu is not None: +# code &= F.require_all(F.PID_MU > minPIDmu) + + if maxIPChi2_muon is not None: + code &= (F.MINIPCHI2(pvs) < maxIPChi2_muon) + + return ParticleFilter(make_particles(), name=name, Cut=F.FILTER(code)) + + + +def make_charmonium_dimuon_base(name='charmonium_dimuon_base_{hash}', + DecayDescriptor='J/psi(1S) -> mu+ mu-', + maxVertexChi2=25, + maxDOCAChi2=None, + minPt_muon=None, + minP_muon=None, + minIPChi2_muon=None, + minIP_muon=None, + minPIDmu=None, + minPt_dimuon=None, + minMass_dimuon=None, + maxMass_dimuon=None): + + # get the long muons + muons = make_charmonium_muons( + minPt_muon=minPt_muon, + minP_muon=minP_muon, + minIPChi2_muon=minIPChi2_muon, + minIP_muon=minIP_muon, + minPIDmu=minPIDmu) + + combination_code = F.ALL + if minMass_dimuon is not None: + combination_code &= (F.MASS > minMass_dimuon) + if maxMass_dimuon is not None: + combination_code &= (F.MASS < maxMass_dimuon) + if maxDOCAChi2 is not None: + combination_code &= (F.SDOCACHI2(1, 2) < maxDOCAChi2) + + # require that the muons come from the same vertex + vertex_code = F.require_all(F.CHI2DOF < maxVertexChi2) + if minPt_dimuon is not None: vertex_code &= (F.PT > minPt_dimuon) + + return ParticleCombiner( + name=name, + Inputs=[muons, muons], + DecayDescriptor=DecayDescriptor, + CombinationCut=combination_code, + CompositeCut=vertex_code) + + +def make_charmonium_dimuon(name='charmonium_dimuon_{hash}', + DecayDescriptor='J/psi(1S) -> mu+ mu-', + minPt_dimuon=None, + minPt_muon=300 * MeV, + minP_muon=None, + minIPChi2_muon=None, + maxVertexChi2=25, + minPIDmu=None, + bpvdls_min=None, + maxDOCAChi2=None, + minMass_dimuon=None, + maxMass_dimuon=None): + + make_particles = make_charmonium_dimuon_base( + DecayDescriptor=DecayDescriptor, + maxVertexChi2=maxVertexChi2, + minIPChi2_muon=minIPChi2_muon, + minPt_muon=minPt_muon, + minP_muon=minP_muon, + minPIDmu=minPIDmu, + maxDOCAChi2=maxDOCAChi2, + minMass_dimuon=minMass_dimuon, + maxMass_dimuon=maxMass_dimuon) + + pvs = make_pvs() + + code = F.require_all(F.CHI2DOF < maxVertexChi2) + if minPt_dimuon is not None: code &= (F.PT > minPt_dimuon) + if bpvdls_min is not None: code &= (F.BPVDLS(pvs) > bpvdls_min) + + return ParticleFilter(make_particles, name=name, Cut=F.FILTER(code)) + + + + +def make_jpsi(name='jpsi_{hash}', + minMass_dimuon=_MASSMIN_JPSI, + maxMass_dimuon=_MASSMAX_JPSI, + minPt_muon=300 * MeV, + minP_muon=None, + minPt_Jpsi=None, + maxVertexChi2=25, + minPIDmu=_PIDMU_JPSI): + + code = F.ALL + if minPt_Jpsi is not None: code &= F.PT > minPt_Jpsi + + dimuon = make_charmonium_dimuon( + DecayDescriptor='J/psi(1S) -> mu+ mu-', + minPt_dimuon=minPt_Jpsi, + minPt_muon=minPt_muon, + minP_muon=minP_muon, + minPIDmu=minPIDmu, + minMass_dimuon=minMass_dimuon, + maxMass_dimuon=maxMass_dimuon, + maxVertexChi2=maxVertexChi2) + + return ParticleFilter(dimuon, name=name, Cut=F.FILTER(code)) + + +def make_psi2s(name='psi2s_{hash}', + minMass_dimuon=_MASSMIN_PSI2S, + maxMass_dimuon=_MASSMAX_PSI2S, + minPt_muon=300 * MeV, + minP_muon=None, + minPt_Psi2S=None, + maxPt_Psi2S=None, + maxVertexChi2=25, + minPIDmu=_PIDMU_PSI2S): + + code = F.ALL + if minPt_Psi2S is not None: code &= F.PT > minPt_Psi2S + if maxPt_Psi2S is not None: code &= F.PT < maxPt_Psi2S + + dimuon = make_charmonium_dimuon( + DecayDescriptor='psi(2S) -> mu+ mu-', + minPt_dimuon=minPt_Psi2S, + minPt_muon=minPt_muon, + minP_muon=minP_muon, + minPIDmu=minPIDmu, + minMass_dimuon=minMass_dimuon, + maxMass_dimuon=maxMass_dimuon, + maxVertexChi2=maxVertexChi2) + + return ParticleFilter(dimuon, name=name, Cut=F.FILTER(code)) + + + +def make_upsilon(name='bandq_upsilon_{hash}', + minMass_dimuon=_MASSMIN_UPSILON, + maxMass_dimuon=_MASSMAX_UPSILON, + minPt_muon=300 * MeV, + minP_muon=0 * MeV, + minPt_upsilon=0 * MeV): + + code = (F.PT > minPt_upsilon) + + dimuon = make_charmonium_dimuon( + DecayDescriptor='Upsilon(1S) -> mu+ mu-', + minPt_dimuon=minPt_upsilon, + minP_muon=minP_muon, + minPt_muon=minPt_muon, + minPIDmu=_PIDMU_UPSILON, + minMass_dimuon=minMass_dimuon, + maxMass_dimuon=maxMass_dimuon) + + return ParticleFilter(dimuon, name=name, Cut=F.FILTER(code)) + -- GitLab From 9af10d07dd5a9c237dce6c98f24e99761cc6d95d Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus957.cern.ch> Date: Mon, 25 Nov 2024 17:58:56 +0100 Subject: [PATCH 09/12] save mcdecaytree decaytree decaytreenopid together --- QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py | 11 +- QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py | 11 +- QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py | 11 +- QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py | 12 +- QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py | 11 +- QuarkoniaToMuMu2024/helpers/dv_tree.py | 6 +- QuarkoniaToMuMu2024/helpers/dv_tree_nopid.py | 514 +++++++++++++++++++ QuarkoniaToMuMu2024/log | 0 8 files changed, 547 insertions(+), 29 deletions(-) create mode 100644 QuarkoniaToMuMu2024/helpers/dv_tree_nopid.py create mode 100644 QuarkoniaToMuMu2024/log diff --git a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py index fcb6c4a4e8..7de5d8d987 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py +++ b/QuarkoniaToMuMu2024/dv_mc_Jpsi2mumu.py @@ -2,7 +2,7 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree, private_combiners +from helpers import dv_tree_nopid, dv_tree, dv_mctree, private_combiners from DaVinci import Options, make_config from RecoConf.event_filters import require_pvs @@ -23,12 +23,13 @@ def main(options: Options): } line_name = 'Hlt2_JpsiToMuMu' -# my_filter = dv_tree.line_prefilter(line_name) - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_jpsi()) + my_filter = dv_tree.line_prefilter(line_name) + my_tuple_nopid = dv_tree_nopid.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_jpsi()) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [ require_pvs(make_pvs()), my_tuple], - #'Alg_tuple': [my_filter, my_tuple], + 'Alg_tuple_nopid': [ require_pvs(make_pvs()), my_tuple_nopid], + 'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py b/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py index a81937cda0..5f45c9c2f0 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py +++ b/QuarkoniaToMuMu2024/dv_mc_Psi2S2mumu.py @@ -2,7 +2,7 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree, private_combiners +from helpers import dv_tree, dv_tree_nopid, dv_mctree, private_combiners from DaVinci import Options, make_config from RecoConf.event_filters import require_pvs @@ -23,12 +23,13 @@ def main(options: Options): } line_name = 'Hlt2_Psi2SToMuMu' - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_psi2s()) -# my_filter = dv_tree.line_prefilter(line_name) + my_tuple_nopid = dv_tree_nopid.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_psi2s()) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_filter = dv_tree.line_prefilter(line_name) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [require_pvs(make_pvs()), my_tuple], - #'Alg_tuple': [my_filter, my_tuple], + 'Alg_tuple_nopid': [require_pvs(make_pvs()), my_tuple_nopid], + 'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py index d685b45b02..fcfb66d7df 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py @@ -2,7 +2,7 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree, private_combiners +from helpers import dv_tree, dv_tree_nopid, dv_mctree, private_combiners from DaVinci import Options, make_config from RecoConf.event_filters import require_pvs @@ -22,13 +22,14 @@ def main(options: Options): } line_name = 'Hlt2BandQ_UpsilonToMuMuEMTF' - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_upsilon()) -# my_filter = dv_tree.line_prefilter(line_name) + my_tuple_nopid = dv_tree_nopid.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_upsilon()) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_filter = dv_tree.line_prefilter(line_name) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [require_pvs(make_pvs()), my_tuple], - #'Alg_tuple': [my_filter, my_tuple], + 'Alg_tuple': [require_pvs(make_pvs()), my_tuple_nopid], + 'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py index 9241ee7ca3..54e5a79bc7 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py @@ -2,14 +2,13 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree, private_combiners +from helpers import dv_tree, dv_tree_nopid, dv_mctree, private_combiners from DaVinci import Options, make_config from RecoConf.event_filters import require_pvs from RecoConf.reconstruction_objects import make_pvs - def main(options: Options): decay_descriptor = { "QQbar": "Upsilon(1S) -> mu+ mu-", @@ -23,13 +22,14 @@ def main(options: Options): } line_name = 'Hlt2BandQ_UpsilonToMuMuEMTF' - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_upsilon()) -# my_filter = dv_tree.line_prefilter(line_name) + my_tuple_nopid = dv_tree_nopid.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_upsilon()) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_filter = dv_tree.line_prefilter(line_name) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [require_pvs(make_pvs()), my_tuple], - #'Alg_tuple': [my_filter, my_tuple], + 'Alg_tuple': [require_pvs(make_pvs()), my_tuple_nopid], + 'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py index de60f00f67..65890de8c4 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py @@ -2,7 +2,7 @@ import os import sys sys.path.append(os.path.join( os.environ['ANALYSIS_PRODUCTIONS_BASE'], 'QuarkoniaToMuMu2024')) -from helpers import dv_tree, dv_mctree, private_combiners +from helpers import dv_tree, dv_tree_nopid, dv_mctree, private_combiners from DaVinci import Options, make_config from RecoConf.event_filters import require_pvs @@ -22,13 +22,14 @@ def main(options: Options): } line_name = 'Hlt2BandQ_UpsilonToMuMuEMTF' - my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_upsilon()) -# my_filter = dv_tree.line_prefilter(line_name) + my_tuple_nopid = dv_tree_nopid.tree_template(decay_descriptor, line_name, True, [], private_combiners.make_upsilon()) + my_tuple = dv_tree.tree_template(decay_descriptor, line_name, True, []) + my_filter = dv_tree.line_prefilter(line_name) my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - #'Alg_tuple': [my_filter, my_tuple], - 'Alg_tuple': [require_pvs(make_pvs()), my_tuple], + 'Alg_tuple': [require_pvs(make_pvs()), my_tuple_nopid], + 'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } return make_config(options, user_algorithms) diff --git a/QuarkoniaToMuMu2024/helpers/dv_tree.py b/QuarkoniaToMuMu2024/helpers/dv_tree.py index cd5222f457..8032c9a904 100644 --- a/QuarkoniaToMuMu2024/helpers/dv_tree.py +++ b/QuarkoniaToMuMu2024/helpers/dv_tree.py @@ -328,12 +328,12 @@ def event_variables(PVs, ODIN, decreports, lines, hlt1lines): return evt_vars -def tree_template(decay_descriptor, line_name, isturbo, Hlt2_decisions, QQbar2mumu_data): +def tree_template(decay_descriptor, line_name, isturbo, Hlt2_decisions): evtpath_prefix = "/Event/Spruce/" if isturbo: evtpath_prefix = "/Event/HLT2/" - #QQbar2mumu_data = get_particles(evtpath_prefix+f"{line_name}/Particles") + QQbar2mumu_data = get_particles(evtpath_prefix+f"{line_name}/Particles") #QQbar2mumu_data = make_jpsi(minPIDmu=-999) pvs = get_pvs() @@ -459,7 +459,7 @@ def tree_template(decay_descriptor, line_name, isturbo, Hlt2_decisions, QQbar2mu }) # get trueid bkgcat info - MC_TRUTH = MCTruthAndBkgCat(QQbar2mumu_data, name='MCTruthAndBkgCat_'+line_name) + MC_TRUTH = MCTruthAndBkgCat(QQbar2mumu_data, name='MCTruthAndBkgCat_'+line_name+"_{hash}") MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MC_TRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MC_TRUTH(F.MC_MOTHER(n, F.OBJECT_KEY)) diff --git a/QuarkoniaToMuMu2024/helpers/dv_tree_nopid.py b/QuarkoniaToMuMu2024/helpers/dv_tree_nopid.py new file mode 100644 index 0000000000..5bfe4a88ee --- /dev/null +++ b/QuarkoniaToMuMu2024/helpers/dv_tree_nopid.py @@ -0,0 +1,514 @@ +############################################################################### +# (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. # +############################################################################### +""" +Read an HLT2 file and create an ntuple with the new DaVinci configuration. +""" +import Functors as F +import FunTuple.functorcollections as FC +from FunTuple import FunctorCollection +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.reading import get_particles, get_pvs, get_rec_summary +from DaVinci.algorithms import create_lines_filter +from DaVinciMCTools import MCTruthAndBkgCat +from FunTuple.functorcollections import MCHierarchy, MCPrimaries, MCPromptDecay, Kinematics, SelectionInfo, HltTisTos, MCVertexInfo, MCKinematics, ParticleID, EventInfo +from PyConf.reading import get_odin # get_decreports, +from DecayTreeFitter import DecayTreeFitter + + + +_basic = "basic" +_composite = "composite" +_toplevel = "toplevel" + +#def all_variables(pvs, dtf, mctruth, ptype, candidates=None, ftAlg=None): +def all_variables(pvs, mctruth, ptype, candidates=None, ftAlg=None): + """ + function that returns dictionary of functors that work. + + functors are listed in order of https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors_reference.html#module-Functo + """ + if ptype not in [_basic, _composite]: + Exception(f"I want {_basic} or {_composite}. Got {ptype}") + all_vars = FunctorCollection({}) + + comp = _composite == ptype or _toplevel == ptype # is composite + basic = _basic == ptype # is not composite + top = _toplevel == ptype # the B + + # First import everything that comes in functorcollections + all_vars += FC.Kinematics() + if basic: + all_vars += FC.ParticleID(extra_info=True) + all_vars += FC.MCKinematics(mctruth_alg=mctruth) + all_vars += FC.MCHierarchy(mctruth_alg=mctruth) + #all_vars += FC.MCPrimaryVertexInfo(mctruth_alg=mctruth) + #Hlt1_decisions = ["Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"] + #if candidates: + #all_vars += FC.HltTisTos( + #selection_type="Hlt", trigger_lines=Hlt1_decisions, data=candidates + #) + #if comp: + # all_vars += FC.MCVertexInfo(mctruth_alg=mctruth) + #if top: + # all_vars += FC.MCPromptDecay(mctruth_alg=mctruth) + + # + # FTAlg not yet implemented + # For Track isolation see weightedrelations_trackvariables + # + # Now all other functors + + # ALL : Not useful for tupling + + if comp: + all_vars.update({"ALV": F.ALV(Child1=1, Child2=2)}) + + all_vars.update({"BKGCAT": mctruth.BkgCat}) + + if comp: # all these require a vertex + all_vars.update({"BPVCORRM": F.BPVCORRM(pvs)}) + all_vars.update({"BPVCORRMERR": F.BPVCORRMERR(pvs)}) + all_vars.update({"BPVDIRA": F.BPVDIRA(pvs)}) + all_vars.update({"BPVDLS": F.BPVDLS(pvs)}) + all_vars.update({"BPVETA": F.BPVETA(pvs)}) + all_vars.update({"BPVFD": F.BPVFD(pvs)}) + all_vars.update({"BPVFDCHI2": F.BPVFDCHI2(pvs)}) + all_vars.update({"BPVFDIR": F.BPVFDIR(pvs)}) + all_vars.update({"BPVFDVEC": F.BPVFDVEC(pvs)}) + + all_vars.update({"BPVIP": F.BPVIP(pvs)}) + all_vars.update({"BPVIPCHI2": F.BPVIPCHI2(pvs)}) + all_vars.update({"BPVX": F.BPVX(pvs)}) + all_vars.update({"BPVY": F.BPVY(pvs)}) + all_vars.update({"BPVZ": F.BPVZ(pvs)}) + # When storing variable length array one can + # give a custom branch name for the index. + # This can be achieved by enclosing custom index + # name within square brackets (see code below). + # The branch name ("nPV") will correspond to the + # index of the PV. If no index branch name given i.e. + # all_vars.update({ 'ALLPVX'] the default "indx" is used. + #all_vars.update({"ALLPVX[nPVs]": F.ALLPVX(pvs)}) + #all_vars.update({"ALLPVY[nPVs]": F.ALLPVY(pvs)}) + #all_vars.update({"ALLPVZ[nPVs]": F.ALLPVZ(pvs)}) + all_vars.update({"ALLPVX": F.ALLPVX(pvs)}) + all_vars.update({"ALLPVY": F.ALLPVY(pvs)}) + all_vars.update({"ALLPVZ": F.ALLPVZ(pvs)}) + + if comp: # all these require a vertex + #all_vars.update({"ALLPV_FD[nPVs]": F.ALLPV_FD(pvs)}) + #all_vars.update({"ALLPV_IP[nPVs]": F.ALLPV_IP(pvs)}) + all_vars.update({"ALLPV_FD": F.ALLPV_FD(pvs)}) + all_vars.update({"ALLPV_IP": F.ALLPV_IP(pvs)}) + all_vars.update({"BPVLTIME": F.BPVLTIME(pvs)}) + all_vars.update({"BPVVDRHO": F.BPVVDRHO(pvs)}) + all_vars.update({"BPVVDX": F.BPVVDX(pvs)}) + all_vars.update({"BPVVDY": F.BPVVDY(pvs)}) + all_vars.update({"BPVVDZ": F.BPVVDZ(pvs)}) + + all_vars.update({"CHARGE": F.CHARGE}) + all_vars.update({"CHI2": F.CHI2}) + all_vars.update({"CHI2DOF": F.CHI2DOF}) + if top: # apply this only to B + all_vars.update({"CHILD1_PT": F.CHILD(1, F.PT)}) # example of CHILD + all_vars.update({"Ds_END_VZ": F.CHILD(1, F.END_VZ)}) + all_vars.update({"Delta_END_VZ_DsB0": F.CHILD(1, F.END_VZ) - F.END_VZ}) + + # if basic: all_vars.update({ 'CLOSESTTOBEAM' : F.CLOSESTTOBEAM # 'Track__ClosestToBeamState' object has no attribute 'to_json' + # COMB + # if basic: all_vars.update({ 'COV' : F.COV # 'Track__Covariance' object has no attribute 'to_json' + + if comp: + all_vars.update({"DOCA": F.SDOCA(Child1=1, Child2=2)}) + all_vars.update({"DOCACHI2": F.SDOCACHI2(Child1=1, Child2=2)}) + all_vars.update({"END_VRHO": F.END_VRHO}) + all_vars.update({"END_VX": F.END_VX}) + all_vars.update({"END_VY": F.END_VY}) + all_vars.update({"END_VZ": F.END_VZ}) + + # duplicated from FC all_vars.update({"ENERGY" : F.ENERGY}) + all_vars.update({"ETA": F.ETA}) + all_vars.update({"FOURMOMENTUM": F.FOURMOMENTUM}) + all_vars.update({"ISBASIC": F.ISBASICPARTICLE}) + + if basic: + all_vars.update({"GHOSTPROB": F.GHOSTPROB}) + all_vars.update({"ISMUON": F.ISMUON}) + all_vars.update({"INMUON": F.INMUON}) + all_vars.update({"INECAL": F.INECAL}) + all_vars.update({"INHCAL": F.INHCAL}) + all_vars.update({"HASBREM": F.HASBREM}) + all_vars.update({"BREMENERGY": F.BREMENERGY}) + all_vars.update({"BREMBENDCORR": F.BREMBENDCORR}) + all_vars.update({"BREMPIDE": F.BREMPIDE}) + all_vars.update({"ECALPIDE": F.ECALPIDE}) + all_vars.update({"ECALPIDMU": F.ECALPIDMU}) + all_vars.update({"HCALPIDE": F.HCALPIDE}) + all_vars.update({"HCALPIDMU": F.HCALPIDMU}) + all_vars.update({"ELECTRONSHOWEREOP": F.ELECTRONSHOWEREOP}) + all_vars.update({"CLUSTERMATCH": F.CLUSTERMATCH_CHI2}) + all_vars.update({"ELECTRONMATCH": F.ELECTRONMATCH_CHI2}) + all_vars.update({"BREMHYPOMATCH": F.BREMHYPOMATCH_CHI2}) + all_vars.update({"ELECTRONENERGY": F.ELECTRONENERGY}) + all_vars.update({"BREMHYPOENERGY": F.BREMHYPOENERGY}) + all_vars.update({"BREMHYPODELTAX": F.BREMHYPODELTAX}) + all_vars.update({"ELECTRONID": F.ELECTRONID}) + all_vars.update({"HCALEOP": F.HCALEOP}) + # Note: the observables for the two functors below are (TRACK_MOM_X, TRACK_MOM_Y, TRACK_MOM_Z}) + # and (TRACK_POS_CLOSEST_TO_BEAM_X, TRACK_POS_CLOSEST_TO_BEAM_Y, TRACK_POS_CLOSEST_TO_BEAM_Z), + # which is why the trailing underscore in the name is added i.e. "TRACK_MOM_" and "TRACK_POS_CLOSEST_TO_BEAM_" + all_vars.update({"TRACK_MOM_": F.TRACK_MOMVEC}) + all_vars.update({"TRACK_POS_CLOSESTTOBEAM_": F.TRACK_POSVEC_CLOSESTTOBEAM}) + + all_vars.update({"IS_ABS_ID_pi": F.IS_ABS_ID("pi+")}) + all_vars.update({"IS_ID_pi": F.IS_ID("pi-")}) + all_vars.update({"PDG_MASS_pi": F.PDG_MASS("pi+")}) + all_vars.update({"SIGNED_DELTA_MASS_pi": F.SIGNED_DELTA_MASS("pi+")}) + all_vars.update({"ABS_DELTA_MASS_pi": F.ABS_DELTA_MASS("pi+")}) + all_vars.update({"IS_NOT_H": F.IS_NOT_H}) + all_vars.update({"IS_PHOTON": F.IS_PHOTON}) + + #if dtf: + # all_vars.update({"DTF_PT": dtf(F.PT)}) + # all_vars.update({"DTF_BPVIPCHI2": dtf(F.BPVIPCHI2(pvs))}) + + #if top and dtf: + # all_vars.update({"DTF_NITER": dtf.NITER}) + # all_vars.update({"DTF_CHI2": dtf.CHI2}) + # all_vars.update({"DTF_NDOF": dtf.NDOF}) + # all_vars.update({"DTF_CHI2DOF": dtf.CHI2DOF}) + + #if comp and dtf: + # all_vars.update({"DTF_MASS": dtf.MASS}) + # all_vars.update({"DTF_MASSERR": dtf.MASSERR}) + # all_vars.update({"DTF_P": dtf.P}) + # all_vars.update({"DTF_PERR": dtf.PERR}) + # all_vars.update({"DTF_TAU": dtf.TAU}) + # all_vars.update({"DTF_TAUERR": dtf.TAUERR}) + # all_vars.update({"DTF_FD": dtf.FD}) + # all_vars.update({"DTF_FDERR": dtf.FDERR}) + + all_vars.update({"MASS": F.MASS}) + #if top: # B + # all_vars.update({"MASSWITHHYPOTHESES": F.MASSWITHHYPOTHESES((939.0, 939.0))}) + #elif comp: # Ds + # all_vars.update( + # {"MASSWITHHYPOTHESES": F.MASSWITHHYPOTHESES((493.7, 493.7, 139.6))} + # ) + if comp: + all_vars.update({"MAXPT": F.MAX(F.PT)}) + all_vars.update({"MAXDOCA": F.MAXSDOCA}) + all_vars.update({"MAXDOCACHI2": F.MAXSDOCACHI2}) + # the above in cut versions. + + # duplicated from FC all_vars.update({ 'MC_MOTHER_ID' : F.VALUE_OR(0) @ mctruth( + # duplicated from FC F.MC_MOTHER(1, F.PARTICLE_ID))}) + + if comp: + all_vars.update({"MINPT": F.MIN(F.PT)}) + all_vars.update({"MINIP": F.MINIP(pvs)}) + all_vars.update({"MINIPCHI2": F.MINIPCHI2(pvs)}) + + if basic: + all_vars.update({"TRACKPT": F.TRACK_PT}) + all_vars.update({"TRACKHISTORY": F.VALUE_OR(-1) @ F.TRACKHISTORY @ F.TRACK}) + all_vars.update({"QOVERP": F.QOVERP @ F.TRACK}) + all_vars.update({"NDOF": F.VALUE_OR(-1) @ F.NDOF @ F.TRACK}) + all_vars.update({"NFTHITS": F.VALUE_OR(-1) @ F.NFTHITS @ F.TRACK}) + all_vars.update({"NHITS": F.VALUE_OR(-1) @ F.NHITS @ F.TRACK}) + all_vars.update({"NUTHITS": F.VALUE_OR(-1) @ F.NUTHITS @ F.TRACK}) + all_vars.update({"NVPHITS": F.VALUE_OR(-1) @ F.NVPHITS @ F.TRACK}) + all_vars.update({"TRACKHASVELO": F.VALUE_OR(-1) @ F.TRACKHASVELO @ F.TRACK}) + all_vars.update({"TRACKHASUT": F.VALUE_OR(-1) @ F.TRACKHASUT @ F.TRACK}) + + all_vars.update({"OBJECT_KEY": F.OBJECT_KEY}) + + # duplicated from FC all_vars.update({ 'ORIGIN_VX' : mctruth(F.ORIGIN_VX) }) + # duplicated from FC all_vars.update({ 'ORIGIN_VY' : mctruth(F.ORIGIN_VY) }) + # duplicated from FC all_vars.update({ 'ORIGIN_VZ' : mctruth(F.ORIGIN_VZ) }) + + # duplicated from FC all_vars.update({"P" : F.P}) + # duplicated from FC all_vars.update({"PARTICLE_ID" : F.PARTICLE_ID}) + all_vars.update({"PHI": F.PHI}) + + # duplicated from FC if basic: + # duplicated from FC all_vars.update({"PID_E" : F.PID_E}) + # duplicated from FC all_vars.update({"PID_K" : F.PID_K}) + # duplicated from FC all_vars.update({"PID_MU" : F.PID_MU}) + # duplicated from FC all_vars.update({"PID_P" : F.PID_P}) + # duplicated from FC all_vars.update({"PID_PI" : F.PID_PI}) + # duplicated from FC #all_vars.update({"PROBNN_D" : F.PROBNN_D}) + # duplicated from FC all_vars.update({"PROBNN_E" : F.PROBNN_E}) + # duplicated from FC all_vars.update({"PROBNN_GHOST" : F.PROBNN_GHOST}) + # duplicated from FC all_vars.update({"PROBNN_K" : F.PROBNN_K}) + # duplicated from FC all_vars.update({"PROBNN_MU" : F.PROBNN_MU}) + # duplicated from FC all_vars.update({"PROBNN_P" : F.PROBNN_P}) + # duplicated from FC all_vars.update({"PROBNN_PI" : F.PROBNN_PI}) + + # duplicated from FC all_vars.update({ 'PT' : F.PT }) + # duplicated from FC all_vars.update({ 'PX' : F.PX }) + # duplicated from FC all_vars.update({ 'PY' : F.PY }) + # duplicated from FC all_vars.update({ 'PZ' : F.PZ }) + all_vars.update({"ABS_PX": F.ABS @ F.PX}) + + all_vars.update({"REFERENCEPOINT_X": F.REFERENCEPOINT_X}) + all_vars.update({"REFERENCEPOINT_Y": F.REFERENCEPOINT_Y}) + all_vars.update({"REFERENCEPOINT_Z": F.REFERENCEPOINT_Z}) + + if comp: + all_vars.update({"SDOCA": F.SDOCA(1, 2)}) + all_vars.update({"SDOCACHI2": F.SDOCACHI2(1, 2)}) + if basic: + all_vars.update({"SHOWER_SHAPE": F.CALO_NEUTRAL_SHOWER_SHAPE}) + + if comp: + all_vars.update({"SUBCOMB12_MM": F.SUBCOMB(Functor=F.MASS, Indices=(1, 2))}) + all_vars.update({"SUMPT": F.SUM(F.PT)}) + + if basic: + all_vars.update({"TX": F.TX}) + all_vars.update({"TY": F.TY}) + + print(f"### For {ptype} returning variables {all_vars.functor_dict.keys()}") + return all_vars + + +def event_variables(PVs, ODIN, decreports, lines, hlt1lines): + """ + event variables + """ + + evt_vars = FunctorCollection({}) + evt_vars += FC.EventInfo() + + evt_vars += FC.SelectionInfo(selection_type="Hlt2", trigger_lines=lines) + evt_vars += FC.SelectionInfo(selection_type="Hlt1", trigger_lines=hlt1lines) + # duplicated from FC if ODIN: + # duplicated from FC evt_vars.update({ 'BUNCHCROSSING_ID' : F.BUNCHCROSSING_ID(ODIN) }) + # duplicated from FC evt_vars.update({ 'BUNCHCROSSING_TYPE' : F.BUNCHCROSSING_TYPE(ODIN) }) + + if decreports: + evt_vars.update( + { + "DECISIONS": F.DECISIONS( + Lines=[bd2dsk_line + "Decision"], DecReports=decreports + ) + } + ) + evt_vars.update( + { + "DECREPORTS_FILTER": F.DECREPORTS_FILTER( + Lines=[bd2dsk_line + "Decision"], DecReports=decreports + ) + } + ) + + if ODIN: + evt_vars.update({"EVENTTYPE": F.EVENTTYPE(ODIN)}) + + # duplicated from FC evt_vars.update({ 'GPSTIME' : F.GPSTIME(ODIN) }) + # duplicated from FC evt_vars.update({ 'ODINTCK' : F.ODINTCK(ODIN) }) + + evt_vars.update({"PV_SIZE": F.SIZE(PVs)}) + # duplicated from FC evt_vars.update({ 'GPSTIME' : F.GPSTIME(ODIN) }) + # duplicated from FC evt_vars.update({ 'ODINTCK' : F.ODINTCK(ODIN) }) + + if decreports: + evt_vars.update({"TCK": F.TCK(decreports)}) + + print(f"### For event returning variables {evt_vars.functor_dict.keys()}") + return evt_vars + + +def tree_template(decay_descriptor, line_name, isturbo, Hlt2_decisions, QQbar2mumu_data): + evtpath_prefix = "/Event/Spruce/" + if isturbo: + evtpath_prefix = "/Event/HLT2/" + + #QQbar2mumu_data = get_particles(evtpath_prefix+f"{line_name}/Particles") + #QQbar2mumu_data = make_jpsi(minPIDmu=-999) + + pvs = get_pvs() + + Hlt1_decisions = [ +# Global line + "Hlt1GlobalDecision", "Hlt1PhysDecision", +# Physics lines + "Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision", "Hlt1D2KKDecision", "Hlt1D2KPiDecision", "Hlt1D2PiPiDecision", "Hlt1Dst2D0PiDecision", "Hlt1KsToPiPiDecision", "Hlt1KsToPiPiDoubleMuonMisIDDecision", "Hlt1TwoTrackKsDecision", "Hlt1TwoKsDecision", "Hlt1LambdaLLDetachedTrackDecision", "Hlt1XiOmegaLLLDecision", "Hlt1SingleHighPtMuonDecision", "Hlt1SingleHighPtMuonNoMuIDDecision", "Hlt1DiMuonHighMassDecision", "Hlt1DiMuonDisplacedDecision", "Hlt1DiMuonSoftDecision", "Hlt1TrackMuonMVADecision", "Hlt1DiMuonNoIP_SSDecision", "Hlt1DiMuonDrellYan_VLowMassDecision", "Hlt1DiMuonDrellYan_VLowMass_SSDecision", "Hlt1DiMuonDrellYanDecision", "Hlt1DiMuonDrellYan_SSDecision", "Hlt1DetJpsiToMuMuPosTagLineDecision", "Hlt1DetJpsiToMuMuNegTagLineDecision", "Hlt1TrackElectronMVADecision", "Hlt1SingleHighPtElectronDecision", "Hlt1DiElectronDisplacedDecision", "Hlt1SingleHighEtDecision", "Hlt1DiPhotonHighMassDecision", "Hlt1Pi02GammaGammaDecision", "Hlt1DiElectronHighMass_SSDecision", "Hlt1DiElectronHighMassDecision", "Hlt1DiMuonNoIPDecision" +## alignment lines +# "Hlt1RICH1AlignmentDecision", "Hlt1RICH2AlignmentDecision", "Hlt1D2KPiAlignmentDecision", "Hlt1Dst2D0PiAlignmentDecision", "Hlt1MaterialVertexSeedsDownstreamzDecision", "Hlt1MaterialVertexSeeds_DWFSDecision", "Hlt1DiMuonHighMassAlignmentDecision", "Hlt1DiMuonJpsiMassAlignmentDecision", "Hlt1OneMuonTrackLineDecision", "Hlt1BeamGasDecision", +## smog2 lines +# "Hlt1SMOG2D2KpiDecision", "Hlt1VeloMicroBiasDecision", "Hlt1SMOG2etacToppDecision", "Hlt1SMOG2KsTopipiDecision", "Hlt1SMOG2etacToppDecision", "Hlt1SMOG2KsTopipiDecision", "Hlt1SMOG22BodyGenericDecision", "Hlt1SMOG22BodyGenericLowPtDecision", "Hlt1SMOG2SingleTrackVeryHighPtDecision", "Hlt1SMOG2SingleTrackHighPtDecision", "Hlt1SMOG2DiMuonHighMassDecision", "Hlt1SMOG2SingleMuonDecision", "Hlt1SMOG2L0ToppiDecision", +## bgi lines +# "Hlt1BGIPseudoPVsNoBeamDecision", "Hlt1BGIPseudoPVsBeamOneDecision", "Hlt1BGIPseudoPVsBeamTwoDecision", "Hlt1BGIPseudoPVsUpBeamBeamDecision", "Hlt1BGIPseudoPVsDownBeamBeamDecision", "Hlt1BGIPseudoPVsIRBeamBeamDecision", "Hlt1BGIPVsCylNoBeamDecision", "Hlt1BGIPVsCylBeamOneDecision", "Hlt1BGIPVsCylBeamTwoDecision", "Hlt1BGIPVsCylUpBeamBeamDecision", "Hlt1BGIPVsCylDownBeamBeamDecision", "Hlt1BGIPVsCylIRBeamBeamDecision", "Hlt1BGIVeloClustersMicroBiasDecision", "Hlt1BGICaloDigitsDecision", "Hlt1BGIPlumeActivityDecision", +## setup hlt1 nodes lines +# "Hlt1ODINCalibDecision", "Hlt1TAEPassthroughDecision", "Hlt1ErrorBankDecision", "Hlt1VeloMicroBiasVeloClosingDecision", "Hlt1GECPassthroughDecision", "Hlt1SMOG2BENoBiasDecision", "Hlt1SMOG2PassThroughLowMult5Decision", "Hlt1SMOG2BELowMultElectronsDecision", "Hlt1SMOG2MinimumBiasDecision", "Hlt1PassthroughPVinSMOG2Decision" + ] + + + composite_variables = FunctorCollection({ + #"ID": F.PARTICLE_ID, + #"KEY": F.OBJECT_KEY, + #"PT": F.PT, + #"PX": F.PX, + #"PY": F.PY, + #"PZ": F.PZ, + #"ENERGY": F.ENERGY, + #"P": F.P, + #"M": F.MASS, + #"ETA": F.ETA, + #"PHI": F.PHI, + #"ENDVERTEX_CHI2NDOF": F.CHI2DOF, + #"FOURMOMENTUM": F.FOURMOMENTUM, + #"BPVDIRA": F.BPVDIRA(pvs), + #"BPVX": F.BPVX(pvs), + #"BPVY": F.BPVY(pvs), + #"BPVZ": F.BPVZ(pvs), + #"END_VX": F.END_VX, + #"END_VY": F.END_VY, + #"END_VZ": F.END_VZ, + "END_VZ_ERR":F.SQRT @ F.CALL(2,2) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "END_VY_ERR":F.SQRT @ F.CALL(1,1) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "END_VX_ERR":F.SQRT @ F.CALL(0,0) @ F.POS_COV_MATRIX @ F.ENDVERTEX, + "BPVZ_ERR": F.SQRT @ F.CALL(2,2) @ F.POS_COV_MATRIX @ F.BPV(pvs), + "BPVY_ERR": F.SQRT @ F.CALL(1,1) @ F.POS_COV_MATRIX @ F.BPV(pvs), + "BPVX_ERR": F.SQRT @ F.CALL(0,0) @ F.POS_COV_MATRIX @ F.BPV(pvs), + #"TAU": F.BPVLTIME(pvs), + #"BPVFDCHI2": F.BPVFDCHI2(pvs), + #"BPVIPCHI2": F.BPVIPCHI2(pvs) + }) + + #composite_variables += Kinematics() + #composite_variables += ParticleID(extra_info=True) + composite_variables += HltTisTos( selection_type="Hlt1", trigger_lines=Hlt1_decisions, data=QQbar2mumu_data) + if not isturbo: + composite_variables += HltTisTos( selection_type="Hlt2", trigger_lines=Hlt2_decisions, data=QQbar2mumu_data) + + daughter_variables = FunctorCollection({ + #"ID": F.PARTICLE_ID, + #"PT": F.PT, + #"PX": F.PX, + #"PY": F.PY, + #"PZ": F.PZ, + #"M": F.MASS, + #"ENERGY": F.ENERGY, + #"P": F.P, + #"ETA": F.ETA, + #"PHI": F.PHI, + #"Track_CHI2NDOF": F.CHI2DOF, + #"ProbNNmu": F.PROBNN_MU, + #"PIDmu": F.PID_MU, + #"IsMuon": F.ISMUON, + #"GhostProb": F.GHOSTPROB, + #"FOURMOMENTUM": F.FOURMOMENTUM, + "PERR": F.SQRT @ F.PERR2, + "PZERR": F.SQRT @ F.CALL(2,2) @ F.THREE_MOM_COV_MATRIX, + "TXERR": F.SQRT @ F.CALL(2,2) @ F.TRACK_COVARIANCE @ F.STATE_AT("FirstMeasurement")@ F.TRACK, + "TYERR": F.SQRT @ F.CALL(3,3) @ F.TRACK_COVARIANCE @ F.STATE_AT("FirstMeasurement")@ F.TRACK, + "COVTXTY": F.CALL(2,3) @ F.TRACK_COVARIANCE @ F.STATE_AT("FirstMeasurement")@ F.TRACK, + }) + + #daughter_variables += Kinematics() + #daughter_variables += ParticleID(extra_info=True) + +# line_prefilter = create_lines_filter(name=f"HLT_PASS{line_name}", lines=[line_name]) + + #define event level variables + odin = get_odin() + decreports = None + rec_sum=get_rec_summary() + event_info = event_variables(pvs, odin, decreports, [line_name], Hlt1_decisions) + FunctorCollection({ + "nPVs": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nPVs"), + "nTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTracks"), + "nLongTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nLongTracks"), + "nDownstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nDownstreamTracks"), + "nUpstreamTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUpstreamTracks"), + "nVeloTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloTracks"), + "nBackTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nBackTracks"), + "nGhosts": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nGhosts"), + "nRich1Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich1Hits"), + "nRich2Hits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nRich2Hits"), + "nVeloClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVeloClusters"), + "nVPClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nVPClusters"), + "nITClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nITClusters"), + "nTTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nTTClusters"), + "nUTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nUTClusters"), + "nOTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nOTClusters"), + "nFTClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nFTClusters"), + "nSPDhits": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nSPDhits"), + "eCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"eCalTot"), + "hCalTot": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"hCalTot"), + "nEcalClusters": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nEcalClusters"), + "nMuonCoordsS0": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS0"), + "nMuonCoordsS1": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS1"), + "nMuonCoordsS2": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS2"), + "nMuonCoordsS3": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS3"), + "nMuonCoordsS4": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonCoordsS4"), + "nMuonTracks": F.VALUE_OR(-1) @F.RECSUMMARY_INFO(rec_sum,"nMuonTracks"), + "ALLPVX": F.ALLPVX(pvs), + "ALLPVY": F.ALLPVY(pvs), + "ALLPVZ": F.ALLPVZ(pvs), + }) + + # get trueid bkgcat info + MC_TRUTH = MCTruthAndBkgCat(QQbar2mumu_data, name='MCTruthAndBkgCat_'+line_name+"_{hash}") + MCMOTHER_ID = lambda n: F.VALUE_OR(0) @ MC_TRUTH(F.MC_MOTHER(n, F.PARTICLE_ID)) + MCMOTHER_KEY = lambda n: F.VALUE_OR(-1) @ MC_TRUTH(F.MC_MOTHER(n, F.OBJECT_KEY)) + + trueid_bkgcat_info = FunctorCollection({ + #"TRUEID": F.VALUE_OR(0) @ MC_TRUTH(F.PARTICLE_ID), + "TRUEKEY": F.VALUE_OR(-1) @ MC_TRUTH(F.OBJECT_KEY), + #"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), + #"TRUEP": MC_TRUTH(F.P), + "TRUEM": MC_TRUTH(F.MASS), + "TRUEETA": MC_TRUTH(F.ETA), + "TRUEPHI": MC_TRUTH(F.PHI), + "TRUEFOURMOMENTUM": MC_TRUTH(F.FOURMOMENTUM), + #"MC_MOTHER_ID": MCMOTHER_ID(1), + #"MC_MOTHER_KEY": MCMOTHER_KEY(1), + #"MC_GD_MOTHER_ID": MCMOTHER_ID(2), + #"MC_GD_MOTHER_KEY": MCMOTHER_KEY(2), + #"MC_GD_GD_MOTHER_ID": MCMOTHER_ID(3), + #"MC_GD_GD_MOTHER_KEY": MCMOTHER_KEY(3), + "TRUEORIGIN_VX": MC_TRUTH(F.ORIGIN_VX), + "TRUEORIGIN_VY": MC_TRUTH(F.ORIGIN_VY), + "TRUEORIGIN_VZ": MC_TRUTH(F.ORIGIN_VZ), + #"TRUEEND_VX": MC_TRUTH(F.END_VX), + #"TRUEEND_VY": MC_TRUTH(F.END_VY), + #"TRUEEND_VZ": MC_TRUTH(F.END_VZ), + "BKGCAT": MC_TRUTH.BkgCat, + }) + + variables = { + "QQbar": composite_variables + all_variables(pvs, MC_TRUTH, _composite) + trueid_bkgcat_info, + "mup": daughter_variables + all_variables(pvs, MC_TRUTH, _basic) + trueid_bkgcat_info, + "mum": daughter_variables + all_variables(pvs, MC_TRUTH, _basic) + trueid_bkgcat_info, + } + + #define FunTuple instance + my_tuple = Funtuple( + name=line_name+"_nopid", + tuple_name="DecayTree", + fields=decay_descriptor, + variables=variables, + event_variables=event_info, + store_multiple_cand_info = True, + inputs=QQbar2mumu_data) + + return my_tuple + +#def line_prefilter(line_name): +# return create_lines_filter(name=f"HLT_PASS{line_name}", lines=[line_name]) + diff --git a/QuarkoniaToMuMu2024/log b/QuarkoniaToMuMu2024/log new file mode 100644 index 0000000000..e69de29bb2 -- GitLab From b2b83d6046910671aa16f93abb9e2fa1877dcd82 Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus959.cern.ch> Date: Thu, 28 Nov 2024 09:44:45 +0100 Subject: [PATCH 10/12] bug fix upsilon --- QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py | 2 +- QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py | 2 +- QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py index fcfb66d7df..c7614b867d 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon1S.py @@ -28,7 +28,7 @@ def main(options: Options): my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [require_pvs(make_pvs()), my_tuple_nopid], + 'Alg_tuple_nopid': [require_pvs(make_pvs()), my_tuple_nopid], 'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py index 54e5a79bc7..8fd3e9496e 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon2S.py @@ -28,7 +28,7 @@ def main(options: Options): my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [require_pvs(make_pvs()), my_tuple_nopid], + 'Alg_tuple_nopid': [require_pvs(make_pvs()), my_tuple_nopid], 'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } diff --git a/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py b/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py index 65890de8c4..05fbcd49e5 100644 --- a/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py +++ b/QuarkoniaToMuMu2024/dv_mc_Upsilon3S.py @@ -28,7 +28,7 @@ def main(options: Options): my_mctuple = dv_mctree.mctree_template(decay_descriptor_mctree) user_algorithms = { - 'Alg_tuple': [require_pvs(make_pvs()), my_tuple_nopid], + 'Alg_tuple_nopid': [require_pvs(make_pvs()), my_tuple_nopid], 'Alg_tuple': [my_filter, my_tuple], 'Alg_mctuple': [my_mctuple], } -- GitLab From 2ac0a1390d2f9d2ef11a64a1c01e0d9e0d61008e Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus904.cern.ch> Date: Fri, 13 Dec 2024 10:19:33 +0100 Subject: [PATCH 11/12] test with new hlt1 noUT MC --- QuarkoniaToMuMu2024/info.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/QuarkoniaToMuMu2024/info.yaml b/QuarkoniaToMuMu2024/info.yaml index 324fd1e0ec..357bb3dfc5 100644 --- a/QuarkoniaToMuMu2024/info.yaml +++ b/QuarkoniaToMuMu2024/info.yaml @@ -23,10 +23,10 @@ defaults: {%- for module, channel, eventtype, dv_input_process in entrypoints %} {%- for polarity_mc, polarity_mc_jobtitle, nu, n_u, dddb, conddb, mcversion_jobtitle, BKK_label1, BKK_label2, simversion in MC_conditions %} -MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_{{mcversion_jobtitle}}_ROOT: +MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_{{mcversion_jobtitle}}_ROOT_HLT1NoUT: application: "DaVinci/v64r12@x86_64_v3-el9-gcc13+detdesc-opt+g" input: - bk_query: "/MC/{{BKK_label1}}/Beam6800GeV-{{BKK_label2}}-{{ polarity_mc }}-Nu{{ nu }}-25ns-Pythia8/{{simversion}}/HLT2-2024.W31.34/{{ eventtype }}/DST" + bk_query: "/MC/{{BKK_label1}}/Beam6800GeV-{{BKK_label2}}-{{ polarity_mc }}-Nu{{ nu }}-25ns-Pythia8/{{simversion}}/HLT1_2024.W31.34_noUT/HLT2-2024.W31.34/{{ eventtype }}/DST" keep_running: true output: QQbar2mumu_MC24_tuple.ROOT options: -- GitLab From d77b618f2ceb459e9cc88e5c56538055b2ea19f8 Mon Sep 17 00:00:00 2001 From: Mengzhen Wang <mengzhen@lxplus916.cern.ch> Date: Fri, 13 Dec 2024 14:47:40 +0100 Subject: [PATCH 12/12] bug fix --- QuarkoniaToMuMu2024/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QuarkoniaToMuMu2024/info.yaml b/QuarkoniaToMuMu2024/info.yaml index 357bb3dfc5..41c5815222 100644 --- a/QuarkoniaToMuMu2024/info.yaml +++ b/QuarkoniaToMuMu2024/info.yaml @@ -26,7 +26,7 @@ defaults: MC_{{module}}_Nu{{n_u}}_{{polarity_mc_jobtitle}}_{{mcversion_jobtitle}}_ROOT_HLT1NoUT: application: "DaVinci/v64r12@x86_64_v3-el9-gcc13+detdesc-opt+g" input: - bk_query: "/MC/{{BKK_label1}}/Beam6800GeV-{{BKK_label2}}-{{ polarity_mc }}-Nu{{ nu }}-25ns-Pythia8/{{simversion}}/HLT1_2024.W31.34_noUT/HLT2-2024.W31.34/{{ eventtype }}/DST" + bk_query: "/MC/{{BKK_label1}}/Beam6800GeV-{{BKK_label2}}-{{ polarity_mc }}-Nu{{ nu }}-25ns-Pythia8/{{simversion}}/HLT1_2024.W31.34_noUT/HLT2-2024.W31.34/{{ eventtype }}/HLT2.DST" keep_running: true output: QQbar2mumu_MC24_tuple.ROOT options: -- GitLab