CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/RecoParticleFlow/PFClusterProducer/plugins/PFRecHitProducerECAL.cc

Go to the documentation of this file.
00001 #include "RecoParticleFlow/PFClusterProducer/plugins/PFRecHitProducerECAL.h"
00002 
00003 #include <memory>
00004 
00005 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00006 
00007 #include "DataFormats/EcalRecHit/interface/EcalRecHit.h"
00008 #include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h"
00009 #include "DataFormats/EcalDetId/interface/EcalSubdetector.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/EcalAlgo/interface/EcalEndcapGeometry.h"
00026 #include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h"
00027 #include "Geometry/CaloTopology/interface/EcalEndcapTopology.h"
00028 #include "Geometry/CaloTopology/interface/EcalBarrelTopology.h"
00029 #include "Geometry/CaloTopology/interface/EcalPreshowerTopology.h"
00030 #include "RecoCaloTools/Navigation/interface/CaloNavigator.h"
00031 
00032 
00033 using namespace std;
00034 using namespace edm;
00035 
00036 PFRecHitProducerECAL::PFRecHitProducerECAL(const edm::ParameterSet& iConfig)
00037  : PFRecHitProducer(iConfig) {
00038 
00039   // access to the collections of rechits
00040 
00041   
00042   inputTagEcalRecHitsEB_ = 
00043     iConfig.getParameter<InputTag>("ecalRecHitsEB");
00044 
00045   inputTagEcalRecHitsEE_ = 
00046     iConfig.getParameter<InputTag>("ecalRecHitsEE");
00047   
00048   
00049   crossBarrelEndcapBorder_ =
00050     iConfig.getParameter<bool>("crossBarrelEndcapBorder");
00051 
00052   timingCleaning_ = 
00053     iConfig.getParameter<bool>("timing_Cleaning");
00054 
00055   topologicalCleaning_ = 
00056     iConfig.getParameter<bool>("topological_Cleaning");
00057 
00058   threshCleaningEB_ = 
00059     iConfig.getParameter<double>("thresh_Cleaning_EB");
00060 
00061   threshCleaningEE_ = 
00062     iConfig.getParameter<double>("thresh_Cleaning_EE");
00063 
00064   neighbourmapcalculated_ = false;
00065 }
00066 
00067 
00068 
00069 PFRecHitProducerECAL::~PFRecHitProducerECAL() {}
00070 
00071 
00072 
00073 
00074 
00075 
00076 void 
00077 PFRecHitProducerECAL::createRecHits(vector<reco::PFRecHit>& rechits,
00078                                     vector<reco::PFRecHit>& rechitsCleaned,
00079                                     edm::Event& iEvent, 
00080                                     const edm::EventSetup& iSetup ) {
00081 
00082 
00083 
00084   // this map is necessary to find the rechit neighbours efficiently
00085   //C but I should think about using Florian's hashed index to do this.
00086   //C in which case the map might not be necessary anymore
00087   // 
00088   // the key of this map is detId. 
00089   // the value is the index in the rechits vector
00090   map<unsigned, unsigned > idSortedRecHits;
00091 //   typedef map<unsigned, unsigned >::iterator IDH;
00092 
00093   edm::ESHandle<CaloGeometry> geoHandle;
00094   iSetup.get<CaloGeometryRecord>().get(geoHandle);
00095   
00096   // get the ecalBarrel geometry
00097   const CaloSubdetectorGeometry *ebtmp = 
00098     geoHandle->getSubdetectorGeometry(DetId::Ecal, EcalBarrel);
00099   
00100   const EcalBarrelGeometry* ecalBarrelGeometry = 
00101     dynamic_cast< const EcalBarrelGeometry* > (ebtmp);
00102   assert( ecalBarrelGeometry );
00103 
00104   // get the ecalBarrel topology
00105   EcalBarrelTopology ecalBarrelTopology(geoHandle);
00106 
00107   // get the endcap geometry
00108   const CaloSubdetectorGeometry *eetmp = 
00109     geoHandle->getSubdetectorGeometry(DetId::Ecal, EcalEndcap);
00110 
00111   const EcalEndcapGeometry* ecalEndcapGeometry = 
00112     dynamic_cast< const EcalEndcapGeometry* > (eetmp);
00113   assert( ecalEndcapGeometry );
00114   
00115 
00116   // get the endcap topology
00117   EcalEndcapTopology ecalEndcapTopology(geoHandle);
00118 
00119     
00120   if(!neighbourmapcalculated_)
00121     ecalNeighbArray( *ecalBarrelGeometry,
00122                      ecalBarrelTopology,
00123                      *ecalEndcapGeometry,
00124                      ecalEndcapTopology );
00125 
00126          
00127   // get the ecalBarrel rechits
00128 
00129   edm::Handle<EcalRecHitCollection> rhcHandle;
00130 
00131 
00132   bool found = iEvent.getByLabel(inputTagEcalRecHitsEB_, 
00133                                  rhcHandle);
00134   
00135   if(!found) {
00136 
00137     ostringstream err;
00138     err<<"could not find rechits "<<inputTagEcalRecHitsEB_;
00139     LogError("PFRecHitProducerECAL")<<err.str()<<endl;
00140     
00141     throw cms::Exception( "MissingProduct", err.str());
00142   }
00143   else {
00144     assert( rhcHandle.isValid() );
00145     
00146     // process ecal ecalBarrel rechits
00147     for(unsigned i=0; i<rhcHandle->size(); i++) {
00148       
00149       const EcalRecHit& erh = (*rhcHandle)[i];
00150       const DetId& detid = erh.detid();
00151       double energy = erh.energy();
00152       // uint32_t flag = erh.recoFlag();
00153       double time = erh.time();
00154 
00155       EcalSubdetector esd=(EcalSubdetector)detid.subdetId();
00156       if (esd != 1) continue;
00157 
00158       if(energy < thresh_Barrel_ ) continue;
00159           
00160       // Check and skip the TT recovered rechits
00161       //if ( flag == EcalRecHit::kTowerRecovered ) { 
00162       if ( erh.checkFlag(EcalRecHit::kTowerRecovered) ) { 
00163         // std::cout << "Rechit was recovered with energy " << energy << std::endl;
00164         continue;
00165       }
00166 
00167       // Just clean ECAL Barrel rechits out of time by more than 5 sigma.
00168       // if ( timingCleaning_ && energy > threshCleaning_ && flag == EcalRecHit::kOutOfTime ) { 
00169       if ( ( timingCleaning_ && energy > threshCleaningEB_ && 
00170              erh.checkFlag(EcalRecHit::kOutOfTime) ) ||
00171            ( topologicalCleaning_ && 
00172              ( erh.checkFlag(EcalRecHit::kWeird) || 
00173                erh.checkFlag(EcalRecHit::kDiWeird) ) ) ) { 
00174         reco::PFRecHit *pfrhCleaned = createEcalRecHit(detid, energy,  
00175                                                        PFLayer::ECAL_BARREL,
00176                                                        ecalBarrelGeometry);
00177         if( !pfrhCleaned ) continue; // problem with this rechit. skip it      
00178         pfrhCleaned->setRescale(time);
00179         rechitsCleaned.push_back( *pfrhCleaned );
00180         delete pfrhCleaned;
00181         continue;
00182       } 
00183 
00184       
00185       reco::PFRecHit *pfrh = createEcalRecHit(detid, energy,  
00186                                               PFLayer::ECAL_BARREL,
00187                                               ecalBarrelGeometry);
00188       
00189       if( !pfrh ) continue; // problem with this rechit. skip it
00190       pfrh->setRescale(time);
00191       
00192       rechits.push_back( *pfrh );
00193       delete pfrh;
00194       idSortedRecHits.insert( make_pair(detid.rawId(), rechits.size()-1 ) ); 
00195     }      
00196   }
00197 
00198 
00199 
00200   //C proceed as for the barrel
00201   // process ecal endcap rechits
00202 
00203   found = iEvent.getByLabel(inputTagEcalRecHitsEE_,
00204                             rhcHandle);
00205   
00206   if(!found) {
00207     ostringstream err;
00208     err<<"could not find rechits "<<inputTagEcalRecHitsEE_;
00209     LogError("PFRecHitProducerECAL")<<err.str()<<endl;
00210     
00211     throw cms::Exception( "MissingProduct", err.str());
00212   }
00213   else {
00214     assert( rhcHandle.isValid() );
00215     
00216     for(unsigned i=0; i<rhcHandle->size(); i++) {
00217       
00218       const EcalRecHit& erh = (*rhcHandle)[i];
00219       const DetId& detid = erh.detid();
00220       double energy = erh.energy();
00221       //uint32_t flag = erh.recoFlag();
00222       double time = erh.time();
00223       EcalSubdetector esd=(EcalSubdetector)detid.subdetId();
00224       if (esd != 2) continue;
00225       if(energy < thresh_Endcap_ ) continue;
00226 
00227       // Check and skip the TT recovered rechits
00228       if ( erh.checkFlag(EcalRecHit::kTowerRecovered) ) {
00229       // if ( flag == EcalRecHit::kTowerRecovered ) { 
00230         // std::cout << "Rechit was recovered with energy " << energy << std::endl;
00231         continue;
00232       }
00233       
00234       
00235       // EE cleaning
00236     
00237       if ( ( timingCleaning_ && energy > threshCleaningEE_ && 
00238              erh.checkFlag(EcalRecHit::kOutOfTime) ) ||
00239            ( topologicalCleaning_ && 
00240              ( erh.checkFlag(EcalRecHit::kWeird) ) ) ) { 
00241         reco::PFRecHit *pfrhCleaned = createEcalRecHit(detid, energy,  
00242                                                        PFLayer::ECAL_ENDCAP,
00243                                                        ecalEndcapGeometry);
00244         if( !pfrhCleaned ) continue; // problem with this rechit. skip it      
00245         pfrhCleaned->setRescale(time);
00246         rechitsCleaned.push_back( *pfrhCleaned );
00247         delete pfrhCleaned;
00248         continue;
00249       } 
00250       
00251 
00252 
00253 
00254       reco::PFRecHit *pfrh = createEcalRecHit(detid, energy,
00255                                               PFLayer::ECAL_ENDCAP,
00256                                               ecalEndcapGeometry);
00257       if( !pfrh ) continue; // problem with this rechit. skip it
00258       pfrh->setRescale(time);
00259 
00260       rechits.push_back( *pfrh );
00261       delete pfrh;
00262       idSortedRecHits.insert( make_pair(detid.rawId(), rechits.size()-1 ) ); 
00263     }
00264   }
00265 
00266 
00267   // do navigation
00268   for(unsigned i=0; i<rechits.size(); i++ ) {
00269     
00270 //     findRecHitNeighbours( rechits[i], idSortedRecHits, 
00271 //                        ecalBarrelTopology, 
00272 //                        *ecalBarrelGeometry, 
00273 //                        ecalEndcapTopology,
00274 //                        *ecalEndcapGeometry);
00275     findRecHitNeighboursECAL( rechits[i], idSortedRecHits ); 
00276                               
00277   }
00278 } 
00279 
00280   
00281 
00282 
00283 reco::PFRecHit* 
00284 PFRecHitProducerECAL::createEcalRecHit( const DetId& detid,
00285                                         double energy,
00286                                         PFLayer::Layer layer,
00287                                         const CaloSubdetectorGeometry* geom ) {
00288 
00289   math::XYZVector position;
00290   math::XYZVector axis;
00291 
00292   const CaloCellGeometry *thisCell 
00293     = geom->getGeometry(detid);
00294   
00295   // find rechit geometry
00296   if(!thisCell) {
00297     LogError("PFRecHitProducerECAL")
00298       <<"warning detid "<<detid.rawId()
00299       <<" not found in geometry"<<endl;
00300     return 0;
00301   }
00302   
00303   position.SetCoordinates ( thisCell->getPosition().x(),
00304                             thisCell->getPosition().y(),
00305                             thisCell->getPosition().z() );
00306 
00307   
00308   
00309   // the axis vector is the difference 
00310   const TruncatedPyramid* pyr 
00311     = dynamic_cast< const TruncatedPyramid* > (thisCell);    
00312   if( pyr ) {
00313     axis.SetCoordinates( pyr->getPosition(1).x(), 
00314                          pyr->getPosition(1).y(), 
00315                          pyr->getPosition(1).z() ); 
00316     
00317     math::XYZVector axis0( pyr->getPosition(0).x(), 
00318                            pyr->getPosition(0).y(), 
00319                            pyr->getPosition(0).z() );
00320     
00321     axis -= axis0;    
00322   }
00323   else return 0;
00324 
00325 //   if( !geomfound ) {
00326 //     LogError("PFRecHitProducerECAL")<<"cannor find geometry for detid "
00327 //                               <<detid.rawId()<<" in layer "<<layer<<endl;
00328 //     return 0; // geometry not found, skip rechit
00329 //   }
00330   
00331   
00332   reco::PFRecHit *rh 
00333     = new reco::PFRecHit( detid.rawId(), layer, 
00334                           energy, 
00335                           position.x(), position.y(), position.z(), 
00336                           axis.x(), axis.y(), axis.z() ); 
00337 
00338 
00339   const CaloCellGeometry::CornersVec& corners = thisCell->getCorners();
00340   assert( corners.size() == 8 );
00341 
00342   rh->setNECorner( corners[0].x(), corners[0].y(),  corners[0].z() );
00343   rh->setSECorner( corners[1].x(), corners[1].y(),  corners[1].z() );
00344   rh->setSWCorner( corners[2].x(), corners[2].y(),  corners[2].z() );
00345   rh->setNWCorner( corners[3].x(), corners[3].y(),  corners[3].z() );
00346 
00347   return rh;
00348 }
00349 
00350 
00351 
00352 
00353 bool
00354 PFRecHitProducerECAL::findEcalRecHitGeometry(const DetId& detid, 
00355                                           const CaloSubdetectorGeometry* geom,
00356                                           math::XYZVector& position, 
00357                                           math::XYZVector& axis ) {
00358   
00359 
00360   const CaloCellGeometry *thisCell 
00361     = geom->getGeometry(detid);
00362   
00363   // find rechit geometry
00364   if(!thisCell) {
00365     LogError("PFRecHitProducerECAL")
00366       <<"warning detid "<<detid.rawId()
00367       <<" not found in geometry"<<endl;
00368     return false;
00369   }
00370   
00371   position.SetCoordinates ( thisCell->getPosition().x(),
00372                             thisCell->getPosition().y(),
00373                             thisCell->getPosition().z() );
00374 
00375   
00376   
00377   // the axis vector is the difference 
00378   const TruncatedPyramid* pyr 
00379     = dynamic_cast< const TruncatedPyramid* > (thisCell);    
00380   if( pyr ) {
00381     axis.SetCoordinates( pyr->getPosition(1).x(), 
00382                          pyr->getPosition(1).y(), 
00383                          pyr->getPosition(1).z() ); 
00384     
00385     math::XYZVector axis0( pyr->getPosition(0).x(), 
00386                            pyr->getPosition(0).y(), 
00387                            pyr->getPosition(0).z() );
00388     
00389     axis -= axis0;
00390 
00391     
00392     return true;
00393   }
00394   else return false;
00395 }
00396 
00397 
00398 
00399 void 
00400 PFRecHitProducerECAL::findRecHitNeighboursECAL
00401 ( reco::PFRecHit& rh, 
00402   const map<unsigned,unsigned >& sortedHits ) {
00403   
00404   DetId center( rh.detId() );
00405 
00406 
00407   DetId north = move( center, NORTH );
00408   DetId northeast = move( center, NORTHEAST );
00409   DetId northwest = move( center, NORTHWEST ); 
00410   DetId south = move( center, SOUTH );  
00411   DetId southeast = move( center, SOUTHEAST );  
00412   DetId southwest = move( center, SOUTHWEST );  
00413   DetId east  = move( center, EAST );  
00414   DetId west  = move( center, WEST );  
00415     
00416   IDH i = sortedHits.find( north.rawId() );
00417   if(i != sortedHits.end() ) 
00418     rh.add4Neighbour( i->second );
00419   
00420   i = sortedHits.find( northeast.rawId() );
00421   if(i != sortedHits.end() ) 
00422     rh.add8Neighbour( i->second );
00423   
00424   i = sortedHits.find( south.rawId() );
00425   if(i != sortedHits.end() ) 
00426     rh.add4Neighbour( i->second );
00427     
00428   i = sortedHits.find( southwest.rawId() );
00429   if(i != sortedHits.end() ) 
00430     rh.add8Neighbour( i->second );
00431     
00432   i = sortedHits.find( east.rawId() );
00433   if(i != sortedHits.end() ) 
00434     rh.add4Neighbour( i->second );
00435     
00436   i = sortedHits.find( southeast.rawId() );
00437   if(i != sortedHits.end() ) 
00438     rh.add8Neighbour( i->second );
00439     
00440   i = sortedHits.find( west.rawId() );
00441   if(i != sortedHits.end() ) 
00442      rh.add4Neighbour( i->second );
00443    
00444   i = sortedHits.find( northwest.rawId() );
00445   if(i != sortedHits.end() ) 
00446     rh.add8Neighbour( i->second );
00447 }
00448 
00449 
00450 
00451 
00452 // Build the array of (max)8 neighbors
00453 void 
00454 PFRecHitProducerECAL::ecalNeighbArray(
00455                               const EcalBarrelGeometry& barrelGeom,
00456                               const CaloSubdetectorTopology& barrelTopo,
00457                               const EcalEndcapGeometry& endcapGeom,
00458                               const CaloSubdetectorTopology& endcapTopo ){
00459   
00460 
00461   static const CaloDirection orderedDir[8]={SOUTHWEST,
00462                                             SOUTH,
00463                                             SOUTHEAST,
00464                                             WEST,
00465                                             EAST,
00466                                             NORTHWEST,
00467                                             NORTH,
00468                                             NORTHEAST};
00469 
00470   const unsigned nbarrel = 62000;
00471   // Barrel first. The hashed index runs from 0 to 61199
00472   neighboursEB_.resize(nbarrel);
00473   
00474   //std::cout << " Building the array of neighbours (barrel) " ;
00475 
00476   const std::vector<DetId>& vec(barrelGeom.getValidDetIds(DetId::Ecal,
00477                                                           EcalBarrel));
00478   unsigned size=vec.size();    
00479   for(unsigned ic=0; ic<size; ++ic) 
00480     {
00481       // We get the 9 cells in a square. 
00482       std::vector<DetId> neighbours(barrelTopo.getWindow(vec[ic],3,3));
00483       //      std::cout << " Cell " << EBDetId(vec[ic]) << std::endl;
00484       unsigned nneighbours=neighbours.size();
00485 
00486       unsigned hashedindex=EBDetId(vec[ic]).hashedIndex();
00487       if(hashedindex>=nbarrel)
00488         {
00489           LogDebug("CaloGeometryTools")  << " Array overflow " << std::endl;
00490         }
00491 
00492 
00493       // If there are 9 cells, it is easy, and this order is know:
00494 //      6  7  8
00495 //      3  4  5 
00496 //      0  1  2   (0 = SOUTHWEST)
00497 
00498       if(nneighbours==9)
00499         {
00500           neighboursEB_[hashedindex].reserve(8);
00501           for(unsigned in=0;in<nneighbours;++in)
00502             {
00503               // remove the centre
00504               if(neighbours[in]!=vec[ic]) 
00505                 {
00506                   neighboursEB_[hashedindex].push_back(neighbours[in]);
00507                   //          std::cout << " Neighbour " << in << " " << EBDetId(neighbours[in]) << std::endl;
00508                 }
00509             }
00510         }
00511       else
00512         {
00513           DetId central(vec[ic]);
00514           neighboursEB_[hashedindex].resize(8,DetId(0));
00515           for(unsigned idir=0;idir<8;++idir)
00516             {
00517               DetId testid=central;
00518               bool status=stdmove(testid,orderedDir[idir],
00519                                   barrelTopo, endcapTopo,
00520                                   barrelGeom, endcapGeom);
00521               if(status) neighboursEB_[hashedindex][idir]=testid;
00522             }
00523 
00524         }
00525     }
00526 
00527   // Moved to the endcap
00528 
00529   //  std::cout << " done " << size << std::endl;
00530   //  std::cout << " Building the array of neighbours (endcap) " ;
00531 
00532 //  vec.clear();
00533   const std::vector<DetId>& vecee=endcapGeom.getValidDetIds(DetId::Ecal,EcalEndcap);
00534   size=vecee.size();    
00535   // There are some holes in the hashedIndex for the EE. Hence the array is bigger than the number
00536   // of crystals
00537   const unsigned nendcap=19960;
00538 
00539   neighboursEE_.resize(nendcap);
00540   for(unsigned ic=0; ic<size; ++ic) 
00541     {
00542       // We get the 9 cells in a square. 
00543       std::vector<DetId> neighbours(endcapTopo.getWindow(vecee[ic],3,3));
00544       unsigned nneighbours=neighbours.size();
00545       // remove the centre
00546       unsigned hashedindex=EEDetId(vecee[ic]).hashedIndex();
00547       
00548       if(hashedindex>=nendcap)
00549         {
00550           LogDebug("CaloGeometryTools")  << " Array overflow " << std::endl;
00551         }
00552 
00553       if(nneighbours==9)
00554         {
00555           neighboursEE_[hashedindex].reserve(8);
00556           for(unsigned in=0;in<nneighbours;++in)
00557             {     
00558               // remove the centre
00559               if(neighbours[in]!=vecee[ic]) 
00560                 {
00561                   neighboursEE_[hashedindex].push_back(neighbours[in]);
00562                 }
00563             }
00564         }
00565       else
00566         {
00567           DetId central(vecee[ic]);
00568           neighboursEE_[hashedindex].resize(8,DetId(0));
00569           for(unsigned idir=0;idir<8;++idir)
00570             {
00571               DetId testid=central;
00572               bool status=stdmove(testid,orderedDir[idir],
00573                                   barrelTopo, endcapTopo,
00574                                   barrelGeom, endcapGeom);
00575 
00576               if(status) neighboursEE_[hashedindex][idir]=testid;
00577             }
00578 
00579         }
00580     }
00581   //  std::cout << " done " << size <<std::endl;
00582   neighbourmapcalculated_ = true;
00583 }
00584 
00585 
00586 
00587 bool 
00588 PFRecHitProducerECAL::stdsimplemove(DetId& cell, 
00589                                     const CaloDirection& dir,
00590                                     const CaloSubdetectorTopology& barrelTopo,
00591                                     const CaloSubdetectorTopology& endcapTopo,
00592                                     const EcalBarrelGeometry& barrelGeom,
00593                                     const EcalEndcapGeometry& endcapGeom ) 
00594   const {
00595 
00596   std::vector<DetId> neighbours;
00597 
00598   // BARREL CASE 
00599   if(cell.subdetId()==EcalBarrel) {
00600     EBDetId ebDetId = cell;
00601 
00602     neighbours = barrelTopo.getNeighbours(ebDetId,dir);
00603 
00604     // first try to move according to the standard navigation
00605     if(neighbours.size()>0 && !neighbours[0].null()) {
00606       cell = neighbours[0];
00607       return true;
00608     }
00609 
00610     // failed.
00611 
00612     if(crossBarrelEndcapBorder_) {
00613       // are we on the outer ring ?
00614       const int ietaAbs ( ebDetId.ietaAbs() ) ; // abs value of ieta
00615       if( EBDetId::MAX_IETA == ietaAbs ) {
00616         // get ee nbrs for for end of barrel crystals  
00617         
00618         // yes we are
00619         const EcalBarrelGeometry::OrderedListOfEEDetId& 
00620           ol( * barrelGeom.getClosestEndcapCells( ebDetId ) ) ;
00621         
00622         // take closest neighbour on the other side, that is in the barrel.
00623         cell = *(ol.begin() );
00624         return true;
00625       }   
00626     }
00627   }
00628 
00629   // ENDCAP CASE 
00630   else if(cell.subdetId()==EcalEndcap) {
00631 
00632     EEDetId eeDetId = cell;
00633 
00634     neighbours= endcapTopo.getNeighbours(eeDetId,dir);
00635 
00636     if(neighbours.size()>0 && !neighbours[0].null()) {
00637       cell = neighbours[0];
00638       return true;
00639     }
00640 
00641     // failed.
00642 
00643     if(crossBarrelEndcapBorder_) {
00644       // are we on the outer ring ?
00645       const int iphi ( eeDetId.iPhiOuterRing() ) ;    
00646       if( iphi!= 0) {
00647         // yes we are
00648         const EcalEndcapGeometry::OrderedListOfEBDetId& 
00649           ol( * endcapGeom.getClosestBarrelCells( eeDetId ) ) ;
00650         
00651         // take closest neighbour on the other side, that is in the barrel.
00652         cell = *(ol.begin() );
00653         return true;
00654       }   
00655     }
00656   } 
00657 
00658   // everything failed 
00659   cell = DetId(0);
00660   return false;
00661 }
00662 
00663 
00664 
00665 bool 
00666 PFRecHitProducerECAL::stdmove(DetId& cell, 
00667                               const CaloDirection& dir,
00668                               const CaloSubdetectorTopology& barrelTopo,
00669                               const CaloSubdetectorTopology& endcapTopo,
00670                               const EcalBarrelGeometry& barrelGeom,
00671                               const EcalEndcapGeometry& endcapGeom  ) 
00672   
00673   const {
00674 
00675 
00676   bool result; 
00677 
00678   if(dir==NORTH) {
00679     result = stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00680     return result;
00681   }
00682   else if(dir==SOUTH) {
00683     result = stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00684     return result;
00685   }
00686   else if(dir==EAST) {
00687     result = stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00688     return result;
00689   }
00690   else if(dir==WEST) {
00691     result = stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00692     return result;
00693   }
00694 
00695 
00696   // One has to try both paths
00697   else if(dir==NORTHEAST)
00698     {
00699       result = stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00700       if(result)
00701         return stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00702       else
00703         {
00704           result = stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00705           if(result)
00706             return stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00707           else
00708             return false; 
00709         }
00710     }
00711   else if(dir==NORTHWEST)
00712     {
00713       result = stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00714       if(result)
00715         return stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00716       else
00717         {
00718           result = stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00719           if(result)
00720             return stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00721           else
00722             return false; 
00723         }
00724     }
00725   else if(dir == SOUTHEAST)
00726     {
00727       result = stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00728       if(result)
00729         return stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00730       else
00731         {
00732           result = stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00733           if(result)
00734             return stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00735           else
00736             return false; 
00737         }
00738     }
00739   else if(dir == SOUTHWEST)
00740     {
00741       result = stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00742       if(result)
00743         return stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00744       else
00745         {
00746           result = stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00747           if(result)
00748             return stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
00749           else
00750             return false; 
00751         }
00752     }
00753   cell = DetId(0);
00754   return false;
00755 }
00756 
00757 
00758 
00759 DetId PFRecHitProducerECAL::move(DetId cell, 
00760                               const CaloDirection&dir ) const
00761 {  
00762   DetId originalcell = cell; 
00763   if(dir==NONE || cell==DetId(0)) return false;
00764 
00765   // Conversion CaloDirection and index in the table
00766   // CaloDirection :NONE,SOUTH,SOUTHEAST,SOUTHWEST,EAST,WEST, NORTHEAST,NORTHWEST,NORTH
00767   // Table : SOUTHWEST,SOUTH,SOUTHEAST,WEST,EAST,NORTHWEST,NORTH, NORTHEAST
00768   static const int calodirections[9]={-1,1,2,0,4,3,7,5,6};
00769     
00770   assert(neighbourmapcalculated_);
00771 
00772   DetId result = (originalcell.subdetId()==EcalBarrel) ? 
00773     neighboursEB_[EBDetId(originalcell).hashedIndex()][calodirections[dir]]:
00774     neighboursEE_[EEDetId(originalcell).hashedIndex()][calodirections[dir]];
00775   return result; 
00776 }
00777