FastJet 3.0.6
|
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