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
virtual PseudoJet area_4vector() const
return the jet 4-vector area.
Definition: PseudoJet.cc:718
deals with clustering
bool has_associated_cluster_sequence() const
returns true if this PseudoJet has an associated ClusterSequence.
Definition: PseudoJet.cc:416
virtual double area(const PseudoJet &) const
return the area associated with the given jet; this base class returns 0.
virtual bool is_pure_ghost() const
true if this jet is made exclusively of ghosts.
Definition: PseudoJet.cc:725
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
const ClusterSequence * associated_cluster_sequence() const
get a (const) pointer to the parent ClusterSequence (NULL if inexistent)
Definition: PseudoJet.cc:423
Class to contain pseudojets, including minimal information of use to jet-clustering routines...
Definition: PseudoJet.hh:65