00001 #include "RecoEcal/EgammaClusterAlgos/interface/HybridClusterAlgo.h"
00002 #include "RecoCaloTools/Navigation/interface/EcalBarrelNavigator.h"
00003 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00004 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include <iostream>
00007 #include <map>
00008 #include <vector>
00009 #include <set>
00010 #include "RecoEcal/EgammaCoreTools/interface/ClusterEtLess.h"
00011 #include "RecoLocalCalo/EcalRecAlgos/interface/EcalSeverityLevelAlgo.h"
00012
00013
00014
00015 HybridClusterAlgo::HybridClusterAlgo(double eb_str,
00016 int step,
00017 double ethres,
00018 double eseed,
00019 double xi,
00020 bool useEtForXi,
00021 double ewing,
00022 std::vector<int> v_chstatus,
00023 const PositionCalc& posCalculator,
00024 bool dynamicEThres,
00025 double eThresA,
00026 double eThresB,
00027 std::vector<int> severityToExclude,
00028 bool excludeFromCluster
00029 ) :
00030
00031 eb_st(eb_str), phiSteps_(step),
00032 eThres_(ethres), eThresA_(eThresA), eThresB_(eThresB),
00033 Eseed(eseed), Xi(xi), UseEtForXi(useEtForXi), Ewing(ewing),
00034 dynamicEThres_(dynamicEThres),
00035 v_chstatus_(v_chstatus), v_severitylevel_(severityToExclude),
00036
00037
00038 excludeFromCluster_(excludeFromCluster)
00039
00040
00041 {
00042
00043 dynamicPhiRoad_ = false;
00044 LogTrace("EcalClusters") << "dynamicEThres: " << dynamicEThres_ << " : A,B " << eThresA_ << ", " << eThresB_;
00045 LogTrace("EcalClusters") << "Eseed: " << Eseed << " , Xi: " << Xi << ", UseEtForXi: " << UseEtForXi;
00046
00047
00048 posCalculator_ = posCalculator;
00049 topo_ = new EcalBarrelHardcodedTopology();
00050
00051 std::sort( v_chstatus_.begin(), v_chstatus_.end() );
00052
00053
00054 }
00055
00056
00057 void HybridClusterAlgo::makeClusters(const EcalRecHitCollection*recColl,
00058 const CaloSubdetectorGeometry*geometry,
00059 reco::BasicClusterCollection &basicClusters,
00060 const EcalSeverityLevelAlgo * sevLv,
00061 bool regional,
00062 const std::vector<EcalEtaPhiRegion>& regions
00063 )
00064 {
00065
00066 seeds.clear();
00067
00068 excludedCrys_.clear();
00069
00070 clustered_.clear();
00071
00072 useddetids.clear();
00073
00074 seedClus_.clear();
00075
00076 recHits_ = recColl;
00077
00078 LogTrace("EcalClusters") << "Cleared vectors, starting clusterization..." ;
00079 LogTrace("EcalClusters") << " Purple monkey aardvark." ;
00080
00081
00082 int nregions=0;
00083 if(regional) nregions=regions.size();
00084
00085 if(!regional || nregions) {
00086
00087 EcalRecHitCollection::const_iterator it;
00088
00089 for (it = recHits_->begin(); it != recHits_->end(); it++){
00090
00091
00092
00093 const CaloCellGeometry *this_cell = (*geometry).getGeometry(it->id());
00094 GlobalPoint position = this_cell->getPosition();
00095
00096
00097
00098
00099 bool withinRegion = false;
00100 if (regional) {
00101 std::vector<EcalEtaPhiRegion>::const_iterator region;
00102 for (region=regions.begin(); region!=regions.end(); region++) {
00103 if (region->inRegion(position)) {
00104 withinRegion = true;
00105 break;
00106 }
00107 }
00108 }
00109
00110 if (!regional || withinRegion) {
00111
00112
00113 float ET = it->energy() * sin(position.theta());
00114
00115 LogTrace("EcalClusters") << "Seed crystal: " ;
00116
00117 if (ET > eb_st) {
00118
00119 uint32_t rhFlag = (*it).recoFlag();
00120 LogTrace("EcalClusters") << "rhFlag: " << rhFlag ;
00121 ;
00122 std::vector<int>::const_iterator vit = std::find( v_chstatus_.begin(), v_chstatus_.end(), rhFlag );
00123 if ( vit != v_chstatus_.end() ){
00124 if (excludeFromCluster_)
00125 excludedCrys_.insert(it->id());
00126 continue;
00127 }
00128
00129 int severityFlag = sevLv->severityLevel( it->id(), *recHits_);
00130 std::vector<int>::const_iterator sit = std::find( v_severitylevel_.begin(), v_severitylevel_.end(), severityFlag);
00131 LogTrace("EcalClusters") << "found flag: " << severityFlag ;
00132
00133
00134 if (sit!=v_severitylevel_.end()){
00135 if (excludeFromCluster_)
00136 excludedCrys_.insert(it->id());
00137 continue;
00138 }
00139 seeds.push_back(*it);
00140
00141 LogTrace("EcalClusters") << "Seed ET: " << ET ;
00142 LogTrace("EcalClsuters") << "Seed E: " << it->energy() ;
00143 }
00144 }
00145 }
00146
00147 }
00148
00149
00150
00151 LogTrace("EcalClusters") << "Built vector of seeds, about to sort them..." ;
00152
00153
00154 sort(seeds.begin(), seeds.end(), less_mag());
00155
00156 LogTrace("EcalClusters") << "done" ;
00157
00158
00159 LogTrace("EcalClusters") << "About to call mainSearch...";
00160 mainSearch(recColl,geometry);
00161 LogTrace("EcalClusters") << "done" ;
00162
00163
00164
00165 std::map<int, reco::BasicClusterCollection>::iterator bic;
00166 for (bic= clustered_.begin();bic!=clustered_.end();bic++){
00167 reco::BasicClusterCollection bl = bic->second;
00168 for (int j=0;j<int(bl.size());++j){
00169 basicClusters.push_back(bl[j]);
00170 }
00171 }
00172
00173
00174 sort(basicClusters.rbegin(), basicClusters.rend(), ClusterEtLess() );
00175
00176 LogTrace("EcalClusters") << "returning to producer. ";
00177
00178 }
00179
00180
00181 void HybridClusterAlgo::mainSearch(const EcalRecHitCollection* hits, const CaloSubdetectorGeometry*geometry)
00182 {
00183 LogTrace("EcalClusters") << "HybridClusterAlgo Algorithm - looking for clusters" ;
00184 LogTrace("EcalClusters") << "Found the following clusters:" ;
00185
00186
00187 std::vector<EcalRecHit>::iterator it;
00188 int clustercounter=0;
00189
00190 for (it = seeds.begin(); it != seeds.end(); it++){
00191 std::vector <reco::BasicCluster> thisseedClusters;
00192 DetId itID = it->id();
00193
00194
00195 std::set<DetId>::iterator seed_in_rechits_it = useddetids.find(itID);
00196
00197 if (seed_in_rechits_it != useddetids.end()) continue;
00198
00199
00200
00201 LogTrace("EcalClusters") << "*****************************************************" << "Seed of energy E = " << it->energy() << " @ " << EBDetId(itID) << "*****************************************************" ;
00202
00203
00204
00205 EcalBarrelNavigator navigator(itID, topo_);
00206
00207
00208
00209
00210 std::vector <double> dominoEnergyPhiPlus;
00211 std::vector <std::vector <EcalRecHit> > dominoCellsPhiPlus;
00212
00213
00214 std::vector <double> dominoEnergyPhiMinus;
00215 std::vector <std::vector <EcalRecHit> > dominoCellsPhiMinus;
00216
00217
00218 std::vector <double> dominoEnergy;
00219 std::vector <std::vector <EcalRecHit> > dominoCells;
00220
00221
00222 std::vector <EcalRecHit> initialdomino;
00223 double e_init = makeDomino(navigator, initialdomino);
00224 if (e_init < Eseed) continue;
00225
00226 LogTrace("EcalClusters") << "Made initial domino" ;
00227
00228
00229
00230 double phiSteps;
00231 double et5x5 = et25(navigator, hits, geometry);
00232 if (dynamicPhiRoad_ && e_init > 0)
00233 {
00234 phiSteps = phiRoadAlgo_->barrelPhiRoad(et5x5);
00235 navigator.home();
00236 } else phiSteps = phiSteps_;
00237
00238
00239 for (int i=0;i<phiSteps;++i){
00240
00241 DetId centerD = navigator.north();
00242 if (centerD.null())
00243 continue;
00244 LogTrace("EcalClusters") << "Step ++" << i << " @ " << EBDetId(centerD) ;
00245 EcalBarrelNavigator dominoNav(centerD, topo_);
00246
00247
00248 std::vector <EcalRecHit> dcells;
00249 double etemp = makeDomino(dominoNav, dcells);
00250
00251
00252 dominoEnergyPhiPlus.push_back(etemp);
00253 dominoCellsPhiPlus.push_back(dcells);
00254 }
00255 LogTrace("EcalClusters") << "Got positive dominos" ;
00256
00257 navigator.home();
00258
00259
00260 for (int i=0;i<phiSteps;++i){
00261
00262 DetId centerD = navigator.south();
00263 if (centerD.null())
00264 continue;
00265
00266 LogTrace("EcalClusters") << "Step --" << i << " @ " << EBDetId(centerD) ;
00267 EcalBarrelNavigator dominoNav(centerD, topo_);
00268
00269
00270 std::vector <EcalRecHit> dcells;
00271 double etemp = makeDomino(dominoNav, dcells);
00272
00273
00274 dominoEnergyPhiMinus.push_back(etemp);
00275 dominoCellsPhiMinus.push_back(dcells);
00276 }
00277
00278 LogTrace("EcalClusters") << "Got negative dominos: " ;
00279
00280
00281 for (int i=int(dominoEnergyPhiMinus.size())-1;i >= 0;--i){
00282 dominoEnergy.push_back(dominoEnergyPhiMinus[i]);
00283 dominoCells.push_back(dominoCellsPhiMinus[i]);
00284 }
00285 dominoEnergy.push_back(e_init);
00286 dominoCells.push_back(initialdomino);
00287 for (int i=0;i<int(dominoEnergyPhiPlus.size());++i){
00288 dominoEnergy.push_back(dominoEnergyPhiPlus[i]);
00289 dominoCells.push_back(dominoCellsPhiPlus[i]);
00290 }
00291
00292
00293 LogTrace("EcalClusters") << "Dumping domino energies: " ;
00294
00295
00296
00297
00298
00299
00300
00301
00302 double etToE(1.);
00303 if(!UseEtForXi){
00304 etToE = 1./e2Et(navigator, hits, geometry);
00305 }
00306 std::vector <int> PeakIndex;
00307 for (int i=1;i<int(dominoEnergy.size())-1;++i){
00308 if (dominoEnergy[i] > dominoEnergy[i-1]
00309 && dominoEnergy[i] >= dominoEnergy[i+1]
00310 && dominoEnergy[i] > sqrt( Eseed*Eseed + Xi*Xi*et5x5*et5x5*etToE*etToE) )
00311 {
00312 PeakIndex.push_back(i);
00313 }
00314 }
00315
00316 LogTrace("EcalClusters") << "Found: " << PeakIndex.size() << " peaks." ;
00317
00318
00319 for (int i=0;i<int(PeakIndex.size());++i){
00320 for (int j=0;j<int(PeakIndex.size())-1;++j){
00321 if (dominoEnergy[PeakIndex[j]] < dominoEnergy[PeakIndex[j+1]]){
00322 int ihold = PeakIndex[j+1];
00323 PeakIndex[j+1] = PeakIndex[j];
00324 PeakIndex[j] = ihold;
00325 }
00326 }
00327 }
00328
00329 std::vector<int> OwnerShip;
00330 std::vector<double> LumpEnergy;
00331 for (int i=0;i<int(dominoEnergy.size());++i) OwnerShip.push_back(-1);
00332
00333
00334 double eThres = eThres_;
00335 double e5x5 = 0.0;
00336 for (int i = 0; i < int(PeakIndex.size()); ++i)
00337 {
00338
00339 int idxPeak = PeakIndex[i];
00340 OwnerShip[idxPeak] = i;
00341 double lump = dominoEnergy[idxPeak];
00342
00343
00344
00345
00346 if (dynamicEThres_) {
00347
00348
00349
00350
00351
00352 e5x5 = lump;
00353
00354 if ((idxPeak + 1) < (int)dominoEnergy.size()) e5x5 += dominoEnergy[idxPeak + 1];
00355
00356 if ((idxPeak + 2) < (int)dominoEnergy.size()) e5x5 += dominoEnergy[idxPeak + 2];
00357
00358 if ((idxPeak - 1) > 0) e5x5 += dominoEnergy[idxPeak - 1];
00359
00360 if ((idxPeak - 2) > 0) e5x5 += dominoEnergy[idxPeak - 2];
00361
00362
00363 eThres = (eThresA_ * e5x5) + eThresB_;
00364
00365
00366 }
00367
00368
00369 for (int j=idxPeak+1;j<int(dominoEnergy.size());++j){
00370 if (OwnerShip[j]==-1 &&
00371 dominoEnergy[j] > eThres
00372 && dominoEnergy[j] <= dominoEnergy[j-1]){
00373 OwnerShip[j]= i;
00374 lump+=dominoEnergy[j];
00375 }
00376 else{
00377 break;
00378 }
00379 }
00380
00381 for (int j=idxPeak-1;j>=0;--j){
00382 if (OwnerShip[j]==-1 &&
00383 dominoEnergy[j] > eThres
00384 && dominoEnergy[j] <= dominoEnergy[j+1]){
00385 OwnerShip[j]= i;
00386 lump+=dominoEnergy[j];
00387 }
00388 else{
00389 break;
00390 }
00391 }
00392 LumpEnergy.push_back(lump);
00393 }
00394
00395
00396 for (int i=0;i<int(PeakIndex.size());++i){
00397 bool HasSeedCrystal = false;
00398
00399 std::vector<EcalRecHit> recHits;
00400 std::vector< std::pair<DetId, float> > dets;
00401 int nhits=0;
00402 for (int j=0;j<int(dominoEnergy.size());++j){
00403 if (OwnerShip[j] == i){
00404 std::vector <EcalRecHit> temp = dominoCells[j];
00405 for (int k=0;k<int(temp.size());++k){
00406 dets.push_back( std::pair<DetId, float>(temp[k].id(), 1.) );
00407 if (temp[k].id()==itID)
00408 HasSeedCrystal = true;
00409 recHits.push_back(temp[k]);
00410 nhits++;
00411 }
00412 }
00413 }
00414 LogTrace("EcalClusters") << "Adding a cluster with: " << nhits;
00415 LogTrace("EcalClusters") << "total E: " << LumpEnergy[i];
00416 LogTrace("EcalClusters") << "total dets: " << dets.size() ;
00417
00418
00419 Point pos = posCalculator_.Calculate_Location(dets,hits,geometry);
00420
00421
00422
00423 std::vector<std::pair<DetId, float> > usedHits;
00424 for (int blarg=0;blarg<int(recHits.size());++blarg){
00425
00426
00427 usedHits.push_back(std::make_pair<DetId, float>(recHits[blarg].id(), 1.0));
00428 useddetids.insert(recHits[blarg].id());
00429 }
00430
00431
00432
00433
00434 if (HasSeedCrystal) {
00435
00436 seedClus_.push_back(reco::BasicCluster(LumpEnergy[i], pos,
00437 reco::CaloID(reco::CaloID::DET_ECAL_BARREL), usedHits,
00438 reco::CaloCluster::hybrid, itID));
00439
00440
00441 thisseedClusters.push_back(reco::BasicCluster(LumpEnergy[i], pos, reco::CaloID(reco::CaloID::DET_ECAL_BARREL),
00442 usedHits, reco::CaloCluster::hybrid, itID));
00443 }
00444 else {
00445
00446
00447
00448 thisseedClusters.push_back(reco::BasicCluster(LumpEnergy[i], pos, reco::CaloID(reco::CaloID::DET_ECAL_BARREL),
00449 usedHits, reco::CaloCluster::hybrid));
00450 }
00451 }
00452
00453
00454
00455
00456 if (thisseedClusters.size() > 0)
00457 {
00458 clustered_.insert(std::make_pair(clustercounter, thisseedClusters));
00459 clustercounter++;
00460 }
00461 }
00462
00463 }
00464
00465 reco::SuperClusterCollection HybridClusterAlgo::makeSuperClusters(const reco::CaloClusterPtrVector& clustersCollection)
00466 {
00467
00468 reco::SuperClusterCollection SCcoll;
00469
00470
00471 std::map<int, reco::BasicClusterCollection>::iterator mapit;
00472 for (mapit = clustered_.begin();mapit!=clustered_.end();mapit++){
00473
00474 reco::CaloClusterPtrVector thissc;
00475 reco::CaloClusterPtr seed;
00476
00477
00478 std::vector <reco::BasicCluster> thiscoll = mapit->second;
00479
00480
00481 double ClusterE = 0;
00482
00483 double posX=0;
00484 double posY=0;
00485 double posZ=0;
00486
00487
00488
00489
00490 for (int i=0;i<int(thiscoll.size());++i){
00491 reco::BasicCluster thisclus = thiscoll[i];
00492 for (int j=0;j<int(clustersCollection.size());++j){
00493
00494 reco::BasicCluster cluster_p = *clustersCollection[j];
00495 if (thisclus== cluster_p){
00496 thissc.push_back(clustersCollection[j]);
00497 bool isSeed = false;
00498 for (int qu=0;qu<int(seedClus_.size());++qu){
00499 if (cluster_p == seedClus_[qu])
00500 isSeed = true;
00501 }
00502 if (isSeed) seed = clustersCollection[j];
00503
00504 ClusterE += cluster_p.energy();
00505 posX += cluster_p.energy() * cluster_p.position().X();
00506 posY += cluster_p.energy() * cluster_p.position().Y();
00507 posZ += cluster_p.energy() * cluster_p.position().Z();
00508
00509 }
00510 }
00511 }
00512
00513 posX /= ClusterE;
00514 posY /= ClusterE;
00515 posZ /= ClusterE;
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 reco::SuperCluster suCl(ClusterE, math::XYZPoint(posX, posY, posZ), seed, thissc);
00532 SCcoll.push_back(suCl);
00533
00534 LogTrace("EcalClusters") << "Super cluster sum: " << ClusterE ;
00535 LogTrace("EcalClusters") << "Made supercluster with energy E: " << suCl.energy() ;
00536
00537 }
00538 sort(SCcoll.rbegin(), SCcoll.rend(), ClusterEtLess());
00539 return SCcoll;
00540 }
00541
00542 double HybridClusterAlgo::makeDomino(EcalBarrelNavigator &navigator, std::vector <EcalRecHit> &cells)
00543 {
00544
00545
00546
00547
00548
00549 cells.clear();
00550 double Etot = 0;
00551
00552
00553 DetId center = navigator.pos();
00554 EcalRecHitCollection::const_iterator center_it = recHits_->find(center);
00555
00556 if (center_it!=recHits_->end()){
00557 EcalRecHit SeedHit = *center_it;
00558 if (useddetids.find(center) == useddetids.end() && excludedCrys_.find(center)==excludedCrys_.end()){
00559 Etot += SeedHit.energy();
00560 cells.push_back(SeedHit);
00561 }
00562 }
00563
00564 DetId ieta1 = navigator.west();
00565 EcalRecHitCollection::const_iterator eta1_it = recHits_->find(ieta1);
00566 if (eta1_it !=recHits_->end()){
00567 EcalRecHit UpEta = *eta1_it;
00568 if (useddetids.find(ieta1) == useddetids.end() && excludedCrys_.find(ieta1)==excludedCrys_.end()){
00569 Etot+=UpEta.energy();
00570 cells.push_back(UpEta);
00571 }
00572 }
00573
00574
00575 navigator.home();
00576
00577
00578 DetId ieta2 = navigator.east();
00579 EcalRecHitCollection::const_iterator eta2_it = recHits_->find(ieta2);
00580 if (eta2_it !=recHits_->end()){
00581 EcalRecHit DownEta = *eta2_it;
00582 if (useddetids.find(ieta2)==useddetids.end() && excludedCrys_.find(ieta2)==excludedCrys_.end()){
00583 Etot+=DownEta.energy();
00584 cells.push_back(DownEta);
00585 }
00586 }
00587
00588
00589
00590 if (Etot < Ewing) {
00591 navigator.home();
00592 return Etot;
00593 }
00594
00595
00596
00597 if (ieta2 != DetId(0)){
00598 DetId ieta3 = navigator.east();
00599 EcalRecHitCollection::const_iterator eta3_it = recHits_->find(ieta3);
00600 if (eta3_it != recHits_->end()){
00601 EcalRecHit DownEta2 = *eta3_it;
00602 if (useddetids.find(ieta3)==useddetids.end() && excludedCrys_.find(ieta3)==excludedCrys_.end()){
00603 Etot+=DownEta2.energy();
00604 cells.push_back(DownEta2);
00605 }
00606 }
00607 }
00608
00609 navigator.home();
00610 navigator.west();
00611 if (ieta1 != DetId(0)){
00612 DetId ieta4 = navigator.west();
00613 EcalRecHitCollection::const_iterator eta4_it = recHits_->find(ieta4);
00614 if (eta4_it != recHits_->end()){
00615 EcalRecHit UpEta2 = *eta4_it;
00616 if (useddetids.find(ieta4) == useddetids.end() && excludedCrys_.find(ieta4)==excludedCrys_.end()){
00617 Etot+=UpEta2.energy();
00618 cells.push_back(UpEta2);
00619 }
00620 }
00621 }
00622 navigator.home();
00623 return Etot;
00624 }
00625
00626 double HybridClusterAlgo::et25(EcalBarrelNavigator &navigator,
00627 const EcalRecHitCollection *hits,
00628 const CaloSubdetectorGeometry *geometry)
00629 {
00630
00631 DetId thisDet;
00632 std::vector< std::pair<DetId, float> > dets;
00633 dets.clear();
00634 EcalRecHitCollection::const_iterator hit;
00635 double energySum = 0.0;
00636
00637 for (int dx = -2; dx < 3; ++dx)
00638 {
00639 for (int dy = -2; dy < 3; ++ dy)
00640 {
00641
00642 thisDet = navigator.offsetBy(dx, dy);
00643 navigator.home();
00644
00645 if (thisDet != DetId(0))
00646 {
00647 hit = recHits_->find(thisDet);
00648 if (hit != recHits_->end())
00649 {
00650 dets.push_back( std::pair<DetId, float>(thisDet, 1.) );
00651 energySum += hit->energy();
00652 }
00653 }
00654 }
00655 }
00656
00657
00658
00659 Point pos = posCalculator_.Calculate_Location(dets, hits, geometry);
00660 double et = energySum/cosh(pos.eta());
00661 return et;
00662
00663 }
00664
00665
00666 double HybridClusterAlgo::e2Et(EcalBarrelNavigator &navigator,
00667 const EcalRecHitCollection *hits,
00668 const CaloSubdetectorGeometry *geometry)
00669 {
00670
00671 DetId thisDet;
00672 std::vector< std::pair<DetId, float> > dets;
00673 dets.clear();
00674 EcalRecHitCollection::const_iterator hit;
00675
00676 for (int dx = -2; dx < 3; ++dx)
00677 {
00678 for (int dy = -2; dy < 3; ++ dy)
00679 {
00680 thisDet = navigator.offsetBy(dx, dy);
00681 navigator.home();
00682
00683 if (thisDet != DetId(0))
00684 {
00685 hit = recHits_->find(thisDet);
00686 if (hit != recHits_->end())
00687 {
00688 dets.push_back( std::pair<DetId, float>(thisDet, 1.) );
00689 }
00690 }
00691 }
00692 }
00693
00694
00695 Point pos = posCalculator_.Calculate_Location(dets, hits, geometry);
00696 return 1/cosh(pos.eta());
00697
00698 }
00699