Fork me on GitHub

source: git/external/fastjet/plugins/SISCone/split_merge.h@ 15772b7

ImprovedOutputFile Timing dual_readout llp
Last change on this file since 15772b7 was 1d208a2, checked in by Pavel Demin <pavel.demin@…>, 8 years ago

update FastJet library to 3.2.1 and Nsubjettiness library to 2.2.4

  • Property mode set to 100644
File size: 17.0 KB
Line 
1// -*- C++ -*-
2///////////////////////////////////////////////////////////////////////////////
3// File: split_merge.h //
4// Description: header file for splitting/merging (contains the CJet class) //
5// This file is part of the SISCone project. //
6// For more details, see http://projects.hepforge.org/siscone //
7// //
8// Copyright (c) 2006 Gavin Salam and Gregory Soyez //
9// //
10// This program is free software; you can redistribute it and/or modify //
11// it under the terms of the GNU General Public License as published by //
12// the Free Software Foundation; either version 2 of the License, or //
13// (at your option) any later version. //
14// //
15// This program is distributed in the hope that it will be useful, //
16// but WITHOUT ANY WARRANTY; without even the implied warranty of //
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
18// GNU General Public License for more details. //
19// //
20// You should have received a copy of the GNU General Public License //
21// along with this program; if not, write to the Free Software //
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
23// //
24// $Revision:: 405 $//
25// $Date:: 2016-05-23 20:15:02 +0200 (Mon, 23 May 2016) $//
26///////////////////////////////////////////////////////////////////////////////
27
28#ifndef __SPLIT_MERGE_H__
29#define __SPLIT_MERGE_H__
30
31#include "config.h"
32#include "defines.h"
33#include "geom_2d.h"
34#include "momentum.h"
35#include <stdio.h>
36#include <vector>
37#include <set>
38#include <memory>
39#include <string>
40
41namespace siscone{
42
43const int CJET_INEXISTENT_PASS = -2;
44
45/**
46 * \class Cjet
47 * real Jet information.
48 *
49 * This class contains information for one single jet.
50 * That is, first, its momentum carrying information
51 * about its centre and pT, and second, its particle
52 * contents
53 */
54class Cjet{
55 public:
56 /// default ctor
57 Cjet();
58
59 /// default dtor
60 ~Cjet();
61
62 Cmomentum v; ///< jet momentum
63 double pt_tilde; ///< p-scheme pt
64 int n; ///< number of particles inside
65 std::vector<int> contents; ///< particle contents (list of indices)
66
67 /// ordering variable used for ordering and overlap in the
68 /// split--merge. This variable is automatically set either to
69 /// pt_tilde, or to mt or to pt, depending on the siscone
70 /// parameter. Note that the default behaviour is pt_tilde and that
71 /// other chices may lead to infrared unsafe situations.
72 /// Note: we use the square of the varible rather than the variable itself
73 double sm_var2;
74
75 /// covered range in eta-phi
76 Ceta_phi_range range;
77
78 /// pass at which the jet has been found
79 /// It starts at 0 (first pass), -1 means infinite rapidity
80 /// (it will be initialised to "CJET_INEXISTENT_PASS" which should
81 /// never appear after clustering)
82 int pass;
83};
84
85/// ordering of jets in pt (e.g. used in final jets ordering)
86bool jets_pt_less(const Cjet &j1, const Cjet &j2);
87
88
89/// the choices of scale variable that can be used in the split-merge
90/// step, both for ordering the protojets and for measuing their
91/// overlap; pt, Et and mt=sqrt(pt^2+m^2) are all defined in E-scheme
92/// (4-momentum) recombination; pttilde = \sum_{i\in jet} |p_{t,i}|
93///
94/// NB: if one changes the order here, one _MUST_ also change the order
95/// in the SISCone plugin
96enum Esplit_merge_scale {
97 SM_pt, ///< transverse momentum (E-scheme), IR unsafe
98 SM_Et, ///< transverse energy (E-scheme), not long. boost inv.
99 ///< original run-II choice [may not be implemented]
100 SM_mt, ///< transverse mass (E-scheme), IR safe except
101 ///< in decays of two identical narrow heavy particles
102 SM_pttilde ///< pt-scheme pt = \sum_{i in jet} |p_{ti}|, should
103 ///< be IR safe in all cases
104};
105
106/// return the name of the split-merge scale choice
107std::string split_merge_scale_name(Esplit_merge_scale sms);
108
109/**
110 * \class Csplit_merge_ptcomparison
111 * comparison of jets for split--merge ordering
112 *
113 * a class that allows us to carry out comparisons of pt of jets, using
114 * information from exact particle contents where necessary.
115 */
116class Csplit_merge_ptcomparison{
117public:
118 /// default ctor
119 Csplit_merge_ptcomparison() :
120 particles(0), split_merge_scale(SM_pttilde){};
121
122 /// return the name corresponding to the SM scale variable
123 std::string SM_scale_name() const {
124 return split_merge_scale_name(split_merge_scale);}
125
126 std::vector<Cmomentum> * particles; ///< pointer to the list of particles
127 std::vector<double> * pt; ///< pointer to the pt of the particles
128
129 /// comparison between 2 jets
130 bool operator()(const Cjet &jet1, const Cjet &jet2) const;
131
132 /**
133 * get the difference between 2 jets, calculated such that rounding
134 * errors will not affect the result even if the two jets have
135 * almost the same content (so that the difference is below the
136 * rounding errors)
137 *
138 * \param j1 first jet
139 * \param j2 second jet
140 * \param v jet1-jet2
141 * \param pt_tilde jet1-jet2 pt_tilde
142 */
143 void get_difference(const Cjet &j1, const Cjet &j2, Cmomentum *v, double *pt_tilde) const;
144
145 /// the following parameter controls the variable we're using for
146 /// the split-merge process i.e. the variable we use for
147 /// 1. ordering jet candidates;
148 /// 2. computing the overlap fraction of two candidates.
149 /// The default value uses pttile (p-scheme pt). Other alternatives are
150 /// pt, mt=sqrt(pt^2+m^2)=sqrt(E^2-pz^2) or Et.
151 /// NOTE: Modifying the default choice can have nasty effects:
152 /// - using pt leads to some IR unsafety when we have two jets,
153 /// e.g. back-to-back, with the same pt. In that case, their ordering
154 /// in pt is random and can be affected by the addition of a
155 /// soft particle. Hence, we highly recommand to keep this to
156 /// the default value i.e. to use pt only for the purpose of
157 /// investigating the IR issue
158 /// - using Et is safe but does not respect boost invariance
159 /// - using mt solves the IR unsafety issues with the pt variable
160 /// for QCD jets but the IR unsafety remains for nack-to-back
161 /// jets of unstable narrow-width particles (e.g. Higgs).
162 /// Therefore, keeping the default value is strongly advised.
163 Esplit_merge_scale split_merge_scale;
164};
165
166
167// iterator types
168/// iterator definition for the jet candidates structure
169typedef std::multiset<siscone::Cjet,Csplit_merge_ptcomparison>::iterator cjet_iterator;
170
171/// iterator definition for the jet structure
172typedef std::vector<siscone::Cjet>::iterator jet_iterator;
173
174
175
176/**
177 * \class Csplit_merge
178 * Class used to split and merge jets.
179 */
180class Csplit_merge{
181 public:
182 /// default ctor
183 Csplit_merge();
184
185 /// default dtor
186 ~Csplit_merge();
187
188
189 //////////////////////////////
190 // initialisation functions //
191 //////////////////////////////
192
193 /**
194 * initialisation function
195 * \param _particles list of particles
196 * \param protocones list of protocones (initial jet candidates)
197 * \param R2 cone radius (squared)
198 * \param ptmin minimal pT allowed for jets
199 * \return 0 on success, 1 on error
200 */
201 int init(std::vector<Cmomentum> &_particles, std::vector<Cmomentum> *protocones, double R2, double ptmin=0.0);
202
203 /**
204 * initialisation function for particle list
205 * \param _particles list of particles
206 * \return 0 on success, 1 on error
207 */
208 int init_particles(std::vector<Cmomentum> &_particles);
209
210 /**
211 * build initial list of left particles
212 */
213 int init_pleft();
214
215 /**
216 * use a pt-dependent boundary for splitting
217 * When called with true, the criterium for splitting two protojets
218 * will be to compare D1^2/kt1^2 vs. D2^2/kt2^2, the (anti-)kt-weighted
219 * distance instead of the plain distance D1^2 vs. D2^2.
220 * This can be set in order to produce more circular hard jets,
221 * with the same underlying philosophy as for the anti-kt algorithm.
222 * We thus expect a behaviour closer to the IterativeCone one.
223 * By default, we use the standard D1^2 vs. D2^2 comparison and this
224 * function is not called.
225 */
226 inline int set_pt_weighted_splitting(bool _use_pt_weighted_splitting){
227 use_pt_weighted_splitting = _use_pt_weighted_splitting;
228 return 0;
229 }
230
231 ////////////////////////
232 // cleaning functions //
233 ////////////////////////
234
235 /// partial clearance
236 int partial_clear();
237
238 /// full clearance
239 int full_clear();
240
241 ///////////////////////////////////////
242 // user-defined stable-cone ordering //
243 ///////////////////////////////////////
244
245 /// \class Cuser_scale_base
246 /// base class for user-defined ordering of stable cones
247 ///
248 /// derived classes have to implement the () operator that returns
249 /// the scale associated with a given jet.
250 class Cuser_scale_base{
251 public:
252 /// empty virtual dtor
253 virtual ~Cuser_scale_base(){}
254
255 /// the scale associated with a given jet
256 ///
257 /// "progressive removal" iteratively removes the stable cone with
258 /// the largest scale
259 virtual double operator()(const Cjet & jet) const = 0;
260
261 /// returns true when the scale associated with jet a is larger than
262 /// the scale associated with jet b
263 ///
264 /// By default this does a simple direct comparison but it can be
265 /// overloaded for higher precision [recommended if possible]
266 ///
267 /// This function assumes that a.sm_var2 and b.sm_var2 have been
268 /// correctly initialised with the signed squared output of
269 /// operator(), as is by default the case when is_larger is called
270 /// from within siscone.
271 virtual bool is_larger(const Cjet & a, const Cjet & b) const{
272 return (a.sm_var2 > b.sm_var2);
273 }
274 };
275
276 /// associate a user-defined scale to order the stable cones
277 ///
278 /// Note that this is only used in "progressive-removal mode",
279 /// e.g. in add_hardest_protocone_to_jets().
280 void set_user_scale(const Cuser_scale_base * user_scale_in){
281 _user_scale = user_scale_in;
282 }
283
284 /// return the user-defined scale (NULL if none)
285 const Cuser_scale_base * user_scale() const { return _user_scale; }
286
287
288 /////////////////////////////////
289 // main parts of the algorithm //
290 /////////////////////////////////
291
292 /**
293 * build the list 'p_uncol_hard' from p_remain by clustering
294 * collinear particles and removing particles softer than
295 * stable_cone_soft_pt2_cutoff
296 * note that thins in only used for stable-cone detection
297 * so the parent_index field is unnecessary
298 */
299 int merge_collinear_and_remove_soft();
300
301 /**
302 * add a list of protocones
303 * \param protocones list of protocones (initial jet candidates)
304 * \param R2 cone radius (squared)
305 * \param ptmin minimal pT allowed for jets
306 * \return 0 on success, 1 on error
307 */
308 int add_protocones(std::vector<Cmomentum> *protocones, double R2, double ptmin=0.0);
309
310 /**
311 * remove the hardest protocone and declare it a jet
312 * \param protocones list of protocones (initial jet candidates)
313 * \param R2 cone radius (squared)
314 * \param ptmin minimal pT allowed for jets
315 * \return 0 on success, 1 on error
316 *
317 * The list of remaining particles (and the uncollinear-hard ones)
318 * is updated.
319 */
320 int add_hardest_protocone_to_jets(std::vector<Cmomentum> *protocones, double R2, double ptmin=0.0);
321
322 /**
323 * really do the splitting and merging
324 * At the end, the vector jets is filled with the jets found.
325 * the 'contents' field of each jets contains the indices
326 * of the particles included in that jet.
327 * \param overlap_tshold threshold for splitting/merging transition
328 * \param ptmin minimal pT allowed for jets
329 * \return the number of jets is returned
330 */
331 int perform(double overlap_tshold, double ptmin=0.0);
332
333
334 //////////////////////////////
335 // save and debug functions //
336 //////////////////////////////
337
338 /// save final jets
339 /// \param flux stream to save the jet contentss
340 int save_contents(FILE *flux);
341
342 /// show jets/candidates status
343 int show();
344
345 // particle information
346 int n; ///< number of particles
347 std::vector<Cmomentum> particles; ///< list of particles
348 std::vector<double> pt; ///< list of particles' pt
349 int n_left; ///< numer of particles that does not belong to any jet
350 std::vector<Cmomentum> p_remain; ///< list of particles remaining to deal with
351 std::vector<Cmomentum> p_uncol_hard; ///< list of particles remaining with collinear clustering
352 int n_pass; ///< index of the run
353
354 /// minimal difference in squared distance between a particle and
355 /// two overlapping protojets when doing a split (useful when
356 /// testing approx. collinear safety)
357 double most_ambiguous_split;
358
359 // jets information
360 std::vector<Cjet> jets; ///< list of jets
361
362 // working entries
363 int *indices; ///< maximal size array for indices works
364 int idx_size; ///< number of elements in indices1
365
366 /// The following flag indicates that identical protocones
367 /// are to be merged automatically each time around the split-merge
368 /// loop and before anything else happens.
369 ///
370 /// This flag is only effective if ALLOW_MERGE_IDENTICAL_PROTOCONES
371 /// is set in 'defines.h'
372 /// Note that this lead to infrared-unsafety so it is disabled
373 /// by default
374 bool merge_identical_protocones;
375
376 /// member used for detailed comparisons of pt's
377 Csplit_merge_ptcomparison ptcomparison;
378
379 /// stop split--merge or progressive-removal when the squared SM_var
380 /// of the hardest protojet is below this cut-off. Note that this is
381 /// a signed square (ie SM_var*|SM_var|) to be able to handle
382 /// negative values.
383 ///
384 /// Note that the cut-off is set on the variable squared.
385 double SM_var2_hardest_cut_off;
386
387 /// pt cutoff for the particles to put in p_uncol_hard
388 /// this is meant to allow removing soft particles in the
389 /// stable-cone search.
390 ///
391 /// This is not collinear-safe so you should not use this
392 /// variable unless you really know what you are doing
393 /// Note that the cut-off is set on the variable squared.
394 double stable_cone_soft_pt2_cutoff;
395
396 private:
397 /**
398 * get the overlap between 2 jets
399 * \param j1 first jet
400 * \param j2 second jet
401 * \param v returned overlap^2 (determined by the choice of SM variable)
402 * \return true if overlapping, false if disjoint
403 */
404 bool get_overlap(const Cjet &j1, const Cjet &j2, double *v);
405
406
407 /**
408 * split the two given jets.
409 * during this procedure, the jets j1 & j2 are replaced
410 * by 2 new jets. Common particles are associted to the
411 * closest initial jet.
412 * \param it_j1 iterator of the first jet in 'candidates'
413 * \param it_j2 iterator of the second jet in 'candidates'
414 * \param j1 first jet (Cjet instance)
415 * \param j2 second jet (Cjet instance)
416 * \return true on success, false on error
417 */
418 bool split(cjet_iterator &it_j1, cjet_iterator &it_j2);
419
420 /**
421 * merge the two given jet.
422 * during this procedure, the jets j1 & j2 are replaced
423 * by 1 single jets containing both of them.
424 * \param it_j1 iterator of the first jet in 'candidates'
425 * \param it_j2 iterator of the second jet in 'candidates'
426 * \return true on success, false on error
427 */
428 bool merge(cjet_iterator &it_j1, cjet_iterator &it_j2);
429
430 /**
431 * Check whether or not a jet has to be inserted in the
432 * list of protojets. If it has, set its sm_variable and
433 * insert it to the list of protojets.
434 * \param jet jet to insert
435 */
436 bool insert(Cjet &jet);
437
438 /**
439 * given a 4-momentum and its associated pT, return the
440 * variable tht has to be used for SM
441 * \param v 4 momentum of the protojet
442 * \param pt_tilde pt_tilde of the protojet
443 */
444 double get_sm_var2(Cmomentum &v, double &pt_tilde);
445
446 // jet information
447 /// list of jet candidates
448#ifdef SISCONE_USES_UNIQUE_PTR_AS_AUTO_PTR
449 std::unique_ptr<std::multiset<Cjet,Csplit_merge_ptcomparison> > candidates;
450#else
451 std::auto_ptr<std::multiset<Cjet,Csplit_merge_ptcomparison> > candidates;
452#endif
453
454 /// minimal pt2
455 double pt_min2;
456
457 /**
458 * do we have or not to use the pt-weighted splitting
459 * (see description for set_pt_weighted_splitting)
460 * This will be false by default
461 */
462 bool use_pt_weighted_splitting;
463
464 /// use a user-defined scale to order the stable cones and jet
465 /// candidates
466 const Cuser_scale_base *_user_scale;
467
468#ifdef ALLOW_MERGE_IDENTICAL_PROTOCONES
469 /// checkxor for the candidates (to avoid having twice the same contents)
470 std::set<Creference> cand_refs;
471#endif
472};
473
474}
475
476
477#endif
Note: See TracBrowser for help on using the repository browser.