Relation Tables and Isolation Variables
Example for testing the VertexAndConeIsolation
tool and for applying ParticleIsolation and ConeIsolation functorcollection.
The job runs over a Spruced sample and retrieves a set of \(B^0 \to K*(892)0 \tau \mu\) candidates.
For each candidate the algorithm looks at the TES location which contains the selection of extra particles and creates a ‘one-to-many’ relation map
relating all the available tracks to the isolated candidate of the events.
from GaudiKernel.SystemOfUnits import GeV
from PyConf.Algorithms import ThOrParticleSelection
from PyConf.reading import get_particles, get_pvs
import Functors as F
from IsolationTools import VertexAndConeIsolation
from Hlt2Conf.algorithms_thor import ParticleCombiner
from FunTuple import FunctorCollection, FunTuple_Particles as Funtuple
import FunTuple.functorcollections as FC
from DaVinci.algorithms import create_lines_filter
from DaVinci import Options, make_config
def main(options: Options):
# Set branches
branches = {
"B": "[B0 -> ([J/psi(1S) -> tau+ mu-]CC)(K*(892)0 -> K+ pi-)]CC",
"tau": "[B0 -> ([J/psi(1S) -> ^tau+ mu-]CC)(K*(892)0 -> K+ pi-)]CC",
"mu": "[B0 -> ([J/psi(1S) -> tau+ ^mu-]CC)(K*(892)0 -> K+ pi-)]CC",
"Kst": "[B0 -> ([J/psi(1S) -> tau+ mu-]CC)^(K*(892)0 -> K+ pi-)]CC",
}
# Helper lambda function get a filtered selection from all the descendants on the base of
# the absolute id of the particle
FILTER_TREE = lambda id: F.FILTER(F.IS_ABS_ID(id)) @ F.GET_ALL_DESCENDANTS()
# list of saved locations
b2ksttaumu_line = "Hlt2RD_BdToKstTauMu_KstToKPi_TauTo3Pi_OS"
long_track_iso = "LongTrackIsolation"
neutral_iso = "NeutralIsolation"
# Get the selection of B and children candidates
b2ksttaumu_data = get_particles(f"/Event/HLT2/{b2ksttaumu_line}/Particles")
b2ksttaumu_kst_data = ThOrParticleSelection(
InputParticles=b2ksttaumu_data, Functor=FILTER_TREE("K*(892)0")
).OutputSelection
b2ksttaumu_tau_data = ThOrParticleSelection(
InputParticles=b2ksttaumu_data, Functor=FILTER_TREE("tau+")
).OutputSelection
b2ksttaumu_mu_data = ThOrParticleSelection(
InputParticles=b2ksttaumu_data, Functor=FILTER_TREE("mu-")
).OutputSelection
# Get the extra particles selected
b_cciso_data = get_particles(
f"/Event/HLT2/{b2ksttaumu_line}/B_{long_track_iso}/Particles"
)
kst_cciso_data = get_particles(
f"/Event/HLT2/{b2ksttaumu_line}/Kst_{long_track_iso}/Particles"
)
tau_cciso_data = get_particles(
f"/Event/HLT2/{b2ksttaumu_line}/tau_{long_track_iso}/Particles"
)
mu_cciso_data = get_particles(
f"/Event/HLT2/{b2ksttaumu_line}/mu_{long_track_iso}/Particles"
)
b_nciso_data = get_particles(
f"/Event/HLT2/{b2ksttaumu_line}/B_{neutral_iso}/Particles"
)
kst_nciso_data = get_particles(
f"/Event/HLT2/{b2ksttaumu_line}/Kst_{neutral_iso}/Particles"
)
tau_nciso_data = get_particles(
f"/Event/HLT2/{b2ksttaumu_line}/tau_{neutral_iso}/Particles"
)
mu_nciso_data = get_particles(
f"/Event/HLT2/{b2ksttaumu_line}/mu_{neutral_iso}/Particles"
)
variables_all = FunctorCollection({"THOR_P": F.P, "THOR_PT": F.PT})
## CONE ISOLATION EXAMPLE: Charged and neutral
#
# Create an instance of 'VertexAndConeIsolation' for B charge isolation with dr=0.5
b_charge_iso = VertexAndConeIsolation(
name="BIso05",
reference_particles=b2ksttaumu_data,
related_particles=b_cciso_data,
cut=(F.SQRT @ F.DR2 < 0.5),
)
# Create an instance of 'VertexAndConeIsolation' for B neutral isolation with dr=1.
b_neutral_iso = VertexAndConeIsolation(
name="BIso10",
reference_particles=b2ksttaumu_data,
related_particles=b_nciso_data,
cut=(F.SQRT @ F.DR2 < 1.0),
)
# Add charge isolation variables with max dr=0.5 and neutral isolation variables with max dr=1 using ConeIsolation functorcollection
b_cone_iso_variables = FC.ConeIsolation(
charged_cone_isolation_alg=b_charge_iso,
neutral_cone_isolation_alg=b_neutral_iso,
array_indx_name="B_cone_indx",
)
# Create an instance of 'VertexAndConeIsolation' for B charge isolation with dr=0.5
tau_charge_iso = VertexAndConeIsolation(
name="TauIso05",
reference_particles=b2ksttaumu_tau_data,
related_particles=tau_cciso_data,
cut=(F.SQRT @ F.DR2 < 0.5),
)
# Create an instance of 'VertexAndConeIsolation' for B neutral isolation with dr=1.
tau_neutral_iso = VertexAndConeIsolation(
name="TauIso10",
reference_particles=b2ksttaumu_tau_data,
related_particles=tau_nciso_data,
cut=(F.SQRT @ F.DR2 < 1.0),
)
# Add charge isolation variables with max dr=0.5 and neutral isolation variables with max dr=1 using ConeIsolation functorcollection
tau_cone_iso_variables = FC.ConeIsolation(
charged_cone_isolation_alg=tau_charge_iso,
neutral_cone_isolation_alg=tau_neutral_iso,
array_indx_name="Tau_cone_indx",
)
# Create an instance of 'VertexAndConeIsolation' for mu charge isolation with dr=0.5
mu_charge_iso = VertexAndConeIsolation(
name="MuIso05",
reference_particles=b2ksttaumu_mu_data,
related_particles=mu_cciso_data,
cut=(F.SQRT @ F.DR2 < 0.5),
)
# Create an instance of 'VertexAndConeIsolation' for mu neutral isolation with dr=1.
mu_neutral_iso = VertexAndConeIsolation(
name="MuIso10",
reference_particles=b2ksttaumu_mu_data,
related_particles=mu_nciso_data,
cut=(F.SQRT @ F.DR2 < 1.0),
)
# Add charge isolation variables with max dr=0.5 and neutral isolation variables with max dr=1 using ConeIsolation functorcollection
mu_cone_iso_variables = FC.ConeIsolation(
charged_cone_isolation_alg=mu_charge_iso,
neutral_cone_isolation_alg=mu_neutral_iso,
array_indx_name="mu_cone_indx",
)
# Create an instance of 'VertexAndConeIsolation' for Kst charge isolation with dr=0.5
kst_charge_iso = VertexAndConeIsolation(
name="KstIso05",
reference_particles=b2ksttaumu_kst_data,
related_particles=kst_cciso_data,
cut=(F.SQRT @ F.DR2 < 0.5),
)
# Create an instance of 'VertexAndConeIsolation' for Kst neutral isolation with dr=1.
kst_neutral_iso = VertexAndConeIsolation(
name="KstIso10",
reference_particles=b2ksttaumu_kst_data,
related_particles=kst_nciso_data,
cut=(F.SQRT @ F.DR2 < 1.0),
)
# Add charge isolation variables with max dr=0.5 and neutral isolation variables with max dr=1 using ConeIsolation functorcollection
kst_cone_iso_variables = FC.ConeIsolation(
charged_cone_isolation_alg=kst_charge_iso,
neutral_cone_isolation_alg=kst_neutral_iso,
array_indx_name="Kst_cone_indx",
)
pvs = get_pvs()
# Other examples of different requirements applied for the isolation
# Change the selection requirement to make different relations
# Instantiate the Isolation tool with different configurations
b_fixpv_iso = VertexAndConeIsolation(
name="BIsoFixPV",
reference_particles=b2ksttaumu_data,
related_particles=b_cciso_data,
cut=(F.SHARE_BPV(pvs) | (F.MINIPCHI2CUT(pvs, 9.0) @ F.FORWARDARG1())),
)
b_fix_pv_iso_variables = FC.ParticleIsolation(
isolation_alg=b_fixpv_iso, array_indx_name="B_FixPV_indx"
)
b_mass_constraint_iso = VertexAndConeIsolation(
name="BIsoMassConstraint",
reference_particles=b2ksttaumu_data,
related_particles=b_nciso_data,
cut=(F.COMB_MASS() < 8 * GeV),
)
b_mass_constraint_iso_variables = FC.ParticleIsolation(
isolation_alg=b_mass_constraint_iso, array_indx_name="B_MassConstraint_indx"
)
## VERTEX ISOLATION EXAMPLE
#
# Create candidates adding one extra particle to the composite
b_vtxiso_onetrack_data = ParticleCombiner(
[b2ksttaumu_data, b_cciso_data],
name="One_extra_track_combination",
DecayDescriptor="[B*+ -> B0 pi+]cc",
CombinationCut=F.ALL,
CompositeCut=F.ALL,
)
# Create candidates adding two extra particles to the composite
b_vtxiso_twotracks_data = ParticleCombiner(
[b2ksttaumu_data, b_cciso_data, b_cciso_data],
name="Two_extra_tracks_combination",
DecayDescriptor="[B*0 -> B0 pi+ pi-]cc",
CombinationCut=F.ALL,
CompositeCut=F.ALL,
)
# Add vertex isolation variables with one and two tracks
b_vtxiso_onetrack = VertexAndConeIsolation(
name="OneTrack",
reference_particles=b2ksttaumu_data,
related_particles=b_vtxiso_onetrack_data,
cut=(F.CHI2() @ F.FORWARDARG1() < 9.0),
)
b_vtxiso_twotracks = VertexAndConeIsolation(
name="TwoTracks",
reference_particles=b2ksttaumu_data,
related_particles=b_vtxiso_twotracks_data,
cut=(F.CHI2() @ F.FORWARDARG1() < 15.0),
)
b_vtxiso_onetrack_variables = FC.VertexIsolation(isolation_alg=b_vtxiso_onetrack)
b_vtxiso_twotracks_variables = FC.VertexIsolation(isolation_alg=b_vtxiso_twotracks)
# Add variables to the branches
variables = {
"B": variables_all
+ b_cone_iso_variables
+ b_fix_pv_iso_variables
+ b_mass_constraint_iso_variables
+ b_vtxiso_onetrack_variables
+ b_vtxiso_twotracks_variables,
"tau": variables_all + tau_cone_iso_variables,
"mu": variables_all + mu_cone_iso_variables,
"Kst": variables_all + kst_cone_iso_variables,
}
my_filter = create_lines_filter(
name="HDRFilter_BdToKstTauMu", lines=[f"{b2ksttaumu_line}"]
)
my_tuple = Funtuple(
name="Tuple",
tuple_name="DecayTree",
fields=branches,
variables=variables,
inputs=b2ksttaumu_data,
)
return make_config(options, [my_filter, my_tuple])
To run the example:
lbexec DaVinciExamples.tupling.option_davinci_tupling_relation_isovariables:main $DAVINCIEXAMPLESROOT/example_data/hlt2_b2ksttaumu_opt.yaml
For reference, these are the options of this example
input_files:
- root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/b_to_ksttaumu_test_isolation.dst
input_manifest_file: root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/b_to_ksttaumu_test_isolation.tck.json
input_type: ROOT
evt_max: -1
ntuple_file: b_to_ksttaumu_test_isolation.root
print_freq: 20
simulation: true
conddb_tag: sim-20180530-vc-mu100
dddb_tag: dddb-20190223
conditions_version: master
geometry_version: run3/trunk
input_process: Hlt2