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