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