ProjectionHandler Class Reference

#include <ProjectionHandler.hh>

Collaboration diagram for ProjectionHandler:

Collaboration graph
[legend]

List of all members.


Detailed Description

The projection handler is a central repository for projections to be used in a Rivet analysis run.

Without centralised projections, it can be hard to know which of an equivalent set of projections will be run on a particular event. In turn, this may mean that certain projections in the chain can go out of scope unexpectedly. There were originally also the issues that projections may need to be held as member pointers to an abstract base class, since post-construction setup is needed; that projections contained pointers to their own dependency chain, which could go out of scope; and that projection members could be modified after being applied to an event which, due to the caching model, would have unpredictable consequences.

By centralising all the projections, these issues are eliminated, as well as allowing analysis classes to contain fewer data members (since projections are now better accessed by name than by storing a data member reference or pointer).

The core of the ProjectionHandler design is that it is a singleton class, essentially a wrapper around a map of Projection*, indexed by a hash of the registering object and its local name for the registered projection.

Definition at line 42 of file ProjectionHandler.hh.


Public Types

enum  ProjDepth { SHALLOW, DEEP }
 Enum to specify depth of projection search. More...
typedef set< ProjHandleProjHandles
 Typedef for a vector of Projection pointers.
typedef map< const string,
ProjHandle
NamedProjs
 Typedef for the structure used to contain named projections for a particular containing Analysis or Projection.

Public Member Functions

void clear ()
Projection registration
const ProjectionregisterProjection (const ProjectionApplier &parent, const Projection &proj, const string &name)
 Attach and retrieve a projection as a reference.
const ProjectionregisterProjection (const ProjectionApplier &parent, const Projection *proj, const string &name)
 Attach and retrieve a projection as a pointer.
Projection retrieval. */
const ProjectiongetProjection (const ProjectionApplier &parent, const string &name) const
set< const Projection * > getChildProjections (const ProjectionApplier &parent, ProjDepth depth=SHALLOW) const

Static Public Member Functions

static ProjectionHandlercreate ()
 Singleton creation function.

Private Types

typedef map< const
ProjectionApplier
*, NamedProjs
NamedProjsMap

Private Member Functions

 ~ProjectionHandler ()
 Private destructor means no inheritance from this class.
ProjectionHandleroperator= (const ProjectionHandler &)
 The assignment operator is hidden.
 ProjectionHandler (const ProjectionHandler &)
 The copy constructor is hidden.
void removeProjectionApplier (ProjectionApplier &parent)
 Remove a ProjectionApplier: designed to only be called by ~ProjectionApplier (as a friend).
LoggetLog () const
 Get a logger.
Construction. */
 ProjectionHandler ()
 The standard constructor.
Projection registration internal helpers
const Projection_getEquiv (const Projection &proj) const
const Projection_clone (const ProjectionApplier &parent, const Projection &proj)
 Make a clone of proj, copying across child references from the original.
const Projection_register (const ProjectionApplier &parent, const Projection &proj, const string &name)
 Internal function to do the registering.
string _getStatus () const
 Get a string dump of the current ProjHandler structure.
bool _checkDuplicate (const ProjectionApplier &parent, const Projection &proj, const string &name) const
 Check that this parent projection doesn't already use this name.

Private Attributes

NamedProjsMap _namedprojs
ProjHandles _projs

Static Private Attributes

static ProjectionHandler_instance = 0

Friends

class ProjectionApplier
 ProjectionApplier's destructor needs to trigger cleaning up the proj handler repo.

Member Typedef Documentation

typedef set<ProjHandle> ProjHandles

Typedef for a vector of Projection pointers.

Definition at line 49 of file ProjectionHandler.hh.

typedef map<const string, ProjHandle> NamedProjs

Typedef for the structure used to contain named projections for a particular containing Analysis or Projection.

Definition at line 53 of file ProjectionHandler.hh.

typedef map<const ProjectionApplier*, NamedProjs> NamedProjsMap [private]

Structure used to map a containing Analysis or Projection to its set of contained projections.

Definition at line 63 of file ProjectionHandler.hh.


Member Enumeration Documentation

enum ProjDepth

Enum to specify depth of projection search.

Enumerator:
SHALLOW 
DEEP 

Definition at line 56 of file ProjectionHandler.hh.

00056 { SHALLOW, DEEP };


Constructor & Destructor Documentation

~ProjectionHandler (  )  [private]

Private destructor means no inheritance from this class.

