CMS 3D CMS Logo

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