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