V2 Composites

Combine particles to create a decay chain and produce a tuple. Muons are created and combined to form a J/psi. The resulting J/psi candidates are combined with a kaon to build a B+ -> J/psi K+ candidate.

from PyConf.Algorithms import ChargedBasicsProducer, UniqueIDGeneratorAlg
from PyConf.Algorithms import ThOrCombiner__2ChargedBasics
from PyConf.Algorithms import ThOrCombiner__CompositesChargedBasics
import Functors as F
from FunTuple import FunctorCollection
from FunTuple import FunTuple_Composites
from FunTuple import FunTuple_ChargedBasics
from DaVinci import Options, make_config


def main(options: Options):
    # make unique_id_generator
    unique_id_gen = UniqueIDGeneratorAlg()

    # produce charged basic particles
    produce_muons = ChargedBasicsProducer(
        InputUniqueIDGenerator=unique_id_gen, ParticleID="muon"
    )

    produce_jpsi = ThOrCombiner__2ChargedBasics(
        InputUniqueIDGenerator=unique_id_gen,
        DecayDescriptor="J/psi(1S) -> mu+ mu-",
        Input1=produce_muons.Particles,
        Input2=produce_muons.Particles,
    )

    produce_kaons = ChargedBasicsProducer(
        InputUniqueIDGenerator=unique_id_gen, ParticleID="kaon"
    )

    produce_B = ThOrCombiner__CompositesChargedBasics(
        InputUniqueIDGenerator=unique_id_gen,
        DecayDescriptor="[B+ -> J/psi(1S) K+]cc",
        Input1=produce_jpsi.Output,
        Input2=produce_kaons.Particles,
    )

    # define FunTuple instance
    # Cannot yet use CHILD functors with v2.
    variables = FunctorCollection({"PX": F.PX, "PY": F.PY, "PZ": F.PZ})

    # Note CC here and cc (small case) above in the decay descriptor. Needs to be uniform.
    # Decay descriptor parsing is not yet available with v2 Composites.
    # Hence, we are simply running over all particles in TES and not selecting any subset using the decay descriptor for the moment.
    bfields = {"B": "[B+ -> J/psi(1S) K+]CC"}
    bvars = {"B": variables}
    ntuple_composite = FunTuple_Composites(
        name="TupleB",
        tuple_name="DecayTree",
        fields=bfields,
        variables=bvars,
        inputs=produce_B.Output,
    )

    # Decay descriptor parsing is not yet available with v2 Composites or ChargedBasic (see above comment).
    kfields = {"K": "[B+ -> J/psi(1S) ^K+]CC"}
    kvars = {"K": variables}
    ntuple_charged_basic = FunTuple_ChargedBasics(
        name="TupleK",
        tuple_name="DecayTree",
        fields=kfields,
        variables=kvars,
        inputs=produce_kaons.Particles,
    )

    algs = {"UserAlgs_1": [ntuple_composite], "UserAlgs_2": {ntuple_charged_basic}}
    return make_config(options, algs)

To run the example:

lbexec DaVinciExamples.option_davinci_v2_composites:main "$DAVINCIEXAMPLESROOT/example_data/FEST_November_2021_dst_newPacking.yaml"

For reference, these are the options of this example

input_files:
   - root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/hlt2_D0_Kpi_100evts_newPacking_newDst.dst
input_manifest_file: root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/hlt2_D0_Kpi_100evts_newPacking_newDst.tck.json
input_type: ROOT
simulation: true
conddb_tag: sim-20201218-vc-md100
dddb_tag: dddb-20201211
conditions_version: master
geometry_version: run3/trunk
histo_file: v2_example_histos.root
ntuple_file: v2_example_ntuples.root
input_process: Hlt2
input_stream: default
print_freq: 1000
input_raw_format: 0.5
persistreco_version: 0.0
lumi: False
write_fsr: False