Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Projection.hh

Go to the documentation of this file.
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