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