Substitute PID

There are many situations where you may want to change the hypothesis on PID or swap the PID of two particles. For the decay \(D_s^- \to K^- \pi^+ \pi^-\), the \(K^-\) and the \(pi^-\) may be misidentified. Swapping the PID of \(K^-\) and \(\pi^-\) allows us to recover the misidentified case. In this example,

  1. we show how to swap the PID of two particles,

  2. store the result in different trees,

  3. and merge two particle containers to tuple the swapped decay and the original decay in the same tree.


from Gaudi.Configuration import INFO
from FunTuple import FunTuple_Particles as Funtuple
from FunTuple import FunctorCollection
from DaVinci.algorithms import create_lines_filter
from PyConf.reading import get_particles
from DaVinciTools import SubstitutePID
from PyConf.Algorithms import ParticleContainerMerger
import FunTuple.functorcollections as FC
from DaVinci import Options, make_config
import Functors as F


def main(options: Options):
    # Define the input
    B_Line = "SpruceB2OC_BdToDsmK_DsmToHHH_FEST"
    B_Data = get_particles(f"/Event/Spruce/{B_Line}/Particles")

    # Filter
    my_filter = create_lines_filter(name="HDRFilter_BdToDsmK", lines=[f"{B_Line}"])

    # Define the swap
    Swapped_Data = SubstitutePID(
        "Subs_SwapKpi",  # name of the algorithm
        B_Data,  # input particle container
        substitutions=[
            "[ B0  -> ( D_s- -> K-{{pi-}} pi+ pi-{{K-}} ) K+ ]CC",
        ],
        output_level=INFO,
    ).Particles

    # Merge the swapped decays and the original decays
    MergedContainer = ParticleContainerMerger(
        name="HypothesisMerger",
        InputContainers=[B_Data, Swapped_Data],
        OutputLevel=INFO,
    ).OutputContainer

    # Prepare output for funtuple
    fields = {
        "B": "[B0 ->  ( D_s- ->  K-  pi+  pi- )  K+]CC",
        "Ds": "[B0 -> ^( D_s- ->  K-  pi+  pi- )  K+]CC",
        "Kminus": "[B0 ->  ( D_s- -> ^K-  pi+  pi- )  K+]CC",
        "piplus": "[B0 ->  ( D_s- ->  K- ^pi+  pi- )  K+]CC",
        "piminus": "[B0 ->  ( D_s- ->  K-  pi+ ^pi- )  K+]CC",
        "Kplus": "[B0 ->  ( D_s- ->  K-  pi+  pi- ) ^K+]CC",
    }

    variables_all = FunctorCollection(
        {
            "ID": F.PARTICLE_ID,
            "M": F.MASS,
            "P": F.P,
            "PT": F.PT,
            "ENERGY": F.ENERGY,
        }
    )

    variables = {"ALL": variables_all}

    # Get event information
    evt_vars = FC.EventInfo()

    #
    # Configure Funtuple algorithms
    #

    # 1. Original decays
    tuple_original = Funtuple(
        name="OriginalTuple",
        tuple_name="DecayTree",
        fields=fields,
        variables=variables,
        event_variables=evt_vars,
        inputs=B_Data,
    )
    # 2. Swapped decays
    tuple_swapped = Funtuple(
        name="SwappedTuple",
        tuple_name="DecayTree",
        fields=fields,
        variables=variables,
        event_variables=evt_vars,
        inputs=Swapped_Data,
    )
    # 3. Original decays + Swapped decays (Merged)
    tuple_merged = Funtuple(
        name="MergedTuple",
        tuple_name="DecayTree",
        fields=fields,
        variables=variables,
        event_variables=evt_vars,
        inputs=MergedContainer,
    )

    # Run
    algs = {
        "Bd2DsmK": [my_filter, tuple_original, tuple_swapped, tuple_merged],
    }
    return make_config(options, algs)

To run the example:

lbexec DaVinciExamples.tupling.option_davinci_tupling_substitutePID:main $DAVINCIEXAMPLESROOT/example_data/Spruce_all_lines_dst.yaml

For reference, these are the options of this example

input_files:
- root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/spruce_all_lines_realtimereco_newPacking_newDst.dst
input_manifest_file: root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/spruce_all_lines_realtime_newPacking_newDst.tck.json
input_type: ROOT
simulation: true
conddb_tag: sim-20171127-vc-md100
dddb_tag: dddb-20171126
conditions_version: master
geometry_version: run3/trunk
lumi: False
write_fsr: False
histo_file: sprucing_histos.root
ntuple_file: sprucing_tuple.root
input_raw_format: 0.5
input_process: Spruce
persistreco_version: 0.0