FastJet  3.3.3
ClusterSequenceStructure.cc
1 //FJSTARTHEADER
2 // $Id: ClusterSequenceStructure.cc 4420 2019-11-29 09:28:20Z soyez $
3 //
4 // Copyright (c) 2005-2019, 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
virtual PseudoJet area_4vector() const
return the jet 4-vector area.
Definition: PseudoJet.cc:736
deals with clustering
bool has_associated_cluster_sequence() const
returns true if this PseudoJet has an associated ClusterSequence.
Definition: PseudoJet.cc:434
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:743
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
const ClusterSequence * associated_cluster_sequence() const
get a (const) pointer to the parent ClusterSequence (NULL if inexistent)
Definition: PseudoJet.cc:441
Class to contain pseudojets, including minimal information of use to jet-clustering routines...
Definition: PseudoJet.hh:67