|
||||
File indexing completed on 2025-01-18 09:57:18
0001 #ifndef __FASTJET_SELECTOR_HH__ 0002 #define __FASTJET_SELECTOR_HH__ 0003 0004 //FJSTARTHEADER 0005 // $Id$ 0006 // 0007 // Copyright (c) 2009-2021, Matteo Cacciari, Gavin P. Salam and Gregory Soyez 0008 // 0009 //---------------------------------------------------------------------- 0010 // This file is part of FastJet. 0011 // 0012 // FastJet is free software; you can redistribute it and/or modify 0013 // it under the terms of the GNU General Public License as published by 0014 // the Free Software Foundation; either version 2 of the License, or 0015 // (at your option) any later version. 0016 // 0017 // The algorithms that underlie FastJet have required considerable 0018 // development. They are described in the original FastJet paper, 0019 // hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use 0020 // FastJet as part of work towards a scientific publication, please 0021 // quote the version you use and include a citation to the manual and 0022 // optionally also to hep-ph/0512210. 0023 // 0024 // FastJet is distributed in the hope that it will be useful, 0025 // but WITHOUT ANY WARRANTY; without even the implied warranty of 0026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0027 // GNU General Public License for more details. 0028 // 0029 // You should have received a copy of the GNU General Public License 0030 // along with FastJet. If not, see <http://www.gnu.org/licenses/>. 0031 //---------------------------------------------------------------------- 0032 //FJENDHEADER 0033 0034 #include "fastjet/PseudoJet.hh" 0035 #ifndef __FJCORE__ 0036 #include "fastjet/RangeDefinition.hh" // for initialisation from a RangeDefinition 0037 #endif // __FJCORE__ 0038 #include <limits> 0039 #include <cmath> 0040 0041 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 0042 0043 //---------------------------------------------------------------------- 0044 /// @ingroup selectors 0045 /// \class Selector 0046 /// Class that encodes information about cuts and other selection 0047 /// criteria that can be applied to PseudoJet(s). 0048 /// 0049 class Selector; 0050 //---------------------------------------------------------------------- 0051 0052 /// @ingroup selectors 0053 /// \class SelectorWorker 0054 /// default selector worker is an abstract virtual base class 0055 /// 0056 /// The Selector class is only an interface, it is the SelectorWorker 0057 /// that really does the work. To implement various selectors, one 0058 /// thus has to overload this class. 0059 class SelectorWorker { 0060 public: 0061 //---------------------------------------------------------- 0062 // fundamental info 0063 //---------------------------------------------------------- 0064 /// default dtor 0065 virtual ~SelectorWorker() {} 0066 0067 //---------------------------------------------------------- 0068 // basic operations for checking what gets selected 0069 //---------------------------------------------------------- 0070 0071 /// returns true if a given object passes the selection criterion, 0072 /// and is the main function that needs to be overloaded by derived 0073 /// workers. 0074 /// 0075 /// NB: this function is used only if applies_jet_by_jet() returns 0076 /// true. If it does not, then derived classes are expected to 0077 /// (re)implement the terminator function() 0078 virtual bool pass(const PseudoJet & jet) const = 0; 0079 0080 /// For each jet that does not pass the cuts, this routine sets the 0081 /// pointer to 0. 0082 /// 0083 /// It does not assume that the PseudoJet* passed as argument are not NULL 0084 virtual void terminator(std::vector<const PseudoJet *> & jets) const { 0085 for (unsigned i = 0; i < jets.size(); i++) { 0086 if (jets[i] && !pass(*jets[i])) jets[i] = NULL; 0087 } 0088 } 0089 0090 /// returns true if this can be applied jet by jet 0091 virtual bool applies_jet_by_jet() const {return true;} 0092 0093 /// returns a description of the worker 0094 virtual std::string description() const {return "missing description";} 0095 0096 0097 //---------------------------------------------------------- 0098 // operations for dealing with reference jets 0099 //---------------------------------------------------------- 0100 0101 /// returns true if the worker is defined with respect to a reference jet 0102 virtual bool takes_reference() const { return false;} 0103 0104 /// sets the reference jet for the selector 0105 /// NB: "reference" is commented to avoid unused-variable compiler warnings 0106 virtual void set_reference(const PseudoJet & /*reference*/){ 0107 throw Error("set_reference(...) cannot be used for a selector worker that does not take a reference"); 0108 } 0109 0110 /// return a copy of the current object. 0111 /// 0112 /// This function is only called for objects that take a reference and need 0113 /// not be reimplemented otherwise. 0114 virtual SelectorWorker* copy(){ 0115 throw Error("this SelectorWorker has nothing to copy"); 0116 } 0117 0118 //---------------------------------------------------------- 0119 // operations for area and extent 0120 //---------------------------------------------------------- 0121 0122 /// returns the rapidity range for which it may return "true" 0123 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const { 0124 rapmax = std::numeric_limits<double>::infinity(); 0125 rapmin = -rapmax; 0126 } 0127 0128 /// check if it is a geometric selector (i.e. only puts constraints 0129 /// on rapidity and azimuthal angle) 0130 virtual bool is_geometric() const { return false;} 0131 0132 /// check if it has a finite area 0133 virtual bool has_finite_area() const; 0134 0135 /// check if it has an analytically computable area 0136 virtual bool has_known_area() const { return false;} 0137 0138 /// if it has a computable area, return it 0139 virtual double known_area() const{ 0140 throw Error("this selector has no computable area"); 0141 } 0142 0143 }; 0144 0145 //---------------------------------------------------------------------- 0146 // class Selector 0147 // 0148 // Class that encodes information about cuts that 0149 class Selector{ 0150 public: 0151 /// default constructor produces a Selector whose action is undefined 0152 /// (any attempt to use it will lead to an error) 0153 Selector() {} 0154 0155 /// constructor that causes the Selector to use the supplied worker 0156 /// 0157 /// Note that the Selector takes ownership of the pointer to the 0158 /// worker (and so will delete automatically when appropriate). 0159 Selector(SelectorWorker * worker_in) {_worker.reset(worker_in);} 0160 0161 #ifndef __FJCORE__ 0162 /// ctor from a RangeDefinition 0163 /// 0164 /// This is provided for backward compatibility and will be removed in 0165 /// a future major release of FastJet 0166 /// 0167 /// Watch out that the Selector will only hold a pointer to the 0168 /// range so the selector will crash if one tries to use it after 0169 /// the range has gone out of scope. We thus strongly advise against 0170 /// the direct use of this constructor. 0171 Selector(const RangeDefinition &range); 0172 #endif // __FJCORE__ 0173 0174 /// dummy virtual dtor 0175 virtual ~Selector(){} 0176 0177 /// return true if the jet passes the selection 0178 bool pass(const PseudoJet & jet) const { 0179 if (!validated_worker()->applies_jet_by_jet()) { 0180 throw Error("Cannot apply this selector to an individual jet"); 0181 } 0182 return _worker->pass(jet); 0183 } 0184 0185 /// an operator way of knowing whether a given jet passes the selection or not 0186 bool operator()(const PseudoJet & jet) const { 0187 return pass(jet); 0188 } 0189 0190 /// Return a count of the objects that pass the selection. 0191 /// 0192 /// This will often be more efficient that getting the vector of objects that 0193 /// passes and then evaluating the size of the vector 0194 unsigned int count(const std::vector<PseudoJet> & jets) const; 0195 0196 /// Return the 4-vector sum of the objects that pass the selection. 0197 /// 0198 /// This will often be more efficient that getting the vector of objects that 0199 /// passes and then evaluating the size of the vector 0200 PseudoJet sum(const std::vector<PseudoJet> & jets) const; 0201 0202 /// Return the scalar pt sum of the objects that pass the selection. 0203 /// 0204 /// This will often be more efficient that getting the vector of objects that 0205 /// passes and then evaluating the size of the vector 0206 double scalar_pt_sum(const std::vector<PseudoJet> & jets) const; 0207 0208 /// sift the input jets into two vectors -- those that pass the selector 0209 /// and those that do not 0210 void sift(const std::vector<PseudoJet> & jets, 0211 std::vector<PseudoJet> & jets_that_pass, 0212 std::vector<PseudoJet> & jets_that_fail) const; 0213 0214 /// returns true if this can be applied jet by jet 0215 bool applies_jet_by_jet() const { 0216 return validated_worker()->applies_jet_by_jet(); 0217 } 0218 0219 /// returns a vector with the jets that pass the selection 0220 std::vector<PseudoJet> operator()(const std::vector<PseudoJet> & jets) const; 0221 0222 /// For each jet that does not pass the cuts, this routine sets the 0223 /// pointer to 0. 0224 /// 0225 /// It is legitimate for some (or all) of the pointers that are 0226 /// passed to already be NULL. 0227 virtual void nullify_non_selected(std::vector<const PseudoJet *> & jets) const { 0228 validated_worker()->terminator(jets); 0229 } 0230 0231 /// returns the rapidity range for which it may return "true" 0232 void get_rapidity_extent(double &rapmin, double &rapmax) const { 0233 return validated_worker()->get_rapidity_extent(rapmin, rapmax); 0234 } 0235 0236 /// returns a textual description of the selector 0237 std::string description() const { 0238 return validated_worker()->description(); 0239 } 0240 0241 /// returns true if it is a geometric selector (i.e. one that only puts 0242 /// constraints on rapidities and azimuthal angles) 0243 bool is_geometric() const{ 0244 return validated_worker()->is_geometric(); 0245 } 0246 0247 /// returns true if it has a meaningful and finite area (i.e. the 0248 /// Selector has the property that is_geometric() returns true and 0249 /// the rapidity extent is finite). 0250 bool has_finite_area() const{ 0251 return validated_worker()->has_finite_area(); 0252 } 0253 0254 #ifndef __FJCORE__ 0255 /// returns the rapidity-phi area associated with the Selector 0256 /// (throws InvalidArea if the area does not make sense). 0257 /// 0258 /// If the result is not known analytically, the area will be 0259 /// estimated using a pseudo Monte Carlo method (as for jet areas), 0260 /// using the default ghost area from the GhostedAreaSpec class 0261 /// (0.01). The Monte Carlo estimate involves a time penalty 0262 /// proportional to the ratio of the rapidity extent of the Selector 0263 /// divided by the ghost area. 0264 double area() const; 0265 0266 /// returns the rapidity-phi area associated with the Selector 0267 /// (throws InvalidArea if the area does not make sense). 0268 /// 0269 /// The behaviour is the as with the area() call, but with the 0270 /// ability to additionally specify the ghost area to be used in the 0271 /// case of a Monte Carlo area evaluation. 0272 /// 0273 double area(double ghost_area) const; 0274 #endif // __FJCORE__ 0275 0276 /// returns a (reference to) the underlying worker's shared pointer 0277 const SharedPtr<SelectorWorker> & worker() const {return _worker;} 0278 0279 /// returns a worker if there is a valid one, otherwise throws an InvalidWorker error 0280 const SelectorWorker* validated_worker() const { 0281 const SelectorWorker* worker_ptr = _worker.get(); 0282 if (worker_ptr == 0) throw InvalidWorker(); 0283 return worker_ptr; 0284 } 0285 0286 /// returns true if this can be applied jet by jet 0287 bool takes_reference() const { 0288 return validated_worker()->takes_reference(); 0289 } 0290 0291 /// set the reference jet for this Selector 0292 const Selector & set_reference(const PseudoJet &reference){ 0293 0294 // if the worker does not take a reference jet, do nothing 0295 if (! validated_worker()->takes_reference()){ 0296 return *this; 0297 } 0298 0299 // since this is a non-const operation, make sure we have a 0300 // correct behaviour with respect to shared workers 0301 _copy_worker_if_needed(); 0302 0303 _worker->set_reference(reference); 0304 return *this; 0305 } 0306 0307 /// class that gets thrown when a Selector is applied despite it not 0308 /// having a valid underlying worker. 0309 class InvalidWorker : public Error { 0310 public: 0311 InvalidWorker() : Error("Attempt to use Selector with no valid underlying worker") {} 0312 }; 0313 0314 /// class that gets thrown when the area is requested from a Selector for which 0315 /// the area is not meaningful 0316 class InvalidArea : public Error { 0317 public: 0318 InvalidArea() : Error("Attempt to obtain area from Selector for which this is not meaningful") {} 0319 }; 0320 0321 // some operators (applying directly on a Selector) 0322 //---------------------------------------------------------------------- 0323 /// For 2 Selectors a and b, a &= b is eauivalent to a = a && b; 0324 Selector & operator &=(const Selector & b); 0325 0326 /// For 2 Selectors a and b, a |= b is eauivalent to a = a || b; 0327 Selector & operator |=(const Selector & b); 0328 0329 0330 protected: 0331 /// Helper for copying selector workers if needed 0332 /// 0333 /// The following is needed if we want to modify a selectors that 0334 /// shares a worker with another selector. In that case, we need to 0335 /// get another copy of the worker to avoid interferences 0336 /// 0337 /// Note that any non-const operation has to call this to behave 0338 /// correctly w.r.t shared workers! 0339 void _copy_worker_if_needed(){ 0340 // do nothing if there's a sinlge user of the worker 0341 if (_worker.unique()) return; 0342 0343 // call the worker's copy 0344 //std::cout << "will make a copy of " << description() << std::endl; 0345 _worker.reset(_worker->copy()); 0346 } 0347 0348 private: 0349 SharedPtr<SelectorWorker> _worker; ///< the underlying worker 0350 }; 0351 0352 0353 //---------------------------------------------------------------------- 0354 // a list of specific selectors 0355 //---------------------------------------------------------------------- 0356 0357 /// \addtogroup selectors 0358 /// @{ 0359 0360 0361 // fundamental selectors 0362 //---------------------------------------------------------------------- 0363 0364 // "identity" selector that lets everything pass 0365 Selector SelectorIdentity(); 0366 0367 // logical operations 0368 //---------------------------------------------------------------------- 0369 0370 /// logical not applied on a selector 0371 /// 0372 /// This will keep objects that do not pass the 's' selector 0373 Selector operator!(const Selector & s); 0374 0375 /// logical or between two selectors 0376 /// 0377 /// this will keep the objects that are selected by s1 or s2 0378 Selector operator ||(const Selector & s1, const Selector & s2); 0379 0380 0381 /// logical and between two selectors 0382 /// 0383 /// this will keep the objects that are selected by both s1 and s2 0384 /// 0385 /// watch out: for both s1 and s2, the selection is applied on the 0386 /// original list of objects. For successive applications of two 0387 /// selectors (convolution/multiplication) see the operator * 0388 Selector operator&&(const Selector & s1, const Selector & s2); 0389 0390 /// successive application of 2 selectors 0391 /// 0392 /// Apply the selector s2, then the selector s1. 0393 /// 0394 /// watch out: the operator * acts like an operator product i.e. does 0395 /// not commute. The order of its arguments is therefore important. 0396 /// Whenever they commute (in particluar, when they apply jet by 0397 /// jet), this would have the same effect as the logical &&. 0398 Selector operator*(const Selector & s1, const Selector & s2); 0399 0400 0401 // selection with kinematic cuts 0402 //---------------------------------------------------------------------- 0403 Selector SelectorPtMin(double ptmin); ///< select objects with pt >= ptmin 0404 Selector SelectorPtMax(double ptmax); ///< select objects with pt <= ptmax 0405 Selector SelectorPtRange(double ptmin, double ptmax); ///< select objects with ptmin <= pt <= ptmax 0406 0407 Selector SelectorEtMin(double Etmin); ///< select objects with Et >= Etmin 0408 Selector SelectorEtMax(double Etmax); ///< select objects with Et <= Etmax 0409 Selector SelectorEtRange(double Etmin, double Etmax); ///< select objects with Etmin <= Et <= Etmax 0410 0411 Selector SelectorEMin(double Emin); ///< select objects with E >= Emin 0412 Selector SelectorEMax(double Emax); ///< select objects with E <= Emax 0413 Selector SelectorERange(double Emin, double Emax); ///< select objects with Emin <= E <= Emax 0414 0415 Selector SelectorMassMin(double Mmin); ///< select objects with Mass >= Mmin 0416 Selector SelectorMassMax(double Mmax); ///< select objects with Mass <= Mmax 0417 Selector SelectorMassRange(double Mmin, double Mmax); ///< select objects with Mmin <= Mass <= Mmax 0418 0419 Selector SelectorRapMin(double rapmin); ///< select objects with rap >= rapmin 0420 Selector SelectorRapMax(double rapmax); ///< select objects with rap <= rapmax 0421 Selector SelectorRapRange(double rapmin, double rapmax); ///< select objects with rapmin <= rap <= rapmax 0422 0423 Selector SelectorAbsRapMin(double absrapmin); ///< select objects with |rap| >= absrapmin 0424 Selector SelectorAbsRapMax(double absrapmax); ///< select objects with |rap| <= absrapmax 0425 Selector SelectorAbsRapRange(double absrapmin, double absrapmax); ///< select objects with absrapmin <= |rap| <= absrapmax 0426 0427 Selector SelectorEtaMin(double etamin); ///< select objects with eta >= etamin 0428 Selector SelectorEtaMax(double etamax); ///< select objects with eta <= etamax 0429 Selector SelectorEtaRange(double etamin, double etamax); ///< select objects with etamin <= eta <= etamax 0430 0431 Selector SelectorAbsEtaMin(double absetamin); ///< select objects with |eta| >= absetamin 0432 Selector SelectorAbsEtaMax(double absetamax); ///< select objects with |eta| <= absetamax 0433 Selector SelectorAbsEtaRange(double absetamin, double absetamax); ///< select objects with absetamin <= |eta| <= absetamax 0434 0435 Selector SelectorPhiRange(double phimin, double phimax); ///< select objects with phimin <= phi <= phimax 0436 0437 /// select objects with rapmin <= rap <= rapmax && phimin <= phi <= phimax 0438 /// 0439 /// Note that this is essentially a combination of SelectorRapRange 0440 /// and SelectorPhiRange. We provide it as a Selector on its own in 0441 /// order to use the known area (which would otherwise be lost by the && 0442 /// operator) 0443 Selector SelectorRapPhiRange(double rapmin, double rapmax, double phimin, double phimax); 0444 0445 /// select the n hardest objects 0446 Selector SelectorNHardest(unsigned int n); 0447 0448 0449 // Selectors that take (require) a reference jet. 0450 //---------------------------------------------------------------------- 0451 0452 /// select objets within a distance 'radius' from the location of the 0453 /// reference jet, set by Selector::set_reference(...) 0454 Selector SelectorCircle(const double radius); 0455 0456 /// select objets with distance from the reference jet is between 'radius_in' 0457 /// and 'radius_out'; the reference jet is set by Selector::set_reference(...) 0458 Selector SelectorDoughnut(const double radius_in, const double radius_out); 0459 0460 /// select objets within a rapidity distance 'half_width' from the 0461 /// location of the reference jet, set by Selector::set_reference(...) 0462 Selector SelectorStrip(const double half_width); 0463 0464 /// select objets within rapidity distance 'half_rap_width' from the 0465 /// reference jet and azimuthal-angle distance within 'half_phi_width'; the 0466 /// reference jet is set by Selector::set_reference(...) 0467 Selector SelectorRectangle(const double half_rap_width, const double half_phi_width); 0468 0469 0470 /// select objects that carry at least a fraction "fraction" of the 0471 /// reference jet. The reference jet must have been set with 0472 /// Selector::set_reference(...) 0473 Selector SelectorPtFractionMin(double fraction); 0474 0475 0476 // additional (mostly helper) selectors 0477 //---------------------------------------------------------------------- 0478 0479 /// select PseudoJet with 0 momentum 0480 Selector SelectorIsZero(); 0481 0482 #ifndef __FJCORE__ 0483 /// select objects that are (or are only made of) ghosts. 0484 /// PseudoJets for which has_area() are considered non-pure-ghost. 0485 Selector SelectorIsPureGhost(); 0486 #endif // __FJCORE__ 0487 0488 /// @} 0489 0490 FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh 0491 0492 #endif // __FASTJET_SELECTOR_HH__ 0493
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |