Home Computing DAQ E-mail Notes Meetings Subsystems Search

 

User Guide to DaVinciAssociators v5r0 - If you are using a DaVinci version before v11r9, check out the documentation for DaVinciAssociators v4r1.

(Ph.Charpentier)

 

Introduction

DaVinciAssociators are a set of specialized helper classes or tools that allow to retrieve the association between high level analysis objects (ProtoParticles/Particles) and Monte-Carlo particles (MCParticles). As from v5r0, their usage was facilitated by the introduction of helper classes. The former association tools are still supported and are backward compatible.

Thereafter we shall call Linker table or Relations table the two types of technologies for keeping the association. The Linker classes and the Associator tools are the two ways to manipulate these tables from the user algorithm. Both tables are filled by the same Associator algorithms.

 

Generalities

Association between objects are kept either in a Linker Table or in a Relations’ Table in the TES. The latter are more generic objects while the former only allow to establish association between objects in KeyedContainers.

Whenever an algorithm looks for such a table, it lookups the TES and in case the table is not found, an Associator-algorithm is launched that produces the table(s). It is then possible to access associations in both directions.

There is however a preferential direction of the relations that depends on how the table is built: it always originates from the analysis objects towards the MCParticle: the relation is said to go From the analysis object To the MCParticle.

Linker class

This technology for keeping/retrieving associations is present since v5r0 of the DaVinciAssociators. It is based on classes developed by Olivier Callot in the package Event/LinkerEvent. The added value is that, as for the Relations table, if the Linker table is not present in the TES, an algorithm is executed that creates it.

A convention is used as for the name of the path where Linker tables are stored in the TES: there is one such table per From-object container and its name is directly derived from this container’s name by prepending Link/ to its name and appending a string that depends on the association method used to create it (see below).

Helper classes

Depending on whether one needs to access only direct associations (i.e. retrieve the MCParticle(s) associated from a given object) or one needs to also access reverse associations (i.e. retrieve the objects associated to a given MCParticle), two helper classes should be used:

Note that for direct relations, there is no need to define the type of object from which the relation is established. It must only be derived from KeyedObject<int>. The actual obect class must be provided a a template class for bi-directional association though, in order to avoid dynamic casting.

These helper objects should be created in the user algorithm’s initialize() method using a new operator. Attention: it must of course be deleted in the finalize() method!

There is only one header file to include:

#include "DaVinciAssociators/Particle2MCLink.h"

 

Helper class constructors

Both classes accept the same constructors. Hence here only those for Object2MCLink will be described.

object2MCLink( [ GaudiAlgorithm | Algorithm ]* this,

               Particle2MCMethod::<method>,

               [ std::vector<std::string>& containerList |       

                 std::string>& container ]); 

Particle2MCMethod

<method>

Extension

AlgorithmType

WithChi2

/WithChi2

Particle2MCWithChi2

Chi2

/Chi2

Particle2MCChi2

Links

/Links

Particle2MCLinks

Composite

/Composite

CompositeParticle2MCLinks

ChargedPP

/PP2MC

ChargedPP2MC

NeutralPP

NeutralPP2MC

object2MCLink( [GaudiAlgorithm | Algorithm]* this,

               std::string& AlgorithmType,

               std::string& extension,

               [ std::vector<std::string>& containerList |       

                 std::string>& container ]);

The name of the algorithm that is executed to build the linker table if not already present is constructed from that of the user algorithm (e.g. myAlg) and its type (e.g. algType) as: myAlg.algType.

Example of code creation:

#include “DaVinciAssociators/Particle2MCLink.h

. . . .

myAlg::initialize()

{

     StatusCode sc = GaudiAlgorithm::initialize();

     if( sc.isFailure ) return sc;

     m_myParticleLinker = new object2MCLink(    this,

                                            Particle2MCMethod::Chi2,

                                            "Bd2PiPi/Particles");

}

. . . .

myAlg::finalize()

