fastjet 2.4.5
|
00001 //STARTHEADER 00002 // $Id: CMSIterativeConePlugin.cc 1504 2009-04-10 13:39:48Z salam $ 00003 // 00004 // Copyright (c) 2007-2009, Matteo Cacciari, Gavin Salam and Gregory Soyez [for the plugin] 00005 // Copyright (c) ????-????, CMS [for the iterative-cone code itself] 00006 // 00007 //---------------------------------------------------------------------- 00008 // This file is part of FastJet. 00009 // 00010 // FastJet is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU General Public License as published by 00012 // the Free Software Foundation; either version 2 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // The algorithms that underlie FastJet have required considerable 00016 // development and are described in hep-ph/0512210. If you use 00017 // FastJet as part of work towards a scientific publication, please 00018 // include a citation to the FastJet paper. 00019 // 00020 // FastJet is distributed in the hope that it will be useful, 00021 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 // GNU General Public License for more details. 00024 // 00025 // You should have received a copy of the GNU General Public License 00026 // along with FastJet; if not, write to the Free Software 00027 // Foundation, Inc.: 00028 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00029 //---------------------------------------------------------------------- 00030 //ENDHEADER 00031 00032 // fastjet stuff 00033 #include "fastjet/ClusterSequence.hh" 00034 #include "fastjet/CMSIterativeConePlugin.hh" 00035 00036 // other stuff 00037 #include <vector> 00038 #include <list> 00039 #include <sstream> 00040 #include "SortByEt.h" 00041 00042 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 00043 00044 using namespace std; 00045 using namespace cms; 00046 00047 //------------------------------------------------------ 00048 // some tools 00049 //------------------------------------------------------ 00050 template <class T> 00051 T deltaPhi (T phi1, T phi2) { 00052 T result = phi1 - phi2; 00053 while (result > M_PI) result -= 2*M_PI; 00054 while (result <= -M_PI) result += 2*M_PI; 00055 return result; 00056 } 00057 00058 template <class T> 00059 T deltaR2 (T eta1, T phi1, T eta2, T phi2) { 00060 T deta = eta1 - eta2; 00061 T dphi = deltaPhi (phi1, phi2); 00062 return deta*deta + dphi*dphi; 00063 } 00064 00065 //------------------------------------------------------ 00066 00067 00068 string CMSIterativeConePlugin::description () const { 00069 ostringstream desc; 00070 desc << "CMSIterativeCone plugin with R = " << theConeRadius << " and seed threshold = " << theSeedThreshold; 00071 return desc.str(); 00072 } 00073 00074 void CMSIterativeConePlugin::run_clustering(ClusterSequence & clust_seq) const { 00075 00076 // This code is adapted from CMSIterativeConeAlgorithms.cc from the 00077 // CMSSW software. 00078 // The adaptation is just meant to use 00079 // - the FastJet 4-vectors instead of the CMS ones 00080 // - the FastJet clustering history structures instead of the 00081 // ProtoJet one used by CMS. 00082 00083 //make a list of input objects ordered by ET 00084 //cout << "copying the list of particles" << endl; 00085 list<PseudoJet> input; 00086 for (unsigned int i=0 ; i<clust_seq.jets().size() ; i++) { 00087 input.push_back(clust_seq.jets()[i]); 00088 } 00089 NumericSafeGreaterByEt<PseudoJet> compCandidate; 00090 //cout << "sorting" << endl; 00091 input.sort(compCandidate); 00092 00093 //find jets 00094 //cout << "launching the main loop" << endl; 00095 while( !input.empty() && (input.front().Et() > theSeedThreshold )) { 00096 //cone centre 00097 double eta0=input.front().eta(); 00098 double phi0=input.front().phi(); 00099 //protojet properties 00100 double eta=0; 00101 double phi=0; 00102 double et=0; 00103 //list of towers in cone 00104 list< list<PseudoJet>::iterator> cone; 00105 for(int iteration=0;iteration<100;iteration++){ 00106 //cout << "iterating" << endl; 00107 cone.clear(); 00108 eta=0; 00109 phi=0; 00110 et=0; 00111 for(list<PseudoJet>::iterator inp=input.begin(); 00112 inp!=input.end();inp++){ 00113 const PseudoJet tower = *inp; 00114 if( deltaR2(eta0,phi0,tower.eta(),tower.phi()) < 00115 theConeRadius*theConeRadius) { 00116 double tower_et = tower.Et(); 00117 cone.push_back(inp); 00118 eta+= tower_et*tower.eta(); 00119 double dphi=tower.phi()-phi0; 00120 if(dphi>M_PI) dphi-=2*M_PI; 00121 else if(dphi<=-M_PI) dphi+=2*M_PI; 00122 phi+=tower_et*dphi; 00123 et +=tower_et; 00124 } 00125 } 00126 eta=eta/et; 00127 phi=phi0+phi/et; 00128 if(phi>M_PI)phi-=2*M_PI; 00129 else if(phi<=-M_PI)phi+=2*M_PI; 00130 00131 if(fabs(eta-eta0)<.001 && fabs(phi-phi0)<.001) break;//stable cone found 00132 eta0=eta; 00133 phi0=phi; 00134 } 00135 00136 //cout << "make the jet final" << endl; 00137 00138 //make a final jet and remove the jet constituents from the input list 00139 // InputCollection jetConstituents; 00140 // list< list<InputItem>::iterator>::const_iterator inp; 00141 // for(inp=cone.begin();inp!=cone.end();inp++) { 00142 // jetConstituents.push_back(**inp); 00143 // input.erase(*inp); 00144 // } 00145 // fOutput->push_back (ProtoJet (jetConstituents)); 00146 // 00147 // IMPORTANT NOTE: 00148 // while the stability of the stable cone is tested using the Et 00149 // scheme recombination, the final jet uses E-scheme 00150 // recombination. 00151 // 00152 // The technique used here is the same as what we already used for 00153 // SISCone except that we act on the 'cone' list. 00154 // We successively merge the particles that make up the cone jet 00155 // until we have all particles in it. We start off with the zeroth 00156 // particle. 00157 list< list<PseudoJet>::iterator>::const_iterator inp; 00158 inp = cone.begin(); 00159 int jet_k = (*inp)->cluster_hist_index(); 00160 // gps tmp 00161 //float px=(*inp)->px(), py=(*inp)->py(), pz=(*inp)->pz(), E = (*inp)->E(); 00162 00163 // remove the particle from the list and jump to the next one 00164 input.erase(*inp); 00165 inp++; 00166 00167 // now loop over the remaining particles 00168 while (inp != cone.end()){ 00169 // take the last result of the merge 00170 int jet_i = jet_k; 00171 // and the next element of the jet 00172 int jet_j = (*inp)->cluster_hist_index(); 00173 // and merge them (with a fake dij) 00174 double dij = 0.0; 00175 00176 // create the new jet by hand so that we can adjust its user index 00177 // Note again the use of the E-scheme recombination here! 00178 PseudoJet newjet = clust_seq.jets()[jet_i] + clust_seq.jets()[jet_j]; 00179 00180 // gps tmp to try out floating issues 00181 //px+=(*inp)->px(), py+=(*inp)->py(), pz+=(*inp)->pz(), E += (*inp)->E(); 00182 //PseudoJet newjet(px,py,pz,E); 00183 00184 clust_seq.plugin_record_ij_recombination(jet_i, jet_j, dij, newjet, jet_k); 00185 00186 // remove the particle from the list and jump to the next one 00187 input.erase(*inp); 00188 inp++; 00189 } 00190 00191 // we have merged all the jet's particles into a single object, so now 00192 // "declare" it to be a beam (inclusive) jet. 00193 // [NB: put a sensible looking d_iB just to be nice...] 00194 double d_iB = clust_seq.jets()[jet_k].perp2(); 00195 clust_seq.plugin_record_iB_recombination(jet_k, d_iB); 00196 00197 00198 } //loop over seeds ended 00199 00200 00201 } 00202 00203 FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh