Use of STL generic algorithms with ATLAS specific function objects

In this document the briefest description of STL generic algorithms is given (mainly using "sort" example). The reader should consult any of many standard books on the subject. This leads to the use of function objects.

Then a description of a set of standard function objects is given, which allow users to invoke STL algorithms very simply, without having to write their own function objects.
 

Introduction

The Standard Template Library (STL) contains many templated types which ore of great use in physics analysis programs. Very important components of this are vectors (or in fact any collection class) and iterators.

As example it is often very convenient for a user to maintain a collection of , say, ReconstructedParticles, in a vector, and traverse them using an iterator. Example:
 

#include <vector>
#include "ReconstructedParticle.h"

// Make a vector
vector<ReconstructedParticle> myParticles ;

// Fill it with some particles
ReconstructedParticle a,b,c,d  ;
myParticles.push_back(  a  ) ;
.......
.......

// Loop through vector to do something to each particle

vector<ReconstructedParticle> ::iterator itr ;

for( itr = myParticles.begin() ; itr < myParticles.end();  ++itr )
{
    // do something with particle. itr acts as a pointer to the item in the vector
    cout << "the mass is"  << itr->mass( ) ;
}
 
 

This example introduces both the idea of a "vector", and the use of "iterators", although clearly the unfamiliar reader will needs to read the documentation to really appreciate what is going on. For the purposes of this document all that is important is the concept that users will likely have vectors of analysis types in their analysis programs.

The STL provides a set of algorithms to carry out common operations on such vectors. Examples are sorting, summing, removing......etc. These algorithms are written to implement operations in a hopefully more efficient way than the user might invent. They are by nature written "generically" (i.e. they have no inherent knowledge of the the type of object in the vector).  This decoupling of the algorithm from the type is achieved by the use of function objects. For example in sorting these encapsulate the specific information needed in order to compare two items for precidence.

As example consider one of the most common operations, sorting. It is very likely that the user may wish to sort a vector of Clusters by energy for example, or a vector of ReconstructedParticles by mass. This can be achieved in one line of code by the following
 

#include <vector>
#include<algorithms>

// Make a vecotr of clusters
vector<Cluster> myClusters

// assume it is filled by some other part of the program

// sort the clusters by energy

sort( myClusters.begin(), myClusters.end(),  CompareByEnergy ) ;

// clusters are now sorted
 

where CompareByEnergy is a special class which you have to write  as follows
 
class CompareByEnergy {
    public:
        bool operator() ( Cluster c1, Cluster c2 )  {   return c1.energy() < c2.energy()  ;}
}
 
To the novice reader this may look a bit strange, but one gets used to it quickly. All the user has to do is write a set of these appropriate to the analysis  in some auxilary file, and from then on sorting is a one line operation anywhere in the code. This may seem cumbersome, but it is most probably neater, faster, or safer than writing your own sort algorithm object, or even worse putting that the explicit code in your program.
 

Pre-defined function objects for ATLAS

The point of this document has now been reached. If all analysis Types honour a well known interface for kinematic quantities, then it is possible to write all of the function objects you are likely to need in advance, and make them available to all users via an #iinclude file.

At the time of writing this the IKinematic interface  is assumed. Using this the following function objects have been implemented.

They allow the user to sort  collections (principally vectors) containing
    - objects which implement IKinematic interface
    - pointers to objects which implement IKinematic interface.

i.e if your object is defined as:
    class yourObject : virtual public IKinematic
these will work for you.
 
 

For STL algortithms:    sort,   partial_sort

Include file:  #include "AtlfastCode/FunctionObjects.h"

Source code:  FunctionObjects.h

They reside in namespace SortAttribute
 
 
Function object name Constructor options Description
SortAttribute::AscendingPhi AscendingPhi( ) Ascending order of phi
SortAttribute::DescendingPhi DescendingPhi( ) Descending order of phi
SortAttribute::AscendingEta AscendingEta( ) Ascending order of Eta
SortAttribute::DescendingEta DescendingPhi( ) Descending order of Eta
SortAttribute::AscendingET AscendingET( ) Ascending order of transverse energy
SortAttribute::DescentingET DescendingET( ) Descending order of transverse energy
SortAttribute::AscendingPT AscendingPT( ) Ascending order of transverse momentum
SortAttribute::DescendingPT DescendingPT( ) Descending order of transverse momentum
SortAttribute::AscendingMT AscendingMT( ) Ascending order of transverse mass
SortAttribute::DescendingMT DescendingMT( ) Descending order of transverse mass
SortAttribute::DeltaPhi DeltaPhi( IKinematic& ref ) 
DeltaPhi( IKinematic* ref )
Sorts by increasing distance in phi from a reference specified by ref in constructor
SortAttribute::DeltaEta DeltaPhi( IKinematic& ref ) 
DeltaPhi( IKinematic* ref )
Sorts by increasing distance in eta from a reference specified by ref in constructor
SortAttribute::DeltaR DeltaPhi( IKinematic& ref ) 
DeltaPhi( IKinematic* ref )
Sorts by increasing distance in R-space (eta-phi) from a reference specified by ref in constructor.  DeltaR means sqrt( dphi**2 + deta**2)
 

Example sof use:

1) To sort a collection according to descending value of transverse energy, either:

    SortAttribute::DescendingET    myCondition ;

  sort( myClusters.begin(),  myClusters.end(),  myCondition ) ;

or equivalently

    sort( myClusters.begin(),  myClusters.end(),  SortAttribute::DescendingET()  ) ;
 

2) To sort a collection of Clusters according to their distance in R-space from a reference ReconstructedParticle (typical use during association or isolation) then either:

    SortAttribute::DeltaR   myCondition( electron ) ;
 
    sort( myClusters.begin(),  myClusters.end(),  myCondition ) ;

or equivalently

    sort( myClusters.begin(),  myClusters.end(),  SortAttribute::DeltaR( electron ) ;

where electron is some instance of ReconstructedParticle.