CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoEcal/EgammaClusterAlgos/src/IslandClusterAlgo.cc

Go to the documentation of this file.
00001 #include "RecoEcal/EgammaClusterAlgos/interface/IslandClusterAlgo.h"
00002 
00003 // Geometry
00004 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00005 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00006 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00007 #include "Geometry/CaloTopology/interface/EcalEndcapTopology.h"
00008 #include "Geometry/CaloTopology/interface/EcalBarrelTopology.h"
00009 
00010 #include "RecoEcal/EgammaCoreTools/interface/PositionCalc.h"
00011 #include "RecoEcal/EgammaCoreTools/interface/ClusterEtLess.h"
00012 
00013 //
00014 #include "DataFormats/CaloRecHit/interface/CaloID.h"
00015 
00016 // Return a vector of clusters from a collection of EcalRecHits:
00017 std::vector<reco::BasicCluster> IslandClusterAlgo::makeClusters(
00018                                   const EcalRecHitCollection* hits,
00019                                   const CaloSubdetectorGeometry *geometry_p,
00020                                   const CaloSubdetectorTopology *topology_p,
00021                                   const CaloSubdetectorGeometry *geometryES_p,
00022                                   EcalPart ecalPart,
00023                                   bool regional,
00024                                   const std::vector<EcalEtaPhiRegion>& regions)
00025 {
00026   seeds.clear();
00027   used_s.clear();
00028   clusters_v.clear();
00029 
00030   recHits_ = hits;
00031 
00032   double threshold = 0;
00033   std::string ecalPart_string;
00034   if (ecalPart == endcap) 
00035     {
00036       threshold = ecalEndcapSeedThreshold;
00037       ecalPart_string = "EndCap";
00038     }
00039   if (ecalPart == barrel) 
00040     {
00041       threshold = ecalBarrelSeedThreshold;
00042       ecalPart_string = "Barrel";
00043     }
00044 
00045   if (verbosity < pINFO)
00046     {
00047       std::cout << "-------------------------------------------------------------" << std::endl;
00048       std::cout << "Island algorithm invoked for ECAL" << ecalPart_string << std::endl;
00049       std::cout << "Looking for seeds, energy threshold used = " << threshold << " GeV" <<std::endl;
00050     }
00051 
00052   int nregions=0;
00053   if(regional) nregions=regions.size();
00054 
00055   if(!regional || nregions) {
00056 
00057     EcalRecHitCollection::const_iterator it;
00058     for(it = hits->begin(); it != hits->end(); it++)
00059       {
00060         double energy = it->energy();
00061         if (energy < threshold) continue; // need to check to see if this line is useful!
00062 
00063         const CaloCellGeometry *thisCell = geometry_p->getGeometry(it->id());
00064         GlobalPoint position = thisCell->getPosition();
00065 
00066         // Require that RecHit is within clustering region in case
00067         // of regional reconstruction
00068         bool withinRegion = false;
00069         if (regional) {
00070           std::vector<EcalEtaPhiRegion>::const_iterator region;
00071           for (region=regions.begin(); region!=regions.end(); region++) {
00072             if (region->inRegion(position)) {
00073               withinRegion =  true;
00074               break;
00075             }
00076           }
00077         }
00078 
00079         if (!regional || withinRegion) {
00080           float ET = it->energy() * sin(position.theta());
00081           if (ET > threshold) seeds.push_back(*it);
00082         }
00083       }
00084     
00085   }
00086   
00087   sort(seeds.begin(), seeds.end(), EcalRecHitLess());
00088 
00089   if (verbosity < pINFO)
00090     {
00091       std::cout << "Total number of seeds found in event = " << seeds.size() << std::endl;
00092     }
00093 
00094   mainSearch(hits,geometry_p,topology_p,geometryES_p,ecalPart);
00095   sort(clusters_v.rbegin(), clusters_v.rend(), ClusterEtLess());
00096 
00097   if (verbosity < pINFO)
00098     {
00099       std::cout << "---------- end of main search. clusters have been sorted ----" << std::endl;
00100     }
00101   
00102   return clusters_v; 
00103 }
00104 
00105 
00106 void IslandClusterAlgo::mainSearch(const EcalRecHitCollection* hits,
00107                                    const CaloSubdetectorGeometry *geometry_p,
00108                                    const CaloSubdetectorTopology *topology_p,
00109                                    const CaloSubdetectorGeometry *geometryES_p,
00110                                    EcalPart ecalPart)
00111 {
00112   if (verbosity < pINFO)
00113     {
00114       std::cout << "Building clusters............" << std::endl;
00115     }
00116 
00117   // Loop over seeds:
00118   std::vector<EcalRecHit>::iterator it;
00119   for (it = seeds.begin(); it != seeds.end(); it++)
00120     {
00121       // make sure the current seed does not belong to a cluster already.
00122       if (used_s.find(it->id()) != used_s.end())
00123         {
00124           if (it == seeds.begin())
00125             {
00126               if (verbosity < pINFO)
00127                 {
00128                   std::cout << "##############################################################" << std::endl;
00129                   std::cout << "DEBUG ALERT: Highest energy seed already belongs to a cluster!" << std::endl;
00130                   std::cout << "##############################################################" << std::endl;
00131                 }
00132             }
00133           continue;
00134         }
00135 
00136       // clear the vector of hits in current cluster
00137       current_v.clear();
00138 
00139       current_v.push_back( std::pair<DetId, float>(it->id(), 1.) ); // by default hit energy fractions are set at 1.
00140       used_s.insert(it->id());
00141 
00142       // Create a navigator at the seed
00143       CaloNavigator<DetId> navigator(it->id(), topology_p);
00144 
00145       searchNorth(navigator);
00146       navigator.home();
00147       searchSouth(navigator);
00148       navigator.home();
00149       searchWest(navigator, topology_p);
00150       navigator.home();
00151       searchEast(navigator, topology_p);
00152  
00153       makeCluster(hits,geometry_p,geometryES_p);
00154    }
00155 }
00156 
00157 
00158 void IslandClusterAlgo::searchNorth(const CaloNavigator<DetId> &navigator)
00159 {
00160   DetId southern = navigator.pos();
00161 
00162   DetId northern = navigator.north();
00163   if (northern == DetId(0)) return; // This means that we went off the ECAL!
00164   // if the crystal to the north belongs to another cluster return
00165   if (used_s.find(northern) != used_s.end()) return;
00166 
00167 
00168   EcalRecHitCollection::const_iterator southern_it = recHits_->find(southern);
00169   EcalRecHitCollection::const_iterator northern_it = recHits_->find(northern);
00170 
00171   if (shouldBeAdded(northern_it, southern_it))
00172     {
00173       current_v.push_back( std::pair<DetId, float>(northern, 1.)); // by default hit energy fractions are set at 1.
00174       used_s.insert(northern);
00175       searchNorth(navigator);
00176     }
00177 }
00178 
00179 
00180 void IslandClusterAlgo::searchSouth(const CaloNavigator<DetId> &navigator)
00181 {
00182   DetId northern = navigator.pos();
00183 
00184   DetId southern = navigator.south();
00185   if (southern == DetId(0)) return; // This means that we went off the ECAL!
00186   if (used_s.find(southern) != used_s.end()) return;
00187 
00188 
00189   EcalRecHitCollection::const_iterator northern_it = recHits_->find(northern);
00190   EcalRecHitCollection::const_iterator southern_it = recHits_->find(southern);
00191 
00192   if (shouldBeAdded(southern_it, northern_it))
00193     {
00194       current_v.push_back( std::pair<DetId, float>(southern, 1.)); // by default hit energy fractions are set at 1.
00195       used_s.insert(southern);
00196       searchSouth(navigator);
00197     }
00198 }
00199 
00200 
00201 void IslandClusterAlgo::searchWest(const CaloNavigator<DetId> &navigator, const CaloSubdetectorTopology* topology)
00202 {
00203   DetId eastern = navigator.pos();
00204   EcalRecHitCollection::const_iterator eastern_it = recHits_->find(eastern);
00205 
00206   DetId western = navigator.west();
00207   if (western == DetId(0)) return; // This means that we went off the ECAL!
00208   EcalRecHitCollection::const_iterator western_it = recHits_->find(western);
00209 
00210   if (shouldBeAdded(western_it, eastern_it))
00211     {
00212       CaloNavigator<DetId> nsNavigator(western, topology);
00213 
00214       searchNorth(nsNavigator);
00215       nsNavigator.home();
00216       searchSouth(nsNavigator);
00217       nsNavigator.home();
00218       searchWest(navigator, topology);
00219 
00220       current_v.push_back( std::pair<DetId, float>(western, 1.)); // by default hit energy fractions are set at 1.
00221       used_s.insert(western);
00222     }
00223 }
00224 
00225 
00226 void IslandClusterAlgo::searchEast(const CaloNavigator<DetId> &navigator, const CaloSubdetectorTopology* topology)
00227 {
00228   DetId western = navigator.pos();
00229   EcalRecHitCollection::const_iterator western_it = recHits_->find(western);
00230 
00231   DetId eastern = navigator.east();
00232   if (eastern == DetId(0)) return; // This means that we went off the ECAL!
00233   EcalRecHitCollection::const_iterator eastern_it = recHits_->find(eastern);
00234 
00235   if (shouldBeAdded(eastern_it, western_it))
00236     {
00237       CaloNavigator<DetId> nsNavigator(eastern, topology);
00238 
00239       searchNorth(nsNavigator);
00240       nsNavigator.home();
00241       searchSouth(nsNavigator);
00242       nsNavigator.home();
00243       searchEast(navigator, topology);
00244 
00245       current_v.push_back( std::pair<DetId, float>(eastern, 1.)); // by default hit energy fractions are set at 1.
00246       used_s.insert(eastern);
00247     }
00248 }
00249 
00250 
00251 // returns true if the candidate crystal fulfills the requirements to be added to the cluster:
00252 bool IslandClusterAlgo::shouldBeAdded(EcalRecHitCollection::const_iterator candidate_it, EcalRecHitCollection::const_iterator previous_it)
00253 {
00254   // crystal should not be included...
00255   if ( (candidate_it == recHits_->end())                 || // ...if it does not correspond to a hit
00256        (used_s.find(candidate_it->id()) != used_s.end()) || // ...if it already belongs to a cluster
00257        (candidate_it->energy() <= 0)                     || // ...if it has a negative or zero energy
00258        (candidate_it->energy() > previous_it->energy()))    // ...or if the previous crystal had lower E
00259     {
00260       return false;
00261     }
00262   return true;
00263 }
00264 
00265 
00266 void IslandClusterAlgo::makeCluster(const EcalRecHitCollection* hits,
00267                                     const CaloSubdetectorGeometry *geometry,
00268                                     const CaloSubdetectorGeometry *geometryES)
00269 {
00270   double energy = 0;
00271   reco::CaloID caloID;
00272 
00273   Point position;
00274   position = posCalculator_.Calculate_Location(current_v,hits,geometry,geometryES);
00275   
00276   std::vector< std::pair<DetId, float> >::iterator it;
00277   for (it = current_v.begin(); it != current_v.end(); it++)
00278     {
00279       EcalRecHitCollection::const_iterator itt = hits->find( (*it).first );
00280       EcalRecHit hit_p = *itt;
00281       if ( (*it).first.subdetId() == EcalBarrel ) {
00282               caloID = reco::CaloID::DET_ECAL_BARREL;
00283       } else {
00284               caloID = reco::CaloID::DET_ECAL_ENDCAP;
00285       }
00286       //      if (hit_p != 0)
00287       //        {
00288           energy += hit_p.energy();
00289       //        }
00290       //      else 
00291       //        {
00292       //          std::cout << "DEBUG ALERT: Requested rechit has gone missing from rechits map! :-S" << std::endl;
00293       //        }
00294     }
00295 
00296   if (verbosity < pINFO)
00297     { 
00298       std::cout << "******** NEW CLUSTER ********" << std::endl;
00299       std::cout << "No. of crystals = " << current_v.size() << std::endl;
00300       std::cout << "     Energy     = " << energy << std::endl;
00301       std::cout << "     Phi        = " << position.phi() << std::endl;
00302       std::cout << "     Eta        = " << position.eta() << std::endl;
00303       std::cout << "*****************************" << std::endl;
00304     }
00305   clusters_v.push_back(reco::BasicCluster(energy, position, caloID, current_v, reco::CaloCluster::island));
00306 }
00307