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