Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-24 08:23:46

0001 // $Id: RecursiveSoftDrop.hh 1444 2024-12-09 18:15:56Z salam $
0002 //
0003 // Copyright (c) 2014-, Gavin P. Salam, Gregory Soyez, Jesse Thaler,
0004 // Kevin Zhou, Frederic Dreyer
0005 //
0006 //----------------------------------------------------------------------
0007 // This file is part of FastJet contrib.
0008 //
0009 // It is free software; you can redistribute it and/or modify it under
0010 // the terms of the GNU General Public License as published by the
0011 // Free Software Foundation; either version 2 of the License, or (at
0012 // your option) any later version.
0013 //
0014 // It is distributed in the hope that it will be useful, but WITHOUT
0015 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
0016 // or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
0017 // License for more details.
0018 //
0019 // You should have received a copy of the GNU General Public License
0020 // along with this code. If not, see <http://www.gnu.org/licenses/>.
0021 //----------------------------------------------------------------------
0022 
0023 #ifndef __RECURSIVESOFTDROP_HH__
0024 #define __RECURSIVESOFTDROP_HH__
0025 
0026 #include "fastjet/config.h"
0027 
0028 // we'll use the native FJ class for reculstering if available
0029 #if FASTJET_VERSION_NUMBER >= 30100
0030 #include "fastjet/tools/Recluster.hh"
0031 #else
0032 #include "Recluster.hh"
0033 #endif
0034 #include "SoftDrop.hh"
0035 #include "fastjet/WrappedStructure.hh"
0036 
0037 #include <iostream>
0038 #include <queue>
0039 #include <vector>
0040 
0041 FASTJET_BEGIN_NAMESPACE
0042 
0043 namespace contrib{
0044 
0045 //------------------------------------------------------------------------
0046 /// \class RecursiveSoftDrop
0047 /// An implementation of the RecursiveSoftDrop.
0048 ///
0049 /// Recursive Soft Drop will recursively groom a jet, removing
0050 /// particles that fail the criterion
0051 /// \f[
0052 ///     z > z_{\rm cut} (\theta/R0)^\beta
0053 /// \f]
0054 /// until n subjets have been found.
0055 ///
0056 /// Several variants are supported:
0057 ///  - set_fixed_depth_mode() switches to fixed depth on all branches
0058 ///    of the clustering tree
0059 ///  - set_dynamical_R0() switches to dynamical R0 implementation of
0060 ///    RSD
0061 ///  - set_hardest_branch_only() switches to following only the
0062 ///    hardest branch (e.g. for Iterated Soft Drop)
0063 ///  - set_min_deltaR_square(val) sets a minimum angle considered for
0064 ///    substructure (e.g. for Iterated Soft Drop)
0065 ///
0066 /// Notes:
0067 ///
0068 ///  - Even though the calls to "set_tagging_mode()" or
0069 ///    "set_grooming_mode(false)" are allowed, they should not be used
0070 ///    with n=-1, and the default grooming_mode has to remain
0071 ///    untouched (except for beta<0 and finite n).
0072 ///
0073 //----------------------------------------------------------------------
0074 class RecursiveSoftDrop : public SoftDrop {
0075 public:
0076   /// Simplified constructor. This takes the value of the "beta"
0077   /// parameter and the symmetry cut (applied by default on the
0078   /// scalar_z variable, as for the mMDT). It also takes an optional
0079   /// subtractor.
0080   ///
0081   /// n is the number of times we require the SoftDrop condition to be
0082   /// satisfied. n=-1 means infinity, i.e. we recurse into the jet
0083   /// until individual constituents
0084   ///
0085   /// If the (optional) pileup subtractor can be supplied, then see
0086   /// also the documentation for the set_input_jet_is_subtracted() member
0087   /// function.
0088   ///
0089   /// \param beta               the value of the beta parameter
0090   /// \param symmetry_cut       the value of the cut on the symmetry measure
0091   /// \param n                  the requested number of iterations
0092   /// \param R0                 the angular distance normalisation [1 by default]
0093   RecursiveSoftDrop(double beta,
0094                     double symmetry_cut,
0095                     int n = -1,
0096                     double R0 = 1,
0097                     const FunctionOfPseudoJet<PseudoJet> * subtractor = 0) : 
0098     SoftDrop(beta, symmetry_cut, R0, subtractor), _n(n) { set_defaults(); }
0099 
0100   /// Full constructor, which takes the following parameters:
0101   ///
0102   /// \param beta               the value of the beta parameter
0103   /// \param symmetry_cut       the value of the cut on the symmetry measure
0104   /// \param symmetry_measure   the choice of measure to use to estimate the symmetry
0105   /// \param n                  the requested number of iterations
0106   /// \param R0                 the angular distance normalisation [1 by default]
0107   /// \param mu_cut             the maximal allowed value of mass drop variable mu = m_heavy/m_parent 
0108   /// \param recursion_choice   the strategy used to decide which subjet to recurse into
0109   /// \param subtractor         an optional pointer to a pileup subtractor (ignored if zero)
0110   RecursiveSoftDrop(double           beta,
0111                     double           symmetry_cut, 
0112                     SymmetryMeasure  symmetry_measure,
0113                     int              n = -1,
0114                     double           R0 = 1.0,
0115                     double           mu_cut = std::numeric_limits<double>::infinity(), 
0116                     RecursionChoice  recursion_choice = larger_pt,
0117                     const FunctionOfPseudoJet<PseudoJet> * subtractor = 0) : 
0118     SoftDrop(beta, symmetry_cut, symmetry_measure, R0, mu_cut, recursion_choice, subtractor),
0119     _n(n) { set_defaults(); }
0120 
0121   /// default destructor
0122   virtual ~RecursiveSoftDrop(){}
0123 
0124   //----------------------------------------------------------------------
0125   // access to class info
0126   int n() const { return _n; }
0127   
0128   //----------------------------------------------------------------------
0129   // on top of the tweaks that we inherit from SoftDrop (via
0130   // RecursiveSymmetryBase):
0131   //  - set_verbose_structure()
0132   //  - set_subtractor()
0133   //  - set_input_jet_is_subtracted()
0134   // we provide several other knobs, given below
0135 
0136   /// initialise all the flags below to their default value
0137   void set_defaults();
0138   
0139   /// switch to using the "same depth" variant where instead of
0140   /// recursing from large to small angles and requiring n SD
0141   /// conditions to be met (our default), we recurse simultaneously in
0142   /// all the branches found during the previous iteration, up to a
0143   /// maximum depth of n.
0144   /// default: false
0145   void set_fixed_depth_mode(bool value=true) { _fixed_depth = value; }
0146   bool fixed_depth_mode() const { return _fixed_depth; }
0147   
0148   /// switch to using a dynamical R0 (used for the normalisation of
0149   /// the symmetry measure) set by the last deltaR at which some
0150   /// substructure was found.
0151   /// default: false
0152   void set_dynamical_R0(bool value=true) { _dynamical_R0 = value; }
0153   bool use_dynamical_R0() const { return _dynamical_R0; }
0154 
0155   /// when finding some substructure, only follow the hardest branch
0156   /// for the recursion
0157   /// default: false (i.e. recurse in both branches)
0158   void set_hardest_branch_only(bool value=true) { _hardest_branch_only = value; }
0159   bool use_hardest_branch_only() const { return _hardest_branch_only; }
0160 
0161   /// set the minimum angle (squared) that we should consider for
0162   /// substructure
0163   /// default: -1.0 (i.e. no minimum)
0164   void set_min_deltaR_squared(double value=-1.0) { _min_dR2 = value; }
0165   double   min_deltaR_squared() const { return _min_dR2; }
0166 
0167   /// description of the tool
0168   virtual std::string description() const;
0169 
0170   //----------------------------------------------------------------------
0171   /// action on a single jet with RecursiveSoftDrop.
0172   ///
0173   /// uses "result_fixed_tags" by default (i.e. recurse from R0 to
0174   /// smaller angles until n SD conditions have been met), or
0175   /// "result_fixed_depth" where each of the previous SD branches are
0176   /// recirsed into down to a depth of n.
0177   virtual PseudoJet result(const PseudoJet &jet) const;
0178 
0179   /// this routine applies the Soft Drop criterion recursively on the
0180   /// CA tree until we find n subjets (or until it converges), and
0181   /// adds them together into a groomed PseudoJet
0182   PseudoJet result_fixed_tags(const PseudoJet &jet) const;
0183 
0184   /// this routine applies the Soft Drop criterion recursively on the
0185   /// CA tree, recursing into all the branches found during the previous iteration
0186   /// until n layers have been found (or until it converges)
0187   PseudoJet result_fixed_depth(const PseudoJet &jet) const;
0188     
0189 protected:  
0190   /// return false if we reached desired layer of grooming _n
0191   bool continue_grooming(int current_n) const {
0192     return ((_n < 0) or (current_n < _n));
0193   }
0194   
0195 private:
0196   int    _n;            ///< the value of n
0197 
0198   // behaviour tweaks
0199   bool _fixed_depth;         ///< look in parallel into each all branches until depth n
0200   bool _dynamical_R0;        ///< when true, use the last deltaR with substructure as D0
0201   bool _hardest_branch_only; ///< recurse only in the hardest branch
0202                              ///  when substructure is found
0203   double _min_dR2;           ///< the min allowed angle to search for substructure
0204 };
0205 
0206 // helper to get the (linear) list of prongs inside a jet resulting
0207 // from RecursiveSoftDrop. This would avoid having amnually to go
0208 // through the successive pairwise compositeness
0209 std::vector<PseudoJet> recursive_soft_drop_prongs(const PseudoJet & rsd_jet);
0210 
0211 }
0212 
0213 FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
0214 #endif // __RECURSIVESOFTDROP_HH__