CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoEcal/EgammaClusterAlgos/src/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          }
00074          continue;
00075           }
00076   
00077           // if rechit affected by features other than these, do not allow if seeding
00078           // features are hard coded, for now; add severity?
00079           uint32_t rhFlag = (*it).recoFlag();
00080           if (!(
00081                 rhFlag == EcalRecHit::kGood      ||
00082                 rhFlag == EcalRecHit::kOutOfTime ||
00083                 rhFlag == EcalRecHit::kPoorCalib
00084                 )
00085               ) continue;
00086 
00087           EcalUncalibratedRecHitCollection::const_iterator itt =  uncalibRecHits_->find(it->id());
00088           
00089           if (itt == uncalibRecHits_->end()){  
00090              if (verbosity < pINFO)
00091          {
00092             std::cout << "-------------------------------------------------------------" << std::endl;
00093             std::cout << "No Uncalibrated RecHit associated with the RecHit Probably no Uncalibrated rec hit collection available" << std::endl;
00094                  }
00095              continue;
00096           }
00097           
00098       EcalUncalibratedRecHit uhit_p = *itt;
00099 
00100       // looking for cluster seeds        
00101           if (uhit_p.amplitude() <  (inEB ? ecalBarrelSeedThreshold : ecalEndcapSeedThreshold) ) continue; // 
00102           
00103           const CaloCellGeometry *thisCell = geometry_p->getGeometry(it->id());
00104           GlobalPoint position = thisCell->getPosition();
00105 
00106         // Require that RecHit is within clustering region in case
00107         // of regional reconstruction
00108         bool withinRegion = false;
00109         if (regional) {
00110           std::vector<EcalEtaPhiRegion>::const_iterator region;
00111           for (region=regions.begin(); region!=regions.end(); region++) {
00112             if (region->inRegion(position)) {
00113               withinRegion =  true;
00114               break;
00115             }
00116           }
00117         }
00118 
00119         if (!regional || withinRegion) {
00120           //float ET = it->energy() * sin(position.theta()); JHaupt Out 4-27-08 Et not needed for Cosmic Events...
00121          // if (energy >= threshold) 
00122           seeds.push_back(*it); // JHaupt 4-27-2008 Et -> energy, most likely not needed as there is already a threshold requirement.
00123         }
00124       }
00125     
00126   }
00127   
00128    sort(seeds.begin(), seeds.end(), EcalRecHitLess());
00129 
00130    if (verbosity < pINFO)
00131    {
00132       std::cout << "JH Total number of seeds found in event = " << seeds.size() << std::endl;
00133           for (EcalRecHitCollection::const_iterator ji = seeds.begin(); ji != seeds.end(); ++ji)
00134           {
00135               //std::cout << "JH Seed Energy " << ji->energy() << " hashed " << ((EBDetId)ji->id()).hashedIndex()  << std::endl;
00136 
00137           }
00138    }
00139 
00140    mainSearch(geometry_p,topology_p,geometryES_p,ecalPart );
00141    sort(clusters_v.rbegin(), clusters_v.rend(),ClusterEtLess());
00142          
00143    if (verbosity < pINFO)
00144    {
00145       std::cout << "---------- end of main search. clusters have been sorted ----" << std::endl;
00146    }
00147   
00148    return clusters_v;
00149  
00150 }
00151 
00152 // Search for clusters
00153 //
00154 void CosmicClusterAlgo::mainSearch(      const CaloSubdetectorGeometry *geometry_p,
00155                    const CaloSubdetectorTopology *topology_p,
00156                    const CaloSubdetectorGeometry *geometryES_p,
00157                    EcalPart ecalPart )
00158 {
00159 
00160    if (verbosity < pINFO)
00161    {
00162       std::cout << "Building clusters............" << std::endl;
00163    }
00164      
00165   // Loop over seeds:
00166    std::vector<EcalRecHit>::iterator it;
00167    for (it = seeds.begin(); it != seeds.end(); it++)
00168    {
00169 
00170       // check if this crystal is able to seed
00171       // (event though it is already used)
00172       bool usedButCanSeed = false;
00173       if (canSeed_s.find(it->id()) != canSeed_s.end()) usedButCanSeed = true;
00174 
00175       // make sure the current seed does not belong to a cluster already.
00176       if ((used_s.find(it->id()) != used_s.end()) && (usedButCanSeed == false))
00177       {
00178          if (it == seeds.begin())
00179          {
00180             if (verbosity < pINFO)
00181             {
00182            std::cout << "##############################################################" << std::endl;
00183                std::cout << "DEBUG ALERT: Highest energy seed already belongs to a cluster!" << std::endl;
00184                std::cout << "##############################################################" << std::endl;
00185             }
00186          }
00187 
00188           // seed crystal is used or is used and cannot seed a cluster
00189           // so continue to the next seed crystal...
00190           continue;
00191       }
00192 
00193       // clear the vector of hits in current clusterconst EcalRecHitCollection* hits,
00194       current_v9.clear();
00195       current_v25.clear();
00196       current_v25Sup.clear();
00197 
00198       // Create a navigator at the seed
00199       CaloNavigator<DetId> navigator(it->id(), topology_p);
00200       DetId seedId = navigator.pos();
00201       navigator.setHome(seedId);
00202 
00203       // Is the seed a local maximum?
00204       bool localMaxima = checkMaxima(navigator);
00205 
00206       if (localMaxima)
00207       {
00208          // build the 5x5 taking care over which crystals //JHaupt 4-27-08 3x3 is a good option...
00209          // can seed new clusters and which can't
00210          prepareCluster(navigator, geometry_p);
00211       }
00212 
00213       // If some crystals in the current vector then 
00214       // make them into a cluster 
00215       if (current_v25.size() > 0) 
00216       {
00217         makeCluster(geometry_p, geometryES_p, seedId);
00218       }
00219 
00220    }  // End loop on seed crystals
00221 
00222 }
00223 
00224 void CosmicClusterAlgo::makeCluster(
00225                                     const CaloSubdetectorGeometry *geometry,
00226                                     const CaloSubdetectorGeometry *geometryES,
00227                                         DetId seedId)
00228 {
00229 
00230    double energy = 0;
00231    double energySecond = 0.;//JHaupt 4-27-08 Added for the second crystal stream
00232    double energyMax = 0.;//JHaupt 4-27-08 Added for the max crystal stream
00233    double chi2   = 0;
00234    DetId detFir;
00235    DetId detSec;
00236    //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... 
00237    
00238    
00239    std::vector<DetId>::iterator it;
00240    for (it = current_v9.begin(); it != current_v9.end(); it++)
00241    {
00242      // Martina - check recoFlag for crystals sorrounding the good one 
00243      EcalRecHitCollection::const_iterator itt = recHits_->find(*it);
00244      // double-check that iterator can be dereferenced   
00245      if(itt==recHits_->end()) continue; 
00246      EcalRecHit hit_p = *itt;
00247      // if rechit affected by features other than these, do not allow 2 crystal seeding either
00248      // features are hard coded, for now; add severity?
00249      uint32_t rhFlag = (*itt).recoFlag();
00250      if (!(
00251            rhFlag == EcalRecHit::kGood      ||
00252            rhFlag == EcalRecHit::kOutOfTime ||
00253            rhFlag == EcalRecHit::kPoorCalib
00254            )
00255          ) continue;
00256      
00258 
00259       EcalUncalibratedRecHitCollection::const_iterator ittu = uncalibRecHits_->find(*it);
00260       EcalUncalibratedRecHit uhit_p = *ittu;
00261           
00262           if (uhit_p.amplitude() > energySecond ) {energySecond = uhit_p.amplitude(); detSec = uhit_p.id();}
00263           if (energySecond > energyMax ) {std::swap(energySecond,energyMax); std::swap(detFir,detSec);}
00264    }
00265    
00266    //if ((detFir.det() == DetId::Ecal) && (detFir.subdetId() == EcalEndcap)) inEB = false;
00267    //We ignore the possiblity that the cluster may span into the EE    
00268 
00269    if ((energyMax < (inEB ? ecalBarrelSingleThreshold : ecalEndcapSingleThreshold)) && (energySecond < (inEB ? ecalBarrelSecondThreshold : ecalEndcapSecondThreshold) )) return;
00270    
00271    for (it = current_v25.begin(); it != current_v25.end(); it++)
00272    {
00273       EcalRecHitCollection::const_iterator itt = recHits_->find(*it);
00274       EcalRecHit hit_p = *itt;
00275           
00276           EcalUncalibratedRecHitCollection::const_iterator ittu = uncalibRecHits_->find(*it);
00277       EcalUncalibratedRecHit uhit_p = *ittu;
00278           
00279       if ( uhit_p.amplitude() > ( inEB ? ecalBarrelSupThreshold : ecalEndcapSupThreshold)) 
00280       {  
00281          // energy fraction = 1
00282          current_v25Sup.push_back( std::pair<DetId, float>( hit_p.id(), 1.) );
00283          energy += hit_p.energy(); //Keep the fully corrected energy 
00284          chi2 += 0;
00285       }     
00286    }
00287    
00288    Point position;
00289    position = posCalculator_.Calculate_Location(current_v25Sup,recHits_, geometry, geometryES);
00290    
00291    chi2 /= energy;
00292    if (verbosity < pINFO)
00293    { 
00294       std::cout << "JH******** NEW CLUSTER ********" << std::endl;
00295       std::cout << "JHNo. of crystals = " << current_v25Sup.size() << std::endl;
00296       std::cout << "JH     Energy     = " << energy << std::endl;
00297       std::cout << "JH     Phi        = " << position.phi() << std::endl;
00298       std::cout << "JH     Eta        = " << position.eta() << std::endl;
00299       std::cout << "JH*****************************" << std::endl;
00300       // specialize this
00301 //       std::cout << "JH****Emax****  "<<energyMax << " ieta " <<detFir.ieta() <<" iphi "<<detFir.ieta()  << std::endl;
00302 //       std::cout << "JH****Esec****  "<<energySecond << " ieta " <<detSec.ieta() <<" iphi "<<detSec.ieta() << std::endl;
00303     }
00304    clusters_v.push_back(reco::BasicCluster(energy, position, reco::CaloID(), current_v25Sup, reco::CaloCluster::multi5x5, seedId));
00305 }
00306 
00307 bool CosmicClusterAlgo::checkMaxima(CaloNavigator<DetId> &navigator)
00308 {
00309 
00310    bool maxima = true;
00311    EcalRecHitCollection::const_iterator thisHit;
00312    EcalRecHitCollection::const_iterator seedHit = recHits_->find(navigator.pos());
00313    double thisEnergy = 0.;
00314    double seedEnergy = seedHit->energy();
00315 
00316    std::vector<DetId> swissCrossVec;
00317    swissCrossVec.clear();
00318 
00319    swissCrossVec.push_back(navigator.west());
00320    navigator.home();
00321    swissCrossVec.push_back(navigator.east());
00322    navigator.home();
00323    swissCrossVec.push_back(navigator.north());
00324    navigator.home();
00325    swissCrossVec.push_back(navigator.south());
00326    navigator.home();
00327 
00328    std::vector<DetId>::const_iterator detItr;
00329    for (unsigned int i = 0; i < swissCrossVec.size(); ++i)
00330    {
00331       thisHit = recHits_->find(swissCrossVec[i]);
00332       if  ((swissCrossVec[i] == DetId(0)) || thisHit == recHits_->end()) thisEnergy = 0.0;
00333       else thisEnergy = thisHit->energy();
00334       if (thisEnergy > seedEnergy)
00335       {
00336          maxima = false;
00337          break;
00338       }
00339    }
00340 
00341    return maxima;
00342 
00343 }
00344 
00345 void CosmicClusterAlgo::prepareCluster(CaloNavigator<DetId> &navigator,  
00346                 const CaloSubdetectorGeometry *geometry)
00347 {
00348 
00349    DetId thisDet;
00350    std::set<DetId>::iterator setItr;
00351 
00352    // now add the 5x5 taking care to mark the edges
00353    // as able to seed and where overlapping in the central
00354    // region with crystals that were previously able to seed
00355    // change their status so they are not able to seed
00356    //std::cout << std::endl;
00357    for (int dx = -2; dx < 3; ++dx) //for (int dx = -2; dx < 3; ++dx)
00358    {
00359       for (int dy = -2; dy < 3; ++ dy) //for (int dy = -2; dy < 3; ++ dy)
00360       {
00361 
00362           // navigate in free steps forming
00363           // a full 5x5
00364           thisDet = navigator.offsetBy(dx, dy);
00365           navigator.home();
00366 
00367           // add the current crystal
00368           //std::cout << "adding " << dx << ", " << dy << std::endl;
00369          
00370 
00371 
00372           // now consider if we are in an edge (outer 16)
00373           // or central (inner 9) region
00374           if ((abs(dx) > 1) || (abs(dy) > 1))
00375           {    
00376              // this is an "edge" so should be allowed to seed
00377              // provided it is not already used
00378              //std::cout << "   setting can seed" << std::endl;
00379                          addCrystal(thisDet,false); //These are in the V25
00380              canSeed_s.insert(thisDet);
00381           }  // end if "edge"
00382           else 
00383           {
00384              // or else we are in the central 3x3
00385              // and must remove any of these crystals from the canSeed set
00386              setItr = canSeed_s.find(thisDet);
00387                          addCrystal(thisDet,true); //These are in the V9
00388              if (setItr != canSeed_s.end())
00389              {
00390                 //std::cout << "   unsetting can seed" << std::endl;
00391                 canSeed_s.erase(setItr);
00392              }
00393           }  // end if "centre"
00394 
00395 
00396       } // end loop on dy
00397 
00398    } // end loop on dx
00399 
00400    //std::cout << "*** " << std::endl;
00401    //std::cout << " current_v contains " << current_v.size() << std::endl;
00402    //std::cout << "*** " << std::endl;
00403 }
00404 
00405 
00406 void CosmicClusterAlgo::addCrystal(const DetId &det, const bool in9)
00407 {   
00408     
00409     EcalRecHitCollection::const_iterator thisIt =  recHits_->find(det);
00410     if ((thisIt != recHits_->end()) && (thisIt->id() != DetId(0)))
00411     { 
00412         if ((used_s.find(thisIt->id()) == used_s.end())) 
00413         {
00414                     EcalUncalibratedRecHitCollection::const_iterator thisItu =  uncalibRecHits_->find(det);
00415             used_s.insert(det);
00416             if ((thisIt->energy() >= -1.) && !(thisItu->chi2() < -1.))
00417             {           
00418                if (in9)  current_v9.push_back(det);
00419                    current_v25.push_back(det);
00420             }
00421             
00422         }
00423     } 
00424    
00425 }