User interface to tuple with FunTuple
Work towards https://gitlab.cern.ch/lhcbdpa/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...
Option A : DecayTreeTuplelike 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 asInputs
,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 indecay_descriptors
and once inleaves
and therefore easy for users to make mistakes. One has to introduce checks when makingFunTuple
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 ParticleTupleProp
wrapper to define the properties of particles for example in the subdecays.
 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]