FastJet 3.0.1
|
00001 #ifndef D0RunIIconeJets_CONESPLITMERGE 00002 #define D0RunIIconeJets_CONESPLITMERGE 00003 // --------------------------------------------------------------------------- 00004 // ConeSplitMerge.hpp 00005 // 00006 // Created: 28-JUL-2000 Francois Touze 00007 // 00008 // Purpose: Implements the pT ordered jet split/merge algorithm for the 00009 // Improved Legacy Cone Algorithm split/merge algo. 00010 // 00011 // Modified: 00012 // 31-JUL-2000 Laurent Duflot 00013 // + introduce support for additional informations (ConeJetInfo) 00014 // 1-AUG-2000 Laurent Duflot 00015 // + jet merge criteria was wrong, now calculate shared_ET and compare to 00016 // neighbour jet pT. 00017 // + split was incomplete: shared items not really removed from jets. 00018 // 4-Aug-2000 Laurent Duflot 00019 // + use item methods y() and phi() rather than p4vec() and then P2y and 00020 // P2phi 00021 // 7-Aug-2000 Laurent Duflot 00022 // + force the list to be organized by decreasing ET and, for identical ET, 00023 // by decreasing seedET. Identical protojets can be found by eg nearby 00024 // seeds. The seedET ordering is such that for identical jets, the one 00025 // with the highest seedET is kept, which is what we want for efficiency 00026 // calculations. 00027 // + avoid unecessary copies of lists by using reference when possible 00028 // 9-Aug-2000 Laurent Duflot 00029 // + save initial jet ET before split/merge 00030 // 1-May-2007 Lars Sonnenschein 00031 // extracted from D0 software framework and modified to remove subsequent dependencies 00032 // --------------------------------------------------------------------------- 00033 // 00034 00035 // History of changes in FastJet compared tothe original version of 00036 // ConeSplitMerge.hpp 00037 // 00038 // 2009-01-17 Gregory Soyez <soyez@fastjet.fr> 00039 // 00040 // * put the code in the fastjet::d0 namespace 00041 // 00042 // 2007-12-14 Gavin Salam <salam@lpthe.jussieu.fr> 00043 // 00044 // * replaced make_pair by std::make_pair 00045 00046 #include <iostream> 00047 #include <map> 00048 #include <utility> 00049 #include <vector> 00050 #include "ProtoJet.hpp" 00051 00052 //using namespace D0RunIIconeJets_CONEJETINFO; 00053 00054 #include <fastjet/internal/base.hh> 00055 00056 FASTJET_BEGIN_NAMESPACE 00057 00058 namespace d0{ 00059 00060 // 00061 // this class is used to order ProtoJets by decreasing ET and seed ET 00062 template <class Item> 00063 class ProtoJet_ET_seedET_order 00064 { 00065 public: 00066 bool operator()(const ProtoJet<Item> & first, const ProtoJet<Item> & second) 00067 { 00068 if ( first.pT() > second.pT() ) return true; 00069 else 00070 if ( first.pT() < second.pT() ) return false; 00071 else return ( first.info().seedET() > second.info().seedET() ); 00072 } 00073 }; 00074 00075 00076 template <class Item> 00077 class ConeSplitMerge { 00078 00079 public : 00080 00081 typedef std::multimap<ProtoJet<Item>,float,ProtoJet_ET_seedET_order<Item> > PJMMAP; 00082 00083 ConeSplitMerge(); 00084 ConeSplitMerge(const std::vector<ProtoJet<Item> >& jvector); 00085 ConeSplitMerge(const std::list<ProtoJet<Item> >& jlist); 00086 ~ConeSplitMerge() {;} 00087 void split_merge(std::vector<ProtoJet<Item> >& ecv,float s, float pT_min_leading_protojet, float pT_min_second_protojet, int MergeMax, float pT_min_noMergeMax); 00088 00089 private : 00090 PJMMAP _members; 00091 }; 00092 /////////////////////////////////////////////////////////////////////////////// 00093 template<class Item> 00094 ConeSplitMerge<Item>::ConeSplitMerge():_members() {;} 00095 00096 template<class Item> 00097 ConeSplitMerge<Item>::ConeSplitMerge(const std::vector<ProtoJet<Item> >& jvector) 00098 { 00099 // sort proto_jets in Et descending order 00100 typename std::vector<ProtoJet<Item> >::const_iterator jt; 00101 for(jt = jvector.begin(); jt != jvector.end(); ++jt) 00102 { 00103 // this is supposed to be a stable cone, declare so 00104 ProtoJet<Item> jet(*jt); 00105 jet.NowStable(); 00106 _members.insert(std::make_pair(jet,jet.pT())); 00107 } 00108 } 00109 00110 template<class Item> 00111 ConeSplitMerge<Item>::ConeSplitMerge(const std::list<ProtoJet<Item> >& jlist) 00112 { 00113 //_max_nb_items =-1; 00114 // sort proto_jets in Et descending order 00115 typename std::list<ProtoJet<Item> >::const_iterator jt; 00116 for(jt = jlist.begin(); jt != jlist.end(); ++jt) 00117 { 00118 // this is supposed to be a stable cone, declare so 00119 ProtoJet<Item> jet(*jt); 00120 jet.NowStable(); 00121 _members.insert(std::make_pair(jet,jet.pT())); 00122 } 00123 } 00124 00125 template<class Item> 00126 void ConeSplitMerge<Item>::split_merge(std::vector<ProtoJet<Item> >& jcv, 00127 float shared_ET_fraction, 00128 float pT_min_leading_protojet, float pT_min_second_protojet, 00129 int MergeMax, float pT_min_noMergeMax) 00130 { 00131 while(!_members.empty()) 00132 { 00133 /* 00134 { 00135 std::cout << std::endl; 00136 std::cout << " --------------- list of protojets ------------------ " <<std::endl; 00137 for ( PJMMAP::iterator it = _members.begin(); 00138 it != _members.end(); ++it) 00139 { 00140 std::cout << " pT y phi " << (*it).pT() << " " << (*it).y() << " " << (*it).phi() << " " << (*it).info().seedET() << " " << (*it).info().nbMerge() << " " << (*it).info().nbSplit() << std::endl; 00141 } 00142 std::cout << " ----------------------------------------------------- " <<std::endl; 00143 } 00144 */ 00145 00146 00147 // select highest Et jet 00148 typename PJMMAP::iterator itmax= _members.begin(); 00149 ProtoJet<Item> imax((*itmax).first); 00150 const std::list<const Item*>& ilist(imax.LItems()); 00151 00152 _members.erase(itmax); 00153 00154 // does jet share items? 00155 bool share= false; 00156 float shared_ET = 0.; 00157 typename PJMMAP::iterator jtmax; 00158 typename PJMMAP::iterator jt; 00159 for(jt = _members.begin(); jt != _members.end(); ++jt) 00160 { 00161 const std::list<const Item*>& jlist((*jt).first.LItems()); 00162 typename std::list<const Item*>::const_iterator tk; 00163 int count; 00164 for(tk = ilist.begin(), count = 0; tk != ilist.end(); 00165 ++tk, ++count) 00166 { 00167 typename std::list<const Item*>::const_iterator where= 00168 find(jlist.begin(),jlist.end(),*tk); 00169 if(where != jlist.end()) 00170 { 00171 share= true; 00172 shared_ET += (*tk)->pT(); 00173 } 00174 } 00175 if(share) 00176 { 00177 jtmax = jt; 00178 break; 00179 } 00180 } 00181 00182 if(!share) { 00183 // add jet to the final jet list 00184 jcv.push_back(imax); 00185 //std::cout << " final jet " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl; 00186 } 00187 else 00188 { 00189 // find highest Et neighbor 00190 ProtoJet<Item> jmax((*jtmax).first); 00191 00192 // drop neighbor 00193 _members.erase(jtmax); 00194 00195 00196 //std::cout << " split or merge ? " << imax.pT() << " " << shared_ET << " " << jmax.pT() << " " << s << " " << (jmax.pT())*s << std::endl; 00197 00198 // merge 00199 if( shared_ET > (jmax.pT())*shared_ET_fraction 00200 && (imax.pT() > pT_min_leading_protojet || jmax.pT() > pT_min_second_protojet) 00201 && (imax.info().nbMerge() < MergeMax || imax.pT() > pT_min_noMergeMax)) 00202 { 00203 // add neighbor's items to imax 00204 const std::list<const Item*>& jlist(jmax.LItems()); 00205 typename std::list<const Item*>::const_iterator tk; 00206 typename std::list<const Item*>::const_iterator iend= ilist.end(); 00207 bool same = true; // is jmax just the same as imax ? 00208 for(tk = jlist.begin(); tk != jlist.end(); ++tk) 00209 { 00210 typename std::list<const Item*>::const_iterator where= 00211 find(ilist.begin(),iend,*tk); 00212 if(where == iend) 00213 { 00214 imax.addItem(*tk); 00215 same = false; 00216 } 00217 } 00218 if ( ! same ) 00219 { 00220 // recalculate 00221 //float old_pT = imax.pT(); 00222 00223 imax.updateJet(); 00224 imax.merged(); 00225 //std::cout << " jet merge :: " << old_pT << " " << jmax.pT() << " " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl; 00226 } 00227 } 00228 00229 //split and assign removed shared cells from lowest pT protojet 00230 else if(shared_ET > (jmax.pT())*shared_ET_fraction) 00231 { 00232 // here we need to pull the lists, because there are items to remove 00233 std::list<const Item*> ilist(imax.LItems()); 00234 std::list<const Item*> jlist(jmax.LItems()); 00235 00236 typename std::list<const Item*>::iterator tk; 00237 for(tk = jlist.begin(); tk != jlist.end(); ) 00238 { 00239 typename std::list<const Item*>::iterator where= 00240 find(ilist.begin(),ilist.end(),*tk); 00241 if(where != ilist.end()) { 00242 tk = jlist.erase(tk); 00243 } 00244 else ++tk; 00245 } 00246 00247 jmax.erase(); 00248 00249 for ( typename std::list<const Item*>::const_iterator it = jlist.begin(); 00250 it != jlist.end(); ++it) jmax.addItem(*it); 00251 00252 // recalculated jet quantities 00253 jmax.updateJet(); 00254 jmax.splitted(); 00255 //std::cout << " jet split 1 :: " << jmax.pT() << " "<< jmax.info().nbMerge() << " " << jmax.info().nbSplit() << std::endl; 00256 _members.insert(std::make_pair(jmax,jmax.pT())); 00257 } 00258 00259 // split and assign shared cells to nearest protojet 00260 else 00261 { 00262 // here we need to pull the lists, because there are items to remove 00263 std::list<const Item*> ilist(imax.LItems()); 00264 std::list<const Item*> jlist(jmax.LItems()); 00265 00266 typename std::list<const Item*>::iterator tk; 00267 for(tk = jlist.begin(); tk != jlist.end(); ) 00268 { 00269 typename std::list<const Item*>::iterator where= 00270 find(ilist.begin(),ilist.end(),*tk); 00271 if(where != ilist.end()) { 00272 float yk = (*tk)->y(); 00273 float phik = (*tk)->phi(); 00274 float di= RD2(imax.y(),imax.phi(),yk,phik); 00275 float dj= RD2(jmax.y(),jmax.phi(),yk,phik); 00276 if(dj > di) 00277 { 00278 tk = jlist.erase(tk); 00279 //std::cout << " shared item " << (*tk)->pT() << " removed from neighbour jet " << std::endl; 00280 } 00281 else 00282 { 00283 ilist.erase(where); 00284 ++tk; 00285 //std::cout << " shared item " << (*tk)->pT() << " removed from leading jet " << std::endl; 00286 } 00287 } 00288 else ++tk; 00289 } 00290 // recalculate jets imax and jmax 00291 00292 // first erase all items 00293 imax.erase(); 00294 // put items that are left 00295 for ( typename std::list<const Item*>::const_iterator it = ilist.begin(); 00296 it != ilist.end(); ++it) imax.addItem(*it); 00297 // recalculated jet quantities 00298 imax.updateJet(); 00299 imax.splitted(); 00300 //std::cout << " jet split 2 :: " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl; 00301 00302 00303 // first erase all items 00304 jmax.erase(); 00305 // put items that are left 00306 for ( typename std::list<const Item*>::const_iterator it = jlist.begin(); 00307 it != jlist.end(); ++it) jmax.addItem(*it); 00308 // recalculated jet quantities 00309 jmax.updateJet(); 00310 jmax.splitted(); 00311 //std::cout << " jet split " << jmax.pT() << " "<< jmax.info().nbMerge() << " " << jmax.info().nbSplit() << std::endl; 00312 00313 _members.insert(std::make_pair(jmax,jmax.pT())); 00314 } 00315 _members.insert(std::make_pair(imax,imax.pT())); 00316 } 00317 } // while 00318 } 00319 /////////////////////////////////////////////////////////////////////////////// 00320 00321 } // namespace d0 00322 00323 FASTJET_END_NAMESPACE 00324 00325 #endif