CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoLocalCalo/EcalDeadChannelRecoveryAlgos/src/EcalDeadChannelRecoveryAlgos.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    EcalDeadChannelRecoveryAlgos
00004 // Class:      EcalDeadChannelRecoveryAlgos
00005 // 
00013 //
00014 // Original Author:  Georgios Daskalakis
00015 //         Created:  Thu Apr 12 17:02:06 CEST 2007
00016 // $Id: EcalDeadChannelRecoveryAlgos.cc,v 1.10 2010/08/06 20:24:54 wmtan Exp $
00017 //
00018 // May 4th 2007 S. Beauceron : modification of MakeNxNMatrice in order to use vectors
00019 //
00020 
00021 
00022 
00023 // Geometry
00024 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00025 #include "Geometry/CaloEventSetup/interface/CaloTopologyRecord.h"
00026 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00027 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00028 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00029 #include "Geometry/CaloTopology/interface/EcalEndcapTopology.h"
00030 #include "Geometry/CaloTopology/interface/EcalBarrelTopology.h"
00031 #include "Geometry/CaloTopology/interface/EcalBarrelHardcodedTopology.h"
00032 #include "Geometry/CaloTopology/interface/CaloTopology.h"
00033 #include "Geometry/CaloTopology/interface/CaloSubdetectorTopology.h"
00034 #include "RecoEcal/EgammaCoreTools/interface/PositionCalc.h"
00035 //#include "Geometry/Vector/interface/GlobalPoint.h"
00036 
00037 // Reconstruction Classes
00038 #include "DataFormats/EcalRecHit/interface/EcalRecHit.h"
00039 #include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h"
00040 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00041 
00042 #include "RecoLocalCalo/EcalDeadChannelRecoveryAlgos/interface/EcalDeadChannelRecoveryAlgos.h"
00043 #include "RecoLocalCalo/EcalDeadChannelRecoveryAlgos/interface/CorrectDeadChannelsClassic.cc"
00044 #include "RecoLocalCalo/EcalDeadChannelRecoveryAlgos/interface/CorrectDeadChannelsNN.cc"
00045 
00046 #include <string>
00047 using namespace cms;
00048 using namespace std;
00049 
00050 
00051 EcalDeadChannelRecoveryAlgos::EcalDeadChannelRecoveryAlgos(const CaloTopology  * theCaloTopology)
00052 //EcalDeadChannelRecoveryAlgos::EcalDeadChannelRecoveryAlgos(const edm::ESHandle<CaloTopology> & theCaloTopology)
00053 {
00054   //now do what ever initialization is needed
00055   calotopo = theCaloTopology;
00056 }
00057 
00058 
00059 EcalDeadChannelRecoveryAlgos::~EcalDeadChannelRecoveryAlgos()
00060 {
00061  
00062    // do anything here that needs to be done at desctruction time
00063    // (e.g. close files, deallocate resources etc.)
00064 
00065 }
00066 
00067 
00068 //
00069 // member functions
00070 //
00071 
00072 // ------------ method called to for each event  ------------
00073 EcalRecHit EcalDeadChannelRecoveryAlgos::correct(const EBDetId Id, const EcalRecHitCollection* hit_collection, std::string algo_, double Sum8Cut)
00074 {
00075   double NewEnergy=0.0;
00076   
00077   double MNxN[121];
00078   int IndDeadChannel[1]={-1};
00079 
00080   double sum8 = MakeNxNMatrice(Id,hit_collection,IndDeadChannel,MNxN);
00081 
00082   if(algo_=="Spline"){
00083      
00084     if(sum8>Sum8Cut){
00085       if(IndDeadChannel[0]>0)NewEnergy = CorrectDeadChannelsClassic(MNxN,Id.ieta());
00086     }
00087   }else if(algo_=="NeuralNetworks"){
00088     if(sum8>Sum8Cut){
00089       if(IndDeadChannel[0]>0)NewEnergy = CorrectDeadChannelsNN(MNxN);
00090     }
00091   }
00092   
00093   // protect against non physical high values
00094   // < sum(energy in neighbours) > = 0.8 * xtal with maximum energy
00095   // => can choose 5 as highest possible energy to be assigned to 
00096   //    the dead channel
00097   uint32_t flag = 0;
00098   if ( NewEnergy > 5. * sum8 ) {
00099           NewEnergy = 0;
00100           //flag = EcalRecHit::kDead;
00101   }
00102 
00103   EcalRecHit NewHit(Id,NewEnergy,0, flag);
00104   return NewHit;
00105 
00106 }
00107 
00108 // FIXME -- temporary backward compatibility
00109 EcalRecHit EcalDeadChannelRecoveryAlgos::Correct(const EBDetId Id, const EcalRecHitCollection* hit_collection, std::string algo_, double Sum8Cut)
00110 {
00111         return correct(Id, hit_collection, algo_, Sum8Cut);
00112 }
00113 
00114 //==============================================================================================================
00115 //==============================================================================================================
00116 //==============================================================================================================
00117 //==============================================================================================================
00118 
00119 
00120 
00121 double EcalDeadChannelRecoveryAlgos::MakeNxNMatrice(EBDetId itID,const EcalRecHitCollection* hit_collection, int *IndDeadChannel, double *MNxN){
00122 
00123   //  std::cout<<" In MakeNxNMatrice "<<std::endl;
00124 
00125   //Build NxN around a given cristal
00126   for(int i=0; i<121;i++)MNxN[i]=0.0;
00127   
00128 //   std::cout<<"===================================================================="<<std::endl;
00129 //   std::cout<<" Dead Cell CENTRAL  eta = "<< itID.ieta()<<" ,  phi = "<< itID.iphi()<<std::endl;
00130 
00131   const CaloSubdetectorTopology* topology=calotopo->getSubdetectorTopology(DetId::Ecal,EcalBarrel);
00132   int size =5;
00133   std::vector<DetId> NxNaroundDC = topology->getWindow(itID,size,size);
00134   //  std::cout<<"===================================================================="<<std::endl;
00135   
00136   
00137   //  std::cout<<"NxNaroundDC size is = "<<NxNaroundDC.size()<<std::endl;
00138   std::vector<DetId>::const_iterator theCells;
00139   
00140   EBDetId EBCellMax = itID;
00141   double EnergyMax = 0.0;
00142 
00143   for(theCells=NxNaroundDC.begin();theCells<NxNaroundDC.end();theCells++){
00144     EBDetId EBCell = EBDetId(*theCells);
00145       
00146     // We Will look for the cristal with maximum energy 
00147     if(!EBCell.null()){
00148       EcalRecHitCollection::const_iterator goS_it = hit_collection->find(EBCell);
00149       if( goS_it !=  hit_collection->end() && goS_it->energy()>=EnergyMax){EnergyMax=goS_it->energy(); EBCellMax = EBCell;}
00150     }else{
00151       continue; 
00152     }
00153   } 
00154   if(EBCellMax.null()){/*cout<<" Error No maximum found around dead channel, no corrections applied"<<std::endl;*/return 0;}
00155   //  std::cout << " Max Cont Crystal eta phi E = " << EBCellMax.ieta() <<" "<< EBCellMax.iphi() <<" "<< EnergyMax<<std::endl;
00156 
00157 
00158   
00159   //NxNaroundMaxCont with N==11
00160   // 000 is now the maximum containement one:
00162   //Any modification of the following parameters will require changes in the Correction algos
00163   // The window is large enought to avoid modification of the number.
00164   int FixedSize =11;
00165   std::vector<DetId> NxNaroundMaxCont = topology->getWindow(EBCellMax,FixedSize,FixedSize);
00166 
00167   double ESUMis=0.0;
00168   int theIndex=0;
00169 
00170   std::vector<DetId>::const_iterator itCells;
00171   for(itCells=NxNaroundMaxCont.begin();itCells<NxNaroundMaxCont.end();itCells++){
00172     EBDetId EBitCell = EBDetId(*itCells);
00173     int CReta = EBitCell.ieta();
00174     int CRphi = EBitCell.iphi();
00175 
00176     double Energy = 0.0;
00177     if(!EBitCell.null()){
00178       EcalRecHitCollection::const_iterator goS_it = hit_collection->find(EBitCell);
00179       if( goS_it !=  hit_collection->end() ) Energy=goS_it->energy();
00180     }
00181 
00182     //    std::cout<<"Around DC we have eta,phi,E "<<CReta<<" "<<CRphi<<" "<<Energy<<std::endl;
00183 
00184     //============
00185     int ietaCorr = 0;
00186     if((CReta * EBCellMax.ieta()) < 0 && EBCellMax.ieta()>0 )ietaCorr= -1;
00187     if((CReta * EBCellMax.ieta()) < 0 && EBCellMax.ieta()<0 )ietaCorr=  1;
00188     if((CReta * EBCellMax.ieta()) > 0 )ietaCorr= 0;
00189     int ieta = -( (CReta -ietaCorr) - EBCellMax.ieta() ) + int((FixedSize - 1)/2);
00190 
00191     int iphiCorr = 0;
00192     if((CRphi - EBCellMax.iphi())> 50)iphiCorr= 360;
00193     if((CRphi - EBCellMax.iphi())<-50)iphiCorr=-360;
00194     int iphi = CRphi - EBCellMax.iphi() - iphiCorr + int((FixedSize - 1)/2);
00195 
00196     int MIndex = ieta+iphi*FixedSize;
00197     if(abs(CReta)<=85)
00198     MNxN[MIndex]=Energy;
00199     if(EBitCell == itID)IndDeadChannel[0]= MIndex;
00200 
00201     
00202     //============
00203 
00204 
00205 
00206     
00207     //We add up the energy in 5x5 around the MaxCont to decide if we will correct for DCs
00208     //  if(theIndex>=36 && theIndex<=40)ESUMis +=  Energy;
00209     //SB: Modify to sum8 only
00210     if(theIndex>=48 && theIndex<=50)ESUMis +=  Energy;
00211     if(theIndex>=59 && theIndex<=61)ESUMis +=  Energy;
00212     if(theIndex>=70 && theIndex<=72)ESUMis +=  Energy;
00213     //    if(theIndex>=80 && theIndex<=84)ESUMis +=  Energy;
00214     theIndex++;
00215   }
00216   //  std::cout<<"Around MaxCont Collected Energy in 5x5 is =  "<< ESUMis  <<std::endl;
00217   //So now, we have a vector which is ordered around the Maximum containement and which contains a dead channel as:
00218     //Filling of the vector : NxNaroundDC with N==11 Typo are possible...
00219     // 000 is Maximum containement which is in +/- 5 from DC
00220     //
00221     // 120 119 118 117 116 115 114 113 112 111 110  
00222     // 109 108 107 106 105 104 103 102 101 100 099 
00223     // 098 097 096 095 094 093 092 091 090 089 088
00224     // 087 086 085 084 083 082 081 080 079 078 077
00225     // 076 075 074 073 072 071 070 069 068 067 066
00226     // 065 064 063 062 061 060 059 058 057 056 055
00227     // 054 053 052 051 050 049 048 047 046 045 044
00228     // 043 042 041 040 039 038 037 036 035 034 033
00229     // 032 031 030 029 028 027 026 025 024 023 022
00230     // 021 020 019 018 017 016 015 014 013 012 011
00231     // 010 009 008 007 006 005 004 003 002 001 000
00233   
00234 
00235   
00236   //================
00237 
00238   return ESUMis;
00239 }
00240