diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/__init__.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/__init__.py index 9d62208085f7fb562a1cadb57d5ca29907798d63..a6bd8e46693cd3fa3088af21eaccaf01dddf794a 100644 --- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/__init__.py +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/__init__.py @@ -16,6 +16,8 @@ from . import b_to_hhgamma_gamma_to_ee from . import b_to_hhhgamma from . import b_to_hhhgamma_gamma_to_ee from . import B2ll_lines +from . import qqbar_to_emu +from . import upsilon_to_ll from .strange import all_lines as strange_lines # provide "all_lines" for correct registration by the overall HLT2 lines module @@ -24,5 +26,7 @@ all_lines.update(b_to_hhgamma.all_lines) all_lines.update(b_to_hhgamma_gamma_to_ee.all_lines) all_lines.update(b_to_hhhgamma.all_lines) all_lines.update(b_to_hhhgamma_gamma_to_ee.all_lines) +all_lines.update(qqbar_to_emu.all_lines) all_lines.update(B2ll_lines.all_lines) all_lines.update(strange_lines) +all_lines.update(upsilon_to_ll.all_lines) diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/builders/qqbar_builder.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/builders/qqbar_builder.py new file mode 100644 index 0000000000000000000000000000000000000000..4b104337f032268c82edf412dfd5fa460e27ccb4 --- /dev/null +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/builders/qqbar_builder.py @@ -0,0 +1,457 @@ +############################################################################## +# (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. # +############################################################################### +""" +Definiton of dedicated prompt builders for LFV lines of qqbar -> emu (detached lines are using standard make_rd_detached_mue) +- Phi(1020) -> E Mu + SS prompt +- J/Psi(1S) -> E Mu + SS prompt +- Upsilon(1S) -> E Mu + SS + +author: Miroslav Saur +date: 27.12.2021 + +""" + +import Functors as F +from Functors.math import in_range + +from GaudiKernel.SystemOfUnits import MeV, GeV + +from RecoConf.reconstruction_objects import make_pvs_v2 as make_pvs + +from Hlt2Conf.algorithms_thor import require_all, ParticleFilter +from PyConf import configurable +from Hlt2Conf.algorithms import ParticleCombinerWithPVs +from Hlt2Conf.lines.rd.builders.rdbuilder_thor import make_rd_tauons_hadronic_decay + +from Hlt2Conf.standard_particles import ( + make_detached_mue_with_brem, + make_detached_dielectron_with_brem, + make_detached_mumu, + make_long_electrons_with_brem, + make_ismuon_long_muon, +) + + +# filter based on the rd_detached_mue / make_detached_mue_with_brem with zero cuts on IP and added combination cuts +@configurable +def make_prompt_mue( + name="prompt_mue_builder", + min_dilepton_mass=0.0 * MeV, + max_dilepton_mass=6000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + max_ipchi2_mue=50, + parent_id="J/psi(1S)", + min_probnn_mu=0.0, + min_PIDmu=0.0, + IsMuon=True, + min_PIDe=2.0, + min_pt_e=0.5 * GeV, + min_pt_mu=0.5 * GeV, + minipchi2=0, # must be 0 for a prompt builder + min_bpvvdchi2=0.0, # must be 0 for a prompt builder + max_vchi2ndof=10.0, + max_trghostprob=0.2, + same_sign=False, +): + """ + Make the detached muon-electron pair, opposite-sign or same-sign. + """ + pvs = make_pvs() + dileptons = make_detached_mue_with_brem( + dilepton_ID=parent_id, + min_probnn_mu=min_probnn_mu, + min_PIDmu=0.0, + IsMuon=IsMuon, + min_PIDe=min_PIDe, + same_sign=same_sign, + min_pt_e=min_pt_e, + min_pt_mu=min_pt_mu, + minipchi2_track=minipchi2, + min_bpvvdchi2=min_bpvvdchi2, + max_vchi2ndof=max_vchi2ndof, + max_trghostprob=max_trghostprob, + ) + code = require_all( + in_range(min_dilepton_mass, F.MASS, max_dilepton_mass), + F.PT > min_dilepton_pt, + F.BPVIPCHI2(pvs) < max_ipchi2_mue, + ) + return ParticleFilter(dileptons, F.FILTER(code), name=name) + + +@configurable +def make_prompt_etau( + name="prompt_mue_builder", + min_dilepton_mass=7000.0 * MeV, + max_dilepton_mass=13000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + max_ipchi2_etau=50, + parent_id="Upsilon(1S)", + min_PIDe=2.0, + max_adocachi2=30.0, + min_pt_e=0.5 * GeV, + min_pt_tau=0.3 * GeV, + minipchi2=0, # must be 0 for a prompt builder + min_bpvvdchi2=0.0, # must be 0 for a prompt builder + max_vchi2ndof=10.0, +): + """ + Make the detached electron-tau pair, opposite-sign for now. + """ + pvs = make_pvs() + descriptor = "[{} -> e+ tau-]cc".format(parent_id) + taus = make_rd_tauons_hadronic_decay( + best_pi_ipchi2_min=minipchi2 + ) # Make them prompt(?) + electrons = make_long_electrons_with_brem() + daughters_code = { + "tau+": f"(PT > {min_pt_tau}) & (MIPCHI2DV(PRIMARY) > {minipchi2})", # Do we need to add a minipchi2 to the taus also for promptness? + "tau-": f"(PT > {min_pt_tau}) & (MIPCHI2DV(PRIMARY) > {minipchi2})", + "e+": f"(PIDe > {min_PIDe}) & (PT > {min_pt_e}) & (MIPCHI2DV(PRIMARY) > {minipchi2})", + "e-": f"(PIDe > {min_PIDe}) & (PT > {min_pt_e}) & (MIPCHI2DV(PRIMARY) > {minipchi2})", + } + combination_code = f"ADOCACHI2CUT({max_adocachi2}, '')" + vertex_code = ( + f"(VFASPF(VCHI2/VDOF) < {max_vchi2ndof}) & (BPVVDCHI2() > {min_bpvvdchi2})" + ) + etau = ParticleCombinerWithPVs( + particles=[electrons, taus], + pvs=pvs, + DaughtersCuts=daughters_code, + DecayDescriptor=descriptor, + CombinationCut=combination_code, + MotherCut=vertex_code, + ) + code = require_all( + in_range(min_dilepton_mass, F.MASS, max_dilepton_mass), + F.PT > min_dilepton_pt, + F.BPVIPCHI2(pvs) < max_ipchi2_etau, + ) + return ParticleFilter(etau, F.FILTER(code), name=name) + + +@configurable +def make_prompt_mutau( + name="prompt_mue_builder", + min_dilepton_mass=7000.0 * MeV, + max_dilepton_mass=13000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + max_ipchi2_mutau=50, + parent_id="Upsilon(1S)", + min_probnn_mu=0.2, + min_PIDmu=0.0, + IsMuon=False, + min_pt_mu=0.0 * GeV, + max_adocachi2=30.0, + min_pt_tau=0.3 * GeV, + minipchi2=0, # must be 0 for a prompt builder + min_bpvvdchi2=0.0, # must be 0 for a prompt builder + max_vchi2ndof=10.0, +): + """ + Make the detached electron-tau pair, opposite-sign for now. + """ + pvs = make_pvs() + descriptor = "[{} -> mu+ tau-]cc".format(parent_id) + taus = make_rd_tauons_hadronic_decay( + best_pi_ipchi2_min=minipchi2 + ) # Make them prompt(?) + muons = make_ismuon_long_muon() + daughters_code = { + "tau+": f"(PT > {min_pt_tau}) & (MIPCHI2DV(PRIMARY) > {minipchi2})", # Do we need to add a minipchi2 to the taus also for promptness? + "tau-": f"(PT > {min_pt_tau}) & (MIPCHI2DV(PRIMARY) > {minipchi2})", + "mu+": f"(PROBNNmu > {min_probnn_mu}) & (PIDmu > {min_PIDmu}) & (PT > {min_pt_mu}) & (MIPCHI2DV(PRIMARY) > {minipchi2})", + "mu-": f"(PROBNNmu > {min_probnn_mu}) & (PIDmu > {min_PIDmu}) & (PT > {min_pt_mu}) & (MIPCHI2DV(PRIMARY) > {minipchi2})", + } + if IsMuon: + daughters_code["mu+"] = daughters_code["mu+"] + " & ISMUON" + daughters_code["mu-"] = daughters_code["mu-"] + " & ISMUON" + combination_code = f"ADOCACHI2CUT({max_adocachi2}, '')" + vertex_code = ( + f"(VFASPF(VCHI2/VDOF) < {max_vchi2ndof}) & (BPVVDCHI2() > {min_bpvvdchi2})" + ) + mutau = ParticleCombinerWithPVs( + particles=[muons, taus], + pvs=pvs, + DaughtersCuts=daughters_code, + DecayDescriptor=descriptor, + CombinationCut=combination_code, + MotherCut=vertex_code, + ) + code = require_all( + in_range(min_dilepton_mass, F.MASS, max_dilepton_mass), + F.PT > min_dilepton_pt, + F.BPVIPCHI2(pvs) < max_ipchi2_mutau, + ) + return ParticleFilter(mutau, F.FILTER(code), name=name) + + +@configurable +def make_prompt_tautau( + name="prompt_tautau_builder", + min_dilepton_mass=7000.0 * MeV, + max_dilepton_mass=13000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + max_ipchi2_tautau=50, + max_adocachi2=30.0, + parent_id="Upsilon(1S)", + min_pt_tau=0.3 * GeV, + minipchi2=0, # must be 0 for a prompt builder + min_bpvvdchi2=0.0, # must be 0 for a prompt builder + max_vchi2ndof=10.0, +): + """ + Make the detached muon-electron pair, opposite-sign or same-sign. + """ + pvs = make_pvs() + taus = make_rd_tauons_hadronic_decay( + best_pi_ipchi2_min=minipchi2 + ) # Make them prompt(?) + descriptor = "{} -> tau+ tau-".format(parent_id) + combination_code = f"ADOCACHI2CUT({max_adocachi2}, '')" + vertex_code = ( + f"(VFASPF(VCHI2/VDOF) < {max_vchi2ndof}) & (BPVVDCHI2() > {min_bpvvdchi2})" + ) + daughters_code = { + "tau+": f"(PT > {min_pt_tau})", # Do we need to add a minipchi2 to the taus also for promptness? + "tau-": f"(PT > {min_pt_tau})", + } + tautau = ParticleCombinerWithPVs( + particles=[taus, taus], + pvs=pvs, + DaughtersCuts=daughters_code, + DecayDescriptor=descriptor, + CombinationCut=combination_code, + MotherCut=vertex_code, + ) + + code = require_all( + in_range(min_dilepton_mass, F.MASS, max_dilepton_mass), + F.PT > min_dilepton_pt, + F.BPVIPCHI2(pvs) < max_ipchi2_tautau, + ) + return ParticleFilter(tautau, F.FILTER(code), name=name) + + +# filter based on the rd_detached_mue / make_detached_mue_with_brem with zero cuts on IP and added combination cuts +@configurable +def make_prompt_mumu( + name="prompt_mumu_builder", + min_dilepton_mass=0.0 * MeV, + max_dilepton_mass=6000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + max_ipchi2_mumu=50, + parent_id="J/psi(1S)", + min_probnn_mu=0.0, + IsMuon=True, + min_pt_mu=0.5 * GeV, + minipchi2=0, # must be 0 for a prompt builder + min_bpvvdchi2=0.0, # must be 0 for a prompt builder + max_trghostprob=0.2, +): + """ + Make the detached muon-electron pair, opposite-sign or same-sign. + """ + pvs = make_pvs() + dileptons = make_detached_mumu( + adocachi2cut=30, + vfaspfchi2ndof=10, + probnn_mu=min_probnn_mu, + pt_mu=min_pt_mu, + minipchi2=minipchi2, + bpvvdchi2=min_bpvvdchi2, + trghostprob=max_trghostprob, + ) + code = require_all( + in_range(min_dilepton_mass, F.MASS, max_dilepton_mass), + F.PT > min_dilepton_pt, + F.BPVIPCHI2(pvs) < max_ipchi2_mumu, + ) + return ParticleFilter(dileptons, F.FILTER(code), name=name) + + +@configurable +def make_prompt_ee( + name="prompt_ee_builder", + opposite_sign=True, + PIDe_min=2.0, + pt_e=0.5 * GeV, + minipchi2=0, # must be 0 for a prompt builder + max_ipchi2_ee=50, + trghostprob=0.2, + parent_id="J/psi(1S)", + min_dilepton_pt=0 * GeV, + min_dilepton_mass=0 * MeV, + max_dilepton_mass=6000 * MeV, + adocachi2cut=30, + max_vchi2ndof=7.5, +): + """ + Make the detached muon-electron pair, opposite-sign or same-sign. + """ + pvs = make_pvs() + dileptons = make_detached_dielectron_with_brem( + opposite_sign=opposite_sign, + PIDe_min=PIDe_min, + pt_e=pt_e, + minipchi2=minipchi2, + trghostprob=trghostprob, + dielectron_ID=parent_id, + pt_diE=min_dilepton_pt, + m_diE_min=min_dilepton_mass, + m_diE_max=max_dilepton_mass, + adocachi2cut=adocachi2cut, + vfaspfchi2ndof=max_vchi2ndof, + ) + code = require_all( + in_range(min_dilepton_mass, F.MASS, max_dilepton_mass), + F.PT > min_dilepton_pt, + F.BPVIPCHI2(pvs) < max_ipchi2_ee, + ) + return ParticleFilter(dileptons, F.FILTER(code), name=name) + + +""" +### dedicated filters and builders for making up everything from the basic particles; keeping it now for posible revison but to be removed before merging into master +@configurable +def make_prompt_long_electrons(pvs, + make_particles=make_long_electrons_with_brem, + name="prompt_long_electrons", + min_pt_e=0. * MeV, + min_p_e=0. * GeV, + min_ipchi2_electron=0, + min_ip_electron=0, + min_pid_electron=-5, + max_ghostprob_electron=0.7, + max_trackchi2_electron=None, + max_ipchi2_electron=None): + + #pvs = make_pvs() + + code = require_all(F.PT > min_pt_e, F.P > min_p_e, + F.MINIPCHI2(pvs) > min_ipchi2_electron, + F.MINIP(pvs) > min_ip_electron, + F.PID_MU > min_pid_electron, + F.GHOSTPROB < max_ghostprob_electron) + + if max_trackchi2_electron is not None: + code &= (F.CHI2 < max_trackchi2_electron) + if max_ipchi2_electron is not None: + code &= (F.MINIPCHI2(pvs) < max_ipchi2_electron) + + return ParticleFilter(make_particles(), name=name, Cut=F.FILTER()) + + +@configurable +def make_prompt_long_muons(pvs, + make_particles=make_long_muons, + name="prompt_long_muons", + min_pt_mu=0. * MeV, + min_p_mu=0. * GeV, + min_ipchi2_muon=0, + min_ip_muon=0, + min_pid_muon=-5, + max_ghostprob_muon=0.7, + max_trackchi2_muon=None, + max_ipchi2_muon=None): + + #pvs = make_pvs() + + code = require_all(F.PT > min_pt_mu, F.ISMUON, F.P > min_p_mu, + F.MINIPCHI2(pvs) > min_ipchi2_muon, + F.MINIP(pvs) > min_ip_muon, F.PID_MU > min_pid_muon, + F.GHOSTPROB < max_ghostprob_muon) + + if max_trackchi2_muon is not None: + code &= (F.CHI2 < max_trackchi2_muon) + if max_ipchi2_muon is not None: + code &= (F.MINIPCHI2(pvs) < max_ipchi2_muon) + + return ParticleFilter(make_particles(), name=name, Cut=F.FILTER(code)) + + +""" +""" +@configurable #currenctly does not work, no events selected even after removing all the requirements +def make_prompt_mue(name='prompt_mue_builder', + DecayDescriptor='[J/psi(1S) -> mu+ e-]CC', + min_dilepton_mass=0. * MeV, + max_dilepton_mass=100000. * MeV, + min_pt_mue=1. * GeV, + min_DIRA_mue=0.95, + min_bpvvdchi2_mue=100., + max_ipchi2_mue=20, + max_vertexchi2_mue=20, + max_vchi2ndof=10, + min_pt_mu=0.25 * GeV, + min_p_mu=2. * GeV, + min_ipchi2_muon=0, + min_ip_muon=0, + max_ghostprob_muon=0.5, + min_pid_muon=-0, + min_pt_e=0.25 * GeV, + min_p_e=1. * GeV, + min_ipchi2_electron=0, + min_ip_electron=0, + max_ghostprob_electron=0.5, + min_pid_electron=-5, + max_trackchi2_muon=None, + max_trackchi2_electron=None): + + #DecayDescriptor = '{} -> mu+ e-'.format(parent_id) # <- giving a weird error: ValueError: received an instance of <class 'list'>, but <class 'str'> expected + #if same_sign: DecayDescriptor = ['[{} -> mu+ e+]CC'.format(parent_id)] + + pvs = make_pvs() + + muons = make_prompt_long_muons( + pvs, + min_pt_mu=min_pt_mu, + min_p_mu=min_p_mu, + min_ipchi2_muon=min_ipchi2_muon, + min_ip_muon=min_ip_muon, + max_ghostprob_muon=max_ghostprob_muon, + max_trackchi2_muon=max_trackchi2_muon, + min_pid_muon=min_pid_muon) + + electrons = make_prompt_long_electrons( + pvs, + min_pt_e=min_pt_e, + min_p_e=min_p_e, + min_ipchi2_electron=min_ipchi2_electron, + min_ip_electron=min_ip_electron, + max_ghostprob_electron=max_ghostprob_electron, + max_trackchi2_electron=max_trackchi2_electron, + min_pid_electron=min_pid_electron) + + combination_code = require_all( + in_range(min_dilepton_mass, F.MASS, max_dilepton_mass)) + + # require that the muons come from the same vertex + vertex_code = require_all( + F.CHI2DOF < max_vertexchi2_mue, + #F.CHI2 / F.NDOF < max_vchi2ndof, <- doesn't work? + F.PT > min_pt_mue, + F.BPVFDCHI2(pvs) > min_bpvvdchi2_mue, + F.BPVIPCHI2(pvs) < max_ipchi2_mue, + F.BPVDIRA(pvs) > min_DIRA_mue) + + return ParticleCombiner( + name=name, + Inputs=[muons, electrons], + DecayDescriptor=DecayDescriptor, + #CombinationCut=combination_code, + #CompositeCut=vertex_code + ) +""" + +################# +## END OF FILE ## +################# diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/builders/rdbuilder_thor.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/builders/rdbuilder_thor.py index cfc3294a05e375efccd1bb2080c7cb3734a54117..23ffc3ee8af09121389977614ca4417363d4cb15 100644 --- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/builders/rdbuilder_thor.py +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/builders/rdbuilder_thor.py @@ -805,6 +805,7 @@ def make_rd_detached_dielectron(name="rd_detached_dielectron", @configurable def make_rd_detached_mue(name="rd_detached_mue", + min_dilepton_mass=0. * MeV, max_dilepton_mass=6000. * MeV, parent_id='J/psi(1S)', min_probnn_mu=0., @@ -830,7 +831,7 @@ def make_rd_detached_mue(name="rd_detached_mue", min_pt_mu=min_pt_mu, min_bpvvdchi2=min_bpvvdchi2, max_vchi2ndof=max_vchi2ndof) - code = require_all(F.MASS < max_dilepton_mass) + code = require_all(in_range(min_dilepton_mass, F.MASS, max_dilepton_mass)) return ParticleFilter(dileptons, F.FILTER(code), name=name) diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/qqbar_to_emu.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/qqbar_to_emu.py new file mode 100644 index 0000000000000000000000000000000000000000..11f2d4a6e3fd841a915fc6a01943025de3380a07 --- /dev/null +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/qqbar_to_emu.py @@ -0,0 +1,348 @@ +############################################################################## +# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +""" +Definiton of LFV lines of qqbar -> emu +- Phi(1020) -> E Mu + SS prompt +- Phi(1020) -> E Mu + SS detached +- J/Psi(1S) -> E Mu + SS prompt +- J/Psi(1S) -> E Mu + SS detached +- Upsilon(1S) -> E Mu + SS prompt only + +add control channels e+e- / mu+mu- + +author: Miroslav Saur +date: 27.12.2021 + +""" + +from GaudiKernel.SystemOfUnits import MeV, GeV +from PyConf import configurable +from RecoConf.hlt1_tracking import require_pvs, require_gec +from RecoConf.reconstruction_objects import (make_pvs_v2 as make_pvs, + upfront_reconstruction) +from Moore.config import register_line_builder +from Moore.lines import Hlt2Line +from Hlt2Conf.lines.rd.builders.rdbuilder_thor import make_rd_detached_mue +from Hlt2Conf.lines.rd.builders.qqbar_builder import make_prompt_mue, make_prompt_ee + +all_lines = {} + + +def prefilters(): + return [require_gec(), require_pvs(make_pvs())] + + +###### PROMPT LINES ##### + + +@register_line_builder(all_lines) +@configurable +def phi_to_mue_line(name="Hlt2RD_PhiToMuE_Line", prescale=1, + persistreco=False): + """ + Definiton of [phi(1020) -> mu- e+]CC + """ + emu = make_prompt_mue( + name="Hlt2RD_PhiToMuE_Builder", + parent_id='phi(1020)', + min_dilepton_mass=850. * MeV, + max_dilepton_mass=1520. * MeV, + min_dilepton_pt=2.0 * GeV, + min_pt_e=0.5 * GeV, + min_pt_mu=0.5 * GeV) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def phi_to_mue_ss_line(name="Hlt2RD_PhiToMuE_SS_Line", + prescale=1, + persistreco=False): + emu = make_prompt_mue( + name="Hlt2RD_PhiToMuE_SS_Builder", + parent_id='phi(1020)', + min_dilepton_mass=850. * MeV, + max_dilepton_mass=1520. * MeV, + min_dilepton_pt=2.0 * GeV, + min_pt_e=0.5 * GeV, + min_pt_mu=0.5 * GeV, + same_sign=True) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def jpsi_to_mue_line(name="Hlt2RD_JpsiToMuE_Line", + prescale=1, + persistreco=False): + + emu = make_prompt_mue( + name="Hlt2RD_JpsiToMuE_Builder", + parent_id='J/psi(1S)', + min_dilepton_mass=2600. * MeV, + max_dilepton_mass=3700. * MeV, + min_dilepton_pt=2.0 * GeV, + min_pt_e=1.0 * GeV, + min_pt_mu=1.0 * GeV) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def jpsi_to_mue_ss_line(name="Hlt2RD_JpsiToMuE_SS_Line", + prescale=1, + persistreco=False): + + emu = make_prompt_mue( + name="Hlt2RD_JpsiToMuE_SS_Builder", + parent_id='J/psi(1S)', + min_dilepton_mass=2600. * MeV, + max_dilepton_mass=3700. * MeV, + min_dilepton_pt=2.0 * GeV, + min_pt_e=1.0 * GeV, + min_pt_mu=1.0 * GeV, + same_sign=True) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def upsilon_to_mue_line(name="Hlt2RD_UpsilonToMuE_Line", + prescale=1, + persistreco=False): + + emu = make_prompt_mue( + name="Hlt2RD_UpsilonToMuE_Builder", + parent_id='Upsilon(1S)', + min_dilepton_mass=7000. * MeV, + max_dilepton_mass=13000. * MeV, + min_dilepton_pt=1.0 * GeV, + min_pt_e=1.0 * GeV, + min_pt_mu=1.0 * GeV, + same_sign=False) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def upsilon_to_mue_ss_line(name="Hlt2RD_UpsilonToMuE_SS_Line", + prescale=1, + persistreco=False): + + emu = make_prompt_mue( + name="Hlt2RD_UpsilonToMuE_SS_Builder", + parent_id='Upsilon(1S)', + min_dilepton_mass=7000. * MeV, + max_dilepton_mass=13000. * MeV, + min_dilepton_pt=1.0 * GeV, + min_pt_e=1.0 * GeV, + min_pt_mu=1.0 * GeV, + same_sign=True) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +##### DETACHED LINES ##### + + +@register_line_builder(all_lines) +@configurable +def phi_to_mue_detached_line(name="Hlt2RD_PhiToMuE_Detached_Line", + prescale=1, + persistreco=False): + """ + Definiton of [phi(1020) -> mu- e+]CC + """ + emu = make_rd_detached_mue( + name="Hlt2RD_PhiToMuE_detached_Builder", + parent_id='phi(1020)', + min_dilepton_mass=800. * MeV, + max_dilepton_mass=1570. * MeV, + min_probnn_mu=0., + min_pt_e=0.25 * GeV, + min_pt_mu=0.25 * GeV, + min_bpvvdchi2=30., + max_vchi2ndof=8., + ) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def phi_to_mue_ss_detached_line(name="Hlt2RD_PhiToMuE_SS_Detached_Line", + prescale=1, + persistreco=False): + """ + Definiton of [phi(1020) -> mu+ e+]CC + """ + emu = make_rd_detached_mue( + name="Hlt2RD_PhiToMuE_SS_detached_Builder", + parent_id='phi(1020)', + min_dilepton_mass=800. * MeV, + max_dilepton_mass=1570. * MeV, + min_probnn_mu=0., + min_pt_e=0.25 * GeV, + min_pt_mu=0.25 * GeV, + min_bpvvdchi2=30., + max_vchi2ndof=8., + same_sign=True) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def jpsi_to_mue_detached_line(name="Hlt2RD_JpsiToMuE_Detached_Line", + prescale=1, + persistreco=False): + """ + Definiton of [J/psi(1S) -> mu- e+]CC + """ + emu = make_rd_detached_mue( + name="Hlt2RD_JpsiToMuE_detached_Builder", + parent_id='J/psi(1S)', + min_dilepton_mass=2600. * MeV, + max_dilepton_mass=3700. * MeV, + min_probnn_mu=0., + min_pt_e=0.5 * GeV, + min_pt_mu=0.5 * GeV, + min_bpvvdchi2=30., + max_vchi2ndof=8., + ) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def jpsi_to_mue_ss_detached_line(name="Hlt2RD_JpsiToMuE_SS_Detached_Line", + prescale=1, + persistreco=False): + """ + Definiton of [J/psi(1S) -> mu+ e+]CC + """ + emu = make_rd_detached_mue( + name="Hlt2RD_JpsiToMuE_SS_deached_Builder", + parent_id='J/psi(1S)', + min_dilepton_mass=2600. * MeV, + max_dilepton_mass=3700. * MeV, + min_probnn_mu=0., + min_pt_e=0.5 * GeV, + min_pt_mu=0.5 * GeV, + min_bpvvdchi2=30., + max_vchi2ndof=8., + same_sign=True) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +##### CONTROL ee/mumu LINES ##### + + +@register_line_builder(all_lines) +@configurable +def phi_to_ee_line(name="Hlt2RD_PhiToEE_Line", prescale=1, persistreco=False): + emu = make_prompt_ee( + name="Hlt2RD_PhiToMuE_SS_Builder", + parent_id='phi(1020)', + opposite_sign=True, + PIDe_min=2., + pt_e=1.5 * GeV, + min_dilepton_pt=2.0 * GeV, + min_dilepton_mass=850 * MeV, + max_dilepton_mass=1520 * MeV) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def jpsi_to_ee_line(name="Hlt2RD_JpsiToEE_Line", prescale=1, + persistreco=False): + emu = make_prompt_ee( + name="Hlt2RD_PhiToMuE_SS_Builder", + parent_id='J/psi(1S)', + opposite_sign=True, + PIDe_min=2., + pt_e=0.5 * GeV, + min_dilepton_pt=1.0 * GeV, + min_dilepton_mass=2600 * MeV, + max_dilepton_mass=3700 * MeV) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +@register_line_builder(all_lines) +@configurable +def upsilon_to_ee_line(name="Hlt2RD_UpsilonToEE_Line", + prescale=1, + persistreco=False): + emu = make_prompt_ee( + name="Hlt2RD_UpsilonToMuE_Builder", + parent_id='Upsilon(1S)', + opposite_sign=True, + PIDe_min=2., + pt_e=1. * GeV, + min_dilepton_pt=0.5 * GeV, + min_dilepton_mass=7000 * MeV, + max_dilepton_mass=13000 * MeV) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + prefilters() + [emu], + prescale=prescale, + persistreco=persistreco) + + +################# +## END OF FILE ## +################# diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/upsilon_to_ll.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/upsilon_to_ll.py new file mode 100644 index 0000000000000000000000000000000000000000..e6bd6e258ccb486c1bbc1a305ac086fba61c71d7 --- /dev/null +++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/upsilon_to_ll.py @@ -0,0 +1,151 @@ +############################################################################### +# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +""" +Registration of Upsilon to ll(')(gamma) lines for the RD working group. +It contains also B2HH as this is an important normalisation. +- Upsilon -> e e +- Upsilon -> mumu +- Upsilon -> tautau +- Upsilon -> etau +- Upsilon -> mutau + +author: Raja Nandakumar, Fergus Wilson +date: 31.01.2022 +""" + +from Moore.config import register_line_builder +from Moore.lines import Hlt2Line +from GaudiKernel.SystemOfUnits import MeV, GeV +from PyConf import configurable + +from RecoConf.reconstruction_objects import upfront_reconstruction + +from Hlt2Conf.lines.rd.builders.qqbar_builder import ( + make_prompt_mumu, + make_prompt_ee, + make_prompt_tautau, +) +from Hlt2Conf.lines.rd.builders.qqbar_builder import make_prompt_etau, make_prompt_mutau + +all_lines = {} + + +@register_line_builder(all_lines) +@configurable +def Hlt2RD_UpsilonToEE_Line( + name="Hlt2RD_UpsilonToEE_Line", prescale=1, persistreco=False +): + + ee = make_prompt_ee( + name="Hlt2RD_UpsilonToEE_Builder", + parent_id="Upsilon(1S)", + opposite_sign=True, + min_dilepton_mass=7000.0 * MeV, + max_dilepton_mass=13000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + pt_e=1.0 * GeV, # The minimum Pt + ) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + [ee], + prescale=prescale, + persistreco=persistreco, + ) + + +@register_line_builder(all_lines) +@configurable +def Hlt2RD_UpsilonToMuMu_Line( + name="Hlt2RD_UpsilonToMuMu_Line", prescale=1, persistreco=False +): + + mumu = make_prompt_mumu( + name="Hlt2RD_UpsilonToMuMu_Builder", + parent_id="Upsilon(1S)", + min_dilepton_mass=7000.0 * MeV, + max_dilepton_mass=13000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + min_pt_mu=1.0 * GeV, + ) + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + [mumu], + prescale=prescale, + persistreco=persistreco, + ) + + +@register_line_builder(all_lines) +@configurable +def Hlt2RD_UpsilonToTauTau_Line( + name="Hlt2RD_UpsilonToTauTau_Line", prescale=1, persistreco=False +): + + tautau = make_prompt_tautau( + name="Hlt2RD_UpsilonToTauTau_Builder", + parent_id="Upsilon(1S)", + min_dilepton_mass=7000.0 * MeV, + max_dilepton_mass=13000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + ) + + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + [tautau], + prescale=prescale, + persistreco=persistreco, + ) + + +@register_line_builder(all_lines) +@configurable +def Hlt2RD_UpsilonToeTau_Line( + name="Hlt2RD_UpsilonToeTau_Line", prescale=1, persistreco=False +): + + etau = make_prompt_etau( + name="Hlt2RD_UpsilonToeTau_Builder", + parent_id="Upsilon(1S)", + min_dilepton_mass=7000.0 * MeV, + max_dilepton_mass=13000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + min_pt_e=1.0 * GeV, + ) + + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + [etau], + prescale=prescale, + persistreco=persistreco, + ) + + +@register_line_builder(all_lines) +@configurable +def Hlt2RD_UpsilonTomuTau_Line( + name="Hlt2RD_UpsilonTomuTau_Line", prescale=1, persistreco=False +): + + mutau = make_prompt_mutau( + name="Hlt2RD_UpsilonTomuTau_Builder", + parent_id="Upsilon(1S)", + min_dilepton_mass=7000.0 * MeV, + max_dilepton_mass=13000.0 * MeV, + min_dilepton_pt=1.0 * GeV, + min_pt_mu=1.0 * GeV, + ) + + return Hlt2Line( + name=name, + algs=upfront_reconstruction() + [mutau], + prescale=prescale, + persistreco=persistreco, + )