Fork me on GitHub

source: svn/trunk/external/fastjet/Selector.hh@ 1352

Last change on this file since 1352 was 1332, checked in by Pavel Demin, 11 years ago

upgrade fastjet to 3.0.6

File size: 18.2 KB
Line 
1#ifndef __FASTJET_SELECTOR_HH__
2#define __FASTJET_SELECTOR_HH__
3
4//STARTHEADER
5// $Id: Selector.hh 3203 2013-09-15 07:49:50Z salam $
6//
7// Copyright (c) 2009-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
8//
9//----------------------------------------------------------------------
10// This file is part of FastJet.
11//
12// FastJet is free software; you can redistribute it and/or modify
13// it under the terms of the GNU General Public License as published by
14// the Free Software Foundation; either version 2 of the License, or
15// (at your option) any later version.
16//
17// The algorithms that underlie FastJet have required considerable
18// development and are described in hep-ph/0512210. If you use
19// FastJet as part of work towards a scientific publication, please
20// include a citation to the FastJet paper.
21//
22// FastJet is distributed in the hope that it will be useful,
23// but WITHOUT ANY WARRANTY; without even the implied warranty of
24// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25// GNU General Public License for more details.
26//
27// You should have received a copy of the GNU General Public License
28// along with FastJet. If not, see <http://www.gnu.org/licenses/>.
29//----------------------------------------------------------------------
30//ENDHEADER
31
32#include "fastjet/PseudoJet.hh"
33#ifndef __FJCORE__
34#include "fastjet/RangeDefinition.hh" // for initialisation from a RangeDefinition
35#endif // __FJCORE__
36#include <limits>
37#include <cmath>
38
39FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
40
41//----------------------------------------------------------------------
42/// @ingroup selectors
43/// \class Selector
44/// Class that encodes information about cuts and other selection
45/// criteria that can be applied to PseudoJet(s).
46///
47class Selector;
48//----------------------------------------------------------------------
49
50/// @ingroup selectors
51/// \class SelectorWorker
52/// default selector worker is an abstract virtual base class
53///
54/// The Selector class is only an interface, it is the SelectorWorker
55/// that really does the work. To implement various selectors, one
56/// thus has to overload this class.
57class SelectorWorker {
58public:
59 //----------------------------------------------------------
60 // fundamental info
61 //----------------------------------------------------------
62 /// default dtor
63 virtual ~SelectorWorker() {}
64
65 //----------------------------------------------------------
66 // basic operations for checking what gets selected
67 //----------------------------------------------------------
68
69 /// returns true if a given object passes the selection criterion.
70 /// This has to be overloaded by derived workers
71 virtual bool pass(const PseudoJet & jet) const = 0;
72
73 /// For each jet that does not pass the cuts, this routine sets the
74 /// pointer to 0.
75 ///
76 /// It does not assume that the PseudoJet* passed as argumetn are not NULL
77 virtual void terminator(std::vector<const PseudoJet *> & jets) const {
78 for (unsigned i = 0; i < jets.size(); i++) {
79 if (jets[i] && !pass(*jets[i])) jets[i] = NULL;
80 }
81 }
82
83 /// returns true if this can be applied jet by jet
84 virtual bool applies_jet_by_jet() const {return true;}
85
86 /// returns a description of the worker
87 virtual std::string description() const {return "missing description";}
88
89
90 //----------------------------------------------------------
91 // operations for dealing with reference jets
92 //----------------------------------------------------------
93
94 /// returns true if the worker is defined with respect to a reference jet
95 virtual bool takes_reference() const { return false;}
96
97 /// sets the reference jet for the selector
98 /// NB: "reference" is commented to avoid unused-variable compiler warnings
99 virtual void set_reference(const PseudoJet & /*reference*/){
100 throw Error("set_reference(...) cannot be used for a selector worker that does not take a reference");
101 }
102
103 /// return a copy of the current object.
104 ///
105 /// This function is only called for objects that take a reference and need
106 /// not be reimplemented otherwise.
107 virtual SelectorWorker* copy(){
108 throw Error("this SelectorWorker has nothing to copy");
109 }
110
111 //----------------------------------------------------------
112 // operations for area and extent
113 //----------------------------------------------------------
114
115 /// returns the rapidity range for which it may return "true"
116 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const {
117 rapmax = std::numeric_limits<double>::infinity();
118 rapmin = -rapmax;
119 }
120
121 /// check if it is a geometric selector (i.e. only puts constraints
122 /// on rapidity and azimuthal angle)
123 virtual bool is_geometric() const { return false;}
124
125 /// check if it has a finite area
126 virtual bool has_finite_area() const;
127
128 /// check if it has an analytically computable area
129 virtual bool has_known_area() const { return false;}
130
131 /// if it has a computable area, return it
132 virtual double known_area() const{
133 throw Error("this selector has no computable area");
134 }
135};
136
137//----------------------------------------------------------------------
138// class Selector
139//
140// Class that encodes information about cuts that
141class Selector{
142public:
143 /// default constructor produces a Selector whose action is undefined
144 /// (any attempt to use it will lead to an error)
145 Selector() {}
146
147 /// constructor that causes the Selector to use the supplied worker
148 ///
149 /// Note that the Selector takes ownership of the pointer to the
150 /// worker (and so will delete automatically when appropriate).
151 Selector(SelectorWorker * worker_in) {_worker.reset(worker_in);}
152
153
154#ifndef __FJCORE__
155 /// ctor from a RangeDefinition
156 ///
157 /// This is provided for backward compatibility and will be removed in
158 /// a future major release of FastJet
159 ///
160 /// Watch out that the Selector will only hold a pointer to the
161 /// range so the selector will crash if one tries to use it after
162 /// the range has gone out of scope. We thus strongly advise against
163 /// the direct use of this constructor.
164 Selector(const RangeDefinition &range);
165#endif // __FJCORE__
166
167 /// dummy virtual dtor
168 virtual ~Selector(){}
169
170 /// return true if the jet passes the selection
171 bool pass(const PseudoJet & jet) const {
172 if (!validated_worker()->applies_jet_by_jet()) {
173 throw Error("Cannot apply this selector to an individual jet");
174 }
175 return _worker->pass(jet);
176 }
177
178 /// an operator way of knowing whether a given jet passes the selection or not
179 bool operator()(const PseudoJet & jet) const {
180 return pass(jet);
181 }
182
183 /// Return a count of the objects that pass the selection.
184 ///
185 /// This will often be more efficient that getting the vector of objects that
186 /// passes and then evaluating the size of the vector
187 unsigned int count(const std::vector<PseudoJet> & jets) const;
188
189 /// sift the input jets into two vectors -- those that pass the selector
190 /// and those that do not
191 void sift(const std::vector<PseudoJet> & jets,
192 std::vector<PseudoJet> & jets_that_pass,
193 std::vector<PseudoJet> & jets_that_fail) const;
194
195 /// returns true if this can be applied jet by jet
196 bool applies_jet_by_jet() const {
197 return validated_worker()->applies_jet_by_jet();
198 }
199
200 /// returns a vector with the jets that pass the selection
201 std::vector<PseudoJet> operator()(const std::vector<PseudoJet> & jets) const;
202
203 /// For each jet that does not pass the cuts, this routine sets the
204 /// pointer to 0.
205 ///
206 /// It is legitimate for some (or all) of the pointers that are
207 /// passed to already be NULL.
208 virtual void nullify_non_selected(std::vector<const PseudoJet *> & jets) const {
209 validated_worker()->terminator(jets);
210 }
211
212 /// returns the rapidity range for which it may return "true"
213 void get_rapidity_extent(double &rapmin, double &rapmax) const {
214 return validated_worker()->get_rapidity_extent(rapmin, rapmax);
215 }
216
217 /// returns a textual description of the selector
218 std::string description() const {
219 return validated_worker()->description();
220 }
221
222 /// returns true if it is a geometric selector (i.e. one that only puts
223 /// constraints on rapidities and azimuthal angles)
224 bool is_geometric() const{
225 return validated_worker()->is_geometric();
226 }
227
228 /// returns true if it has a meaningful and finite area (i.e. the
229 /// Selector has the property that is_geometric() returns true and
230 /// the rapidity extent is finite).
231 bool has_finite_area() const{
232 return validated_worker()->has_finite_area();
233 }
234
235#ifndef __FJCORE__
236 /// returns the rapidity-phi area associated with the Selector
237 /// (throws InvalidArea if the area does not make sense).
238 ///
239 /// If the result is not known analytically, the area will be
240 /// estimated using a pseudo Monte Carlo method (as for jet areas),
241 /// using the default ghost area from the GhostedAreaSpec class
242 /// (0.01). The Monte Carlo estimate involves a time penalty
243 /// proportional to the ratio of the rapidity extent of the Selector
244 /// divided by the ghost area.
245 double area() const;
246
247 /// returns the rapidity-phi area associated with the Selector
248 /// (throws InvalidArea if the area does not make sense).
249 ///
250 /// The behaviour is the as with the area() call, but with the
251 /// ability to additionally specify the ghost area to be used in the
252 /// case of a Monte Carlo area evaluation.
253 ///
254 double area(double ghost_area) const;
255#endif // __FJCORE__
256
257 /// returns a (reference to) the underlying worker's shared pointer
258 const SharedPtr<SelectorWorker> & worker() const {return _worker;}
259
260 /// returns a worker if there is a valid one, otherwise throws an InvalidWorker error
261 const SelectorWorker* validated_worker() const {
262 const SelectorWorker* worker_ptr = _worker.get();
263 if (worker_ptr == 0) throw InvalidWorker();
264 return worker_ptr;
265 }
266
267 /// returns true if this can be applied jet by jet
268 bool takes_reference() const {
269 return validated_worker()->takes_reference();
270 }
271
272 /// set the reference jet for this Selector
273 const Selector & set_reference(const PseudoJet &reference){
274
275 // if the worker does not take a reference jet, do nothing
276 if (! validated_worker()->takes_reference()){
277 return *this;
278 }
279
280 // since this is a non-const operation, make sure we have a
281 // correct behaviour with respect to shared workers
282 _copy_worker_if_needed();
283
284 _worker->set_reference(reference);
285 return *this;
286 }
287
288 /// class that gets throw when a Selector is applied despite it not
289 /// having a valid underlying worker.
290 class InvalidWorker : public Error {
291 public:
292 InvalidWorker() : Error("Attempt to use Selector with no valid underlying worker") {}
293 };
294
295 /// class that gets throw when a Selector is applied despite it not
296 /// having a valid underlying worker.
297 class InvalidArea : public Error {
298 public:
299 InvalidArea() : Error("Attempt to obtain area from Selector for which this is not meaningful") {}
300 };
301
302 // some operators (applying directly on a Selector)
303 //----------------------------------------------------------------------
304 /// For 2 Selectors a and b, a &= b is eauivalent to a = a && b;
305 Selector & operator &=(const Selector & b);
306
307 /// For 2 Selectors a and b, a |= b is eauivalent to a = a || b;
308 Selector & operator |=(const Selector & b);
309
310
311protected:
312 /// Helper for copying selector workers if needed
313 ///
314 /// The following is needed if we want to modify a selectors that
315 /// shares a worker with another selector. In that case, we need to
316 /// get another copy of the worker to avoid interferences
317 ///
318 /// Note that any non-const operation has to call this to behave
319 /// correctly w.r.t shared workers!
320 void _copy_worker_if_needed(){
321 // do nothing if there's a sinlge user of the worker
322 if (_worker.unique()) return;
323
324 // call the worker's copy
325 //std::cout << "will make a copy of " << description() << std::endl;
326 _worker.reset(_worker->copy());
327 }
328
329private:
330 SharedPtr<SelectorWorker> _worker; ///< the underlying worker
331};
332
333
334//----------------------------------------------------------------------
335// a list of specific selectors
336//----------------------------------------------------------------------
337
338/// \addtogroup selectors
339/// @{
340
341
342// fundamental selectors
343//----------------------------------------------------------------------
344
345// "identity" selector that lets everything pass
346Selector SelectorIdentity();
347
348// logical operations
349//----------------------------------------------------------------------
350
351/// logical not applied on a selector
352///
353/// This will keep objects that do not pass the 's' selector
354Selector operator!(const Selector & s);
355
356/// logical or between two selectors
357///
358/// this will keep the objects that are selected by s1 or s2
359Selector operator ||(const Selector & s1, const Selector & s2);
360
361
362/// logical and between two selectors
363///
364/// this will keep the objects that are selected by both s1 and s2
365///
366/// watch out: for both s1 and s2, the selection is applied on the
367/// original list of objects. For successive applications of two
368/// selectors (convolution/multiplication) see the operator *
369Selector operator&&(const Selector & s1, const Selector & s2);
370
371/// successive application of 2 selectors
372///
373/// Apply the selector s2, then the selector s1.
374///
375/// watch out: the operator * acts like an operator product i.e. does
376/// not commute. The order of its arguments is therefore important.
377/// Whenever they commute (in particluar, when they apply jet by
378/// jet), this would have the same effect as the logical &&.
379Selector operator*(const Selector & s1, const Selector & s2);
380
381
382// selection with kinematic cuts
383//----------------------------------------------------------------------
384Selector SelectorPtMin(double ptmin); ///< select objects with pt >= ptmin
385Selector SelectorPtMax(double ptmax); ///< select objects with pt <= ptmax
386Selector SelectorPtRange(double ptmin, double ptmax); ///< select objects with ptmin <= pt <= ptmax
387
388Selector SelectorEtMin(double Etmin); ///< select objects with Et >= Etmin
389Selector SelectorEtMax(double Etmax); ///< select objects with Et <= Etmax
390Selector SelectorEtRange(double Etmin, double Etmax); ///< select objects with Etmin <= Et <= Etmax
391
392Selector SelectorEMin(double Emin); ///< select objects with E >= Emin
393Selector SelectorEMax(double Emax); ///< select objects with E <= Emax
394Selector SelectorERange(double Emin, double Emax); ///< select objects with Emin <= E <= Emax
395
396Selector SelectorMassMin(double Mmin); ///< select objects with Mass >= Mmin
397Selector SelectorMassMax(double Mmax); ///< select objects with Mass <= Mmax
398Selector SelectorMassRange(double Mmin, double Mmax); ///< select objects with Mmin <= Mass <= Mmax
399
400Selector SelectorRapMin(double rapmin); ///< select objects with rap >= rapmin
401Selector SelectorRapMax(double rapmax); ///< select objects with rap <= rapmax
402Selector SelectorRapRange(double rapmin, double rapmax); ///< select objects with rapmin <= rap <= rapmax
403
404Selector SelectorAbsRapMin(double absrapmin); ///< select objects with |rap| >= absrapmin
405Selector SelectorAbsRapMax(double absrapmax); ///< select objects with |rap| <= absrapmax
406Selector SelectorAbsRapRange(double absrapmin, double absrapmax); ///< select objects with absrapmin <= |rap| <= absrapmax
407
408Selector SelectorEtaMin(double etamin); ///< select objects with eta >= etamin
409Selector SelectorEtaMax(double etamax); ///< select objects with eta <= etamax
410Selector SelectorEtaRange(double etamin, double etamax); ///< select objects with etamin <= eta <= etamax
411
412Selector SelectorAbsEtaMin(double absetamin); ///< select objects with |eta| >= absetamin
413Selector SelectorAbsEtaMax(double absetamax); ///< select objects with |eta| <= absetamax
414Selector SelectorAbsEtaRange(double absetamin, double absetamax); ///< select objects with absetamin <= |eta| <= absetamax
415
416Selector SelectorPhiRange(double phimin, double phimax); ///< select objects with phimin <= phi <= phimax
417
418/// select objects with rapmin <= rap <= rapmax && phimin <= phi <= phimax
419///
420/// Note that this is essentially a combination of SelectorRapRange
421/// and SelectorPhiRange. We provide it as a Selector on its own in
422/// order to use the known area (which would otherwise be lost by the &&
423/// operator)
424Selector SelectorRapPhiRange(double rapmin, double rapmax, double phimin, double phimax);
425
426/// select the n hardest objects
427Selector SelectorNHardest(unsigned int n);
428
429
430// Selectors that take (require) a reference jet.
431//----------------------------------------------------------------------
432
433/// select objets within a distance 'radius' from the location of the
434/// reference jet, set by Selector::set_reference(...)
435Selector SelectorCircle(const double & radius);
436
437/// select objets with distance from the reference jet is between 'radius_in'
438/// and 'radius_out'; the reference jet is set by Selector::set_reference(...)
439Selector SelectorDoughnut(const double & radius_in, const double & radius_out);
440
441/// select objets within a rapidity distance 'half_width' from the
442/// location of the reference jet, set by Selector::set_reference(...)
443Selector SelectorStrip(const double & half_width);
444
445/// select objets within rapidity distance 'half_rap_width' from the
446/// reference jet and azimuthal-angle distance within 'half_phi_width'; the
447/// reference jet is set by Selector::set_reference(...)
448Selector SelectorRectangle(const double & half_rap_width, const double & half_phi_width);
449
450
451/// select objects that carry at least a fraction "fraction" of the
452/// reference jet. The reference jet must have been set with
453/// Selector::set_reference(...)
454Selector SelectorPtFractionMin(double fraction);
455
456
457// additional (mostly helper) selectors
458//----------------------------------------------------------------------
459
460/// select PseudoJet with 0 momentum
461Selector SelectorIsZero();
462
463#ifndef __FJCORE__
464/// select objects that are (or are only made of) ghosts.
465/// PseudoJets for which has_area() are considered non-pure-ghost.
466Selector SelectorIsPureGhost();
467#endif // __FJCORE__
468
469/// @}
470
471FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh
472
473#endif // __FASTJET_SELECTOR_HH__
474
Note: See TracBrowser for help on using the repository browser.