Definition at line 44 of file ProjectionHandler.cc.

References ProjectionHandler::clear().

00044                                         {
00045     clear();
00046   }

ProjectionHandler ( const ProjectionHandler  )  [private]

The copy constructor is hidden.

ProjectionHandler (  )  [inline, private]

The standard constructor.

Definition at line 91 of file ProjectionHandler.hh.

Referenced by ProjectionHandler::create().

00091 { }


Member Function Documentation

ProjectionHandler& operator= ( const ProjectionHandler  )  [private]

The assignment operator is hidden.

ProjectionHandler * create (  )  [static]

Singleton creation function.

Definition at line 18 of file ProjectionHandler.cc.

References ProjectionHandler::_instance, Log::getLog(), ProjectionHandler::ProjectionHandler(), and Log::TRACE.

00018                                                {
00019     if (!_instance) {
00020       _instance = new ProjectionHandler();
00021       Log::getLog("Rivet.ProjectionHandler")
00022         << Log::TRACE << "Created new ProjectionHandler at " << _instance << endl;
00023     }
00024     return _instance;
00025   }

const Projection & registerProjection ( const ProjectionApplier parent,
const Projection proj,
const string &  name 
)

Attach and retrieve a projection as a reference.

Definition at line 53 of file ProjectionHandler.cc.

References ProjectionHandler::_checkDuplicate(), ProjectionHandler::_clone(), ProjectionHandler::_getEquiv(), ProjectionHandler::_register(), ProjectionHandler::getLog(), ProjectionApplier::name(), Projection::name(), and Log::TRACE.

Referenced by ProjectionApplier::_addProjection(), and ProjectionHandler::registerProjection().

00056   {
00057     getLog() << Log::TRACE << "Trying to register"
00058              << " projection " << &proj  << " (" << proj.name() << ")"
00059              << " for parent " << &parent << " (" << parent.name() << ")"
00060              << " with name '" << name << "'" << endl;
00061 
00062     // Check for duplicate use of "name" on "parent"
00063     const bool dupOk = _checkDuplicate(parent, proj, name);
00064     if (!dupOk) exit(1);
00065 
00066     // Choose which version of the projection to register with this parent and name
00067     const Projection* p = _getEquiv(proj);
00068     if (p == 0) { // a null pointer is a non-match
00069       // If there is no equivalent projection, clone proj and use the clone for registering
00070       p = _clone(parent, proj);
00071     }
00072 
00073     // Do the registering
00074     p = _register(parent, *p, name);
00075 
00076     // Return registered proj
00077     return *p;
00078   }

const Projection * registerProjection ( const ProjectionApplier parent,
const Projection proj,
const string &  name 
)

Attach and retrieve a projection as a pointer.

Definition at line 84 of file ProjectionHandler.cc.

References ProjectionHandler::registerProjection().

00086                                                                               {
00087     if (proj == 0) return 0;
00088     const Projection& p = registerProjection(parent, *proj, name);
00089     return &p;
00090   }

const Projection * _getEquiv ( const Projection proj  )  const [private]

Try to get an equivalent projection from the system

Returns:
0 if no equivalent projection found

Definition at line 143 of file ProjectionHandler.cc.

References ProjectionHandler::_projs, Rivet::EQUIVALENT, ProjectionHandler::getLog(), Projection::name(), Rivet::pcmp(), and Log::TRACE.

Referenced by ProjectionHandler::registerProjection().

00144   {
00145     // Get class type using RTTI
00146     const std::type_info& newtype = typeid(proj);
00147     getLog() << Log::TRACE << "RTTI type of " << &proj << " is " << newtype.name() << endl;
00148 
00149     // Compare to ALL projections via _projs collection
00150     getLog() << Log::TRACE << "Comparing " << &proj
00151              << " with " << _projs.size()
00152              << " registered projection" << (_projs.size() == 1 ? "" : "s") <<  endl;
00153     foreach (const ProjHandle& ph, _projs) {
00154       // Make sure the concrete types match, using RTTI.
00155       const std::type_info& regtype = typeid(*ph);
00156       getLog() << Log::TRACE << "RTTI type comparison with " << ph << ": "
00157                << newtype.name() << " vs. " << regtype.name() << endl;
00158       if (newtype != regtype) continue;
00159       getLog() << Log::TRACE << "RTTI type matches with " << ph << endl;
00160    
00161       // Test for semantic match
00162       if (pcmp(*ph, proj) != EQUIVALENT) {
00163         getLog() << Log::TRACE << "Projections at "
00164                  << &proj << " and " << ph << " are not equivalent" << endl;
00165       } else {
00166         getLog() << Log::TRACE << "MATCH! Projections at "
00167                  << &proj << " and " << ph << " are equivalent" << endl;
00168         return ph.get();
00169       }
00170     }
00171 
00172     // If no match, just return a null pointer
00173     return 0;
00174   }

