CMS 3D CMS Logo

EcalEndcapRecHitsMaker.cc

Go to the documentation of this file.
00001 #include "FastSimulation/CaloRecHitsProducer/interface/EcalEndcapRecHitsMaker.h"
00002 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h"
00003 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00004 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00005 
00006 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"        
00007 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
00008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00009 #include "DataFormats/Common/interface/Handle.h"
00010 #include "FWCore/Framework/interface/ESHandle.h"
00011 #include "FWCore/Framework/interface/Event.h"
00012 #include "FWCore/Framework/interface/EventSetup.h"
00013 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00014 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00015 #include "Geometry/EcalAlgo/interface/EcalEndcapGeometry.h"
00016 #include "CondFormats/EcalObjects/interface/EcalIntercalibConstants.h"
00017 #include "CondFormats/DataRecord/interface/EcalIntercalibConstantsRcd.h"
00018 
00019 
00020 EcalEndcapRecHitsMaker::EcalEndcapRecHitsMaker(edm::ParameterSet const & p, 
00021                                                edm::ParameterSet const & pcalib,
00022                                                const RandomEngine * myrandom) 
00023   : random_(myrandom)
00024 {
00025   edm::ParameterSet RecHitsParameters = p.getParameter<edm::ParameterSet>("ECALEndcap");
00026   inputCol_=RecHitsParameters.getParameter<edm::InputTag>("MixedSimHits");
00027   noise_ = RecHitsParameters.getParameter<double>("Noise");
00028   threshold_ = RecHitsParameters.getParameter<double>("Threshold");
00029   refactor_ = RecHitsParameters.getParameter<double> ("Refactor");
00030   refactor_mean_ = RecHitsParameters.getParameter<double> ("Refactor_mean");
00031   theCalorimeterHits_.resize(20000,0.);
00032   noisified_ = (noise_==0.);
00033   double c1 = pcalib.getParameter<double>("EEs25notContainment");
00034   calibfactor_= 1./c1;
00035 
00036   adcToGeV_= 0.060;
00037   minAdc_ = 200;
00038   maxAdc_ = 4085;
00039   
00040   geVToAdc1_ = 1./adcToGeV_;
00041   geVToAdc2_ = geVToAdc1_/2.;
00042   geVToAdc3_ = geVToAdc1_/12.;
00043   
00044   t1_ = ((int)maxAdc_-(int)minAdc_)*adcToGeV_;
00045   t2_ = 2.* t1_ ; 
00046 
00047   sat_ = 12.*t1_*calibfactor_;
00048 }
00049   
00050 
00051 EcalEndcapRecHitsMaker::~EcalEndcapRecHitsMaker()
00052 {;
00053 }
00054 
00055 void EcalEndcapRecHitsMaker::clean()
00056 {
00057 
00058   unsigned size=theFiredCells_.size();
00059   for(unsigned ic=0;ic<size;++ic)
00060     {
00061       theCalorimeterHits_[theFiredCells_[ic]] = 0.;
00062     }
00063   theFiredCells_.clear();
00064   // If the noise is set to 0. No need to simulate it. 
00065   noisified_ = (noise_==0.);
00066 }
00067 
00068 
00069 void EcalEndcapRecHitsMaker::loadEcalEndcapRecHits(edm::Event &iEvent,EERecHitCollection & ecalHits,EEDigiCollection & ecalDigis)
00070 {
00071   clean();
00072   loadPCaloHits(iEvent);
00073 
00074   unsigned nhit=theFiredCells_.size();
00075   unsigned gain, adc;
00076   ecalDigis.reserve(nhit);
00077   ecalHits.reserve(nhit);
00078   for(unsigned ihit=0;ihit<nhit;++ihit)
00079     {      
00080       unsigned icell = theFiredCells_[ihit];
00081 
00082       EEDetId myDetId(endcapRawId_[icell]);
00083       if(doDigis_)
00084         {
00085            ecalDigis.push_back( myDetId );
00086            EEDataFrame myDataFrame( ecalDigis.back() );
00087            // myDataFrame.setSize(1); // now useless - by construction fixed at 1 frame - FIXME
00088            //  The real work is in the following line
00089            geVtoGainAdc(theCalorimeterHits_[icell],gain,adc);
00090            myDataFrame.setSample(0,EcalMGPASample(adc,gain));
00091            //ecalDigis.push_back(myDataFrame);
00092         }
00093 
00094       // It is safer to update the orignal array in case this methods is called several times
00095       if (!noisified_ )  theCalorimeterHits_[icell] += random_->gaussShoot(0.,noise_);
00096       
00097       // If the energy+noise is below the threshold, a hit is nevertheless created, otherwise, there is a risk that a "noisy" hit 
00098       // is afterwards put in this cell which would not be correct. 
00099       float energy=theCalorimeterHits_[icell];
00100       if ( energy<threshold_ ) 
00101         {
00102           theCalorimeterHits_[icell]=0.;
00103           energy=0.;
00104         }
00105       else 
00106         if( energy > sat_)
00107           {
00108             energy=sat_;
00109             theCalorimeterHits_[icell]=sat_;
00110           }
00111 
00112       ecalHits.push_back(EcalRecHit(myDetId,energy,0.));
00113     }
00114   noisified_ = true;
00115 
00116 }
00117 
00118 void EcalEndcapRecHitsMaker::loadPCaloHits(const edm::Event & iEvent)
00119 {
00120 
00121   edm::Handle<CrossingFrame<PCaloHit> > cf;
00122   iEvent.getByLabel(inputCol_,cf);
00123   std::auto_ptr<MixCollection<PCaloHit> > colcalo(new MixCollection<PCaloHit>(cf.product(),std::pair<int,int>(0,0) ));
00124 
00125   theFiredCells_.reserve(colcalo->size());
00126 
00127   MixCollection<PCaloHit>::iterator cficalo;
00128   MixCollection<PCaloHit>::iterator cficaloend=colcalo->end();
00129   float calib=1.;
00130   for (cficalo=colcalo->begin(); cficalo!=cficaloend;cficalo++) 
00131     {
00132 
00133       unsigned hashedindex = EEDetId(cficalo->id()).hashedIndex();      
00134       // Check if the hit already exists
00135       if(theCalorimeterHits_[hashedindex]==0.)
00136         {
00137           theFiredCells_.push_back(hashedindex); 
00138         }
00139       // the famous 1/0.97 calibration factor is applied here ! 
00140       calib=calibfactor_;
00141       // the miscalibration is applied here:
00142       if(doMisCalib_) calib*=theCalibConstants_[hashedindex];
00143       // cficalo->energy can be 0 (a 7x7 grid is always built), in this case, one should not kill the cell (for later noise injection), but it should
00144       // be added only once.  This is a dirty trick. 
00145       float energy=(cficalo->energy()==0.) ? 0.000001 : cficalo->energy() ;
00146       theCalorimeterHits_[hashedindex]+=energy*calib;   
00147     }
00148 }
00149 
00150 
00151 void EcalEndcapRecHitsMaker::init(const edm::EventSetup &es,bool doDigis,bool domiscalib)  
00152 {
00153   doDigis_=doDigis;
00154   doMisCalib_=domiscalib;
00155   endcapRawId_.resize(20000);
00156   if (doMisCalib_) theCalibConstants_.resize(20000);
00157   edm::ESHandle<CaloGeometry> pG;
00158   es.get<CaloGeometryRecord>().get(pG);   
00159   
00160   const EcalEndcapGeometry * myEcalEndcapGeometry = dynamic_cast<const EcalEndcapGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal,EcalEndcap));
00161   const std::vector<DetId>& vec(myEcalEndcapGeometry->getValidDetIds(DetId::Ecal,EcalEndcap));
00162   unsigned size=vec.size();    
00163   for(unsigned ic=0; ic<size; ++ic) 
00164     {
00165       endcapRawId_[EEDetId(vec[ic]).hashedIndex()]=vec[ic].rawId();
00166     }
00167   //  std::cout << " Made the array " << std::endl;
00168   // Stores the miscalibration constants
00169   if(doMisCalib_)
00170     {
00171       float rms=0.;
00172       unsigned ncells=0;
00173       // Intercalib constants
00174       edm::ESHandle<EcalIntercalibConstants> pIcal;
00175       es.get<EcalIntercalibConstantsRcd>().get(pIcal);
00176       const EcalIntercalibConstants* ical = pIcal.product();
00177 
00178 
00179       theCalibConstants_ = ical->endcapItems();
00180       std::vector<float>::iterator it=theCalibConstants_.begin();
00181       std::vector<float>::iterator itend=theCalibConstants_.end();
00182       for ( ; it != itend; ++it ) {     
00183         if(!EEDetId::validHashIndex(ncells)) continue;
00184         *it= refactor_mean_+(*it-1.)*refactor_;
00185         rms+=(*it-1.)*(*it-1.);
00186         ++ncells;
00187       }
00188       rms = std::sqrt(rms) / (float)ncells;
00189       // The following should be on LogInfo
00190       //std::cout << " Found " << ncells << " cells in the endcap calibration map. RMS is " << rms << std::endl;
00191     }  
00192 }
00193 
00194 
00195 void EcalEndcapRecHitsMaker::geVtoGainAdc(float e,unsigned & gain, unsigned &adc) const
00196 {
00197   if(e<t1_)
00198     {
00199       gain = 1; // x1 
00200       //      std::cout << " E " << e << std::endl;
00201       adc = minAdc_ + (unsigned)(e*geVToAdc1_);
00202       //      std::cout << " e*geVtoAdc1_ " << e*geVToAdc1_ << " " <<(unsigned)(e*geVToAdc1_) << std::endl;
00203     } 
00204   else if (e<t2_)
00205     {
00206       gain = 2; // x6
00207       adc = minAdc_ + (unsigned)(e*geVToAdc2_);
00208     }
00209   else 
00210     {
00211       gain = 3; // x12
00212       adc = std::min(minAdc_+(unsigned)(e*geVToAdc3_),maxAdc_);
00213     }
00214 }

Generated on Tue Jun 9 17:35:02 2009 for CMSSW by  doxygen 1.5.4