CMS 3D CMS Logo

CosmicClusterAlgo.cc

Go to the documentation of this file.
00001 
00002 #include "RecoEcal/EgammaClusterAlgos/interface/CosmicClusterAlgo.h"
00003 
00004 #include <vector> //TEMP JHAUPT 4-27
00005 
00006 // Geometry
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 // Return a vector of clusters from a collection of EcalRecHits:
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         // Require that RecHit is within clustering region in case
00096         // of regional reconstruction
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           //float ET = it->energy() * sin(position.theta()); JHaupt Out 4-27-08 Et not needed for Cosmic Events...
00110          // if (energy >= threshold) 
00111           seeds.push_back(*it); // JHaupt 4-27-2008 Et -> energy, most likely not needed as there is already a threshold requirement.
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               //std::cout << "JH Seed Energy " << ji->energy() << " hashed " << ((EBDetId)ji->id()).hashedIndex()  << std::endl;
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 // Search for clusters
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   // Loop over seeds:
00155    std::vector<EcalRecHit>::iterator it;
00156    for (it = seeds.begin(); it != seeds.end(); it++)
00157    {
00158 
00159       // check if this crystal is able to seed
00160       // (event though it is already used)
00161       bool usedButCanSeed = false;
00162       if (canSeed_s.find(it->id()) != canSeed_s.end()) usedButCanSeed = true;
00163 
00164       // make sure the current seed does not belong to a cluster already.
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           // seed crystal is used or is used and cannot seed a cluster
00178           // so continue to the next seed crystal...
00179           continue;
00180       }
00181 
00182       // clear the vector of hits in current clusterconst EcalRecHitCollection* hits,
00183       current_v9.clear();
00184       current_v25.clear();
00185       current_v25Sup.clear();
00186 
00187       // Create a navigator at the seed
00188       CaloNavigator<DetId> navigator(it->id(), topology_p);
00189       DetId seedId = navigator.pos();
00190       navigator.setHome(seedId);
00191 
00192       // Is the seed a local maximum?
00193       bool localMaxima = checkMaxima(navigator);
00194 
00195       if (localMaxima)
00196       {
00197          // build the 5x5 taking care over which crystals //JHaupt 4-27-08 3x3 is a good option...
00198          // can seed new clusters and which can't
00199          prepareCluster(navigator, geometry_p);
00200       }
00201 
00202       // If some crystals in the current vector then 
00203       // make them into a cluster 
00204       if (current_v25.size() > 0) 
00205       {
00206         makeCluster(geometry_p, geometryES_p);
00207       }
00208 
00209    }  // End loop on seed crystals
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.;//JHaupt 4-27-08 Added for the second crystal stream
00220    double energyMax = 0.;//JHaupt 4-27-08 Added for the max crystal stream
00221    double chi2   = 0;
00222    DetId detFir;
00223    DetId detSec;
00224    //bool goodCluster = false; //JHaupt 4-27-08 Added so that some can be earased.. used another day Might not be needed as seeds are energy ordered... 
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    //if ((detFir.det() == DetId::Ecal) && (detFir.subdetId() == EcalEndcap)) inEB = false;
00238    //We ignore the possiblity that the cluster may span into the EE    
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(); //Keep the fully corrected 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       // specialize this
00271 //       std::cout << "JH****Emax****  "<<energyMax << " ieta " <<detFir.ieta() <<" iphi "<<detFir.ieta()  << std::endl;
00272 //       std::cout << "JH****Esec****  "<<energySecond << " ieta " <<detSec.ieta() <<" iphi "<<detSec.ieta() << std::endl;
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    // now add the 5x5 taking care to mark the edges
00324    // as able to seed and where overlapping in the central
00325    // region with crystals that were previously able to seed
00326    // change their status so they are not able to seed
00327    //std::cout << std::endl;
00328    for (int dx = -2; dx < 3; ++dx) //for (int dx = -2; dx < 3; ++dx)
00329    {
00330       for (int dy = -2; dy < 3; ++ dy) //for (int dy = -2; dy < 3; ++ dy)
00331       {
00332 
00333           // navigate in free steps forming
00334           // a full 5x5
00335           thisDet = navigator.offsetBy(dx, dy);
00336           navigator.home();
00337 
00338           // add the current crystal
00339           //std::cout << "adding " << dx << ", " << dy << std::endl;
00340          
00341 
00342 
00343           // now consider if we are in an edge (outer 16)
00344           // or central (inner 9) region
00345           if ((abs(dx) > 1) || (abs(dy) > 1))
00346           {    
00347              // this is an "edge" so should be allowed to seed
00348              // provided it is not already used
00349              //std::cout << "   setting can seed" << std::endl;
00350                          addCrystal(thisDet,false); //These are in the V25
00351              canSeed_s.insert(thisDet);
00352           }  // end if "edge"
00353           else 
00354           {
00355              // or else we are in the central 3x3
00356              // and must remove any of these crystals from the canSeed set
00357              setItr = canSeed_s.find(thisDet);
00358                          addCrystal(thisDet,true); //These are in the V9
00359              if (setItr != canSeed_s.end())
00360              {
00361                 //std::cout << "   unsetting can seed" << std::endl;
00362                 canSeed_s.erase(setItr);
00363              }
00364           }  // end if "centre"
00365 
00366 
00367       } // end loop on dy
00368 
00369    } // end loop on dx
00370 
00371    //std::cout << "*** " << std::endl;
00372    //std::cout << " current_v contains " << current_v.size() << std::endl;
00373    //std::cout << "*** " << std::endl;
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 }

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