CMS 3D CMS Logo

PFRecHitProducerHCAL.cc

Go to the documentation of this file.
00001 #include "RecoParticleFlow/PFClusterProducer/interface/PFRecHitProducerHCAL.h"
00002 
00003 #include <memory>
00004 
00005 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00006 
00007 #include "DataFormats/HcalRecHit/interface/HBHERecHit.h"
00008 #include "DataFormats/HcalRecHit/interface/HcalRecHitCollections.h"
00009 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
00010 
00011 #include "DataFormats/DetId/interface/DetId.h"
00012 
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014 #include "FWCore/Framework/interface/ESHandle.h"
00015 #include "FWCore/Framework/interface/EventSetup.h"
00016 
00017 
00018 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00019 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00020 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00021 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00022 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00023 
00024 #include "Geometry/CaloTopology/interface/HcalTopology.h"
00025 #include "RecoCaloTools/Navigation/interface/CaloNavigator.h"
00026 
00027 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00028 
00029 #include "Geometry/CaloTopology/interface/CaloTowerTopology.h"
00030 #include "RecoCaloTools/Navigation/interface/CaloTowerNavigator.h"
00031 
00032 
00033 using namespace std;
00034 using namespace edm;
00035 
00036 PFRecHitProducerHCAL::PFRecHitProducerHCAL(const edm::ParameterSet& iConfig)
00037   : PFRecHitProducer( iConfig ) 
00038 {
00039 
00040  
00041 
00042   // access to the collections of rechits 
00043 
00044   
00045   inputTagHcalRecHitsHBHE_ =
00046     iConfig.getParameter<InputTag>("hcalRecHitsHBHE");
00047     
00048  
00049   inputTagCaloTowers_ = 
00050     iConfig.getParameter<InputTag>("caloTowers");
00051    
00052   thresh_HF_ = 
00053     iConfig.getParameter<double>("thresh_HF");
00054 }
00055 
00056 
00057 
00058 PFRecHitProducerHCAL::~PFRecHitProducerHCAL() {}
00059 
00060 
00061 
00062 void PFRecHitProducerHCAL::createRecHits(vector<reco::PFRecHit>& rechits,
00063                                          edm::Event& iEvent, 
00064                                          const edm::EventSetup& iSetup ) {
00065 
00066   
00067   // this map is necessary to find the rechit neighbours efficiently
00068   //C but I should think about using Florian's hashed index to do this.
00069   //C in which case the map might not be necessary anymore
00070   //C however the hashed index does not seem to be implemented for HCAL
00071   // 
00072   // the key of this map is detId. 
00073   // the value is the index in the rechits vector
00074   map<unsigned,  unsigned > idSortedRecHits;
00075   typedef map<unsigned, unsigned >::iterator IDH;  
00076 
00077 
00078   edm::ESHandle<CaloGeometry> geoHandle;
00079   iSetup.get<CaloGeometryRecord>().get(geoHandle);
00080   
00081   // get the hcalBarrel geometry
00082   const CaloSubdetectorGeometry *hcalBarrelGeometry = 
00083     geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalBarrel);
00084 
00085   // get the endcap geometry
00086   const CaloSubdetectorGeometry *hcalEndcapGeometry = 
00087     geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalEndcap);
00088 
00089  
00090   // 2 possibilities to make HCAL clustering :
00091   // - from the HCAL rechits
00092   // - from the CaloTowers. 
00093   // ultimately, clustering will be done taking CaloTowers as an 
00094   // input. This possibility is currently under investigation, and 
00095   // was thus made optional.
00096 
00097   // in the first step, we will fill the map of PFRecHits hcalrechits
00098   // either from CaloTowers or from HCAL rechits. 
00099 
00100   // in the second step, we will perform clustering on this map.
00101 
00102   if( !(inputTagCaloTowers_ == InputTag()) ) {
00103       
00104     edm::Handle<CaloTowerCollection> caloTowers; 
00105     CaloTowerTopology caloTowerTopology; 
00106     const CaloSubdetectorGeometry *caloTowerGeometry = 0; 
00107     // = geometry_->getSubdetectorGeometry(id)
00108 
00109     // get calotowers
00110     bool found = iEvent.getByLabel(inputTagCaloTowers_,
00111                                    caloTowers);
00112 
00113     if(!found) {
00114       ostringstream err;
00115       err<<"could not find rechits "<<inputTagCaloTowers_;
00116       LogError("PFRecHitProducerHCAL")<<err.str()<<endl;
00117     
00118       throw cms::Exception( "MissingProduct", err.str());
00119     }
00120     else {
00121       assert( caloTowers.isValid() );
00122       
00123       // create rechits
00124       typedef CaloTowerCollection::const_iterator ICT;
00125       
00126       for(ICT ict=caloTowers->begin(); ict!=caloTowers->end();ict++) {
00127           
00128         const CaloTower& ct = (*ict);
00129           
00130         //C     
00131         if(!caloTowerGeometry) 
00132           caloTowerGeometry = geoHandle->getSubdetectorGeometry(ct.id());
00133           
00134         // get the hadronic energy.
00135         double energy = ct.hadEnergy()+ct.emEnergy();
00136 
00137         if( energy < 1e-9 ) continue;  
00138           
00139           
00140           
00141         // the layer will be taken from the first constituent. 
00142         // all thresholds for ECAL must be set to very high values !!!
00143         assert( ct.constituentsSize() );          
00144         const HcalDetId& detid = ct.constituent(0);
00145           
00146         reco::PFRecHit* pfrh = 0;
00147           
00148         switch( detid.subdet() ) {
00149         case HcalBarrel: 
00150           {
00151             if(energy < thresh_Barrel_ ) continue;
00152             pfrh = createHcalRecHit( detid, 
00153                                      energy, 
00154                                      PFLayer::HCAL_BARREL1, 
00155                                      hcalBarrelGeometry,
00156                                      ct.id().rawId() );
00157           }
00158           break;
00159         case HcalEndcap:
00160           {
00161             if(energy < thresh_Endcap_ ) continue;
00162             pfrh = createHcalRecHit( detid, 
00163                                      energy, 
00164                                      PFLayer::HCAL_ENDCAP, 
00165                                      hcalEndcapGeometry,
00166                                      ct.id().rawId() );
00167           }
00168           break;
00169         case HcalForward:
00170           {
00171             if(energy < thresh_HF_ ) continue;
00172             pfrh = createHcalRecHit( detid, 
00173                                      energy, 
00174                                      PFLayer::HCAL_HF, 
00175                                      hcalEndcapGeometry,
00176                                      ct.id().rawId() );
00177           }
00178           break;
00179         default:
00180           LogError("PFRecHitProducerHCAL")
00181             <<"CaloTower constituent: unknown layer : "
00182             <<detid.subdet()<<endl;
00183         } 
00184           
00185         if(pfrh) { 
00186           rechits.push_back( *pfrh );
00187           delete pfrh;
00188           idSortedRecHits.insert( make_pair(ct.id().rawId(), 
00189                                             rechits.size()-1 ) ); 
00190         }
00191       }
00192         
00193         
00194 
00195       // do navigation 
00196       for(unsigned i=0; i<rechits.size(); i++ ) {
00197           
00198         findRecHitNeighboursCT( rechits[i], 
00199                                 idSortedRecHits, 
00200                                 caloTowerTopology);
00201           
00202       }
00203     }   
00204   }
00205   else if( !(inputTagHcalRecHitsHBHE_ == InputTag()) ) { 
00206     // clustering is not done on CaloTowers but on HCAL rechits.
00207        
00208 
00209     // get the hcal topology
00210     HcalTopology hcalTopology;
00211     
00212     // HCAL rechits 
00213     //    vector<edm::Handle<HBHERecHitCollection> > hcalHandles;  
00214     edm::Handle<HBHERecHitCollection>  hcalHandle;  
00215 
00216     
00217     bool found = iEvent.getByLabel(inputTagHcalRecHitsHBHE_, 
00218                                    hcalHandle );
00219 
00220     if(!found) {
00221       ostringstream err;
00222       err<<"could not find rechits "<<inputTagHcalRecHitsHBHE_;
00223       LogError("PFRecHitProducerHCAL")<<err.str()<<endl;
00224     
00225       throw cms::Exception( "MissingProduct", err.str());
00226     }
00227     else {
00228       assert( hcalHandle.isValid() );
00229       
00230       const edm::Handle<HBHERecHitCollection>& handle = hcalHandle;
00231       for(unsigned irechit=0; irechit<handle->size(); irechit++) {
00232         const HBHERecHit& hit = (*handle)[irechit];
00233         
00234         double energy = hit.energy();
00235         
00236         reco::PFRecHit* pfrh = 0;
00237         
00238 
00239         const HcalDetId& detid = hit.detid();
00240         switch( detid.subdet() ) {
00241         case HcalBarrel:
00242           {
00243             if(energy < thresh_Barrel_ ) continue;
00244             pfrh = createHcalRecHit( detid, 
00245                                      energy, 
00246                                      PFLayer::HCAL_BARREL1, 
00247                                      hcalBarrelGeometry );
00248           }
00249           break;
00250         case HcalEndcap:
00251           {
00252             if(energy < thresh_Endcap_ ) continue;
00253             pfrh = createHcalRecHit( detid, 
00254                                      energy, 
00255                                      PFLayer::HCAL_ENDCAP, 
00256                                      hcalEndcapGeometry );        
00257           }
00258           break;
00259         case HcalForward:
00260           {
00261             if(energy < thresh_HF_ ) continue;
00262             pfrh = createHcalRecHit( detid, 
00263                                      energy, 
00264                                      PFLayer::HCAL_HF, 
00265                                      hcalEndcapGeometry );
00266           }
00267           break;
00268         default:
00269           LogError("PFRecHitProducerHCAL")
00270             <<"HCAL rechit: unknown layer : "<<detid.subdet()<<endl;
00271           continue;
00272         } 
00273 
00274         if(pfrh) { 
00275           rechits.push_back( *pfrh );
00276           delete pfrh;
00277           idSortedRecHits.insert( make_pair(detid.rawId(), 
00278                                             rechits.size()-1 ) ); 
00279         }
00280       }
00281       
00282       
00283       // do navigation:
00284       for(unsigned i=0; i<rechits.size(); i++ ) {
00285         
00286         findRecHitNeighbours( rechits[i], idSortedRecHits, 
00287                               hcalTopology, 
00288                               *hcalBarrelGeometry, 
00289                               hcalTopology,
00290                               *hcalEndcapGeometry);
00291       } // loop for navigation
00292     }  // endif hcal rechits were found
00293   } // endif clustering on rechits in hcal
00294 }
00295 
00296 
00297 
00298 
00299 
00300 
00301 reco::PFRecHit* 
00302 PFRecHitProducerHCAL::createHcalRecHit( const DetId& detid,
00303                                         double energy,
00304                                         PFLayer::Layer layer,
00305                                         const CaloSubdetectorGeometry* geom,
00306                                         unsigned newDetId ) {
00307   
00308   const CaloCellGeometry *thisCell = geom->getGeometry(detid);
00309   if(!thisCell) {
00310     edm::LogError("PFRecHitProducerHCAL")
00311       <<"warning detid "<<detid.rawId()<<" not found in layer "
00312       <<layer<<endl;
00313     return 0;
00314   }
00315   
00316   const GlobalPoint& position = thisCell->getPosition();
00317   
00318   
00319   unsigned id = detid;
00320   if(newDetId) id = newDetId;
00321   reco::PFRecHit *rh = 
00322     new reco::PFRecHit( id,  layer, energy, 
00323                         position.x(), position.y(), position.z(), 
00324                         0,0,0 );
00325  
00326   
00327   
00328   
00329   // set the corners
00330   const CaloCellGeometry::CornersVec& corners = thisCell->getCorners();
00331 
00332   assert( corners.size() == 8 );
00333 
00334   rh->setNECorner( corners[0].x(), corners[0].y(),  corners[0].z() );
00335   rh->setSECorner( corners[1].x(), corners[1].y(),  corners[1].z() );
00336   rh->setSWCorner( corners[2].x(), corners[2].y(),  corners[2].z() );
00337   rh->setNWCorner( corners[3].x(), corners[3].y(),  corners[3].z() );
00338  
00339   return rh;
00340 }
00341 
00342 
00343 
00344 
00345 void 
00346 PFRecHitProducerHCAL::findRecHitNeighbours
00347 ( reco::PFRecHit& rh, 
00348   const map<unsigned,unsigned >& sortedHits, 
00349   const CaloSubdetectorTopology& barrelTopology, 
00350   const CaloSubdetectorGeometry& barrelGeometry, 
00351   const CaloSubdetectorTopology& endcapTopology, 
00352   const CaloSubdetectorGeometry& endcapGeometry ) {
00353   
00354 
00355   if( rh.layer() == PFLayer::HCAL_HF )
00356     return;
00357   
00358   DetId detid( rh.detId() );
00359 
00360   const CaloSubdetectorTopology* topology = 0;
00361   const CaloSubdetectorGeometry* geometry = 0;
00362   const CaloSubdetectorGeometry* othergeometry = 0;
00363   
00364   switch( rh.layer() ) {
00365   case PFLayer::ECAL_ENDCAP: 
00366     topology = &endcapTopology;
00367     geometry = &endcapGeometry;
00368     break;
00369   case PFLayer::ECAL_BARREL: 
00370     topology = &barrelTopology;
00371     geometry = &barrelGeometry;
00372     break;
00373   case PFLayer::HCAL_ENDCAP:
00374     topology = &endcapTopology;
00375     geometry = &endcapGeometry;
00376     othergeometry = &barrelGeometry;
00377     break;
00378   case PFLayer::HCAL_BARREL1:
00379     topology = &barrelTopology;
00380     geometry = &barrelGeometry;
00381     othergeometry = &endcapGeometry;
00382     break;
00383   case PFLayer::PS1:
00384   case PFLayer::PS2:
00385     topology = &barrelTopology;
00386     geometry = &barrelGeometry;
00387     othergeometry = &endcapGeometry;
00388     break;
00389   default:
00390     assert(0);
00391   }
00392   
00393   assert( topology && geometry );
00394 
00395   CaloNavigator<DetId> navigator(detid, topology);
00396 
00397   DetId north = navigator.north();  
00398   
00399   DetId northeast(0);
00400   if( north != DetId(0) ) {
00401     northeast = navigator.east();  
00402   }
00403   navigator.home();
00404 
00405 
00406   DetId south = navigator.south();
00407 
00408   
00409 
00410   DetId southwest(0); 
00411   if( south != DetId(0) ) {
00412     southwest = navigator.west();
00413   }
00414   navigator.home();
00415 
00416 
00417   DetId east = navigator.east();
00418   DetId southeast;
00419   if( east != DetId(0) ) {
00420     southeast = navigator.south(); 
00421   }
00422   navigator.home();
00423   DetId west = navigator.west();
00424   DetId northwest;
00425   if( west != DetId(0) ) {   
00426     northwest = navigator.north();  
00427   }
00428   navigator.home();
00429     
00430   IDH i = sortedHits.find( north.rawId() );
00431   if(i != sortedHits.end() ) 
00432     rh.add4Neighbour( i->second );
00433   
00434   i = sortedHits.find( northeast.rawId() );
00435   if(i != sortedHits.end() ) 
00436     rh.add8Neighbour( i->second );
00437   
00438   i = sortedHits.find( south.rawId() );
00439   if(i != sortedHits.end() ) 
00440     rh.add4Neighbour( i->second );
00441     
00442   i = sortedHits.find( southwest.rawId() );
00443   if(i != sortedHits.end() ) 
00444     rh.add8Neighbour( i->second );
00445     
00446   i = sortedHits.find( east.rawId() );
00447   if(i != sortedHits.end() ) 
00448     rh.add4Neighbour( i->second );
00449     
00450   i = sortedHits.find( southeast.rawId() );
00451   if(i != sortedHits.end() ) 
00452     rh.add8Neighbour( i->second );
00453     
00454   i = sortedHits.find( west.rawId() );
00455   if(i != sortedHits.end() ) 
00456      rh.add4Neighbour( i->second );
00457    
00458   i = sortedHits.find( northwest.rawId() );
00459   if(i != sortedHits.end() ) 
00460     rh.add8Neighbour( i->second );
00461     
00462 
00463 }
00464 
00465 
00466 void 
00467 PFRecHitProducerHCAL::findRecHitNeighboursCT
00468 ( reco::PFRecHit& rh, 
00469   const map<unsigned, unsigned >& sortedHits, 
00470   const CaloSubdetectorTopology& topology ) {
00471 
00472   if( rh.layer() == PFLayer::HCAL_HF )
00473     return;
00474 
00475   CaloTowerDetId ctDetId( rh.detId() );
00476     
00477 
00478   vector<DetId> northids = topology.north(ctDetId);
00479   vector<DetId> westids = topology.west(ctDetId);
00480   vector<DetId> southids = topology.south(ctDetId);
00481   vector<DetId> eastids = topology.east(ctDetId);
00482 
00483 
00484   CaloTowerDetId badId;
00485 
00486   // all the following detids will be CaloTowerDetId
00487   CaloTowerDetId north;
00488   CaloTowerDetId northwest;
00489   CaloTowerDetId west;
00490   CaloTowerDetId southwest;
00491   CaloTowerDetId south;
00492   CaloTowerDetId southeast;
00493   CaloTowerDetId east;
00494   CaloTowerDetId northeast;
00495   
00496   // for north and south, there is no ambiguity : 1 or 0 neighbours
00497   string err("PFRecHitProducerHCAL::findRecHitNeighboursCT : incorrect number of neighbours "); 
00498   char n[20];
00499   
00500   switch( northids.size() ) {
00501   case 0: 
00502     break;
00503   case 1: 
00504     north = northids[0];
00505     break;
00506   default:
00507     sprintf(n, "north: %d", northids.size() );
00508     err += n;
00509     throw( err ); 
00510   }
00511 
00512   switch( southids.size() ) {
00513   case 0: 
00514     break;
00515   case 1: 
00516     south = southids[0];
00517     break;
00518   default:
00519     sprintf(n, "south %d", southids.size() );
00520     err += n;
00521     throw( err ); 
00522   }
00523   
00524   // for east and west, one must take care 
00525   // of the pitch change in HCAL endcap.
00526 
00527   switch( eastids.size() ) {
00528   case 0: 
00529     break;
00530   case 1: 
00531     east = eastids[0];
00532     northeast = getNorth(east, topology);
00533     southeast = getSouth(east, topology);
00534     break;
00535   case 2:  
00536     // in this case, 0 is more on the north than 1
00537     east = eastids[0];
00538     northeast = getNorth(east, topology );
00539     southeast = getSouth(eastids[1], topology);    
00540     break;
00541   default:
00542     sprintf(n, "%d", eastids.size() );
00543     err += n;
00544     throw( err ); 
00545   }
00546   
00547   
00548   switch( westids.size() ) {
00549   case 0: 
00550     break;
00551   case 1: 
00552     west = westids[0];
00553     northwest = getNorth(west, topology);
00554     southwest = getSouth(west, topology);
00555     break;
00556   case 2:  
00557     // in this case, 0 is more on the north than 1
00558     west = westids[0];
00559     northwest = getNorth(west, topology );
00560     southwest = getSouth(westids[1], topology );    
00561     break;
00562   default:
00563     sprintf(n, "%d", westids.size() );
00564     err += n;
00565     throw( err ); 
00566   }
00567 
00568 
00569 
00570 
00571   // find and set neighbours
00572     
00573   IDH i = sortedHits.find( north.rawId() );
00574   if(i != sortedHits.end() ) 
00575     rh.add4Neighbour( i->second );
00576   
00577   i = sortedHits.find( northeast.rawId() );
00578   if(i != sortedHits.end() ) 
00579     rh.add8Neighbour( i->second );
00580   
00581   i = sortedHits.find( south.rawId() );
00582   if(i != sortedHits.end() ) 
00583     rh.add4Neighbour( i->second );
00584     
00585   i = sortedHits.find( southwest.rawId() );
00586   if(i != sortedHits.end() ) 
00587     rh.add8Neighbour( i->second );
00588     
00589   i = sortedHits.find( east.rawId() );
00590   if(i != sortedHits.end() ) 
00591     rh.add4Neighbour( i->second );
00592     
00593   i = sortedHits.find( southeast.rawId() );
00594   if(i != sortedHits.end() ) 
00595     rh.add8Neighbour( i->second );
00596     
00597   i = sortedHits.find( west.rawId() );
00598   if(i != sortedHits.end() ) 
00599      rh.add4Neighbour( i->second );
00600    
00601   i = sortedHits.find( northwest.rawId() );
00602   if(i != sortedHits.end() ) 
00603     rh.add8Neighbour( i->second );
00604 }
00605 
00606 
00607 
00608 DetId PFRecHitProducerHCAL::getSouth(const DetId& id, 
00609                                   const CaloSubdetectorTopology& topology) {
00610 
00611   DetId south;
00612   vector<DetId> sids = topology.south(id);
00613   if(sids.size() == 1)
00614     south = sids[0];
00615   
00616   return south;
00617 } 
00618 
00619 
00620 
00621 DetId PFRecHitProducerHCAL::getNorth(const DetId& id, 
00622                                   const CaloSubdetectorTopology& topology) {
00623 
00624   DetId north;
00625   vector<DetId> nids = topology.north(id);
00626   if(nids.size() == 1)
00627     north = nids[0];
00628   
00629   return north;
00630 } 
00631 
00632 

Generated on Tue Jun 9 17:44:40 2009 for CMSSW by  doxygen 1.5.4