CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/RecoEcal/EgammaClusterProducers/src/PreshowerClusterProducer.cc

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