CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/RecoParticleFlow/PFClusterProducer/plugins/PFRecHitProducerHO.cc

Go to the documentation of this file.
00001 #include "RecoParticleFlow/PFClusterProducer/plugins/PFRecHitProducerHO.h"
00002 
00003 #include <memory>
00004 
00005 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00006 
00007 #include "DataFormats/HcalRecHit/interface/HORecHit.h"
00008 #include "DataFormats/HcalRecHit/interface/HcalRecHitCollections.h"
00009 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
00010 
00011 #include "DataFormats/DetId/interface/DetId.h"
00012 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00013 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00014 
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 #include "FWCore/Framework/interface/ESHandle.h"
00017 #include "FWCore/Framework/interface/EventSetup.h"
00018 
00019 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00020 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00021 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00022 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00023 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00024 
00025 #include "Geometry/CaloTopology/interface/HcalTopology.h"
00026 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00027 
00028 #include "Geometry/CaloTopology/interface/CaloTowerTopology.h"
00029 #include "RecoCaloTools/Navigation/interface/CaloTowerNavigator.h"
00030 
00031 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalCaloFlagLabels.h"
00032 #include "RecoCaloTools/Navigation/interface/CaloNavigator.h"
00033 
00034 
00035 using namespace std;
00036 using namespace edm;
00037 
00038 PFRecHitProducerHO::PFRecHitProducerHO(const edm::ParameterSet& iConfig)
00039   : PFRecHitProducer(iConfig) {
00040   
00041   // access to the collections of rechits
00042   inputTagHORecHits_ = 
00043     iConfig.getParameter<InputTag>("recHitsHO");
00044   
00045   neighbourmapcalculated_ = false;
00046 }
00047 
00048 
00049 
00050 PFRecHitProducerHO::~PFRecHitProducerHO() {}
00051 
00052 void 
00053 PFRecHitProducerHO::createRecHits(vector<reco::PFRecHit>& rechits,
00054                                   vector<reco::PFRecHit>& rechitsCleaned,
00055                                   edm::Event& iEvent, 
00056                                   const edm::EventSetup& iSetup ) {
00057 
00058 
00059 
00060   // this map is necessary to find the rechit neighbours efficiently
00061   //C but I should think about using Florian's hashed index to do this.
00062   //C in which case the map might not be necessary anymore
00063   // 
00064   // the key of this map is detId. 
00065   // the value is the index in the rechits vector
00066   map<unsigned, unsigned > idSortedRecHits;
00067   //   typedef map<unsigned, unsigned >::iterator IDH;
00068   
00069   edm::ESHandle<CaloGeometry> geoHandle;
00070   iSetup.get<CaloGeometryRecord>().get(geoHandle);
00071   
00072   // get the HO geometry
00073   const CaloSubdetectorGeometry *hcalBarrelGeometry = 
00074     geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalOuter);
00075   
00076   // get the HO topology
00077   HcalTopology hcalBarrelTopology; // (geoHandle);
00078   
00079   if(!neighbourmapcalculated_)
00080     hoNeighbArray( *hcalBarrelGeometry,
00081                    hcalBarrelTopology);
00082   
00083   // get the HO rechits
00084   
00085   edm::Handle<HORecHitCollection> rhcHandle;
00086   
00087   
00088   bool found = iEvent.getByLabel(inputTagHORecHits_, 
00089                                  rhcHandle);
00090   
00091   if(!found) {
00092     
00093     ostringstream err;
00094     err<<"could not find rechits "<<inputTagHORecHits_;
00095     LogError("PFRecHitProducerHO")<<err.str()<<endl;
00096     
00097     throw cms::Exception( "MissingProduct", err.str());
00098   }
00099   else {
00100     assert( rhcHandle.isValid() );
00101     
00102     // process HO rechits
00103     for(unsigned i=0; i<rhcHandle->size(); i++) {
00104       
00105       const HORecHit& erh = (*rhcHandle)[i];
00106       const HcalDetId& detid = (HcalDetId)erh.detid();
00107       
00108       double energy = erh.energy();
00109       // uint32_t flag = erh.recoFlag();
00110       double time = erh.time();
00111       
00112       HcalSubdetector esd=(HcalSubdetector)detid.subdetId();
00113       
00114       if (esd != 3) continue;
00115       int hoeta=detid.ieta();
00116       if ( (abs(hoeta)<=4 && energy < thresh_Barrel_) || 
00117            (abs(hoeta)> 4 && energy < thresh_Endcap_) ) continue;
00118       
00119       reco::PFRecHit *pfrh = createHORecHit(detid, energy,  
00120                                             PFLayer::HCAL_BARREL2, // HO,
00121                                             hcalBarrelGeometry);
00122       
00123       if( !pfrh ) continue; // problem with this rechit. skip it
00124       
00125       pfrh->setRescale(time);
00126       
00127       rechits.push_back( *pfrh );
00128       delete pfrh;
00129       idSortedRecHits.insert( make_pair(detid.rawId(), rechits.size()-1 ) ); 
00130     }      
00131   }
00132   
00133   // do navigation
00134   for(unsigned i=0; i<rechits.size(); i++ ) {
00135     findRecHitNeighboursHO( rechits[i], idSortedRecHits ); 
00136   }
00137   
00138 } 
00139 
00140 
00141 reco::PFRecHit* 
00142 PFRecHitProducerHO::createHORecHit( const DetId& detid,
00143                                     double energy,
00144                                     PFLayer::Layer layer,
00145                                     const CaloSubdetectorGeometry* geom ) {
00146   
00147   math::XYZVector position;
00148   math::XYZVector axis;
00149   
00150   const CaloCellGeometry *thisCell 
00151     = geom->getGeometry(detid);
00152   
00153   // find rechit geometry
00154   if(!thisCell) {
00155     LogError("PFRecHitProducerHO")
00156       <<"warning detid "<<detid.rawId()
00157       <<" not found in geometry"<<endl;
00158     return 0;
00159   }
00160   
00161   double sclel0l1r=0.946; //384.8/406.6
00162   
00163   if (abs(thisCell->getPosition().z())>130) {
00164     position.SetCoordinates ( sclel0l1r*thisCell->getPosition().x(),
00165                               sclel0l1r*thisCell->getPosition().y(),
00166                               sclel0l1r*thisCell->getPosition().z() );   
00167     
00168   } else {
00169     position.SetCoordinates ( thisCell->getPosition().x(),
00170                               thisCell->getPosition().y(),
00171                               thisCell->getPosition().z() );
00172   }
00173   
00174   // the axis vector is the difference 
00175   
00176   //   const TruncatedPyramid* pyr 
00177   //     = dynamic_cast< const TruncatedPyramid* > (thisCell);    
00178   //   if( pyr ) {
00179   //     axis.SetCoordinates( pyr->getPosition(1).x(), 
00180   //                     pyr->getPosition(1).y(), 
00181   //                     pyr->getPosition(1).z() ); 
00182   
00183   //     math::XYZVector axis0( pyr->getPosition(0).x(), 
00184   //                       pyr->getPosition(0).y(), 
00185   //                       pyr->getPosition(0).z() );
00186   
00187   //     axis -= axis0;    
00188   //   }
00189   //   else return 0;
00190   
00191   axis = math::XYZVector(0,0,0);
00192   
00193   //   if( !geomfound ) {
00194   //     LogError("PFRecHitProducerHO")<<"cannor find geometry for detid "
00195   //                             <<detid.rawId()<<" in layer "<<layer<<endl;
00196   //     return 0; // geometry not found, skip rechit
00197   //   }
00198   
00199   
00200   reco::PFRecHit *rh 
00201     = new reco::PFRecHit( detid.rawId(), layer, 
00202                           energy, 
00203                           position.x(), position.y(), position.z(), 
00204                           axis.x(), axis.y(), axis.z() ); 
00205   
00206   const CaloCellGeometry::CornersVec& corners = thisCell->getCorners();
00207   assert( corners.size() == 8 );
00208   
00209   if (abs(corners[0].z())>130.0) {
00210     rh->setNECorner( sclel0l1r*corners[0].x(), sclel0l1r*corners[0].y(),  sclel0l1r*corners[0].z() );
00211     rh->setSECorner( sclel0l1r*corners[1].x(), sclel0l1r*corners[1].y(),  sclel0l1r*corners[1].z() );
00212     rh->setSWCorner( sclel0l1r*corners[2].x(), sclel0l1r*corners[2].y(),  sclel0l1r*corners[2].z() );
00213     rh->setNWCorner( sclel0l1r*corners[3].x(), sclel0l1r*corners[3].y(),  sclel0l1r*corners[3].z() );
00214     
00215   } else {
00216     rh->setNECorner( corners[0].x(), corners[0].y(),  corners[0].z() );
00217     rh->setSECorner( corners[1].x(), corners[1].y(),  corners[1].z() );
00218     rh->setSWCorner( corners[2].x(), corners[2].y(),  corners[2].z() );
00219     rh->setNWCorner( corners[3].x(), corners[3].y(),  corners[3].z() );
00220   }
00221   
00222   return rh;
00223 }
00224 
00225 
00226 bool
00227 PFRecHitProducerHO::findHORecHitGeometry(const DetId& detid, 
00228                                          const CaloSubdetectorGeometry* geom,
00229                                          math::XYZVector& position, 
00230                                          math::XYZVector& axis ) {
00231   
00232   
00233   const CaloCellGeometry *thisCell 
00234     = geom->getGeometry(detid);
00235   
00236   // find rechit geometry
00237   if(!thisCell) {
00238     LogError("PFRecHitProducerHO")
00239       <<"warning detid "<<detid.rawId()
00240       <<" not found in geometry"<<endl;
00241     return false;
00242   }
00243   
00244   position.SetCoordinates ( thisCell->getPosition().x(),
00245                             thisCell->getPosition().y(),
00246                             thisCell->getPosition().z() );
00247   
00248   
00249   
00250   // the axis vector is the difference 
00251   //   const TruncatedPyramid* pyr 
00252   //     = dynamic_cast< const TruncatedPyramid* > (thisCell);    
00253   //   if( pyr ) {
00254   //     axis.SetCoordinates( pyr->getPosition(1).x(), 
00255   //                     pyr->getPosition(1).y(), 
00256   //                     pyr->getPosition(1).z() ); 
00257   
00258   //     math::XYZVector axis0( pyr->getPosition(0).x(), 
00259   //                       pyr->getPosition(0).y(), 
00260   //                       pyr->getPosition(0).z() );
00261   
00262   //     axis -= axis0;
00263   
00264   
00265   //     return true;
00266   //   }
00267   
00268   axis = math::XYZVector(0,0,0);
00269   return true;
00270   
00271   //  else return false;
00272 }
00273 
00274 
00275 
00276 void 
00277 PFRecHitProducerHO::findRecHitNeighboursHO
00278 ( reco::PFRecHit& rh, 
00279   const map<unsigned,unsigned >& sortedHits ) {
00280   
00281   DetId center( rh.detId() );
00282   
00283   
00284   DetId north = move( center, NORTH );
00285   DetId northeast = move( center, NORTHEAST );
00286   DetId northwest = move( center, NORTHWEST ); 
00287   DetId south = move( center, SOUTH );  
00288   DetId southeast = move( center, SOUTHEAST );  
00289   DetId southwest = move( center, SOUTHWEST );  
00290   DetId east  = move( center, EAST );  
00291   DetId west  = move( center, WEST );  
00292   
00293   IDH i = sortedHits.find( north.rawId() );
00294   if(i != sortedHits.end() ) 
00295     rh.add4Neighbour( i->second );
00296   
00297   i = sortedHits.find( northeast.rawId() );
00298   if(i != sortedHits.end() ) 
00299     rh.add8Neighbour( i->second );
00300   
00301   i = sortedHits.find( south.rawId() );
00302   if(i != sortedHits.end() ) 
00303     rh.add4Neighbour( i->second );
00304   
00305   i = sortedHits.find( southwest.rawId() );
00306   if(i != sortedHits.end() ) 
00307     rh.add8Neighbour( i->second );
00308   
00309   i = sortedHits.find( east.rawId() );
00310   if(i != sortedHits.end() ) 
00311     rh.add4Neighbour( i->second );
00312   
00313   i = sortedHits.find( southeast.rawId() );
00314   if(i != sortedHits.end() ) 
00315     rh.add8Neighbour( i->second );
00316   
00317   i = sortedHits.find( west.rawId() );
00318   if(i != sortedHits.end() ) 
00319     rh.add4Neighbour( i->second );
00320   
00321   i = sortedHits.find( northwest.rawId() );
00322   if(i != sortedHits.end() ) 
00323     rh.add8Neighbour( i->second );
00324 }
00325 
00326 
00327 // Build the array of (max)8 neighbors
00328 void 
00329 PFRecHitProducerHO::hoNeighbArray(
00330                                   const CaloSubdetectorGeometry& barrelGeom,
00331                                   const CaloSubdetectorTopology& barrelTopo){
00332   
00333   static const CaloDirection orderedDir[8]={SOUTHWEST,
00334                                             SOUTH,
00335                                             SOUTHEAST,
00336                                             WEST,
00337                                             EAST,
00338                                             NORTHWEST,
00339                                             NORTH,
00340                                             NORTHEAST};
00341   
00342   const unsigned nbarrel = 2160; //62000;
00343   // Barrel first. The hashed index runs from 0 to 2199 61199
00344   neighboursHO_.resize(nbarrel);
00345   
00346   //std::cout << " Building the array of neighbours (barrel) " ;
00347   
00348   const std::vector<DetId>& vec(barrelGeom.getValidDetIds(DetId::Hcal,
00349                                                           HcalOuter));
00350   unsigned size=vec.size();    
00351   for(unsigned ic=0; ic<size; ++ic) 
00352     {
00353       // We get the 9 cells in a square. 
00354       std::vector<DetId> neighbours(barrelTopo.getWindow(vec[ic],3,3));
00355       unsigned nneighbours=neighbours.size();
00356       
00357       unsigned hashedindex=HcalDetId(vec[ic]).hashed_index()-5184; //2*( kHBhalf + kHEhalf )
00358       //           std::cout << " Cell " << ic<<" "<<vec[ic].rawId()<<" "<<HcalDetId(vec[ic]) <<" "<<hashedindex<<" "<<nneighbours<< std::endl;
00359       if(hashedindex>=nbarrel)
00360         {
00361           LogDebug("CaloGeometryTools")  << " Array overflow " << std::endl;
00362         }
00363       
00364       
00365       // If there are 9 cells, it is easy, and this order is know:
00366       //      6  7  8
00367       //      3  4  5 
00368       //      0  1  2   (0 = SOUTHWEST)
00369       
00370       if(nneighbours==9)
00371         {
00372           neighboursHO_[hashedindex].reserve(8);
00373           for(unsigned in=0;in<nneighbours;++in)
00374             {
00375               // remove the centre
00376               //    cout<<"ic "<<ic<<" "<<in<<" "<<neighbours[in].rawId()<<" "<<vec[ic].rawId()<<" "<<hashedindex<<endl; 
00377               if(neighbours[in]!=vec[ic]) 
00378                 {
00379                   neighboursHO_[hashedindex].push_back(neighbours[in]);
00380                   //            std::cout << " Neighbour " << ic<<" "<<size<<" "<<in << " " <<hashedindex<<" "<< HcalDetId(neighbours[in]) << std::endl;
00381                 }
00382             }
00383         }
00384       else
00385         {
00386           DetId central(vec[ic]);
00387           neighboursHO_[hashedindex].resize(8,DetId(0));
00388           for(unsigned idir=0;idir<8;++idir)
00389             {
00390               DetId testid=central;
00391               bool status=stdmove(testid,orderedDir[idir],
00392                                   barrelTopo, barrelGeom);
00393               if(status) neighboursHO_[hashedindex][idir]=testid;
00394             }
00395           
00396         }
00397     }
00398   
00399   //    std::cout << " done " << size <<std::endl;
00400   neighbourmapcalculated_ = true;
00401 }
00402 
00403 bool 
00404 PFRecHitProducerHO::stdsimplemove(DetId& cell, 
00405                                   const CaloDirection& dir,
00406                                   const CaloSubdetectorTopology& barrelTopo,
00407                                   const CaloSubdetectorGeometry& barrelGeom)
00408   const {
00409   
00410   std::vector<DetId> neighbours;
00411   
00412   // BARREL CASE 
00413   if(cell.subdetId()==HcalOuter) {
00414     HcalDetId hoDetId = cell;
00415     
00416     neighbours = barrelTopo.getNeighbours(hoDetId,dir);
00417     
00418     // first try to move according to the standard navigation
00419     if(neighbours.size()>0 && !neighbours[0].null()) {
00420       cell = neighbours[0];
00421       return true;
00422     }
00423     
00424     // failed.
00425     
00426     
00427   }
00428   
00429   // everything failed 
00430   cell = DetId(0);
00431   return false;
00432 }
00433 
00434 
00435 
00436 bool 
00437 PFRecHitProducerHO::stdmove(DetId& cell, 
00438                             const CaloDirection& dir,
00439                             const CaloSubdetectorTopology& barrelTopo,
00440                             const CaloSubdetectorGeometry& barrelGeom)
00441   
00442   const {
00443   
00444   
00445   bool result; 
00446   
00447   if(dir==NORTH) {
00448     result = stdsimplemove(cell,NORTH, barrelTopo, barrelGeom);
00449     return result;
00450   }
00451   else if(dir==SOUTH) {
00452     result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom);
00453     return result;
00454   }
00455   else if(dir==EAST) {
00456     result = stdsimplemove(cell,EAST, barrelTopo, barrelGeom);
00457     return result;
00458   }
00459   else if(dir==WEST) {
00460     result = stdsimplemove(cell,WEST, barrelTopo, barrelGeom);
00461     return result;
00462   }
00463   
00464   
00465   // One has to try both paths
00466   else if(dir==NORTHEAST)
00467     {
00468       result = stdsimplemove(cell,NORTH, barrelTopo, barrelGeom);
00469       if(result)
00470         return stdsimplemove(cell,EAST, barrelTopo, barrelGeom);
00471       else
00472         {
00473           result = stdsimplemove(cell,EAST, barrelTopo, barrelGeom);
00474           if(result)
00475             return stdsimplemove(cell,NORTH, barrelTopo, barrelGeom);
00476           else
00477             return false; 
00478         }
00479     }
00480   else if(dir==NORTHWEST)
00481     {
00482       result = stdsimplemove(cell,NORTH, barrelTopo, barrelGeom );
00483       if(result)
00484         return stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
00485       else
00486         {
00487           result = stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
00488           if(result)
00489             return stdsimplemove(cell,NORTH, barrelTopo, barrelGeom );
00490           else
00491             return false; 
00492         }
00493     }
00494   else if(dir == SOUTHEAST)
00495     {
00496       result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
00497       if(result)
00498         return stdsimplemove(cell,EAST, barrelTopo, barrelGeom );
00499       else
00500         {
00501           result = stdsimplemove(cell,EAST, barrelTopo, barrelGeom );
00502           if(result)
00503             return stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
00504           else
00505             return false; 
00506         }
00507     }
00508   else if(dir == SOUTHWEST)
00509     {
00510       result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
00511       if(result)
00512         return stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
00513       else
00514         {
00515           result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
00516           if(result)
00517             return stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
00518           else
00519             return false; 
00520         }
00521     }
00522   cell = DetId(0);
00523   return false;
00524 }
00525 
00526 DetId PFRecHitProducerHO::move(DetId cell, 
00527                                const CaloDirection&dir ) const
00528 {  
00529   DetId originalcell = cell; 
00530   if(dir==NONE || cell==DetId(0)) return false;
00531   
00532   // Conversion CaloDirection and index in the table
00533   // CaloDirection :NONE,SOUTH,SOUTHEAST,SOUTHWEST,EAST,WEST, NORTHEAST,NORTHWEST,NORTH
00534   // Table : SOUTHWEST,SOUTH,SOUTHEAST,WEST,EAST,NORTHWEST,NORTH, NORTHEAST
00535   static const int calodirections[9]={-1,1,2,0,4,3,7,5,6};
00536   
00537   assert(neighbourmapcalculated_);
00538   
00539   DetId result = neighboursHO_[HcalDetId(originalcell).hashed_index()-5184][calodirections[dir]];
00540   return result; 
00541 }
00542