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