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