Changeset b7b836a in git for external/fastjet/contribs/RecursiveTools
- Timestamp:
- Jun 6, 2018, 10:05:10 PM (7 years ago)
- Branches:
- ImprovedOutputFile, Timing, dual_readout, llp, master
- Children:
- 17d0ab8
- Parents:
- 95e6b7a
- Location:
- external/fastjet/contribs/RecursiveTools
- Files:
-
- 6 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
external/fastjet/contribs/RecursiveTools/AUTHORS
r95e6b7a rb7b836a 4 4 Gregory Soyez <soyez@fastjet.fr> 5 5 Jesse Thaler <jthaler@jthaler.net> 6 Kevin Zhou <knzhou@mit.edu> 7 Frederic Dreyer <fdreyer@mit.edu> 6 8 7 9 The physics is based on: … … 16 18 Andrew J. Larkoski, Simone Marzani, Gregory Soyez, and Jesse Thaler. 17 19 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
r95e6b7a rb7b836a 14 14 arXiv:1307.0007 15 15 arXiv:1402.2657 16 arXiv:1704.06266 16 17 17 18 ====================================================================== -
external/fastjet/contribs/RecursiveTools/ChangeLog
r95e6b7a rb7b836a 1 2018-05-29 Jesse Thaler <jthaler@jthaler.net> 2 3 * VERSION 4 * NEWS 5 Changed to 2.0.0-beta2, noted in news 6 7 2018-04-21 Jesse Thaler <jthaler@jthaler.net> 8 9 * AUTHORS: updated arxiv number for RecursiveSoftDrop 10 11 2018-04-21 Gavin Salam <gavin.salam@cern.ch> 12 13 * README: updated arxiv number for RecursiveSoftDrop & Bottom-up 14 Soft Drop. 15 16 2018-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 22 2018-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 28 2017-10-10 Jesse Thaler <jthaler@jthaler.net> 29 * AUTHORS 30 Added mention of BUSD 31 32 * README 33 Some tweaks to the wording 34 35 2017-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 41 2017-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 54 2017-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 80 2017-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 91 2017-09-19 Gregory Soyez <soyez@fastjet.fr> 92 93 * example_isd.ref: 94 updated to the latest version of the example 95 96 2017-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 146 2017-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 158 2017-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 164 2017-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 191 2017-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 196 2017-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 219 2017-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 245 2017-08-10 Gregory Soyez <soyez@fastjet.fr> 246 247 * RecursiveSoftDrop.cc: 248 fixed trivial typo in variable name 249 250 >>>>>>> .r1071 251 2017-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 256 2017-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 281 2017-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 301 2017-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 311 2017-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 335 2017-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 343 2017-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 360 2017-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 391 2014-07-30 Gregory Soyez <soyez@fastjet.fr> 392 393 * Recluster.hh: fixed the name of the #define for the header 394 1 395 2014-07-09 Gregory Soyez <soyez@fastjet.fr> + Jesse 2 396 -
external/fastjet/contribs/RecursiveTools/ModifiedMassDropTagger.hh
r95e6b7a rb7b836a 1 // $Id: ModifiedMassDropTagger.hh 688 2014-06-17 14:29:56Z jthaler$1 // $Id: ModifiedMassDropTagger.hh 1032 2017-07-31 14:20:03Z gsoyez $ 2 2 // 3 3 // Copyright (c) 2014-, Gavin P. Salam … … 105 105 virtual ~ModifiedMassDropTagger(){} 106 106 107 //---------------------------------------------------------------------- 108 // access to class info 109 double symmetry_cut() const { return _symmetry_cut; } 110 107 111 protected: 108 112 … … 110 114 /// has no dependence on the subjet kinematics 111 115 virtual double symmetry_cut_fn(const PseudoJet & /* p1 */, 112 const PseudoJet & /* p2 */ 116 const PseudoJet & /* p2 */, 117 void *extra_parameters = 0 113 118 ) const {return _symmetry_cut;} 114 119 virtual std::string symmetry_cut_description() const; -
external/fastjet/contribs/RecursiveTools/NEWS
r95e6b7a rb7b836a 1 2018/05/31: release of version 2.0.0-beta2 with corrected syntax 2 3 2017/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 1 10 2014/07/09: release of version 1.0.0 of RecursiveTools including 2 11 ModifiedMassDropTagger and SoftDrop (as well as Recluster) -
external/fastjet/contribs/RecursiveTools/README
r95e6b7a rb7b836a 17 17 Marzani, Gregory Soyez, Jesse Thaler 18 18 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 19 28 - Recluster 20 29 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. 23 34 24 35 The interface for these tools is described in more detail below, with … … 74 85 75 86 The SoftDrop procedure is very similar to mMDT, albeit with a 76 generali zed symmetry condition:87 generalised symmetry condition: 77 88 78 89 z > z_cut * (R / R0)^beta … … 108 119 109 120 ------------------------------------------------------------------------ 121 RecursiveSoftDrop 122 ------------------------------------------------------------------------ 123 124 The RecursiveSoftDrop procedure applies the Soft Drop procedure N times 125 in a jet in order to find up to N+1 prongs. N=0 makes no modification 126 to the jet, and N=1 is equivalent to the original SoftDrop. 127 128 Once one has more than one prong, one has to decide which will be 129 declustered next. At each step of the declustering procedure, one 130 undoes 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 134 Compared to SoftDrop, RecursiveSoftDrop takes an extra argument N 135 specifying the number of times the SoftDrop procedure is recursively 136 applied. Negative N means that the procedure is applied until no 137 further 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 145 One then acts on a jet as 146 147 PseudoJet groomed_jet = rsd(jet) 148 149 and get additional information via 150 151 groomed_jet.structure_of<RecursiveSoftDrop>() 152 153 ------------------------------------------------------------------------ 154 IteratedSoftDrop 155 ------------------------------------------------------------------------ 156 157 Iterated Soft Drop (ISD) is a repeated variant of SoftDrop. After 158 performing the Soft Drop procedure once, it logs the groomed symmetry 159 factor, then recursively performs Soft Drop again on the harder 160 branch. This procedure is repeated down to an (optional) angular cut 161 theta_cut, yielding a set of symmetry factors from which observables 162 can be built. 163 164 An 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 172 By default, ISD applied on a jet gives a result of type 173 IteratedSoftDropInfo that can then be probed to obtain physical 174 observables 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 188 Alternatively, one can directly get the multiplicity, angularity, and 189 (zg,thetag) pairs from the IteratedSoftDrop class, at the expense of 190 re-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 197 Note: 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 ------------------------------------------------------------------------ 205 BottomUpSoftDrop 206 ------------------------------------------------------------------------ 207 208 This is a bottom-up version of the RecursiveSoftDrop procedure, in a 209 similar way as Pruning can be seen as a bottom-up version of Trimming. 210 211 In practice, the jet is reclustered and at each step of the clustering 212 one checks the SoftDrop condition 213 214 z > z_cut * (R / R0)^beta 215 216 If the condition is met, the pair is recombined. If the condition is 217 not met, only the hardest of the two objects is kept for further 218 clustering and the softest is rejected. 219 220 ------------------------------------------------------------------------ 110 221 Recluster 111 222 ------------------------------------------------------------------------ 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 *** 112 227 113 228 The Recluster class allows the constituents of a jet to be reclustered 114 229 with 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 230 internally in the mMDT/SoftDrop/RecursiveSoftDrop/IteratedSoftDrop 231 code in order to recluster the jet using the CA algorithm. This is 232 achieved via 117 233 118 234 Recluster ca_reclusterer(cambridge_algorithm, … … 123 239 delete_self_when_unused. 124 240 125 126 241 ------------------------------------------------------------------------ 127 242 Changing behaviour 128 243 ------------------------------------------------------------------------ 129 244 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] 245 The behaviour of the all the tools provided here 246 (ModifiedMassDropTagger, SoftDrop, RecursiveSoftDrop and 247 IteratedSoftDrop) can be tweaked using the following options: 248 249 SymmetryMeasure = {scalar_z, vector_z, y, theta_E, cos_theta_E} 250 [constructor argument] 134 251 : 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 263 RecursionChoice = {larger_pt, larger_mt, larger_m, larger_E} 264 [constructor argument] 138 265 : 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 140 269 141 270 mu_cut [constructor argument] 142 271 : An optional mass drop condition 143 272 144 set_subtractor(subtractor*) [or subtract er as a constructor argument]273 set_subtractor(subtractor*) [or subtractor as a constructor argument] 145 274 : provide a subtractor. When a subtractor is supplied, the 146 275 kinematic constraints are applied on subtracted 4-vectors. In … … 165 294 and SoftDrop defaults to grooming mode. 166 295 296 set_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 301 For the specific case of RecursiveSoftDrop, additional tweaking is 302 possible via the following methods 303 304 set_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 311 set_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 317 set_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 322 set_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 167 327 ------------------------------------------------------------------------ 168 328 Technical Details -
external/fastjet/contribs/RecursiveTools/Recluster.hh
r95e6b7a rb7b836a 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__ 3 3 4 // $Id: Recluster.hh 7 00 2014-07-07 12:50:05Z gsoyez $4 // $Id: Recluster.hh 723 2014-07-30 09:11:01Z gsoyez $ 5 5 // 6 6 // Copyright (c) 2014-, Matteo Cacciari, Gavin P. Salam and Gregory Soyez … … 181 181 FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh 182 182 183 #endif // __FASTJET_ TOOLS_RECLUSTER_HH__183 #endif // __FASTJET_CONTRIB_TOOLS_RECLUSTER_HH__ -
external/fastjet/contribs/RecursiveTools/RecursiveSymmetryCutBase.cc
r95e6b7a rb7b836a 1 // $Id: RecursiveSymmetryCutBase.cc 700 2014-07-07 12:50:05Z gsoyez $1 // $Id: RecursiveSymmetryCutBase.cc 1080 2017-09-28 07:51:37Z gsoyez $ 2 2 // 3 3 // Copyright (c) 2014-, Gavin P. Salam, Gregory Soyez, Jesse Thaler … … 23 23 #include "fastjet/JetDefinition.hh" 24 24 #include "fastjet/ClusterSequenceAreaBase.hh" 25 #include <cassert> 25 26 #include <algorithm> 26 27 #include <cstdlib> … … 42 43 PseudoJet RecursiveSymmetryCutBase::result(const PseudoJet & jet) const { 43 44 // construct the input jet (by default, recluster with C/A) 44 45 45 if (! jet.has_constituents()){ 46 46 throw Error("RecursiveSymmetryCutBase can only be applied to jets with constituents"); 47 47 } 48 48 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 61 52 if (! j.has_valid_cluster_sequence()){ 62 53 throw Error("RecursiveSymmetryCutBase can only be applied to jets associated to a (valid) cluster sequence"); 63 54 } 64 55 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? 65 58 if (_subtractor) { 66 59 const ClusterSequenceAreaBase * csab = … … 75 68 subjet = (*_subtractor)(subjet); 76 69 } 77 78 bool use_mu_cut = (_mu_cut != numeric_limits<double>::infinity());79 70 80 71 // variables for tracking what will happen … … 86 77 std::vector<double> dropped_symmetry; 87 78 std::vector<double> dropped_mu; 79 80 double sym, mu2; 88 81 89 82 // 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); 174 116 175 117 // if desired, store information about dropped branches before recursing … … 179 121 dropped_mu.push_back((mu2 >= 0) ? sqrt(mu2) : -sqrt(-mu2)); 180 122 } 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) 157 RecursiveSymmetryCutBase::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 225 270 //---------------------------------------------------------------------- 226 271 string RecursiveSymmetryCutBase::description() const { … … 235 280 case vector_z: 236 281 ostr << "vector_z"; break; 282 case theta_E: 283 ostr << "theta_E"; break; 284 case cos_theta_E: 285 ostr << "cos_theta_E"; break; 237 286 default: 238 287 cerr << "failed to interpret symmetry_measure" << endl; exit(-1); … … 254 303 case larger_m: 255 304 ostr << "mass"; break; 305 case larger_E: 306 ostr << "energy"; break; 256 307 default: 257 308 cerr << "failed to interpret recursion_choice" << endl; exit(-1); … … 259 310 260 311 if (_subtractor) { 261 ostr << " andsubtractor: " << _subtractor->description();312 ostr << ", subtractor: " << _subtractor->description(); 262 313 if (_input_jet_is_subtracted) {ostr << " (input jet is assumed already subtracted)";} 263 314 } 315 316 if (_recluster) { 317 ostr << " and reclustering using " << _recluster->description(); 318 } 319 264 320 return ostr.str(); 265 321 } 266 322 323 //---------------------------------------------------------------------- 324 // helper for handling the reclustering 325 PseudoJet 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 //---------------------------------------------------------------------- 267 340 // decide what to return when no substructure has been found 341 double 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 //---------------------------------------------------------------------- 268 357 PseudoJet RecursiveSymmetryCutBase::_result_no_substructure(const PseudoJet &last_parent) const{ 269 358 if (_grooming_mode){ … … 277 366 278 367 368 //======================================================================== 369 // implementation of the details of the structure 370 371 // the number of dropped subjets 372 int 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 419 vector<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 466 vector<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 513 vector<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 560 double 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 597 class SortRecursiveSoftDropStructureZgThetagPair{ 598 public: 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 606 vector<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 279 640 } // namespace contrib 280 641 -
external/fastjet/contribs/RecursiveTools/RecursiveSymmetryCutBase.hh
r95e6b7a rb7b836a 1 // $Id: RecursiveSymmetryCutBase.hh 700 2014-07-07 12:50:05Z gsoyez $1 // $Id: RecursiveSymmetryCutBase.hh 1074 2017-09-18 15:15:20Z gsoyez $ 2 2 // 3 3 // Copyright (c) 2014-, Gavin P. Salam, Gregory Soyez, Jesse Thaler … … 24 24 25 25 #include <limits> 26 #include <cassert> 26 27 #include <fastjet/internal/base.hh> 27 28 #include "fastjet/tools/Transformer.hh" 28 29 #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 30 38 #include "Recluster.hh" 39 #endif 31 40 32 41 /** \mainpage RecursiveTools contrib 33 42 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: 38 45 - fastjet::contrib::ModifiedMassDropTagger 39 46 - 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 43 51 */ 44 52 … … 78 86 79 87 /// 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) 84 94 }; 85 95 … … 87 97 enum RecursionChoice{larger_pt, ///< choose the subjet with larger \f$ p_t \f$ 88 98 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) 90 101 }; 91 102 … … 119 130 virtual ~RecursiveSymmetryCutBase(){} 120 131 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 121 138 // internal subtraction configuration 122 139 //---------------------------------------------------------------------- … … 147 164 //---------------------------------------------------------------------- 148 165 149 /// configure the reclustering prior to the SoftDropde-clustering166 /// configure the reclustering prior to the recursive de-clustering 150 167 /// \param do_reclustering recluster the jet or not? 151 168 /// \param recluster how to recluster the jet … … 174 191 /// in particular values of symmetry, delta_R, and mu of dropped branches 175 192 void set_verbose_structure(bool enable=true) { _verbose_structure = enable; } 193 bool has_verbose_structure() const { return _verbose_structure; } 176 194 177 195 … … 185 203 /// subtracted jet. 186 204 virtual PseudoJet result(const PseudoJet & j) const; 187 205 188 206 /// description of the tool 189 207 virtual std::string description() const; 190 208 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 193 214 194 215 class StructureType; … … 203 224 /// apply for a given pair of subjets p1 and p2 204 225 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; 206 228 /// the associated dwescription 207 229 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 } 208 269 209 270 private: … … 238 299 public: 239 300 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), 241 315 _has_verbose(false) // by default, do not store verbose structure 242 316 {} 243 317 244 318 // 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;} 248 324 249 325 // additional verbose information about dropped branches 250 326 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 branches259 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 branches265 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 branches271 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 dropped277 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 283 359 private: 284 360 double _delta_R, _symmetry, _mu; 285 361 friend class RecursiveSymmetryCutBase; 286 362 363 bool _is_composite; 364 287 365 // additional verbose information 288 366 bool _has_verbose; … … 291 369 std::vector<double> _dropped_symmetry; 292 370 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 293 380 294 381 }; -
external/fastjet/contribs/RecursiveTools/SoftDrop.cc
r95e6b7a rb7b836a 1 // $Id: SoftDrop.cc 686 2014-06-14 03:25:09Z jthaler$1 // $Id: SoftDrop.cc 1059 2017-09-07 20:48:00Z gsoyez $ 2 2 // 3 3 // Copyright (c) 2014-, Gregory Soyez, Jesse. Thaler … … 57 57 //---------------------------------------------------------------------- 58 58 double 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); 61 63 } 62 64 -
external/fastjet/contribs/RecursiveTools/SoftDrop.hh
r95e6b7a rb7b836a 1 // $Id: SoftDrop.hh 686 2014-06-14 03:25:09Z jthaler$1 // $Id: SoftDrop.hh 1034 2017-08-01 10:03:53Z gsoyez $ 2 2 // 3 3 // Copyright (c) 2014-, Gregory Soyez, Jesse Thaler … … 112 112 RecursiveSymmetryCutBase(symmetry_measure, mu_cut, recursion_choice, subtractor), 113 113 _beta(beta), _symmetry_cut(symmetry_cut), _R0sqr(R0*R0) 114 {} 114 { 115 // change the default: use grooming mode 116 set_grooming_mode(); 117 } 115 118 116 119 /// default destructor 117 120 virtual ~SoftDrop(){} 118 121 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 119 128 protected: 120 129 121 130 // Unlike MMDT, the SoftDrop symmetry_cut_fn depends on the subjet kinematics 122 131 // 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; 125 135 virtual std::string symmetry_cut_description() const; 126 136 127 private:137 //private: 128 138 double _beta; ///< the power of the angular distance to be used 129 139 ///< in the symmetry condition -
external/fastjet/contribs/RecursiveTools/TODO
r95e6b7a rb7b836a 1 For 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 1 17 For future releases? 2 18 -------------------- … … 7 23 auto-indenting. [Consider this for the full contrib??] 8 24 - More generic kinematic cuts? 25 - KZ: common base class for IteratedSoftDrop and RecursiveSoftDrop? 26 - KZ: make IteratedSoftDrop use Recluster -
external/fastjet/contribs/RecursiveTools/VERSION
r95e6b7a rb7b836a 1 1.0.0 1 2.0.0-beta2
Note:
See TracChangeset
for help on using the changeset viewer.