Selector.hh

00001 #ifndef __SELECTOR_HH__
00002 #define __SELECTOR_HH__
00003 
00004 //STARTHEADER
00005 // $Id: Selector.hh 1987 2011-03-10 10:01:56Z salam $
00006 //
00007 // Copyright (c) 2009-2010, Matteo Cacciari, Gavin Salam and Gregory Soyez
00008 //
00009 //----------------------------------------------------------------------
00010 // This file is part of FastJet.
00011 //
00012 //  FastJet is free software; you can redistribute it and/or modify
00013 //  it under the terms of the GNU General Public License as published by
00014 //  the Free Software Foundation; either version 2 of the License, or
00015 //  (at your option) any later version.
00016 //
00017 //  The algorithms that underlie FastJet have required considerable
00018 //  development and are described in hep-ph/0512210. If you use
00019 //  FastJet as part of work towards a scientific publication, please
00020 //  include a citation to the FastJet paper.
00021 //
00022 //  FastJet is distributed in the hope that it will be useful,
00023 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025 //  GNU General Public License for more details.
00026 //
00027 //  You should have received a copy of the GNU General Public License
00028 //  along with FastJet; if not, write to the Free Software
00029 //  Foundation, Inc.:
00030 //      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00031 //----------------------------------------------------------------------
00032 //ENDHEADER
00033 
00034 #include "fastjet/PseudoJet.hh"
00035 #include "fastjet/GhostedAreaSpec.hh"  // for area support
00036 #include <limits>
00037 #include <cmath>
00038 
00039 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
00040 
00041 //----------------------------------------------------------------------
00042 /// @ingroup selectors
00043 /// \class Selector
00044 /// Class that encodes information about cuts and other selection
00045 /// criteria that can be applied to PseudoJet(s).
00046 ///
00047 class Selector;
00048 //----------------------------------------------------------------------
00049 
00050 /// @ingroup selectors
00051 /// \class SelectorWorker
00052 /// default selector worker is an abstract virtual base class
00053 ///
00054 /// The Selector class is only an interface, it is the SelectorWorker
00055 /// that really does the work. To implement various selectors, one
00056 /// thus has to overload this class.
00057 class SelectorWorker {
00058 public:
00059   //----------------------------------------------------------
00060   // fundamental info
00061   //----------------------------------------------------------
00062   /// default dtor
00063   virtual ~SelectorWorker() {}
00064 
00065   //----------------------------------------------------------
00066   // basic operations for checking what gets selected
00067   //----------------------------------------------------------
00068 
00069   /// returns true if a given object passes the selection criterion.
00070   /// This has to be overloaded by derived workers
00071   virtual bool pass(const PseudoJet & jet) const = 0;
00072 
00073   /// For each jet that does not pass the cuts, this routine sets the 
00074   /// pointer to 0. 
00075   ///
00076   /// It does not assume that the PseudoJet* passed as argumetn are not NULL
00077   virtual void terminator(std::vector<const PseudoJet *> & jets) const {
00078     for (unsigned i = 0; i < jets.size(); i++) {
00079       if (jets[i] && !pass(*jets[i])) jets[i] = NULL;
00080     }
00081   }
00082 
00083   /// returns true if this can be applied jet by jet
00084   virtual bool applies_jet_by_jet() const {return true;}
00085 
00086   /// returns a description of the worker
00087   virtual std::string description() const {return "missing description";}
00088 
00089   //----------------------------------------------------------
00090   // operations for dealing with reference jets
00091   //----------------------------------------------------------
00092 
00093   /// returns true if the worker is defined with respect to a reference jet
00094   virtual bool takes_reference() const { return false;}
00095 
00096   /// sets the reference jet for the selector
00097   virtual void set_reference(const PseudoJet & reference){
00098     throw Error("set_reference(...) cannot be used for a selector worker that does not take a reference");
00099   }
00100 
00101   /// return a copy of the current object.
00102   ///
00103   /// This function is only called for objects that take a reference and need
00104   /// not be reimplemented otherwise.
00105   virtual SelectorWorker* copy(){ 
00106     throw Error("this SelectorWorker has nothing to copy");
00107   }
00108 
00109   //----------------------------------------------------------
00110   // operations for area and extent
00111   //----------------------------------------------------------
00112 
00113   /// returns the rapidity range for which it may return "true"
00114   virtual void get_rapidity_extent(double & rapmin, double & rapmax) const {
00115     rapmax = std::numeric_limits<double>::max();
00116     rapmin = -rapmax; 
00117   }
00118 
00119   /// check if it has a finite area
00120   virtual bool has_area() const { return false;}
00121 
00122   /// check if it has an analytically computable area
00123   virtual bool has_known_area() const { return false;}
00124 
00125   /// if it has a computable area, return it
00126   virtual double known_area() const{
00127     throw Error("this selector has no computable area");
00128   }
00129 };
00130 
00131 //----------------------------------------------------------------------
00132 // class Selector
00133 //
00134 // Class that encodes information about cuts that 
00135 class Selector{
00136 public:
00137   /// default constructor produces a Selector whose action is undefined
00138   /// (any attempt to use it will lead to an error)
00139   Selector() {}
00140 
00141   /// constructor that causes the Selector to use the supplied worker
00142   ///
00143   /// Note that the Selector takes ownership of the pointer to the
00144   /// worker (and so will delete automatically when appropriate).
00145   Selector(SelectorWorker * worker) {_worker.reset(worker);}
00146 
00147   /// dummy virtual dtor
00148   virtual ~Selector(){}
00149 
00150   /// return true if the jet passes the selection
00151   bool pass(const PseudoJet & jet) const {
00152     if (!validated_worker()->applies_jet_by_jet()) {
00153       throw Error("Cannot apply this selector to an individual jet");
00154     }
00155     return _worker->pass(jet);
00156   }
00157 
00158   /// an operator way of knowing whether a given jet passes the selection or not
00159   bool operator()(const PseudoJet & jet) const {
00160     return pass(jet);
00161   }
00162 
00163   /// returns true if this can be applied jet by jet
00164   bool applies_jet_by_jet() const {
00165     return validated_worker()->applies_jet_by_jet();
00166   }
00167 
00168   /// returns a vector with the jets that pass the selection
00169   std::vector<PseudoJet> operator()(const std::vector<PseudoJet> & jets) const;
00170 
00171   /// For each jet that does not pass the cuts, this routine sets the 
00172   /// pointer to 0. 
00173   ///
00174   /// It does not assume that the PseudoJet* passed as argumetn are not NULL
00175   virtual void nullify_non_selected(std::vector<const PseudoJet *> & jets) const {
00176     validated_worker()->terminator(jets);
00177   }
00178 
00179   /// returns the rapidity range for which it may return "true"
00180   void get_rapidity_extent(double &rapmin, double &rapmax) const {
00181     return validated_worker()->get_rapidity_extent(rapmin, rapmax);
00182   }
00183 
00184   /// return a textual description of the selector
00185   std::string description() const {
00186     return validated_worker()->description();
00187   }
00188 
00189   /// check if it has a meaningful and finite area
00190   bool has_area() const{
00191     return validated_worker()->has_area();
00192   }
00193 
00194   /// returns the rapidity-phi area associated with the Selector
00195   /// (throws InvalidArea if the area does not make sense).
00196   ///
00197   /// The argument passed is the requested cell area, which is used
00198   /// for obtaining a Monte Carlo type estimate of the area in case
00199   /// the Selector does not have an analytically known error. The
00200   /// Monte Carlo estimate involves a time penalty proportional to
00201   /// rapidity extent of the Selector.
00202   ///
00203   double area(double cell_area=gas::def_ghost_area) const;
00204 
00205   /// returns a (reference to) the underlying worker's shared pointer
00206   const SharedPtr<SelectorWorker> & worker() const {return _worker;}
00207 
00208   /// returns a worker if there is a valid one, otherwise throws an InvalidWorker error
00209   const SelectorWorker* validated_worker() const {
00210     const SelectorWorker* worker_ptr = _worker.get();
00211     if (worker_ptr == 0) throw InvalidWorker();
00212     return worker_ptr;
00213   }
00214 
00215   /// class that gets throw when a Selector is applied despite it not
00216   /// having a valid underlying worker.
00217   class InvalidWorker : public Error {
00218   public:
00219     InvalidWorker() : Error("Attempt to use Selector with no valid underlying worker") {}
00220   };
00221 
00222   /// class that gets throw when a Selector is applied despite it not
00223   /// having a valid underlying worker.
00224   class InvalidArea : public Error {
00225   public:
00226     InvalidArea() : Error("Attempt to obtain area from Selector for which this is not meaningful") {}
00227   };
00228 
00229   //----------------------------------------------------
00230   // non-const operations
00231   //----------------------------------------------------
00232 
00233 protected:
00234   /// Helper for copying selector workers if needed
00235   ///
00236   /// The following is needed if we want to modify a selectors that
00237   /// shares a worker with another selector. In that case, we need to
00238   /// get another copy of the worker to avoid interferences
00239   ///
00240   /// Note that any non-const operation has to call this to behave
00241   /// correctly w.r.t shared workers!
00242   void _copy_worker_if_needed(){
00243     // do nothing if there's a sinlge user of the worker
00244     if (_worker.unique()) return;
00245 
00246     // call the worker's copy
00247     //std::cout << "will make a copy of " << description() << std::endl;
00248     _worker.reset(_worker->copy());
00249   }
00250 public:
00251 
00252   /// returns true if this can be applied jet by jet
00253   bool takes_reference() const {
00254     return validated_worker()->takes_reference();
00255   }
00256 
00257   /// set the reference jet for this Selector
00258   const Selector & set_reference(const PseudoJet &reference){
00259 
00260     // if the worker does not take a reference jet, do nothing 
00261     if (! validated_worker()->takes_reference()){
00262       return *this;
00263     }
00264     
00265     // since this is a non-const operation, make sure we have a
00266     // correct behaviour with respect to shared workers
00267     _copy_worker_if_needed();
00268 
00269     _worker->set_reference(reference);
00270     return *this;
00271   }
00272 
00273 private:
00274   SharedPtr<SelectorWorker> _worker; ///< the underlying worker
00275 };
00276 
00277 
00278 //----------------------------------------------------------------------
00279 // a list of specific selectors
00280 //----------------------------------------------------------------------
00281 
00282 /// \addtogroup selectors
00283 /// @{
00284 
00285 
00286 // fundamental selectors
00287 //----------------------------------------------------------------------
00288 
00289 // "identity" selector that lets everything pass
00290 Selector SelectorIdentity();
00291 
00292 // logical operations
00293 //----------------------------------------------------------------------
00294 
00295 /// logical not applied on a selector
00296 ///
00297 /// This will keep objects that do not pass the 's' selector
00298 Selector operator!(const Selector & s);
00299 
00300 /// logical or between two selectors
00301 ///
00302 /// this will keep the objects that are selected by s1 or s2
00303 Selector operator ||(const Selector & s1, const Selector & s2);
00304 
00305 
00306 /// logical and between two selectors
00307 ///
00308 /// this will keep the objects that are selected by both s1 and s2
00309 /// 
00310 /// watch out: for both s1 and s2, the selection is applied on the
00311 ///   original list of objects. For successive applications of two
00312 ///   selectors (convolution/multiplication) see the operator *
00313 Selector operator&&(const Selector & s1, const Selector & s2);
00314 
00315 /// successive application of 2 selectors
00316 ///
00317 /// Apply the selector s2, then the selector s1.
00318 ///
00319 /// watch out: the operator * acts like an operator product i.e. does
00320 ///   not commute. The order of its arguments is therefore important.
00321 ///   Whenever they commute (in particluar, when they apply jet by
00322 ///   jet), this would have the same effect as the logical &&.
00323 Selector operator*(const Selector & s1, const Selector & s2);
00324 
00325 
00326 // selection with kinematic cuts
00327 //----------------------------------------------------------------------
00328 Selector SelectorPtMin(double ptmin);                    ///< select objects with pt >= ptmin
00329 Selector SelectorPtMax(double ptmax);                    ///< select objects with pt <= ptmax
00330 Selector SelectorPtRange(double ptmin, double ptmax);    ///< select objects with ptmin <= pt <= ptmax
00331 
00332 Selector SelectorEtMin(double Etmin);                    ///< select objects with Et >= Etmin
00333 Selector SelectorEtMax(double Etmax);                    ///< select objects with Et <= Etmax
00334 Selector SelectorEtRange(double Etmin, double Etmax);    ///< select objects with Etmin <= Et <= Etmax
00335 
00336 Selector SelectorEMin(double Emin);                      ///< select objects with E >= Emin
00337 Selector SelectorEMax(double Emax);                      ///< select objects with E <= Emax
00338 Selector SelectorERange(double Emin, double Emax);       ///< select objects with Emin <= E <= Emax
00339 
00340 Selector SelectorMMin(double Mmin);                      ///< select objects with M >= Mmin
00341 Selector SelectorMMax(double Mmax);                      ///< select objects with M <= Mmax
00342 Selector SelectorMRange(double Mmin, double Mmax);       ///< select objects with Mmin <= M <= Mmax
00343 
00344 Selector SelectorRapMin(double rapmin);                  ///< select objects with rap >= rapmin
00345 Selector SelectorRapMax(double rapmax);                  ///< select objects with rap <= rapmax
00346 Selector SelectorRapRange(double rapmin, double rapmax); ///< select objects with rapmin <= rap <= rapmax
00347 
00348 Selector SelectorAbsRapMin(double absrapmin);                     ///< select objects with |rap| >= absrapmin
00349 Selector SelectorAbsRapMax(double absrapmax);                     ///< select objects with |rap| <= absrapmax
00350 Selector SelectorAbsRapRange(double absrapmin, double absrapmax); ///< select objects with absrapmin <= |rap| <= absrapmax
00351 
00352 Selector SelectorEtaMin(double etamin);                  ///< select objects with eta >= etamin
00353 Selector SelectorEtaMax(double etamax);                  ///< select objects with eta <= etamax
00354 Selector SelectorEtaRange(double etamin, double etamax); ///< select objects with etamin <= eta <= etamax
00355 
00356 Selector SelectorAbsEtaMin(double absetamin);                     ///< select objects with |eta| >= absetamin
00357 Selector SelectorAbsEtaMax(double absetamax);                     ///< select objects with |eta| <= absetamax
00358 Selector SelectorAbsEtaRange(double absetamin, double absetamax); ///< select objects with absetamin <= |eta| <= absetamax
00359 
00360 Selector SelectorPhiRange(double phimin, double phimax); ///< select objects with phimin <= phi <= phimax
00361 
00362 /// select objects with rapmin <= rap <= rapmax  &&  phimin <= phi <= phimax
00363 ///
00364 /// Note that this is essentially a combination of SelectorRapRange
00365 /// and SelectorPhiRange. We provide it as a Selector on its own in
00366 /// order to use the known area (which would otherwise be lost by the &&
00367 /// operator)
00368 Selector SelectorRapPhiRange(double rapmin, double rapmax, double phimin, double phimax);
00369 
00370 /// select the n hardest objects 
00371 Selector SelectorNHardest(unsigned int n); 
00372 
00373 
00374 // Selectors that take (require) a reference jet.
00375 //----------------------------------------------------------------------
00376 
00377 /// select objets within a distance 'radius' from the location of the
00378 /// reference jet, set by Selector::set_reference(...)
00379 Selector SelectorCircle(const double & radius); 
00380 
00381 /// select objets with distance from the reference jet is between 'radius_in'
00382 /// and 'radius_out'; the reference jet is set by Selector::set_reference(...)
00383 Selector SelectorDoughnut(const double & radius_in, const double & radius_out); 
00384 
00385 /// select objets within a rapidity distance 'half_width' from the
00386 /// location of the reference jet, set by Selector::set_reference(...)
00387 Selector SelectorStrip(const double & half_width);
00388 
00389 /// select objets within rapidity distance 'half_rap_width' from the
00390 /// reference jet and azimuthal-angle distance within 'half_phi_width'; the
00391 /// reference jet is set by Selector::set_reference(...)
00392 Selector SelectorRectangle(const double & half_rap_width, const double & half_phi_width);
00393 
00394 
00395 /// select objects that carry at least a fraction "fraction" of the
00396 /// reference jet. The reference jet must have been set with
00397 /// Selector::set_reference(...)
00398 Selector SelectorPtFractionMin(double fraction);
00399 
00400 
00401 // additional (mostly helper) selectors
00402 //----------------------------------------------------------------------
00403 
00404 /// select objects that are (or are only made of) ghosts.
00405 /// PseudoJets for which has_area() are considered non-pure-ghost.
00406 Selector SelectorIsPureGhost();
00407 
00408 /// @}
00409 
00410 FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
00411 
00412 #endif // __SELECTOR_HH__
00413