FastJet 3.0.1
|
00001 ////////////////////////////////////////////////////////////// 00002 // File: ConeClusterAlgo.hpp 00003 // 00004 // Author: G. Le Meur & F. Touze 00005 // 00006 // Created: 15-JUNE-1998 00007 // 00008 // Purpose: make jet clusters using fixed cone like algorithm 00009 // implemented in RUNI. 00010 // 00011 // Modified: 00012 // 28-OCT-1998 to use KinemUtil (S. Protopopescu) 00013 // 8-JAN-1999: Laurent Duflot 00014 // . correct bugs in getItemsInCone and updateEtaPhiEt for jets 00015 // overlapping the phi=0 line 00016 // . change abs(float) to fabs(float) 00017 // 1-NOV-1999: Laurent Duflot 00018 // . correct bug in makeCluster: when the temporary jet was emptied the eta 00019 // and phi were not set again. The main effect was a nearly zero 00020 // efficiency for jets at phi=pi (as seen by Volker Buescher) 00021 // 25-JAN-2000: Francois Touze 00022 // . change in updateEtaPhiEt : the method E() which returns energy doesn't 00023 // exist in MCparticle classe,... so use the 4-momentum components 00024 // . declare const the EnergyClusterCollection of seeds in makeClusters 00025 // 01-FEB-2000: Laurent Duflot 00026 // . add a missing break statement in the removal of shared items. Caused 00027 // an infinite loop on some events. 00028 // . correct typo in variable name. Change a variable name that was in 00029 // French. 00030 // . leave some debug printout (commented) 00031 // 15-Sep-2009 Lars Sonnenschein 00032 // extracted from D0 software framework and modified to remove subsequent dependencies 00033 // 00034 ////////////////////////////////////////////////////////////// 00035 00036 //#ifndef CONECLUSTERALGO_H 00037 //#define CONECLUSTERALGO_H 00038 00039 #ifndef D0RunIconeJets_CONECLUSTERALGO_H 00040 #define D0RunIconeJets_CONECLUSTERALGO_H 00041 00042 // History of changes in FastJet compared tothe original version of 00043 // ConeClusterAlgo.hpp 00044 // 00045 // 2011-10-06 Gregory Soyez <soyez@fastjet.fr> 00046 // 00047 // * put the code in the fastjet::d0 namespace 00048 00049 00050 //#include "EnergyClusterReco.hpp" 00051 #include <vector> 00052 #include <list> 00053 #include <utility> 00054 //#include "kinem_util/AnglesUtil.hpp" 00055 00056 #include <algorithm> 00057 #include <iostream> 00058 00059 #include "inline_maths.h" 00060 #include <fastjet/internal/base.hh> 00061 00062 FASTJET_BEGIN_NAMESPACE 00063 00064 namespace d0runi{ 00065 00066 using namespace std; 00067 00068 //some utility functions 00069 inline float R2(float eta1, float phi1, float eta2, float phi2) { 00070 return (eta1-eta2)*(eta1-eta2)+(phi1-phi2)*(phi1-phi2); } 00071 00072 inline float R2_bis(float eta1, float phi1, float eta2, float phi2) { 00073 //float dphi = kinem::delta_phi(phi1,phi2); 00074 float dphi = inline_maths::delta_phi(phi1,phi2); 00075 return (eta1-eta2)*(eta1-eta2)+dphi*dphi; } 00076 00077 inline float DELTA_r(float eta1,float eta2,float phi1,float phi2) { 00078 //float dphi = kinem::delta_phi(phi1,phi2); 00079 float dphi = inline_maths::delta_phi(phi1,phi2); 00080 return sqrt((eta1-eta2)*(eta1-eta2)+dphi*dphi); 00081 } 00082 00083 inline float E2eta(float* p) { 00084 float small= 1.E-05; 00085 float E[3]; 00086 if(p[3] < 0.0) { 00087 E[0]= -p[0]; 00088 E[1]= -p[1]; 00089 E[2]= -p[2]; 00090 } 00091 else { 00092 E[0]= p[0]; 00093 E[1]= p[1]; 00094 E[2]= p[2]; 00095 } 00096 float pperp= sqrt(E[0]*E[0]+E[1]*E[1])+small; 00097 float ptotal= sqrt(E[0]*E[0]+E[1]*E[1]+E[2]*E[2])+small; 00098 //float theta= atan2(pperp,E[2]); 00099 00100 float eta= 0.0; 00101 if(E[2] > 0.0) eta= log((ptotal+E[2])/pperp); 00102 else eta= log(pperp/(ptotal-E[2])); 00103 return eta; 00104 } 00105 00106 inline float E2phi(float* p) { 00107 float small= 1.E-05; 00108 float E[3]; 00109 if(p[3] < 0.0) { 00110 E[0]= -p[0]; 00111 E[1]= -p[1]; 00112 E[2]= -p[2]; 00113 } 00114 else { 00115 E[0]= p[0]; 00116 E[1]= p[1]; 00117 E[2]= p[2]; 00118 } 00119 float phi= atan2(E[1],E[0]+small); 00120 //if(phi < 0.0) phi+=kinem::TWOPI; 00121 if (phi < 0.0) phi += inline_maths::TWOPI; 00122 return phi; 00123 } 00124 00125 //template < class CalItem,class CalItemAddress,class CalIClusterChunk > 00126 template < class CalItem > 00127 class ConeClusterAlgo { 00128 // 00129 // Purpose: make calorimeter clusters using a cone algorithm from 00130 // preclusters created previously by the class ConePreClusterAlgo. 00131 // Items must have addresses and 4-momenta. 00132 // The algorithm is implemented with a template function makeClusters. 00133 // 00134 public : 00135 00136 00137 //default constructor 00138 ConeClusterAlgo() {} 00139 00140 //constructor for cone jet algorithm 00141 ConeClusterAlgo( float CONErad,float JETmne,float SPLifr): 00142 _CONErad(fabs(CONErad)), 00143 _JETmne(JETmne), 00144 _SPLifr(SPLifr), 00145 _TWOrad(0.), 00146 _D0_Angle(false), 00147 _Increase_Delta_R(true), 00148 _Kill_Far_Clusters(true), 00149 _Jet_Et_Min_On_Iter(true), 00150 _Far_Ratio(0.5), 00151 _Eitem_Negdrop(-1.0), 00152 _Et_Min_Ratio(0.5), 00153 _Thresh_Diff_Et(0.01) 00154 {} 00155 00156 //changing default thresholds & parameters 00157 // (declared by PARAMETER in RUNI code) 00158 ConeClusterAlgo( float CONErad,float JETmne,float SPLifr,float TWOrad, 00159 float Tresh_Diff_Et,bool D0_Angle,bool Increase_Delta_R, 00160 bool Kill_Far_Clusters,bool Jet_Et_Min_On_Iter, 00161 float Far_Ratio,float Eitem_Negdrop,float Et_Min_Ratio ): 00162 _CONErad(fabs(CONErad)), 00163 _JETmne(JETmne), 00164 _SPLifr(SPLifr), 00165 _TWOrad(TWOrad), 00166 _D0_Angle(D0_Angle), 00167 _Increase_Delta_R(Increase_Delta_R), 00168 _Kill_Far_Clusters(Kill_Far_Clusters), 00169 _Jet_Et_Min_On_Iter(Jet_Et_Min_On_Iter), 00170 _Far_Ratio(Far_Ratio), 00171 _Eitem_Negdrop(Eitem_Negdrop), 00172 _Et_Min_Ratio(Et_Min_Ratio), 00173 _Thresh_Diff_Et(Tresh_Diff_Et) 00174 {} 00175 00176 //destructor 00177 ~ConeClusterAlgo() {} 00178 00179 //to make jet clusters using cone algorithm 00180 void makeClusters(//const EnergyClusterReco* r, 00181 std::list<CalItem> &jets, 00182 list<const CalItem*> &itemlist, float Zvertex 00183 //, const EnergyClusterCollection<CalItemAddress> &preclu, 00184 //CalIClusterChunk* chunkptr 00185 //) const; 00186 ); 00187 00188 //print parameters of the algorithm 00189 void print(ostream &os)const; 00190 00191 //vector< TemporaryJet > TempColl; 00192 00193 00194 private : 00195 00196 float _CONErad; 00197 float _JETmne; 00198 float _SPLifr; 00199 00200 float _TWOrad; 00201 bool _D0_Angle; 00202 bool _Increase_Delta_R; 00203 bool _Kill_Far_Clusters; 00204 bool _Jet_Et_Min_On_Iter; 00205 float _Far_Ratio; 00206 float _Eitem_Negdrop; 00207 float _Et_Min_Ratio; 00208 float _Thresh_Diff_Et; 00209 00210 class TemporaryJet { 00211 00212 public: 00213 00214 00215 00216 TemporaryJet() {} 00217 00218 TemporaryJet(float eta,float phi) { 00219 _Eta=eta; 00220 _Phi=phi; 00221 } 00222 00223 ~TemporaryJet() {} 00224 00225 void addItem(const CalItem* tw) { 00226 _LItems.push_back(tw); 00227 } 00228 00229 void setEtaPhiEt(float eta,float phi,float pT) { 00230 _Eta= eta; 00231 _Phi= phi; 00232 _Et = pT; 00233 } 00234 00235 void erase() { 00236 _LItems.erase(_LItems.begin(),_LItems.end()); 00237 _Eta= 0.0; 00238 _Phi= 0.0; 00239 _Et = 0.0; 00240 } 00241 00242 bool share_jets(TemporaryJet &NewJet,float SharedFr,float SPLifr) { 00243 // 00244 // combined 00245 // 00246 if(SharedFr >= SPLifr) { 00247 typename list<const CalItem*>::iterator it; 00248 typename list<const CalItem*>::iterator end_of_old=_LItems.end(); 00249 for(it=NewJet._LItems.begin(); it!=NewJet._LItems.end(); it++) { 00250 typename list<const CalItem*>::iterator 00251 where = find(_LItems.begin(),end_of_old,*it); 00252 // if the item is not shared, add to this jet 00253 if(where == end_of_old) { 00254 _LItems.push_back(*it); 00255 } 00256 } 00257 NewJet.erase(); 00258 return false; 00259 } else { 00260 // 00261 // split 00262 // 00263 typename list<const CalItem*>::iterator it; 00264 for(it=NewJet._LItems.begin(); it!=NewJet._LItems.end(); ) { 00265 typename list<const CalItem*>::iterator 00266 where = find(_LItems.begin(),_LItems.end(),*it); 00267 if(where != _LItems.end()) { 00268 //float EtaItem=(*it)->eta(); 00269 //float PhiItem=(*it)->phi(); 00270 // stay closer to the RUNI conventions for negative E cells 00271 float pz[4]; 00272 (*it)->p4vec(pz); 00273 float EtaItem= E2eta(pz); 00274 float PhiItem= E2phi(pz); 00275 00276 float RadOld=R2_bis(_Eta,_Phi,EtaItem,PhiItem); 00277 float RadNew=R2_bis(NewJet.Eta(),NewJet.Phi(),EtaItem,PhiItem); 00278 if (RadNew > RadOld) { 00279 it = NewJet._LItems.erase(it); 00280 } 00281 else { 00282 _LItems.erase(where); 00283 ++it; 00284 } 00285 } 00286 else ++it; 00287 } 00288 return true; 00289 } 00290 } 00291 00292 00293 float dist_R2(TemporaryJet &jet) const { 00294 float deta= _Eta-jet.Eta(); 00295 //float dphi= kinem::delta_phi(_Phi,jet.Phi()); 00296 float dphi= inline_maths::delta_phi(_Phi,jet.Phi()); 00297 return (deta*deta+dphi*dphi); 00298 } 00299 00300 bool ItemInJet(const CalItem* tw) const { 00301 typename list<const CalItem*>::const_iterator 00302 where= find(_LItems.begin(),_LItems.end(),tw); 00303 if(where != _LItems.end()) return true; 00304 else return false; 00305 } 00306 00307 bool updateEtaPhiEt() { 00308 float ETsum = 0.0; 00309 float ETAsum= 0.0; 00310 float PHIsum= 0.0; 00311 float Esum= 0.0; 00312 typename list<const CalItem*>::iterator it; 00313 for(it=_LItems.begin(); it!=_LItems.end(); it++) { 00314 float ETk = (*it)->pT(); 00315 // now done in CalCell/CalTower if((*it)->E() < 0.0) ETk= -ETk; 00316 00317 //float ETAk= (*it)->eta(); 00318 //float PHIk= (*it)->phi(); 00319 float pz[4]; 00320 (*it)->p4vec(pz); 00321 float ETAk= E2eta(pz); 00322 // take care of the phi=0=2pi problem 00323 float PHIk= E2phi(pz); 00324 //if(fabs(PHIk-_Phi) > kinem::TWOPI-fabs(PHIk-_Phi)) 00325 if(fabs(PHIk-_Phi) > inline_maths::TWOPI-fabs(PHIk-_Phi)) 00326 { 00327 if(_Phi < PHIk) 00328 { 00329 //PHIk -= kinem::TWOPI; 00330 PHIk -= inline_maths::TWOPI; 00331 } 00332 else 00333 { 00334 //PHIk += kinem::TWOPI; 00335 PHIk += inline_maths::TWOPI; 00336 } 00337 } 00338 ETAsum+= ETAk*ETk; 00339 PHIsum+= PHIk*ETk; 00340 ETsum += ETk; 00341 // Esum+=(*it)->E(); use 4-momentum components 00342 Esum+= pz[3]; 00343 } 00344 if(ETsum <= 0.0) { 00345 _Eta= 0.0; 00346 _Phi= 0.0; 00347 _Et = 0.0; 00348 _E=0.; 00349 return false; 00350 } 00351 else { 00352 _Eta= ETAsum/ETsum; 00353 _Phi= PHIsum/ETsum; 00354 //if ( _Phi<0 ) _Phi+=kinem::TWOPI; 00355 if ( _Phi<0 ) _Phi+=inline_maths::TWOPI; 00356 _Et = ETsum; 00357 _E = Esum; 00358 return true; 00359 } 00360 } 00361 00362 void D0_Angle_updateEtaPhi() { 00363 float EXsum = 0.0; 00364 float EYsum = 0.0; 00365 float EZsum = 0.0; 00366 typename list<const CalItem*>::iterator it; 00367 for(it=_LItems.begin(); it!=_LItems.end(); it++) { 00368 float p[4]; 00369 (*it)->p4vec(p); 00370 EXsum += p[0]; 00371 EYsum += p[1]; 00372 EZsum += p[2]; 00373 } 00374 //_Phi=kinem::phi(EYsum,EXsum); 00375 _Phi=inline_maths::phi(EYsum,EXsum); 00376 //_Eta=kinem::eta(EXsum,EYsum,EZsum); 00377 _Eta=inline_maths::eta(EXsum,EYsum,EZsum); 00378 } 00379 00380 void getItems(list<const CalItem*> &ecv) const { 00381 ecv.clear(); //ls 27/Feb/2010 00382 typename list<const CalItem*>::const_iterator it; 00383 for(it=_LItems.begin(); it!=_LItems.end(); it++) { 00384 ecv.push_back(*it); 00385 } 00386 } 00387 00388 float Eta() {return _Eta;} 00389 float Phi() {return _Phi;} 00390 float Et() {return _Et;} 00391 float E() {return _E;} 00392 list<const CalItem*> &LItems() {return _LItems;} 00393 00394 private: 00395 list<const CalItem*> _LItems; 00396 float _Eta; 00397 float _Phi; 00398 float _Et; 00399 float _E; 00400 }; //class TemporaryJet 00401 00402 void getItemsInCone(list<const CalItem*> &tlist, float etaJet, float phiJet, 00403 float cone_radius, float zvertex_in) const; 00404 void getItemsInCone_bis(list<const CalItem*> &tlist, float etaJet, 00405 float phiJet,float cone_radius, float zvertex_in) const; 00406 00407 public: 00408 00409 vector< TemporaryJet > TempColl; 00410 00411 }; 00412 ///////////////////////////////////////////////////////// 00413 00414 //template < class CalItem,class CalItemAddress,class CalIClusterChunk > 00415 template < class CalItem > 00416 //void ConeClusterAlgo <CalItem,CalItemAddress,CalIClusterChunk >:: 00417 void ConeClusterAlgo <CalItem >:: 00418 getItemsInCone(list<const CalItem*> &tlist, float etaJet, float phiJet, 00419 float cone_radius, float zvertex_in) const { 00420 // 00421 // provide the list of Items (towers, Cells...) containing the energy from a 00422 // jet of a given cone size 00423 // 00424 float ZVERTEX_MAX=200.; 00425 float DMIN=80.; 00426 float DMAX=360.; 00427 float THETA_margin=0.022; 00428 00429 float zvertex=zvertex_in; 00430 float d1,d2; 00431 float phi_d1, phi_d2; 00432 float theta_E1, r1, r2, z1, z2; 00433 float theta_d1, theta_d2, eta_d1, eta_d2; 00434 00435 // Ignore very large vertex positions 00436 if (fabs(zvertex) > ZVERTEX_MAX ) zvertex=0.0; 00437 00438 if (zvertex >=0. ) { 00439 d1=fabs(DMIN-zvertex); 00440 d2=fabs(DMAX+zvertex); 00441 } else { 00442 d1=fabs(DMAX-zvertex); 00443 d2=fabs(DMIN+zvertex); 00444 } 00445 00446 // calculate theta of physics cone and find which eta's this intercepts 00447 // a the maximum points 00448 phi_d1 = phiJet+cone_radius; 00449 //theta_E1 = kinem::theta(etaJet+cone_radius); 00450 theta_E1 = inline_maths::theta(etaJet+cone_radius); 00451 z1 = zvertex+d1*cos(theta_E1); 00452 r1 = d1*sin(theta_E1); 00453 00454 phi_d2 = phiJet-cone_radius; 00455 //theta_E1 = kinem::theta(etaJet-cone_radius); 00456 theta_E1 = inline_maths::theta(etaJet-cone_radius); 00457 z2 = zvertex+d2*cos(theta_E1); 00458 r2 = d2*sin(theta_E1); 00459 00460 // maximum spread in detector theta 00461 theta_d1 = atan2(r1, z1); 00462 theta_d2 = atan2(r2, z2); 00463 00464 // make sure they stay in the calorimeter 00465 theta_d1=max(theta_d1, THETA_margin); 00466 theta_d2=max(theta_d2, THETA_margin); 00467 //theta_d1=min(kinem::PI-(double)THETA_margin, (double)theta_d1); 00468 theta_d1=min(inline_maths::PI-(double)THETA_margin, (double)theta_d1); 00469 //theta_d2=min(kinem::PI-(double)THETA_margin, (double)theta_d2); 00470 theta_d2=min(inline_maths::PI-(double)THETA_margin, (double)theta_d2); 00471 00472 //eta_d1 = kinem::eta(theta_d1); 00473 eta_d1 = inline_maths::eta(theta_d1); 00474 //eta_d2 = kinem::eta(theta_d2); 00475 eta_d2 = inline_maths::eta(theta_d2); 00476 00477 00478 typename list<const CalItem*>::iterator it; 00479 for (it=tlist.begin() ; it != tlist.end() ; ) { 00480 //float eta_cur= (*it)->eta(); 00481 //float phi_cur= (*it)->phi(); 00482 float pz[4]; 00483 (*it)->p4vec(pz); 00484 float eta_cur= E2eta(pz); 00485 float phi_cur= E2phi(pz); 00486 00487 bool accepted = eta_cur < eta_d1 && eta_cur > eta_d2; 00488 //if ( phi_d2>0 && phi_d1<kinem::TWOPI ) { 00489 if ( phi_d2>0 && phi_d1<inline_maths::TWOPI ) { 00490 accepted = accepted && phi_cur<phi_d1 && phi_cur>phi_d2; 00491 } 00492 else{ // case the cone overlap the phi=0=2pi line 00493 if ( phi_d2>0 ){ 00494 accepted = accepted && 00495 //((phi_cur>phi_d2 && phi_cur<kinem::TWOPI) || phi_cur<phi_d1-kinem::TWOPI); 00496 ((phi_cur>phi_d2 && phi_cur<inline_maths::TWOPI) || phi_cur<phi_d1-inline_maths::TWOPI); 00497 } 00498 else{ 00499 accepted = accepted && 00500 //((phi_cur<phi_d1 && phi_cur>0) || phi_cur>phi_d2+kinem::TWOPI); 00501 ((phi_cur<phi_d1 && phi_cur>0) || phi_cur>phi_d2+inline_maths::TWOPI); 00502 } 00503 } 00504 if ( ! accepted ) it = tlist.erase(it); 00505 else ++it; 00506 00507 } 00508 } 00509 ///////////////////////////////////////////////////////// 00510 //template < class CalItem,class CalItemAddress,class CalIClusterChunk > 00511 template < class CalItem > 00512 //void ConeClusterAlgo <CalItem,CalItemAddress,CalIClusterChunk >:: 00513 void ConeClusterAlgo <CalItem>:: 00514 getItemsInCone_bis(list<const CalItem*> &tlist, float etaJet, float phiJet, 00515 float cone_radius, float zvertex_in) const { 00516 // 00517 // provide the list of Items (towers, Cells...) containing the energy from a 00518 // jet of a given cone size 00519 // 00520 // WARNING: this is only to be used to compare to RUN I cone jets 00521 // 00522 float ZVERTEX_MAX=200.; 00523 float DMIN=80.; 00524 float DMAX=360.; 00525 float THETA_margin=0.022; 00526 00527 float zvertex=zvertex_in; 00528 float d1,d2; 00529 float phi_d1, phi_d2; 00530 float theta_E1, r1, r2, z1, z2; 00531 float theta_d1, theta_d2, eta_d1, eta_d2; 00532 00533 // Ignore very large vertex positions 00534 if (fabs(zvertex) > ZVERTEX_MAX ) zvertex=0.0; 00535 00536 if (zvertex >=0. ) { 00537 d1=fabs(DMIN-zvertex); 00538 d2=fabs(DMAX+zvertex); 00539 } else { 00540 d1=fabs(DMAX-zvertex); 00541 d2=fabs(DMIN+zvertex); 00542 } 00543 00544 // calculate theta of physics cone and find which eta's this intercepts 00545 // a the maximum points 00546 00547 phi_d1 = phiJet+cone_radius; 00548 //theta_E1 = kinem::theta(etaJet+cone_radius); 00549 theta_E1 = inline_maths::theta(etaJet+cone_radius); 00550 z1 = zvertex+d1*cos(theta_E1); 00551 r1 = d1*sin(theta_E1); 00552 00553 phi_d2 = phiJet-cone_radius; 00554 //theta_E1 = kinem::theta(etaJet-cone_radius); 00555 theta_E1 = inline_maths::theta(etaJet-cone_radius); 00556 z2 = zvertex+d2*cos(theta_E1); 00557 r2 = d2*sin(theta_E1); 00558 00559 // maximum spread in detector theta 00560 00561 theta_d1 = atan2(r1, z1); 00562 theta_d2 = atan2(r2, z2); 00563 00564 // make sure they stay in the calorimeter 00565 00566 theta_d1=max(theta_d1, THETA_margin); 00567 theta_d2=max(theta_d2, THETA_margin); 00568 //theta_d1=min(kinem::PI-(double)THETA_margin, (double)theta_d1); 00569 theta_d1=min(inline_maths::PI-(double)THETA_margin, (double)theta_d1); 00570 //theta_d2=min(kinem::PI-(double)THETA_margin, (double)theta_d2); 00571 theta_d2=min(inline_maths::PI-(double)THETA_margin, (double)theta_d2); 00572 00573 00574 //eta_d1 = kinem::eta(theta_d1); 00575 eta_d1 = inline_maths::eta(theta_d1); 00576 //eta_d2 = kinem::eta(theta_d2); 00577 eta_d2 = inline_maths::eta(theta_d2); 00578 00579 float signe; 00580 00581 if( eta_d1>=0.0 ) signe= 1.0; 00582 else signe= -1.0; 00583 int ietaMAX= eta_d1/0.1+signe; 00584 if(fabs(eta_d1)>=4.45) ietaMAX= 37*signe; 00585 else if(fabs(eta_d1)>=4.1) ietaMAX= 36*signe; 00586 else if(fabs(eta_d1)>=3.7) ietaMAX= 35*signe; 00587 else if(fabs(eta_d1)>=3.42) ietaMAX= 34*signe; 00588 else if(fabs(eta_d1)>=3.2) ietaMAX= 33*signe; 00589 00590 if( eta_d2>=0.0 ) signe= 1.0; 00591 else signe= -1.0; 00592 int ietaMIN= eta_d2/0.1+signe; 00593 if(fabs(eta_d2)>=4.45) ietaMIN= 37*signe; 00594 else if(fabs(eta_d2)>=4.1) ietaMIN= 36*signe; 00595 else if(fabs(eta_d2)>=3.7) ietaMIN= 35*signe; 00596 else if(fabs(eta_d2)>=3.42) ietaMIN= 34*signe; 00597 else if(fabs(eta_d2)>=3.2) ietaMIN= 33*signe; 00598 00599 //int iphiMAX= 64*phi_d1/(2.*kinem::PI)+1; 00600 int iphiMAX= 64*phi_d1/(2.*inline_maths::PI)+1; 00601 //int iphiMIN= 64*phi_d2/(2.*kinem::PI)+1; 00602 int iphiMIN= 64*phi_d2/(2.*inline_maths::PI)+1; 00603 00604 typename list<const CalItem*>::iterator it; 00605 for (it=tlist.begin() ; it != tlist.end() ; ) { 00606 //float eta_cur= (*it)->eta(); 00607 //float phi_cur= (*it)->phi(); 00608 int ieta= (*it)->address().ieta(); 00609 int iphi= (*it)->address().iphi(); 00610 00611 bool accepted = ieta<ietaMAX && ieta>ietaMIN; 00612 if ( iphiMIN>0 && iphiMAX<=64 ) { 00613 accepted = accepted && iphi<iphiMAX && iphi>iphiMIN; 00614 } 00615 else{ // case the cone overlap the phi=0=2pi line 00616 if ( iphiMIN>0 ){ 00617 accepted = accepted && 00618 ((iphi>iphiMIN && iphi<=64) || iphi<iphiMAX-64); 00619 } 00620 else{ 00621 accepted = accepted && 00622 ((iphi<iphiMAX && iphi>0) || iphi>iphiMIN+64); 00623 } 00624 } 00625 if ( ! accepted ) it = tlist.erase(it); 00626 else ++it; 00627 00628 } 00629 } 00630 ///////////////////////////////////////////////////////// 00631 //template < class CalItem,class CalItemAddress,class CalIClusterChunk > 00632 template < class CalItem > 00633 //inline void ConeClusterAlgo <CalItem,CalItemAddress,CalIClusterChunk >:: 00634 inline void ConeClusterAlgo <CalItem >:: 00635 print(ostream &os) const { 00636 os<<endl<<" CONE ALGORITHM, cone radius= "<<_CONErad<<endl<< 00637 " min E_T fraction= "<<_JETmne<<endl<< 00638 " minimum Delta_R separation between cones= "<<_TWOrad<<endl<< 00639 " shared E_T fraction threshold for combining jets= "<<_SPLifr<<endl; 00640 } 00641 ///////////////////////////////////////////////////////// 00642 00643 //template < class CalItem,class CalItemAddress,class CalIClusterChunk > 00644 template < class CalItem > 00645 //void ConeClusterAlgo <CalItem,CalItemAddress,CalIClusterChunk >:: 00646 void ConeClusterAlgo <CalItem >:: 00647 makeClusters(//const EnergyClusterReco* r, 00648 std::list<CalItem> &jets, 00649 list<const CalItem*> &itemlist, float Zvertex 00650 //, const EnergyClusterCollection<CalItemAddress> &preclu, 00651 //CalIClusterChunk* chunkptr 00652 //) const { 00653 ) { 00654 00655 // create an energy cluster collection for jets 00656 //EnergyClusterCollection<CalItemAddress>* ptrcol; 00657 //r->createClusterCollection(chunkptr, ptrcol); 00658 std::vector<const CalItem*> ecv; 00659 for ( typename std::list<const CalItem*>::iterator it = itemlist.begin(); 00660 it != itemlist.end(); it++) { 00661 ecv.push_back(*it); 00662 } 00663 00664 00665 // Initialize 00666 float Rcut= 1.E-06; 00667 if(_Increase_Delta_R) Rcut= 1.E-04; 00668 bool nojets; 00669 00670 //vector< TemporaryJet > TempColl; 00671 list< pair<float,float> > LTrack; 00672 00673 // get a vector with pointers to EnergyCluster in the collection 00674 //vector<const EnergyCluster<CalItemAddress>*> ecv; 00675 //preclu.getClusters(ecv); 00676 00677 // loop over all preclusters 00678 //typename vector<const EnergyCluster<CalItemAddress>*>::iterator jclu; 00679 typename std::vector<const CalItem*>::iterator jclu; 00680 for( jclu=ecv.begin(); jclu!=ecv.end(); jclu++ ) { 00681 ////const EnergyCluster<CalItemAddress>* ptr= *jclu; 00682 const CalItem* ptr= *jclu; 00683 //float PHIst= ptr->phi(); 00684 //float ETAst= ptr->eta(); 00685 float pz[4]; 00686 ptr->p4vec(pz); 00687 float ETAst= E2eta(pz); 00688 float PHIst= E2phi(pz); 00689 00690 //cout << "seed 4-vec "; 00691 //for ( int i = 0; i < 4; i++) cout << pz[i] << " "; 00692 //cout << endl; 00693 00694 nojets= false; 00695 // check to see if precluster is too close to a found jet 00696 if(_Kill_Far_Clusters) { 00697 list< pair<float,float> >::iterator kj; 00698 for(kj=LTrack.begin(); kj!=LTrack.end(); kj++) { 00699 if(DELTA_r((*kj).first,ETAst,(*kj).second,PHIst)<_Far_Ratio*_CONErad) { 00700 nojets= true; 00701 //cout << "seed too close ! skip " << endl; 00702 break; 00703 } 00704 } 00705 } 00706 if( nojets==false ) { 00707 TemporaryJet TJet(ETAst,PHIst); 00708 list< pair<int,float> > JETshare; 00709 00710 // start of cone building loop 00711 int trial= 0; 00712 do{ 00713 trial++; 00714 //cout << " trial " << trial << endl; 00715 00716 ETAst= TJet.Eta(); 00717 PHIst= TJet.Phi(); 00718 TJet.erase(); 00719 00720 //if(PHIst > kinem::TWOPI) PHIst= PHIst-kinem::TWOPI; 00721 if(PHIst > inline_maths::TWOPI) PHIst= PHIst-inline_maths::TWOPI; 00722 //if(PHIst < 0.0 ) PHIst= PHIst+kinem::TWOPI; 00723 if(PHIst < 0.0 ) PHIst= PHIst+inline_maths::TWOPI; 00724 //if( PHIst>kinem::TWOPI || PHIst<0.0 ) { 00725 if( PHIst>inline_maths::TWOPI || PHIst<0.0 ) { 00726 TJet.setEtaPhiEt(0.0,0.0,0.0); 00727 break; // end loop do (illegal jet PHI) 00728 } 00729 TJet.setEtaPhiEt(ETAst,PHIst,0.0); 00730 00731 // calculate eta & phi limits for cone 00732 list<const CalItem*> Twlist(itemlist); 00733 00734 getItemsInCone(Twlist,ETAst,PHIst,_CONErad,Zvertex); 00735 // only to compare with RUN I cone jets ! getItemsInCone_bis(Twlist,ETAst,PHIst,_CONErad,Zvertex); 00736 00737 // loop over the possible items for this cone 00738 typename list<const CalItem*>::iterator tk; 00739 for( tk= Twlist.begin(); tk!=Twlist.end(); tk++ ) { 00740 float ETk =(*tk)->pT(); 00741 // now done in CalCell/CalTower if((*tk)->E() < 0.0) ETk= -ETk; 00742 00743 if( ETk > _Eitem_Negdrop ) { 00744 //float ETAk=(*tk)->eta(); 00745 //float PHIk=(*tk)->phi(); 00746 float pz[4]; 00747 (*tk)->p4vec(pz); 00748 float ETAk= E2eta(pz); 00749 float PHIk= E2phi(pz); 00750 00751 float dphi= fabs(PHIk-PHIst); 00752 //if(dphi > kinem::TWOPI-dphi) { 00753 if(dphi > inline_maths::TWOPI-dphi) { 00754 //if(PHIst < PHIk) PHIk= PHIk-kinem::TWOPI; 00755 if(PHIst < PHIk) PHIk= PHIk-inline_maths::TWOPI; 00756 //else PHIk= PHIk+kinem::TWOPI; 00757 else PHIk= PHIk+inline_maths::TWOPI; 00758 } 00759 00760 if( R2_bis(ETAk,PHIk,ETAst,PHIst) <= _CONErad*_CONErad ) { 00761 TJet.addItem(*tk); 00762 } 00763 } 00764 }// end loop tk 00765 00766 if(TJet.updateEtaPhiEt()==false) { 00767 //cout << " negative E jet ! drop " << endl; 00768 break; 00769 } 00770 00771 // require some minimum ET on every iteration 00772 if(_Jet_Et_Min_On_Iter) { 00773 if( TJet.Et() < _JETmne*_Et_Min_Ratio ) { 00774 //cout << " too low ET jet ! drop " << endl; 00775 break; // end loop trial 00776 } 00777 } 00778 00779 //cout << " R2 = " << R2_bis(TJet.Eta(),TJet.Phi(),ETAst,PHIst) << 00780 // " Rcut = " << Rcut << endl; 00781 }while(R2_bis(TJet.Eta(),TJet.Phi(),ETAst,PHIst)>=Rcut && trial<=50); 00782 00783 if( TJet.Et() >= _JETmne ) { 00784 //cout << " jet accepted will check for overlaps " << endl; 00785 if(_D0_Angle) TJet.D0_Angle_updateEtaPhi(); 00786 //cout << " after TJet.D0_Angle_updateEtaPhi() " << endl; 00787 00788 // item also in another jet 00789 list<const CalItem*> Lst; 00790 TJet.getItems(Lst); 00791 typename list<const CalItem*>::iterator tk; 00792 for(tk=Lst.begin(); tk!=Lst.end(); tk++) { 00793 float ETk=(*tk)->pT(); 00794 // now done in CalCell/CalTower if((*tk)->E() < 0.0) ETk= -ETk; 00795 for(unsigned int kj=0; kj<TempColl.size(); kj++) { 00796 if(TempColl[kj].ItemInJet(*tk)==true) { 00797 list< pair<int,float> >::iterator pit; 00798 bool jetok= false; 00799 for(pit=JETshare.begin(); pit!=JETshare.end();pit++) { 00800 if((*pit).first == (int) kj) { 00801 jetok= true; 00802 (*pit).second+= ETk; 00803 break; 00804 } 00805 } 00806 if(jetok==false) JETshare.push_back(make_pair(kj,ETk)); 00807 } 00808 } 00809 } 00810 00811 if(JETshare.size() >0) { 00812 list< pair<int,float> >::iterator pit; 00813 float Ssum= 0.0; 00814 list< pair<int,float> >::iterator pitMAX=JETshare.begin(); 00815 for(pit=JETshare.begin(); pit!=JETshare.end(); pit++) { 00816 Ssum+= (*pit).second; 00817 if((*pit).second > (*pitMAX).second) pitMAX= pit; 00818 } 00819 00820 //int IJET= (*pitMAX).first; 00821 bool splshr; 00822 float Eleft= fabs(TJet.Et()-Ssum); 00823 float Djets= TempColl[(*pitMAX).first].dist_R2(TJet); 00824 if(Djets <= _TWOrad || Eleft <= _Thresh_Diff_Et) { 00825 TJet.erase(); 00826 splshr= false; 00827 } 00828 else { 00829 float SharedFr=Ssum/min(TempColl[(*pitMAX).first].Et(),TJet.Et()); 00830 if(JETshare.size() >1) { 00831 typename list<const CalItem*>::iterator tk; 00832 for(tk=TJet.LItems().begin(); tk!=TJet.LItems().end(); ) { 00833 bool found = false; 00834 list< pair<int,float> >::iterator pit; 00835 for(pit=JETshare.begin(); pit!=JETshare.end();pit++) { 00836 if((*pit).first!=(*pitMAX).first) { 00837 if(TempColl[(*pit).first].ItemInJet(*tk)==true) { 00838 tk = TJet.LItems().erase(tk); 00839 found = true; 00840 break; 00841 } 00842 } 00843 } 00844 if ( !found ) ++tk; 00845 } 00846 } 00847 00848 splshr= TempColl[(*pitMAX).first].share_jets(TJet,SharedFr,_SPLifr); 00849 00850 if( splshr==true ) { 00851 //cout << " jet splitted due to overlaps " << endl; 00852 TempColl[(*pitMAX).first].updateEtaPhiEt(); 00853 TJet.updateEtaPhiEt(); 00854 if(_D0_Angle) TJet.D0_Angle_updateEtaPhi(); 00855 if(_D0_Angle) TempColl[(*pitMAX).first].D0_Angle_updateEtaPhi(); 00856 TempColl.push_back(TJet); 00857 LTrack.push_back(make_pair(TJet.Eta(),TJet.Phi())); 00858 } 00859 else { 00860 //cout << " jet merged due to overlaps " << endl; 00861 TempColl[(*pitMAX).first].updateEtaPhiEt(); 00862 if(_D0_Angle) TempColl[(*pitMAX).first].D0_Angle_updateEtaPhi(); 00863 } 00864 } 00865 } 00866 else { 00867 TJet.updateEtaPhiEt(); 00868 if(_D0_Angle) TJet.D0_Angle_updateEtaPhi(); 00869 TempColl.push_back(TJet); 00870 LTrack.push_back(make_pair(TJet.Eta(),TJet.Phi())); 00871 } 00872 } //JETmne 00873 } //nojets 00874 }// end loop jclu 00875 00876 for(unsigned int i=0; i<TempColl.size(); i++) { 00877 //EnergyCluster<CalItemAddress>* ptrclu; 00878 CalItem ptrclu; 00879 //r->createCluster(ptrcol,ptrclu); 00880 list<const CalItem*> Vi; 00881 TempColl[i].getItems(Vi); 00882 typename list<const CalItem*>::iterator it; 00883 for(it=Vi.begin(); it!=Vi.end(); it++) { 00884 const CalItem* ptr= *it; 00885 //CalItemAddress addr= ptr->address(); 00886 float p[4]; 00887 ptr->p4vec(p); 00888 //float emE= ptr->emE(); 00889 //r->addClusterItem(ptrclu,addr,p,emE); 00890 ptrclu.Add(*ptr); 00891 } 00892 jets.push_back(ptrclu); 00893 } 00894 00895 }// end 00896 00897 } //namespace d0runi 00898 00899 FASTJET_END_NAMESPACE 00900 00901 #endif // CONECLUSTERALGO_H 00902 00903 00904