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