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