FastJet 3.0.5
ClusterSequenceStructure.cc
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends