FastJet 3.0.6
|
00001 //STARTHEADER 00002 // $Id: ClusterSequenceStructure.cc 3071 2013-04-01 12:52:46Z cacciari $ 00003 // 00004 // Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez 00005 // 00006 //---------------------------------------------------------------------- 00007 // This file is part of FastJet. 00008 // 00009 // FastJet is free software; you can redistribute it and/or modify 00010 // it under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation; either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // The algorithms that underlie FastJet have required considerable 00015 // development and are described in hep-ph/0512210. If you use 00016 // FastJet as part of work towards a scientific publication, please 00017 // include a citation to the FastJet paper. 00018 // 00019 // FastJet is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 // GNU General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with FastJet. If not, see <http://www.gnu.org/licenses/>. 00026 //---------------------------------------------------------------------- 00027 //ENDHEADER 00028 00029 #include "fastjet/ClusterSequenceStructure.hh" 00030 #include "fastjet/Error.hh" 00031 #include "fastjet/PseudoJet.hh" 00032 #include "fastjet/ClusterSequence.hh" 00033 #ifndef __FJCORE__ 00034 #include "fastjet/ClusterSequenceAreaBase.hh" 00035 #endif // __FJCORE__ 00036 #include <iostream> 00037 00038 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 00039 00040 using namespace std; 00041 00042 ClusterSequenceStructure::~ClusterSequenceStructure(){ 00043 if (_associated_cs != NULL 00044 && _associated_cs->will_delete_self_when_unused()) { 00045 // automatically handle deletion of the cluster sequence; 00046 // execution should only ever reach this point if the user had 00047 // called CS::delete_self_when_unused, which resets the count of 00048 // the shared pointer to CSS (otherwise the CS's own destructor 00049 // will have zeroed the _associated_cs pointer before the shared 00050 // pointer count goes to zero [on destruction of the last of the 00051 // jets in the CS and the destruction of the CS's copy of the 00052 // shared pointer) 00053 _associated_cs->signal_imminent_self_deletion(); 00054 delete _associated_cs; 00055 } 00056 } 00057 00058 00059 //---------------------------------------------------------------------- 00060 // Direct access to the associated ClusterSequence object. 00061 //---------------------------------------------------------------------- 00062 00063 // check whether this PseudoJet has an associated parent 00064 // ClusterSequence 00065 bool ClusterSequenceStructure::has_valid_cluster_sequence() const{ 00066 return (_associated_cs != NULL); 00067 } 00068 00069 // get a (const) pointer to the associated ClusterSequence (NULL if 00070 // inexistent) 00071 const ClusterSequence* ClusterSequenceStructure::associated_cluster_sequence() const{ 00072 return _associated_cs; 00073 } 00074 00075 00076 // If there is a valid cluster sequence associated with this jet, 00077 // returns a pointer to it; otherwise throws an Error. 00078 // 00079 // Open question: should these errors be upgraded to classes of their 00080 // own so that they can be caught? [Maybe, but later] 00081 const ClusterSequence * ClusterSequenceStructure::validated_cs() const { 00082 if (!_associated_cs) 00083 throw Error("you requested information about the internal structure of a jet, but its associated ClusterSequence has gone out of scope."); 00084 return _associated_cs; 00085 } 00086 00087 00088 //---------------------------------------------------------------------- 00089 // Methods for access to information about jet structure 00090 //---------------------------------------------------------------------- 00091 00092 // check if it has been recombined with another PseudoJet in which 00093 // case, return its partner through the argument. Otherwise, 00094 // 'partner' is set to 0. 00095 // 00096 // false is also returned if this PseudoJet has no associated 00097 // ClusterSequence 00098 bool ClusterSequenceStructure::has_partner(const PseudoJet &reference, PseudoJet &partner) const{ 00099 return validated_cs()->has_partner(reference, partner); 00100 } 00101 00102 // check if it has been recombined with another PseudoJet in which 00103 // case, return its child through the argument. Otherwise, 'child' 00104 // is set to 0. 00105 // 00106 // false is also returned if this PseudoJet has no associated 00107 // ClusterSequence, with the child set to 0 00108 bool ClusterSequenceStructure::has_child(const PseudoJet &reference, PseudoJet &child) const{ 00109 return validated_cs()->has_child(reference, child); 00110 } 00111 00112 // check if it is the product of a recombination, in which case 00113 // return the 2 parents through the 'parent1' and 'parent2' 00114 // arguments. Otherwise, set these to 0. 00115 // 00116 // false is also returned if this PseudoJet has no parent 00117 // ClusterSequence 00118 bool ClusterSequenceStructure::has_parents(const PseudoJet &reference, PseudoJet &parent1, PseudoJet &parent2) const{ 00119 return validated_cs()->has_parents(reference, parent1, parent2); 00120 } 00121 00122 00123 // check if the reference PseudoJet is inside the "jet" passed as an argument 00124 // 00125 // an error is thrown if there is no CS associated with one of the 2 jets. 00126 // fasle is returned if teh 2 jets do not belong to the same CS 00127 bool ClusterSequenceStructure::object_in_jet(const PseudoJet &reference, const PseudoJet &jet) const{ 00128 if ((!has_associated_cluster_sequence()) || (!jet.has_associated_cluster_sequence())) 00129 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."); 00130 00131 if (reference.associated_cluster_sequence() != jet.associated_cluster_sequence()) return false; 00132 00133 return validated_cs()->object_in_jet(reference, jet); 00134 } 00135 00136 00137 // return true if the structure supports constituents. 00138 // 00139 // an Error is thrown if this PseudoJet has no currently valid 00140 // associated ClusterSequence 00141 bool ClusterSequenceStructure::has_constituents() const{ 00142 if (!has_associated_cluster_sequence()) 00143 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."); 00144 00145 return true; 00146 } 00147 00148 00149 // retrieve the constituents. An empty vector is returned if there is 00150 // no associated ClusterSequence 00151 vector<PseudoJet> ClusterSequenceStructure::constituents(const PseudoJet &reference) const{ 00152 return validated_cs()->constituents(reference); 00153 } 00154 00155 // return true if the structure supports exclusive_subjets. 00156 // 00157 // an Error is thrown if this PseudoJet has no currently valid 00158 // associated ClusterSequence 00159 bool ClusterSequenceStructure::has_exclusive_subjets() const{ 00160 if (!has_associated_cluster_sequence()) 00161 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."); 00162 00163 return true; 00164 } 00165 00166 // return a vector of all subjets of the current jet (in the sense 00167 // of the exclusive algorithm) that would be obtained when running 00168 // the algorithm with the given dcut. 00169 // 00170 // Time taken is O(m ln m), where m is the number of subjets that 00171 // are found. If m gets to be of order of the total number of 00172 // constituents in the jet, this could be substantially slower than 00173 // just getting that list of constituents. 00174 // 00175 // an Error is thrown if this PseudoJet has no currently valid 00176 // associated ClusterSequence 00177 std::vector<PseudoJet> ClusterSequenceStructure::exclusive_subjets (const PseudoJet &reference, const double & dcut) const { 00178 return validated_cs()->exclusive_subjets(reference, dcut); 00179 } 00180 00181 // return the size of exclusive_subjets(...); still n ln n with same 00182 // coefficient, but marginally more efficient than manually taking 00183 // exclusive_subjets.size() 00184 // 00185 // an Error is thrown if this PseudoJet has no currently valid 00186 // associated ClusterSequence 00187 int ClusterSequenceStructure::n_exclusive_subjets(const PseudoJet &reference, const double & dcut) const { 00188 return validated_cs()->n_exclusive_subjets(reference, dcut); 00189 } 00190 00191 // return the list of subjets obtained by unclustering the supplied 00192 // jet down to n subjets (or all constituents if there are fewer 00193 // than n). 00194 // 00195 // requires n ln n time 00196 // 00197 // an Error is thrown if this PseudoJet has no currently valid 00198 // associated ClusterSequence 00199 std::vector<PseudoJet> ClusterSequenceStructure::exclusive_subjets_up_to (const PseudoJet &reference, int nsub) const { 00200 return validated_cs()->exclusive_subjets_up_to(reference, nsub); 00201 } 00202 00203 // return the dij that was present in the merging nsub+1 -> nsub 00204 // subjets inside this jet. 00205 // 00206 // an Error is thrown if this PseudoJet has no currently valid 00207 // associated ClusterSequence 00208 double ClusterSequenceStructure::exclusive_subdmerge(const PseudoJet &reference, int nsub) const { 00209 return validated_cs()->exclusive_subdmerge(reference, nsub); 00210 } 00211 00212 // return the maximum dij that occurred in the whole event at the 00213 // stage that the nsub+1 -> nsub merge of subjets occurred inside 00214 // this jet. 00215 // 00216 // an Error is thrown if this PseudoJet has no currently valid 00217 // associated ClusterSequence 00218 double ClusterSequenceStructure::exclusive_subdmerge_max(const PseudoJet &reference, int nsub) const { 00219 return validated_cs()->exclusive_subdmerge_max(reference, nsub); 00220 } 00221 00222 00223 //---------------------------------------------------------------------- 00224 // information related to the pieces of the jet 00225 //---------------------------------------------------------------------- 00226 00227 // by convention, a jet associated with a ClusterSequence will have 00228 // pieces if it has parents in the cluster sequence. 00229 // 00230 // an error is thrown if the ClusterSequence is out of scope (since 00231 // the answer depends on information in the Cluster Sequence) 00232 bool ClusterSequenceStructure::has_pieces(const PseudoJet &reference) const{ 00233 PseudoJet dummy1, dummy2; 00234 return has_parents(reference, dummy1, dummy2); 00235 } 00236 00237 // by convention, the pieces of a jet associated with a 00238 // ClusterSequence are its parents in the Cluster Sequence. If it has 00239 // no parents, an empty jet is returned. 00240 // 00241 // an error is thrown if the ClusterSequence is out of scope 00242 vector<PseudoJet> ClusterSequenceStructure::pieces(const PseudoJet &reference) const{ 00243 PseudoJet j1, j2; 00244 vector<PseudoJet> res; 00245 if (has_parents(reference, j1, j2)){ 00246 res.push_back(j1); 00247 res.push_back(j2); 00248 } 00249 00250 return res; 00251 } 00252 00253 00254 //---------------------------------------------------------------------- 00255 // the following ones require a computation of the area in the 00256 // associated ClusterSequence (See ClusterSequenceAreaBase for details) 00257 //---------------------------------------------------------------------- 00258 00259 #ifndef __FJCORE__ 00260 // if possible, return a valid ClusterSequenceAreaBase pointer; otherwise 00261 // throw an error 00262 const ClusterSequenceAreaBase * ClusterSequenceStructure::validated_csab() const { 00263 const ClusterSequenceAreaBase *csab = dynamic_cast<const ClusterSequenceAreaBase*>(validated_cs()); 00264 if (csab == NULL) throw Error("you requested jet-area related information, but the PseudoJet does not have associated area information."); 00265 return csab; 00266 } 00267 00268 // check if it has a defined area 00269 bool ClusterSequenceStructure::has_area() const{ 00270 if (! has_associated_cluster_sequence()) return false; 00271 return (dynamic_cast<const ClusterSequenceAreaBase*>(_associated_cs) != NULL); 00272 } 00273 00274 // return the jet (scalar) area. 00275 // throw an Error if there is no support for area in the associated CS 00276 double ClusterSequenceStructure::area(const PseudoJet &reference) const{ 00277 return validated_csab()->area(reference); 00278 } 00279 00280 // return the error (uncertainty) associated with the determination 00281 // of the area of this jet. 00282 // throws an Error if there is no support for area in the associated CS 00283 double ClusterSequenceStructure::area_error(const PseudoJet &reference) const{ 00284 return validated_csab()->area_error(reference); 00285 } 00286 00287 // return the jet 4-vector area 00288 // throws an Error if there is no support for area in the associated CS 00289 PseudoJet ClusterSequenceStructure::area_4vector(const PseudoJet &reference) const{ 00290 return validated_csab()->area_4vector(reference); 00291 } 00292 00293 // true if this jet is made exclusively of ghosts 00294 // throws an Error if there is no support for area in the associated CS 00295 bool ClusterSequenceStructure::is_pure_ghost(const PseudoJet &reference) const{ 00296 return validated_csab()->is_pure_ghost(reference); 00297 } 00298 00299 #endif // __FJCORE__ 00300 00301 00302 00303 FASTJET_END_NAMESPACE