|
||||
File indexing completed on 2025-01-18 09:57:15
0001 // $Id: RecursiveSymmetryCutBase.hh 1074 2017-09-18 15:15:20Z gsoyez $ 0002 // 0003 // Copyright (c) 2014-, Gavin P. Salam, Gregory Soyez, Jesse Thaler 0004 // 0005 //---------------------------------------------------------------------- 0006 // This file is part of FastJet contrib. 0007 // 0008 // It is free software; you can redistribute it and/or modify it under 0009 // the terms of the GNU General Public License as published by the 0010 // Free Software Foundation; either version 2 of the License, or (at 0011 // your option) any later version. 0012 // 0013 // It is distributed in the hope that it will be useful, but WITHOUT 0014 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 0015 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 0016 // License for more details. 0017 // 0018 // You should have received a copy of the GNU General Public License 0019 // along with this code. If not, see <http://www.gnu.org/licenses/>. 0020 //---------------------------------------------------------------------- 0021 0022 #ifndef __FASTJET_CONTRIB_RECURSIVESYMMETRYCUTBASE_HH__ 0023 #define __FASTJET_CONTRIB_RECURSIVESYMMETRYCUTBASE_HH__ 0024 0025 #include <limits> 0026 #include <cassert> 0027 #include <fastjet/internal/base.hh> 0028 #include "fastjet/tools/Transformer.hh" 0029 #include "fastjet/WrappedStructure.hh" 0030 #include "fastjet/CompositeJetStructure.hh" 0031 0032 #include "fastjet/config.h" 0033 0034 // we'll use the native FJ class for reculstering if available 0035 #if FASTJET_VERSION_NUMBER >= 30100 0036 #include "fastjet/tools/Recluster.hh" 0037 #else 0038 #include "Recluster.hh" 0039 #endif 0040 0041 /** \mainpage RecursiveTools contrib 0042 0043 The RecursiveTools contrib provides a set of tools for 0044 recursive investigation jet substructure. Currently it includes: 0045 - fastjet::contrib::ModifiedMassDropTagger 0046 - fastjet::contrib::SoftDrop 0047 - fastjet::contrib::RecursiveSymmetryCutBase (from which the above two classes derive) 0048 - fastjet::contrib::IteratedSoftDropSymmetryFactors (defines ISD procedure) 0049 - fastjet::contrib::IteratedSoftDropMultiplicity (defines a useful observable using ISD) 0050 - example*.cc provides usage examples 0051 */ 0052 0053 0054 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 0055 0056 namespace contrib{ 0057 0058 //------------------------------------------------------------------------ 0059 /// \class RecursiveSymmetryCutBase 0060 /// A base class for all the tools that de-cluster a jet until a 0061 /// sufficiently symmetric configuration if found. 0062 /// 0063 /// Derived classes (so far, ModifiedMassDropTagger and SoftDrop) have to 0064 /// implement the symmetry cut and its description 0065 /// 0066 /// Note that by default, the jet will be reculstered with 0067 /// Cambridge/Aachen before applying the de-clustering procedure. This 0068 /// behaviour can be changed using set_clustering (see below). 0069 /// 0070 /// By default, this class behaves as a tagger, i.e. returns an empty 0071 /// PseudoJet if no substructure is found. While the derived 0072 /// ModifiedMassDropTagger is a tagger, the derived SoftDrop is a groomer 0073 /// (i.e. it returns a non-zero jet even if no substructure is found). 0074 /// 0075 /// This class provides support for 0076 /// - an optional mass-drop cut (see ctor) 0077 /// - options to select which symmetry measure should be used (see ctor) 0078 /// - options to select how the recursion proceeds (see ctor) 0079 /// - options for reclustering the jet before running the de-clustering 0080 /// (see set_reclustering) 0081 /// - an optional subtractor (see ctor and other methods below) 0082 class RecursiveSymmetryCutBase : public Transformer { 0083 public: 0084 // ctors and dtors 0085 //---------------------------------------------------------------------- 0086 0087 /// an enum of the different (a)symmetry measures that can be used 0088 enum SymmetryMeasure{scalar_z, ///< \f$ \min(p_{ti}, p_{tj})/(p_{ti} + p_{tj}) \f$ 0089 vector_z, ///< \f$ \min(p_{ti}, p_{tj})/p_{t(i+j)} \f$ 0090 y, ///< \f$ \min(p_{ti}^2,p_{tj}^2) \Delta R_{ij}^2 / m_{ij}^2 \f$ 0091 theta_E, ///< \f$ \min(E_i,E_j)/(E_i+E_j) \f$ with 3d angle (ee collisions) 0092 cos_theta_E ///< \f$ \min(E_i,E_j)/(E_i+E_j) \f$ with 0093 /// \f$ \sqrt{2[1-cos(theta)]}\f$ for angles (ee collisions) 0094 }; 0095 0096 /// an enum for the options of how to choose which of two subjets to recurse into 0097 enum RecursionChoice{larger_pt, ///< choose the subjet with larger \f$ p_t \f$ 0098 larger_mt, ///< choose the subjet with larger \f$ m_t \equiv (m^2+p_t^2)^{\frac12}] \f$ 0099 larger_m, ///< choose the subjet with larger mass (deprecated) 0100 larger_E ///< choose the subjet with larger energy (meant for ee collisions) 0101 }; 0102 0103 /// Full constructor, which takes the following parameters: 0104 /// 0105 /// \param symmetry_measure the choice of measure to use to estimate the symmetry 0106 /// \param mu_cut the maximal allowed value of mass drop variable mu = m_heavy/m_parent 0107 /// \param recursion_choice the strategy used to decide which subjet to recurse into 0108 /// \param subtractor an optional pointer to a pileup subtractor (ignored if zero) 0109 /// 0110 /// If the (optional) pileup subtractor is supplied, then, by 0111 /// default, the input jet is assumed unsubtracted and the 0112 /// RecursiveSymmetryCutBase returns a subtracted 4-vector. [see 0113 /// also the set_input_jet_is_subtracted() member function]. 0114 /// 0115 RecursiveSymmetryCutBase(SymmetryMeasure symmetry_measure = scalar_z, 0116 double mu_cut = std::numeric_limits<double>::infinity(), 0117 RecursionChoice recursion_choice = larger_pt, 0118 const FunctionOfPseudoJet<PseudoJet> * subtractor = 0 0119 ) : 0120 _symmetry_measure(symmetry_measure), 0121 _mu_cut(mu_cut), 0122 _recursion_choice(recursion_choice), 0123 _subtractor(subtractor), _input_jet_is_subtracted(false), 0124 _do_reclustering(true), _recluster(0), 0125 _grooming_mode(false), 0126 _verbose_structure(false) // by default, don't story verbose information 0127 {} 0128 0129 /// default destructor 0130 virtual ~RecursiveSymmetryCutBase(){} 0131 0132 // access to class info 0133 //---------------------------------------------------------------------- 0134 SymmetryMeasure symmetry_measure() const { return _symmetry_measure; } 0135 double mu_cut() const { return _mu_cut; } 0136 RecursionChoice recursion_choice() const { return _recursion_choice; } 0137 0138 // internal subtraction configuration 0139 //---------------------------------------------------------------------- 0140 0141 /// This tells the tagger whether to assume that the input jet has 0142 /// already been subtracted. This is relevant only if a non-null 0143 /// subtractor pointer has been supplied, and the default assymption 0144 /// is that the input jet is passed unsubtracted. 0145 /// 0146 /// Note: given that subtractors usually change the momentum of the 0147 /// main jet, but not that of the subjets, subjets will continue to 0148 /// have subtraction applied to them. 0149 void set_input_jet_is_subtracted(bool is_subtracted) {_input_jet_is_subtracted = is_subtracted;} 0150 0151 /// returns a bool to indicate if the input jet is assumed already subtracted 0152 bool input_jet_is_subtracted() const {return _input_jet_is_subtracted;} 0153 0154 /// an alternative way to set the subtractor 0155 /// 0156 /// Note that when a subtractor is provided, the result of the 0157 /// RecursiveSymmetryCutBase will be a subtracted jet. 0158 void set_subtractor(const FunctionOfPseudoJet<PseudoJet> * subtractor_) {_subtractor = subtractor_;} 0159 0160 /// returns a pointer to the subtractor 0161 const FunctionOfPseudoJet<PseudoJet> * subtractor() const {return _subtractor;} 0162 0163 // reclustering behaviour 0164 //---------------------------------------------------------------------- 0165 0166 /// configure the reclustering prior to the recursive de-clustering 0167 /// \param do_reclustering recluster the jet or not? 0168 /// \param recluster how to recluster the jet 0169 /// (only if do_recluster is true; 0170 /// Cambridge/Aachen used if NULL) 0171 /// 0172 /// Note that the ModifiedMassDropTagger and SoftDrop are designed 0173 /// to work with a Cambridge/Aachen clustering. Use any other option 0174 /// at your own risk! 0175 void set_reclustering(bool do_reclustering=true, const Recluster *recluster=0){ 0176 _do_reclustering = do_reclustering; 0177 _recluster = recluster; 0178 } 0179 0180 // what to do when no substructure is found 0181 //---------------------------------------------------------------------- 0182 /// specify the behaviour adopted when no substructure is found 0183 /// - in tagging mode, an empty PseudoJet will be returned 0184 /// - in grooming mode, a single particle is returned 0185 /// for clarity, we provide both function although they are redundant 0186 void set_grooming_mode(bool enable=true){ _grooming_mode = enable;} 0187 void set_tagging_mode(bool enable=true){ _grooming_mode = !enable;} 0188 0189 0190 /// Allows access to verbose information about recursive declustering, 0191 /// in particular values of symmetry, delta_R, and mu of dropped branches 0192 void set_verbose_structure(bool enable=true) { _verbose_structure = enable; } 0193 bool has_verbose_structure() const { return _verbose_structure; } 0194 0195 0196 // inherited from the Transformer base 0197 //---------------------------------------------------------------------- 0198 0199 /// the function that carries out the tagging; if a subtractor is 0200 /// being used, then this function assumes that input jet is 0201 /// unsubtracted (unless set_input_jet_is_subtracted(true) has been 0202 /// explicitly called before) and the result of the MMDT will be a 0203 /// subtracted jet. 0204 virtual PseudoJet result(const PseudoJet & j) const; 0205 0206 /// description of the tool 0207 virtual std::string description() const; 0208 0209 /// returns the gepometrical distance between the two particles 0210 /// depending on the symmetry measure used 0211 double squared_geometric_distance(const PseudoJet &j1, 0212 const PseudoJet &j2) const; 0213 0214 0215 class StructureType; 0216 0217 /// for testing 0218 static bool _verbose; 0219 0220 protected: 0221 // the methods below have to be defined by deerived classes 0222 //---------------------------------------------------------------------- 0223 /// the cut on the symmetry measure (typically z) that one need to 0224 /// apply for a given pair of subjets p1 and p2 0225 virtual double symmetry_cut_fn(const PseudoJet & /* p1 */, 0226 const PseudoJet & /* p2 */, 0227 void *extra_parameters = 0) const = 0; 0228 /// the associated dwescription 0229 virtual std::string symmetry_cut_description() const = 0; 0230 0231 //---------------------------------------------------------------------- 0232 /// this defines status codes when checking for substructure 0233 enum RecursionStatus{ 0234 recursion_success=0, //< found some substructure 0235 recursion_dropped, //< dropped softest prong; recursion continues 0236 recursion_no_parents, //< down to constituents; bottom of recursion 0237 recursion_issue //< something went wrong; recursion stops 0238 }; 0239 0240 //---------------------------------------------------------------------- 0241 /// the method below is the one actually performing one step of the 0242 /// recursion. 0243 /// 0244 /// It returns a status code (defined above) 0245 /// 0246 /// In case of success, all the information is filled 0247 /// In case of "no parents", piee1 is the same subjet 0248 /// In case of trouble, piece2 will be a 0 PJ and piece1 is the PJ we 0249 /// should return (either 0 itself if the issue was critical, or 0250 /// non-wero in case of a minor issue just causing the recursion to 0251 /// stop) 0252 /// 0253 /// The extra_parameter argument allows one to pass extra agruments 0254 /// to the symmetry condition 0255 RecursionStatus recurse_one_step(const PseudoJet & subjet, 0256 PseudoJet &piece1, PseudoJet &piece2, 0257 double &sym, double &mu2, 0258 void *extra_parameters = 0) const; 0259 0260 //---------------------------------------------------------------------- 0261 /// helper for handling the reclustering 0262 PseudoJet _recluster_if_needed(const PseudoJet &jet) const; 0263 0264 //---------------------------------------------------------------------- 0265 // helpers for selecting between ee and pp cases 0266 bool is_ee() const{ 0267 return ((_symmetry_measure==theta_E) || (_symmetry_measure==cos_theta_E)); 0268 } 0269 0270 private: 0271 SymmetryMeasure _symmetry_measure; 0272 double _mu_cut; 0273 RecursionChoice _recursion_choice; 0274 const FunctionOfPseudoJet<PseudoJet> * _subtractor; 0275 bool _input_jet_is_subtracted; 0276 0277 bool _do_reclustering; ///< start with a reclustering 0278 const Recluster *_recluster; ///< how to recluster the jet 0279 0280 bool _grooming_mode; ///< grooming or tagging mode 0281 0282 static LimitedWarning _negative_mass_warning; 0283 static LimitedWarning _mu2_gt1_warning; 0284 //static LimitedWarning _nonca_warning; 0285 static LimitedWarning _explicit_ghost_warning; 0286 0287 // additional verbose structure information 0288 bool _verbose_structure; 0289 0290 /// decide what to return when no substructure has been found 0291 PseudoJet _result_no_substructure(const PseudoJet &last_parent) const; 0292 }; 0293 0294 0295 0296 //---------------------------------------------------------------------- 0297 /// class to hold the structure of a jet tagged by RecursiveSymmetryCutBase. 0298 class RecursiveSymmetryCutBase::StructureType : public WrappedStructure { 0299 public: 0300 StructureType(const PseudoJet & j) : 0301 WrappedStructure(j.structure_shared_ptr()), _delta_R(-1.0), _symmetry(-1.0), _mu(-1.0), 0302 _is_composite(false), _has_verbose(false) // by default, do not store verbose structure 0303 {} 0304 0305 /// construct a structure with 0306 /// - basic info inherited from the reference jet "j" 0307 /// - a given deltaR for substructure 0308 /// - a given symmetry for substructure 0309 /// - a given mu parameter for substructure 0310 /// If j is a "copmposite jet", it means that it has further 0311 /// substructure to potentially recurse into 0312 StructureType(const PseudoJet & j, double delta_R_in, double symmetry_in, double mu_in=-1.0) : 0313 WrappedStructure(j.structure_shared_ptr()), _delta_R(delta_R_in), _symmetry(symmetry_in), _mu(mu_in), 0314 _is_composite(dynamic_cast<const CompositeJetStructure*>(j.structure_ptr()) != NULL), 0315 _has_verbose(false) // by default, do not store verbose structure 0316 {} 0317 0318 // information about kept branch 0319 double delta_R() const {return _delta_R;} 0320 double thetag() const {return _delta_R;} // alternative name 0321 double symmetry() const {return _symmetry;} 0322 double zg() const {return _symmetry;} // alternative name 0323 double mu() const {return _mu;} 0324 0325 // additional verbose information about dropped branches 0326 bool has_verbose() const { return _has_verbose;} 0327 void set_verbose(bool value) { _has_verbose = value;} 0328 0329 /// returns true if the current jet has some substructure (i.e. has 0330 /// been tagged by the resursion) or not 0331 /// 0332 /// Note that this should include deltaR==0 (e.g. a perfectly 0333 /// collinear branching with SoftDrop) 0334 bool has_substructure() const { return _delta_R>=0; } 0335 0336 /// number of dropped branches 0337 int dropped_count(bool global=true) const; 0338 0339 /// delta_R of dropped branches 0340 /// when "global" is set, recurse into possile further substructure 0341 std::vector<double> dropped_delta_R(bool global=true) const; 0342 void set_dropped_delta_R(const std::vector<double> &v) { _dropped_delta_R = v; } 0343 0344 /// symmetry values of dropped branches 0345 std::vector<double> dropped_symmetry(bool global=true) const; 0346 void set_dropped_symmetry(const std::vector<double> &v) { _dropped_symmetry = v; } 0347 0348 /// mass drop values of dropped branches 0349 std::vector<double> dropped_mu(bool global=true) const; 0350 void set_dropped_mu(const std::vector<double> &v) { _dropped_mu = v; } 0351 0352 /// maximum symmetry value dropped 0353 double max_dropped_symmetry(bool global=true) const; 0354 0355 /// (global) list of groomed away elements as zg and thetag 0356 /// sorted from largest to smallest anlge 0357 std::vector<std::pair<double,double> > sorted_zg_and_thetag() const; 0358 0359 private: 0360 double _delta_R, _symmetry, _mu; 0361 friend class RecursiveSymmetryCutBase; 0362 0363 bool _is_composite; 0364 0365 // additional verbose information 0366 bool _has_verbose; 0367 // information about dropped values 0368 std::vector<double> _dropped_delta_R; 0369 std::vector<double> _dropped_symmetry; 0370 std::vector<double> _dropped_mu; 0371 0372 bool check_verbose(const std::string &what) const{ 0373 if (!_has_verbose){ 0374 throw Error("RecursiveSymmetryCutBase::StructureType: Verbose structure must be turned on to get "+what+"."); 0375 return false; 0376 } 0377 return true; 0378 } 0379 0380 0381 }; 0382 0383 } // namespace contrib 0384 0385 FASTJET_END_NAMESPACE 0386 0387 #endif // __FASTJET_CONTRIB_RECURSIVESYMMETRYCUTBASE_HH__
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |