00001 #include "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 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00009
00010 using namespace std;
00011 using namespace reco;
00020 HFClusterAlgo::HFClusterAlgo()
00021 {
00022 m_isMC=true;
00023
00024 }
00025
00026 class CompareHFCompleteHitET {
00027 public:
00028 bool operator()(const HFClusterAlgo::HFCompleteHit& h1,const HFClusterAlgo::HFCompleteHit& h2) const {
00029 return h1.et>h2.et;
00030 }
00031 };
00032
00033 class CompareHFCore {
00034 public:
00035 bool operator()(const double c1,const double c2) const {
00036 return c1>c2;
00037 }
00038 };
00039
00040 static int indexByEta(HcalDetId id) {
00041 return (id.zside()>0)?(id.ietaAbs()-29+13):(41-id.ietaAbs());
00042 }
00043 static const double MCMaterialCorrections_3XX[] = { 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 m_seedmnEta.push_back(99);
00062 m_seedMXeta.push_back(-1);
00063 }
00064 for(int ii=0;ii<73;ii++){
00065 double minphi=0.0872664*(ii-1);
00066 double maxphi=0.0872664*(ii+1);
00067 while (minphi < -M_PI)
00068 minphi+=2*M_PI;
00069 while (minphi > M_PI)
00070 minphi-=2*M_PI;
00071 while (maxphi < -M_PI)
00072 maxphi+=2*M_PI;
00073 while (maxphi > M_PI)
00074 maxphi-=2*M_PI;
00075 if(ii==37)
00076 minphi=-3.1415904;
00077 m_seedmnPhi.push_back(minphi);
00078 m_seedMXphi.push_back(maxphi);
00079 }
00080
00081
00082 for (int ii=0; ii<13*2; ii++)
00083 m_correctionByEta.push_back(1.0);
00084 if (m_correctionSet==1) {
00085 for (int ii=0; ii<13*2; ii++)
00086 m_correctionByEta[ii]=MCMaterialCorrections_3XX[ii];
00087 }
00088 }
00089
00091 void HFClusterAlgo::clusterize(const HFRecHitCollection& hf,
00092 const CaloGeometry& geom,
00093 HFEMClusterShapeCollection& clusterShapes,
00094 SuperClusterCollection& SuperClusters) {
00095
00096 std::vector<HFCompleteHit> protoseeds, seeds;
00097 HFRecHitCollection::const_iterator j,j2;
00098 std::vector<HFCompleteHit>::iterator i;
00099 std::vector<HFCompleteHit>::iterator k;
00100 int dP, dE, PWrap;
00101 bool isok=true;
00102 HFEMClusterShape clusShp;
00103
00104 SuperCluster Sclus;
00105 bool doCluster=false;
00106
00107 for (j=hf.begin(); j!= hf.end(); j++) {
00108 const int aieta=j->id().ietaAbs();
00109 int iz=(aieta-29);
00110
00111 if (j->id().depth()!=1) continue;
00112 if (aieta==40 || aieta==41 || aieta==29) continue;
00113
00114
00115 if (iz<0 || iz>12) {
00116 edm::LogWarning("HFClusterAlgo") << "Strange invalid HF hit: " << j->id();
00117 continue;
00118 }
00119
00120 if (m_cutByEta[iz]<0) {
00121 double eta=geom.getPosition(j->id()).eta();
00122 m_cutByEta[iz]=m_seedThreshold*cosh(eta);
00123 const CaloCellGeometry* ccg=geom.getGeometry(j->id());
00124 const CaloCellGeometry::CornersVec& CellCorners=ccg->getCorners();
00125 for(size_t sc=0;sc<CellCorners.size();sc++){
00126 if(fabs(CellCorners[sc].z())<1200){
00127 if(fabs(CellCorners[sc].eta())<m_seedmnEta[iz])m_seedmnEta[iz]=fabs(CellCorners[sc].eta());
00128 if(fabs(CellCorners[sc].eta())>m_seedMXeta[iz])m_seedMXeta[iz]=fabs(CellCorners[sc].eta());
00129 }
00130 }
00131 }
00132 double elong=j->energy()*m_correctionByEta[indexByEta(j->id())];
00133 if (elong>m_cutByEta[iz]) {
00134 j2=hf.find(HcalDetId(HcalForward,j->id().ieta(),j->id().iphi(),2));
00135 double eshort=(j2==hf.end())?(0):(j2->energy());
00136 if (j2!=hf.end())
00137 eshort*=m_correctionByEta[indexByEta(j2->id())];
00138 if (((elong-eshort)/(elong+eshort))>m_maximumSL) continue;
00139
00140
00141 if(isPMTHit(*j)) continue;
00142
00143 HFCompleteHit ahit;
00144 double eta=geom.getPosition(j->id()).eta();
00145 ahit.id=j->id();
00146 ahit.energy=elong;
00147 ahit.et=ahit.energy/cosh(eta);
00148 protoseeds.push_back(ahit);
00149 }
00150 }
00151
00152 if(!protoseeds.empty()){
00153 std::sort(protoseeds.begin(), protoseeds.end(), CompareHFCompleteHitET());
00154 for (i=protoseeds.begin(); i!= protoseeds.end(); i++) {
00155 isok=true;
00156 doCluster=false;
00157
00158 if ( (i==protoseeds.begin()) && (isok) ) {
00159 doCluster=true;
00160 }else {
00161
00162 for (k=seeds.begin(); isok && k!=seeds.end(); k++) {
00163
00164 for (dE=-2; dE<=2; dE++)
00165 for (dP=-4;dP<=4; dP+=2) {
00166 PWrap=k->id.iphi()+dP;
00167 if (PWrap<0)
00168 PWrap+=72;
00169 if (PWrap>72)
00170 PWrap-=72;
00171
00172 if ( (i->id.iphi()==PWrap) && (i->id.ieta()==k->id.ieta()+dE))
00173 isok = false;
00174 }
00175 }
00176 if (isok) {
00177 doCluster=true;
00178 }
00179 }
00180 if (doCluster) {
00181 seeds.push_back(*i);
00182
00183 bool clusterOk=makeCluster( i->id(),hf, geom,clusShp,Sclus);
00184 if (clusterOk) {
00185 clusterShapes.push_back(clusShp);
00186 SuperClusters.push_back(Sclus);
00187 }
00188
00189 }
00190 }
00191 }
00192 }
00193
00194
00195 bool HFClusterAlgo::makeCluster(const HcalDetId& seedid,
00196 const HFRecHitCollection& hf,
00197 const CaloGeometry& geom,
00198 HFEMClusterShape& clusShp,
00199 SuperCluster& Sclus) {
00200
00201
00202 double w=0;
00203 double wgt=0;
00204 double w_e=0;
00205 double w_x=0;
00206 double w_y=0;
00207 double w_z=0;
00208 double wp_e=0;
00209 double e_e=0;
00210 double e_ep=0;
00211
00212 double l_3=0;
00213 double s_3=0;
00214 double l_5=0;
00215 double s_5=0;
00216 double l_1=0;
00217 double s_1=0;
00218 int de, dp, phiWrap;
00219 double l_1e=0;
00220 GlobalPoint sp=geom.getPosition(seedid);
00221 std::vector<double> coreCanid;
00222 std::vector<double>::const_iterator ci;
00223 HFRecHitCollection::const_iterator i,is,il;
00224 std::vector<DetId> usedHits;
00225
00226 HFRecHitCollection::const_iterator si;
00227 HcalDetId sid(HcalForward,seedid.ieta(),seedid.iphi(),1);
00228 si=hf.find(sid);
00229
00230 bool clusterOk=true;
00231
00232
00233
00234 bool edge_type1=seedid.ietaAbs()==39 && (seedid.iphi()%4)==3;
00235
00236 double e_seed=si->energy()*m_correctionByEta[indexByEta(si->id())];
00237
00238 for (de=-2; de<=2; de++)
00239 for (dp=-4;dp<=4; dp+=2) {
00240 phiWrap=seedid.iphi()+dp;
00241 if (phiWrap<0)
00242 phiWrap+=72;
00243 if (phiWrap>72)
00244 phiWrap-=72;
00245
00246
00247
00248 if (edge_type1 && de==seedid.zside()) {
00249 if (dp==-2) {
00250 phiWrap-=2;
00251 if (phiWrap<0)
00252 phiWrap+=72;
00253 }
00254 else if (dp==-4) {
00255 continue;
00256 }
00257 }
00258
00259 HcalDetId idl(HcalForward,seedid.ieta()+de,phiWrap,1);
00260 HcalDetId ids(HcalForward,seedid.ieta()+de,phiWrap,2);
00261
00262
00263 il=hf.find(idl);
00264 is=hf.find(ids);
00265
00266
00267
00268
00269 double e_long=1.0;
00270 double e_short=0.0;
00271 if (il!=hf.end()) e_long=il->energy()*m_correctionByEta[indexByEta(il->id())];
00272 if (e_long <= m_minTowerEnergy) e_long=0.0;
00273 if (is!=hf.end()) e_short=is->energy()*m_correctionByEta[indexByEta(is->id())];
00274 if (e_short <= m_minTowerEnergy) e_short=0.0;
00275 double eRatio=(e_long-e_short)/std::max(1.0,(e_long+e_short));
00276
00277
00278 if ((abs(eRatio) > m_maximumSL)&&(std::max(e_long,e_short) > m_maximumRenergy)) {
00279 if (dp==0 && de==0) clusterOk=false;
00280 continue;
00281 }
00282
00283 if((il!=hf.end())&&(isPMTHit(*il))){
00284 if (dp==0 && de==0) clusterOk=false;
00285 continue;
00286 }
00287
00288
00289
00290
00291
00292 if (e_long > m_minTowerEnergy && il!=hf.end()) {
00293
00294
00295 usedHits.push_back(idl.rawId());
00296
00297 l_5+=e_long;
00298
00299 if ((de>-2)&&(de<2)&&(dp>-4)&&(dp<4)) {
00300 l_3+=e_long;
00301
00302
00303 if ((dp==0)&&(de==0)) {
00304 l_1=e_long;
00305 }
00306
00307
00308 if ((de>-2)&&(de<2)&&(dp>-4)&&(dp<4)&&(e_long>(.5*e_seed))) {
00309 coreCanid.push_back(e_long);
00310 }
00311
00312
00313 GlobalPoint p=geom.getPosition(idl);
00314
00315 double d_p = p.phi()-sp.phi();
00316 while (d_p < -M_PI)
00317 d_p+=2*M_PI;
00318 while (d_p > M_PI)
00319 d_p-=2*M_PI;
00320 double d_e = p.eta()-sp.eta();
00321
00322 wgt=log((e_long));
00323 if (wgt>0){
00324 w+=wgt;
00325 w_e+=(d_e)*wgt;
00326 wp_e+=(d_p)*wgt;
00327 e_e+=d_e;
00328 e_ep+=d_p;
00329
00330 w_x+=(p.x())*wgt;
00331 w_y+=(p.y())*wgt;
00332 w_z+=(p.z())*wgt;
00333 }
00334 }
00335 } else {
00336 if (dp==0 && de==0) clusterOk=false;
00337 }
00338
00339 if (e_short > m_minTowerEnergy && is!=hf.end()) {
00340
00341 usedHits.push_back(ids.rawId());
00342
00343 s_5+=e_short;
00344
00345 if ((de>-2)&&(de<2)&&(dp>-4)&&(dp<4)) {
00346 s_3+=e_short;
00347 }
00348
00349 if ((dp==0)&&(de==0)) {
00350 s_1=e_short;
00351 }
00352 }
00353 }
00354
00355
00356 if (!clusterOk) return false;
00357
00358
00359 std::sort(coreCanid.begin(), coreCanid.end(), CompareHFCore());
00360 for (ci=coreCanid.begin();ci!=coreCanid.end();ci++){
00361 if(ci==coreCanid.begin()){
00362 l_1e=*ci;
00363 }else if (*ci>.5*l_1e){
00364 l_1e+=*ci;
00365 }
00366 }
00367
00368 double z_=w_z/w;
00369 double x_=w_x/w;
00370 double y_=w_y/w;
00371 math::XYZPoint xyzclus(x_,y_,z_);
00372
00373 double eta=xyzclus.eta();
00374
00375 double phi=xyzclus.phi();
00376
00377 while (phi < -M_PI)
00378 phi+=2*M_PI;
00379 while (phi > M_PI)
00380 phi-=2*M_PI;
00381
00382
00383 int idx= fabs(seedid.ieta())-29;
00384 int ipx=seedid.iphi();
00385 double Cphi =(phi-m_seedmnPhi[ipx])/(m_seedMXphi[ipx]-m_seedmnPhi[ipx]);
00386 double Ceta=(fabs(eta)- m_seedmnEta[idx])/(m_seedMXeta[idx]-m_seedmnEta[idx]);
00387
00388
00389 HFEMClusterShape myClusShp(l_1, s_1, l_3, s_3, l_5,s_5, l_1e,Ceta, Cphi,seedid);
00390 clusShp = myClusShp;
00391
00392 SuperCluster MySclus(l_3,xyzclus);
00393 Sclus=MySclus;
00394
00395 return clusterOk;
00396
00397 }
00398 bool HFClusterAlgo::isPMTHit(const HFRecHit& hfr){
00399
00400 bool pmthit=false;
00401
00402 if((hfr.flagField(HcalCaloFlagLabels::HFLongShort))&&(m_usePMTFlag)) pmthit=true;
00403 if (!(m_isMC && !m_forcePulseFlagMC))
00404 if((hfr.flagField(HcalCaloFlagLabels::HFDigiTime))&&(m_usePulseFlag)) pmthit=true;
00405
00406 return pmthit;
00407 }
00408 void HFClusterAlgo::resetForRun() {
00409 edm::LogInfo("HFClusterAlgo")<<"Resetting for Run!";
00410 for(int ii=0;ii<13;ii++){
00411 m_cutByEta.push_back(-1);
00412 m_seedmnEta.push_back(99);
00413 m_seedMXeta.push_back(-1);
00414 }
00415 }
00416