CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoEcal/EgammaClusterProducers/src/PreshowerPhiClusterProducer.cc

Go to the documentation of this file.
00001 #include <vector>
00002 #include <memory>
00003 
00004 #include "FWCore/Framework/interface/Frameworkfwd.h"
00005 #include "FWCore/Framework/interface/EDAnalyzer.h"
00006 #include "FWCore/Framework/interface/Event.h"
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008 #include "FWCore/Framework/interface/ESHandle.h"
00009 #include "FWCore/Framework/interface/MakerMacros.h"
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include "FWCore/Utilities/interface/Exception.h"
00012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00013 #include "DataFormats/Common/interface/Handle.h"
00014 #include "DataFormats/EcalRecHit/interface/EcalRecHit.h"
00015 #include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h"
00016 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00017 #include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
00018 #include "DataFormats/EgammaReco/interface/PreshowerClusterFwd.h"
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/EcalAlgo/interface/EcalPreshowerGeometry.h"
00024 #include "Geometry/CaloTopology/interface/EcalPreshowerTopology.h"
00025 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00026 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00027 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00028 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00029 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00030 #include "DataFormats/EcalDetId/interface/ESDetId.h"
00031 #include "CondFormats/DataRecord/interface/ESGainRcd.h"
00032 #include "CondFormats/DataRecord/interface/ESMIPToGeVConstantRcd.h"
00033 #include "CondFormats/DataRecord/interface/ESEEIntercalibConstantsRcd.h"
00034 #include "CondFormats/DataRecord/interface/ESMissingEnergyCalibrationRcd.h"
00035 #include "CondFormats/DataRecord/interface/ESChannelStatusRcd.h"
00036 #include "DataFormats/Math/interface/deltaPhi.h"
00037 #include <fstream>
00038 
00039 #include "RecoEcal/EgammaClusterProducers/interface/PreshowerPhiClusterProducer.h"
00040 
00041 using namespace edm;
00042 using namespace std;
00043 
00044 PreshowerPhiClusterProducer::PreshowerPhiClusterProducer(const edm::ParameterSet& ps) {
00045 
00046   // use configuration file to setup input/output collection names 
00047   preshHitProducer_   = ps.getParameter<edm::InputTag>("preshRecHitProducer");
00048   
00049   // Name of a SuperClusterCollection to make associations:
00050   endcapSClusterProducer_   = ps.getParameter<edm::InputTag>("endcapSClusterProducer");
00051   
00052   // Output collections:
00053   preshClusterCollectionX_ = ps.getParameter<std::string>("preshClusterCollectionX");
00054   preshClusterCollectionY_ = ps.getParameter<std::string>("preshClusterCollectionY");
00055   
00056   assocSClusterCollection_ = ps.getParameter<std::string>("assocSClusterCollection");
00057   
00058   produces< reco::PreshowerClusterCollection >(preshClusterCollectionX_);
00059   produces< reco::PreshowerClusterCollection >(preshClusterCollectionY_);
00060   produces< reco::SuperClusterCollection >(assocSClusterCollection_);
00061   
00062   float esStripECut          = ps.getParameter<double>("esStripEnergyCut");
00063   esPhiClusterDeltaEta_      = ps.getParameter<double>("esPhiClusterDeltaEta");
00064   esPhiClusterDeltaPhi_      = ps.getParameter<double>("esPhiClusterDeltaPhi");
00065 
00066   presh_algo = new PreshowerPhiClusterAlgo(esStripECut);
00067 }
00068 
00069 PreshowerPhiClusterProducer::~PreshowerPhiClusterProducer() {
00070   delete presh_algo;
00071 }
00072 
00073 void PreshowerPhiClusterProducer::produce(edm::Event& evt, const edm::EventSetup& es) {
00074   
00075   edm::Handle< EcalRecHitCollection >   pRecHits;
00076   edm::Handle< reco::SuperClusterCollection > pSuperClusters;
00077   
00078   // get the ECAL geometry:
00079   edm::ESHandle<CaloGeometry> geoHandle;
00080   es.get<CaloGeometryRecord>().get(geoHandle);
00081   
00082   // retrieve ES-EE intercalibration constants and channel status
00083   set(es);
00084   const ESChannelStatus *channelStatus = esChannelStatus_.product();
00085   
00086   const CaloSubdetectorGeometry *geometry = geoHandle->getSubdetectorGeometry(DetId::Ecal, EcalPreshower);
00087   const CaloSubdetectorGeometry *& geometry_p = geometry;
00088   
00089   // create auto_ptr to a PreshowerClusterCollection
00090   std::auto_ptr< reco::PreshowerClusterCollection > clusters_p1(new reco::PreshowerClusterCollection);
00091   std::auto_ptr< reco::PreshowerClusterCollection > clusters_p2(new reco::PreshowerClusterCollection);
00092   // create new collection of corrected super clusters
00093   std::auto_ptr< reco::SuperClusterCollection > superclusters_p(new reco::SuperClusterCollection);
00094   
00095   CaloSubdetectorTopology * topology_p=0;
00096   if (geometry)
00097     topology_p  = new EcalPreshowerTopology(geoHandle);
00098   
00099   // fetch the product (pSuperClusters)
00100   evt.getByLabel(endcapSClusterProducer_, pSuperClusters);   
00101   const reco::SuperClusterCollection* SClusts = pSuperClusters.product();
00102   
00103   // fetch the product (RecHits)
00104   evt.getByLabel( preshHitProducer_, pRecHits);
00105   // pointer to the object in the product
00106   const EcalRecHitCollection* rechits = pRecHits.product(); // EcalRecHitCollection hit_collection = *rhcHandle;
00107   
00108   LogTrace("EcalClusters") << "PreshowerPhiClusterProducerInfo: ### Total # of preshower RecHits: "<< rechits->size();
00109   
00110   // make the map of rechits:
00111   std::map<DetId, EcalRecHit> rechits_map;
00112   EcalRecHitCollection::const_iterator it;
00113   for (it = rechits->begin(); it != rechits->end(); it++) {
00114     // remove bad ES rechits
00115     if (it->recoFlag()==1 || it->recoFlag()==14 || (it->recoFlag()<=10 && it->recoFlag()>=5)) continue;
00116     //Make the map of DetID, EcalRecHit pairs
00117     rechits_map.insert(std::make_pair(it->id(), *it));   
00118   }
00119   // The set of used DetID's for a given event:
00120   std::set<DetId> used_strips;
00121   used_strips.clear();
00122   LogTrace("EcalClusters") << "PreshowerPhiClusterProducerInfo: ### rechits_map of size " << rechits_map.size() <<" was created!";
00123   
00124   reco::PreshowerClusterCollection clusters1, clusters2;   // output collection of corrected PCs
00125   reco::SuperClusterCollection new_SC; // output collection of corrected SCs
00126   
00127   //make cycle over super clusters
00128   reco::SuperClusterCollection::const_iterator it_super;
00129   int isc  = 0;
00130   for (it_super=SClusts->begin();  it_super!=SClusts->end(); ++it_super) {     
00131 
00132     float e1     = 0;
00133     float e2     = 0;
00134     float deltaE = 0;
00135 
00136     reco::CaloClusterPtrVector new_BC; 
00137     ++isc;
00138     LogTrace("EcalClusters")<< " superE = " << it_super->energy() << " superETA = " << it_super->eta() << " superPHI = " << it_super->phi() ;
00139     
00140     //cout<<"=== new SC ==="<<endl;
00141     //cout<<"superE = "<<it_super->energy()<<" superETA = "<<it_super->eta()<<" superPHI = "<<it_super->phi()<<endl;
00142 
00143     int nBC = 0;
00144     int condP1 = 1; // 0: dead channel; 1: active channel
00145     int condP2 = 1;
00146     float maxDeltaPhi = 0;
00147     float minDeltaPhi = 0;
00148     float refPhi = 0; 
00149 
00150     reco::CaloCluster_iterator bc_iter = it_super->clustersBegin();
00151     for ( ; bc_iter !=it_super->clustersEnd(); ++bc_iter) {
00152       if (nBC == 0) {
00153         refPhi = (*bc_iter)->phi();
00154       } else {
00155         if (reco::deltaPhi((*bc_iter)->phi(), refPhi) > 0 && reco::deltaPhi((*bc_iter)->phi(), refPhi) > maxDeltaPhi)
00156           maxDeltaPhi = reco::deltaPhi((*bc_iter)->phi(), refPhi);
00157         if (reco::deltaPhi((*bc_iter)->phi(), refPhi) < 0 && reco::deltaPhi((*bc_iter)->phi(), refPhi) < minDeltaPhi)
00158           minDeltaPhi = reco::deltaPhi((*bc_iter)->phi(), refPhi);
00159         //cout<<"delta phi : "<<reco::deltaPhi((*bc_iter)->phi(), refPhi)<<endl;
00160       }
00161       //cout<<"BC : "<<nBC<<" "<<(*bc_iter)->energy()<<" "<<(*bc_iter)->eta()<<" "<<(*bc_iter)->phi()<<endl; 
00162       nBC++;
00163     }
00164     maxDeltaPhi += esPhiClusterDeltaPhi_;
00165     minDeltaPhi -= esPhiClusterDeltaPhi_;
00166 
00167     nBC = 0;
00168     for (bc_iter = it_super->clustersBegin() ; bc_iter !=it_super->clustersEnd(); ++bc_iter) {  
00169       if (geometry) {
00170         
00171         // Get strip position at intersection point of the line EE - Vertex:
00172         double X = (*bc_iter)->x();
00173         double Y = (*bc_iter)->y();
00174         double Z = (*bc_iter)->z();        
00175         const GlobalPoint point(X,Y,Z);    
00176         
00177         DetId tmp1 = (dynamic_cast<const EcalPreshowerGeometry*>(geometry_p))->getClosestCellInPlane(point, 1);
00178         DetId tmp2 = (dynamic_cast<const EcalPreshowerGeometry*>(geometry_p))->getClosestCellInPlane(point, 2);
00179         ESDetId strip1 = (tmp1 == DetId(0)) ? ESDetId(0) : ESDetId(tmp1);
00180         ESDetId strip2 = (tmp2 == DetId(0)) ? ESDetId(0) : ESDetId(tmp2);     
00181 
00182         if (nBC == 0) {
00183           if (strip1 != ESDetId(0) && strip2 != ESDetId(0)) {
00184             ESChannelStatusMap::const_iterator status_p1 = channelStatus->getMap().find(strip1);
00185             ESChannelStatusMap::const_iterator status_p2 = channelStatus->getMap().find(strip2);
00186             if (status_p1->getStatusCode() == 1) condP1 = 0;
00187             if (status_p2->getStatusCode() == 1) condP2 = 0;
00188           } else if (strip1 == ESDetId(0)) {
00189             condP1 = 0;
00190           } else if (strip2 == ESDetId(0)) {
00191             condP2 = 0;
00192           }
00193           
00194           //cout<<"starting cluster : "<<maxDeltaPhi<<" "<<minDeltaPhi<<" "<<esPhiClusterDeltaEta_<<endl;
00195           //cout<<"do plane 1 === "<<strip1.zside()<<" "<<strip1.plane()<<" "<<strip1.six()<<" "<<strip1.siy()<<" "<<strip1.strip()<<endl;
00196           // Get a vector of ES clusters (found by the PreshSeeded algorithm) associated with a given EE basic cluster.           
00197           reco::PreshowerCluster cl1 = presh_algo->makeOneCluster(strip1,&used_strips,&rechits_map,geometry_p,topology_p,esPhiClusterDeltaEta_,minDeltaPhi,maxDeltaPhi);   
00198           cl1.setBCRef(*bc_iter);
00199           clusters1.push_back(cl1);
00200           e1 += cl1.energy();       
00201           
00202           //cout<<"do plane 2 === "<<strip2.zside()<<" "<<strip2.plane()<<" "<<strip2.six()<<" "<<strip2.siy()<<" "<<strip2.strip()<<endl;
00203           reco::PreshowerCluster cl2 = presh_algo->makeOneCluster(strip2,&used_strips,&rechits_map,geometry_p,topology_p,esPhiClusterDeltaEta_,minDeltaPhi,maxDeltaPhi); 
00204           cl2.setBCRef(*bc_iter);
00205           clusters2.push_back(cl2);
00206           e2 += cl2.energy();
00207         }
00208       }
00209 
00210       new_BC.push_back(*bc_iter);
00211       nBC++;
00212     }  // end of cycle over BCs
00213 
00214     LogTrace("EcalClusters") << " For SC #" << isc-1 << ", containing " 
00215                              << it_super->clustersSize()                              
00216                              << " basic clusters, PreshowerPhiClusterAlgo made " 
00217                              << clusters1.size() << " in X plane and " 
00218                              << clusters2.size()       
00219                              << " in Y plane " << " preshower clusters " ;
00220     
00221     // update energy of the SuperCluster    
00222     if(e1+e2 > 1.0e-10) {
00223 
00224       e1 = e1 / mip_; // GeV to #MIPs
00225       e2 = e2 / mip_;
00226       
00227       if (condP1 == 1 && condP2 == 1) {
00228         deltaE = gamma0_*(e1 + alpha0_*e2);       
00229       } else if (condP1 == 1 && condP2 == 0) {
00230         deltaE = gamma1_*(e1 + alpha1_*e2);       
00231       } else if (condP1 == 0 && condP2 == 1) {
00232         deltaE = gamma2_*(e1 + alpha2_*e2);       
00233       } else if (condP1 == 0 && condP2 == 0) {
00234         deltaE = gamma3_*(e1 + alpha3_*e2);       
00235       }
00236     }
00237     
00238     //corrected Energy
00239     float E = it_super->energy() + deltaE;
00240     
00241     LogTrace("EcalClusters") << " Creating corrected SC ";
00242     
00243     reco::SuperCluster sc(E, it_super->position(), it_super->seed(), new_BC, deltaE);
00244     sc.setPreshowerEnergyPlane1(e1*mip_);
00245     sc.setPreshowerEnergyPlane2(e2*mip_);
00246     if (condP1 == 1 && condP2 == 1) sc.setPreshowerPlanesStatus(0);
00247     else if (condP1 == 1 && condP2 == 0) sc.setPreshowerPlanesStatus(1);
00248     else if (condP1 == 0 && condP2 == 1) sc.setPreshowerPlanesStatus(2);
00249     else if (condP1 == 0 && condP2 == 0) sc.setPreshowerPlanesStatus(3);
00250 
00251     new_SC.push_back(sc);
00252     //cout<<"result : "<<sc.energy()<<" "<<it_super->energy()<<" "<<deltaE<<" "<<e1*mip_<<" "<<e2*mip_<<endl;    
00253   } // end of cycle over SCs
00254   
00255   // copy the preshower clusters into collections and put in the Event:
00256   clusters_p1->assign(clusters1.begin(), clusters1.end());
00257   clusters_p2->assign(clusters2.begin(), clusters2.end());
00258   // put collection of preshower clusters to the event
00259   evt.put( clusters_p1, preshClusterCollectionX_ );
00260   evt.put( clusters_p2, preshClusterCollectionY_ );
00261   LogTrace("EcalClusters") << "Preshower clusters added to the event" ;
00262   
00263   // put collection of corrected super clusters to the event
00264   superclusters_p->assign(new_SC.begin(), new_SC.end());
00265   evt.put(superclusters_p, assocSClusterCollection_);
00266   LogTrace("EcalClusters") << "Corrected SClusters added to the event" ;
00267   
00268   if (topology_p) delete topology_p;
00269 }
00270 
00271 void PreshowerPhiClusterProducer::set(const edm::EventSetup& es) {
00272   
00273   es.get<ESGainRcd>().get(esgain_);
00274   const ESGain *gain = esgain_.product();
00275   
00276   double ESGain = gain->getESGain();
00277 
00278   es.get<ESMIPToGeVConstantRcd>().get(esMIPToGeV_);
00279   const ESMIPToGeVConstant *mipToGeV = esMIPToGeV_.product();
00280 
00281   mip_ = (ESGain == 1) ? mipToGeV->getESValueLow() : mipToGeV->getESValueHigh(); 
00282 
00283   es.get<ESChannelStatusRcd>().get(esChannelStatus_);
00284 
00285   es.get<ESEEIntercalibConstantsRcd>().get(esEEInterCalib_);
00286   const ESEEIntercalibConstants *esEEInterCalib = esEEInterCalib_.product();
00287 
00288   // both planes work
00289   gamma0_ = (ESGain == 1) ? esEEInterCalib->getGammaLow0() : esEEInterCalib->getGammaHigh0();
00290   alpha0_ = (ESGain == 1) ? esEEInterCalib->getAlphaLow0() : esEEInterCalib->getAlphaHigh0();
00291 
00292   // only first plane works 
00293   gamma1_ = (ESGain == 1) ? esEEInterCalib->getGammaLow1() : esEEInterCalib->getGammaHigh1();
00294   alpha1_ = (ESGain == 1) ? esEEInterCalib->getAlphaLow1() : esEEInterCalib->getAlphaHigh1();
00295 
00296   // only second plane works
00297   gamma2_ = (ESGain == 1) ? esEEInterCalib->getGammaLow2() : esEEInterCalib->getGammaHigh2();
00298   alpha2_ = (ESGain == 1) ? esEEInterCalib->getAlphaLow2() : esEEInterCalib->getAlphaHigh2();
00299 
00300   // both planes do not work
00301   gamma3_ = (ESGain == 1) ? esEEInterCalib->getGammaLow3() : esEEInterCalib->getGammaHigh3();
00302   alpha3_ = (ESGain == 1) ? esEEInterCalib->getAlphaLow3() : esEEInterCalib->getAlphaHigh3();
00303 
00304   es.get<ESMissingEnergyCalibrationRcd>().get(esMissingECalib_);
00305   const ESMissingEnergyCalibration * esMissingECalib = esMissingECalib_.product();
00306 
00307   // |eta| < 1.9
00308   aEta_[0] = esMissingECalib->getConstAEta0();
00309   bEta_[0] = esMissingECalib->getConstBEta0();
00310 
00311   // 1.9 < |eta| < 2.1
00312   aEta_[1] = esMissingECalib->getConstAEta1();
00313   bEta_[1] = esMissingECalib->getConstBEta1();
00314 
00315   // 2.1 < |eta| < 2.3
00316   aEta_[2] = esMissingECalib->getConstAEta2();
00317   bEta_[2] = esMissingECalib->getConstBEta2();
00318 
00319   // 2.3 < |eta| < 2.5
00320   aEta_[3] = esMissingECalib->getConstAEta3();
00321   bEta_[3] = esMissingECalib->getConstBEta3();
00322 
00323 }