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