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