const Projection* _clone ( const ProjectionApplier parent,
const Projection proj 
) [private]

Make a clone of proj, copying across child references from the original.

Referenced by ProjectionHandler::registerProjection().

const Projection * _register ( const ProjectionApplier parent,
const Projection proj,
const string &  name 
) [private]

Internal function to do the registering.

Definition at line 123 of file ProjectionHandler.cc.

References ProjectionHandler::_namedprojs, ProjectionHandler::_projs, ProjectionHandler::getLog(), and Log::TRACE.

Referenced by ProjectionHandler::registerProjection().

00126   {
00127     ProjHandle ph(&proj);
00128     getLog() << Log::TRACE << "Registering new projection at " << ph << endl;
00129 
00130     // Add the passed Projection to _projs
00131     _projs.insert(ph);
00132 
00133     // Add the ProjApplier* => name location to the associative container
00134     _namedprojs[&parent][name] = ph;
00135 
00136     return ph.get();
00137   }

string _getStatus (  )  const [private]

Get a string dump of the current ProjHandler structure.

Definition at line 178 of file ProjectionHandler.cc.

References ProjectionHandler::_namedprojs.

Referenced by ProjectionHandler::_checkDuplicate().

00178                                              {
00179     ostringstream msg;
00180     msg << "Current projection hierarchy:" << endl;
00181     foreach (const NamedProjsMap::value_type& nps, _namedprojs) {
00182       //const string parentname = nps.first->name();
00183       msg << nps.first << endl; //"(" << parentname << ")" << endl;
00184       foreach (const NamedProjs::value_type& np, nps.second) {
00185         msg << "  " << np.second << " (" << np.second->name()
00186             << ", locally called '" << np.first << "')" << endl;
00187       }
00188       msg << endl;
00189     }
00190     return msg.str();
00191   }

bool _checkDuplicate ( const ProjectionApplier parent,
const Projection proj,
const string &  name 
) const [private]

Check that this parent projection doesn't already use this name.

Definition at line 196 of file ProjectionHandler.cc.

References ProjectionHandler::_getStatus(), ProjectionHandler::_namedprojs, Log::ERROR, ProjectionHandler::getLog(), Projection::name(), and ProjectionApplier::name().

Referenced by ProjectionHandler::registerProjection().

00199   {
00200     NamedProjsMap::const_iterator ipnps = _namedprojs.find(&parent);
00201     if (ipnps != _namedprojs.end()) {
00202       const NamedProjs pnps = ipnps->second;
00203       const NamedProjs::const_iterator ipph = pnps.find(name);
00204       if (ipph != pnps.end()) {
00205         const ProjHandle pph = ipph->second;
00206         getLog() << Log::ERROR << "Projection clash! "
00207                  << parent.name() << " (" << &parent << ") "
00208                  << "is trying to overwrite its registered '" << name << "' "
00209                  << "projection (" << pph << "="
00210                  << pph->name() << ") with a non-equivalent projection "
00211                  << "(" << &proj << "=" << proj.name() << ")" << endl;
00212         getLog() << Log::ERROR << _getStatus();
00213         return false;
00214       }
00215     }
00216     return true;
00217   }

const Projection & getProjection ( const ProjectionApplier parent,
const string &  name 
) const

Retrieve a named projection for the given parent. Returning as a reference is partly to discourage ProjectionApplier classes from storing pointer members to the registered projections, since that can lead to problems and there is no need to do so.

Definition at line 262 of file ProjectionHandler.cc.

References ProjectionHandler::_namedprojs, ProjectionHandler::getLog(), and Log::TRACE.

Referenced by ProjectionApplier::getProjection().

