Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:16

0001 #ifndef __FASTJET_BACKGROUND_ESTIMATOR_HH__
0002 #define __FASTJET_BACKGROUND_ESTIMATOR_HH__
0003 
0004 
0005 //FJSTARTHEADER
0006 // $Id$
0007 //
0008 // Copyright (c) 2005-2021, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
0009 //
0010 //----------------------------------------------------------------------
0011 // This file is part of FastJet.
0012 //
0013 //  FastJet is free software; you can redistribute it and/or modify
0014 //  it under the terms of the GNU General Public License as published by
0015 //  the Free Software Foundation; either version 2 of the License, or
0016 //  (at your option) any later version.
0017 //
0018 //  The algorithms that underlie FastJet have required considerable
0019 //  development. They are described in the original FastJet paper,
0020 //  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
0021 //  FastJet as part of work towards a scientific publication, please
0022 //  quote the version you use and include a citation to the manual and
0023 //  optionally also to hep-ph/0512210.
0024 //
0025 //  FastJet is distributed in the hope that it will be useful,
0026 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
0027 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0028 //  GNU General Public License for more details.
0029 //
0030 //  You should have received a copy of the GNU General Public License
0031 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
0032 //----------------------------------------------------------------------
0033 //FJENDHEADER
0034 
0035 #include "fastjet/config.h"
0036 #include "fastjet/ClusterSequenceAreaBase.hh"
0037 #include "fastjet/AreaDefinition.hh"
0038 #include "fastjet/FunctionOfPseudoJet.hh"
0039 #include "fastjet/Selector.hh"
0040 #include "fastjet/tools/BackgroundEstimatorBase.hh"
0041 #include <iostream>
0042 
0043 #ifdef FASTJET_HAVE_THREAD_SAFETY
0044 #include <atomic>
0045 #endif
0046 
0047 FASTJET_BEGIN_NAMESPACE     // defined in fastjet/internal/base.hh
0048 
0049 
0050 /// @ingroup tools_background
0051 /// \class JetMedianBackgroundEstimator
0052 ///
0053 /// Class to estimate the pt density of the background per unit area,
0054 /// using the median of the distribution of pt/area from jets that
0055 /// pass some selection criterion.
0056 ///
0057 /// Events are passed either in the form of the event particles (in
0058 /// which they're clustered by the class), a ClusterSequenceArea (in
0059 /// which case the jets used are those returned by "inclusive_jets()")
0060 /// or directly as a set of jets.
0061 ///
0062 /// The selection criterion is typically a geometrical one (e.g. all
0063 /// jets with |y|<2) sometimes supplemented with some kinematical
0064 /// restriction (e.g. exclusion of the two hardest jets). It is passed
0065 /// to the class through a Selector.
0066 ///
0067 /// Beware: 
0068 ///   by default, to correctly handle partially empty events, the
0069 ///   class attempts to calculate an "empty area", based
0070 ///   (schematically) on
0071 ///
0072 ///          range.total_area() - sum_{jets_in_range} jets.area()
0073 ///  
0074 ///   For ranges with small areas, this can be inaccurate (particularly 
0075 ///   relevant in dense events where empty_area should be zero and ends
0076 ///   up not being zero).
0077 ///
0078 ///   This calculation of empty area can be avoided if a
0079 ///   ClusterSequenceArea class with explicit ghosts
0080 ///   (ActiveAreaExplicitGhosts) is used.  This is _recommended_
0081 ///   unless speed requirements cause you to use Voronoi areas. For
0082 ///   speedy background estimation you could also consider using
0083 ///   GridMedianBackgroundEstimator.
0084 ///
0085 ///
0086 class JetMedianBackgroundEstimator : public BackgroundEstimatorBase {
0087 public:
0088   /// @name constructors and destructors
0089   //\{
0090   //----------------------------------------------------------------
0091   /// Constructor that sets the rho range as well as the jet
0092   /// definition and area definition to be used to cluster the
0093   /// particles. Prior to the estimation of rho, one has to provide
0094   /// the particles to cluster using set_particles(...)
0095   ///
0096   /// \param rho_range  the Selector specifying which jets will be considered
0097   /// \param jet_def    the jet definition to use for the clustering
0098   /// \param area_def   the area definition to use for the clustering
0099   JetMedianBackgroundEstimator(const Selector &rho_range,
0100                                const JetDefinition &jet_def,
0101                                const AreaDefinition &area_def);
0102 
0103   /// ctor from a ClusterSequenceAreaBase with area
0104   ///
0105   /// \param rho_range   the Selector specifying which jets will be considered
0106   /// \param csa         the ClusterSequenceArea to use
0107   ///
0108   /// Pre-conditions: 
0109   ///  - one should be able to estimate the "empty area" (i.e. the area
0110   ///    not occupied by jets). This is feasible if at least one of the following
0111   ///    conditions is satisfied:
0112   ///     ( i) the ClusterSequence has explicit ghosts
0113   ///     (ii) the range has a computable area.
0114   ///  - the jet algorithm must be suited for median computation
0115   ///    (otherwise a warning will be issues)
0116   ///
0117   /// Note that selectors with e.g. hardest-jets exclusion do not have
0118   /// a well-defined area. For this reasons, it is STRONGLY advised to
0119   /// use an area with explicit ghosts.
0120   JetMedianBackgroundEstimator(const Selector &rho_range,
0121                                const ClusterSequenceAreaBase &csa);
0122 
0123 
0124   /// Default constructor that optionally sets the rho range. The
0125   /// configuration must be done later calling
0126   /// set_cluster_sequence(...) or set_jets(...).
0127   ///
0128   /// \param rho_range   the Selector specifying which jets will be considered
0129   ///
0130   JetMedianBackgroundEstimator(const Selector &rho_range = SelectorIdentity())
0131     : _rho_range(rho_range), _jet_def(JetDefinition()),
0132       _enable_rho_m(true){ reset(); }
0133 
0134   
0135   /// default dtor
0136   ~JetMedianBackgroundEstimator(){}
0137 
0138   //\}
0139 
0140 
0141   /// @name setting a new event
0142   //\{
0143   //----------------------------------------------------------------
0144 
0145   /// tell the background estimator that it has a new event, composed
0146   /// of the specified particles.
0147   virtual void set_particles(const std::vector<PseudoJet> & particles) FASTJET_OVERRIDE;
0148 
0149   // tell the background estimator that it has a new event, composed
0150   // of the specified particles and use the supplied seed for the
0151   // generation of ghosts. If the seed is empty, it is ignored.
0152   virtual void set_particles_with_seed(const std::vector<PseudoJet> & particles, const std::vector<int> & seed) FASTJET_OVERRIDE;
0153 
0154   /// (re)set the cluster sequence (with area support) to be used by
0155   /// future calls to rho() etc. 
0156   ///
0157   /// \param csa  the cluster sequence area
0158   ///
0159   /// Pre-conditions: 
0160   ///  - one should be able to estimate the "empty area" (i.e. the area
0161   ///    not occupied by jets). This is feasible if at least one of the following
0162   ///    conditions is satisfied:
0163   ///     ( i) the ClusterSequence has explicit ghosts
0164   ///     (ii) the range selected has a computable area.
0165   ///  - the jet algorithm must be suited for median computation
0166   ///    (otherwise a warning will be issues)
0167   ///
0168   /// Note that selectors with e.g. hardest-jets exclusion do not have
0169   /// a well-defined area. For this reasons, it is STRONGLY advised to
0170   /// use an area with explicit ghosts.
0171   void set_cluster_sequence(const ClusterSequenceAreaBase & csa);
0172 
0173   /// (re)set the jets (which must have area support) to be used by future
0174   /// calls to rho() etc.; for the conditions that must be satisfied
0175   /// by the jets, see the Constructor that takes jets.
0176   void set_jets(const std::vector<PseudoJet> &jets);
0177 
0178   /// (re)set the selector to be used for future calls to rho() etc.
0179   void set_selector(const Selector & rho_range_selector) {
0180     _rho_range = rho_range_selector;
0181     _set_cache_unavailable();
0182   }
0183 
0184   /// determine whether the automatic calculation of rho_m and sigma_m
0185   /// is enabled (by default true)
0186   void set_compute_rho_m(bool enable){
0187     _enable_rho_m = enable;
0188     _set_cache_unavailable();
0189   }
0190 
0191   //\}
0192 
0193 
0194   /// return a pointer to a copy of this BGE; the user is responsible
0195   /// for eventually deleting the resulting object.
0196   BackgroundEstimatorBase * copy() const FASTJET_OVERRIDE {
0197     return new JetMedianBackgroundEstimator(*this);
0198   };
0199 
0200 
0201   /// @name  retrieving fundamental information
0202   //\{
0203   //----------------------------------------------------------------
0204   /// get the full set of background properties
0205   ///
0206   /// For background estimators using a local ranges, this throws an
0207   ///   error (use estimate(jet) instead)
0208   /// In the presence of a rescaling, the rescaling is not included
0209   BackgroundEstimate estimate() const FASTJET_OVERRIDE;
0210   
0211   /// get the full set of background properties for a given reference jet
0212   BackgroundEstimate estimate(const PseudoJet &jet) const FASTJET_OVERRIDE;
0213 
0214   /// get rho, the median background density per unit area
0215   double rho() const FASTJET_OVERRIDE;
0216 
0217   /// get sigma, the background fluctuations per unit area
0218   double sigma() const FASTJET_OVERRIDE;
0219 
0220   /// get rho, the median background density per unit area, locally at
0221   /// the position of a given jet.
0222   ///
0223   /// If the Selector associated with the range takes a reference jet
0224   /// (i.e. is relocatable), then for subsequent operations the
0225   /// Selector has that jet set as its reference.
0226   double rho(const PseudoJet & jet) FASTJET_OVERRIDE;
0227 
0228   /// get sigma, the background fluctuations per unit area,
0229   /// locally at the position of a given jet.
0230   ///
0231   /// If the Selector associated with the range takes a reference jet
0232   /// (i.e. is relocatable), then for subsequent operations the
0233   /// Selector has that jet set as its reference.
0234   double sigma(const PseudoJet &jet) FASTJET_OVERRIDE;
0235 
0236   /// returns true if this background estimator has support for
0237   /// determination of sigma
0238   virtual bool has_sigma() const FASTJET_OVERRIDE {return true;}
0239 
0240   //----------------------------------------------------------------
0241   // now do the same thing for rho_m and sigma_m
0242 
0243   /// returns rho_m, the purely longitudinal, particle-mass-induced
0244   /// component of the background density per unit area
0245   virtual double rho_m() const FASTJET_OVERRIDE;
0246 
0247   /// returns sigma_m, a measure of the fluctuations in the purely
0248   /// longitudinal, particle-mass-induced component of the background
0249   /// density per unit area; must be multipled by sqrt(area) to get
0250   /// fluctuations for a region of a given area.
0251   virtual double sigma_m() const FASTJET_OVERRIDE;
0252 
0253   /// Returns rho_m locally at the jet position. As for rho(jet), it is non-const.
0254   virtual double rho_m(const PseudoJet & /*jet*/) FASTJET_OVERRIDE;
0255 
0256   /// Returns sigma_m locally at the jet position. As for rho(jet), it is non-const.
0257   virtual double sigma_m(const PseudoJet & /*jet*/) FASTJET_OVERRIDE;
0258 
0259   /// Returns true if this background estimator has support for
0260   /// determination of rho_m.
0261   ///
0262   /// In te presence of a density class, support for rho_m is
0263   /// automatically disabled
0264   ///
0265   /// Note that support for sigma_m is automatic is one has sigma and
0266   /// rho_m support.
0267   virtual bool has_rho_m() const FASTJET_OVERRIDE {return _enable_rho_m && (_jet_density_class == 0);}
0268   //\}
0269   
0270   /// @name  retrieving additional useful information
0271   //\{
0272   //----------------------------------------------------------------
0273   /// Returns the mean area of the jets used to actually compute the
0274   /// background properties in the last call of rho() or sigma()
0275   /// If the configuration has changed in the meantime, throw an error.
0276   double mean_area() const;
0277   
0278   /// returns the number of jets used to actually compute the
0279   /// background properties in the last call of rho() or sigma()
0280   /// If the configuration has changed in the meantime, throw an error.
0281   unsigned int n_jets_used() const;
0282 
0283   /// returns the jets used to actually compute the background
0284   /// properties
0285   std::vector<PseudoJet> jets_used() const;
0286 
0287   /// Returns the estimate of the area (within the range defined by
0288   /// the selector) that is not occupied by jets. The value is that
0289   /// for the last call of rho() or sigma()
0290   /// If the configuration has changed in the meantime, throw an error.
0291   ///
0292   /// The answer is defined to be zero if the area calculation
0293   /// involved explicit ghosts; if the area calculation was an active
0294   /// area, then use is made of the active area's internal list of
0295   /// pure ghost jets (taking those that pass the selector); otherwise
0296   /// it is based on the difference between the selector's total area
0297   /// and the area of the jets that pass the selector.
0298   ///
0299   /// The result here is just the cached result of the corresponding
0300   /// call to the ClusterSequenceAreaBase function.
0301   double empty_area() const;
0302 
0303   /// Returns the number of empty jets used when computing the
0304   /// background properties. The value is that for the last call of
0305   /// rho() or sigma().
0306   /// If the configuration has changed in the meantime, throw an error.
0307   ///
0308   /// If the area has explicit ghosts the result is zero; for active
0309   /// areas it is the number of internal pure ghost jets that pass the
0310   /// selector; otherwise it is deduced from the empty area, divided by 
0311   /// \f$ 0.55 \pi R^2 \f$ (the average pure-ghost-jet area).
0312   ///
0313   /// The result here is just the cached result of the corresponding
0314   /// call to the ClusterSequenceAreaBase function.
0315   double n_empty_jets() const;
0316 
0317   //}
0318 
0319 
0320   /// @name configuring behaviour
0321   //\{
0322   //----------------------------------------------------------------
0323 
0324   /// Resets the class to its default state, including the choice to
0325   /// use 4-vector areas.
0326   ///
0327   void reset();
0328 
0329   /// By default when calculating pt/Area for a jet, it is the
0330   /// transverse component of the 4-vector area that is used in the ratiof \f$p_t/A\f$. 
0331   /// Calling this function with a "false" argument causes the scalar area to
0332   /// be used instead. 
0333   ///
0334   /// While the difference between the two choices is usually small,
0335   /// for high-precision work it is usually the 4-vector area that is
0336   /// to be preferred.
0337   ///
0338   ///  \param use_it             whether one uses the 4-vector area or not (true by default)
0339   void set_use_area_4vector(bool use_it = true){
0340     _use_area_4vector = use_it;
0341     _set_cache_unavailable();
0342   }  
0343 
0344   /// check if the estimator uses the 4-vector area or the scalar area
0345   bool use_area_4vector() const{ return _use_area_4vector;}
0346 
0347   /// The FastJet v2.X sigma calculation had a small spurious offset
0348   /// in the limit of a small number of jets. This is fixed by default
0349   /// in versions 3 upwards. The old behaviour can be obtained with a
0350   /// call to this function.
0351   void set_provide_fj2_sigma(bool provide_fj2_sigma = true) {
0352     _provide_fj2_sigma = provide_fj2_sigma;
0353     _set_cache_unavailable();
0354   }
0355 
0356   /// Set a pointer to a class that calculates the quantity whose
0357   /// median will be calculated; if the pointer is null then pt/area
0358   /// is used (as occurs also if this function is not called).
0359   ///
0360   /// Note that this is still <i>preliminary</i> in FastJet 3.0 and
0361   /// that backward compatibility is not guaranteed in future releases
0362   /// of FastJet
0363   void set_jet_density_class(const FunctionOfPseudoJet<double> * jet_density_class);
0364 
0365   /// return the pointer to the jet density class
0366   const FunctionOfPseudoJet<double> *  jet_density_class() const{
0367     return _jet_density_class;
0368   }
0369 
0370   /// Set a pointer to a class that calculates the rescaling factor as
0371   /// a function of the jet (position). Note that the rescaling factor
0372   /// is used both in the determination of the "global" rho (the pt/A
0373   /// of each jet is divided by this factor) and when asking for a
0374   /// local rho (the result is multiplied by this factor).
0375   ///
0376   /// The BackgroundRescalingYPolynomial class can be used to get a
0377   /// rescaling that depends just on rapidity.
0378   virtual void set_rescaling_class(const FunctionOfPseudoJet<double> * rescaling_class_in) FASTJET_OVERRIDE {
0379     BackgroundEstimatorBase::set_rescaling_class(rescaling_class_in);
0380     _set_cache_unavailable();
0381   }
0382 
0383   //\}
0384 
0385   /// @name description
0386   //\{
0387   //----------------------------------------------------------------
0388 
0389   /// returns a textual description of the background estimator
0390   std::string description() const FASTJET_OVERRIDE;
0391 
0392   //\}
0393 
0394   /// an internal class to hold results of the calculation
0395   /// that are to be assigned to the "extras" part of a BackgroundEstimate
0396   class Extras : public BackgroundEstimate::Extras {
0397   public:
0398     Extras()
0399       :  _reference_jet(PseudoJet()), _n_jets_used(0),
0400          _n_empty_jets(0.0), _empty_area(0.0) {}
0401 
0402     /// returns the current reference jet
0403     PseudoJet reference_jet() const {return _reference_jet;}
0404     
0405     /// returns the number of jets used to estimate the background
0406     unsigned int n_jets_used() const {return _n_jets_used;}
0407     
0408     /// returns the number of empty (pure-ghost) jets
0409     double n_empty_jets() const {return _n_empty_jets;}
0410       
0411     /// returns the empty (pure-ghost/unclustered) area!
0412     double empty_area() const {return _empty_area;}
0413 
0414     void set_reference_jet(const PseudoJet &reference_jet_in){
0415       _reference_jet = reference_jet_in;
0416     }
0417     void set_n_jets_used(int n_jets_used_in){ _n_jets_used=n_jets_used_in;}
0418     void set_n_empty_jets(double n_empty_jets_in){ _n_empty_jets=n_empty_jets_in;}
0419     void set_empty_area(double empty_area_in){ _empty_area=empty_area_in;}
0420     
0421     
0422   protected:
0423     PseudoJet _reference_jet;  ///< current reference jet
0424     unsigned int _n_jets_used; ///< number of jets used to estimate the background
0425     double _n_empty_jets;      ///< number of empty (pure-ghost) jets
0426     double _empty_area;        ///< the empty (pure-ghost/unclustered) area!
0427   };
0428 
0429   
0430 private:
0431 
0432   /// compute the background properties for a given jet (excluding
0433   /// rescaling factors) and return a corresponding BackgroundEstimate
0434   ///
0435   /// this leaves the cache (and the status flags) unchanged
0436   BackgroundEstimate _compute(const PseudoJet &jet) const;
0437 
0438   //------
0439   // the next calls are meant for the case where the cache can be
0440   // filled once and for all, i.e. cases where the selector does NOT
0441   // take a reference
0442   
0443   /// fill the cache with the given estimate
0444   void _cache_no_overwrite(const BackgroundEstimate &estimate) const;
0445    
0446   /// fill the cache with a computed estimate
0447   void _compute_and_cache_no_overwrite() const;
0448 
0449   //------
0450   // the next calls are meant for the case where the selector does
0451   // take a reference and the cache needs to be refilled whenever one
0452   // calls this background estimate with a different reference jet
0453 
0454   /// fill the cache with the given estimate
0455   void _cache(const BackgroundEstimate &estimate) const;
0456    
0457   /// update the cache if need be and return the background
0458   /// estimate. This is meant to be called for cases with a local
0459   /// range (selector that takesa reference)
0460   BackgroundEstimate _compute_and_cache_if_needed(const PseudoJet &jet) const;
0461   //-----
0462   
0463   /// check that the underlying structure is still alive
0464   /// throw an error otherwise
0465   void _check_csa_alive() const;
0466 
0467   /// check that the algorithm used for the clustering is adapted for
0468   /// background estimation (i.e. either kt or C/A)
0469   /// Issue a warning otherwise
0470   void _check_jet_alg_good_for_median() const;
0471 
0472   // the basic parameters of this class (passed through the variou ctors)
0473   Selector _rho_range;                   ///< range to compute the background in
0474   JetDefinition _jet_def;                ///< the jet def to use for teh clustering
0475   AreaDefinition _area_def;              ///< the area def to use for teh clustering
0476   std::vector<PseudoJet> _included_jets; ///< jets to be used
0477   
0478   // the tunable parameters of the class
0479   bool _use_area_4vector;
0480   bool _provide_fj2_sigma;
0481   const FunctionOfPseudoJet<double> * _jet_density_class;
0482   //SharedPtr<BackgroundRescalingBase> _rescaling_class_sharedptr;
0483   bool _enable_rho_m;
0484   
0485   // internal variables
0486   SharedPtr<PseudoJetStructureBase> _csi; ///< allows to check if _csa is still valid
0487 
0488   /// handle warning messages
0489   static LimitedWarning _warnings;
0490   static LimitedWarning _warnings_zero_area;
0491   static LimitedWarning _warnings_preliminary;
0492 };
0493 
0494 
0495 
0496 
0497 //----------------------------------------------------------------------
0498 /// @ingroup tools_background
0499 /// \class BackgroundJetPtDensity
0500 /// Class that implements pt/area_4vector.perp() for background estimation
0501 /// <i>(this is a preliminary class)</i>.
0502 class BackgroundJetPtDensity : public FunctionOfPseudoJet<double> {
0503 public:
0504   virtual double result(const PseudoJet & jet) const {
0505     return jet.perp() / jet.area_4vector().perp();
0506   }
0507   virtual std::string description() const {return "BackgroundJetPtDensity";}
0508 };
0509 
0510 
0511 //----------------------------------------------------------------------
0512 /// @ingroup tools_background
0513 /// \class BackgroundJetScalarPtDensity
0514 /// Class that implements (scalar pt sum of jet)/(scalar area of jet)
0515 /// for background estimation <i>(this is a preliminary class)</i>.
0516 ///
0517 /// Optionally it can return a quantity based on the sum of pt^n,
0518 /// e.g. for use in subtracting fragementation function moments.
0519 class BackgroundJetScalarPtDensity : public FunctionOfPseudoJet<double> {
0520 public:
0521   /// Default constructor provides background estimation with scalar pt sum
0522   BackgroundJetScalarPtDensity() : _pt_power(1) {}
0523 
0524   /// Constructor to provide background estimation based on 
0525   /// \f$ sum_{i\in jet} p_{ti}^{n} \f$
0526   BackgroundJetScalarPtDensity(double n) : _pt_power(n) {}
0527 
0528   virtual double result(const PseudoJet & jet) const;
0529 
0530   virtual std::string description() const;
0531 
0532 private:
0533   double _pt_power;
0534 };
0535 
0536 //----------------------------------------------------------------------
0537 /// @ingroup tools_background
0538 /// \class BackgroundJetPtMDensity
0539 /// Class that implements
0540 /// \f$  \frac{1}{A} \sum_{i \in jet} (\sqrt{p_{ti}^2+m^2} - p_{ti}) \f$
0541 /// for background estimation <i>(this is a preliminary class)</i>.
0542 /// 
0543 ///
0544 /// This is useful for correcting jet masses in cases where the event
0545 /// involves massive particles.
0546 class BackgroundJetPtMDensity : public FunctionOfPseudoJet<double> {
0547 public:
0548   virtual double result(const PseudoJet & jet) const {
0549     std::vector<PseudoJet> constituents = jet.constituents();
0550     double scalar_ptm = 0;
0551     for (unsigned i = 0; i < constituents.size(); i++) {
0552       scalar_ptm += constituents[i].mperp() - constituents[i].perp();
0553     }
0554     return scalar_ptm / jet.area();
0555   }
0556 
0557   virtual std::string description() const {return "BackgroundPtMDensity";}
0558 };
0559 
0560 
0561 FASTJET_END_NAMESPACE
0562 
0563 #endif  // __BACKGROUND_ESTIMATOR_HH__
0564