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