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