The projection handler is a central repository for projections to be used in a Rivet analysis run. More...
#include <ProjectionHandler.hh>
Public Types | |
enum | ProjDepth { SHALLOW, DEEP } |
Enum to specify depth of projection search. More... | |
typedef set< ProjHandle > | ProjHandles |
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 Projection & | registerProjection (const ProjectionApplier &parent, const Projection &proj, const string &name) |
Attach and retrieve a projection as a reference. | |
const Projection * | registerProjection (const ProjectionApplier &parent, const Projection *proj, const string &name) |
Attach and retrieve a projection as a pointer. | |
Projection retrieval. */ | |
const Projection & | getProjection (const ProjectionApplier &parent, const string &name) const |
set< const Projection * > | getChildProjections (const ProjectionApplier &parent, ProjDepth depth=SHALLOW) const |
Static Public Member Functions | |
static ProjectionHandler & | getInstance () |
Singleton creation function. | |
Private Types | |
typedef map< const ProjectionApplier *, NamedProjs > | NamedProjsMap |
Private Member Functions | |
void | removeProjectionApplier (ProjectionApplier &parent) |
Remove a ProjectionApplier: designed to only be called by ~ProjectionApplier (as a friend). | |
Log & | getLog () const |
Get a logger. | |
Projection registration internal helpers | |
const Projection * | _getEquiv (const Projection &proj) const |
const Projection * | _clone (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 |
Friends | |
class | ProjectionApplier |
ProjectionApplier's destructor needs to trigger cleaning up the proj handler repo. | |
Construction. */ | |
| |
static ProjectionHandler * | _instance = 0 |
~ProjectionHandler () | |
Private destructor means no inheritance from this class. | |
ProjectionHandler & | operator= (const ProjectionHandler &) |
The assignment operator is hidden. | |
ProjectionHandler (const ProjectionHandler &) | |
The copy constructor is hidden. | |
ProjectionHandler () | |
The standard constructor. |
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 41 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 52 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 62 of file ProjectionHandler.hh.
typedef set<ProjHandle> ProjHandles |
Typedef for a vector of Projection pointers.
Definition at line 48 of file ProjectionHandler.hh.
enum ProjDepth |
Enum to specify depth of projection search.
Definition at line 55 of file ProjectionHandler.hh.
~ProjectionHandler | ( | ) | [private] |
Private destructor means no inheritance from this class.
Definition at line 38 of file ProjectionHandler.cc.
References ProjectionHandler::clear().
00038 { 00039 clear(); 00040 }
ProjectionHandler | ( | const ProjectionHandler & | ) | [private] |
The copy constructor is hidden.
ProjectionHandler | ( | ) | [inline, private] |
The standard constructor.
Definition at line 88 of file ProjectionHandler.hh.
Referenced by ProjectionHandler::getInstance().
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 192 of file ProjectionHandler.cc.
References ProjectionHandler::_getStatus(), ProjectionHandler::_namedprojs, Log::ERROR, ProjectionHandler::getLog(), Projection::name(), and ProjectionApplier::name().
Referenced by ProjectionHandler::registerProjection().
00195 { 00196 NamedProjsMap::const_iterator ipnps = _namedprojs.find(&parent); 00197 if (ipnps != _namedprojs.end()) { 00198 const NamedProjs pnps = ipnps->second; 00199 const NamedProjs::const_iterator ipph = pnps.find(name); 00200 if (ipph != pnps.end()) { 00201 const ProjHandle pph = ipph->second; 00202 getLog() << Log::ERROR << "Projection clash! " 00203 << parent.name() << " (" << &parent << ") " 00204 << "is trying to overwrite its registered '" << name << "' " 00205 << "projection (" << pph << "=" 00206 << pph->name() << ") with a non-equivalent projection " 00207 << "(" << &proj << "=" << proj.name() << ")" << endl; 00208 getLog() << Log::ERROR << _getStatus(); 00209 return false; 00210 } 00211 } 00212 return true; 00213 }
const Projection * _clone | ( | const Projection & | proj | ) | [private] |
Make a clone of proj, copying across child references from the original.
Definition at line 92 of file ProjectionHandler.cc.
References ProjectionHandler::_namedprojs, Projection::clone(), ProjectionHandler::getLog(), Projection::name(), and Log::TRACE.
Referenced by ProjectionHandler::registerProjection().
00093 { 00094 // Clone a new copy of the passed projection on the heap 00095 getLog() << Log::TRACE << "Cloning projection " << proj.name() << " from " << &proj << endl; 00096 const Projection* newproj = proj.clone(); 00097 getLog() << Log::TRACE << "Cloned projection " << proj.name() << " at " << newproj << endl; 00098 getLog() << Log::TRACE << "Clone types " << typeid(proj).name() << " -> " << typeid(newproj).name() << endl; 00099 00100 // Copy all the child ProjHandles when cloning, since otherwise links to "stack parents" 00101 // will be generated by their children, without any connection to the cloned parent 00102 if (&proj != newproj) { 00103 NamedProjsMap::const_iterator nps = _namedprojs.find(&proj); 00104 if (nps != _namedprojs.end()) { 00105 getLog() << Log::TRACE << "Cloning registered projections list: " 00106 << &proj << " -> " << newproj << endl; 00107 _namedprojs[newproj] = nps->second; 00108 } 00109 } 00110 00111 return newproj; 00112 }
const Projection * _getEquiv | ( | const Projection & | proj | ) | const [private] |
Try to get an equivalent projection from the system
Definition at line 139 of file ProjectionHandler.cc.
References ProjectionHandler::_projs, Rivet::EQUIVALENT, ProjectionHandler::getLog(), Projection::name(), Rivet::pcmp(), and Log::TRACE.
Referenced by ProjectionHandler::registerProjection().
00140 { 00141 // Get class type using RTTI 00142 const std::type_info& newtype = typeid(proj); 00143 getLog() << Log::TRACE << "RTTI type of " << &proj << " is " << newtype.name() << endl; 00144 00145 // Compare to ALL projections via _projs collection 00146 getLog() << Log::TRACE << "Comparing " << &proj 00147 << " with " << _projs.size() 00148 << " registered projection" << (_projs.size() == 1 ? "" : "s") << endl; 00149 foreach (const ProjHandle& ph, _projs) { 00150 // Make sure the concrete types match, using RTTI. 00151 const std::type_info& regtype = typeid(*ph); 00152 getLog() << Log::TRACE << "RTTI type comparison with " << ph << ": " 00153 << newtype.name() << " vs. " << regtype.name() << endl; 00154 if (newtype != regtype) continue; 00155 getLog() << Log::TRACE << "RTTI type matches with " << ph << endl; 00156 00157 // Test for semantic match 00158 if (pcmp(*ph, proj) != EQUIVALENT) { 00159 getLog() << Log::TRACE << "Projections at " 00160 << &proj << " and " << ph << " are not equivalent" << endl; 00161 } else { 00162 getLog() << Log::TRACE << "MATCH! Projections at " 00163 << &proj << " and " << ph << " are equivalent" << endl; 00164 return ph.get(); 00165 } 00166 } 00167 00168 // If no match, just return a null pointer 00169 return 0; 00170 }
string _getStatus | ( | ) | const [private] |
Get a string dump of the current ProjHandler structure.
Definition at line 174 of file ProjectionHandler.cc.
References ProjectionHandler::_namedprojs.
Referenced by ProjectionHandler::_checkDuplicate().
00174 { 00175 ostringstream msg; 00176 msg << "Current projection hierarchy:" << endl; 00177 foreach (const NamedProjsMap::value_type& nps, _namedprojs) { 00178 //const string parentname = nps.first->name(); 00179 msg << nps.first << endl; //"(" << parentname << ")" << endl; 00180 foreach (const NamedProjs::value_type& np, nps.second) { 00181 msg << " " << np.second << " (" << np.second->name() 00182 << ", locally called '" << np.first << "')" << endl; 00183 } 00184 msg << endl; 00185 } 00186 return msg.str(); 00187 }
const Projection * _register | ( | const ProjectionApplier & | parent, | |
const Projection & | proj, | |||
const string & | name | |||
) | [private] |
Internal function to do the registering.
Definition at line 119 of file ProjectionHandler.cc.
References ProjectionHandler::_namedprojs, ProjectionHandler::_projs, ProjectionHandler::getLog(), and Log::TRACE.
Referenced by ProjectionHandler::registerProjection().
00122 { 00123 ProjHandle ph(&proj); 00124 getLog() << Log::TRACE << "Registering new projection at " << ph << endl; 00125 00126 // Add the passed Projection to _projs 00127 _projs.insert(ph); 00128 00129 // Add the ProjApplier* => name location to the associative container 00130 _namedprojs[&parent][name] = ph; 00131 00132 return ph.get(); 00133 }
void clear | ( | ) |
Projection clearing method: deletes all known projections and empties the reference collections.
Definition at line 31 of file ProjectionHandler.cc.
References ProjectionHandler::_namedprojs, and ProjectionHandler::_projs.
Referenced by ProjectionHandler::~ProjectionHandler().
00031 { 00032 _projs.clear(); 00033 _namedprojs.clear(); 00034 }
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 233 of file ProjectionHandler.cc.
References ProjectionHandler::_namedprojs, ProjectionHandler::DEEP, and ProjectionHandler::SHALLOW.
Referenced by ProjectionApplier::getProjections().
00235 { 00236 set<const Projection*> toplevel; 00237 NamedProjs nps = _namedprojs.find(&parent)->second; 00238 foreach (NamedProjs::value_type& np, nps) { 00239 toplevel.insert(np.second.get()); 00240 } 00241 if (depth == SHALLOW) { 00242 // Only return the projections directly contained within the top level 00243 return toplevel; 00244 } else { 00245 // Return recursively built projection list 00246 set<const Projection*> alllevels = toplevel; 00247 foreach (const Projection* p, toplevel) { 00248 set<const Projection*> allsublevels = getChildProjections(*p, DEEP); 00249 alllevels.insert(allsublevels.begin(), allsublevels.end()); 00250 } 00251 return alllevels; 00252 } 00253 }
ProjectionHandler & getInstance | ( | ) | [static] |
Singleton creation function.
Definition at line 14 of file ProjectionHandler.cc.
References ProjectionHandler::_instance, ProjectionHandler::getLog(), ProjectionHandler::ProjectionHandler(), and Log::TRACE.
00014 { 00015 if (!_instance) { 00016 _instance = new ProjectionHandler(); 00017 Log::getLog("Rivet.ProjectionHandler") 00018 << Log::TRACE << "Created new ProjectionHandler at " << _instance << endl; 00019 } 00020 return *_instance; 00021 }
Log & getLog | ( | ) | const [private] |
Get a logger.
Definition at line 26 of file ProjectionHandler.cc.
Referenced by ProjectionHandler::_checkDuplicate(), ProjectionHandler::_clone(), ProjectionHandler::_getEquiv(), ProjectionHandler::_register(), ProjectionHandler::getInstance(), and ProjectionHandler::registerProjection().
00026 { 00027 return Log::getLog("Rivet.ProjectionHandler"); 00028 }
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 258 of file ProjectionHandler.cc.
References ProjectionHandler::_namedprojs.
Referenced by ProjectionApplier::getProjection().
00259 { 00260 //getLog() << Log::TRACE << "Searching for child projection '" 00261 // << name << "' of " << &parent << endl; 00262 NamedProjsMap::const_iterator nps = _namedprojs.find(&parent); 00263 if (nps == _namedprojs.end()) { 00264 ostringstream msg; 00265 msg << "No projections registered for parent " << &parent; 00266 throw Error(msg.str()); 00267 } 00268 NamedProjs::const_iterator np = nps->second.find(name); 00269 if (np == nps->second.end()) { 00270 ostringstream msg; 00271 msg << "No projection '" << name << "' found for parent " << &parent; 00272 throw Error(msg.str()); 00273 } 00274 // If it's registered with the projection handler, we must be able to safely 00275 // dereference the Projection pointer to a reference... 00276 return *(np->second); 00277 }
ProjectionHandler& operator= | ( | const ProjectionHandler & | ) | [private] |
The assignment operator is hidden.
const Projection * registerProjection | ( | const ProjectionApplier & | parent, | |
const Projection * | proj, | |||
const string & | name | |||
) |
Attach and retrieve a projection as a pointer.
Definition at line 81 of file ProjectionHandler.cc.
References ProjectionHandler::registerProjection().
00083 { 00084 if (proj == 0) return 0; 00085 const Projection& p = registerProjection(parent, *proj, name); 00086 return &p; 00087 }
const Projection & registerProjection | ( | const ProjectionApplier & | parent, | |
const Projection & | proj, | |||
const string & | name | |||
) |
Attach and retrieve a projection as a reference.
Definition at line 47 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().
00050 { 00051 getLog() << Log::TRACE << "Trying to register" 00052 << " projection " << &proj << " (" << proj.name() << ")" 00053 << " for parent " << &parent << " (" << parent.name() << ")" 00054 << " with name '" << name << "'" << endl; 00055 00056 // Check for duplicate use of "name" on "parent" 00057 const bool dupOk = _checkDuplicate(parent, proj, name); 00058 if (!dupOk) { 00059 cerr << "Duplicate name '" << name << "' in parent '" << parent.name() << "'." << endl; 00060 exit(1); 00061 } 00062 00063 // Choose which version of the projection to register with this parent and name 00064 const Projection* p = _getEquiv(proj); 00065 if (p == 0) { // a null pointer is a non-match 00066 // If there is no equivalent projection, clone proj and use the clone for registering 00067 p = _clone(proj); 00068 } 00069 00070 // Do the registering 00071 p = _register(parent, *p, name); 00072 00073 // Return registered proj 00074 return *p; 00075 }
void removeProjectionApplier | ( | ProjectionApplier & | parent | ) | [private] |
Remove a ProjectionApplier: designed to only be called by ~ProjectionApplier (as a friend).
Definition at line 218 of file ProjectionHandler.cc.
References ProjectionHandler::_namedprojs, ProjectionHandler::_projs, and Rivet::pi.
Referenced by ProjectionApplier::~ProjectionApplier().
00218 { 00219 NamedProjsMap::iterator npi = _namedprojs.find(&parent); 00220 if (npi != _namedprojs.end()) _namedprojs.erase(npi); 00221 // 00222 const Projection* parentprojptr = dynamic_cast<Projection*>(&parent); 00223 if (parentprojptr) { 00224 ProjHandle parentph(parentprojptr); 00225 ProjHandles::iterator pi = find(_projs.begin(), _projs.end(), parentph); 00226 if (pi != _projs.end()) _projs.erase(pi); 00227 } 00228 }
friend class ProjectionApplier [friend] |
ProjectionApplier's destructor needs to trigger cleaning up the proj handler repo.
Definition at line 45 of file ProjectionHandler.hh.
ProjectionHandler * _instance = 0 [static, private] |
Definition at line 91 of file ProjectionHandler.hh.
Referenced by ProjectionHandler::getInstance().
NamedProjsMap _namedprojs [private] |
Core data member, associating a given containing class (via a ProjectionApplier pointer) to its contained projections.
Definition at line 66 of file ProjectionHandler.hh.
Referenced by ProjectionHandler::_checkDuplicate(), ProjectionHandler::_clone(), ProjectionHandler::_getStatus(), ProjectionHandler::_register(), ProjectionHandler::clear(), ProjectionHandler::getChildProjections(), ProjectionHandler::getProjection(), and ProjectionHandler::removeProjectionApplier().
ProjHandles _projs [private] |
Cache of Projections for reverse lookup, to speed up registering new projections as _namedprojs
gets large.
Definition at line 70 of file ProjectionHandler.hh.
Referenced by ProjectionHandler::_getEquiv(), ProjectionHandler::_register(), ProjectionHandler::clear(), and ProjectionHandler::removeProjectionApplier().