FastJet 3.0.5
Selector.hh
00001 #ifndef __FASTJET_SELECTOR_HH__
00002 #define __FASTJET_SELECTOR_HH__
00003 
00004 //STARTHEADER
00005 // $Id: Selector.hh 3203 2013-09-15 07:49:50Z salam $
00006 //
00007 // Copyright (c) 2009-2011, Matteo Cacciari, Gavin P. 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, see <http://www.gnu.org/licenses/>.
00029 //----------------------------------------------------------------------
00030 //ENDHEADER
00031 
00032 #include "fastjet/PseudoJet.hh"
00033 #ifndef __FJCORE__
00034 #include "fastjet/RangeDefinition.hh"  // for initialisation from a RangeDefinition
00035 #endif  // __FJCORE__
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   //----------------------------------------------------------
00091   // operations for dealing with reference jets
00092   //----------------------------------------------------------
00093 
00094   /// returns true if the worker is defined with respect to a reference jet
00095   virtual bool takes_reference() const { return false;}
00096 
00097   /// sets the reference jet for the selector
00098   /// NB: "reference" is commented to avoid unused-variable compiler warnings
00099   virtual void set_reference(const PseudoJet & /*reference*/){
00100     throw Error("set_reference(...) cannot be used for a selector worker that does not take a reference");
00101   }
00102 
00103   /// return a copy of the current object.
00104   ///
00105   /// This function is only called for objects that take a reference and need
00106   /// not be reimplemented otherwise.
00107   virtual SelectorWorker* copy(){ 
00108     throw Error("this SelectorWorker has nothing to copy");
00109   }
00110 
00111   //----------------------------------------------------------
00112   // operations for area and extent
00113   //----------------------------------------------------------
00114 
00115   /// returns the rapidity range for which it may return "true"
00116   virtual void get_rapidity_extent(double & rapmin, double & rapmax) const {
00117     rapmax = std::numeric_limits<double>::infinity();
00118     rapmin = -rapmax; 
00119   }
00120 
00121   /// check if it is a geometric selector (i.e. only puts constraints
00122   /// on rapidity and azimuthal angle)
00123   virtual bool is_geometric() const { return false;}
00124 
00125   /// check if it has a finite area
00126   virtual bool has_finite_area() const;
00127 
00128   /// check if it has an analytically computable area
00129   virtual bool has_known_area() const { return false;}
00130 
00131   /// if it has a computable area, return it
00132   virtual double known_area() const{
00133     throw Error("this selector has no computable area");
00134   }
00135 };
00136 
00137 //----------------------------------------------------------------------
00138 // class Selector
00139 //
00140 // Class that encodes information about cuts that 
00141 class Selector{
00142 public:
00143   /// default constructor produces a Selector whose action is undefined
00144   /// (any attempt to use it will lead to an error)
00145   Selector() {}
00146 
00147   /// constructor that causes the Selector to use the supplied worker
00148   ///
00149   /// Note that the Selector takes ownership of the pointer to the
00150   /// worker (and so will delete automatically when appropriate).
00151   Selector(SelectorWorker * worker_in) {_worker.reset(worker_in);}
00152 
00153 
00154 #ifndef __FJCORE__
00155   /// ctor from a RangeDefinition
00156   ///
00157   /// This is provided for backward compatibility and will be removed in
00158   /// a future major release of FastJet
00159   ///
00160   /// Watch out that the Selector will only hold a pointer to the
00161   /// range so the selector will crash if one tries to use it after
00162   /// the range has gone out of scope. We thus strongly advise against
00163   /// the direct use of this constructor.
00164   Selector(const RangeDefinition &range);
00165 #endif  // __FJCORE__
00166 
00167   /// dummy virtual dtor
00168   virtual ~Selector(){}
00169 
00170   /// return true if the jet passes the selection
00171   bool pass(const PseudoJet & jet) const {
00172     if (!validated_worker()->applies_jet_by_jet()) {
00173       throw Error("Cannot apply this selector to an individual jet");
00174     }
00175     return _worker->pass(jet);
00176   }
00177 
00178   /// an operator way of knowing whether a given jet passes the selection or not
00179   bool operator()(const PseudoJet & jet) const {
00180     return pass(jet);
00181   }
00182 
00183   /// Return a count of the objects that pass the selection.
00184   ///
00185   /// This will often be more efficient that getting the vector of objects that
00186   /// passes and then evaluating the size of the vector
00187   unsigned int count(const std::vector<PseudoJet> & jets) const;
00188 
00189   /// sift the input jets into two vectors -- those that pass the selector
00190   /// and those that do not
00191   void sift(const std::vector<PseudoJet> & jets,
00192                   std::vector<PseudoJet> & jets_that_pass,
00193                   std::vector<PseudoJet> & jets_that_fail) const;
00194 
00195   /// returns true if this can be applied jet by jet
00196   bool applies_jet_by_jet() const {
00197     return validated_worker()->applies_jet_by_jet();
00198   }
00199 
00200   /// returns a vector with the jets that pass the selection
00201   std::vector<PseudoJet> operator()(const std::vector<PseudoJet> & jets) const;
00202 
00203   /// For each jet that does not pass the cuts, this routine sets the 
00204   /// pointer to 0. 
00205   ///
00206   /// It is legitimate for some (or all) of the pointers that are
00207   /// passed to already be NULL.
00208   virtual void nullify_non_selected(std::vector<const PseudoJet *> & jets) const {
00209     validated_worker()->terminator(jets);
00210   }
00211 
00212   /// returns the rapidity range for which it may return "true"
00213   void get_rapidity_extent(double &rapmin, double &rapmax) const {
00214     return validated_worker()->get_rapidity_extent(rapmin, rapmax);
00215   }
00216 
00217   /// returns a textual description of the selector
00218   std::string description() const {
00219     return validated_worker()->description();
00220   }
00221 
00222   /// returns true if it is a geometric selector (i.e. one that only puts
00223   /// constraints on rapidities and azimuthal angles)
00224   bool is_geometric() const{
00225     return validated_worker()->is_geometric();
00226   }
00227 
00228   /// returns true if it has a meaningful and finite area (i.e. the
00229   /// Selector has the property that is_geometric() returns true and
00230   /// the rapidity extent is finite).
00231   bool has_finite_area() const{
00232     return validated_worker()->has_finite_area();
00233   }
00234 
00235 #ifndef __FJCORE__
00236   /// returns the rapidity-phi area associated with the Selector
00237   /// (throws InvalidArea if the area does not make sense).
00238   ///
00239   /// If the result is not known analytically, the area will be
00240   /// estimated using a pseudo Monte Carlo method (as for jet areas),
00241   /// using the default ghost area from the GhostedAreaSpec class
00242   /// (0.01). The Monte Carlo estimate involves a time penalty
00243   /// proportional to the ratio of the rapidity extent of the Selector
00244   /// divided by the ghost area.
00245   double area() const;
00246 
00247   /// returns the rapidity-phi area associated with the Selector
00248   /// (throws InvalidArea if the area does not make sense).
00249   ///
00250   /// The behaviour is the as with the area() call, but with the
00251   /// ability to additionally specify the ghost area to be used in the
00252   /// case of a Monte Carlo area evaluation.
00253   ///
00254   double area(double ghost_area) const;
00255 #endif  // __FJCORE__
00256 
00257   /// returns a (reference to) the underlying worker's shared pointer
00258   const SharedPtr<SelectorWorker> & worker() const {return _worker;}
00259 
00260   /// returns a worker if there is a valid one, otherwise throws an InvalidWorker error
00261   const SelectorWorker* validated_worker() const {
00262     const SelectorWorker* worker_ptr = _worker.get();
00263     if (worker_ptr == 0) throw InvalidWorker();
00264     return worker_ptr;
00265   }
00266 
00267   /// returns true if this can be applied jet by jet
00268   bool takes_reference() const {
00269     return validated_worker()->takes_reference();
00270   }
00271 
00272   /// set the reference jet for this Selector
00273   const Selector & set_reference(const PseudoJet &reference){
00274 
00275     // if the worker does not take a reference jet, do nothing 
00276     if (! validated_worker()->takes_reference()){
00277       return *this;
00278     }
00279     
00280     // since this is a non-const operation, make sure we have a
00281     // correct behaviour with respect to shared workers
00282     _copy_worker_if_needed();
00283 
00284     _worker->set_reference(reference);
00285     return *this;
00286   }
00287 
00288   /// class that gets throw when a Selector is applied despite it not
00289   /// having a valid underlying worker.
00290   class InvalidWorker : public Error {
00291   public:
00292     InvalidWorker() : Error("Attempt to use Selector with no valid underlying worker") {}
00293   };
00294 
00295   /// class that gets throw when a Selector is applied despite it not
00296   /// having a valid underlying worker.
00297   class InvalidArea : public Error {
00298   public:
00299     InvalidArea() : Error("Attempt to obtain area from Selector for which this is not meaningful") {}
00300   };
00301 
00302   // some operators (applying directly on a Selector)
00303   //----------------------------------------------------------------------
00304   /// For 2 Selectors a and b, a &= b is eauivalent to a = a && b;
00305   Selector & operator &=(const Selector & b);
00306 
00307   /// For 2 Selectors a and b, a |= b is eauivalent to a = a || b;
00308   Selector & operator |=(const Selector & b);
00309 
00310 
00311 protected:
00312   /// Helper for copying selector workers if needed
00313   ///
00314   /// The following is needed if we want to modify a selectors that
00315   /// shares a worker with another selector. In that case, we need to
00316   /// get another copy of the worker to avoid interferences
00317   ///
00318   /// Note that any non-const operation has to call this to behave
00319   /// correctly w.r.t shared workers!
00320   void _copy_worker_if_needed(){
00321     // do nothing if there's a sinlge user of the worker
00322     if (_worker.unique()) return;
00323 
00324     // call the worker's copy
00325     //std::cout << "will make a copy of " << description() << std::endl;
00326     _worker.reset(_worker->copy());
00327   }
00328 
00329 private:
00330   SharedPtr<SelectorWorker> _worker; ///< the underlying worker
00331 };
00332 
00333 
00334 //----------------------------------------------------------------------
00335 // a list of specific selectors
00336 //----------------------------------------------------------------------
00337 
00338 /// \addtogroup selectors
00339 /// @{
00340 
00341 
00342 // fundamental selectors
00343 //----------------------------------------------------------------------
00344 
00345 // "identity" selector that lets everything pass
00346 Selector SelectorIdentity();
00347 
00348 // logical operations
00349 //----------------------------------------------------------------------
00350 
00351 /// logical not applied on a selector
00352 ///
00353 /// This will keep objects that do not pass the 's' selector
00354 Selector operator!(const Selector & s);
00355 
00356 /// logical or between two selectors
00357 ///
00358 /// this will keep the objects that are selected by s1 or s2
00359 Selector operator ||(const Selector & s1, const Selector & s2);
00360 
00361 
00362 /// logical and between two selectors
00363 ///
00364 /// this will keep the objects that are selected by both s1 and s2
00365 /// 
00366 /// watch out: for both s1 and s2, the selection is applied on the
00367 ///   original list of objects. For successive applications of two
00368 ///   selectors (convolution/multiplication) see the operator *
00369 Selector operator&&(const Selector & s1, const Selector & s2);
00370 
00371 /// successive application of 2 selectors
00372 ///
00373 /// Apply the selector s2, then the selector s1.
00374 ///
00375 /// watch out: the operator * acts like an operator product i.e. does
00376 ///   not commute. The order of its arguments is therefore important.
00377 ///   Whenever they commute (in particluar, when they apply jet by
00378 ///   jet), this would have the same effect as the logical &&.
00379 Selector operator*(const Selector & s1, const Selector & s2);
00380 
00381 
00382 // selection with kinematic cuts
00383 //----------------------------------------------------------------------
00384 Selector SelectorPtMin(double ptmin);                    ///< select objects with pt >= ptmin
00385 Selector SelectorPtMax(double ptmax);                    ///< select objects with pt <= ptmax
00386 Selector SelectorPtRange(double ptmin, double ptmax);    ///< select objects with ptmin <= pt <= ptmax
00387 
00388 Selector SelectorEtMin(double Etmin);                    ///< select objects with Et >= Etmin
00389 Selector SelectorEtMax(double Etmax);                    ///< select objects with Et <= Etmax
00390 Selector SelectorEtRange(double Etmin, double Etmax);    ///< select objects with Etmin <= Et <= Etmax
00391 
00392 Selector SelectorEMin(double Emin);                      ///< select objects with E >= Emin
00393 Selector SelectorEMax(double Emax);                      ///< select objects with E <= Emax
00394 Selector SelectorERange(double Emin, double Emax);       ///< select objects with Emin <= E <= Emax
00395 
00396 Selector SelectorMassMin(double Mmin);                      ///< select objects with Mass >= Mmin
00397 Selector SelectorMassMax(double Mmax);                      ///< select objects with Mass <= Mmax
00398 Selector SelectorMassRange(double Mmin, double Mmax);       ///< select objects with Mmin <= Mass <= Mmax
00399 
00400 Selector SelectorRapMin(double rapmin);                  ///< select objects with rap >= rapmin
00401 Selector SelectorRapMax(double rapmax);                  ///< select objects with rap <= rapmax
00402 Selector SelectorRapRange(double rapmin, double rapmax); ///< select objects with rapmin <= rap <= rapmax
00403 
00404 Selector SelectorAbsRapMin(double absrapmin);                     ///< select objects with |rap| >= absrapmin
00405 Selector SelectorAbsRapMax(double absrapmax);                     ///< select objects with |rap| <= absrapmax
00406 Selector SelectorAbsRapRange(double absrapmin, double absrapmax); ///< select objects with absrapmin <= |rap| <= absrapmax
00407 
00408 Selector SelectorEtaMin(double etamin);                  ///< select objects with eta >= etamin
00409 Selector SelectorEtaMax(double etamax);                  ///< select objects with eta <= etamax
00410 Selector SelectorEtaRange(double etamin, double etamax); ///< select objects with etamin <= eta <= etamax
00411 
00412 Selector SelectorAbsEtaMin(double absetamin);                     ///< select objects with |eta| >= absetamin
00413 Selector SelectorAbsEtaMax(double absetamax);                     ///< select objects with |eta| <= absetamax
00414 Selector SelectorAbsEtaRange(double absetamin, double absetamax); ///< select objects with absetamin <= |eta| <= absetamax
00415 
00416 Selector SelectorPhiRange(double phimin, double phimax); ///< select objects with phimin <= phi <= phimax
00417 
00418 /// select objects with rapmin <= rap <= rapmax  &&  phimin <= phi <= phimax
00419 ///
00420 /// Note that this is essentially a combination of SelectorRapRange
00421 /// and SelectorPhiRange. We provide it as a Selector on its own in
00422 /// order to use the known area (which would otherwise be lost by the &&
00423 /// operator)
00424 Selector SelectorRapPhiRange(double rapmin, double rapmax, double phimin, double phimax);
00425 
00426 /// select the n hardest objects 
00427 Selector SelectorNHardest(unsigned int n); 
00428 
00429 
00430 // Selectors that take (require) a reference jet.
00431 //----------------------------------------------------------------------
00432 
00433 /// select objets within a distance 'radius' from the location of the
00434 /// reference jet, set by Selector::set_reference(...)
00435 Selector SelectorCircle(const double & radius); 
00436 
00437 /// select objets with distance from the reference jet is between 'radius_in'
00438 /// and 'radius_out'; the reference jet is set by Selector::set_reference(...)
00439 Selector SelectorDoughnut(const double & radius_in, const double & radius_out); 
00440 
00441 /// select objets within a rapidity distance 'half_width' from the
00442 /// location of the reference jet, set by Selector::set_reference(...)
00443 Selector SelectorStrip(const double & half_width);
00444 
00445 /// select objets within rapidity distance 'half_rap_width' from the
00446 /// reference jet and azimuthal-angle distance within 'half_phi_width'; the
00447 /// reference jet is set by Selector::set_reference(...)
00448 Selector SelectorRectangle(const double & half_rap_width, const double & half_phi_width);
00449 
00450 
00451 /// select objects that carry at least a fraction "fraction" of the
00452 /// reference jet. The reference jet must have been set with
00453 /// Selector::set_reference(...)
00454 Selector SelectorPtFractionMin(double fraction);
00455 
00456 
00457 // additional (mostly helper) selectors
00458 //----------------------------------------------------------------------
00459 
00460 /// select PseudoJet with 0 momentum
00461 Selector SelectorIsZero();
00462 
00463 #ifndef __FJCORE__
00464 /// select objects that are (or are only made of) ghosts.
00465 /// PseudoJets for which has_area() are considered non-pure-ghost.
00466 Selector SelectorIsPureGhost();
00467 #endif  // __FJCORE__
00468 
00469 /// @}
00470 
00471 FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
00472 
00473 #endif // __FASTJET_SELECTOR_HH__
00474 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends