Skip to content
Snippets Groups Projects

B2taunu with btracking lines

Merged Maarten Van Veghel requested to merge mveghel-b2taunu-btracking into master
Compare and
6 files
+ 485
2
Compare changes
  • Side-by-side
  • Inline
Files
6
###############################################################################
# (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 Hlt2Conf.standard_particles import (make_has_rich_long_pions,
make_has_rich_long_kaons)
from RecoConf.hlt2_tracking import make_veloheavyflavourtracks
"""
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
"""
@configurable
def make_candidate_btracking(name,
make_particles,
make_pvs=make_pvs,
p_min=10 * GeV,
pt_min=0.5 * GeV,
min_ip=0.1 * mm,
pid=None):
"""
base candidates for btracking
note: no extra track quality (based) cuts due to possible B hits in tracks
"""
pvs = make_pvs()
code = F.require_all(F.P > p_min, F.PT > pt_min, F.MINIP(pvs) > min_ip)
if pid is not None:
code = F.require_all(code, pid)
return ParticleFilter(make_particles(), name=name, Cut=F.FILTER(code))
@configurable
def make_x23prong_btracking(name="SLB_ThreeProng_BTracking",
particles=make_has_rich_long_pions,
descriptor="[tau+ -> pi- pi+ pi+]cc",
make_pvs=make_pvs,
pt_min=5.0 * GeV,
comb_doca_max=0.2 * mm,
vchi2_max=18,
m_min=500. * MeV,
m_max=3500. * MeV,
fdt_min=4. * mm,
mcorr_min=None,
twobody_m_max=1670 * MeV):
"""
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)
# three-body selection
combination_code = F.require_all(
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 mcorr_min is not None:
vertex_code = F.require_all(vertex_code, F.BPVCORRM(pvs) > mcorr_min)
if fdt_min is not None:
vertex_code = F.require_all(vertex_code, F.BPVVDRHO(pvs) > fdt_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_TwoPions_{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_candidate_btracking(
name="SLB_BTracking_Pions_{hash}",
make_particles=make_has_rich_long_pions,
pid=(F.PID_K < 5))
return make_x23prong_btracking(
name="SLB_BTracking_TauToThreePion",
particles=[pions, pions, pions],
descriptor="[tau+ -> pi- pi+ pi+]cc",
m_max=1825. * MeV)
def make_b2dpipi_d2kpipi(process,
vchi2_max=16,
m_min=5.0 * GeV,
m_max=5.7 * GeV,
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!'
pions = make_candidate_btracking(
name="SLB_BTracking_Pions_{hash}",
make_particles=make_has_rich_long_pions,
pid=(F.PID_K < 2))
kaons = make_candidate_btracking(
name="SLB_BTracking_Kaons",
make_particles=make_has_rich_long_kaons,
pid=(F.PID_K > 4))
# input D-, same selection as tau23pi aside from mass window
dps = make_x23prong_btracking(
name="SLB_BTracking_DToKaonTwoPion_{hash}",
particles=[kaons, pions, pions],
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_TwoPion_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)
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_veloheavyflavourtracks(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(raw_banks: bool):
"""
defines general set of raw banks to be persisted for heavy-flavour track lines
"""
return ['VPRetinaCluster'] if raw_banks else None
Loading