Fork me on GitHub

Changeset 667a02a in git for external/fastjet/contribs


Ignore:
Timestamp:
Jun 8, 2018, 3:23:13 PM (6 years ago)
Author:
Michele Selvaggi <michele.selvaggi@…>
Branches:
ImprovedOutputFile, Timing, dual_readout, llp, master
Children:
e57c062
Parents:
001ee95 (diff), 17d0ab8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of github.com:delphes/delphes

Location:
external/fastjet/contribs
Files:
6 added
1 deleted
19 edited

Legend:

Unmodified
Added
Removed
  • external/fastjet/contribs/Nsubjettiness/AUTHORS

    r001ee95 r667a02a  
    3939   Iain W. Stewart, Frank J. Tackmann, Jesse Thaler,
    4040   Christopher K. Vermilion, and Thomas F. Wilkason.
    41    arXiv:1508.01516.
     41   JHEP 1511:072 (2015), arXiv:1508.01516.
    4242
    4343   Resolving Boosted Jets with XCone.
    4444   Jesse Thaler and Thomas F. Wilkason.
    45    arXiv:1508.01518.
     45   JHEP 1512:051 (2015), arXiv:1508.01518.
    4646
    4747-------------------------------------------------------------------------------
  • external/fastjet/contribs/Nsubjettiness/AxesDefinition.hh

    r001ee95 r667a02a  
    55//  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
    66//
    7 //  $Id: AxesDefinition.hh 833 2015-07-23 14:35:23Z jthaler $
     7//  $Id: AxesDefinition.hh 1130 2018-06-06 12:09:46Z jthaler $
    88//----------------------------------------------------------------------
    99// This file is part of FastJet contrib.
     
    508508/// \brief Wrapper for jet definitions (for memory management)
    509509///
    510 /// This class was introduced to avoid issue of a FastJet bug when using genKT clustering
    511 /// Now using this for all AxesDefinition with a manual recombiner to use the delete_recombiner_when_unused function
     510/// This class is used by all AxesDefinition with a manual recombiner to
     511/// ensure that the delete_recombiner_when_unused function is always called
    512512///------------------------------------------------------------------------
    513513class JetDefinitionWrapper {
     
    549549   : ExclusiveJetAxes(JetDefinitionWrapper(fastjet::kt_algorithm,
    550550                                          fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
    551                                           _recomb = new WinnerTakeAllRecombiner(), // Needs to be explicitly declared (this will be deleted by JetDefinitionWrapper)
     551                                          new WinnerTakeAllRecombiner(), // Needs to be explicitly declared (this will be deleted by JetDefinitionWrapper)
    552552                                          fastjet::Best).getJetDef()
    553553                      ) {
     
    571571   virtual WTA_KT_Axes* create() const {return new WTA_KT_Axes(*this);}
    572572
    573 private:
    574    const WinnerTakeAllRecombiner *_recomb;  ///< Internal recombiner
    575 
    576573};
    577574   
     
    588585   : ExclusiveJetAxes(JetDefinitionWrapper(fastjet::cambridge_algorithm,
    589586                                             fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
    590                                              _recomb = new WinnerTakeAllRecombiner(), // Needs to be explicitly declared (this will be deleted by JetDefinitionWrapper)
     587                                             new WinnerTakeAllRecombiner(), // Needs to be explicitly declared (this will be deleted by JetDefinitionWrapper)
    591588                                             fastjet::Best).getJetDef()) {
    592589    setNPass(NO_REFINING);
     
    608605   /// For copying purposes
    609606   virtual WTA_CA_Axes* create() const {return new WTA_CA_Axes(*this);}
    610    
    611 private:
    612    const WinnerTakeAllRecombiner *_recomb;  ///< Internal recombiner
    613 
     607 
    614608};
    615609
     
    674668                                            R0,
    675669                                            p,
    676                                             _recomb = new WinnerTakeAllRecombiner()
     670                                            new WinnerTakeAllRecombiner()
    677671                                            ).getJetDef()), _p(p), _R0(R0) {
    678672      if (p < 0) throw Error("WTA_GenKT_Axes:  Currently only p >=0 is supported.");
     
    702696   double _p;   ///< genkT power
    703697   double _R0;  ///< jet radius
    704    const WinnerTakeAllRecombiner *_recomb; ///< Internal recombiner
    705698};
    706699   
     
    717710   /// Constructor
    718711   GenET_GenKT_Axes(double delta, double p, double R0 = fastjet::JetDefinition::max_allowable_R)
    719    : ExclusiveJetAxes((JetDefinitionWrapper(fastjet::genkt_algorithm, R0, p, _recomb = new GeneralEtSchemeRecombiner(delta))).getJetDef() ),
     712   : ExclusiveJetAxes((JetDefinitionWrapper(fastjet::genkt_algorithm, R0, p, new GeneralEtSchemeRecombiner(delta))).getJetDef() ),
    720713    _delta(delta), _p(p), _R0(R0) {
    721714       if (p < 0) throw Error("GenET_GenKT_Axes:  Currently only p >=0 is supported.");
     
    750743   double _p;     ///< GenkT power
    751744   double _R0;    ///< jet radius
    752    const GeneralEtSchemeRecombiner *_recomb;   ///< Internal recombiner
    753745};
    754746
     
    12011193   /// Constructor
    12021194   Comb_WTA_GenKT_Axes(int nExtra, double p, double R0 = fastjet::JetDefinition::max_allowable_R)
    1203    : ExclusiveCombinatorialJetAxes((JetDefinitionWrapper(fastjet::genkt_algorithm, R0, p, _recomb = new WinnerTakeAllRecombiner())).getJetDef(), nExtra),
     1195   : ExclusiveCombinatorialJetAxes((JetDefinitionWrapper(fastjet::genkt_algorithm, R0, p, new WinnerTakeAllRecombiner())).getJetDef(), nExtra),
    12041196    _p(p), _R0(R0) {
    12051197       if (p < 0) throw Error("Comb_WTA_GenKT_Axes:  Currently only p >=0 is supported.");
     
    12271219   double _p;        ///< GenkT power
    12281220   double _R0;       ///< jet radius
    1229    const WinnerTakeAllRecombiner *_recomb;   ///< Internal recombiner
    12301221};
    12311222   
     
    12411232   /// Constructor
    12421233   Comb_GenET_GenKT_Axes(int nExtra, double delta, double p, double R0 = fastjet::JetDefinition::max_allowable_R)
    1243    : ExclusiveCombinatorialJetAxes((JetDefinitionWrapper(fastjet::genkt_algorithm, R0, p, _recomb = new GeneralEtSchemeRecombiner(delta))).getJetDef(), nExtra),
     1234   : ExclusiveCombinatorialJetAxes((JetDefinitionWrapper(fastjet::genkt_algorithm, R0, p, new GeneralEtSchemeRecombiner(delta))).getJetDef(), nExtra),
    12441235    _delta(delta), _p(p), _R0(R0) {
    12451236       if (p < 0) throw Error("Comb_GenET_GenKT_Axes:  Currently only p >=0 is supported.");
     
    12711262   double _p;        ///< GenkT power
    12721263   double _R0;       ///< jet radius
    1273    const GeneralEtSchemeRecombiner *_recomb;  ///<  Internal recombiner
    12741264};
    12751265   
  • external/fastjet/contribs/Nsubjettiness/ChangeLog

    r001ee95 r667a02a  
     12018-07-06 <jthaler>
     2   Updated comments in AxesDefinition.hh about role of JetDefinitionWrapper
     3   Updated AUTHORS with JHEP publication information for XCone
     4   Prepared VERSION and NEWS for 2.2.5 release
     52018-07-05 <jthaler>
     6   Fixed bug in AxesDefinition.hh where _recomb was used before it was declared.
    172016-06-08 <jthaler>
    28   Fixed bug in MeasureDefinition.cc where axes were not completely defined,
  • external/fastjet/contribs/Nsubjettiness/MeasureDefinition.cc

    r001ee95 r667a02a  
    55//  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
    66//
    7 //  $Id: MeasureDefinition.cc 946 2016-06-14 19:11:27Z jthaler $
     7//  $Id: MeasureDefinition.cc 943 2016-06-09 00:55:29Z jthaler $
    88//----------------------------------------------------------------------
    99// This file is part of FastJet contrib.
  • external/fastjet/contribs/Nsubjettiness/NEWS

    r001ee95 r667a02a  
    3232    N-jettiness as a jet finder using the new ConicalGeometric measure.
    3333
     34-- 2.2.5:  (June 6, 2018) Fixed bug involved undefined pointer for in
     35           AxesDefinition (thanks Attila Krasznahorkay)
    3436-- 2.2.4:  (Jun 14, 2016) Fixed bug where multi-pass minimization could yield
    3537           pathological axes (thanks Gregory Soyez)
  • external/fastjet/contribs/Nsubjettiness/VERSION

    r001ee95 r667a02a  
    1 2.2.4
     12.2.5
  • external/fastjet/contribs/RecursiveTools/AUTHORS

    r001ee95 r667a02a  
    44   Gregory Soyez <soyez@fastjet.fr>
    55   Jesse Thaler <jthaler@jthaler.net>
     6   Kevin Zhou <knzhou@mit.edu>
     7   Frederic Dreyer <fdreyer@mit.edu>
    68
    79The physics is based on:
     
    1618   Andrew J. Larkoski, Simone Marzani, Gregory Soyez, and Jesse Thaler.
    1719   JHEP 1405:146 (2014), arXiv:1402.2657
     20
     21   [IteratedSoftDrop]
     22   Casimir Meets Poisson: Improved Quark/Gluon Discrimination with Counting Observables.
     23   Christopher Frye, Andrew J. Larkoski, Jesse Thaler, Kevin Zhou.
     24   JHEP 1709:083 (2017), arXiv:1704.06266
     25
     26   [RecursiveSoftDrop]
     27   [BottomUpSoftDrop]
     28   Recursive Soft Drop.
     29   Frederic A. Dreyer, Lina Necib, Gregory Soyez, and Jesse Thaler
     30   arXiv:1804.03657
     31   
  • external/fastjet/contribs/RecursiveTools/COPYING

    r001ee95 r667a02a  
    1414  arXiv:1307.0007
    1515  arXiv:1402.2657
     16  arXiv:1704.06266
    1617
    1718======================================================================
  • external/fastjet/contribs/RecursiveTools/ChangeLog

    r001ee95 r667a02a  
     12018-05-29  Jesse Thaler  <jthaler@jthaler.net>
     2
     3        * VERSION
     4        * NEWS
     5        Changed to 2.0.0-beta2, noted in news
     6
     72018-04-21  Jesse Thaler  <jthaler@jthaler.net>
     8
     9        * AUTHORS: updated arxiv number for RecursiveSoftDrop
     10
     112018-04-21  Gavin Salam  <gavin.salam@cern.ch>
     12
     13        * README: updated arxiv number for RecursiveSoftDrop & Bottom-up
     14        Soft Drop.
     15
     162018-04-04  Gregory Soyez  <soyez@fastjet.fr>
     17
     18        * RecursiveSoftDrop.cc (contrib):
     19        fixed syntax of calls to structure_of<...>
     20        (thanks to Attila Krasznahorkay)
     21
     222018-01-24  Gregory Soyez  <soyez@fastjet.fr>
     23
     24        * RecursiveSoftDrop.cc:
     25        for the (dafault) dynamical R0 implementation, the dynamical R0 is
     26        evolved independently in each branch.
     27
     282017-10-10  Jesse Thaler  <jthaler@jthaler.net>
     29        * AUTHORS
     30        Added mention of BUSD
     31
     32        * README
     33        Some tweaks to the wording
     34
     352017-10-11  Gregory Soyez  <soyez@fastjet.fr>
     36
     37        * IteratedSoftDrop.hh:
     38        IteratedSoftDropInfo::size() and multiplicity() now return an
     39        unsigned int instead of a double
     40
     412017-10-10  Jesse Thaler  <jthaler@jthaler.net>
     42        * AUTHORS
     43        Updated journal reference for ISD
     44
     45        * example_isd.{cc,ref}:
     46        Included soft drop multiplicity in example
     47
     48        * README
     49        Added warning at top that documentation has not been updated
     50
     51        * VERSION
     52        Changed to 2.0.0-beta1
     53
     542017-10-10  Gregory Soyez  <soyez@fastjet.fr>
     55
     56        * example_isd.ref:
     57        updated to reflect the bugfix below
     58
     59        * IteratedSoftDrop.cc:
     60        fixed issue in description (was taking sqrt of -ve number when
     61        there were no angular cut)
     62
     63        * NEWS:
     64        drafted for RecursiveTools-2.0.0-beta1
     65
     66        * TODO:
     67        updated list in view of a beta release
     68
     69        * example_isd.cc:
     70        pointed to the right header for IteratedSoftDrop
     71
     72        * RecursiveSoftDrop.{hh,cc}:
     73        * IteratedSoftDrop.{hh,cc}:
     74        moved IteratedSoftDrop to its own file (replacing the old
     75        implementation)
     76
     77        * example_advanced_usage.ref:
     78        updated reference file following the fix below.
     79
     802017-09-28  Gregory Soyez  <soyez@fastjet.fr>
     81
     82        * RecursiveSymmetryCutBase.cc:
     83        when no substructure is found, keep the _symmetry, _delta_R and
     84        _mu structure variables at -1.  This for example allows one to
     85        trigger on substructure by checking if delta_R>=0.
     86
     87        Note: we could set it to 0 (as it was before) and trigger using
     88        _delta_R>0 but there might be some genuine substructure exactly
     89        collinear.
     90
     912017-09-19  Gregory Soyez  <soyez@fastjet.fr>
     92
     93        * example_isd.ref:
     94        updated to the latest version of the example
     95
     962017-09-18  Gregory Soyez  <soyez@fastjet.fr>
     97
     98        * Makefile:
     99        updating make check to use all the examples (failing on ISD as
     100        expected, see below)
     101
     102        * example_bottomup_softdrop.cc:
     103        fixed typo
     104
     105        * example_bottomup_softdrop.ref:
     106        * example_recursive_softdrop.ref:
     107        added reference output for this example
     108
     109        * RecursiveSoftDrop.{hh,cc}:
     110        * RecursiveSymmetryCutBase.{cc,hh}:
     111        moved the "all_prongs" method from the base structure t oa
     112        standalone function in RecursiveSoftDrop.hh
     113
     114        In practice, this is irrelevant for mMDT and SD (since pieces()
     115        gets the job done, and the substructure class does not have (as
     116        is) reliable info to get the full structure)
     117
     118        * RecursiveSymmetryCutBase.cc:
     119        revamped a series of requests for substructure info to better
     120        handle possible recursion into deeper jet substructure.
     121
     122        * RecursiveSoftDrop.{hh,cc}:
     123        updated "description" to reuse the info from the base class
     124
     125        * example_isd.cc:
     126        updated to use the newer implementation of ISD. Checked that it
     127        gives the same results as the former implementation.
     128
     129        Note: make check still needs fixing because the example now
     130              computes a different set of angularities
     131
     132        * RecursiveSoftDrop.hh:
     133        added a few helpers to IteratedSoftDropInfo ([] operator and size,
     134        meaning it can be used as a vector<pair<double,double> >)
     135
     136        * RecursiveSymmetryCutBase.cc:
     137        . fixed bugs in the calculation of the geometric distances for ee
     138          coordinates
     139        . fixed bug in the computation of the (zg,thetag) pairs [it was
     140          returning the groomed ones instead of the ones passing the
     141          condition]
     142
     143        * example_recursive_softdrop.cc:
     144        set the R0 parameter to the original jet radius
     145
     1462017-09-13  Gregory Soyez  <soyez@fastjet.fr>
     147
     148        * example_recursive_softdrop.cc:
     149        tied up a few comments and the code output
     150
     151        * RecursiveSymmetryCutBase.{hh,cc}:
     152        removed the unneeded _is_composite
     153
     154        * RecursiveSoftDrop.cc:
     155        fixed issue with "verbose" dropped info on branches with no
     156        further substructure
     157
     1582017-09-11  Gregory Soyez  <soyez@fastjet.fr>
     159
     160        * RecursiveSoftDrop.{hh,cc}:
     161        have IteratedSoftDDrop returning by default an object of type
     162        IteratedSoftDropInfo; added several helpers
     163
     1642017-09-08  Gregory Soyez  <soyez@fastjet.fr>
     165
     166        * RecursiveSoftDrop.{hh,cc}:
     167        updated IteratedSoftDrop to give it the flexibility of
     168        RecursiveSoftDrop
     169
     170        * RecursiveSymmetryCutBase.hh:
     171        fixed typo in comment
     172
     173        * example_mmdt_ee.cc:     *** ADDED ***
     174        added an example to illustrat usage in ee collisions
     175
     176        * example_isd.cc:
     177        * BottomUpSoftDrop.cc:
     178        * IteratedSoftDrop.cc:
     179        * RecursiveSoftDrop.cc:
     180        Fixed compilation issues with FJ 3.0 (mostly the usage of features
     181        introduced only in FJ3.1)
     182
     183        * RecursiveSymmetryCutBase.{hh,cc}:
     184        used the internal Recluster class for FJ<3.1.0 and the FJ antive
     185        one for FJ>=3.1.0
     186
     187        * BottomUpSoftDrop.{hh,cc}:
     188        moved the implementation of global_grooming to the source file and
     189        fixed a few trivial compilation errors
     190
     1912017-09-08  Frédéric Dreyer  <frederic.dreyer@gmail.com>
     192
     193        * BottomUpSoftDrop.hh:
     194        added the global_grooming method to process full event
     195
     1962017-09-07  Gregory Soyez  <soyez@fastjet.fr>
     197
     198        * RecursiveSoftDrop.cc:
     199        cleaned (mostly by removing older commented-out code)
     200
     201        * RecursiveSoftDrop.{hh,cc}:
     202        * RecursiveSymmetryCutBase.{hh,cc}:
     203        * SoftDrop.cc:
     204
     205        added support for ee coordinates.  For that, the symmetry measure
     206        has to be set to either theta_E (which uses the 3-vector angle
     207        theta) or to cos_theta_E which uses sqrt(2*[1-cos(theta)])
     208
     209        Accordingly, the recursion_choice can be set to larger_E to
     210        recurse into the branch with the largest energy. The larger_m
     211        mode, recorsing into the larger-mass branch is also possible but
     212        not advised (for the same reason as the pp version).
     213
     214        * RecursiveSymmetryCutBase.{hh,cc}:
     215        switched to the Recluster class provided with FastJet. ASlso
     216        included the recluster description to RecursiveSymmetryCutBase
     217        when it is user-defined.
     218
     2192017-09-06  Gregory Soyez  <soyez@fastjet.fr>
     220
     221        * BottomUpSoftDrop.{hh,cc}:
     222        . renamed SoftDropStructure  -> BottomUpSoftDropStructure
     223                  SoftDropRecombiner -> BottomUpSoftDropRecombiner
     224                  SoftDropPlugin     -> BottomUpSoftDropPlugin
     225        . moved 'description' to source file (instead of header)
     226        . kept the "area" information when available (jets will just
     227        appear as having a 0 area)
     228        . added most class description (main class still missing)
     229
     230        * RecursiveSoftDrop.cc:
     231        . put internal classes to handle CS history in an internal namespace
     232        . replaced the "switch" in the mail loop by a series of if (allows
     233          us a few simplificatins/cleaning)
     234        . more uniform treatment of issues in the presence of an angular cut
     235          (as part of the above reorganisation)
     236
     237        * example_advanced_usage.ref:
     238        updated reference output file following the bugfix (missing
     239        "grooming mode" initialisation in one of the SoftDrop ctors) on
     240        2017-08-01
     241
     242        * RecursiveSymmetryCutBase.cc:
     243        removed redundent code
     244
     2452017-08-10  Gregory Soyez  <soyez@fastjet.fr>
     246
     247        * RecursiveSoftDrop.cc:
     248        fixed trivial typo in variable name
     249
     250>>>>>>> .r1071
     2512017-08-04  Gregory Soyez  <soyez@fastjet.fr>
     252
     253        * RecursiveSoftDrop.cc:
     254        do not impose an angular cut in IterativeSD if it is -ve.
     255
     2562017-08-01  Gregory Soyez  <soyez@fastjet.fr>
     257
     258        * example_recursive_softdrop.cc:
     259        added a series of optional flags
     260
     261        * RecursiveSoftDrop.cc:
     262        fixed a few issues with the fixed depth version
     263
     264        * RecursiveSymmetryCutBase.hh:
     265        a jet is now considered as havig substructure if deltaR>0
     266        (coherent with released version)
     267
     268        * SoftDrop.hh:
     269        bugfix: set the "grooming mode" by default in all ctors
     270        EDIT: caused issue with make check, fixed on 2017-09-069 (see
     271              above)
     272
     273        * RecursiveSoftDrop.{hh,cc}:
     274        added support for the "same depth" variant
     275
     276        * RecursiveSymmetryCutBase.cc:
     277        also associate a RecursiveSymmetryCutBase::StructureType structure
     278        to the result jet in case it is just a single particle (in
     279        grooming mode)
     280
     2812017-07-31  Gregory Soyez  <soyez@fastjet.fr>
     282
     283        * RecursiveSymmetryCutBase.{hh,cc}:
     284        added the option to pass an extra parameter to the symmetry cut
     285        function
     286
     287        * RecursiveSymmetryCutBase.{hh,cc}:
     288        * ModifiedMassDropTagger.hh
     289        * SoftDrop.hh:
     290        minor adaptions due to the above change + added a few methods to
     291        query the class information (symmetry cut, beta, ...)
     292
     293        * RecursiveSoftDrop.{hh,cc}:
     294        Added support for
     295        - a dynamical R0
     296        - recursing only in the hardest branch
     297        - imposing a min deltaR cut
     298
     299        Added a tentative IterativeSoftDrop class
     300
     3012017-07-28  Gregory Soyez  <soyez@fastjet.fr>
     302
     303        * RecursiveSoftDrop.cc:
     304        adapted to the latest changes in RecursiveSymmetryCutBase
     305
     306        * RecursiveSymmetryCutBase.{hh,cc}:
     307        reorganised the output of the recursion step (recurse_one_step)
     308        using an enum to make iot more readable (and to fix issues where
     309        the dropped prong is actually 0, e.g. after subtraction)
     310
     3112017-07-26  Gregory Soyez  <soyez@fastjet.fr>
     312
     313        * example_recursive_softdrop.cc:   *** ADDED ***
     314        added a draft example for the use of RecursiveSoftDrop
     315
     316        * RecursiveSoftDrop.{hh,cc}:       *** ADDED ***
     317        added a first pass at an implementation of RecursiveSoftDrop.
     318
     319        This is based on Frederic's initial version but keeps the
     320        branching structure of the jet. Some of the features, like
     321        dynamical R0, direct access to the substructure or the same depth
     322        variant, are still unsupported.
     323
     324        * SoftDrop.hh:
     325        declared _beta, _symmetry_cut and _R0sqr as protected (was
     326        private) so they ca n be used by RecursiveSoftDrop
     327
     328        * RecursiveSymmetryCutBase.{hh,cc}:
     329        extracted from result() the part that performs one step of the
     330        resursion (implemented as recurse_one_step()). This is repeatedly
     331        called by result(). It has specific conventions to indicate
     332        whether or not some substructure has been found or if one ran into
     333        some issue.
     334
     3352017-04-25  Kevin Zhou  <knzhou@mit.edu>
     336
     337        * IteratedSoftDrop.hh
     338          . Added Doxygen documentation
     339
     340        * RecursiveSymmetryCutBase.hh
     341          . Added references to ISD
     342
     3432017-04-25  Jesse Thaler  <jthaler@jthaler.net>
     344        * AUTHORS, COPYING:
     345          . Added ISD arXiv number
     346
     347        * example_isd.{cc,ref}
     348          . Added ISD arXiv number
     349          . Changing z_cut to be optimal value (with Lambda = 1 GeV)
     350          . Tweaked formatting
     351
     352        * IteratedSoftDrop.{hh,cc}
     353          . Added ISD arXiv number
     354          . Assert added if recluster does not return one jet.
     355
     356        * README
     357          . Added ISD arXiv number and tweaked wording
     358
     359
     3602017-04-20  Kevin Zhou  <knzhou@mit.edu>
     361
     362        * example_isd.{cc,ref}      ** ADDED **
     363        * IteratedSoftDrop.{cc,hh}  ** ADDED **
     364
     365        * Makefile
     366          . Added IteratedSoftDrop (ISD) as appropriate
     367
     368        * AUTHORS
     369          . Added myself to author list
     370          . Added placeholder for ISD paper
     371
     372        * COPYING
     373          . Added placeholder for ISD paper
     374
     375        * README
     376          . Added description of ISD
     377
     378        * TODO
     379          . Added tasks to integrate ISD with other classes, e.g. SD,
     380            Recluster, and the future RecursiveSoftDrop (RSD)
     381
     382        * NEWS
     383          . Added dummy for release of 1.1.0
     384
     385        * VERSION:
     386          . Switched version number to 1.1.0-dev
     387
     388        * example_advanced_usage.cc:
     389          . Added $Id$ tag, didn't change anything else
     390
     3912014-07-30  Gregory Soyez  <soyez@fastjet.fr>
     392
     393        * Recluster.hh: fixed the name of the #define for the header
     394
    13952014-07-09  Gregory Soyez  <soyez@fastjet.fr> + Jesse
    2396
  • external/fastjet/contribs/RecursiveTools/ModifiedMassDropTagger.hh

    r001ee95 r667a02a  
    1 // $Id: ModifiedMassDropTagger.hh 688 2014-06-17 14:29:56Z jthaler $
     1// $Id: ModifiedMassDropTagger.hh 1032 2017-07-31 14:20:03Z gsoyez $
    22//
    33// Copyright (c) 2014-, Gavin P. Salam
     
    105105  virtual ~ModifiedMassDropTagger(){}
    106106
     107  //----------------------------------------------------------------------
     108  // access to class info
     109  double symmetry_cut() const { return _symmetry_cut; }
     110 
    107111protected:
    108112
     
    110114  /// has no dependence on the subjet kinematics
    111115  virtual double symmetry_cut_fn(const PseudoJet & /* p1 */,
    112                                  const PseudoJet & /* p2 */
     116                                 const PseudoJet & /* p2 */,
     117                                 void *extra_parameters = 0
    113118                                 ) const {return _symmetry_cut;}
    114119  virtual std::string symmetry_cut_description() const;
  • external/fastjet/contribs/RecursiveTools/NEWS

    r001ee95 r667a02a  
     12018/05/31: release of version 2.0.0-beta2 with corrected syntax
     2
     32017/10/10: release of version 2.0.0-beta1 including implementations of
     4
     5* RecursiveSoftDrop (see example_rsd.hh for usage)
     6* IteratedSoftDrop (see example_isd.hh for usage)
     7* e+e- version of the recursive tools (see example_mmdt_ee.hh for usage)
     8* BottomUpSoftDrop (see example_bottomup_softdrop.cc for usage)
     9
    1102014/07/09: release of version 1.0.0 of RecursiveTools including
    211            ModifiedMassDropTagger and SoftDrop (as well as Recluster)
  • external/fastjet/contribs/RecursiveTools/README

    r001ee95 r667a02a  
    1717  Marzani, Gregory Soyez, Jesse Thaler
    1818
     19- RecursiveSoftDrop
     20- BottomUpSoftDrop
     21  This corresponds to arXiv:1804.03657 by Frederic Dreyer, Lina
     22  Necib, Gregory Soyez and Jesse Thaler
     23
     24- IteratedSoftDrop
     25  This corresponds to arXiv:1704.06266 by Christopher Frye, Andrew J.
     26  Larkoski, Jesse Thaler, Kevin Zhou
     27
    1928- Recluster
    2029  A generic tool to recluster a given jet into subjets
    21   Note: this is largely based on the Filter code in FastJet v3.0 and
    22   ultimately, this tool will probably be moved into FastJet
     30  Note: a Recluster class is available natively in FastJet since v3.1.
     31        Users are therefore encouraged to use the FastJet version
     32        rather than this one which is mostly provided for
     33        compatibility of this contrib with older versions of FastJet.
    2334
    2435The interface for these tools is described in more detail below, with
     
    7485
    7586The SoftDrop procedure is very similar to mMDT, albeit with a
    76 generalized symmetry condition:
     87generalised symmetry condition:
    7788 
    7889   z > z_cut * (R / R0)^beta
     
    108119
    109120------------------------------------------------------------------------
     121RecursiveSoftDrop
     122------------------------------------------------------------------------
     123
     124The RecursiveSoftDrop procedure applies the Soft Drop procedure N times
     125in a jet in order to find up to N+1 prongs.  N=0 makes no modification
     126to the jet, and N=1 is equivalent to the original SoftDrop.
     127
     128Once one has more than one prong, one has to decide which will be
     129declustered next.  At each step of the declustering procedure, one
     130undoes the clustering which has the largest declustering angle
     131(amongst all the branches that are searched for substructure). [see
     132"set_fixed_depth" below for an alternative]
     133
     134Compared to SoftDrop, RecursiveSoftDrop takes an extra argument N
     135specifying the number of times the SoftDrop procedure is recursively
     136applied. Negative N means that the procedure is applied until no
     137further substructure is found (i.e. corresponds to taking N=infinity).
     138
     139   double z_cut = 0.10;
     140   double beta  = 2.0;
     141   double R0    = 1.0; // this is the default value
     142   int N        = -1; 
     143   RecursiveSoftDrop rsd(z_cut, beta, N, R0);
     144
     145One then acts on a jet as
     146
     147   PseudoJet groomed_jet = rsd(jet)
     148
     149and get additional information via
     150
     151   groomed_jet.structure_of<RecursiveSoftDrop>()
     152
     153------------------------------------------------------------------------
     154IteratedSoftDrop
     155------------------------------------------------------------------------
     156
     157Iterated Soft Drop (ISD) is a repeated variant of SoftDrop.  After
     158performing the Soft Drop procedure once, it logs the groomed symmetry
     159factor, then recursively performs Soft Drop again on the harder
     160branch.  This procedure is repeated down to an (optional) angular cut
     161theta_cut, yielding a set of symmetry factors from which observables
     162can be built.
     163
     164An IteratedSoftDrop tool can be created as follows:
     165
     166  double beta = -1.0;
     167  double z_cut = 0.005;
     168  double theta_cut = 0.0;
     169  double R0 = 0.5;        // characteristic radius of jet algorithm
     170  IteratedSoftDrop isd(beta, z_cut, double theta_cut, R0);
     171
     172By default, ISD applied on a jet gives a result of type
     173IteratedSoftDropInfo that can then be probed to obtain physical
     174observables
     175
     176  IteratedSoftDropInfo isd_info = isd(jet);
     177
     178  unsigned int multiplicity = isd_info.multiplicity();
     179  double kappa = 1.0;     // changes angular scale of ISD angularity
     180  double isd_width = isd_info.angularity(kappa);
     181  vector<pair<double,double> > zg_thetags = isd_info.all_zg_thetag();
     182  vector<pair<double,double> > zg_thetags = isd_info();
     183  for (unsigned int i=0; i< isd_info.size(); ++i){
     184    cout << "(zg, theta_g)_" << i << " = "
     185         << isd_info[i].first << " " <<  isd_info[i].second << endl;
     186  }
     187
     188Alternatively, one can directly get the multiplicity, angularity, and
     189(zg,thetag) pairs from the IteratedSoftDrop class, at the expense of
     190re-running the declustering procedure:
     191
     192  unsigned int multiplicity = isd.multiplicity(jet);
     193  double isd_width = isd.angularity(jet, 1.0);
     194  vector<pair<double,double> > zg_thetags = isd.all_zg_thetag(jet);
     195
     196
     197Note: the iterative declustering procedure is the same as what one
     198  would obtain with RecursiveSoftDrop with an (optional) angular cut
     199  and recursing only in the hardest branch [see the "Changing
     200  behaviour" section below for details], except that it returns some
     201  information about the jet instead of a modified jet as RSD does.
     202
     203
     204------------------------------------------------------------------------
     205BottomUpSoftDrop
     206------------------------------------------------------------------------
     207
     208This is a bottom-up version of the RecursiveSoftDrop procedure, in a
     209similar way as Pruning can be seen as a bottom-up version of Trimming.
     210
     211In practice, the jet is reclustered and at each step of the clustering
     212one checks the SoftDrop condition
     213
     214   z > z_cut * (R / R0)^beta
     215
     216If the condition is met, the pair is recombined. If the condition is
     217not met, only the hardest of the two objects is kept for further
     218clustering and the softest is rejected.
     219
     220------------------------------------------------------------------------
    110221Recluster
    111222------------------------------------------------------------------------
     223
     224  *** NOTE: this is provided only for backwards compatibility ***
     225  *** with FastJet <3.1. For FastJet >=3.1, the native        ***
     226  *** fastjet::Recluster is used instead                      ***
    112227
    113228The Recluster class allows the constituents of a jet to be reclustered
    114229with a different recursive clustering algorithm.  This is used
    115 internally in the mMDT/SoftDrop code in order to recluster the jet using
    116 the CA algorithm.  This is achieved via
     230internally in the mMDT/SoftDrop/RecursiveSoftDrop/IteratedSoftDrop
     231code in order to recluster the jet using the CA algorithm.  This is
     232achieved via
    117233
    118234  Recluster ca_reclusterer(cambridge_algorithm,
     
    123239delete_self_when_unused.
    124240
    125 
    126241------------------------------------------------------------------------
    127242Changing behaviour
    128243------------------------------------------------------------------------
    129244
    130 The behaviour of the ModifiedMassDropTagger and SoftDrop classes can
    131 be tweaked using the following options:
    132 
    133 SymmetryMeasure = {scalar_z,vector_z,y}  [constructor argument]
     245The behaviour of the all the tools provided here
     246(ModifiedMassDropTagger, SoftDrop, RecursiveSoftDrop and
     247IteratedSoftDrop) can be tweaked using the following options:
     248
     249SymmetryMeasure = {scalar_z, vector_z, y, theta_E, cos_theta_E}
     250  [constructor argument]
    134251  : The definition of the energy sharing between subjets, with 0
    135     corresponding to the most asymmetric
    136 
    137 RecursionChoice = {larger_pt,larger_mt,larger_m}  [constructor argument]
     252    corresponding to the most asymmetric.
     253    . scalar_z = min(pt1,pt2)/(pt1+pt2)   [default]
     254    . vector_z = min(pt1,pt2)/pt_{1+2}
     255    . y = min(pt1^2,pt2^2)/m_{12}^2  (original y from MDT)
     256    . theta_E     = min(E1,E2)/(E1+E2),
     257           with angular measure theta_{12}^2
     258    . cos_theta_E = min(E1,E2)/(E1+E2),
     259           with angular measure 2[1-cos(theta_{12})]
     260    The last two variants are meant for use in e+e- collisions,
     261    together with the "larger_E" recursion choice (see below)
     262
     263RecursionChoice = {larger_pt, larger_mt, larger_m, larger_E}
     264  [constructor argument]
    138265  : The path to recurse through the tree after the symmetry condition
    139     fails
     266    fails. Options refer to transverse momentum (pt), transverse mass
     267    (mt=sqrt(pt^2+m^2), mass (m) or energy (E). the latter is meant
     268    for use in e+e- collisions
    140269
    141270mu_cut   [constructor argument]
    142271  : An optional mass drop condition
    143272
    144 set_subtractor(subtractor*) [or subtracter as a constructor argument]
     273set_subtractor(subtractor*) [or subtractor as a constructor argument]
    145274  : provide a subtractor. When a subtractor is supplied, the
    146275    kinematic constraints are applied on subtracted 4-vectors. In
     
    165294    and SoftDrop defaults to grooming mode.
    166295
     296set_verbose_structure(bool)
     297  : when set to true, additional information will be stored in the jet
     298    structure. This includes in particular values of symmetry,
     299    delta_R, and mu of dropped branches
     300
     301For the specific case of RecursiveSoftDrop, additional tweaking is
     302possible via the following methods
     303
     304set_fixed_depth_mode(bool)
     305  : when this is true, RSD will recurse (N times) into all the
     306    branches found during the previous iteration [instead of recursing
     307    through the largest declustering angle until N prongs have been
     308    found]. This yields at most 2^N prong. For infinite N, the two
     309    options are equivalent.
     310
     311set_dynamical_R0(bool)
     312  : By default the angles in the SD condition are normalised to the
     313    parameter R0. With "dynamical R0", RSD will dynamically adjust R0
     314    to be the angle between the two prongs found during the previous
     315    iteration.
     316
     317set_hardest_branch_only(bool)
     318  : When substructure is found, only recurse into the hardest of the
     319    two branches for further substructure search. This uses the class
     320    RecursionChoice.
     321
     322set_min_deltaR_squared(double):
     323  : set a minimal angle (squared) at which we stop the declustering
     324    procedure.  This cut is ineffective for negative values of the
     325    argument.
     326
    167327------------------------------------------------------------------------
    168328Technical Details
  • external/fastjet/contribs/RecursiveTools/Recluster.hh

    r001ee95 r667a02a  
    1 #ifndef __FASTJET_TOOLS_RECLUSTER_HH__
    2 #define __FASTJET_TOOLS_RECLUSTER_HH__
     1#ifndef __FASTJET_CONTRIB_TOOLS_RECLUSTER_HH__
     2#define __FASTJET_CONTRIB_TOOLS_RECLUSTER_HH__
    33
    4 // $Id: Recluster.hh 700 2014-07-07 12:50:05Z gsoyez $
     4// $Id: Recluster.hh 723 2014-07-30 09:11:01Z gsoyez $
    55//
    66// Copyright (c) 2014-, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
     
    181181FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
    182182
    183 #endif   // __FASTJET_TOOLS_RECLUSTER_HH__
     183#endif   // __FASTJET_CONTRIB_TOOLS_RECLUSTER_HH__
  • external/fastjet/contribs/RecursiveTools/RecursiveSymmetryCutBase.cc

    r001ee95 r667a02a  
    1 // $Id: RecursiveSymmetryCutBase.cc 700 2014-07-07 12:50:05Z gsoyez $
     1// $Id: RecursiveSymmetryCutBase.cc 1080 2017-09-28 07:51:37Z gsoyez $
    22//
    33// Copyright (c) 2014-, Gavin P. Salam, Gregory Soyez, Jesse Thaler
     
    2323#include "fastjet/JetDefinition.hh"
    2424#include "fastjet/ClusterSequenceAreaBase.hh"
     25#include <cassert>
    2526#include <algorithm>
    2627#include <cstdlib>
     
    4243PseudoJet RecursiveSymmetryCutBase::result(const PseudoJet & jet) const {
    4344  // construct the input jet (by default, recluster with C/A)
    44 
    4545  if (! jet.has_constituents()){
    4646    throw Error("RecursiveSymmetryCutBase can only be applied to jets with constituents");
    4747  }
    4848
    49   PseudoJet j =
    50     _do_reclustering
    51       ? _recluster ? (*_recluster)(jet)
    52                    : Recluster(cambridge_algorithm, JetDefinition::max_allowable_R)(jet)
    53       : jet;
    54    
    55   // issue a warning if the jet is not obtained through a C/A
    56   // clustering
    57   // if ((! j.has_associated_cluster_sequence()) ||
    58   //     (j.validated_cs()->jet_def().jet_algorithm() != cambridge_algorithm))
    59   //  _nonca_warning.warn("RecursiveSymmetryCutBase is designed to be applied on jets from a Cambridge/Aachen clustering; use it with other algorithms at your own risk.");
    60 
     49  PseudoJet j = _recluster_if_needed(jet);
     50
     51  // sanity check: the jet must have a valid CS
    6152  if (! j.has_valid_cluster_sequence()){
    6253    throw Error("RecursiveSymmetryCutBase can only be applied to jets associated to a (valid) cluster sequence");
    6354  }
    6455
     56  // check that area information is there in case we have a subtractor
     57  // GS: do we really need this since subtraction may not require areas?
    6558  if (_subtractor) {
    6659    const ClusterSequenceAreaBase * csab =
     
    7568    subjet = (*_subtractor)(subjet);
    7669  }
    77 
    78   bool use_mu_cut = (_mu_cut != numeric_limits<double>::infinity());
    7970
    8071  // variables for tracking what will happen
     
    8677  std::vector<double> dropped_symmetry;
    8778  std::vector<double> dropped_mu;
     79
     80  double sym, mu2;
    8881 
    8982  // now recurse into the jet's structure
    90   while (subjet.has_parents(piece1, piece2)) {
    91    
    92     // first sanity check:
    93     // - zero or negative pts are not allowed for the input subjet
    94     // - zero or negative masses are not allowed for configurations
    95     //   in which the mass will effectively appear in a denominator
    96     //   (The masses will be checked later)
    97     if (subjet.pt2() <= 0) return PseudoJet();
    98 
    99     if (_subtractor) {
    100       piece1 = (*_subtractor)(piece1);
    101       piece2 = (*_subtractor)(piece2);
    102     }
    103    
    104     // determine the symmetry parameter
    105     double sym;
    106 
    107     if        (_symmetry_measure == y) {
    108       // the original d_{ij}/m^2 choice from MDT
    109       // first make sure the mass is sensible
    110       if (subjet.m2() <= 0) {
    111         _negative_mass_warning.warn("RecursiveSymmetryCutBase: cannot calculate y, because (sub)jet mass is negative; bailing out");
    112         return _result_no_substructure(subjet); //TBC: do we return the hardest parent? A NULL PseudoJet?
    113       }
    114       sym = piece1.kt_distance(piece2) / subjet.m2();
    115 
    116     } else if (_symmetry_measure == vector_z) {
    117       // min(pt1, pt2)/(pt), where the denominator is a vector sum
    118       // of the two subjets
    119       sym = min(piece1.pt(), piece2.pt()) / subjet.pt();
    120 
    121     } else if (_symmetry_measure == scalar_z) {
    122       // min(pt1, pt2)/(pt1+pt2), where the denominator is a scalar sum
    123       // of the two subjets
    124       double pt1 = piece1.pt();
    125       double pt2 = piece2.pt();
    126       // make sure denominator is non-zero
    127       sym = pt1 + pt2;
    128       if (sym == 0) return PseudoJet();
    129       sym = min(pt1, pt2) / sym;
    130 
    131     } else {
    132       throw Error ("Unrecognized choice of symmetry_measure");
    133     }
    134 
    135     // determine the symmetry cut
    136     // (This function is specified in the derived classes)
    137     double this_symmetry_cut = symmetry_cut_fn(piece1, piece2);
    138 
    139     // and make a first tagging decision based on symmetry cut
    140     bool tagged = (sym > this_symmetry_cut);
    141 
    142     // if tagged based on symmetry cut, then check the mu cut (if relevant)
    143     // and update the tagging decision. Calculate mu^2 regardless, for cases
    144     // of users not cutting on mu2, but still interested in its value.
    145     double mu2 = max(piece1.m2(), piece2.m2())/subjet.m2();
    146     if (tagged && use_mu_cut) {
    147       // first a sanity check -- mu2 won't be sensible if the subjet mass
    148       // is negative, so we can't then trust the mu cut - bail out
    149       if (subjet.m2() <= 0) {
    150         _negative_mass_warning.warn("RecursiveSymmetryCutBase: cannot trust mu, because (sub)jet mass is negative; bailing out");
    151         return PseudoJet();
    152       }
    153       if (mu2 > 1) _mu2_gt1_warning.warn("RecursiveSymmetryCutBase encountered mu^2 value > 1");
    154       if (mu2 > pow(_mu_cut,2)) tagged = false;
    155     }
    156 
    157 
    158     // if we've tagged the splitting, return the jet with its substructure
    159     if (tagged) {
    160       // record relevant information
    161       StructureType * structure = new StructureType(subjet);
    162       structure->_symmetry = sym;
    163       structure->_mu       = (mu2 >= 0) ? sqrt(mu2) : -sqrt(-mu2);
    164       structure->_delta_R  = piece1.delta_R(piece2);
    165       if (_verbose_structure) {
    166         structure->_has_verbose = true;
    167         structure->_dropped_symmetry = dropped_symmetry;
    168         structure->_dropped_mu = dropped_mu;
    169         structure->_dropped_delta_R = dropped_delta_R;
    170       }
    171       subjet.set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>(structure));
    172       return subjet;
    173     }
     83  RecursionStatus status;
     84  while ((status=recurse_one_step(subjet, piece1, piece2, sym, mu2)) != recursion_success) {
     85    // start with sanity checks:
     86    if ((status == recursion_issue) || (status == recursion_no_parents)) {
     87      // we should return piece1 by our convention for recurse_one_step
     88      PseudoJet result;
     89      if (status == recursion_issue){
     90        result = piece1;
     91        if (_verbose) cout << "reached end; returning null jet " << endl;
     92      } else {
     93        result = _result_no_substructure(piece1);
     94        if (_verbose) cout << "no parents found; returning last PJ or empty jet" << endl;
     95      }
     96     
     97      if (result != 0) {
     98        // if in grooming mode, add dummy structure information
     99        StructureType * structure = new StructureType(result);
     100        // structure->_symmetry = 0.0;
     101        // structure->_mu       = 0.0;
     102        // structure->_delta_R  = 0.0;
     103        if (_verbose_structure) { // still want to store verbose information about dropped branches
     104          structure->_has_verbose = true;
     105          structure->_dropped_symmetry = dropped_symmetry;
     106          structure->_dropped_mu = dropped_mu;
     107          structure->_dropped_delta_R = dropped_delta_R;
     108        }
     109        result.set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>(structure));
     110      }
     111 
     112      return result;
     113    }
     114
     115    assert(status == recursion_dropped);
    174116   
    175117    // if desired, store information about dropped branches before recursing
     
    179121      dropped_mu.push_back((mu2 >= 0) ? sqrt(mu2) : -sqrt(-mu2));
    180122    }
    181    
    182     // otherwise continue unclustering, allowing for the different
    183     // ways of choosing which parent to look into
    184     int choice;
    185     if        (_recursion_choice == larger_mt) {
    186       choice = piece1.mt2() > piece2.mt2() ? 1 : 2;
    187 
    188     } else if (_recursion_choice == larger_pt) {
    189       choice = piece1.pt2() > piece2.pt2() ? 1 : 2;
    190 
    191     } else if (_recursion_choice == larger_m)  {
    192       choice = piece1.m2()  > piece2.m2()  ? 1 : 2;
    193 
    194     } else {
    195       throw Error ("Unrecognized value for recursion_choice");
    196     }   
    197     if (_verbose) cout << "choice is " << choice << endl;;
    198     subjet = (choice == 1) ? piece1 : piece2;
    199   } // (subjet.has_parents(...))
    200 
    201   if (_verbose) cout << "reached end; returning null jet " << endl;
    202  
    203   // decide on tagging versus grooming mode here
    204   PseudoJet result = _result_no_substructure(subjet);
    205  
    206   if (result != 0) {
    207     // if in grooming mode, add dummy structure information
    208     StructureType * structure = new StructureType(result);
    209     structure->_symmetry = 0.0;
    210     structure->_mu       = 0.0;
    211     structure->_delta_R  = 0.0;
    212     if (_verbose_structure) { // still want to store verbose information about dropped branches
    213       structure->_has_verbose = true;
    214       structure->_dropped_symmetry = dropped_symmetry;
    215       structure->_dropped_mu = dropped_mu;
    216       structure->_dropped_delta_R = dropped_delta_R;
    217     }
    218     result.set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>(structure));
    219   }
    220  
    221   return result;
    222 }
    223 
    224 
     123
     124    subjet = piece1;
     125  }
     126 
     127
     128  // we've tagged the splitting, return the jet with its substructure
     129  StructureType * structure = new StructureType(subjet);
     130  structure->_symmetry = sym;
     131  structure->_mu       = (mu2 >= 0) ? sqrt(mu2) : -sqrt(-mu2);
     132  structure->_delta_R  = sqrt(squared_geometric_distance(piece1, piece2));
     133  if (_verbose_structure) {
     134    structure->_has_verbose = true;
     135    structure->_dropped_symmetry = dropped_symmetry;
     136    structure->_dropped_mu = dropped_mu;
     137    structure->_dropped_delta_R = dropped_delta_R;
     138  }
     139  subjet.set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>(structure));
     140  return subjet;
     141}
     142
     143
     144 
     145//----------------------------------------------------------------------
     146// the method below is the one actually performing one step of the
     147// recursion.
     148//
     149// It returns a status code (defined above)
     150//
     151// In case of success, all the information is filled
     152// In case of "no parents", piee1 is the same subjet
     153// In case of trouble, piece2 will be a 0 PJ and piece1 is the PJ we
     154//   should return (either 0 itself if the issue was critical, or
     155//   non-wero in case of a minor issue just causing the recursion to
     156//   stop)
     157RecursiveSymmetryCutBase::RecursionStatus
     158      RecursiveSymmetryCutBase::recurse_one_step(const PseudoJet & subjet,
     159                                                 PseudoJet &piece1, PseudoJet &piece2,
     160                                                 double &sym, double &mu2,
     161                                                 void *extra_parameters) const {
     162  if (!subjet.has_parents(piece1, piece2)){
     163    piece1 = subjet;   
     164    piece2 = PseudoJet();
     165    return recursion_no_parents;
     166  }
     167
     168  // first sanity check:
     169  // - zero or negative pts are not allowed for the input subjet
     170  // - zero or negative masses are not allowed for configurations
     171  //   in which the mass will effectively appear in a denominator
     172  //   (The masses will be checked later)
     173  if (subjet.pt2() <= 0){ // this is a critical problem, return an empty PJ
     174    piece1 = piece2 = PseudoJet();
     175    return recursion_issue;
     176  }
     177
     178  if (_subtractor) {
     179    piece1 = (*_subtractor)(piece1);
     180    piece2 = (*_subtractor)(piece2);
     181  }
     182   
     183  // determine the symmetry parameter
     184  if        (_symmetry_measure == y) {
     185    // the original d_{ij}/m^2 choice from MDT
     186    // first make sure the mass is sensible
     187    if (subjet.m2() <= 0) {
     188      _negative_mass_warning.warn("RecursiveSymmetryCutBase: cannot calculate y, because (sub)jet mass is negative; bailing out");
     189      // since rounding errors can give -ve masses, be a it more
     190      // tolerant and consider that no substructure has been found
     191      piece1 = _result_no_substructure(subjet);
     192      piece2 = PseudoJet();
     193      return recursion_issue;
     194    }
     195    sym = piece1.kt_distance(piece2) / subjet.m2();
     196   
     197  } else if (_symmetry_measure == vector_z) {
     198    // min(pt1, pt2)/(pt), where the denominator is a vector sum
     199    // of the two subjets
     200    sym = min(piece1.pt(), piece2.pt()) / subjet.pt();   
     201  } else if (_symmetry_measure == scalar_z) {
     202    // min(pt1, pt2)/(pt1+pt2), where the denominator is a scalar sum
     203    // of the two subjets
     204    double pt1 = piece1.pt();
     205    double pt2 = piece2.pt();
     206    // make sure denominator is non-zero
     207    sym = pt1 + pt2;
     208    if (sym == 0){ // this is a critical problem, return an empty PJ
     209      piece1 = piece2 = PseudoJet();
     210      return recursion_issue;
     211    }
     212    sym = min(pt1, pt2) / sym;
     213  } else if ((_symmetry_measure == theta_E) || (_symmetry_measure == cos_theta_E)){
     214    // min(E1, E2)/(E1+E2)
     215    double E1 = piece1.E();
     216    double E2 = piece2.E();
     217    // make sure denominator is non-zero
     218    sym = E1 + E2;
     219    if (sym == 0){ // this is a critical problem, return an empty PJ
     220      piece1 = piece2 = PseudoJet();
     221      return recursion_issue;
     222    }
     223    sym = min(E1, E2) / sym;
     224  } else {
     225    throw Error ("Unrecognized choice of symmetry_measure");
     226  }
     227 
     228  // determine the symmetry cut
     229  // (This function is specified in the derived classes)
     230  double this_symmetry_cut = symmetry_cut_fn(piece1, piece2, extra_parameters);
     231 
     232  // and make a first tagging decision based on symmetry cut
     233  bool tagged = (sym > this_symmetry_cut);
     234
     235  // if tagged based on symmetry cut, then check the mu cut (if relevant)
     236  // and update the tagging decision. Calculate mu^2 regardless, for cases
     237  // of users not cutting on mu2, but still interested in its value.
     238  bool use_mu_cut = (_mu_cut != numeric_limits<double>::infinity());
     239  mu2 = max(piece1.m2(), piece2.m2())/subjet.m2();
     240  if (tagged && use_mu_cut) {
     241    // first a sanity check -- mu2 won't be sensible if the subjet mass
     242    // is negative, so we can't then trust the mu cut - bail out
     243    if (subjet.m2() <= 0) {
     244      _negative_mass_warning.warn("RecursiveSymmetryCutBase: cannot trust mu, because (sub)jet mass is negative; bailing out");
     245      piece1 = piece2 = PseudoJet();
     246      return recursion_issue;
     247    }
     248    if (mu2 > 1) _mu2_gt1_warning.warn("RecursiveSymmetryCutBase encountered mu^2 value > 1");
     249    if (mu2 > pow(_mu_cut,2)) tagged = false;
     250  }
     251
     252  // we'll continue unclustering, allowing for the different
     253  // ways of choosing which parent to look into
     254  if        (_recursion_choice == larger_pt) {
     255    if (piece1.pt2() < piece2.pt2()) std::swap(piece1, piece2);   
     256  } else if (_recursion_choice == larger_mt) {
     257    if (piece1.mt2() < piece2.mt2()) std::swap(piece1, piece2);   
     258  } else if (_recursion_choice == larger_m)  {
     259    if (piece1.m2() < piece2.m2()) std::swap(piece1, piece2);   
     260  } else if (_recursion_choice == larger_E)  {
     261    if (piece1.E()  < piece2.E())  std::swap(piece1, piece2);   
     262  } else {
     263    throw Error ("Unrecognized value for recursion_choice");
     264  }   
     265
     266  return tagged ? recursion_success : recursion_dropped;
     267}
     268
     269 
    225270//----------------------------------------------------------------------
    226271string RecursiveSymmetryCutBase::description() const {
     
    235280  case vector_z:
    236281    ostr << "vector_z"; break;
     282  case theta_E:
     283    ostr << "theta_E"; break;
     284  case cos_theta_E:
     285    ostr << "cos_theta_E"; break;
    237286  default:
    238287    cerr << "failed to interpret symmetry_measure" << endl; exit(-1);
     
    254303  case larger_m:
    255304    ostr << "mass"; break;
     305  case larger_E:
     306    ostr << "energy"; break;
    256307  default:
    257308    cerr << "failed to interpret recursion_choice" << endl; exit(-1);
     
    259310
    260311  if (_subtractor) {
    261     ostr << " and subtractor: " << _subtractor->description();
     312    ostr << ", subtractor: " << _subtractor->description();
    262313    if (_input_jet_is_subtracted) {ostr << " (input jet is assumed already subtracted)";}
    263314  }
     315
     316  if (_recluster) {
     317    ostr << " and reclustering using " << _recluster->description();
     318  }
     319 
    264320  return ostr.str();
    265321}
    266322
     323//----------------------------------------------------------------------
     324// helper for handling the reclustering
     325PseudoJet RecursiveSymmetryCutBase::_recluster_if_needed(const PseudoJet &jet) const{
     326  if (! _do_reclustering) return jet;
     327  if (_recluster) return (*_recluster)(jet);
     328  if (is_ee()){
     329#if FASTJET_VERSION_NUMBER >= 30100
     330    return Recluster(JetDefinition(ee_genkt_algorithm, JetDefinition::max_allowable_R, 0.0), true)(jet);
     331#else
     332    return Recluster(JetDefinition(ee_genkt_algorithm, JetDefinition::max_allowable_R, 0.0))(jet);
     333#endif
     334  }
     335
     336  return Recluster(cambridge_algorithm, JetDefinition::max_allowable_R)(jet);
     337
     338 
     339//----------------------------------------------------------------------
    267340// decide what to return when no substructure has been found
     341double RecursiveSymmetryCutBase::squared_geometric_distance(const PseudoJet &j1,
     342                                                            const PseudoJet &j2) const{
     343  if (_symmetry_measure == theta_E){
     344    double dot_3d = j1.px()*j2.px() + j1.py()*j2.py() + j1.pz()*j2.pz();
     345    double cos_theta = max(-1.0,min(1.0, dot_3d/sqrt(j1.modp2()*j2.modp2())));
     346    double theta = acos(cos_theta);
     347    return theta*theta;
     348  } else if (_symmetry_measure == cos_theta_E){
     349    double dot_3d = j1.px()*j2.px() + j1.py()*j2.py() + j1.pz()*j2.pz();
     350    return max(0.0, 2*(1-dot_3d/sqrt(j1.modp2()*j2.modp2())));
     351  }
     352
     353  return j1.squared_distance(j2);
     354}
     355
     356//----------------------------------------------------------------------
    268357PseudoJet RecursiveSymmetryCutBase::_result_no_substructure(const PseudoJet &last_parent) const{
    269358  if (_grooming_mode){
     
    277366
    278367
     368//========================================================================
     369// implementation of the details of the structure
     370 
     371// the number of dropped subjets
     372int RecursiveSymmetryCutBase::StructureType::dropped_count(bool global) const {
     373  check_verbose("dropped_count()");
     374
     375  // if this jet has no substructure, just return an empty vector
     376  if (!has_substructure()) return _dropped_delta_R.size();
     377
     378  // deal with the non-global case
     379  if (!global) return _dropped_delta_R.size();
     380
     381  // for the global case, we've unfolded the recursion (likely more
     382  // efficient as it requires less copying)
     383  unsigned int count = 0;
     384  vector<const RecursiveSymmetryCutBase::StructureType*> to_parse;
     385  to_parse.push_back(this);
     386
     387  unsigned int i_parse = 0;
     388  while (i_parse<to_parse.size()){
     389    const RecursiveSymmetryCutBase::StructureType *current = to_parse[i_parse];
     390    count += current->_dropped_delta_R.size();
     391
     392    // check if we need to recurse deeper in the substructure
     393    //
     394    // we can have 2 situations here for the underlying structure (the
     395    // one we've wrapped around):
     396    //  - it's of the clustering type
     397    //  - it's a composite jet
     398    // only in the 2nd case do we have to recurse deeper
     399    const CompositeJetStructure *css = dynamic_cast<const CompositeJetStructure*>(current->_structure.get());
     400    if (css == 0){ ++i_parse; continue; }
     401   
     402    vector<PseudoJet> prongs = css->pieces(PseudoJet()); // argument irrelevant
     403    assert(prongs.size() == 2);
     404    for (unsigned int i_prong=0; i_prong<2; ++i_prong){
     405      if (prongs[i_prong].has_structure_of<RecursiveSymmetryCutBase>()){
     406        RecursiveSymmetryCutBase::StructureType* prong_structure
     407          = (RecursiveSymmetryCutBase::StructureType*) prongs[i_prong].structure_ptr();
     408        if (prong_structure->has_substructure())
     409          to_parse.push_back(prong_structure);
     410      }
     411    }
     412
     413    ++i_parse;
     414  }
     415  return count;
     416}
     417
     418// the delta_R of all the dropped subjets
     419vector<double> RecursiveSymmetryCutBase::StructureType::dropped_delta_R(bool global) const {
     420  check_verbose("dropped_delta_R()");
     421
     422  // if this jet has no substructure, just return an empty vector
     423  if (!has_substructure()) return vector<double>();
     424
     425  // deal with the non-global case
     426  if (!global) return _dropped_delta_R;
     427
     428  // for the global case, we've unfolded the recursion (likely more
     429  // efficient as it requires less copying)
     430  vector<double> all_dropped;
     431  vector<const RecursiveSymmetryCutBase::StructureType*> to_parse;
     432  to_parse.push_back(this);
     433
     434  unsigned int i_parse = 0;
     435  while (i_parse<to_parse.size()){
     436    const RecursiveSymmetryCutBase::StructureType *current = to_parse[i_parse];
     437    all_dropped.insert(all_dropped.end(), current->_dropped_delta_R.begin(), current->_dropped_delta_R.end());
     438
     439    // check if we need to recurse deeper in the substructure
     440    //
     441    // we can have 2 situations here for the underlying structure (the
     442    // one we've wrapped around):
     443    //  - it's of the clustering type
     444    //  - it's a composite jet
     445    // only in the 2nd case do we have to recurse deeper
     446    const CompositeJetStructure *css = dynamic_cast<const CompositeJetStructure*>(current->_structure.get());
     447    if (css == 0){ ++i_parse; continue; }
     448   
     449    vector<PseudoJet> prongs = css->pieces(PseudoJet()); // argument irrelevant
     450    assert(prongs.size() == 2);
     451    for (unsigned int i_prong=0; i_prong<2; ++i_prong){
     452      if (prongs[i_prong].has_structure_of<RecursiveSymmetryCutBase>()){
     453        RecursiveSymmetryCutBase::StructureType* prong_structure
     454          = (RecursiveSymmetryCutBase::StructureType*) prongs[i_prong].structure_ptr();
     455        if (prong_structure->has_substructure())
     456          to_parse.push_back(prong_structure);
     457      }
     458    }
     459
     460    ++i_parse;
     461  }
     462  return all_dropped;
     463}
     464
     465// the symmetry of all the dropped subjets
     466vector<double> RecursiveSymmetryCutBase::StructureType::dropped_symmetry(bool global) const {
     467  check_verbose("dropped_symmetry()");
     468
     469  // if this jet has no substructure, just return an empty vector
     470  if (!has_substructure()) return vector<double>();
     471
     472  // deal with the non-global case
     473  if (!global) return _dropped_symmetry;
     474
     475  // for the global case, we've unfolded the recursion (likely more
     476  // efficient as it requires less copying)
     477  vector<double> all_dropped;
     478  vector<const RecursiveSymmetryCutBase::StructureType*> to_parse;
     479  to_parse.push_back(this);
     480
     481  unsigned int i_parse = 0;
     482  while (i_parse<to_parse.size()){
     483    const RecursiveSymmetryCutBase::StructureType *current = to_parse[i_parse];
     484    all_dropped.insert(all_dropped.end(), current->_dropped_symmetry.begin(), current->_dropped_symmetry.end());
     485
     486    // check if we need to recurse deeper in the substructure
     487    //
     488    // we can have 2 situations here for the underlying structure (the
     489    // one we've wrapped around):
     490    //  - it's of the clustering type
     491    //  - it's a composite jet
     492    // only in the 2nd case do we have to recurse deeper
     493    const CompositeJetStructure *css = dynamic_cast<const CompositeJetStructure*>(current->_structure.get());
     494    if (css == 0){ ++i_parse; continue; }
     495   
     496    vector<PseudoJet> prongs = css->pieces(PseudoJet()); // argument irrelevant
     497    assert(prongs.size() == 2);
     498    for (unsigned int i_prong=0; i_prong<2; ++i_prong){
     499      if (prongs[i_prong].has_structure_of<RecursiveSymmetryCutBase>()){
     500        RecursiveSymmetryCutBase::StructureType* prong_structure
     501          = (RecursiveSymmetryCutBase::StructureType*) prongs[i_prong].structure_ptr();
     502        if (prong_structure->has_substructure())
     503          to_parse.push_back(prong_structure);
     504      }
     505    }
     506
     507    ++i_parse;
     508  }
     509  return all_dropped;
     510}
     511
     512// the mu of all the dropped subjets
     513vector<double> RecursiveSymmetryCutBase::StructureType::dropped_mu(bool global) const {
     514  check_verbose("dropped_mu()");
     515
     516  // if this jet has no substructure, just return an empty vector
     517  if (!has_substructure()) return vector<double>();
     518
     519  // deal with the non-global case
     520  if (!global) return _dropped_mu;
     521
     522  // for the global case, we've unfolded the recursion (likely more
     523  // efficient as it requires less copying)
     524  vector<double> all_dropped;
     525  vector<const RecursiveSymmetryCutBase::StructureType*> to_parse;
     526  to_parse.push_back(this);
     527
     528  unsigned int i_parse = 0;
     529  while (i_parse<to_parse.size()){
     530    const RecursiveSymmetryCutBase::StructureType *current = to_parse[i_parse];
     531    all_dropped.insert(all_dropped.end(), current->_dropped_mu.begin(), current->_dropped_mu.end());
     532
     533    // check if we need to recurse deeper in the substructure
     534    //
     535    // we can have 2 situations here for the underlying structure (the
     536    // one we've wrapped around):
     537    //  - it's of the clustering type
     538    //  - it's a composite jet
     539    // only in the 2nd case do we have to recurse deeper
     540    const CompositeJetStructure *css = dynamic_cast<const CompositeJetStructure*>(current->_structure.get());
     541    if (css == 0){ ++i_parse; continue; }
     542   
     543    vector<PseudoJet> prongs = css->pieces(PseudoJet()); // argument irrelevant
     544    assert(prongs.size() == 2);
     545    for (unsigned int i_prong=0; i_prong<2; ++i_prong){
     546      if (prongs[i_prong].has_structure_of<RecursiveSymmetryCutBase>()){
     547        RecursiveSymmetryCutBase::StructureType* prong_structure
     548          = (RecursiveSymmetryCutBase::StructureType*) prongs[i_prong].structure_ptr();
     549        if (prong_structure->has_substructure())
     550          to_parse.push_back(prong_structure);
     551      }
     552    }
     553
     554    ++i_parse;
     555  }
     556  return all_dropped;
     557}
     558
     559// the maximum of the symmetry over the dropped subjets
     560double RecursiveSymmetryCutBase::StructureType::max_dropped_symmetry(bool global) const {
     561  check_verbose("max_dropped_symmetry()");
     562
     563  // if there is no substructure, just exit
     564  if (!has_substructure()){ return 0.0; }
     565
     566  // local value of the max_dropped_symmetry
     567  double local_max = (_dropped_symmetry.size() == 0)
     568    ? 0.0 : *max_element(_dropped_symmetry.begin(),_dropped_symmetry.end());
     569
     570  // recurse down the structure if instructed to do so
     571  if (global){
     572    // we can have 2 situations here for the underlying structure (the
     573    // one we've wrapped around):
     574    //  - it's of the clustering type
     575    //  - it's a composite jet
     576    // only in the 2nd case do we have to recurse deeper
     577    const CompositeJetStructure *css = dynamic_cast<const CompositeJetStructure*>(_structure.get());
     578    if (css == 0) return local_max;
     579   
     580    vector<PseudoJet> prongs = css->pieces(PseudoJet()); // argument irrelevant
     581    assert(prongs.size() == 2);
     582    for (unsigned int i_prong=0; i_prong<2; ++i_prong){
     583      // check if the prong has further substructure
     584      if (prongs[i_prong].has_structure_of<RecursiveSymmetryCutBase>()){
     585        RecursiveSymmetryCutBase::StructureType* prong_structure
     586          = (RecursiveSymmetryCutBase::StructureType*) prongs[i_prong].structure_ptr();
     587        local_max = max(local_max, prong_structure->max_dropped_symmetry(true));
     588      }
     589    }
     590  }
     591
     592  return local_max;
     593}
     594
     595//------------------------------------------------------------------------
     596// helper class to sort by decreasing thetag
     597class SortRecursiveSoftDropStructureZgThetagPair{
     598public:
     599  bool operator()(const pair<double, double> &p1, const pair<double, double> &p2) const{
     600    return p1.second > p2.second;
     601  }
     602};
     603//------------------------------------------------------------------------
     604
     605// the (zg,thetag) pairs of all the splitting that were found and passed the SD condition
     606vector<pair<double,double> > RecursiveSymmetryCutBase::StructureType::sorted_zg_and_thetag() const {
     607  //check_verbose("sorted_zg_and_thetag()");
     608
     609  // if this jet has no substructure, just return an empty vector
     610  if (!has_substructure()) return vector<pair<double,double> >();
     611 
     612  // otherwise fill a vector with all the prongs (no specific ordering)
     613  vector<pair<double,double> > all;
     614  vector<const RecursiveSymmetryCutBase::StructureType*> to_parse;
     615  to_parse.push_back(this);
     616
     617  unsigned int i_parse = 0;
     618  while (i_parse<to_parse.size()){
     619    const RecursiveSymmetryCutBase::StructureType *current = to_parse[i_parse];
     620    all.push_back(pair<double,double>(current->_symmetry, current->_delta_R));
     621
     622    vector<PseudoJet> prongs = current->pieces(PseudoJet());
     623    assert(prongs.size() == 2);
     624    for (unsigned int i_prong=0; i_prong<2; ++i_prong){
     625      if (prongs[i_prong].has_structure_of<RecursiveSymmetryCutBase>()){
     626        RecursiveSymmetryCutBase::StructureType* prong_structure
     627          = (RecursiveSymmetryCutBase::StructureType*) prongs[i_prong].structure_ptr();
     628        if (prong_structure->has_substructure())
     629          to_parse.push_back(prong_structure);
     630      }
     631    }
     632
     633    ++i_parse;
     634  }
     635
     636  sort(all.begin(), all.end(), SortRecursiveSoftDropStructureZgThetagPair());
     637  return all;
     638}
     639
    279640} // namespace contrib
    280641
  • external/fastjet/contribs/RecursiveTools/RecursiveSymmetryCutBase.hh

    r001ee95 r667a02a  
    1 // $Id: RecursiveSymmetryCutBase.hh 700 2014-07-07 12:50:05Z gsoyez $
     1// $Id: RecursiveSymmetryCutBase.hh 1074 2017-09-18 15:15:20Z gsoyez $
    22//
    33// Copyright (c) 2014-, Gavin P. Salam, Gregory Soyez, Jesse Thaler
     
    2424
    2525#include <limits>
     26#include <cassert>
    2627#include <fastjet/internal/base.hh>
    2728#include "fastjet/tools/Transformer.hh"
    2829#include "fastjet/WrappedStructure.hh"
    29 
     30#include "fastjet/CompositeJetStructure.hh"
     31
     32#include "fastjet/config.h"
     33
     34// we'll use the native FJ class for reculstering if available
     35#if FASTJET_VERSION_NUMBER >= 30100
     36#include "fastjet/tools/Recluster.hh"
     37#else
    3038#include "Recluster.hh"
     39#endif
    3140
    3241/** \mainpage RecursiveTools contrib
    3342
    34     The aims RecursiveTools contrib to provide a set of tools for
    35     recursive investigation of the substructure of jets.
    36 
    37     Currently it includes:
     43    The RecursiveTools contrib provides a set of tools for
     44    recursive investigation jet substructure. Currently it includes:
    3845    - fastjet::contrib::ModifiedMassDropTagger
    3946    - fastjet::contrib::SoftDrop
    40     - the two above classes derive from fastjet::contrib::RecursiveSymmetryCutBase
    41     - fastjet::contrib::Recluster provides a reclustering transformer
    42     - example*.cc provides a usage examples
     47    - fastjet::contrib::RecursiveSymmetryCutBase (from which the above two classes derive)
     48    - fastjet::contrib::IteratedSoftDropSymmetryFactors (defines ISD procedure)
     49    - fastjet::contrib::IteratedSoftDropMultiplicity (defines a useful observable using ISD) 
     50    - example*.cc provides usage examples
    4351 */
    4452
     
    7886
    7987  /// an enum of the different (a)symmetry measures that can be used
    80   enum SymmetryMeasure{scalar_z, ///< \f$ \min(p_{ti}, p_{tj})/(p_{ti} + p_{tj}) \f$
    81                        vector_z, ///< \f$ \min(p_{ti}, p_{tj})/p_{t(i+j)} \f$
    82                        y         ///  \f$ \min(p_{ti}^2,p_{tj}^2) \Delta R_{ij}^2 / m_{ij}^2 \f$
    83                        
     88  enum SymmetryMeasure{scalar_z,   ///< \f$ \min(p_{ti}, p_{tj})/(p_{ti} + p_{tj}) \f$
     89                       vector_z,   ///< \f$ \min(p_{ti}, p_{tj})/p_{t(i+j)} \f$
     90                       y,          ///< \f$ \min(p_{ti}^2,p_{tj}^2) \Delta R_{ij}^2 / m_{ij}^2 \f$
     91                       theta_E,    ///< \f$ \min(E_i,E_j)/(E_i+E_j) \f$ with 3d angle (ee collisions)
     92                       cos_theta_E ///< \f$ \min(E_i,E_j)/(E_i+E_j) \f$ with
     93                                   ///  \f$ \sqrt{2[1-cos(theta)]}\f$ for angles (ee collisions)
    8494  };
    8595
     
    8797  enum RecursionChoice{larger_pt, ///< choose the subjet with larger \f$ p_t \f$
    8898                       larger_mt, ///< choose the subjet with larger \f$ m_t \equiv (m^2+p_t^2)^{\frac12}] \f$
    89                        larger_m   ///  choose the subjet with larger mass (deprecated)
     99                       larger_m,  ///< choose the subjet with larger mass (deprecated)
     100                       larger_E   ///< choose the subjet with larger energy (meant for ee collisions)
    90101  };
    91102
     
    119130  virtual ~RecursiveSymmetryCutBase(){}
    120131
     132  // access to class info
     133  //----------------------------------------------------------------------
     134  SymmetryMeasure symmetry_measure() const { return _symmetry_measure; }
     135  double mu_cut() const { return _mu_cut; }
     136  RecursionChoice recursion_choice() const { return _recursion_choice; }
     137
    121138  // internal subtraction configuration
    122139  //----------------------------------------------------------------------
     
    147164  //----------------------------------------------------------------------
    148165
    149   /// configure the reclustering prior to the SoftDrop de-clustering
     166  /// configure the reclustering prior to the recursive de-clustering
    150167  ///  \param do_reclustering   recluster the jet or not?
    151168  ///  \param recluster         how to recluster the jet
     
    174191  /// in particular values of symmetry, delta_R, and mu of dropped branches
    175192  void set_verbose_structure(bool enable=true) { _verbose_structure = enable; }
     193  bool has_verbose_structure() const { return _verbose_structure; }
    176194 
    177195 
     
    185203  /// subtracted jet.
    186204  virtual PseudoJet result(const PseudoJet & j) const;
    187 
     205 
    188206  /// description of the tool
    189207  virtual std::string description() const;
    190208
    191   /// the type of the associated structure
    192   //typedef RecursiveSymmetryCutBaseStructure StructureType; 
     209  /// returns the gepometrical distance between the two particles
     210  /// depending on the symmetry measure used
     211  double squared_geometric_distance(const PseudoJet &j1,
     212                                    const PseudoJet &j2) const;
     213 
    193214
    194215  class StructureType;
     
    203224  /// apply for a given pair of subjets p1 and p2
    204225  virtual double symmetry_cut_fn(const PseudoJet & /* p1 */,
    205                                  const PseudoJet & /* p2 */) const = 0;
     226                                 const PseudoJet & /* p2 */,
     227                                 void *extra_parameters = 0) const = 0;
    206228  /// the associated dwescription
    207229  virtual std::string symmetry_cut_description() const = 0;
     230
     231  //----------------------------------------------------------------------
     232  /// this defines status codes when checking for substructure
     233  enum RecursionStatus{
     234    recursion_success=0,   //< found some substructure
     235    recursion_dropped,     //< dropped softest prong; recursion continues
     236    recursion_no_parents,  //< down to constituents; bottom of recursion
     237    recursion_issue        //< something went wrong; recursion stops
     238  };
     239 
     240  //----------------------------------------------------------------------
     241  /// the method below is the one actually performing one step of the
     242  /// recursion.
     243  ///
     244  /// It returns a status code (defined above)
     245  ///
     246  /// In case of success, all the information is filled
     247  /// In case of "no parents", piee1 is the same subjet
     248  /// In case of trouble, piece2 will be a 0 PJ and piece1 is the PJ we
     249  ///   should return (either 0 itself if the issue was critical, or
     250  ///   non-wero in case of a minor issue just causing the recursion to
     251  ///   stop)
     252  ///
     253  /// The extra_parameter argument allows one to pass extra agruments
     254  /// to the symmetry condition
     255  RecursionStatus recurse_one_step(const PseudoJet & subjet,
     256                                   PseudoJet &piece1, PseudoJet &piece2,
     257                                   double &sym, double &mu2,
     258                                   void *extra_parameters = 0) const;
     259
     260  //----------------------------------------------------------------------
     261  /// helper for handling the reclustering
     262  PseudoJet _recluster_if_needed(const PseudoJet &jet) const;
     263 
     264  //----------------------------------------------------------------------
     265  // helpers for selecting between ee and pp cases
     266  bool is_ee() const{
     267    return ((_symmetry_measure==theta_E) || (_symmetry_measure==cos_theta_E));
     268  }
    208269
    209270private:
     
    238299public:
    239300  StructureType(const PseudoJet & j) :
    240     WrappedStructure(j.structure_shared_ptr()),
     301    WrappedStructure(j.structure_shared_ptr()), _delta_R(-1.0), _symmetry(-1.0), _mu(-1.0),
     302    _is_composite(false), _has_verbose(false) // by default, do not store verbose structure
     303  {}
     304
     305  /// construct a structure with
     306  ///  - basic info inherited from the reference jet "j"
     307  ///  - a given deltaR       for substructure
     308  ///  - a given symmetry     for substructure
     309  ///  - a given mu parameter for substructure
     310  /// If j is a "copmposite jet", it means that it has further
     311  /// substructure to potentially recurse  into
     312  StructureType(const PseudoJet & j, double delta_R_in, double symmetry_in, double mu_in=-1.0) :
     313    WrappedStructure(j.structure_shared_ptr()), _delta_R(delta_R_in), _symmetry(symmetry_in), _mu(mu_in),
     314    _is_composite(dynamic_cast<const CompositeJetStructure*>(j.structure_ptr()) != NULL),
    241315    _has_verbose(false) // by default, do not store verbose structure
    242316  {}
    243317 
    244318  // information about kept branch
    245   double delta_R()  const {return _delta_R;};
    246   double symmetry() const {return _symmetry;};
    247   double mu()       const {return _mu;};
     319  double delta_R()  const {return _delta_R;}
     320  double thetag()   const {return _delta_R;}  // alternative name
     321  double symmetry() const {return _symmetry;}
     322  double zg()       const {return _symmetry;} // alternative name
     323  double mu()       const {return _mu;}
    248324 
    249325  // additional verbose information about dropped branches
    250326  bool has_verbose() const { return _has_verbose;}
    251  
    252   // number of dropped branches
    253   int dropped_count() const {
    254     if (!_has_verbose) throw Error("RecursiveSymmetryCutBase::StructureType: Verbose structure must be turned on to get dropped_count() values.");
    255     return _dropped_delta_R.size();
    256   }
    257  
    258   // delta_R of dropped branches
    259   std::vector<double> dropped_delta_R() const {
    260     if (!_has_verbose) throw Error("RecursiveSymmetryCutBase::StructureType: Verbose structure must be turned on to get dropped_delta_R() values.");
    261     return _dropped_delta_R;
    262   }
    263 
    264   // symmetry values of dropped branches
    265   std::vector<double> dropped_symmetry() const {
    266     if (!_has_verbose) throw Error("RecursiveSymmetryCutBase::StructureType: Verbose structure must be turned on to get dropped_symmetry() values.");
    267     return _dropped_symmetry;
    268   }
    269 
    270   // mass drop values of dropped branches
    271   std::vector<double> dropped_mu() const {
    272     if (!_has_verbose) throw Error("RecursiveSymmetryCutBase::StructureType: Verbose structure must be turned on to get dropped_mu() values.");
    273     return _dropped_mu;
    274   }
    275  
    276   // maximum symmetry value dropped
    277   double max_dropped_symmetry() const {
    278     if (!_has_verbose) throw Error("RecursiveSymmetryCutBase::StructureType: Verbose structure must be turned on to get max_dropped_symmetry().");
    279     if (_dropped_symmetry.size() == 0) return 0.0;
    280     return *std::max_element(_dropped_symmetry.begin(),_dropped_symmetry.end());
    281   }
    282  
     327  void set_verbose(bool value) { _has_verbose = value;}
     328
     329  /// returns true if the current jet has some substructure (i.e. has
     330  /// been tagged by the resursion) or not
     331  ///
     332  /// Note that this should include deltaR==0 (e.g. a perfectly
     333  /// collinear branching with SoftDrop)
     334  bool has_substructure() const { return _delta_R>=0; }
     335 
     336  /// number of dropped branches
     337  int dropped_count(bool global=true) const;
     338 
     339  /// delta_R of dropped branches
     340  /// when "global" is set, recurse into possile further substructure
     341  std::vector<double> dropped_delta_R(bool global=true) const;
     342  void set_dropped_delta_R(const std::vector<double> &v) { _dropped_delta_R = v; }
     343
     344  /// symmetry values of dropped branches
     345  std::vector<double> dropped_symmetry(bool global=true) const;
     346  void set_dropped_symmetry(const std::vector<double> &v) { _dropped_symmetry = v; }
     347
     348  /// mass drop values of dropped branches
     349  std::vector<double> dropped_mu(bool global=true) const;
     350  void set_dropped_mu(const std::vector<double> &v) { _dropped_mu = v; }
     351 
     352  /// maximum symmetry value dropped
     353  double max_dropped_symmetry(bool global=true) const;
     354
     355  /// (global) list of groomed away elements as zg and thetag
     356  /// sorted from largest to smallest anlge
     357  std::vector<std::pair<double,double> > sorted_zg_and_thetag() const;
     358
    283359private:
    284360  double _delta_R, _symmetry, _mu;
    285361  friend class RecursiveSymmetryCutBase;
    286362
     363  bool _is_composite;
     364 
    287365  // additional verbose information
    288366  bool _has_verbose;
     
    291369  std::vector<double> _dropped_symmetry;
    292370  std::vector<double> _dropped_mu;
     371
     372  bool check_verbose(const std::string &what) const{
     373    if (!_has_verbose){
     374      throw Error("RecursiveSymmetryCutBase::StructureType: Verbose structure must be turned on to get "+what+".");
     375      return false;
     376    }
     377    return true;
     378  }
     379   
    293380 
    294381};
  • external/fastjet/contribs/RecursiveTools/SoftDrop.cc

    r001ee95 r667a02a  
    1 // $Id: SoftDrop.cc 686 2014-06-14 03:25:09Z jthaler $
     1// $Id: SoftDrop.cc 1059 2017-09-07 20:48:00Z gsoyez $
    22//
    33// Copyright (c) 2014-, Gregory Soyez, Jesse. Thaler
     
    5757//----------------------------------------------------------------------
    5858double SoftDrop::symmetry_cut_fn(const PseudoJet & p1,
    59                                  const PseudoJet & p2) const{
    60   return _symmetry_cut * pow(p1.squared_distance(p2)/_R0sqr, 0.5*_beta);
     59                                 const PseudoJet & p2,
     60                                 void *optional_R0sqr_ptr) const{
     61  double R0sqr = (optional_R0sqr_ptr == 0) ? _R0sqr : *((double*) optional_R0sqr_ptr);
     62  return _symmetry_cut * pow(squared_geometric_distance(p1,p2)/R0sqr, 0.5*_beta);
    6163}
    6264
  • external/fastjet/contribs/RecursiveTools/SoftDrop.hh

    r001ee95 r667a02a  
    1 // $Id: SoftDrop.hh 686 2014-06-14 03:25:09Z jthaler $
     1// $Id: SoftDrop.hh 1034 2017-08-01 10:03:53Z gsoyez $
    22//
    33// Copyright (c) 2014-, Gregory Soyez, Jesse Thaler
     
    112112     RecursiveSymmetryCutBase(symmetry_measure, mu_cut, recursion_choice, subtractor),
    113113     _beta(beta), _symmetry_cut(symmetry_cut), _R0sqr(R0*R0)
    114   {}
     114  {
     115    // change the default: use grooming mode
     116    set_grooming_mode();
     117  }
    115118
    116119  /// default destructor
    117120  virtual ~SoftDrop(){}
    118121
     122  //----------------------------------------------------------------------
     123  // access to class info
     124  double beta()         const { return _beta; }
     125  double symmetry_cut() const { return _symmetry_cut; }
     126  double R0()           const { return sqrt(_R0sqr); }
     127 
    119128protected:
    120129
    121130  // Unlike MMDT, the SoftDrop symmetry_cut_fn depends on the subjet kinematics
    122131  // since the symmetry condition depends on the DeltaR between subjets.
    123   virtual double symmetry_cut_fn(const PseudoJet & /* p1 */,
    124                                  const PseudoJet & /* p2 */) const;
     132  virtual double symmetry_cut_fn(const PseudoJet & p1,
     133                                 const PseudoJet & p2,
     134                                 void * optional_R0sqr_ptr = 0) const;
    125135  virtual std::string symmetry_cut_description() const;
    126136
    127 private:
     137  //private:
    128138  double _beta;         ///< the power of the angular distance to be used
    129139                        ///< in the symmetry condition
  • external/fastjet/contribs/RecursiveTools/TODO

    r001ee95 r667a02a  
     1For v2.0
     2--------
     3
     4- CHECK: lines 100-102 of RecursiveSymmetryCutBase.hh: this was
     5  initially setting the structure members to 0. I think it's highly
     6  preferable to set them to their default of -1, signalling the
     7  absence of substructure. [0 dR might happen with a perfectly
     8  collinear splitting]
     9
     10- CHECK: are we happy with how the structure info is stored and the
     11  recursive_soft_drop_prongs(...) function in RecursiveSoftDrop.hh?
     12
     13- QUESTION: do we move set_min_deltaR_squared in the base class?
     14
     15- Add option to define z wrt to original jet?
     16
    117For future releases?
    218--------------------
     
    723  auto-indenting. [Consider this for the full contrib??]
    824- More generic kinematic cuts?
     25- KZ: common base class for IteratedSoftDrop and RecursiveSoftDrop?
     26- KZ: make IteratedSoftDrop use Recluster
  • external/fastjet/contribs/RecursiveTools/VERSION

    r001ee95 r667a02a  
    1 1.0.0
     12.0.0-beta2
Note: See TracChangeset for help on using the changeset viewer.