FastJet  3.2.1
ClusterSequenceStructure.cc
1 //FJSTARTHEADER
2 // $Id: ClusterSequenceStructure.cc 3433 2014-07-23 08:17:03Z salam $
3 //
4 // Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
5 //
6 //----------------------------------------------------------------------
7 // This file is part of FastJet.
8 //
9 // FastJet is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // The algorithms that underlie FastJet have required considerable
15 // development. They are described in the original FastJet paper,
16 // hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
17 // FastJet as part of work towards a scientific publication, please
18 // quote the version you use and include a citation to the manual and
19 // optionally also to hep-ph/0512210.
20 //
21 // FastJet is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 // GNU General Public License for more details.
25 //
26 // You should have received a copy of the GNU General Public License
27 // along with FastJet. If not, see <http://www.gnu.org/licenses/>.
28 //----------------------------------------------------------------------
29 //FJENDHEADER
30 
31 #include "fastjet/ClusterSequenceStructure.hh"
32 #include "fastjet/Error.hh"
33 #include "fastjet/PseudoJet.hh"
34 #include "fastjet/ClusterSequence.hh"
35 #ifndef __FJCORE__
36 #include "fastjet/ClusterSequenceAreaBase.hh"
37 #endif // __FJCORE__
38 #include <iostream>
39 
40 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
41 
42 using namespace std;
43 
44 ClusterSequenceStructure::~ClusterSequenceStructure(){
45  if (_associated_cs != NULL
46  && _associated_cs->will_delete_self_when_unused()) {
47  // automatically handle deletion of the cluster sequence;
48  // execution should only ever reach this point if the user had
49  // called CS::delete_self_when_unused, which resets the count of
50  // the shared pointer to CSS (otherwise the CS's own destructor
51  // will have zeroed the _associated_cs pointer before the shared
52  // pointer count goes to zero [on destruction of the last of the
53  // jets in the CS and the destruction of the CS's copy of the
54  // shared pointer)
55  _associated_cs->signal_imminent_self_deletion();
56  delete _associated_cs;
57  }
58 }
59 
60 
61 //----------------------------------------------------------------------
62 // Direct access to the associated ClusterSequence object.
63 //----------------------------------------------------------------------
64 
65 // check whether this PseudoJet has an associated parent
66 // ClusterSequence
67 bool ClusterSequenceStructure::has_valid_cluster_sequence() const{
68  return (_associated_cs != NULL);
69 }
70 
71 // get a (const) pointer to the associated ClusterSequence (NULL if
72 // inexistent)
73 const ClusterSequence* ClusterSequenceStructure::associated_cluster_sequence() const{
74  return _associated_cs;
75 }
76 
77 
78 // If there is a valid cluster sequence associated with this jet,
79 // returns a pointer to it; otherwise throws an Error.
80 //
81 // Open question: should these errors be upgraded to classes of their
82 // own so that they can be caught? [Maybe, but later]
83 const ClusterSequence * ClusterSequenceStructure::validated_cs() const {
84  if (!_associated_cs)
85  throw Error("you requested information about the internal structure of a jet, but its associated ClusterSequence has gone out of scope.");
86  return _associated_cs;
87 }
88 
89 
90 //----------------------------------------------------------------------
91 // Methods for access to information about jet structure
92 //----------------------------------------------------------------------
93 
94 // check if it has been recombined with another PseudoJet in which
95 // case, return its partner through the argument. Otherwise,
96 // 'partner' is set to 0.
97 //
98 // false is also returned if this PseudoJet has no associated
99 // ClusterSequence
100 bool ClusterSequenceStructure::has_partner(const PseudoJet &reference, PseudoJet &partner) const{
101  return validated_cs()->has_partner(reference, partner);
102 }
103 
104 // check if it has been recombined with another PseudoJet in which
105 // case, return its child through the argument. Otherwise, 'child'
106 // is set to 0.
107 //
108 // false is also returned if this PseudoJet has no associated
109 // ClusterSequence, with the child set to 0
110 bool ClusterSequenceStructure::has_child(const PseudoJet &reference, PseudoJet &child) const{
111  return validated_cs()->has_child(reference, child);
112 }
113 
114 // check if it is the product of a recombination, in which case
115 // return the 2 parents through the 'parent1' and 'parent2'
116 // arguments. Otherwise, set these to 0.
117 //
118 // false is also returned if this PseudoJet has no parent
119 // ClusterSequence
120 bool ClusterSequenceStructure::has_parents(const PseudoJet &reference, PseudoJet &parent1, PseudoJet &parent2) const{
121  return validated_cs()->has_parents(reference, parent1, parent2);
122 }
123 
124 
125 // check if the reference PseudoJet is inside the "jet" passed as an argument
126 //
127 // an error is thrown if there is no CS associated with one of the 2 jets.
128 // fasle is returned if teh 2 jets do not belong to the same CS
129 bool ClusterSequenceStructure::object_in_jet(const PseudoJet &reference, const PseudoJet &jet) const{
130  if ((!has_associated_cluster_sequence()) || (!jet.has_associated_cluster_sequence()))
131  throw Error("you requested information about the internal structure of a jet, but it is not associated with a ClusterSequence or its associated ClusterSequence has gone out of scope.");
132 
133  if (reference.associated_cluster_sequence() != jet.associated_cluster_sequence()) return false;
134 
135  return validated_cs()->object_in_jet(reference, jet);
136 }
137 
138 
139 // return true if the structure supports constituents.
140 //
141 // an Error is thrown if this PseudoJet has no currently valid
142 // associated ClusterSequence
143 bool ClusterSequenceStructure::has_constituents() const{
144  if (!has_associated_cluster_sequence())
145  throw Error("you requested information about the internal structure of a jet, but it is not associated with a ClusterSequence or its associated ClusterSequence has gone out of scope.");
146 
147  return true;
148 }
149 
150 
151 // retrieve the constituents. An empty vector is returned if there is
152 // no associated ClusterSequence
153 vector<PseudoJet> ClusterSequenceStructure::constituents(const PseudoJet &reference) const{
154  return validated_cs()->constituents(reference);
155 }
156 
157 // return true if the structure supports exclusive_subjets.
158 //
159 // an Error is thrown if this PseudoJet has no currently valid
160 // associated ClusterSequence
161 bool ClusterSequenceStructure::has_exclusive_subjets() const{
162  if (!has_associated_cluster_sequence())
163  throw Error("you requested information about the internal structure of a jet, but it is not associated with a ClusterSequence or its associated ClusterSequence has gone out of scope.");
164 
165  return true;
166 }
167 
168 // return a vector of all subjets of the current jet (in the sense
169 // of the exclusive algorithm) that would be obtained when running
170 // the algorithm with the given dcut.
171 //
172 // Time taken is O(m ln m), where m is the number of subjets that
173 // are found. If m gets to be of order of the total number of
174 // constituents in the jet, this could be substantially slower than
175 // just getting that list of constituents.
176 //
177 // an Error is thrown if this PseudoJet has no currently valid
178 // associated ClusterSequence
179 std::vector<PseudoJet> ClusterSequenceStructure::exclusive_subjets (const PseudoJet &reference, const double & dcut) const {
180  return validated_cs()->exclusive_subjets(reference, dcut);
181 }
182 
183 // return the size of exclusive_subjets(...); still n ln n with same
184 // coefficient, but marginally more efficient than manually taking
185 // exclusive_subjets.size()
186 //
187 // an Error is thrown if this PseudoJet has no currently valid
188 // associated ClusterSequence
189 int ClusterSequenceStructure::n_exclusive_subjets(const PseudoJet &reference, const double & dcut) const {
190  return validated_cs()->n_exclusive_subjets(reference, dcut);
191 }
192 
193 // return the list of subjets obtained by unclustering the supplied
194 // jet down to n subjets (or all constituents if there are fewer
195 // than n).
196 //
197 // requires n ln n time
198 //
199 // an Error is thrown if this PseudoJet has no currently valid
200 // associated ClusterSequence
201 std::vector<PseudoJet> ClusterSequenceStructure::exclusive_subjets_up_to (const PseudoJet &reference, int nsub) const {
202  return validated_cs()->exclusive_subjets_up_to(reference, nsub);
203 }
204 
205 // return the dij that was present in the merging nsub+1 -> nsub
206 // subjets inside this jet.
207 //
208 // an Error is thrown if this PseudoJet has no currently valid
209 // associated ClusterSequence
210 double ClusterSequenceStructure::exclusive_subdmerge(const PseudoJet &reference, int nsub) const {
211  return validated_cs()->exclusive_subdmerge(reference, nsub);
212 }
213 
214 // return the maximum dij that occurred in the whole event at the
215 // stage that the nsub+1 -> nsub merge of subjets occurred inside
216 // this jet.
217 //
218 // an Error is thrown if this PseudoJet has no currently valid
219 // associated ClusterSequence
220 double ClusterSequenceStructure::exclusive_subdmerge_max(const PseudoJet &reference, int nsub) const {
221  return validated_cs()->exclusive_subdmerge_max(reference, nsub);
222 }
223 
224 
225 //----------------------------------------------------------------------
226 // information related to the pieces of the jet
227 //----------------------------------------------------------------------
228 
229 // by convention, a jet associated with a ClusterSequence will have
230 // pieces if it has parents in the cluster sequence.
231 //
232 // an error is thrown if the ClusterSequence is out of scope (since
233 // the answer depends on information in the Cluster Sequence)
234 bool ClusterSequenceStructure::has_pieces(const PseudoJet &reference) const{
235  PseudoJet dummy1, dummy2;
236  return has_parents(reference, dummy1, dummy2);
237 }
238 
239 // by convention, the pieces of a jet associated with a
240 // ClusterSequence are its parents in the Cluster Sequence. If it has
241 // no parents, an empty jet is returned.
242 //
243 // an error is thrown if the ClusterSequence is out of scope
244 vector<PseudoJet> ClusterSequenceStructure::pieces(const PseudoJet &reference) const{
245  PseudoJet j1, j2;
246  vector<PseudoJet> res;
247  if (has_parents(reference, j1, j2)){
248  res.push_back(j1);
249  res.push_back(j2);
250  }
251 
252  return res;
253 }
254 
255 
256 //----------------------------------------------------------------------
257 // the following ones require a computation of the area in the
258 // associated ClusterSequence (See ClusterSequenceAreaBase for details)
259 //----------------------------------------------------------------------
260 
261 #ifndef __FJCORE__
262 // if possible, return a valid ClusterSequenceAreaBase pointer; otherwise
263 // throw an error
264 const ClusterSequenceAreaBase * ClusterSequenceStructure::validated_csab() const {
265  const ClusterSequenceAreaBase *csab = dynamic_cast<const ClusterSequenceAreaBase*>(validated_cs());
266  if (csab == NULL) throw Error("you requested jet-area related information, but the PseudoJet does not have associated area information.");
267  return csab;
268 }
269 
270 // check if it has a defined area
271 bool ClusterSequenceStructure::has_area() const{
272  if (! has_associated_cluster_sequence()) return false;
273  return (dynamic_cast<const ClusterSequenceAreaBase*>(_associated_cs) != NULL);
274 }
275 
276 // return the jet (scalar) area.
277 // throw an Error if there is no support for area in the associated CS
278 double ClusterSequenceStructure::area(const PseudoJet &reference) const{
279  return validated_csab()->area(reference);
280 }
281 
282 // return the error (uncertainty) associated with the determination
283 // of the area of this jet.
284 // throws an Error if there is no support for area in the associated CS
285 double ClusterSequenceStructure::area_error(const PseudoJet &reference) const{
286  return validated_csab()->area_error(reference);
287 }
288 
289 // return the jet 4-vector area
290 // throws an Error if there is no support for area in the associated CS
291 PseudoJet ClusterSequenceStructure::area_4vector(const PseudoJet &reference) const{
292  return validated_csab()->area_4vector(reference);
293 }
294 
295 // true if this jet is made exclusively of ghosts
296 // throws an Error if there is no support for area in the associated CS
297 bool ClusterSequenceStructure::is_pure_ghost(const PseudoJet &reference) const{
298  return validated_csab()->is_pure_ghost(reference);
299 }
300 
301 #endif // __FJCORE__
302 
303 
304 
305 FASTJET_END_NAMESPACE
deals with clustering
virtual double area(const PseudoJet &) const
return the area associated with the given jet; this base class returns 0.
base class that sets interface for extensions of ClusterSequence that provide information about the a...
base class corresponding to errors that can be thrown by FastJet
Definition: Error.hh:47
virtual bool is_pure_ghost() const
true if this jet is made exclusively of ghosts.
Definition: PseudoJet.cc:739
const ClusterSequence * associated_cluster_sequence() const
get a (const) pointer to the parent ClusterSequence (NULL if inexistent)
Definition: PseudoJet.cc:437
bool has_associated_cluster_sequence() const
returns true if this PseudoJet has an associated ClusterSequence.
Definition: PseudoJet.cc:430
Class to contain pseudojets, including minimal information of use to jet-clustering routines...
Definition: PseudoJet.hh:67
virtual PseudoJet area_4vector() const
return the jet 4-vector area.
Definition: PseudoJet.cc:732