Skip to content
Snippets Groups Projects

B2taunu with btracking lines

Merged Maarten Van Veghel requested to merge mveghel-b2taunu-btracking into master
Compare and
7 files
+ 927
2
Compare changes
  • Side-by-side
  • Inline
Files
7
###############################################################################
# (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. #
###############################################################################
from __future__ import absolute_import
from PyConf import configurable
import Functors as F
from Functors.math import in_range
from GaudiKernel.SystemOfUnits import GeV, MeV, mm
from Hlt2Conf.algorithms_thor import ParticleFilter, ParticleCombiner
from PyConf.Algorithms import ParticleWithHeavyFlavourTrackMaker
from RecoConf.reconstruction_objects import make_pvs
from .builders import base_builder
from RecoConf.hlt2_tracking import make_velo_heavyflavour_tracks
"""
SL lines for the B->taunu decays (and control modes) with purpose of using charged
B tracking, hence large transverse flight distance requirements and VELO raw banks
"""
def make_pions(pid=(F.PID_K < 4)):
with base_builder.make_candidate.bind(pid=pid):
return base_builder.make_prong_pions()
def make_kaons(pid=(F.PID_K > 4)):
return base_builder.make_kaons(pid=pid)
@configurable
def make_x23prong_btracking(particles,
name,
descriptor="[tau+ -> pi- pi+ pi+]cc",
make_pvs=make_pvs,
comb_doca_max=0.2 * mm,
pt_min=5. * GeV,
vchi2_max=16,
m_min=500. * MeV,
m_max=3500. * MeV,
fdt_min=4. * mm,
bpvipchi2_min=9.,
mcorr_min=None,
twobody_m_max=None):
"""
3-prong decay for B tracking purposes, with large transverse flight distance (fdt)
"""
pvs = make_pvs()
# two-body selection
twobody_code = F.require_all(
F.MASS < twobody_m_max) if twobody_m_max is not None else F.ALL
# three-body selection
combination_code = F.require_all(
F.PT > 0.9 * pt_min,
in_range(m_min - 50 * MeV, F.MASS, m_max + 50 * MeV),
F.MAXDOCACUT(comb_doca_max))
# vertex-based selection
vertex_code = F.require_all(F.PT > pt_min, in_range(m_min, F.MASS, m_max),
F.CHI2 < vchi2_max)
if fdt_min is not None:
vertex_code = F.require_all(vertex_code, F.BPVVDRHO(pvs) > fdt_min)
if mcorr_min is not None:
vertex_code = F.require_all(vertex_code, F.BPVCORRM(pvs) > mcorr_min)
if bpvipchi2_min is not None:
vertex_code = F.require_all(vertex_code,
F.BPVIPCHI2(pvs) > bpvipchi2_min)
return ParticleCombiner(
particles,
DecayDescriptor=descriptor,
Combination12Cut=twobody_code,
CombinationCut=combination_code,
CompositeCut=vertex_code,
name=name)
def make_twopions(pions,
mother_id="rho(770)0",
m_max=3.5 * GeV,
comb_doca_max=0.2 * mm,
vchi2_max=12,
name='SLB_BTracking_PiPi_{hash}'):
"""
for pions from B+->D-pi+pi+ dalitz decays, these pions form the B vertex
"""
combination_code = F.require_all(F.MASS < (m_max + 50 * MeV),
F.MAXDOCACUT(comb_doca_max))
vertex_code = F.require_all(F.CHI2 < vchi2_max, F.MASS < m_max)
return ParticleCombiner([pions, pions],
DecayDescriptor=f"[{mother_id} -> pi+ pi+]cc",
CombinationCut=combination_code,
CompositeCut=vertex_code,
name=name)
def make_b2taunu_tau2pipipi(process):
"""
for candidates of B(c)+ -> tau+ ( -> pi+ pi+ pi- nu_tau ) nu_tau
with B tracking
"""
assert process in ['hlt2', 'spruce'
], 'Line must be defined as Hlt2 or Sprucing line!'
pions = make_pions()
return make_x23prong_btracking(
particles=[pions, pions, pions],
name="SLB_BTracking_TauToPiPiPi",
descriptor="[tau+ -> pi- pi+ pi+]cc",
m_max=1825. * MeV,
twobody_m_max=1670. * MeV)
def make_b2dpipi_d2kpipi(process,
vchi2_max=16,
m_min=5.0 * GeV,
m_max=5.7 * GeV,
bpvdira_min=0.9995,
name='SLB_BTracking_B2DPiPi_{hash}'):
"""
for candidates for B+ -> D- ( -> K+ pi- pi- ) pi+ pi+ with B tracking (control channel)
"""
assert process in ['hlt2', 'spruce'
], 'Line must be defined as Hlt2 or Sprucing line!'
pvs = make_pvs()
pions = make_pions()
kaons = make_kaons()
# input D-, same selection as tau23pi aside from mass window
dps = make_x23prong_btracking(
particles=[kaons, pions, pions],
name="SLB_BTracking_DpToKPiPi_{hash}",
descriptor="[D- -> K+ pi- pi-]cc",
m_min=1830 * MeV,
m_max=1910 * MeV)
twopions_id = "rho(770)0"
twopions = make_twopions(
pions, mother_id=twopions_id, name="SLB_BTracking_PiPi_For_B_{hash}")
# combine to form full B
combination_code = F.require_all(
in_range(m_min - 50 * MeV, F.MASS, m_max + 50 * MeV))
vertex_code = F.require_all(
in_range(m_min, F.MASS, m_max), F.CHI2 < vchi2_max,
F.BPVDIRA(pvs) > bpvdira_min)
return ParticleCombiner([dps, twopions],
DecayDescriptor=f"[B+ -> D- {twopions_id}]cc",
CombinationCut=combination_code,
CompositeCut=vertex_code,
name=name)
def make_line_with_btracking(process,
make_line,
velo_nsensors_min=0,
velo_nhits_min=None,
mcorr_min=None,
make_pvs=make_pvs):
"""
adds heavy flavour tracking to line with possible corrected mass requirement based on btracking hits
"""
assert process in [
'hlt2'
], 'Line must be defined as Hlt2 line, as it requires VP hits!'
parts = make_line(process)
btracking = make_velo_heavyflavour_tracks(composites=parts, pvs=make_pvs())
btrack_alg = btracking['VeloHeavyFlavourTrackFinder']
rels = btrack_alg.OutputRelations
code = F.require_all(
F.BTRACKING_NPRVELO3DEXPECT(rels) >= velo_nsensors_min)
if velo_nhits_min is not None:
code = F.require_all(code, F.BTRACKING_NHITS(rels) >= velo_nhits_min)
if mcorr_min is not None:
code = F.require_all(code, F.BTRACKING_BPVCORRM(rels) > mcorr_min)
composites = ParticleFilter(
parts,
name=parts.producer.name + "_With_BTracking_Filter",
Cut=F.FILTER(code))
parts_with_btracks = ParticleWithHeavyFlavourTrackMaker(
InputComposites=composites, Composite2TrackRelations=rels)
return {
"Composites": composites,
"BTracking": btrack_alg,
"ParticlesWithBTracks": parts_with_btracks,
"VPHits": btracking['VPHits'],
}
def get_btracking_extra_outputs(btracking: dict):
"""
returns Particles with heavy-flavour tracks added to them, used for 'extra_outputs' of 'HltLine's
"""
return [("ParticlesWithHeavyFlavourTracks",
btracking['ParticlesWithBTracks'].OutputParticles)]
def get_btracking_raw_banks(persist_raw_banks: bool):
"""
defines general set of raw banks to be persisted for heavy-flavour track lines
"""
return ['VPRetinaCluster'] if persist_raw_banks else None
Loading