00001 // -*- C++ -*- 00002 #ifndef RIVET_Projection_HH 00003 #define RIVET_Projection_HH 00004 00005 #include "Rivet/Rivet.hh" 00006 #include "Projection.fhh" 00007 #include "Rivet/Constraints.hh" 00008 #include "Rivet/ParticleName.hh" 00009 #include "Rivet/Event.fhh" 00010 #include "Rivet/Tools/Logging.fhh" 00011 00012 00013 namespace Rivet { 00014 00015 /// Projection is the base class of all Projections to be used by 00016 /// Rivet. A Projection object can be assigned to an Event object and 00017 /// will then define a processed part of the information available in 00018 /// the Event, which then can be used by other Projection objects 00019 /// and/or Analysis objects. 00020 /// 00021 /// The main virtual functions to be overridden by concrete sub-classes 00022 /// are project(const Event &) and compare(const Projection &). 00023 class Projection { 00024 00025 public: 00026 00027 /// Event is a friend. 00028 friend class Event; 00029 00030 /// The Cmp specialization for Projection is a friend. 00031 friend class Cmp<Projection>; 00032 00033 public: 00034 00035 /// @name Standard constructors and destructors. 00036 //@{ 00037 /// The default constructor. 00038 inline Projection() { 00039 addBeamPair(ANY, ANY); 00040 }; 00041 00042 /// The destructor. 00043 inline virtual ~Projection() { }; 00044 //@} 00045 00046 protected: 00047 00048 /// Take the information available in the Event and make the 00049 /// calculations necessary to obtain the projection. Note that this 00050 /// function must never be called except inside the 00051 /// Event::applyProjection(Projection *) function. If the information 00052 /// from other projections are necessary, their project(const Event&) 00053 /// should not be called, rather the corresponding objects should 00054 /// be added to the Event using the Event::applyProjection(Projection *) 00055 /// function. 00056 virtual void project(const Event& e) = 0; 00057 00058 00059 /// This function is used to define a unique ordering between 00060 /// different Projection objects of the same class. If this is 00061 /// considered to be equivalent to the Projector object, \a p, in the 00062 /// argument the function should return 0. If this object should be 00063 /// ordered before \a p a negative value should be returned, 00064 /// otherwise a positive value should be returned. This function must 00065 /// never be called explicitly, but should only be called from the 00066 /// operator<(const Projection &). When implementing the function in 00067 /// concrete sub-classes, it is then guarranteed that the Projection 00068 /// object \a p in the argument is of the same class as the sub-class 00069 /// and can be safely dynamically casted to that class. 00070 /// 00071 /// When implementing this function in a sub-class, the immediate 00072 /// base class version of the function should be called first. If the 00073 /// base class function returns a non-zero value, that value should 00074 /// be returned immediately. Only if zero is returned should this 00075 /// function check the member variables of the sub-class to determine 00076 /// whether this should be ordered before or after \a p, or if it is 00077 /// equivalent with \a p. 00078 virtual int compare(const Projection& p) const = 0; 00079 00080 public: 00081 00082 00083 /// Determine whether this object should be ordered before the object 00084 /// \a p given as argument. If \a p is of a different class than 00085 /// this, the before() function of the corresponding type_info 00086 /// objects is used. Otherwise, if the objects are of the same class, 00087 /// the virtual compare(const Projection &) will be returned. 00088 inline bool before(const Projection& p) const { 00089 const std::type_info& thisid = typeid(*this); 00090 const std::type_info& otherid = typeid(p); 00091 if (thisid == otherid) { 00092 return compare(p) < 0; 00093 } else { 00094 return thisid.before(otherid); 00095 } 00096 } 00097 00098 /// Return the Cuts objects for this projection. Derived 00099 /// classes should ensure that all contained projections are 00100 /// registered in the @a _projections set for the cut chaining 00101 /// to work. 00102 inline virtual const Cuts getCuts() const { 00103 Cuts totalCuts = _cuts; 00104 for (set<Projection*>::const_iterator p = _projections.begin(); p != _projections.end(); ++p) { 00105 totalCuts.addCuts((*p)->getCuts()); 00106 } 00107 return totalCuts; 00108 } 00109 00110 /// Return the BeamConstraints for this projection. Derived 00111 /// classes should ensure that all contained projections are 00112 /// registered in the @a _projections set for the beam constraint 00113 /// chaining to work. 00114 inline virtual const set<BeamPair> getBeamPairs() const { 00115 set<BeamPair> ret = _beamPairs; 00116 for (set<Projection*>::const_iterator p = _projections.begin(); p != _projections.end(); ++p) { 00117 ret = intersection(ret, (*p)->getBeamPairs()); 00118 } 00119 return ret; 00120 } 00121 00122 /// Get the name of the projection. 00123 inline virtual string getName() const { 00124 return ""; 00125 } 00126 00127 /// Get the contained projections, including recursion. 00128 inline set<Projection*> getProjections() const { 00129 set<Projection*> allProjections = _projections; 00130 for (set<Projection*>::const_iterator p = _projections.begin(); p != _projections.end(); ++p) { 00131 allProjections.insert((*p)->getProjections().begin(), (*p)->getProjections().end()); 00132 } 00133 return allProjections; 00134 } 00135 00136 protected: 00137 00138 /// Add a projection dependency to the projection list. 00139 inline Projection& addProjection(Projection& proj) { 00140 _projections.insert(&proj); 00141 return *this; 00142 } 00143 00144 /// Add a colliding beam pair. 00145 inline Projection& addBeamPair(const ParticleName& beam1, const ParticleName& beam2) { 00146 _beamPairs.insert(BeamPair(beam1, beam2)); 00147 return *this; 00148 } 00149 00150 /// Add a cut. 00151 inline Projection& addCut(const string& quantity, const Comparison& comparison, const double value) { 00152 //cout << getName() << "::addCut(): " << quantity << " " << comparison << " " << value << endl; 00153 _cuts.addCut(quantity, comparison, value); 00154 return *this; 00155 } 00156 00157 /// Get a Log object based on the getName() property of the calling projection object. 00158 Log& getLog(); 00159 00160 /// Parameter constraints 00161 Cuts _cuts; 00162 00163 /// Beam-type constraint 00164 set<BeamPair> _beamPairs; 00165 00166 /// Collection of pointers to projections, for automatically combining constraints. 00167 set<Projection*> _projections; 00168 00169 private: 00170 00171 /// The assignment operator is private and must never be called. 00172 /// In fact, it should not even be implemented. 00173 //Projection& operator=(const Projection&); 00174 00175 }; 00176 00177 } 00178 00179 00180 namespace std { 00181 00182 /// This is the function called when comparing two pointers to Rivet::Projection. 00183 template <> 00184 struct less<const Rivet::Projection*> 00185 : public binary_function<const Rivet::Projection*, const Rivet::Projection*, bool> { 00186 bool operator()(const Rivet::Projection* x, const Rivet::Projection* y) const { 00187 return x->before(*y); 00188 } 00189 }; 00190 00191 } 00192 00193 00194 #endif