Back to home page

EIC code displayed by LXR

 
 

    


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