CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoEgamma/EgammaHFProducers/src/HFClusterAlgo.cc

Go to the documentation of this file.
00001 #include "RecoEgamma/EgammaHFProducers/interface/HFClusterAlgo.h"
00002 #include <sstream>
00003 #include <iostream>
00004 #include <algorithm>
00005 #include <list> 
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalCaloFlagLabels.h"
00008 
00009 using namespace std;
00010 using namespace reco;
00019 HFClusterAlgo::HFClusterAlgo() 
00020 {
00021   m_isMC=true; // safest
00022   
00023 }
00024 
00025 class CompareHFCompleteHitET {
00026 public:
00027   bool operator()(const HFClusterAlgo::HFCompleteHit& h1,const HFClusterAlgo::HFCompleteHit& h2) const {
00028     return h1.et>h2.et;
00029   }
00030 };
00031 
00032 class CompareHFCore {
00033 public:
00034   bool operator()(const double c1,const double c2) const {
00035     return c1>c2;
00036   }
00037 };
00038 
00039 static int indexByEta(HcalDetId id) {
00040   return (id.zside()>0)?(id.ietaAbs()-29+13):(41-id.ietaAbs());
00041 }
00042 
00043 static const double MCMaterialCorrections[] = {  1.000,1.000,1.105,0.970,0.965,0.975,0.956,0.958,0.981,1.005,0.986,1.086,1.000,
00044                                                  1.000,1.086,0.986,1.005,0.981,0.958,0.956,0.975,0.965,0.970,1.105,1.000,1.000 };
00045 
00046     
00047 
00048 void HFClusterAlgo::setup(double minTowerEnergy, double seedThreshold,double maximumSL,double maximumRenergy,
00049                           bool usePMTflag,bool usePulseflag, bool forcePulseFlagMC, int correctionSet){
00050   m_seedThreshold=seedThreshold;
00051   m_minTowerEnergy=minTowerEnergy;
00052   m_maximumSL=maximumSL;
00053   m_usePMTFlag=usePMTflag;
00054   m_usePulseFlag=usePulseflag;
00055   m_forcePulseFlagMC=forcePulseFlagMC;
00056   m_maximumRenergy=maximumRenergy;
00057   m_correctionSet = correctionSet;
00058 
00059   for(int ii=0;ii<13;ii++){
00060     m_cutByEta.push_back(-1);
00061   }
00062 
00063   // always set all the corrections to one...
00064   for (int ii=0; ii<13*2; ii++) 
00065     m_correctionByEta.push_back(1.0);
00066 
00067   if (m_correctionSet==1) { // corrections for material from MC
00068     for (int ii=0; ii<13*2; ii++) 
00069       m_correctionByEta[ii]=MCMaterialCorrections[ii];
00070   }
00071 
00072 }
00073 
00075 void HFClusterAlgo::clusterize(const HFRecHitCollection& hf, 
00076                                const CaloGeometry& geom,
00077                                HFEMClusterShapeCollection& clusterShapes,
00078                                SuperClusterCollection& SuperClusters) {
00079   
00080   std::vector<HFCompleteHit> protoseeds, seeds;
00081   HFRecHitCollection::const_iterator j,j2;
00082   std::vector<HFCompleteHit>::iterator i;
00083   std::vector<HFCompleteHit>::iterator k;
00084   int dP, dE, PWrap;
00085   bool isok=true;
00086   HFEMClusterShape clusShp;
00087  
00088   SuperCluster Sclus;
00089   bool doCluster=false;
00090   
00091   for (j=hf.begin(); j!= hf.end(); j++)  {
00092     const int aieta=j->id().ietaAbs();
00093     int iz=(aieta-29);
00094     // only long fibers and not 29,40,41 allowed to be considered as seeds
00095     if (j->id().depth()!=1) continue;
00096     if (aieta==40 || aieta==41 || aieta==29) continue;
00097    
00098 
00099     if (iz<0 || iz>12) {
00100       edm::LogWarning("HFClusterAlgo") << "Strange invalid HF hit: " << j->id();
00101       continue;
00102     }
00103 
00104     if (m_cutByEta[iz]<0) {
00105       double eta=geom.getPosition(j->id()).eta();
00106       m_cutByEta[iz]=m_seedThreshold*cosh(eta); // convert ET to E for this ring
00107     }
00108     double elong=j->energy()*m_correctionByEta[indexByEta(j->id())];
00109     if (elong>m_cutByEta[iz]) {
00110       j2=hf.find(HcalDetId(HcalForward,j->id().ieta(),j->id().iphi(),2));
00111       double eshort=(j2==hf.end())?(0):(j2->energy());
00112       if (j2!=hf.end())
00113          eshort*=m_correctionByEta[indexByEta(j2->id())];
00114       if (((elong-eshort)/(elong+eshort))>m_maximumSL) continue;
00115       //if ((m_usePMTFlag)&&(j->flagField(4,1))) continue;
00116       //if ((m_usePulseFlag)&&(j->flagField(1,1))) continue;
00117       if(isPMTHit(*j)) continue;
00118 
00119       HFCompleteHit ahit;
00120       double eta=geom.getPosition(j->id()).eta();
00121       ahit.id=j->id();
00122       ahit.energy=elong;
00123       ahit.et=ahit.energy/cosh(eta);
00124       protoseeds.push_back(ahit);
00125     }
00126   }
00127 
00128   if(!protoseeds.empty()){   
00129     std::sort(protoseeds.begin(), protoseeds.end(), CompareHFCompleteHitET());
00130     for (i=protoseeds.begin(); i!= protoseeds.end(); i++)  {
00131       isok=true;
00132       doCluster=false;
00133 
00134       if ( (i==protoseeds.begin()) && (isok) ) {
00135         doCluster=true;
00136       }else {
00137         // check for overlap with existing clusters 
00138         for (k=seeds.begin(); isok && k!=seeds.end(); k++) { //i->hits, k->seeds
00139           
00140           for (dE=-2; dE<=2; dE++)
00141             for (dP=-4;dP<=4; dP+=2) {
00142               PWrap=k->id.iphi()+dP;    
00143               if (PWrap<0) 
00144                 PWrap+=72;
00145               if (PWrap>72)
00146                 PWrap-=72;
00147               
00148               if ( (i->id.iphi()==PWrap) && (i->id.ieta()==k->id.ieta()+dE))
00149                 isok = false;
00150             }
00151         }
00152         if (isok) {
00153           doCluster=true;
00154         }
00155       }
00156       if (doCluster) { 
00157         seeds.push_back(*i);
00158 
00159         bool clusterOk=makeCluster( i->id(),hf, geom,clusShp,Sclus);
00160         if (clusterOk) { // cluster is _not_ ok if seed is rejected due to other cuts
00161           clusterShapes.push_back(clusShp);
00162           SuperClusters.push_back(Sclus);
00163         }
00164 
00165       }
00166     }//end protoseed loop
00167   }//end if seeCount
00168 }
00169 
00170 
00171 bool HFClusterAlgo::makeCluster(const HcalDetId& seedid,
00172                                 const HFRecHitCollection& hf, 
00173                                 const CaloGeometry& geom,
00174                                 HFEMClusterShape& clusShp,
00175                                 SuperCluster& Sclus)  {
00176                         
00177 
00178   double w=0;//sum over all log E's
00179   double wgt=0;
00180   double w_e=0;//sum over ieat*energy
00181   double w_x=0;
00182   double w_y=0;
00183   double w_z=0;
00184   double wp_e=0;//sum over iphi*energy
00185   double e_e=0;//nonwieghted eta sum
00186   double e_ep=0; //nonweighted phi sum
00187  
00188   double l_3=0;//sum for enenergy in 3x3 long fibers etc.
00189   double s_3=0;
00190   double l_5=0;
00191   double s_5=0;
00192   double l_1=0;
00193   double s_1=0;
00194   int de, dp, phiWrap;
00195   double l_1e=0;
00196   GlobalPoint sp=geom.getPosition(seedid);
00197   std::vector<double> coreCanid;
00198   std::vector<double>::const_iterator ci;
00199   HFRecHitCollection::const_iterator i,is,il;
00200   std::vector<DetId> usedHits; 
00201  
00202   HFRecHitCollection::const_iterator si;
00203   HcalDetId sid(HcalForward,seedid.ieta(),seedid.iphi(),1);
00204   si=hf.find(sid);  
00205 
00206   bool clusterOk=true; // assume the best to start...
00207 
00208   // lots happens here
00209   // edge type 1 has 40/41 in 3x3 and 5x5
00210   bool edge_type1=seedid.ietaAbs()==39 && (seedid.iphi()%4)==3;
00211 
00212   double e_seed=si->energy()*m_correctionByEta[indexByEta(si->id())];
00213   
00214   for (de=-2; de<=2; de++)
00215     for (dp=-4;dp<=4; dp+=2) {
00216       phiWrap=seedid.iphi()+dp; 
00217       if (phiWrap<0) 
00218         phiWrap+=72;
00219       if (phiWrap>72)
00220         phiWrap-=72;
00221 
00222   
00223         /* Handling of phi-width change problems */
00224         if (edge_type1 && de==seedid.zside()) {
00225           if (dp==-2) { // we want it in the 3x3
00226             phiWrap-=2;
00227             if (phiWrap<0) 
00228               phiWrap+=72;
00229           } 
00230           else if (dp==-4) {
00231             continue; // but not double counted in 5x5
00232           }
00233         }
00234 
00235         HcalDetId idl(HcalForward,seedid.ieta()+de,phiWrap,1);
00236         HcalDetId ids(HcalForward,seedid.ieta()+de,phiWrap,2);
00237 
00238         
00239         il=hf.find(idl);
00240         is=hf.find(ids);        
00241 
00242 
00243 
00244 
00245         double e_long=1.0; 
00246         double e_short=0.0; 
00247         if (il!=hf.end()) e_long=il->energy()*m_correctionByEta[indexByEta(il->id())];
00248         if (e_long <= m_minTowerEnergy) e_long=0.0;
00249         if (is!=hf.end()) e_short=is->energy()*m_correctionByEta[indexByEta(is->id())];
00250         if (e_short <= m_minTowerEnergy) e_short=0.0;
00251         double eRatio=(e_long-e_short)/std::max(1.0,(e_long+e_short));
00252         
00253         // require S/L > a minimum amount for inclusion
00254         if ((abs(eRatio) > m_maximumSL)&&(std::max(e_long,e_short) > m_maximumRenergy)) {
00255           if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
00256           continue;
00257         }
00258          
00259         if((il!=hf.end())&&(isPMTHit(*il))){
00260           if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
00261           continue;//continue to next hit, do not include this one in cluster
00262         }
00263         
00264 
00265          /*
00266 
00267          old pmt code
00268          // cut on "PMT HIT" flag
00269          if ((il!=hf.end())&&(il->flagField(4,1))&&(m_usePMTFlag)) {//HFPET flag for lone/short doil->flagField(0,1)
00270          if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
00271          continue;//continue to next hit, do not include this one in cluster
00272          }
00273          
00274          // cut on "Pulse shape HIT" flag
00275          if ((il!=hf.end())&&(il->flagField(1,1))&&(m_usePulseFlag)) {//HF DIGI TIME flag
00276          if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
00277          continue;//continue to next hit, do not include this one in cluster
00278          }
00279          */
00280  
00281 
00282 
00283 
00284         if (e_long > m_minTowerEnergy && il!=hf.end()) {
00285 
00286           // record usage
00287           usedHits.push_back(idl.rawId());
00288           // always in the 5x5
00289           l_5+=e_long;
00290           // maybe in the 3x3
00291           if ((de>-2)&&(de<2)&&(dp>-4)&&(dp<4)) {
00292             l_3+=e_long;
00293           }
00294           // sometimes in the 1x1
00295           if ((dp==0)&&(de==0)) {
00296             l_1=e_long;
00297           }
00298 
00299           // maybe in the core?
00300           if ((de>-2)&&(de<2)&&(dp>-4)&&(dp<4)&&(e_long>(.5*e_seed))) {
00301             coreCanid.push_back(e_long);
00302           }
00303           
00304           // position calculation
00305           GlobalPoint p=geom.getPosition(idl);
00306           
00307           double d_p = p.phi()-sp.phi();
00308           while (d_p < -M_PI)
00309             d_p+=2*M_PI;
00310           while (d_p > M_PI)
00311             d_p-=2*M_PI;
00312           double d_e = p.eta()-sp.eta();
00313           
00314           wgt=log((e_long));
00315           if (wgt>0){
00316             w+=wgt;
00317             w_e+=(d_e)*wgt;
00318             wp_e+=(d_p)*wgt;
00319             e_e+=d_e;
00320             e_ep+=d_p;
00321            
00322             w_x+=(p.x())*wgt;//(p.x()-sp.x())*wgt;
00323             w_y+=(p.y())*wgt;
00324               w_z+=(p.z())*wgt;
00325           }
00326         } else {
00327           if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
00328         }
00329         
00330         if (e_short > m_minTowerEnergy && is!=hf.end()) {
00331           // record usage
00332           usedHits.push_back(ids.rawId());
00333           // always in the 5x5
00334           s_5+=e_short;
00335           // maybe in the 3x3
00336           if ((de>-2)&&(de<2)&&(dp>-4)&&(dp<4)) {
00337             s_3+=e_short;
00338           }
00339           // sometimes in the 1x1
00340           if ((dp==0)&&(de==0)) {
00341             s_1=e_short;
00342           }
00343         }
00344     }
00345 
00346 
00347   if (!clusterOk) return false;
00348 
00349   //Core sorting done here
00350   std::sort(coreCanid.begin(), coreCanid.end(), CompareHFCore());
00351   for (ci=coreCanid.begin();ci!=coreCanid.end();ci++){
00352     if(ci==coreCanid.begin()){
00353       l_1e=*ci;
00354     }else if (*ci>.5*l_1e){
00355       l_1e+=*ci;
00356     }
00357   }//core sorting end 
00358   
00359   double z_=w_z/w;    
00360   double x_=w_x/w;
00361   double y_=w_y/w;
00362   
00363   //calcualte position, final
00364   double eta=w_e/w+sp.eta();
00365   
00366   double phi=(wp_e/w)+sp.phi();
00367   
00368   while (phi < -M_PI)
00369     phi+=2*M_PI;
00370   while (phi > M_PI)
00371     phi-=2*M_PI;
00372   
00373   //calculate cell phi and cell eta
00374   static const double HFEtaBounds[14] = {2.853, 2.964, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191};
00375   double RcellEta = fabs(eta);
00376   double Cphi = (phi>0.)?(fmod((phi),0.087*2)/(0.087*2)):((fmod((phi),0.087*2)/(0.087*2))+1.0);
00377   double Rbin = -1.0;
00378   for (int icell = 0; icell < 12; icell++ ){
00379     if ( (RcellEta>HFEtaBounds[icell]) && (RcellEta<HFEtaBounds[icell+1]) )
00380       Rbin = (RcellEta - HFEtaBounds[icell])/(HFEtaBounds[icell+1] - HFEtaBounds[icell]);
00381   }
00382   double Ceta=Rbin;
00383   
00384   while (phi< -M_PI)
00385     phi+=2*M_PI;
00386   while (phi > M_PI)
00387     phi-=2*M_PI;
00388   
00389   
00390   math::XYZPoint xyzclus(x_,y_,z_);
00391   
00392   //return  HFEMClusterShape, SuperCluster
00393   HFEMClusterShape myClusShp(l_1, s_1, l_3, s_3, l_5,s_5, l_1e,Ceta, Cphi,seedid);
00394   clusShp = myClusShp;
00395       
00396   SuperCluster MySclus(l_3,xyzclus);
00397   Sclus=MySclus;
00398 
00399   return clusterOk;
00400   
00401 }
00402 bool HFClusterAlgo::isPMTHit(const HFRecHit& hfr){
00403 
00404   bool pmthit=false;
00405 
00406   if((hfr.flagField(HcalCaloFlagLabels::HFLongShort))&&(m_usePMTFlag)) pmthit=true;
00407   if (!(m_isMC && !m_forcePulseFlagMC))
00408     if((hfr.flagField(HcalCaloFlagLabels::HFDigiTime))&&(m_usePulseFlag)) pmthit=true;
00409  
00410   return pmthit;
00411 
00412 
00413 }