CMS 3D CMS Logo

Multi5x5ClusterAlgo.cc

Go to the documentation of this file.
00001 
00002 #include "RecoEcal/EgammaClusterAlgos/interface/Multi5x5ClusterAlgo.h"
00003 
00004 // Geometry
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 // Return a vector of clusters from a collection of EcalRecHits:
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; // need to check to see if this line is useful!
00060 
00061         const CaloCellGeometry *thisCell = geometry_p->getGeometry(it->id());
00062         GlobalPoint position = thisCell->getPosition();
00063 
00064         // Require that RecHit is within clustering region in case
00065         // of regional reconstruction
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 // Search for clusters
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    // Loop over seeds:
00119    std::vector<EcalRecHit>::iterator it;
00120    for (it = seeds.begin(); it != seeds.end(); it++)
00121    {
00122 
00123       // check if this crystal is able to seed
00124       // (event though it is already used)
00125       bool usedButCanSeed = false;
00126       if (canSeed_s.find(it->id()) != canSeed_s.end()) usedButCanSeed = true;
00127 
00128       // make sure the current seed does not belong to a cluster already.
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           // seed crystal is used or is used and cannot seed a cluster
00142           // so continue to the next seed crystal...
00143           continue;
00144       }
00145 
00146       // clear the vector of hits in current cluster
00147       current_v.clear();
00148 
00149       // Create a navigator at the seed and get seed
00150       // energy
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       // Is the seed a local maximum?
00158       bool localMaxima = checkMaxima(navigator, hits);
00159 
00160       if (localMaxima)
00161       {
00162          // build the 5x5 taking care over which crystals
00163          // can seed new clusters and which can't
00164          prepareCluster(navigator, hits, geometry_p);
00165       }
00166 
00167       // If some crystals in the current vector then 
00168       // make them into a cluster 
00169       if (current_v.size() > 0) 
00170       {
00171          makeCluster(hits, geometry_p, geometryES_p, seedEnergy);
00172       }
00173 
00174    }  // End loop on seed crystals
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    // to be a valid cluster the cluster energy
00210    // must be at least the seed energy
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    // now add the 5x5 taking care to mark the edges
00266    // as able to seed and where overlapping in the central
00267    // region with crystals that were previously able to seed
00268    // change their status so they are not able to seed
00269    //std::cout << std::endl;
00270    for (int dx = -2; dx < 3; ++dx)
00271    {
00272       for (int dy = -2; dy < 3; ++ dy)
00273       {
00274 
00275           // navigate in free steps forming
00276           // a full 5x5
00277           thisDet = navigator.offsetBy(dx, dy);
00278           navigator.home();
00279 
00280           // add the current crystal
00281           //std::cout << "adding " << dx << ", " << dy << std::endl;
00282           addCrystal(thisDet);
00283 
00284           // now consider if we are in an edge (outer 16)
00285           // or central (inner 9) region
00286           if ((abs(dx) > 1) || (abs(dy) > 1))
00287           {    
00288              // this is an "edge" so should be allowed to seed
00289              // provided it is not already used
00290              //std::cout << "   setting can seed" << std::endl;
00291              canSeed_s.insert(thisDet);
00292           }  // end if "edge"
00293           else 
00294           {
00295              // or else we are in the central 3x3
00296              // and must remove any of these crystals from the canSeed set
00297              setItr = canSeed_s.find(thisDet);
00298              if (setItr != canSeed_s.end())
00299              {
00300                 //std::cout << "   unsetting can seed" << std::endl;
00301                 canSeed_s.erase(setItr);
00302              }
00303           }  // end if "centre"
00304 
00305 
00306       } // end loop on dy
00307 
00308    } // end loop on dx
00309 
00310    //std::cout << "*** " << std::endl;
00311    //std::cout << " current_v contains " << current_v.size() << std::endl;
00312    //std::cout << "*** " << std::endl;
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          //std::cout << "   ... this is a good crystal and will be added" << std::endl;
00325          current_v.push_back(det);
00326          used_s.insert(det);
00327       }
00328    } 
00329   
00330 }
00331 

Generated on Tue Jun 9 17:43:12 2009 for CMSSW by  doxygen 1.5.4