56 #ifndef  D0RunIconeJets_CONECLUSTERALGO_H 
   57 #define  D0RunIconeJets_CONECLUSTERALGO_H 
   69 #include "inline_maths.h" 
   70 #include <fastjet/internal/base.hh> 
   72 FASTJET_BEGIN_NAMESPACE
 
   79 inline float R2(
float eta1, 
float phi1, 
float eta2, 
float phi2) {
 
   80   return (eta1-eta2)*(eta1-eta2)+(phi1-phi2)*(phi1-phi2); }
 
   82 inline float R2_bis(
float eta1, 
float phi1, 
float eta2, 
float phi2) {
 
   84   float dphi = inline_maths::delta_phi(phi1,phi2);
 
   85   return (eta1-eta2)*(eta1-eta2)+dphi*dphi; }
 
   87 inline float DELTA_r(
float eta1,
float eta2,
float phi1,
float phi2) {
 
   89   float dphi = inline_maths::delta_phi(phi1,phi2);
 
   90   return sqrt((eta1-eta2)*(eta1-eta2)+dphi*dphi);
 
   93 inline float E2eta(
float* p) { 
 
  106    float pperp= sqrt(E[0]*E[0]+E[1]*E[1])+small;
 
  107    float ptotal= sqrt(E[0]*E[0]+E[1]*E[1]+E[2]*E[2])+small;
 
  111    if(E[2] > 0.0) eta= log((ptotal+E[2])/pperp);
 
  112    else eta= log(pperp/(ptotal-E[2]));
 
  116 inline float E2phi(
float* p) { 
 
  129    float phi= atan2(E[1],E[0]+small);
 
  131    if (phi < 0.0) phi += inline_maths::TWOPI;
 
  136 template < 
class CalItem >
 
  137 class ConeClusterAlgo {
 
  151 ConeClusterAlgo( 
float CONErad,
float JETmne,
float SPLifr):
 
  152   _CONErad(fabs(CONErad)), 
 
  157   _Increase_Delta_R(true),
 
  158   _Kill_Far_Clusters(true),
 
  159   _Jet_Et_Min_On_Iter(true),
 
  161   _Eitem_Negdrop(-1.0),
 
  163   _Thresh_Diff_Et(0.01)
 
  168 ConeClusterAlgo( 
float CONErad,
float JETmne,
float SPLifr,
float TWOrad, 
 
  169                  float Tresh_Diff_Et,
bool D0_Angle,
bool Increase_Delta_R,
 
  170                  bool Kill_Far_Clusters,
bool Jet_Et_Min_On_Iter,
 
  171                  float Far_Ratio,
float Eitem_Negdrop,
float Et_Min_Ratio ):
 
  172   _CONErad(fabs(CONErad)), 
 
  177   _Increase_Delta_R(Increase_Delta_R),
 
  178   _Kill_Far_Clusters(Kill_Far_Clusters),
 
  179   _Jet_Et_Min_On_Iter(Jet_Et_Min_On_Iter),
 
  180   _Far_Ratio(Far_Ratio),
 
  181   _Eitem_Negdrop(Eitem_Negdrop),
 
  182   _Et_Min_Ratio(Et_Min_Ratio),
 
  183   _Thresh_Diff_Et(Tresh_Diff_Et)
 
  187 ~ConeClusterAlgo() {}
 
  191                   std::list<CalItem> &jets,
 
  192                   list<const CalItem*> &itemlist, 
float Zvertex 
 
  199 void print(ostream &os)
const;
 
  212   bool _Increase_Delta_R;
 
  213   bool _Kill_Far_Clusters;
 
  214   bool _Jet_Et_Min_On_Iter;
 
  216   float _Eitem_Negdrop;
 
  218   float _Thresh_Diff_Et;
 
  228     TemporaryJet(
float eta,
float phi) { 
 
  235     void addItem(
const CalItem* tw) {
 
  236       _LItems.push_back(tw);
 
  239     void setEtaPhiEt(
float eta,
float phi,
float pT) {
 
  246       _LItems.erase(_LItems.begin(),_LItems.end());
 
  252     bool share_jets(TemporaryJet &NewJet,
float SharedFr,
float SPLifr) {
 
  256       if(SharedFr >= SPLifr) {
 
  257         typename list<const CalItem*>::iterator it;
 
  258         typename list<const CalItem*>::iterator end_of_old=_LItems.end();
 
  259         for(it=NewJet._LItems.begin(); it!=NewJet._LItems.end(); it++) {
 
  260           typename list<const CalItem*>::iterator 
 
  261             where = find(_LItems.begin(),end_of_old,*it);
 
  263           if(where == end_of_old) {
 
  264             _LItems.push_back(*it);
 
  273         typename list<const CalItem*>::iterator it;
 
  274         for(it=NewJet._LItems.begin(); it!=NewJet._LItems.end(); ) {
 
  275           typename list<const CalItem*>::iterator 
 
  276             where = find(_LItems.begin(),_LItems.end(),*it);
 
  277           if(where != _LItems.end()) {
 
  283             float EtaItem= E2eta(pz);
 
  284             float PhiItem= E2phi(pz);
 
  286             float RadOld=R2_bis(_Eta,_Phi,EtaItem,PhiItem);
 
  287             float RadNew=R2_bis(NewJet.Eta(),NewJet.Phi(),EtaItem,PhiItem);
 
  288             if (RadNew > RadOld) { 
 
  289               it = NewJet._LItems.erase(it);
 
  292               _LItems.erase(where);
 
  303     float dist_R2(TemporaryJet &jet)
 const {
 
  304       float deta= _Eta-jet.Eta();
 
  306       float dphi= inline_maths::delta_phi(_Phi,jet.Phi());
 
  307       return (deta*deta+dphi*dphi); 
 
  310     bool ItemInJet(
const CalItem* tw)
 const {
 
  311       typename list<const CalItem*>::const_iterator
 
  312         where= find(_LItems.begin(),_LItems.end(),tw);
 
  313       if(where != _LItems.end()) 
return true;
 
  317     bool updateEtaPhiEt() { 
 
  322       typename list<const CalItem*>::iterator it;
 
  323       for(it=_LItems.begin(); it!=_LItems.end(); it++) {
 
  324         float ETk = (*it)->pT();
 
  331         float ETAk= E2eta(pz);
 
  333         float PHIk= E2phi(pz);
 
  335         if(fabs(PHIk-_Phi) > inline_maths::TWOPI-fabs(PHIk-_Phi))
 
  340               PHIk -= inline_maths::TWOPI;
 
  345               PHIk += inline_maths::TWOPI;
 
  365          if ( _Phi<0 ) _Phi+=inline_maths::TWOPI;
 
  372     void D0_Angle_updateEtaPhi() {
 
  376       typename list<const CalItem*>::iterator it;
 
  377       for(it=_LItems.begin(); it!=_LItems.end(); it++) {
 
  385       _Phi=inline_maths::phi(EYsum,EXsum);
 
  387       _Eta=inline_maths::eta(EXsum,EYsum,EZsum);
 
  390     void getItems(list<const CalItem*> &ecv)
 const {
 
  392       typename list<const CalItem*>::const_iterator it;
 
  393       for(it=_LItems.begin(); it!=_LItems.end(); it++) {
 
  398     float Eta() {
return _Eta;}
 
  399     float Phi() {
return _Phi;}
 
  400     float Et()  {
return _Et;}
 
  401     float E()  {
return _E;}
 
  402     list<const CalItem*> &LItems() {
return _LItems;}
 
  405     list<const CalItem*> _LItems;
 
  412   void getItemsInCone(list<const CalItem*> &tlist, 
float etaJet, 
float phiJet,
 
  413                       float cone_radius, 
float zvertex_in) 
const; 
 
  414   void getItemsInCone_bis(list<const CalItem*> &tlist, 
float etaJet, 
 
  415                float phiJet,
float cone_radius, 
float zvertex_in) 
const; 
 
  419   vector< TemporaryJet > TempColl;  
 
  425 template < 
class CalItem >
 
  427 void ConeClusterAlgo <CalItem >:: 
 
  428 getItemsInCone(list<const CalItem*> &tlist, 
float etaJet, 
float phiJet, 
 
  429                float cone_radius, 
float zvertex_in)
 const {
 
  434   float ZVERTEX_MAX=200.;
 
  437   float THETA_margin=0.022;
 
  439   float zvertex=zvertex_in;
 
  441   float phi_d1, phi_d2;
 
  442   float theta_E1, r1, r2, z1, z2;
 
  443   float theta_d1, theta_d2, eta_d1, eta_d2;
 
  446   if (fabs(zvertex) > ZVERTEX_MAX ) zvertex=0.0;
 
  449     d1=fabs(DMIN-zvertex);
 
  450     d2=fabs(DMAX+zvertex);
 
  452     d1=fabs(DMAX-zvertex);
 
  453     d2=fabs(DMIN+zvertex);
 
  458   phi_d1 = phiJet+cone_radius;
 
  460   theta_E1 = inline_maths::theta(etaJet+cone_radius);
 
  461   z1 = zvertex+d1*cos(theta_E1);
 
  462   r1 = d1*sin(theta_E1);
 
  464   phi_d2 = phiJet-cone_radius;
 
  466   theta_E1 = inline_maths::theta(etaJet-cone_radius);
 
  467   z2 = zvertex+d2*cos(theta_E1);
 
  468   r2 = d2*sin(theta_E1);
 
  471   theta_d1 = atan2(r1, z1);
 
  472   theta_d2 = atan2(r2, z2);
 
  475   theta_d1=max(theta_d1, THETA_margin);
 
  476   theta_d2=max(theta_d2, THETA_margin);
 
  478   theta_d1=min(inline_maths::PI-(
double)THETA_margin, (
double)theta_d1);
 
  480   theta_d2=min(inline_maths::PI-(
double)THETA_margin, (
double)theta_d2);
 
  483   eta_d1 = inline_maths::eta(theta_d1);
 
  485   eta_d2 = inline_maths::eta(theta_d2);
 
  488   typename list<const CalItem*>::iterator it;
 
  489   for (it=tlist.begin() ; it != tlist.end() ; ) {
 
  494     float eta_cur= E2eta(pz);
 
  495     float phi_cur= E2phi(pz);
 
  497     bool accepted = eta_cur < eta_d1 && eta_cur > eta_d2;
 
  499     if ( phi_d2>0 && phi_d1<inline_maths::TWOPI ) {
 
  500       accepted = accepted && phi_cur<phi_d1 && phi_cur>phi_d2;
 
  504         accepted = accepted && 
 
  506           ((phi_cur>phi_d2 && phi_cur<inline_maths::TWOPI) || phi_cur<phi_d1-inline_maths::TWOPI);
 
  509         accepted = accepted && 
 
  511           ((phi_cur<phi_d1 && phi_cur>0) || phi_cur>phi_d2+inline_maths::TWOPI);
 
  514     if ( ! accepted ) it = tlist.erase(it);
 
  521 template < 
class CalItem >
 
  523 void ConeClusterAlgo <CalItem>:: 
 
  524 getItemsInCone_bis(list<const CalItem*> &tlist, 
float etaJet, 
float phiJet, 
 
  525                float cone_radius, 
float zvertex_in)
 const {
 
  532   float ZVERTEX_MAX=200.;
 
  535   float THETA_margin=0.022;
 
  537   float zvertex=zvertex_in;
 
  539   float phi_d1, phi_d2;
 
  540   float theta_E1, r1, r2, z1, z2;
 
  541   float theta_d1, theta_d2, eta_d1, eta_d2;
 
  544   if (fabs(zvertex) > ZVERTEX_MAX ) zvertex=0.0;
 
  547     d1=fabs(DMIN-zvertex);
 
  548     d2=fabs(DMAX+zvertex);
 
  550     d1=fabs(DMAX-zvertex);
 
  551     d2=fabs(DMIN+zvertex);
 
  557   phi_d1 = phiJet+cone_radius;
 
  559   theta_E1 = inline_maths::theta(etaJet+cone_radius);
 
  560   z1 = zvertex+d1*cos(theta_E1);
 
  561   r1 = d1*sin(theta_E1);
 
  563   phi_d2 = phiJet-cone_radius;
 
  565   theta_E1 = inline_maths::theta(etaJet-cone_radius);
 
  566   z2 = zvertex+d2*cos(theta_E1);
 
  567   r2 = d2*sin(theta_E1);
 
  571   theta_d1 = atan2(r1, z1);
 
  572   theta_d2 = atan2(r2, z2);
 
  576   theta_d1=max(theta_d1, THETA_margin);
 
  577   theta_d2=max(theta_d2, THETA_margin);
 
  579   theta_d1=min(inline_maths::PI-(
double)THETA_margin, (
double)theta_d1);
 
  581   theta_d2=min(inline_maths::PI-(
double)THETA_margin, (
double)theta_d2);
 
  585   eta_d1 = inline_maths::eta(theta_d1);
 
  587   eta_d2 = inline_maths::eta(theta_d2);
 
  591   if( eta_d1>=0.0 ) signe= 1.0;
 
  593   int ietaMAX= eta_d1/0.1+signe;
 
  594   if(fabs(eta_d1)>=4.45) ietaMAX= 37*signe; 
 
  595   else if(fabs(eta_d1)>=4.1) ietaMAX= 36*signe; 
 
  596   else if(fabs(eta_d1)>=3.7) ietaMAX= 35*signe; 
 
  597   else if(fabs(eta_d1)>=3.42) ietaMAX= 34*signe; 
 
  598   else if(fabs(eta_d1)>=3.2) ietaMAX= 33*signe; 
 
  600   if( eta_d2>=0.0 ) signe= 1.0;
 
  602   int ietaMIN= eta_d2/0.1+signe;
 
  603   if(fabs(eta_d2)>=4.45) ietaMIN= 37*signe; 
 
  604   else if(fabs(eta_d2)>=4.1) ietaMIN= 36*signe; 
 
  605   else if(fabs(eta_d2)>=3.7) ietaMIN= 35*signe; 
 
  606   else if(fabs(eta_d2)>=3.42) ietaMIN= 34*signe; 
 
  607   else if(fabs(eta_d2)>=3.2) ietaMIN= 33*signe; 
 
  610   int iphiMAX= 64*phi_d1/(2.*inline_maths::PI)+1;
 
  612   int iphiMIN= 64*phi_d2/(2.*inline_maths::PI)+1;
 
  614   typename list<const CalItem*>::iterator it;
 
  615   for (it=tlist.begin() ; it != tlist.end() ; ) {
 
  618     int ieta= (*it)->address().ieta();
 
  619     int iphi= (*it)->address().iphi();
 
  621     bool accepted = ieta<ietaMAX && ieta>ietaMIN;
 
  622     if ( iphiMIN>0 && iphiMAX<=64 ) {
 
  623       accepted = accepted && iphi<iphiMAX && iphi>iphiMIN;
 
  627         accepted = accepted && 
 
  628           ((iphi>iphiMIN && iphi<=64) || iphi<iphiMAX-64);
 
  631         accepted = accepted && 
 
  632           ((iphi<iphiMAX && iphi>0) || iphi>iphiMIN+64);
 
  635     if ( ! accepted ) it = tlist.erase(it);
 
  642 template < 
class CalItem >
 
  644 inline void ConeClusterAlgo <CalItem >:: 
 
  645 print(ostream &os)
 const {
 
  646     os<<endl<<
" CONE ALGORITHM, cone radius= "<<_CONErad<<endl<<
 
  647     " min E_T fraction= "<<_JETmne<<endl<<
 
  648     " minimum Delta_R separation between cones= "<<_TWOrad<<endl<<
 
  649     " shared E_T fraction threshold for combining jets= "<<_SPLifr<<endl;
 
  654 template < 
class CalItem >
 
  656 void ConeClusterAlgo <CalItem >:: 
 
  658              std::list<CalItem> &jets,
 
  659              list<const CalItem*> &itemlist, 
float Zvertex 
 
  668   std::vector<const CalItem*> ecv;
 
  669   for ( 
typename std::list<const CalItem*>::iterator it = itemlist.begin(); 
 
  670         it != itemlist.end(); it++) {
 
  677   if(_Increase_Delta_R) Rcut= 1.E-04;
 
  681   list< pair<float,float> > LTrack;
 
  689   typename std::vector<const CalItem*>::iterator jclu;
 
  690   for( jclu=ecv.begin(); jclu!=ecv.end(); jclu++ ) {
 
  692     const CalItem* ptr= *jclu;
 
  697     float ETAst= E2eta(pz);
 
  698     float PHIst= E2phi(pz);
 
  706     if(_Kill_Far_Clusters) {
 
  707       list< pair<float,float> >::iterator kj;
 
  708       for(kj=LTrack.begin(); kj!=LTrack.end(); kj++) {
 
  709         if(DELTA_r((*kj).first,ETAst,(*kj).second,PHIst)<_Far_Ratio*_CONErad) {
 
  716     if( nojets==
false ) {
 
  717       TemporaryJet TJet(ETAst,PHIst);
 
  718       list< pair<int,float> > JETshare;
 
  731         if(PHIst > inline_maths::TWOPI) PHIst= PHIst-inline_maths::TWOPI;
 
  733         if(PHIst < 0.0  ) PHIst= PHIst+inline_maths::TWOPI;
 
  735         if( PHIst>inline_maths::TWOPI || PHIst<0.0 ) {
 
  736           TJet.setEtaPhiEt(0.0,0.0,0.0);
 
  739         TJet.setEtaPhiEt(ETAst,PHIst,0.0);
 
  742         list<const CalItem*> Twlist(itemlist);
 
  744         getItemsInCone(Twlist,ETAst,PHIst,_CONErad,Zvertex); 
 
  748         typename list<const CalItem*>::iterator tk;
 
  749         for( tk= Twlist.begin(); tk!=Twlist.end(); tk++ ) {
 
  750           float ETk =(*tk)->pT();
 
  753           if( ETk > _Eitem_Negdrop ) { 
 
  758             float ETAk= E2eta(pz);
 
  759             float PHIk= E2phi(pz);
 
  761             float dphi= fabs(PHIk-PHIst);
 
  763             if(dphi > inline_maths::TWOPI-dphi) {
 
  765               if(PHIst < PHIk) PHIk= PHIk-inline_maths::TWOPI;
 
  767               else PHIk= PHIk+inline_maths::TWOPI; 
 
  770             if( R2_bis(ETAk,PHIk,ETAst,PHIst) <= _CONErad*_CONErad ) { 
 
  776         if(TJet.updateEtaPhiEt()==
false) {
 
  782         if(_Jet_Et_Min_On_Iter) {
 
  783           if( TJet.Et() < _JETmne*_Et_Min_Ratio ) {
 
  791       }
while(R2_bis(TJet.Eta(),TJet.Phi(),ETAst,PHIst)>=Rcut && trial<=50);
 
  793       if( TJet.Et() >= _JETmne ) {
 
  795         if(_D0_Angle) TJet.D0_Angle_updateEtaPhi();
 
  799         list<const CalItem*> Lst;
 
  801         typename list<const CalItem*>::iterator tk;
 
  802         for(tk=Lst.begin(); tk!=Lst.end(); tk++) {
 
  803           float ETk=(*tk)->pT();
 
  805           for(
unsigned int kj=0; kj<TempColl.size(); kj++) {
 
  806             if(TempColl[kj].ItemInJet(*tk)==
true) {
 
  807               list< pair<int,float> >::iterator pit;
 
  809               for(pit=JETshare.begin(); pit!=JETshare.end();pit++) {
 
  810                 if((*pit).first == (
int) kj) {
 
  816               if(jetok==
false) JETshare.push_back(make_pair(kj,ETk));
 
  821         if(JETshare.size() >0) {
 
  822           list< pair<int,float> >::iterator pit;
 
  824           list< pair<int,float> >::iterator pitMAX=JETshare.begin();
 
  825           for(pit=JETshare.begin(); pit!=JETshare.end(); pit++) {
 
  826             Ssum+= (*pit).second;
 
  827             if((*pit).second > (*pitMAX).second) pitMAX= pit;
 
  832           float Eleft= fabs(TJet.Et()-Ssum);
 
  833           float Djets= TempColl[(*pitMAX).first].dist_R2(TJet);
 
  834           if(Djets <= _TWOrad || Eleft <= _Thresh_Diff_Et) { 
 
  839             float SharedFr=Ssum/min(TempColl[(*pitMAX).first].Et(),TJet.Et());
 
  840             if(JETshare.size() >1) {
 
  841               typename list<const CalItem*>::iterator tk;
 
  842               for(tk=TJet.LItems().begin(); tk!=TJet.LItems().end(); ) {
 
  844                 list< pair<int,float> >::iterator pit;
 
  845                 for(pit=JETshare.begin(); pit!=JETshare.end();pit++) {
 
  846                   if((*pit).first!=(*pitMAX).first) { 
 
  847                     if(TempColl[(*pit).first].ItemInJet(*tk)==
true) {
 
  848                       tk = TJet.LItems().erase(tk);
 
  858             splshr= TempColl[(*pitMAX).first].share_jets(TJet,SharedFr,_SPLifr);
 
  862               TempColl[(*pitMAX).first].updateEtaPhiEt();
 
  863               TJet.updateEtaPhiEt();
 
  864               if(_D0_Angle) TJet.D0_Angle_updateEtaPhi();
 
  865               if(_D0_Angle) TempColl[(*pitMAX).first].D0_Angle_updateEtaPhi();
 
  866               TempColl.push_back(TJet);  
 
  867               LTrack.push_back(make_pair(TJet.Eta(),TJet.Phi()));
 
  871               TempColl[(*pitMAX).first].updateEtaPhiEt();
 
  872               if(_D0_Angle) TempColl[(*pitMAX).first].D0_Angle_updateEtaPhi();
 
  877           TJet.updateEtaPhiEt();
 
  878           if(_D0_Angle) TJet.D0_Angle_updateEtaPhi();
 
  879           TempColl.push_back(TJet);  
 
  880           LTrack.push_back(make_pair(TJet.Eta(),TJet.Phi()));
 
  886   for(
unsigned int i=0; i<TempColl.size(); i++) {
 
  890     list<const CalItem*> Vi;
 
  891     TempColl[i].getItems(Vi);
 
  892     typename list<const CalItem*>::iterator it;
 
  893     for(it=Vi.begin(); it!=Vi.end(); it++) {
 
  894       const CalItem* ptr= *it;
 
  902     jets.push_back(ptrclu);
 
  909 FASTJET_END_NAMESPACE
 
  911 #endif  //  CONECLUSTERALGO_H