Skip to content

User interface to tuple with FunTuple

Work towards https://gitlab.cern.ch/lhcb-dpa/project/-/issues/6:

For FunTuple, instead of defining a custom Gaudi::Property object (like discussed here), we can make a wrapper python class that derives from FunTupleBase class (defined in C++ and imported into python from Configurables). Currently three options emerged through preliminary discussions with @mferrill and @erodrigu (please add and correct my summary below). There might be simpler and better options, so inputs are very welcome here...

FYI: @powen and @pkoppenb

Option A : DecayTreeTuple-like interface (see below).

  • Pros: Familiar interface for users like in Run1 and 2.
  • Cons: The problem is that FunTuple object is initialized with some default attributes and which have to be set correctly later (with methods such as Inputs, add_decays, add_functors, etc) before running the algorithm.
#Here NewTupleTools is hypothetical and is a replacement for whatever TupleTools get modified to
from NewTupleTools import Kinematics, Topological
import Functors as F
from Configurables import FunTuple_Particles as FunTuple

ftp = FunTuple('FunTupleAlg')

#define inputs
ftp.Inputs = ()

#add branches/decays
ftp.add_decays({ "Kp" :  "[B+ -> ^K+ (J/psi(1S) -> mu+ mu-)]CC",
                 "Jpsi"  :  "[B+ -> K+ ^(J/psi(1S) -> mu+ mu-)]CC" })

#Define common set of functors for all branches above. 
ftp.All.add_functors(Kinematics) 

#add functors to jpsi branch and extend it with additional variables
ftp.Jpsi.add_functors(Topological)
#add extra functor to jpsi 
ftp.Jpsi.add_functors({'LOKI_PT': 'PT',
                       'THOR_PT': F.PT})

#add the algorithms to the sequence
ApplicationMgr().TopAlg = [ftp]

Option B: In this interface, we have an object called FunctorCollection that handles the functor library from the hypothetical NewTupleTools and any locally user defined functor library through add_functors method.

  • Pros: Overcomes the problem in option A.
  • Cons: The name Jpsi gets repeated once in decay_descriptors and once in leaves and therefore easy for users to make mistakes. One has to introduce checks when making FunTuple object to warn the user.
#Here NewTupleTools is hypothetical and is a replacement for whatever TupleTools get modified to
from NewTupleTools import Kinematics, Topological
import Functors as F
from Funtuple import FunctorCollection
from Configurables import FunTuple_Particles as FunTuple

#define decay descritors
decay_descriptors = { "Kp" :  "[B+ -> ^K+ (J/psi(1S) -> mu+ mu-)]CC",
                      "Jpsi"  :  "[B+ -> K+ ^(J/psi(1S) -> mu+ mu-)]CC" }

#defining functors (here FunctorCollection is wrapper class that makes adding new functors to collection easily)
functors_all  = FunctorCollection(Kinematics)
functors_jpsi = FunctorCollection(Topological)
functors_jpsi.add_functors({'LOKI_PT': 'PT',
                            'THOR_PT': F.PT})
#Define leaves
leaves = {"ALL" : functors_all, 
          "Jpsi": functors_jpsi)

#define FunTuple instance
ftp = FunTuple("MyFunTuple", Inputs=(), decays=decay_descriptors, leaves=leaves)

#add the algorithms to the sequence
ApplicationMgr().TopAlg = [ftp]

Option C: In this interface, on top of introducing the wrapper FunctorCollection, we introduce ParticleTuplePropwrapper to define the properties of particles for example in the sub-decays.

  • Pros: Overcomes the problem in option A and option B.
  • Cons: ...maybe is just an overkill and probably too many layers for simple task...
#Here NewTupleTools is hypothetical and is a replacement for whatever TupleTools get modified to
from NewTupleTools import Kinematics, Topological
import Functors as F
from Funtuple import FunctorCollection, ParticleTupleProp
from Configurables import FunTuple_Particles as FunTuple

#defining functors (here FunctorCollection is wrapper class that makes adding new functors to collection easily)
functors_all  = FunctorCollection(Kinematics)
functors_jpsi = FunctorCollection(Topological)
functors_jpsi.add_functors({'LOKI_PT': 'PT',
                            'THOR_PT': F.PT})

#define ParticleTupleProp again a wrapper class
ptp_jspi = ParticleTupleProp(name="Jpsi",
                             decay_descriptor = "[B+ -> K+ ^(J/psi(1S) -> mu+ mu-)]CC",
                             functors = functors_jpsi)

#ALL is special and decay_descriptor is just None
ptp_all  = ParticleTupleProp(name="ALL", functors = functors_all)

#define FunTuple instance
ftp = FunTuple("MyFunTuple", Inputs=(), particle_tuple_props=[ptp_jspi, ptp_all])

#add the algorithms to the sequence
ApplicationMgr().TopAlg = [ftp]
Edited by Eduardo Rodrigues