00001
00002 #include "RecoEcal/EgammaClusterAlgos/interface/Multi5x5ClusterAlgo.h"
00003
00004
00005 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00006 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00007 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00008 #include "Geometry/CaloTopology/interface/EcalEndcapTopology.h"
00009 #include "Geometry/CaloTopology/interface/EcalBarrelTopology.h"
00010 #include "RecoEcal/EgammaCoreTools/interface/ClusterEtLess.h"
00011
00012 #include "DataFormats/CaloRecHit/interface/CaloID.h"
00013
00014
00015
00016 std::vector<reco::BasicCluster> Multi5x5ClusterAlgo::makeClusters(
00017 const EcalRecHitCollection* hits,
00018 const CaloSubdetectorGeometry *geometry_p,
00019 const CaloSubdetectorTopology *topology_p,
00020 const CaloSubdetectorGeometry *geometryES_p,
00021 reco::CaloID::Detectors detector,
00022 bool regional,
00023 const std::vector<EcalEtaPhiRegion>& regions
00024 )
00025 {
00026 seeds.clear();
00027 used_s.clear();
00028 canSeed_s.clear();
00029 clusters_v.clear();
00030
00031 recHits_ = hits;
00032
00033 double threshold = 0;
00034 std::string ecalPart_string;
00035 detector_ = reco::CaloID::DET_NONE;
00036 if (detector == reco::CaloID::DET_ECAL_ENDCAP)
00037 {
00038 detector_ = reco::CaloID::DET_ECAL_ENDCAP;
00039 threshold = ecalEndcapSeedThreshold;
00040 ecalPart_string = "EndCap";
00041 }
00042 if (detector == reco::CaloID::DET_ECAL_BARREL)
00043 {
00044 detector_ = reco::CaloID::DET_ECAL_BARREL;
00045 threshold = ecalBarrelSeedThreshold;
00046 ecalPart_string = "Barrel";
00047 }
00048
00049 if (verbosity < pINFO)
00050 {
00051 std::cout << "-------------------------------------------------------------" << std::endl;
00052 std::cout << "Island algorithm invoked for ECAL" << ecalPart_string << std::endl;
00053 std::cout << "Looking for seeds, energy threshold used = " << threshold << " GeV" <<std::endl;
00054 }
00055
00056 int nregions=0;
00057 if(regional) nregions=regions.size();
00058
00059 if(!regional || nregions) {
00060
00061 EcalRecHitCollection::const_iterator it;
00062 for(it = hits->begin(); it != hits->end(); it++)
00063 {
00064 double energy = it->energy();
00065 if (energy < threshold) continue;
00066
00067 const CaloCellGeometry *thisCell = geometry_p->getGeometry(it->id());
00068 GlobalPoint position = thisCell->getPosition();
00069
00070
00071
00072 bool withinRegion = false;
00073 if (regional) {
00074 std::vector<EcalEtaPhiRegion>::const_iterator region;
00075 for (region=regions.begin(); region!=regions.end(); region++) {
00076 if (region->inRegion(position)) {
00077 withinRegion = true;
00078 break;
00079 }
00080 }
00081 }
00082
00083 if (!regional || withinRegion) {
00084 float ET = it->energy() * sin(position.theta());
00085 if (ET > threshold) seeds.push_back(*it);
00086 }
00087 }
00088
00089 }
00090
00091 sort(seeds.begin(), seeds.end(), EcalRecHitLess());
00092
00093 if (verbosity < pINFO)
00094 {
00095 std::cout << "Total number of seeds found in event = " << seeds.size() << std::endl;
00096 }
00097
00098 mainSearch(hits, geometry_p, topology_p, geometryES_p);
00099 sort(clusters_v.rbegin(), clusters_v.rend(), ClusterEtLess());
00100
00101 if (verbosity < pINFO)
00102 {
00103 std::cout << "---------- end of main search. clusters have been sorted ----" << std::endl;
00104 }
00105
00106 return clusters_v;
00107
00108 }
00109
00110
00111
00112 void Multi5x5ClusterAlgo::mainSearch(const EcalRecHitCollection* hits,
00113 const CaloSubdetectorGeometry *geometry_p,
00114 const CaloSubdetectorTopology *topology_p,
00115 const CaloSubdetectorGeometry *geometryES_p
00116 )
00117 {
00118
00119 if (verbosity < pINFO)
00120 {
00121 std::cout << "Building clusters............" << std::endl;
00122 }
00123
00124
00125 std::vector<EcalRecHit>::iterator it;
00126 for (it = seeds.begin(); it != seeds.end(); it++)
00127 {
00128
00129
00130
00131 bool usedButCanSeed = false;
00132 if (canSeed_s.find(it->id()) != canSeed_s.end()) usedButCanSeed = true;
00133
00134
00135 uint32_t rhFlag = (*it).recoFlag();
00136 std::vector<int>::const_iterator vit = std::find( v_chstatus_.begin(), v_chstatus_.end(), rhFlag );
00137 if ( vit != v_chstatus_.end() ) continue;
00138
00139
00140 if ((used_s.find(it->id()) != used_s.end()) && (usedButCanSeed == false))
00141 {
00142 if (it == seeds.begin())
00143 {
00144 if (verbosity < pINFO)
00145 {
00146 std::cout << "##############################################################" << std::endl;
00147 std::cout << "DEBUG ALERT: Highest energy seed already belongs to a cluster!" << std::endl;
00148 std::cout << "##############################################################" << std::endl;
00149 }
00150 }
00151
00152
00153
00154 continue;
00155 }
00156
00157
00158 current_v.clear();
00159
00160
00161
00162 CaloNavigator<DetId> navigator(it->id(), topology_p);
00163 DetId seedId = navigator.pos();
00164 EcalRecHitCollection::const_iterator seedIt = hits->find(seedId);
00165 navigator.setHome(seedId);
00166
00167
00168 bool localMaxima = checkMaxima(navigator, hits);
00169
00170 if (localMaxima)
00171 {
00172
00173
00174 prepareCluster(navigator, hits, geometry_p);
00175 }
00176
00177
00178
00179 if (current_v.size() > 0)
00180 {
00181 makeCluster(hits, geometry_p, geometryES_p, seedIt);
00182 }
00183
00184 }
00185
00186 }
00187
00188 void Multi5x5ClusterAlgo::makeCluster(const EcalRecHitCollection* hits,
00189 const CaloSubdetectorGeometry *geometry,
00190 const CaloSubdetectorGeometry *geometryES,
00191 const EcalRecHitCollection::const_iterator &seedIt)
00192 {
00193
00194 double energy = 0;
00195
00196 reco::CaloID caloID;
00197 Point position;
00198 position = posCalculator_.Calculate_Location(current_v, hits,geometry, geometryES);
00199
00200 std::vector<std::pair<DetId, float> >::iterator it;
00201 for (it = current_v.begin(); it != current_v.end(); it++)
00202 {
00203 EcalRecHitCollection::const_iterator itt = hits->find( (*it).first );
00204 EcalRecHit hit_p = *itt;
00205 energy += hit_p.energy();
00206
00207 if ( (*it).first.subdetId() == EcalBarrel ) {
00208 caloID = reco::CaloID::DET_ECAL_BARREL;
00209 } else {
00210 caloID = reco::CaloID::DET_ECAL_ENDCAP;
00211 }
00212
00213 }
00214
00215
00216 if (verbosity < pINFO)
00217 {
00218 std::cout << "******** NEW CLUSTER ********" << std::endl;
00219 std::cout << "No. of crystals = " << current_v.size() << std::endl;
00220 std::cout << " Energy = " << energy << std::endl;
00221 std::cout << " Phi = " << position.phi() << std::endl;
00222 std::cout << " Eta = " << position.eta() << std::endl;
00223 std::cout << "*****************************" << std::endl;
00224 }
00225
00226
00227
00228 double seedEnergy = seedIt->energy();
00229 if (energy >= seedEnergy)
00230 {
00231
00232 clusters_v.push_back(reco::BasicCluster(energy, position, reco::CaloID(detector_), current_v, reco::CaloCluster::multi5x5, seedIt->id()));
00233 }
00234
00235 }
00236
00237 bool Multi5x5ClusterAlgo::checkMaxima(CaloNavigator<DetId> &navigator,
00238 const EcalRecHitCollection *hits)
00239 {
00240
00241 bool maxima = true;
00242 EcalRecHitCollection::const_iterator thisHit;
00243 EcalRecHitCollection::const_iterator seedHit = hits->find(navigator.pos());
00244 double seedEnergy = seedHit->energy();
00245
00246 std::vector<DetId> swissCrossVec;
00247 swissCrossVec.clear();
00248
00249 swissCrossVec.push_back(navigator.west());
00250 navigator.home();
00251 swissCrossVec.push_back(navigator.east());
00252 navigator.home();
00253 swissCrossVec.push_back(navigator.north());
00254 navigator.home();
00255 swissCrossVec.push_back(navigator.south());
00256 navigator.home();
00257
00258 std::vector<DetId>::const_iterator detItr;
00259 for (unsigned int i = 0; i < swissCrossVec.size(); ++i)
00260 {
00261
00262
00263 thisHit = recHits_->find(swissCrossVec[i]);
00264
00265
00266 if ((swissCrossVec[i] == DetId(0)) || thisHit == recHits_->end()) continue;
00267
00268
00269
00270 uint32_t rhFlag = thisHit->recoFlag();
00271 std::vector<int>::const_iterator vit = std::find(v_chstatus_.begin(), v_chstatus_.end(), rhFlag);
00272 if (vit != v_chstatus_.end()) continue;
00273
00274
00275
00276 if (thisHit->energy() > seedEnergy)
00277 {
00278 maxima = false;
00279 break;
00280 }
00281 }
00282
00283 return maxima;
00284
00285 }
00286
00287 void Multi5x5ClusterAlgo::prepareCluster(CaloNavigator<DetId> &navigator,
00288 const EcalRecHitCollection *hits,
00289 const CaloSubdetectorGeometry *geometry)
00290 {
00291
00292 DetId thisDet;
00293 std::set<DetId>::iterator setItr;
00294
00295
00296
00297
00298
00299
00300 for (int dx = -2; dx < 3; ++dx)
00301 {
00302 for (int dy = -2; dy < 3; ++ dy)
00303 {
00304
00305
00306
00307 thisDet = navigator.offsetBy(dx, dy);
00308 navigator.home();
00309
00310
00311
00312 addCrystal(thisDet);
00313
00314
00315
00316 if ((abs(dx) > 1) || (abs(dy) > 1))
00317 {
00318
00319
00320
00321 canSeed_s.insert(thisDet);
00322 }
00323 else
00324 {
00325
00326
00327 setItr = canSeed_s.find(thisDet);
00328 if (setItr != canSeed_s.end())
00329 {
00330
00331 canSeed_s.erase(setItr);
00332 }
00333 }
00334
00335
00336 }
00337
00338 }
00339
00340
00341
00342
00343 }
00344
00345
00346 void Multi5x5ClusterAlgo::addCrystal(const DetId &det)
00347 {
00348
00349 EcalRecHitCollection::const_iterator thisIt = recHits_->find(det);
00350 if ((thisIt != recHits_->end()) && (thisIt->id() != DetId(0)))
00351 {
00352 if ((used_s.find(thisIt->id()) == used_s.end()))
00353 {
00354
00355 current_v.push_back( std::pair<DetId, float>(det, 1.) );
00356 used_s.insert(det);
00357 }
00358 }
00359
00360 }
00361