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