{

     if( NULL != m_myParticleLinker ) delete m_myParticleLinker;

     return GaudiAlgorithm::finalize();

}

 

Helper class methods for direct association

Below is a list of the methods for direct association that are provided for Object2MCLink and also for Object2FromMCLink<ObjectClass> as it inherits from the former.

These methods are similar to those of the underlying LinkedFrom helper classes. Note the optional suffix MCP that can be used for clarity (symmetric to the P used for reverse associations, see later). They return a NULL pointer if no associated MCParticle was found.

Returns the weight associated to the current association.

Returns the number of MCParticles associated to a given object.

returns true if the linker table was not found for one of the declared containers (or the one given as argument)

returns true if an association is found in any container between obj and mcPart.

Example of usage:

execute()

{

. . . .

     msg << MSG::VERBOSE;

     Particle* part = . . . ;

     int nbAss = m_myParticleLinker->assocaitedMCP( part );

     msg << nbAss << “ MCParticles associated to part”

         << part->key() << endreq;

     MCParticle* mcPart = m_myParticleLinker->firstMCP( part );

     while( NULL != mcPart ) {

        // An MCParticle was found, gets the association weight

        double weight = m_myParticleLinker->weightMCP();

        . . . .

        mcpart = m_myParticleLinker->nextMCP();

     }

. . . .

     mcPart = . . . . ;

     if( checkAssociation( part, mcPart ) {

         msg << "Particle" << part->key() << “ and “

             << "MCParticle" << mcPart->key() << “ are associated”

             << endreq;

         . . . .

     }

}

 

Helper class methods for reverse association

For reverse association to be used, a helper class of type Object2FromMCLink<ObjectClass> should be used. As there is no way to guess in which container a potentially associated ObjectClass object is located, an explicit list of containers has to be either given in the constructor or built by calls to direct association methods before asking for revers association.

Note that typedef are defined for most frequently used types of associated objects in analysis:

typedef Object2FromMC<ProtoParticle> ProtoParticle2MCLink;

typedef Object2FromMC<>              Particle2MCLink;

The following are methods of the reverse association:

 

These methods are similar to those of the underlying LinkedTo helper classes, except for the suffix “P” that indicates it is a reverse association (“P” for ProtoParticle or Particle, the most used objects in DaVinciAssociators). They return a NULL pointer if no associated ObjectClass was found.

Returns the weight associated to the current association.

Returns the number of Objects associated to a given MCParticle.

Helper class methods for usage in the association algorithms

For convenience a number of public methods are available to ease the writing of association algorithms willing to create linker tables for association to MCParticles.

A dummy helper class of type Object2MCLink should be created in the initialize() method, using the simplest constructor:

Object2MCLink([GaudiAlgorithm | Algorithm]* this );

One can then create an object of type LinkerWithKey<MCParticle> (aliased to Object2MCLink::Linker) using the following methods:

If no linker table was found for the corresponding tableName, a valid pointer is returned that can be used to create the association table. However, if the table already existed, a NULL pointer is returned. This is very useful, as otherwise another set of associations would be appended to the existing ones, leading to multiple counting of associations. This is the only added value of this helper method.

Note that the first mandatory parameter tableName is that of the table, not of the input object container. Hence if an extension is expected, it should be concatenated to the input container name before calling the method.

The second optional argument must have been created as follows:

Object2MCLink::To testLink( evtSvc(), NULL, tableName);

It is used first internally for testing the existence of the table. If the table is not found, the linker object is created (see above) and testLink is reset to a valid helper object that can be used later to access the linker table as it is being filled. The main use case is to avoid double association.

Example of usage (extracted from the algorithm Particle2MCLinks):

 

for( std::vector<std::string>::iterator inp= m_inputData.begin();

       m_inputData.end()!= inp; inp++) {

    // create a Linker table for this Particle container

    const std::string linkContainer = *inp +

          Particle2MCMethod::extension[Particle2MCMethod::Links];

    // Just a fake helper class

    Object2MCLink p2MCLink( this );

    Object2MCLink::Linker* linkerTable =

      p2MCLink.linkerTable( linkContainer );

    if( NULL == linkerTable ) continue;

. . . .

// An association is found between part and an mcPart, weight w

//    then register the association in the linker table

          linkerTable->link( part, mcPart, w);

. . . .

}

 

 

Associator tools

The DaVinciAssociator tools are based on an implementation of Associator tools by Vanya Belyaev that allows very generic relations to be established between any type of objects.

There are two important TES locations that need to be defined for a DaVinciAssociator:

  1. The TES path of the relations table
  2. The TES path(s) of where the analysis objects are

In addition the associator needs to know which algorithm has to be run in order to build the table (in case it is not already preexisting). An alternative is of course to first run the relation-making algorithm and then run the algorithm that uses the relations.

Associators can be of two types: weighted and unweighted. The difference is that for weighted associators, a “weight” (can be any type, but for DVASct, always a double) is stored for each link between two objects.

Gaudi properties

DaVinciAssociators and their algorithms have default values for their properties:

TES path for the relations table

Type of the algorithm to be used

Name of the algorithm (default = <AlgType>)

The algorithms have another property (OutputData) that must be set to <TablePath>. This is done automatically by the initialize() method of the associator.

DaVinciAssociators

Several instances of the same Associator Type may exist, differentiated only by their properties, in particular their building algorithm. Currently the following DaVinciAssociators exist. They are listed here with their AlgorithmType that in principle the user doesn’t need to change. In case the is an alternate possibility, it is mentioned as “Alt”.

Note that in case more than one instance of the same associator has to be used, different options files should be given in particular for the Location, AlgorithmName and InputData properties.

ProtoParticle2MC Associator

From Type

ProtoParticle

Weighted

double   (fraction of hits)

Associator Type

ProtoParticle2MCAsct

Algorithm Type

Def: ChargedPP2MC

Alt: NeutralPP2MC

Location

Def: Rec/Relations/ChargedPP2MC

Alt: Rec/Relations/NeutralPP2MC

InputData

Def: Rec/ProtoP/Charged

     Rec/ProtoP/Upstream

Alt: Rec/ProtoP/Neutrals

This associator looks for the Track or CaloCluster from which the Protoparticle is originating and associates all MCParticles that are associated to that Track/CaloCluster. In about 1% of the cases, there are more than one MCParticle for Tracks.

Particle2MCLinks Associator

From Type

Particle

Weighted

double   (fraction of hits)

Associator Type

Particle2MCLinksAsct

Algorithm Type

Particle2MCLinks

Location

Phys/Relations/Particle2MCLinks

InputData

Phys/Prod/Particles

This associator uses the ChargedPP2MC associator in order to build associations between Particles and MCParticles. Note that there is no check on the ParticleID at this stage.

CompositeParticle2MCLinks Associator

From Type

Particle

Weighted

no

Associator Type

Particle2MCAsct

Algorithm Type

CompositeParticle2MCLinks

Location

Phys/Relations/CompPart2MCfromLinks

InputData

Phys/Prod/Particles

This associator associates a Particle and an MCParticle if all members of their decay trees are associated. Possibly extra photons can be allowed (see later)

Particle2MCWithChi2 Associator

From Type

Particle

Weighted

double   (c2)

Associator Type

Particle2MCWithChi2Asct

Algorithm Type

Particle2MCWithChi2

Location

Phys/Relations/Particle2MCWithChi2

InputData

Phys/Prod/Particles

This associator computes the c2 between the charged tracks corresponding to the Particle and the MCParticle. It associates the MCParticle that gives the lowest c2. Not cut is applied at this stage, hence all Particles have an associated MCParticle.

Particle2MCChi2 Associator

From Type

Particle

Weighted

no

Associator Type

Particle2MCAsct

Algorithm Type

Particle2MCChi2

Location

Phys/Relations/Particle2MC

InputData

Phys/Prod/Particles

This associator uses the previous one and applies a configurable cut on the c2.

Retrieving a DaVinciAssociator

In order to use an associator of a given type, its header file has to be included:

#include "DaVinciAssociator/<AsctType>.h"

It is advised to get a private version of the associator in the user algorithm. One may also define an alternate name to the default (identical to the type). A pointer to the associator interface class is returned as an argument (of type <AsctType>::IAsct). This code should be part of the initialize() method of the user algorithm. Note that the first argument should be the associator type as defined in the tables above.

StatusCode sc;

<AsctType>::IAsct* m_pAsct;

sc = toolSvc()->retrieveTool( "<AsctType>",

                               m_pAsct,

                               this);

This retrieves an associator of type <AsctType> with a name <myAlg>.<AsctType> (default)

sc = toolSvc()->retrieveTool( "<AsctType>",

                              "<AsctName>",

                               m_pAsct,

                               this);

 

This retrieves an associator of type <AsctType> with a name <myAlg>.<AsctName>

Using a DaVinciAssociator

The following methods are available from the associators interface. For simplicity, we assume here that the From type is Particle, but the same would apply for ProtoParticle.

Associators Methods

bool tableExists()

MCParticle* associatedFrom(Particle*)

Particle* associatedTo(MCParticle*)

<AsctType>::ToRange rangeFrom(Particle*)

<AsctType>::FromRange rangeTo(MCParticle*)

Methods specific to weighted associators

<AsctType>::ToRange rangeFromWithLowCut(Particle*, double cut)

<AsctType>::ToRange rangeFromWithHighCut(Particle*, double cut)

<AsctType>::FromRange rangeToWithLowCut(MCParticle*, double cut)

<AsctType>::FromRange rangeToWithLowCut(MCParticle*, double cut)

The associatedFrom()/associatedTo() methods return the “first” element associated from or to an item. “first” is either the first element associated when creating the table (non-weighted associators) or the element with the smallest weight (weighted associators). This latter behaviour can be changed by a JobOption as follows:

<AsctName>.DecreasingWeight = true;

Both FromRange and ToRange are classes that behave a bit like standard containers, i.e. one can check their sizes and iterate on them. The Range methods are listed below (identical for ToRange as for FromRange).

<AsctType>::FromRange methods

bool empty()

long size()

<AsctType>::FromIterator begin()

<AsctType>::FromIterator end()

<AsctType>::FromIterator rbegin()

<AsctType>::FromIterator rend()

<AsctType>::FromIterator front()

<AsctType>::FromIterator back()

The main difference between Range classes and standard containers is that they cannot directly be dereferenced to the associated item, as there might be two quantities queried for: the item pointer and the weight. Hence the From/ToIterator can be considered as a pointer to an item with the following methods (here the example of a ToIterator), rather than a pointer to a Particle*/MCParticle*:

Particle* from()

MCParticle* to()

double weight()

As an example, here is the code to retrieve the range associated to a Particle and loop through the associated items:

Particle* part;

. . . . . . . .

Particle2MCLinksAsct::ToRange mcPartRange =

     m_pAsct->rangeFrom( part );

Particle2MCLinksAsct::ToIterator mcPartIt;

 

for( mcPartIt = mcPartRange.begin();

     mcPartRange.end() != mcPartIt;

     mcPartIt++ ) {

  MCParticle* mcPart = mcPartIt->to();

  double weight = mcPartIt->weight();

}

Auxiliary associators

Some association-building algorithms are using other associators in order to produce their own tables. It is hence important that they get private instances of this auxiliary associator and of its algorithms. The properties for these two auxiliary items should also be set in a unique and consistent fashion in order to avoid lengthy and painful writing of JobOptions for the user.

Hence these auxiliary associators and algorithms produce private relations table (no need for the user to know their names!) and are forwarded the InputData property from their parent associator. The auxiliary items are given a name that reflect their parenthood.

DaVinciAssociators have the following dependency (<AsctAlgNAme> is the name of the building algorithm for the parent associator).

Associator

 

Auxiliary names

Particle2MCWithChi2

Asct

Alg

none

none

ChargedPP2MC

Asct

Alg

ToolSvc.Track2MCAsct

none (table from OODST)

NeutralPP2MC

Asct

Alg

ToolSvc.CCs2MCPs

none

Particle2MCLinks

Asct

Alg

Asct

Alg

ToolSvc.ChargedPP2MCAsct

ChargedPP2MC

ToolSvc.NeutralPP2MCAsct

NeutralPP2MC

CompositeParticle2MCLinks

Asct

Alg

<AsctAlgName>.Particle2MCLinksAsct

<AsctAlgName>.Particle2MCLinks

Particle2MCChi2

Asct

Alg

<AsctAlgName>.Particle2MCWithChi2Asct

<AsctAlgName>.Particle2MCWithChi2

Note that as there is only one way of building ProtoParticles2MC relations, the associators and their algorithms are generic and not private.  

Particle2MCLinks associator

Although the default Particle2MCLinksAsct assumes the Particles are stored in the TEs and the building algorithm is called to build the full relations table, it is also possible in this specific case to look for the association of Particles that are not stored in the TES, i.e. local instances of Particles. This can be particularly interesting when debugging analysis code. In this case, the association is delegated to the ChargedPP2MC associator without creating a table.

The only jobOption that needs to be changed is the Location of the table that has to be void:

<myAlg>.Particle2MCLinks.Asct.Location = “”;

 

Additional jobOptions

Only two DaVinciAssociators’ algorithms have additional tuneable properties whose default values are listed here:

This is the cut applied on the Chi2 of the 2 tracks in order for declaring a Particle and an MCParticle associated. The number of degrees of freedom is 5.

When set to true, this allows extra photons to be present in the decay tree.

Examples of usage of associators

Single instance

Initialize() method of the user algorithm myAlg:

StatusCode sc;

Particle2MCLinksAsct::IAsct* m_pAsct;

sc = toolSvc()->retrieveTool( "Particle2MCLinksAsct",

                               m_pAsct, this);

This retrieves an associator interface of type Particle2MCLinksAsct, of name myAlg.Particle2MCLinks

jobOptions file:

myAlg.Particle2MCLinks.Location = "Phys/Relations/myPart2MC";

Particle2MCLinks.InputData = {"Phys/mySelection/Particles"};

or, if one wants to give a name to the algorithm:

myAlg.Particle2MCLinks.Location = "Phys/Relations/myPart2MC";

myAlg.Particle2MCLinks.AlgorithmName = "myAsctAlg";

myAsctAlg.InputData = {"Phys/mySelection/Particles"};

Multiple instances

Initialize() method of the user algorithm myAlg:

StatusCode sc;

Particle2MCLinksAsct::IAsct* m_pAsct1;

Particle2MCLinksAsct::IAsct* m_pAsct2;

sc = toolSvc()->retrieveTool( "Particle2MCLinksAsct",

                              "LinksAsct1"

                               m_pAsct1,

                               this);

sc = toolSvc()->retrieveTool( "Particle2MCLinksAsct",

                              "LinksAsct2"

                               m_pAsct2,

                               this);

 

This retrieves two associator interfaces of type Particle2MCLinksAsct, of name myAlg.LinksAsct1 and myAlg.LinksAsct2

 Corresponding jobOptions file:

//For the first instance of the associator

//

myAlg.LinksAsct1.Location = "Phys/Relations/myPart2MC_1";

myAlg.LinksAsct1.AlgorithmName = "myAsctAlg1";

myAsctAlg1.InputData = {"Phys/mySelection/Particles_1"};

//

//For the second instance of the associator, define another

//table location, another algorithm name and its input

//location

//

myAlg.LinksAsct2.Location = "Phys/Relations/myPart2MC_2";

myAlg.LinksAsct2.AlgorithmName = "myAsctAlg2";

myAsctAlg2.InputData = {"Phys/mySelection/Particles_2"};

//