1 | // Nsubjettiness Package
|
---|
2 | // Questions/Comments? jthaler@jthaler.net
|
---|
3 | //
|
---|
4 | // Copyright (c) 2011-14
|
---|
5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
|
---|
6 | //
|
---|
7 | // $Id: MeasureDefinition.hh 828 2015-07-20 14:52:06Z jthaler $
|
---|
8 | //----------------------------------------------------------------------
|
---|
9 | // This file is part of FastJet contrib.
|
---|
10 | //
|
---|
11 | // It is free software; you can redistribute it and/or modify it under
|
---|
12 | // the terms of the GNU General Public License as published by the
|
---|
13 | // Free Software Foundation; either version 2 of the License, or (at
|
---|
14 | // your option) any later version.
|
---|
15 | //
|
---|
16 | // It is distributed in the hope that it will be useful, but WITHOUT
|
---|
17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
---|
18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
---|
19 | // License for more details.
|
---|
20 | //
|
---|
21 | // You should have received a copy of the GNU General Public License
|
---|
22 | // along with this code. If not, see <http://www.gnu.org/licenses/>.
|
---|
23 | //----------------------------------------------------------------------
|
---|
24 |
|
---|
25 | #ifndef __FASTJET_CONTRIB_MEASUREDEFINITION_HH__
|
---|
26 | #define __FASTJET_CONTRIB_MEASUREDEFINITION_HH__
|
---|
27 |
|
---|
28 | #include "fastjet/PseudoJet.hh"
|
---|
29 | #include <cmath>
|
---|
30 | #include <vector>
|
---|
31 | #include <list>
|
---|
32 | #include <limits>
|
---|
33 |
|
---|
34 | #include "TauComponents.hh"
|
---|
35 |
|
---|
36 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
|
---|
37 |
|
---|
38 | namespace contrib{
|
---|
39 |
|
---|
40 |
|
---|
41 |
|
---|
42 | // The following Measures are available (and their relevant arguments):
|
---|
43 | // Recommended for usage as jet shapes
|
---|
44 | class DefaultMeasure; // Default measure from which next classes derive (should not be called directly)
|
---|
45 | class NormalizedMeasure; // (beta,R0)
|
---|
46 | class UnnormalizedMeasure; // (beta)
|
---|
47 | class NormalizedCutoffMeasure; // (beta,R0,Rcutoff)
|
---|
48 | class UnnormalizedCutoffMeasure; // (beta,Rcutoff)
|
---|
49 |
|
---|
50 | // New measures as of v2.2
|
---|
51 | // Recommended for usage as event shapes (or for jet finding)
|
---|
52 | class ConicalMeasure; // (beta,R)
|
---|
53 | class OriginalGeometricMeasure; // (R)
|
---|
54 | class ModifiedGeometricMeasure; // (R)
|
---|
55 | class ConicalGeometricMeasure; // (beta, gamma, R)
|
---|
56 | class XConeMeasure; // (beta, R)
|
---|
57 |
|
---|
58 | // Formerly GeometricMeasure, now no longer recommended, kept commented out only for cross-check purposes
|
---|
59 | //class DeprecatedGeometricMeasure; // (beta)
|
---|
60 | //class DeprecatedGeometricCutoffMeasure; // (beta,Rcutoff)
|
---|
61 |
|
---|
62 |
|
---|
63 | ///////
|
---|
64 | //
|
---|
65 | // MeasureDefinition
|
---|
66 | //
|
---|
67 | ///////
|
---|
68 |
|
---|
69 | //This is a helper class for the Minimum Axes Finders. It is defined later.
|
---|
70 | class LightLikeAxis;
|
---|
71 |
|
---|
72 | ///------------------------------------------------------------------------
|
---|
73 | /// \class MeasureDefinition
|
---|
74 | /// \brief Base class for measure definitions
|
---|
75 | ///
|
---|
76 | /// This is the base class for measure definitions. Derived classes will calculate
|
---|
77 | /// the tau_N of a jet given a specific measure and a set of axes. The measure is
|
---|
78 | /// determined by various jet and beam distances (and possible normalization factors).
|
---|
79 | ///------------------------------------------------------------------------
|
---|
80 | class MeasureDefinition {
|
---|
81 |
|
---|
82 | public:
|
---|
83 |
|
---|
84 | /// Description of measure and parameters
|
---|
85 | virtual std::string description() const = 0;
|
---|
86 |
|
---|
87 | /// In derived classes, this should return a copy of the corresponding derived class
|
---|
88 | virtual MeasureDefinition* create() const = 0;
|
---|
89 |
|
---|
90 | //The following five functions define the measure by which tau_N is calculated,
|
---|
91 | //and are overloaded by the various measures below
|
---|
92 |
|
---|
93 | /// Distanes to jet axis. This is called many times, so needs to be as fast as possible
|
---|
94 | /// Unless overloaded, it just calls jet_numerator
|
---|
95 | virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
96 | return jet_numerator(particle,axis);
|
---|
97 | }
|
---|
98 |
|
---|
99 | /// Distanes to beam. This is called many times, so needs to be as fast as possible
|
---|
100 | /// Unless overloaded, it just calls beam_numerator
|
---|
101 | virtual double beam_distance_squared(const fastjet::PseudoJet& particle) const {
|
---|
102 | return beam_numerator(particle);
|
---|
103 | }
|
---|
104 |
|
---|
105 | /// The jet measure used in N-(sub)jettiness
|
---|
106 | virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const = 0;
|
---|
107 | /// The beam measure used in N-(sub)jettiness
|
---|
108 | virtual double beam_numerator(const fastjet::PseudoJet& particle) const = 0;
|
---|
109 |
|
---|
110 | /// A possible normalization factor
|
---|
111 | virtual double denominator(const fastjet::PseudoJet& particle) const = 0;
|
---|
112 |
|
---|
113 | /// Run a one-pass minimization routine. There is a generic one-pass minimization that works for a wide variety of measures.
|
---|
114 | /// This should be overloaded to create a measure-specific minimization scheme
|
---|
115 | virtual std::vector<fastjet::PseudoJet> get_one_pass_axes(int n_jets,
|
---|
116 | const std::vector<fastjet::PseudoJet>& inputs,
|
---|
117 | const std::vector<fastjet::PseudoJet>& seedAxes,
|
---|
118 | int nAttempts = 1000, // cap number of iterations
|
---|
119 | double accuracy = 0.0001 // cap distance of closest approach
|
---|
120 | ) const;
|
---|
121 |
|
---|
122 | public:
|
---|
123 |
|
---|
124 | /// Returns the tau value for a give set of particles and axes
|
---|
125 | double result(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) const {
|
---|
126 | return component_result(particles,axes).tau();
|
---|
127 | }
|
---|
128 |
|
---|
129 | /// Short-hand for the result() function
|
---|
130 | inline double operator() (const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) const {
|
---|
131 | return result(particles,axes);
|
---|
132 | }
|
---|
133 |
|
---|
134 | /// Return all of the TauComponents for specific input particles and axes
|
---|
135 | TauComponents component_result(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) const;
|
---|
136 |
|
---|
137 | /// Create the partitioning according the jet/beam distances and stores them a TauPartition
|
---|
138 | TauPartition get_partition(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) const;
|
---|
139 |
|
---|
140 | /// Calculate the tau result using an existing partition
|
---|
141 | TauComponents component_result_from_partition(const TauPartition& partition, const std::vector<fastjet::PseudoJet>& axes) const;
|
---|
142 |
|
---|
143 |
|
---|
144 |
|
---|
145 | /// virtual destructor
|
---|
146 | virtual ~MeasureDefinition(){}
|
---|
147 |
|
---|
148 | protected:
|
---|
149 |
|
---|
150 | /// Flag set by derived classes to choose whether or not to use beam/denominator
|
---|
151 | TauMode _tau_mode;
|
---|
152 |
|
---|
153 | /// Flag set by derived classes to say whether cheap get_one_pass_axes method can be used (true by default)
|
---|
154 | bool _useAxisScaling;
|
---|
155 |
|
---|
156 | /// This is the only constructor, which requires _tau_mode and _useAxisScaling to be manually set by derived classes.
|
---|
157 | MeasureDefinition() : _tau_mode(UNDEFINED_SHAPE), _useAxisScaling(true) {}
|
---|
158 |
|
---|
159 |
|
---|
160 | /// Used by derived classes to set whether or not to use beam/denominator information
|
---|
161 | void setTauMode(TauMode tau_mode) {
|
---|
162 | _tau_mode = tau_mode;
|
---|
163 | }
|
---|
164 |
|
---|
165 | /// Used by derived classes to say whether one can use cheap get_one_pass_axes
|
---|
166 | void setAxisScaling(bool useAxisScaling) {
|
---|
167 | _useAxisScaling = useAxisScaling;
|
---|
168 | }
|
---|
169 |
|
---|
170 | /// Uses denominator information?
|
---|
171 | bool has_denominator() const { return (_tau_mode == NORMALIZED_JET_SHAPE || _tau_mode == NORMALIZED_EVENT_SHAPE);}
|
---|
172 | /// Uses beam information?
|
---|
173 | bool has_beam() const {return (_tau_mode == UNNORMALIZED_EVENT_SHAPE || _tau_mode == NORMALIZED_EVENT_SHAPE);}
|
---|
174 |
|
---|
175 | /// Create light-like axis (used in default one-pass minimization routine)
|
---|
176 | fastjet::PseudoJet lightFrom(const fastjet::PseudoJet& input) const {
|
---|
177 | double length = sqrt(pow(input.px(),2) + pow(input.py(),2) + pow(input.pz(),2));
|
---|
178 | return fastjet::PseudoJet(input.px()/length,input.py()/length,input.pz()/length,1.0);
|
---|
179 | }
|
---|
180 |
|
---|
181 | /// Shorthand for squaring
|
---|
182 | static inline double sq(double x) {return x*x;}
|
---|
183 |
|
---|
184 | };
|
---|
185 |
|
---|
186 |
|
---|
187 | ///////
|
---|
188 | //
|
---|
189 | // Default Measures
|
---|
190 | //
|
---|
191 | ///////
|
---|
192 |
|
---|
193 |
|
---|
194 | ///------------------------------------------------------------------------
|
---|
195 | /// \enum DefaultMeasureType
|
---|
196 | /// \brief Options for default measure
|
---|
197 | ///
|
---|
198 | /// Can be used to switch between pp and ee measure types in the DefaultMeasure
|
---|
199 | ///------------------------------------------------------------------------
|
---|
200 | enum DefaultMeasureType {
|
---|
201 | pt_R, /// use transverse momenta and boost-invariant angles,
|
---|
202 | E_theta, /// use energies and angles,
|
---|
203 | lorentz_dot, /// use dot product inspired measure
|
---|
204 | perp_lorentz_dot /// use conical geometric inspired measures
|
---|
205 | };
|
---|
206 |
|
---|
207 | ///------------------------------------------------------------------------
|
---|
208 | /// \class DefaultMeasure
|
---|
209 | /// \brief Base class for default N-subjettiness measure definitions
|
---|
210 | ///
|
---|
211 | /// This class is the default measure as defined in the original N-subjettiness papers.
|
---|
212 | /// Based on the conical measure, but with a normalization factor
|
---|
213 | /// This measure is defined as the pT of the particle multiplied by deltaR
|
---|
214 | /// to the power of beta. This class includes the normalization factor determined by R0
|
---|
215 | ///------------------------------------------------------------------------
|
---|
216 | class DefaultMeasure : public MeasureDefinition {
|
---|
217 |
|
---|
218 | public:
|
---|
219 |
|
---|
220 | /// Description
|
---|
221 | virtual std::string description() const;
|
---|
222 | /// To allow copying around of these objects
|
---|
223 | virtual DefaultMeasure* create() const {return new DefaultMeasure(*this);}
|
---|
224 |
|
---|
225 | /// fast jet distance
|
---|
226 | virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
227 | return angleSquared(particle, axis);
|
---|
228 | }
|
---|
229 |
|
---|
230 | /// fast beam distance
|
---|
231 | virtual double beam_distance_squared(const fastjet::PseudoJet& /*particle*/) const {
|
---|
232 | return _RcutoffSq;
|
---|
233 | }
|
---|
234 |
|
---|
235 | /// true jet distance (given by general definitions of energy and angle)
|
---|
236 | virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const{
|
---|
237 | double jet_dist = angleSquared(particle, axis);
|
---|
238 | if (jet_dist > 0.0) {
|
---|
239 | return energy(particle) * std::pow(jet_dist,_beta/2.0);
|
---|
240 | } else {
|
---|
241 | return 0.0;
|
---|
242 | }
|
---|
243 | }
|
---|
244 |
|
---|
245 | /// true beam distance
|
---|
246 | virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
|
---|
247 | return energy(particle) * std::pow(_Rcutoff,_beta);
|
---|
248 | }
|
---|
249 |
|
---|
250 | /// possible denominator for normalization
|
---|
251 | virtual double denominator(const fastjet::PseudoJet& particle) const {
|
---|
252 | return energy(particle) * std::pow(_R0,_beta);
|
---|
253 | }
|
---|
254 |
|
---|
255 | /// Special minimization routine (from v1.0 of N-subjettiness)
|
---|
256 | virtual std::vector<fastjet::PseudoJet> get_one_pass_axes(int n_jets,
|
---|
257 | const std::vector<fastjet::PseudoJet>& inputs,
|
---|
258 | const std::vector<fastjet::PseudoJet>& seedAxes,
|
---|
259 | int nAttempts, // cap number of iterations
|
---|
260 | double accuracy // cap distance of closest approach
|
---|
261 | ) const;
|
---|
262 |
|
---|
263 | protected:
|
---|
264 | double _beta; ///< Angular exponent
|
---|
265 | double _R0; ///< Normalization factor
|
---|
266 | double _Rcutoff; ///< Cutoff radius
|
---|
267 | double _RcutoffSq; ///< Cutoff radius squared
|
---|
268 | DefaultMeasureType _measure_type; ///< Type of measure used (i.e. pp style or ee style)
|
---|
269 |
|
---|
270 |
|
---|
271 | /// Constructor is protected so that no one tries to call this directly.
|
---|
272 | DefaultMeasure(double beta, double R0, double Rcutoff, DefaultMeasureType measure_type = pt_R)
|
---|
273 | : MeasureDefinition(), _beta(beta), _R0(R0), _Rcutoff(Rcutoff), _RcutoffSq(sq(Rcutoff)), _measure_type(measure_type)
|
---|
274 | {
|
---|
275 | if (beta <= 0) throw Error("DefaultMeasure: You must choose beta > 0.");
|
---|
276 | if (R0 <= 0) throw Error("DefaultMeasure: You must choose R0 > 0.");
|
---|
277 | if (Rcutoff <= 0) throw Error("DefaultMeasure: You must choose Rcutoff > 0.");
|
---|
278 | }
|
---|
279 |
|
---|
280 | /// Added set measure method in case it becomes useful later
|
---|
281 | void setDefaultMeasureType(DefaultMeasureType measure_type) {
|
---|
282 | _measure_type = measure_type;
|
---|
283 | }
|
---|
284 |
|
---|
285 | /// Generalized energy value (determined by _measure_type)
|
---|
286 | double energy(const PseudoJet& jet) const;
|
---|
287 | /// Generalized angle value (determined by _measure_type)
|
---|
288 | double angleSquared(const PseudoJet& jet1, const PseudoJet& jet2) const;
|
---|
289 |
|
---|
290 | /// Name of _measure_type, so description will include the measure type
|
---|
291 | std::string measure_type_name() const {
|
---|
292 | if (_measure_type == pt_R) return "pt_R";
|
---|
293 | else if (_measure_type == E_theta) return "E_theta";
|
---|
294 | else if (_measure_type == lorentz_dot) return "lorentz_dot";
|
---|
295 | else if (_measure_type == perp_lorentz_dot) return "perp_lorentz_dot";
|
---|
296 | else return "Measure Type Undefined";
|
---|
297 | }
|
---|
298 |
|
---|
299 | /// templated for speed (TODO: probably should remove, since not clear that there is a speed gain)
|
---|
300 | template <int N> std::vector<LightLikeAxis> UpdateAxesFast(const std::vector <LightLikeAxis> & old_axes,
|
---|
301 | const std::vector <fastjet::PseudoJet> & inputJets,
|
---|
302 | double accuracy) const;
|
---|
303 |
|
---|
304 | /// called by get_one_pass_axes to update axes iteratively
|
---|
305 | std::vector<LightLikeAxis> UpdateAxes(const std::vector <LightLikeAxis> & old_axes,
|
---|
306 | const std::vector <fastjet::PseudoJet> & inputJets,
|
---|
307 | double accuracy) const;
|
---|
308 | };
|
---|
309 |
|
---|
310 |
|
---|
311 | ///------------------------------------------------------------------------
|
---|
312 | /// \class NormalizedCutoffMeasure
|
---|
313 | /// \brief Dimensionless default measure, with radius cutoff
|
---|
314 | ///
|
---|
315 | /// This measure is just a wrapper for DefaultMeasure
|
---|
316 | ///------------------------------------------------------------------------
|
---|
317 | class NormalizedCutoffMeasure : public DefaultMeasure {
|
---|
318 |
|
---|
319 | public:
|
---|
320 |
|
---|
321 | /// Constructor
|
---|
322 | NormalizedCutoffMeasure(double beta, double R0, double Rcutoff, DefaultMeasureType measure_type = pt_R)
|
---|
323 | : DefaultMeasure(beta, R0, Rcutoff, measure_type) {
|
---|
324 | setTauMode(NORMALIZED_JET_SHAPE);
|
---|
325 | }
|
---|
326 |
|
---|
327 | /// Description
|
---|
328 | virtual std::string description() const;
|
---|
329 |
|
---|
330 | /// For copying purposes
|
---|
331 | virtual NormalizedCutoffMeasure* create() const {return new NormalizedCutoffMeasure(*this);}
|
---|
332 |
|
---|
333 | };
|
---|
334 |
|
---|
335 | ///------------------------------------------------------------------------
|
---|
336 | /// \class NormalizedMeasure
|
---|
337 | /// \brief Dimensionless default measure, with no cutoff
|
---|
338 | ///
|
---|
339 | /// This measure is the same as NormalizedCutoffMeasure, with Rcutoff taken to infinity.
|
---|
340 | ///------------------------------------------------------------------------
|
---|
341 | class NormalizedMeasure : public NormalizedCutoffMeasure {
|
---|
342 |
|
---|
343 | public:
|
---|
344 |
|
---|
345 | /// Constructor
|
---|
346 | NormalizedMeasure(double beta, double R0, DefaultMeasureType measure_type = pt_R)
|
---|
347 | : NormalizedCutoffMeasure(beta, R0, std::numeric_limits<double>::max(), measure_type) {
|
---|
348 | _RcutoffSq = std::numeric_limits<double>::max();
|
---|
349 | setTauMode(NORMALIZED_JET_SHAPE);
|
---|
350 | }
|
---|
351 |
|
---|
352 | /// Description
|
---|
353 | virtual std::string description() const;
|
---|
354 | /// For copying purposes
|
---|
355 | virtual NormalizedMeasure* create() const {return new NormalizedMeasure(*this);}
|
---|
356 |
|
---|
357 | };
|
---|
358 |
|
---|
359 |
|
---|
360 | ///------------------------------------------------------------------------
|
---|
361 | /// \class UnnormalizedCutoffMeasure
|
---|
362 | /// \brief Dimensionful default measure, with radius cutoff
|
---|
363 | ///
|
---|
364 | /// This class is the unnormalized conical measure. The only difference from NormalizedCutoffMeasure
|
---|
365 | /// is that the denominator is defined to be 1.0 by setting _has_denominator to false.
|
---|
366 | /// class UnnormalizedCutoffMeasure : public NormalizedCutoffMeasure {
|
---|
367 | ///------------------------------------------------------------------------
|
---|
368 | class UnnormalizedCutoffMeasure : public DefaultMeasure {
|
---|
369 |
|
---|
370 | public:
|
---|
371 |
|
---|
372 | /// Since all methods are identical, UnnormalizedMeasure inherits directly
|
---|
373 | /// from NormalizedMeasure. R0 is a dummy value since the value of R0 is unecessary for this class,
|
---|
374 | /// and the "false" flag sets _has_denominator in MeasureDefinition to false so no denominator is used.
|
---|
375 | UnnormalizedCutoffMeasure(double beta, double Rcutoff, DefaultMeasureType measure_type = pt_R)
|
---|
376 | : DefaultMeasure(beta, std::numeric_limits<double>::quiet_NaN(), Rcutoff, measure_type) {
|
---|
377 | setTauMode(UNNORMALIZED_EVENT_SHAPE);
|
---|
378 | }
|
---|
379 |
|
---|
380 | /// Description
|
---|
381 | virtual std::string description() const;
|
---|
382 | /// For copying purposes
|
---|
383 | virtual UnnormalizedCutoffMeasure* create() const {return new UnnormalizedCutoffMeasure(*this);}
|
---|
384 |
|
---|
385 | };
|
---|
386 |
|
---|
387 |
|
---|
388 | ///------------------------------------------------------------------------
|
---|
389 | /// \class UnnormalizedMeasure
|
---|
390 | /// \brief Dimensionless default measure, with no cutoff
|
---|
391 | ///
|
---|
392 | /// This measure is the same as UnnormalizedCutoffMeasure, with Rcutoff taken to infinity.
|
---|
393 | ///------------------------------------------------------------------------
|
---|
394 | class UnnormalizedMeasure : public UnnormalizedCutoffMeasure {
|
---|
395 |
|
---|
396 | public:
|
---|
397 | /// Since all methods are identical, UnnormalizedMeasure inherits directly
|
---|
398 | /// from NormalizedMeasure. R0 is a dummy value since the value of R0 is unecessary for this class,
|
---|
399 | /// and the "false" flag sets _has_denominator in MeasureDefinition to false so no denominator is used.
|
---|
400 | UnnormalizedMeasure(double beta, DefaultMeasureType measure_type = pt_R)
|
---|
401 | : UnnormalizedCutoffMeasure(beta, std::numeric_limits<double>::max(), measure_type) {
|
---|
402 | _RcutoffSq = std::numeric_limits<double>::max();
|
---|
403 | setTauMode(UNNORMALIZED_JET_SHAPE);
|
---|
404 | }
|
---|
405 |
|
---|
406 | /// Description
|
---|
407 | virtual std::string description() const;
|
---|
408 |
|
---|
409 | /// For copying purposes
|
---|
410 | virtual UnnormalizedMeasure* create() const {return new UnnormalizedMeasure(*this);}
|
---|
411 |
|
---|
412 | };
|
---|
413 |
|
---|
414 |
|
---|
415 | ///------------------------------------------------------------------------
|
---|
416 | /// \class ConicalMeasure
|
---|
417 | /// \brief Dimensionful event-shape measure, with radius cutoff
|
---|
418 | ///
|
---|
419 | /// Very similar to UnnormalizedCutoffMeasure, but with different normalization convention
|
---|
420 | /// and using the new default one-pass minimization algorithm.
|
---|
421 | /// Axes are also made to be light-like to ensure sensible behavior
|
---|
422 | /// Intended to be used as an event shape.
|
---|
423 | ///------------------------------------------------------------------------
|
---|
424 | class ConicalMeasure : public MeasureDefinition {
|
---|
425 |
|
---|
426 | public:
|
---|
427 |
|
---|
428 | /// Constructor
|
---|
429 | ConicalMeasure(double beta, double Rcutoff)
|
---|
430 | : MeasureDefinition(), _beta(beta), _Rcutoff(Rcutoff), _RcutoffSq(sq(Rcutoff)) {
|
---|
431 | if (beta <= 0) throw Error("ConicalMeasure: You must choose beta > 0.");
|
---|
432 | if (Rcutoff <= 0) throw Error("ConicalMeasure: You must choose Rcutoff > 0.");
|
---|
433 | setTauMode(UNNORMALIZED_EVENT_SHAPE);
|
---|
434 | }
|
---|
435 |
|
---|
436 | /// Description
|
---|
437 | virtual std::string description() const;
|
---|
438 | /// For copying purposes
|
---|
439 | virtual ConicalMeasure* create() const {return new ConicalMeasure(*this);}
|
---|
440 |
|
---|
441 | /// fast jet distance
|
---|
442 | virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
443 | PseudoJet lightAxis = lightFrom(axis);
|
---|
444 | return particle.squared_distance(lightAxis);
|
---|
445 | }
|
---|
446 |
|
---|
447 | /// fast beam distance
|
---|
448 | virtual double beam_distance_squared(const fastjet::PseudoJet& /*particle*/) const {
|
---|
449 | return _RcutoffSq;
|
---|
450 | }
|
---|
451 |
|
---|
452 |
|
---|
453 | /// true jet distance
|
---|
454 | virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
455 | PseudoJet lightAxis = lightFrom(axis);
|
---|
456 | double jet_dist = particle.squared_distance(lightAxis)/_RcutoffSq;
|
---|
457 | double jet_perp = particle.perp();
|
---|
458 |
|
---|
459 | if (_beta == 2.0) {
|
---|
460 | return jet_perp * jet_dist;
|
---|
461 | } else {
|
---|
462 | return jet_perp * pow(jet_dist,_beta/2.0);
|
---|
463 | }
|
---|
464 | }
|
---|
465 |
|
---|
466 | /// true beam distance
|
---|
467 | virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
|
---|
468 | return particle.perp();
|
---|
469 | }
|
---|
470 |
|
---|
471 | /// no denominator used for this measure
|
---|
472 | virtual double denominator(const fastjet::PseudoJet& /*particle*/) const {
|
---|
473 | return std::numeric_limits<double>::quiet_NaN();
|
---|
474 | }
|
---|
475 |
|
---|
476 | protected:
|
---|
477 | double _beta; ///< angular exponent
|
---|
478 | double _Rcutoff; ///< effective jet radius
|
---|
479 | double _RcutoffSq;///< effective jet radius squared
|
---|
480 | };
|
---|
481 |
|
---|
482 |
|
---|
483 |
|
---|
484 | ///------------------------------------------------------------------------
|
---|
485 | /// \class OriginalGeometricMeasure
|
---|
486 | /// \brief Dimensionful event-shape measure, with dot-product distances
|
---|
487 | ///
|
---|
488 | /// This class is the original (and hopefully now correctly coded) geometric measure.
|
---|
489 | /// This measure is defined by the Lorentz dot product between
|
---|
490 | /// the particle and the axis. This class does not include normalization of tau_N.
|
---|
491 | /// New in Nsubjettiness v2.2
|
---|
492 | /// NOTE: This is defined differently from the DeprecatedGeometricMeasure which are now commented out.
|
---|
493 | ///------------------------------------------------------------------------
|
---|
494 | class OriginalGeometricMeasure : public MeasureDefinition {
|
---|
495 |
|
---|
496 | public:
|
---|
497 | /// Constructor
|
---|
498 | OriginalGeometricMeasure(double Rcutoff)
|
---|
499 | : MeasureDefinition(), _Rcutoff(Rcutoff), _RcutoffSq(sq(Rcutoff)) {
|
---|
500 | if (Rcutoff <= 0) throw Error("OriginalGeometricMeasure: You must choose Rcutoff > 0.");
|
---|
501 | setTauMode(UNNORMALIZED_EVENT_SHAPE);
|
---|
502 | setAxisScaling(false); // No need to rescale axes (for speed up in one-pass minimization)
|
---|
503 | }
|
---|
504 |
|
---|
505 | /// Description
|
---|
506 | virtual std::string description() const;
|
---|
507 | /// For copying purposes
|
---|
508 | virtual OriginalGeometricMeasure* create() const {return new OriginalGeometricMeasure(*this);}
|
---|
509 |
|
---|
510 | // This class uses the default jet_distance_squared and beam_distance_squared
|
---|
511 |
|
---|
512 | /// true jet measure
|
---|
513 | virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
514 | return dot_product(lightFrom(axis), particle)/_RcutoffSq;
|
---|
515 | }
|
---|
516 |
|
---|
517 | /// true beam measure
|
---|
518 | virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
|
---|
519 | fastjet::PseudoJet beam_a(0,0,1,1);
|
---|
520 | fastjet::PseudoJet beam_b(0,0,-1,1);
|
---|
521 | double min_perp = std::min(dot_product(beam_a, particle),dot_product(beam_b, particle));
|
---|
522 | return min_perp;
|
---|
523 | }
|
---|
524 |
|
---|
525 | /// no denominator needed for this measure.
|
---|
526 | virtual double denominator(const fastjet::PseudoJet& /*particle*/) const {
|
---|
527 | return std::numeric_limits<double>::quiet_NaN();
|
---|
528 | }
|
---|
529 |
|
---|
530 | protected:
|
---|
531 | double _Rcutoff; ///< Effective jet radius (rho = R^2)
|
---|
532 | double _RcutoffSq; ///< Effective jet radius squared
|
---|
533 |
|
---|
534 | };
|
---|
535 |
|
---|
536 |
|
---|
537 | ///------------------------------------------------------------------------
|
---|
538 | /// \class ModifiedGeometricMeasure
|
---|
539 | /// \brief Dimensionful event-shape measure, with dot-product distances, modified beam measure
|
---|
540 | ///
|
---|
541 | /// This class is the Modified geometric measure. This jet measure is defined by the Lorentz dot product between
|
---|
542 | /// the particle and the axis, as in the Original Geometric Measure. The beam measure is defined differently from
|
---|
543 | /// the above OriginalGeometric to allow for more conical jets. New in Nsubjettiness v2.2
|
---|
544 | ///------------------------------------------------------------------------
|
---|
545 | class ModifiedGeometricMeasure : public MeasureDefinition {
|
---|
546 |
|
---|
547 | public:
|
---|
548 | /// Constructor
|
---|
549 | ModifiedGeometricMeasure(double Rcutoff)
|
---|
550 | : MeasureDefinition(), _Rcutoff(Rcutoff), _RcutoffSq(sq(Rcutoff)) {
|
---|
551 | if (Rcutoff <= 0) throw Error("ModifiedGeometricMeasure: You must choose Rcutoff > 0.");
|
---|
552 | setTauMode(UNNORMALIZED_EVENT_SHAPE);
|
---|
553 | setAxisScaling(false); // No need to rescale axes (for speed up in one-pass minimization)
|
---|
554 | }
|
---|
555 |
|
---|
556 | /// Description
|
---|
557 | virtual std::string description() const;
|
---|
558 | /// For copying purposes
|
---|
559 | virtual ModifiedGeometricMeasure* create() const {return new ModifiedGeometricMeasure(*this);}
|
---|
560 |
|
---|
561 | // This class uses the default jet_distance_squared and beam_distance_squared
|
---|
562 |
|
---|
563 | /// True jet measure
|
---|
564 | virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
565 | return dot_product(lightFrom(axis), particle)/_RcutoffSq;
|
---|
566 | }
|
---|
567 |
|
---|
568 | /// True beam measure
|
---|
569 | virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
|
---|
570 | fastjet::PseudoJet lightParticle = lightFrom(particle);
|
---|
571 | return 0.5*particle.mperp()*lightParticle.pt();
|
---|
572 | }
|
---|
573 |
|
---|
574 | /// This measure does not require a denominator
|
---|
575 | virtual double denominator(const fastjet::PseudoJet& /*particle*/) const {
|
---|
576 | return std::numeric_limits<double>::quiet_NaN();
|
---|
577 | }
|
---|
578 |
|
---|
579 | protected:
|
---|
580 | double _Rcutoff; ///< Effective jet radius (rho = R^2)
|
---|
581 | double _RcutoffSq; ///< Effective jet radius squared
|
---|
582 |
|
---|
583 |
|
---|
584 | };
|
---|
585 |
|
---|
586 | ///------------------------------------------------------------------------
|
---|
587 | /// \class ConicalGeometricMeasure
|
---|
588 | /// \brief Dimensionful event-shape measure, basis for XCone jet algorithm
|
---|
589 | ///
|
---|
590 | /// This class is the Conical Geometric measure. This measure is defined by the Lorentz dot product between
|
---|
591 | /// the particle and the axis normalized by the axis and particle pT, as well as a factor of cosh(y) to vary
|
---|
592 | /// the rapidity depepdence of the beam. New in Nsubjettiness v2.2, and the basis for the XCone jet algorithm
|
---|
593 | ///------------------------------------------------------------------------
|
---|
594 | class ConicalGeometricMeasure : public MeasureDefinition {
|
---|
595 |
|
---|
596 | public:
|
---|
597 |
|
---|
598 | /// Constructor
|
---|
599 | ConicalGeometricMeasure(double jet_beta, double beam_gamma, double Rcutoff)
|
---|
600 | : MeasureDefinition(), _jet_beta(jet_beta), _beam_gamma(beam_gamma), _Rcutoff(Rcutoff), _RcutoffSq(sq(Rcutoff)){
|
---|
601 | if (jet_beta <= 0) throw Error("ConicalGeometricMeasure: You must choose beta > 0.");
|
---|
602 | if (beam_gamma <= 0) throw Error("ConicalGeometricMeasure: You must choose gamma > 0.");
|
---|
603 | if (Rcutoff <= 0) throw Error("ConicalGeometricMeasure: You must choose Rcutoff > 0.");
|
---|
604 | setTauMode(UNNORMALIZED_EVENT_SHAPE);
|
---|
605 | }
|
---|
606 |
|
---|
607 | /// Description
|
---|
608 | virtual std::string description() const;
|
---|
609 | /// For copying purposes
|
---|
610 | virtual ConicalGeometricMeasure* create() const {return new ConicalGeometricMeasure(*this);}
|
---|
611 |
|
---|
612 | /// fast jet measure
|
---|
613 | virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
614 | fastjet::PseudoJet lightAxis = lightFrom(axis);
|
---|
615 | double pseudoRsquared = 2.0*dot_product(lightFrom(axis),particle)/(lightAxis.pt()*particle.pt());
|
---|
616 | return pseudoRsquared;
|
---|
617 | }
|
---|
618 |
|
---|
619 | /// fast beam measure
|
---|
620 | virtual double beam_distance_squared(const fastjet::PseudoJet& /*particle*/) const {
|
---|
621 | return _RcutoffSq;
|
---|
622 | }
|
---|
623 |
|
---|
624 | /// true jet measure
|
---|
625 | virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
626 | double jet_dist = jet_distance_squared(particle,axis)/_RcutoffSq;
|
---|
627 | if (jet_dist > 0.0) {
|
---|
628 | fastjet::PseudoJet lightParticle = lightFrom(particle);
|
---|
629 | double weight = (_beam_gamma == 1.0) ? 1.0 : std::pow(0.5*lightParticle.pt(),_beam_gamma - 1.0);
|
---|
630 | return particle.pt() * weight * std::pow(jet_dist,_jet_beta/2.0);
|
---|
631 | } else {
|
---|
632 | return 0.0;
|
---|
633 | }
|
---|
634 | }
|
---|
635 |
|
---|
636 | /// true beam measure
|
---|
637 | virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
|
---|
638 | fastjet::PseudoJet lightParticle = lightFrom(particle);
|
---|
639 | double weight = (_beam_gamma == 1.0) ? 1.0 : std::pow(0.5*lightParticle.pt(),_beam_gamma - 1.0);
|
---|
640 | return particle.pt() * weight;
|
---|
641 | }
|
---|
642 |
|
---|
643 | /// no denominator needed
|
---|
644 | virtual double denominator(const fastjet::PseudoJet& /*particle*/) const {
|
---|
645 | return std::numeric_limits<double>::quiet_NaN();
|
---|
646 | }
|
---|
647 |
|
---|
648 | protected:
|
---|
649 | double _jet_beta; ///< jet angular exponent
|
---|
650 | double _beam_gamma; ///< beam angular exponent (gamma = 1.0 is recommended)
|
---|
651 | double _Rcutoff; ///< effective jet radius
|
---|
652 | double _RcutoffSq; ///< effective jet radius squared
|
---|
653 |
|
---|
654 | };
|
---|
655 |
|
---|
656 | ///------------------------------------------------------------------------
|
---|
657 | /// \class XConeMeasure
|
---|
658 | /// \brief Dimensionful event-shape measure used in XCone jet algorithm
|
---|
659 | ///
|
---|
660 | /// This class is the XCone Measure. This is the default measure for use with the
|
---|
661 | /// XCone algorithm. It is identical to the conical geometric measure but with gamma = 1.0.
|
---|
662 | ///------------------------------------------------------------------------
|
---|
663 | class XConeMeasure : public ConicalGeometricMeasure {
|
---|
664 |
|
---|
665 | public:
|
---|
666 | /// Constructor
|
---|
667 | XConeMeasure(double jet_beta, double R)
|
---|
668 | : ConicalGeometricMeasure(jet_beta,
|
---|
669 | 1.0, // beam_gamma, hard coded at gamma = 1.0 default
|
---|
670 | R // Rcutoff scale
|
---|
671 | ) { }
|
---|
672 |
|
---|
673 | /// Description
|
---|
674 | virtual std::string description() const;
|
---|
675 | /// For copying purposes
|
---|
676 | virtual XConeMeasure* create() const {return new XConeMeasure(*this);}
|
---|
677 |
|
---|
678 | };
|
---|
679 |
|
---|
680 | ///------------------------------------------------------------------------
|
---|
681 | /// \class LightLikeAxis
|
---|
682 | /// \brief Helper class to define light-like axes directions
|
---|
683 | ///
|
---|
684 | /// This is a helper class for the minimization routines.
|
---|
685 | /// It creates a convenient way of defining axes in order to better facilitate calculations.
|
---|
686 | ///------------------------------------------------------------------------
|
---|
687 | class LightLikeAxis {
|
---|
688 |
|
---|
689 | public:
|
---|
690 | /// Bare constructor
|
---|
691 | LightLikeAxis() : _rap(0.0), _phi(0.0), _weight(0.0), _mom(0.0) {}
|
---|
692 | /// Constructor
|
---|
693 | LightLikeAxis(double my_rap, double my_phi, double my_weight, double my_mom) :
|
---|
694 | _rap(my_rap), _phi(my_phi), _weight(my_weight), _mom(my_mom) {}
|
---|
695 |
|
---|
696 | /// Rapidity
|
---|
697 | double rap() const {return _rap;}
|
---|
698 | /// Azimuth
|
---|
699 | double phi() const {return _phi;}
|
---|
700 | /// weight factor
|
---|
701 | double weight() const {return _weight;}
|
---|
702 | /// pt momentum
|
---|
703 | double mom() const {return _mom;}
|
---|
704 |
|
---|
705 | /// set rapidity
|
---|
706 | void set_rap(double my_set_rap) {_rap = my_set_rap;}
|
---|
707 | /// set azimuth
|
---|
708 | void set_phi(double my_set_phi) {_phi = my_set_phi;}
|
---|
709 | /// set weight factor
|
---|
710 | void set_weight(double my_set_weight) {_weight = my_set_weight;}
|
---|
711 | /// set pt momentum
|
---|
712 | void set_mom(double my_set_mom) {_mom = my_set_mom;}
|
---|
713 | /// set all kinematics
|
---|
714 | void reset(double my_rap, double my_phi, double my_weight, double my_mom) {_rap=my_rap; _phi=my_phi; _weight=my_weight; _mom=my_mom;}
|
---|
715 |
|
---|
716 | /// Return PseudoJet version
|
---|
717 | fastjet::PseudoJet ConvertToPseudoJet();
|
---|
718 |
|
---|
719 | /// Squared distance to PseudoJet
|
---|
720 | double DistanceSq(const fastjet::PseudoJet& input) const {
|
---|
721 | return DistanceSq(input.rap(),input.phi());
|
---|
722 | }
|
---|
723 |
|
---|
724 | /// Distance to PseudoJet
|
---|
725 | double Distance(const fastjet::PseudoJet& input) const {
|
---|
726 | return std::sqrt(DistanceSq(input));
|
---|
727 | }
|
---|
728 |
|
---|
729 | /// Squared distance to Lightlikeaxis
|
---|
730 | double DistanceSq(const LightLikeAxis& input) const {
|
---|
731 | return DistanceSq(input.rap(),input.phi());
|
---|
732 | }
|
---|
733 |
|
---|
734 | /// Distance to Lightlikeaxis
|
---|
735 | double Distance(const LightLikeAxis& input) const {
|
---|
736 | return std::sqrt(DistanceSq(input));
|
---|
737 | }
|
---|
738 |
|
---|
739 | private:
|
---|
740 | double _rap; ///< rapidity
|
---|
741 | double _phi; ///< azimuth
|
---|
742 | double _weight; ///< weight factor
|
---|
743 | double _mom; ///< pt momentum
|
---|
744 |
|
---|
745 | /// Internal squared distance calculation
|
---|
746 | double DistanceSq(double rap2, double phi2) const {
|
---|
747 | double rap1 = _rap;
|
---|
748 | double phi1 = _phi;
|
---|
749 |
|
---|
750 | double distRap = rap1-rap2;
|
---|
751 | double distPhi = std::fabs(phi1-phi2);
|
---|
752 | if (distPhi > M_PI) {distPhi = 2.0*M_PI - distPhi;}
|
---|
753 | return distRap*distRap + distPhi*distPhi;
|
---|
754 | }
|
---|
755 |
|
---|
756 | /// Internal distance calculation
|
---|
757 | double Distance(double rap2, double phi2) const {
|
---|
758 | return std::sqrt(DistanceSq(rap2,phi2));
|
---|
759 | }
|
---|
760 |
|
---|
761 | };
|
---|
762 |
|
---|
763 |
|
---|
764 | ////------------------------------------------------------------------------
|
---|
765 | ///// \class DeprecatedGeometricCutoffMeasure
|
---|
766 | //// This class is the old, incorrectly coded geometric measure.
|
---|
767 | //// It is kept in case anyone wants to check old code, but should not be used for production purposes.
|
---|
768 | //class DeprecatedGeometricCutoffMeasure : public MeasureDefinition {
|
---|
769 | //
|
---|
770 | //public:
|
---|
771 | //
|
---|
772 | // // Please, please don't use this.
|
---|
773 | // DeprecatedGeometricCutoffMeasure(double jet_beta, double Rcutoff)
|
---|
774 | // : MeasureDefinition(),
|
---|
775 | // _jet_beta(jet_beta),
|
---|
776 | // _beam_beta(1.0), // This is hard coded, since alternative beta_beam values were never checked.
|
---|
777 | // _Rcutoff(Rcutoff),
|
---|
778 | // _RcutoffSq(sq(Rcutoff)) {
|
---|
779 | // setTauMode(UNNORMALIZED_EVENT_SHAPE);
|
---|
780 | // setAxisScaling(false);
|
---|
781 | // if (jet_beta != 2.0) {
|
---|
782 | // throw Error("Geometric minimization is currently only defined for beta = 2.0.");
|
---|
783 | // }
|
---|
784 | // }
|
---|
785 | //
|
---|
786 | // virtual std::string description() const;
|
---|
787 | //
|
---|
788 | // virtual DeprecatedGeometricCutoffMeasure* create() const {return new DeprecatedGeometricCutoffMeasure(*this);}
|
---|
789 | //
|
---|
790 | // virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
791 | // fastjet::PseudoJet lightAxis = lightFrom(axis);
|
---|
792 | // double pseudoRsquared = 2.0*dot_product(lightFrom(axis),particle)/(lightAxis.pt()*particle.pt());
|
---|
793 | // return pseudoRsquared;
|
---|
794 | // }
|
---|
795 | //
|
---|
796 | // virtual double beam_distance_squared(const fastjet::PseudoJet& /*particle*/) const {
|
---|
797 | // return _RcutoffSq;
|
---|
798 | // }
|
---|
799 | //
|
---|
800 | // virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
|
---|
801 | // fastjet::PseudoJet lightAxis = lightFrom(axis);
|
---|
802 | // double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(lightAxis.pt(),_beam_beta - 1.0);
|
---|
803 | // return particle.pt() * weight * std::pow(jet_distance_squared(particle,axis),_jet_beta/2.0);
|
---|
804 | // }
|
---|
805 | //
|
---|
806 | // virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
|
---|
807 | // double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(particle.pt()/particle.e(),_beam_beta - 1.0);
|
---|
808 | // return particle.pt() * weight * std::pow(_Rcutoff,_jet_beta);
|
---|
809 | // }
|
---|
810 | //
|
---|
811 | // virtual double denominator(const fastjet::PseudoJet& /*particle*/) const {
|
---|
812 | // return std::numeric_limits<double>::quiet_NaN();
|
---|
813 | // }
|
---|
814 | //
|
---|
815 | // virtual std::vector<fastjet::PseudoJet> get_one_pass_axes(int n_jets,
|
---|
816 | // const std::vector<fastjet::PseudoJet>& inputs,
|
---|
817 | // const std::vector<fastjet::PseudoJet>& seedAxes,
|
---|
818 | // int nAttempts, // cap number of iterations
|
---|
819 | // double accuracy // cap distance of closest approach
|
---|
820 | // ) const;
|
---|
821 | //
|
---|
822 | //protected:
|
---|
823 | // double _jet_beta;
|
---|
824 | // double _beam_beta;
|
---|
825 | // double _Rcutoff;
|
---|
826 | // double _RcutoffSq;
|
---|
827 | //
|
---|
828 | //};
|
---|
829 | //
|
---|
830 | //// ------------------------------------------------------------------------
|
---|
831 | //// / \class DeprecatedGeometricMeasure
|
---|
832 | //// Same as DeprecatedGeometricMeasureCutoffMeasure, but with Rcutoff taken to infinity.
|
---|
833 | //// NOTE: This class should not be used for production purposes.
|
---|
834 | //class DeprecatedGeometricMeasure : public DeprecatedGeometricCutoffMeasure {
|
---|
835 | //
|
---|
836 | //public:
|
---|
837 | // DeprecatedGeometricMeasure(double beta)
|
---|
838 | // : DeprecatedGeometricCutoffMeasure(beta,std::numeric_limits<double>::max()) {
|
---|
839 | // _RcutoffSq = std::numeric_limits<double>::max();
|
---|
840 | // setTauMode(UNNORMALIZED_JET_SHAPE);
|
---|
841 | // }
|
---|
842 | //
|
---|
843 | // virtual std::string description() const;
|
---|
844 | //
|
---|
845 | // virtual DeprecatedGeometricMeasure* create() const {return new DeprecatedGeometricMeasure(*this);}
|
---|
846 | //};
|
---|
847 |
|
---|
848 |
|
---|
849 | } //namespace contrib
|
---|
850 |
|
---|
851 | FASTJET_END_NAMESPACE
|
---|
852 |
|
---|
853 | #endif // __FASTJET_CONTRIB_MEASUREDEFINITION_HH__
|
---|