Skip to content
Snippets Groups Projects

B2taunu with btracking lines

Merged Maarten Van Veghel requested to merge mveghel-b2taunu-btracking into master
Compare and
8 files
+ 487
4
Compare changes
  • Side-by-side
  • Inline
Files
8
###############################################################################
# (c) Copyright 2021-2023 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, make_tracks
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)):
return base_builder.make_prong_pions(pid=pid)
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_b2taunu_tau2pipipi():
"""
for candidates of B(c)+ -> tau+ ( -> pi+ pi+ pi- nu_tau ) nu_tau
with B tracking
"""
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_parts_with_btracking(parts,
velo_nsensors_min=0,
velo_nhits_min=None,
mcorr_min=None,
make_pvs=make_pvs,
revert_charge=False):
"""
adds heavy flavour tracking to Particles with possible corrected mass requirement based on btracking hits
"""
btracking = make_velo_heavyflavour_tracks(
composites=parts, pvs=make_pvs(), revert_charge=revert_charge)
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 make_b2taunu_tau2pipipi_with_btracking(process,
mcorr_min=2. * GeV,
velo_nsensors_min=1,
velo_nhits_min=0):
"""
SL Hlt2 line for B+(c)->Tau+(->Pi+Pi+Pi-Nu)Nu + c.c. with B+(c) tracking
"""
assert process in [
'hlt2'
], 'Line must be defined as Hlt2 line, as it requires VP hits!'
proto_taus = make_b2taunu_tau2pipipi()
ret_dict = make_parts_with_btracking(
parts=proto_taus,
mcorr_min=mcorr_min,
velo_nsensors_min=velo_nsensors_min,
velo_nhits_min=velo_nhits_min)
ret_dict['LineAlg'] = ret_dict['Composites']
return ret_dict
def make_b2dpipi_d2kpipi_with_btracking(process,
vchi2_max=16,
m_min=5.0 * GeV,
m_max=5.7 * GeV,
bpvdira_min=0.9995,
twopi_doca_max=0.1 * mm,
twopi_mass_max=3.5 * GeV,
mcorr_min=None,
velo_nsensors_min=0,
velo_nhits_min=None,
name='SLB_BTracking_B2DPiPi_{hash}'):
"""
for candidates for B+ -> D- ( -> K+ pi- pi- ) pi+ pi+ with B tracking (control channel)
"""
assert process in [
'hlt2'
], 'Line must be defined as Hlt2 line, as it requires VP hits!'
pvs = make_pvs()
pions = make_pions()
kaons = make_kaons()
# input D-, same selection as tau23pi aside from mass window
proto_dms = 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)
# perform the search for HF track (B+) with D- as input (similar to tau in B+ -> tau+ nu)
ret_dict = make_parts_with_btracking(
proto_dms,
mcorr_min=mcorr_min,
velo_nsensors_min=velo_nsensors_min,
velo_nhits_min=velo_nhits_min,
revert_charge=True)
dms = ret_dict['Composites']
# combine to form full B with some additional requirements on pi+pi+ combination
combination_code = F.require_all(
F.SUBCOMB(Functor=F.MAXDOCACUT(twopi_doca_max), Indices=(2, 3)),
F.SUBCOMB(Functor=(F.MASS < twopi_mass_max), Indices=(2, 3)),
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)
bps = ParticleCombiner([dms, pions, pions],
DecayDescriptor="[B+ -> D- pi+ pi+]cc",
CombinationCut=combination_code,
CompositeCut=vertex_code,
name=name)
ret_dict['LineAlg'] = bps
return ret_dict
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 ['VP'] if persist_raw_banks else None
def get_mc_checker(line_with_btracking: dict,
name='PrVeloHeavyFlavourTrackingChecker'):
"""
return MC checker that produces ntuple and has counter on efficiencies relating to
heavy flavour tracking (specifically with B+->tau+nu in mind)
"""
from RecoConf.mc_checking import check_velo_heavyflavour_tracking
return check_velo_heavyflavour_tracking(
composites=line_with_btracking['Composites'],
relations=line_with_btracking['BTracking'].OutputRelations,
pvs=make_pvs(),
get_tracks=make_tracks,
name=name)
Loading