00263                                                                                {
00264     getLog() << Log::TRACE << "Searching for child projection '"
00265              << name << "' of " << &parent << endl;
00266     NamedProjsMap::const_iterator nps = _namedprojs.find(&parent);
00267     if (nps == _namedprojs.end()) {
00268       ostringstream msg;
00269       msg << "No projections registered for parent " << &parent;
00270       throw Error(msg.str());
00271     }
00272     NamedProjs::const_iterator np = nps->second.find(name);
00273     if (np == nps->second.end()) {
00274       ostringstream msg;
00275       msg << "No projection '" << name << "' found for parent " << &parent;
00276       throw Error(msg.str());
00277     }
00278     // If it's registered with the projection handler, we must be able to safely
00279     // dereference the Projection pointer to a reference...
00280     return *(np->second);
00281   }

set< const Projection * > getChildProjections ( const ProjectionApplier parent,
ProjDepth  depth = SHALLOW 
) const

Get child projections for the given parent. By default this will just return the projections directly contained by the parent, but the depth argument can be changed to do a deep retrieval, which will recurse through the whole projection chain. In this case, there is no protection against getting stuck in a circular projection dependency loop.

Definition at line 237 of file ProjectionHandler.cc.

References ProjectionHandler::_namedprojs, ProjectionHandler::DEEP, and ProjectionHandler::SHALLOW.

Referenced by ProjectionApplier::getProjections().

00239   {
00240     set<const Projection*> toplevel;
00241     NamedProjs nps = _namedprojs.find(&parent)->second;
00242     foreach (NamedProjs::value_type& np, nps) {
00243       toplevel.insert(np.second.get());
00244     }
00245     if (depth == SHALLOW) {
00246       // Only return the projections directly contained within the top level
00247       return toplevel;
00248     } else {
00249       // Return recursively built projection list
00250       set<const Projection*> alllevels = toplevel;
00251       foreach (const Projection* p, toplevel) {
00252         set<const Projection*> allsublevels = getChildProjections(*p, DEEP);
00253         alllevels.insert(allsublevels.begin(), allsublevels.end());
00254       }
00255       return alllevels;
00256     }
00257   }

void clear (  ) 

Projection clearing method: deletes all known projections and empties the reference collections.

Definition at line 36 of file ProjectionHandler.cc.

References ProjectionHandler::_namedprojs, and ProjectionHandler::_projs.

Referenced by ProjectionHandler::~ProjectionHandler().

00036                                 {
00037     _projs.clear();
00038     _namedprojs.clear();
00039   }

void removeProjectionApplier ( ProjectionApplier parent  )  [private]

Remove a ProjectionApplier: designed to only be called by ~ProjectionApplier (as a friend).

Definition at line 222 of file ProjectionHandler.cc.

References ProjectionHandler::_namedprojs, ProjectionHandler::_projs, and Rivet::pi.

Referenced by ProjectionApplier::~ProjectionApplier().

00222                                                                            {
00223     NamedProjsMap::iterator npi = _namedprojs.find(&parent);
00224     if (npi != _namedprojs.end()) _namedprojs.erase(npi);
00225     //
00226     const Projection* parentprojptr = dynamic_cast<Projection*>(&parent);
00227     if (parentprojptr) {
00228       ProjHandle parentph(parentprojptr);
00229       ProjHandles::iterator pi = find(_projs.begin(), _projs.end(), parentph);
00230       if (pi != _projs.end()) _projs.erase(pi);
00231     }
00232   }

Log & getLog (  )  const [private]

Get a logger.

Definition at line 30 of file ProjectionHandler.cc.

References Log::getLog().

Referenced by ProjectionHandler::_checkDuplicate(), ProjectionHandler::_getEquiv(), ProjectionHandler::_register(), ProjectionHandler::getProjection(), and ProjectionHandler::registerProjection().

00030                                        {
00031     return Log::getLog("Rivet.ProjectionHandler");
00032   }


Friends And Related Function Documentation

friend class ProjectionApplier [friend]

ProjectionApplier's destructor needs to trigger cleaning up the proj handler repo.

Definition at line 46 of file ProjectionHandler.hh.


Member Data Documentation

ProjHandles _projs [private]

Cache of Projections for reverse lookup, to speed up registering new projections as _namedprojs gets large.

Definition at line 71 of file ProjectionHandler.hh.

Referenced by ProjectionHandler::_getEquiv(), ProjectionHandler::_register(), ProjectionHandler::clear(), and ProjectionHandler::removeProjectionApplier().

ProjectionHandler * _instance = 0 [static, private]

Singleton instance

Todo:
Threading?

Definition at line 96 of file ProjectionHandler.hh.

Referenced by ProjectionHandler::create().


The documentation for this class was generated from the following files: