CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/FastSimulation/CaloRecHitsProducer/src/HcalRecHitsMaker.cc

Go to the documentation of this file.
00001 #include "FastSimulation/CaloRecHitsProducer/interface/HcalRecHitsMaker.h"
00002 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h"
00003 
00004 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00005 #include "DataFormats/Common/interface/Handle.h"
00006 #include "FWCore/Framework/interface/ESHandle.h"
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008 #include "FWCore/Framework/interface/Event.h"
00009 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"        
00010 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
00011 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00012 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00013 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00014 #include "DataFormats/HcalDigi/interface/HBHEDataFrame.h"
00015 #include "CLHEP/GenericFunctions/Erf.hh"
00016 #include "CalibFormats/HcalObjects/interface/HcalTPGRecord.h"
00017 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00018 #include "CalibFormats/HcalObjects/interface/HcalDbService.h"
00019 #include "CondFormats/HcalObjects/interface/HcalGains.h"
00020 #include "CondFormats/HcalObjects/interface/HcalPedestal.h"
00021 #include "SimCalorimetry/HcalSimAlgos/interface/HcalSimParameterMap.h"
00022 #include "CalibCalorimetry/CaloMiscalibTools/interface/MiscalibReaderFromXMLHcal.h"
00023 #include "CalibCalorimetry/CaloMiscalibTools/interface/CaloMiscalibMapHcal.h"
00024 #include "CondFormats/HcalObjects/interface/HcalRespCorrs.h"
00025 #include "CondFormats/DataRecord/interface/HcalRespCorrsRcd.h"
00026 
00027 #include "TFile.h"
00028 #include "TGraph.h"
00029 #include "TROOT.h"
00030 #include <fstream>
00031 
00032 class RandomEngine;
00033 
00034 bool HcalRecHitsMaker::initialized_ = false; 
00035 std::vector<float> HcalRecHitsMaker::peds_;
00036 std::vector<int> HcalRecHitsMaker::fctoadc_;
00037 std::vector<float> HcalRecHitsMaker::sat_;
00038 std::vector<float> HcalRecHitsMaker::gains_;
00039 std::vector<float> HcalRecHitsMaker::noisesigma_;
00040 std::vector<float> HcalRecHitsMaker::TPGFactor_;
00041 std::vector<float> HcalRecHitsMaker::miscalib_;
00042 std::vector<HcalDetId> HcalRecHitsMaker::theDetIds_;
00043 std::vector<int> HcalRecHitsMaker::hbhi_;
00044 std::vector<int> HcalRecHitsMaker::hehi_;
00045 std::vector<int> HcalRecHitsMaker::hohi_;
00046 std::vector<int> HcalRecHitsMaker::hfhi_;
00047 unsigned HcalRecHitsMaker::maxIndex_  = 0 ; 
00048 
00049 HcalRecHitsMaker::HcalRecHitsMaker(edm::ParameterSet const & p, int det,
00050                                    const RandomEngine * myrandom)
00051   :
00052   det_(det),
00053   doDigis_(false),
00054   noiseFromDb_(false),
00055   random_(myrandom)
00056   //,myHcalSimParameterMap_(0)
00057 {
00058   edm::ParameterSet RecHitsParameters=p.getParameter<edm::ParameterSet>("HCAL");
00059   noise_ = RecHitsParameters.getParameter<std::vector<double> >("Noise");
00060   threshold_ = RecHitsParameters.getParameter<std::vector<double> >("Threshold");
00061   doSaturation_ = RecHitsParameters.getParameter<bool>("EnableSaturation");
00062     
00063   refactor_ = RecHitsParameters.getParameter<double> ("Refactor");
00064   refactor_mean_ = RecHitsParameters.getParameter<double> ("Refactor_mean");
00065   hcalfileinpath_= RecHitsParameters.getParameter<std::string> ("fileNameHcal");  
00066   inputCol_=RecHitsParameters.getParameter<edm::InputTag>("MixedSimHits");
00067   nhbcells_=nhecells_=nhocells_=nhfcells_=0;
00068 
00069   if(det_==4)
00070     {
00071       hbhi_.reserve(2600);
00072       hehi_.reserve(2600);
00073     }
00074   else if (det_==5)
00075     hohi_.reserve(2200);
00076   else if (det_==6)
00077     hfhi_.reserve(1800);
00078 
00079   if(threshold_.size()!=noise_.size())
00080     {
00081       edm::LogWarning("CaloRecHitsProducer") << " WARNING : HCAL Noise simulation, the number of parameters should be the same for the noise and the thresholds. Disabling the noise simulation " << std::endl;
00082       noise_.clear();
00083       noise_.push_back(0.);
00084     }
00085   else 
00086     nnoise_=noise_.size(); 
00087 
00088   //  edm::ParameterSet hcalparam = p2.getParameter<edm::ParameterSet>("hcalSimParam"); 
00089   //  myHcalSimParameterMap_ = new HcalSimParameterMap(hcalparam);
00090 
00091   // Computes the fraction of HCAL above the threshold
00092   Genfun::Erf myErf;
00093   hcalHotFraction_.resize(nnoise_,0.);
00094   myGaussianTailGenerators_.resize(nnoise_,0);
00095   if(noise_.size()>0) 
00096     {
00097       for(unsigned inoise=0;inoise<nnoise_;++inoise)
00098         {
00099           if(noise_[inoise]==0) 
00100             {
00101               hcalHotFraction_[inoise]=0.;
00102               continue;
00103             }
00104           else if(noise_[inoise]==-1) {
00105             noiseFromDb_=true;
00106             continue;
00107           }
00108           else
00109             {
00110               hcalHotFraction_.push_back(0.5-0.5*myErf(threshold_[inoise]/noise_[inoise]/sqrt(2.)));
00111               myGaussianTailGenerators_[inoise]=new GaussianTail(random_,noise_[inoise],threshold_[inoise]);
00112             }
00113         }   
00114     }  
00115 }
00116 
00117 HcalRecHitsMaker::~HcalRecHitsMaker()
00118 {
00119   clean();  
00120   if(myGaussianTailGenerators_.size()) 
00121     {
00122       for(unsigned igt=0; igt<myGaussianTailGenerators_.size();++igt)
00123         delete myGaussianTailGenerators_[igt];
00124     }
00125   myGaussianTailGenerators_.clear();
00126   theDetIds_.clear();
00127   hbhi_.clear();
00128   hehi_.clear();
00129   hohi_.clear();
00130   hfhi_.clear();
00131     
00132 }
00133 
00134 void HcalRecHitsMaker::init(const edm::EventSetup &es,bool doDigis,bool doMiscalib)
00135 {
00136   doDigis_=doDigis;
00137   doMiscalib_=doMiscalib;
00138 // needed for the noise simulation
00139   edm::ESHandle<HcalDbService> conditions;
00140   es.get<HcalDbRecord>().get(conditions);
00141   const HcalDbService * theDbService=conditions.product();
00142 
00143   // get the correction factors
00144   edm::ESHandle<HcalRespCorrs> rchandle;
00145   es.get<HcalRespCorrsRcd>().get(rchandle);
00146   myRespCorr= rchandle.product();
00147   
00148 
00149   if(!initialized_) 
00150     {     
00151       theDetIds_.resize(9201);
00152       unsigned ncells=createVectorsOfCells(es);
00153       edm::LogInfo("CaloRecHitsProducer") << "Total number of cells in HCAL " << ncells << std::endl;
00154       hcalRecHits_.resize(maxIndex_+1,0.);
00155       edm::LogInfo("CaloRecHitsProducer") << "Largest HCAL hashedindex" << maxIndex_ << std::endl;
00156 
00157       peds_.resize(9201);
00158       gains_.resize(9201);
00159       if(doSaturation_)
00160         sat_.resize(9201);
00161       if(noiseFromDb_)
00162         noisesigma_.resize(9201);
00163       
00164       
00165       
00166       miscalib_.resize(maxIndex_+1,1.);
00167       // Read from file ( a la HcalRecHitsRecalib.cc)
00168       // here read them from xml (particular to HCAL)
00169       CaloMiscalibMapHcal mapHcal;
00170       mapHcal.prefillMap();
00171       
00172 
00173       edm::FileInPath hcalfiletmp("CalibCalorimetry/CaloMiscalibTools/data/"+hcalfileinpath_);      
00174       std::string hcalfile=hcalfiletmp.fullPath();            
00175       if(doMiscalib_ && !hcalfile.empty()) 
00176         {
00177           MiscalibReaderFromXMLHcal hcalreader_(mapHcal);
00178 
00179           hcalreader_.parseXMLMiscalibFile(hcalfile);
00180           //      mapHcal.print();
00181           std::map<uint32_t,float>::const_iterator it=mapHcal.get().begin();
00182           std::map<uint32_t,float>::const_iterator itend=mapHcal.get().end();
00183           for(;it!=itend;++it)
00184             {
00185               HcalDetId myDetId(it->first);
00186               float icalconst=it->second;
00187               miscalib_[myDetId.hashed_index()]=refactor_mean_+(icalconst-refactor_mean_)*refactor_;
00188             }
00189         }
00190       
00191       
00192       // Open the histogram for the fC to ADC conversion
00193       gROOT->cd();
00194       edm::FileInPath myDataFile("FastSimulation/CaloRecHitsProducer/data/adcvsfc.root");
00195       TFile * myFile = new TFile(myDataFile.fullPath().c_str(),"READ");
00196       TGraph * myGraf = (TGraph*)myFile->Get("adcvsfc");
00197       unsigned size=myGraf->GetN();
00198       fctoadc_.resize(10000);
00199       unsigned p_index=0;
00200       fctoadc_[0]=0;
00201       int prev_nadc=0;
00202       int nadc=0;
00203       for(unsigned ibin=0;ibin<size;++ibin)
00204         {
00205           double x,y;
00206           myGraf->GetPoint(ibin,x,y);
00207           int index=(int)floor(x);
00208           if(index<0||index>=10000) continue;
00209           prev_nadc=nadc;
00210           nadc=(int)y;
00211           // Now fills the vector
00212           for(unsigned ivec=p_index;ivec<(unsigned)index;++ivec)
00213             {
00214               fctoadc_[ivec] = prev_nadc;
00215             }
00216           p_index = index;
00217         }
00218       myFile->Close();
00219       gROOT->cd();
00220       edm::FileInPath myTPGFilePath("CalibCalorimetry/HcalTPGAlgos/data/RecHit-TPG-calib.dat");
00221       TPGFactor_.resize(87,1.2);
00222       std::ifstream  myTPGFile(myTPGFilePath.fullPath().c_str(),ifstream::in);
00223       if(myTPGFile)
00224         {
00225           float gain;
00226           myTPGFile >> gain;
00227           for(unsigned i=0;i<86;++i)
00228             {
00229               myTPGFile >> TPGFactor_[i] ;
00230               //          std::cout << TPGFactor_[i] << std::endl;
00231             }
00232         }
00233       else
00234         {
00235           std::cout << " Unable to open CalibCalorimetry/HcalTPGAlgos/data/RecHit-TPG-calib.dat" << std::endl;
00236           std::cout <<  " Using a constant 1.2 factor " << std::endl;
00237         }
00238       //HB
00239       for(unsigned ic=0;ic<nhbcells_;++ic)
00240         {
00241           float gain = theDbService->getGain(theDetIds_[hbhi_[ic]])->getValue(0);
00242           float mgain=0.;
00243           for(unsigned ig=0;ig<4;++ig)
00244             mgain+=theDbService->getGain(theDetIds_[hbhi_[ic]])->getValue(ig);
00245           if(noiseFromDb_)
00246             noisesigma_[hbhi_[ic]]=noiseInfCfromDB(theDbService,theDetIds_[hbhi_[ic]])*mgain*0.25;
00247           //      std::cout << " NOISEHB " << theDetIds_[hbhi_[ic]].ieta() << " " << noisesigma_[hbhi_[ic]] << "  "<< std::endl;
00248             // 10000 (ADC scale) / 4. (to compute the mean) / 0.92  ADC/fC
00249   // *1.25 (only ~80% in 1ts Digi, while saturation applied to 4ts RecHit) 
00250           int ieta=theDetIds_[hbhi_[ic]].ieta();
00251           float tpgfactor=TPGFactor_[(ieta>0)?ieta+43:-ieta];
00252           mgain*=2500./0.92*tpgfactor ;// 10000 (ADC scale) / 4. (to compute the mean)
00253           sat_[hbhi_[ic]]=(doSaturation_)?mgain:99999.;
00254       
00255           peds_[hbhi_[ic]]=theDbService->getPedestal(theDetIds_[hbhi_[ic]])->getValue(0);
00256 
00257           gain*=tpgfactor;
00258           gains_[hbhi_[ic]]=gain;
00259         }
00260       //HE
00261 
00262       for(unsigned ic=0;ic<nhecells_;++ic)
00263         {
00264           float gain= theDbService->getGain(theDetIds_[hehi_[ic]])->getValue(0);
00265           int ieta=theDetIds_[hehi_[ic]].ieta();
00266           float mgain=0.;
00267           for(unsigned ig=0;ig<4;++ig)
00268             mgain+=theDbService->getGain(theDetIds_[hehi_[ic]])->getValue(ig);
00269           if(noiseFromDb_)
00270             noisesigma_[hehi_[ic]]=noiseInfCfromDB(theDbService,theDetIds_[hehi_[ic]])*mgain*0.25;
00271       
00272           //      std::cout << " NOISEHE " << theDetIds_[hehi_[ic]].ieta() << " " << noisesigma_[hehi_[ic]] << "  "<< std::endl;
00273           float tpgfactor=TPGFactor_[(ieta>0)?ieta+44:-ieta+1];
00274           mgain*=2500./0.92*tpgfactor;
00275           sat_[hehi_[ic]]=(doSaturation_)?mgain:99999.;
00276       
00277           gain*=tpgfactor;
00278           peds_[hehi_[ic]]=theDbService->getPedestal(theDetIds_[hehi_[ic]])->getValue(0);
00279           gains_[hehi_[ic]]=gain;
00280         }
00281       //HO
00282 
00283       for(unsigned ic=0;ic<nhocells_;++ic)
00284         {
00285           float ped=theDbService->getPedestal(theDetIds_[hohi_[ic]])->getValue(0);
00286           float gain=theDbService->getGain(theDetIds_[hohi_[ic]])->getValue(0);
00287           float mgain=0.;
00288           for(unsigned ig=0;ig<4;++ig)
00289             mgain+=theDbService->getGain(theDetIds_[hohi_[ic]])->getValue(ig);
00290           if(noiseFromDb_)
00291             noisesigma_[hohi_[ic]]=noiseInfCfromDB(theDbService,theDetIds_[hohi_[ic]])*mgain*0.25;
00292           //      std::cout << " NOISEHO " << theDetIds_[hohi_[ic]].ieta() << " " << noisesigma_[hohi_[ic]] << "  "<< std::endl;
00293           int ieta=HcalDetId(hohi_[ic]).ieta();
00294           float tpgfactor=TPGFactor_[(ieta>0)?ieta+43:-ieta];
00295           mgain*=2500./0.92*tpgfactor;
00296           sat_[hohi_[ic]]=(doSaturation_)?mgain:99999.;
00297 
00298           gain*=tpgfactor;
00299           peds_[hohi_[ic]]=ped;
00300           gains_[hohi_[ic]]=gain;
00301         }
00302       //HF
00303 
00304       for(unsigned ic=0;ic<nhfcells_;++ic)
00305         {
00306           float ped=theDbService->getPedestal(theDetIds_[hfhi_[ic]])->getValue(0);
00307           float gain=theDbService->getGain(theDetIds_[hfhi_[ic]])->getValue(0);
00308           float mgain=0.;
00309           for(unsigned ig=0;ig<4;++ig)
00310             mgain+=theDbService->getGain(theDetIds_[hfhi_[ic]])->getValue(ig);
00311           // additional 1/2 factor for the HF (Salavat)
00312           if(noiseFromDb_)
00313             {
00314               // computation from when the noise was taken 
00315               noisesigma_[hfhi_[ic]]=noiseInfCfromDB(theDbService,theDetIds_[hfhi_[ic]])*mgain*0.25;
00316             }
00317           //      std::cout << " NOISEHF " << theDetIds_[hfhi_[ic]].ieta() << " " << noisesigma_[hfhi_[ic]] << "  "<< std::endl;
00318       
00319           mgain*=2500./0.36;
00320           sat_[hfhi_[ic]]=(doSaturation_)?mgain:99999.;
00321           int ieta=theDetIds_[hfhi_[ic]].ieta();
00322           gain*=TPGFactor_[(ieta>0)?ieta+45:-ieta+2];
00323           peds_[hfhi_[ic]]=ped;
00324           gains_[hfhi_[ic]]=gain;
00325         }
00326       initialized_=true; 
00327     }
00328   
00329   // clear the vector we don't need. It is a bit stupid 
00330   hcalRecHits_.resize(maxIndex_+1,0.);
00331 
00332 }
00333 
00334 
00335 // Get the PCaloHits from the event. They have to be stored in a map, because when
00336 // the pile-up is added thanks to the Mixing Module, the same cell can be present several times
00337 void HcalRecHitsMaker::loadPCaloHits(const edm::Event & iEvent)
00338 {
00339   clean();
00340 
00341   edm::Handle<CrossingFrame<PCaloHit> > cf;
00342   iEvent.getByLabel(inputCol_,cf);
00343   std::auto_ptr<MixCollection<PCaloHit> > colcalo(new MixCollection<PCaloHit>(cf.product(),std::pair<int,int>(0,0) ));
00344 
00345   MixCollection<PCaloHit>::iterator it=colcalo->begin();;
00346   MixCollection<PCaloHit>::iterator itend=colcalo->end();
00347   unsigned counter=0;
00348   for(;it!=itend;++it)
00349     {
00350       HcalDetId detid(it->id());
00351       int hashedindex=detid.hashed_index();
00352 
00353       switch(detid.subdet())
00354         {
00355         case HcalBarrel: 
00356           {
00357             if(det_==4)
00358               Fill(hashedindex,it->energy(),firedCells_,noise_[0]);
00359           }
00360           break;
00361         case HcalEndcap: 
00362           {       
00363             if(det_==4)
00364               Fill(hashedindex,it->energy(),firedCells_,noise_[1]);
00365           }
00366           break;
00367         case HcalOuter: 
00368           {
00369             if(det_==5)
00370               Fill(hashedindex,it->energy(),firedCells_,noise_[0]);
00371           }
00372           break;                     
00373         case HcalForward: 
00374           {
00375             if(det_==6)
00376               Fill(hashedindex,it->energy(),firedCells_,noise_[0]);
00377           }
00378           break;
00379         default:
00380           edm::LogWarning("CaloRecHitsProducer") << "RecHit not registered\n";
00381           ;
00382         }
00383       ++counter;
00384     }
00385 }
00386 
00387 // Fills the collections. 
00388 void HcalRecHitsMaker::loadHcalRecHits(edm::Event &iEvent,HBHERecHitCollection& hbheHits, HBHEDigiCollection& hbheDigis)
00389 {
00390   loadPCaloHits(iEvent);
00391   noisify();
00392   hbheHits.reserve(firedCells_.size());
00393   if(doDigis_)
00394     {
00395       hbheDigis.reserve(firedCells_.size());
00396     }
00397   static HcalQIESample zeroSample(0,0,0,0);
00398   unsigned nhits=firedCells_.size();
00399   // HB and HE
00400 
00401   for(unsigned ihit=0;ihit<nhits;++ihit)
00402     {
00403       unsigned cellhashedindex=firedCells_[ihit];
00404       const HcalDetId& detid  = theDetIds_[cellhashedindex];
00405       unsigned subdet=(detid.subdet()==HcalBarrel) ? 0: 1;      
00406 
00407       float energy=hcalRecHits_[cellhashedindex];
00408       // Check if it is above the threshold
00409       if(energy<threshold_[subdet]) continue; 
00410       // apply RespCorr only to the RecHit
00411       energy *= myRespCorr->getValues(theDetIds_[cellhashedindex])->getValue();
00412       // poor man saturation
00413       if(energy>sat_[cellhashedindex]) 
00414         {
00415           //      std::cout << " Saturation " << energy << " " << sat_[cellhashedindex] << " HB " << std::endl;
00416           energy=sat_[cellhashedindex];
00417         }
00418       
00419 
00420       hbheHits.push_back(HBHERecHit(detid,energy,0.));      
00421       if(doDigis_)
00422         {
00423           HBHEDataFrame myDataFrame(detid);
00424           myDataFrame.setSize(2);
00425           double nfc=hcalRecHits_[cellhashedindex]/gains_[cellhashedindex]+peds_[cellhashedindex];
00426           int nadc=fCtoAdc(nfc);
00427           HcalQIESample qie(nadc, 0, 0, 0) ;
00428           myDataFrame.setSample(0,qie);
00429           myDataFrame.setSample(1,zeroSample);
00430           hbheDigis.push_back(myDataFrame);
00431         }
00432     }
00433 }
00434 
00435 
00436 // Fills the collections. 
00437 void HcalRecHitsMaker::loadHcalRecHits(edm::Event &iEvent, HORecHitCollection &hoHits, HODigiCollection & hoDigis)
00438 {
00439   loadPCaloHits(iEvent);
00440   noisify();
00441   hoHits.reserve(firedCells_.size());
00442   if(doDigis_)
00443     {
00444       hoDigis.reserve(firedCells_.size());
00445     }
00446   static HcalQIESample zeroSample(0,0,0,0);
00447 
00448   // HO
00449   unsigned nhits=firedCells_.size();
00450   for(unsigned ihit=0;ihit<nhits;++ihit)
00451     {
00452 
00453       unsigned cellhashedindex=firedCells_[ihit];
00454       // Check if it is above the threshold
00455       if(hcalRecHits_[cellhashedindex]<threshold_[0]) continue; 
00456 
00457       const HcalDetId&  detid=theDetIds_[cellhashedindex];
00458       int ieta = detid.ieta();
00459       
00460       // Force  only Ring#0 to remain
00461       if(ieta > 4 || ieta < -4 ) continue;
00462 
00463       float energy=hcalRecHits_[cellhashedindex];
00464       // apply RespCorr
00465       energy *= myRespCorr->getValues(theDetIds_[cellhashedindex])->getValue();
00466 
00467       // poor man saturation
00468       if(energy>sat_[cellhashedindex]) energy=sat_[cellhashedindex];
00469 
00470       hoHits.push_back(HORecHit(detid,energy,0));
00471     }
00472 }
00473 
00474 // Fills the collections. 
00475 void HcalRecHitsMaker::loadHcalRecHits(edm::Event &iEvent,HFRecHitCollection &hfHits, HFDigiCollection& hfDigis)
00476 {
00477   loadPCaloHits(iEvent);
00478   noisify();
00479   hfHits.reserve(firedCells_.size());
00480   if(doDigis_)
00481     {
00482       hfDigis.reserve(firedCells_.size());
00483     }
00484   static HcalQIESample zeroSample(0,0,0,0);
00485 
00486   unsigned nhits=firedCells_.size();
00487   for(unsigned ihit=0;ihit<nhits;++ihit)
00488     {
00489       unsigned cellhashedindex=firedCells_[ihit];
00490       // Check if it is above the threshold
00491       if(hcalRecHits_[cellhashedindex]<threshold_[0]) continue; 
00492 
00493       float energy=hcalRecHits_[cellhashedindex];
00494 
00495       // apply RespCorr
00496       energy *= myRespCorr->getValues(theDetIds_[cellhashedindex])->getValue();
00497 
00498       // poor man saturation
00499       if(energy>sat_[cellhashedindex]) energy=sat_[cellhashedindex];
00500 
00501       const HcalDetId & detid=theDetIds_[cellhashedindex];
00502       hfHits.push_back(HFRecHit(detid,energy,0.));      
00503       if(doDigis_)
00504         {
00505           HFDataFrame myDataFrame(detid);
00506           myDataFrame.setSize(1);
00507 
00508           double nfc= hcalRecHits_[cellhashedindex]/gains_[cellhashedindex]+peds_[cellhashedindex];
00509           int nadc=fCtoAdc(nfc/2.6);
00510           HcalQIESample qie(nadc, 0, 0, 0) ;
00511           myDataFrame.setSample(0,qie);
00512           hfDigis.push_back(myDataFrame);
00513         }
00514     }
00515 }
00516 
00517 
00518 // For a fast injection of the noise: the list of cell ids is stored
00519 unsigned HcalRecHitsMaker::createVectorsOfCells(const edm::EventSetup &es)
00520 {
00521     edm::ESHandle<CaloGeometry> pG;
00522     es.get<CaloGeometryRecord>().get(pG);     
00523     nhbcells_ = createVectorOfSubdetectorCells(*pG, HcalBarrel,  hbhi_);    
00524     nhecells_ = createVectorOfSubdetectorCells(*pG, HcalEndcap,  hehi_);
00525     nhocells_ = createVectorOfSubdetectorCells(*pG, HcalOuter,   hohi_);
00526     nhfcells_ = createVectorOfSubdetectorCells(*pG, HcalForward, hfhi_);    
00527 
00528     return nhbcells_+nhecells_+nhocells_+nhfcells_;
00529 }
00530 
00531 // list of the cellids for a given subdetector
00532 unsigned HcalRecHitsMaker::createVectorOfSubdetectorCells(const CaloGeometry& cg,int subdetn,std::vector<int>& cellsvec ) 
00533 {
00534 
00535   const CaloSubdetectorGeometry* geom=cg.getSubdetectorGeometry(DetId::Hcal,subdetn);  
00536   const std::vector<DetId>& ids=geom->getValidDetIds(DetId::Hcal,subdetn);  
00537 
00538   for (std::vector<DetId>::const_iterator i=ids.begin(); i!=ids.end(); i++) 
00539     {
00540       HcalDetId myDetId(*i);
00541       //      std::cout << myDetId << myHcalSimParameterMap_->simParameters(myDetId).simHitToPhotoelectrons() << std::endl;;
00542       //      std::cout << " hi " << hi << " " theDetIds_.size() << std::endl;
00543       unsigned hi=myDetId.hashed_index();
00544       theDetIds_[hi]=myDetId;
00545       //      std::cout << myDetId << " " << hi <<  std::endl;
00546       cellsvec.push_back(hi);      
00547 
00548       if(hi>maxIndex_)
00549         maxIndex_=hi;
00550     }
00551   return cellsvec.size();
00552 }
00553 
00554 // Takes a hit (from a PSimHit) and fills a map 
00555 void HcalRecHitsMaker::Fill(int id, float energy, std::vector<int>& theHits,float noise)
00556 {
00557   if(doMiscalib_) 
00558     energy*=miscalib_[id];
00559 
00560   if(noiseFromDb_)
00561     noise=noisesigma_[id];
00562 
00563   // Check if the RecHit exists
00564   if(hcalRecHits_[id]>0.)
00565     hcalRecHits_[id]+=energy;
00566   else
00567     {
00568       // the noise is injected only the first time
00569       hcalRecHits_[id]=energy + random_->gaussShoot(0.,noise);
00570       theHits.push_back(id);
00571     }
00572 }
00573 
00574 void HcalRecHitsMaker::noisify()
00575 {
00576   unsigned total=0;
00577   switch(det_)
00578     {
00579     case 4:
00580       {
00581         // do the HB
00582         if(noise_[0] != 0.) {
00583           total+=noisifySubdet(hcalRecHits_,firedCells_,hbhi_,nhbcells_,hcalHotFraction_[0],myGaussianTailGenerators_[0],noise_[0],threshold_[0]);
00584         }
00585         // do the HE
00586         if(noise_[1] != 0.) {    
00587           total+=noisifySubdet(hcalRecHits_,firedCells_,hehi_,nhecells_,hcalHotFraction_[1],myGaussianTailGenerators_[1],noise_[1],threshold_[1]);
00588         }
00589       }
00590       break;
00591     case 5:
00592       {
00593         // do the HO
00594         if(noise_[0] != 0.) {
00595           total+=noisifySubdet(hcalRecHits_,firedCells_,hohi_,nhocells_,hcalHotFraction_[0],myGaussianTailGenerators_[0],noise_[0],threshold_[0]);
00596         }
00597       }
00598       break;
00599     case 6:
00600       {
00601         // do the HF
00602         if(noise_[0] != 0.) {
00603           total+=noisifySubdet(hcalRecHits_,firedCells_,hfhi_,nhfcells_,hcalHotFraction_[0],myGaussianTailGenerators_[0],noise_[0],threshold_[0]);
00604         }
00605       }
00606       break;
00607     default:
00608       break;
00609     }
00610   edm::LogInfo("CaloRecHitsProducer") << "CaloRecHitsProducer : added noise in "<<  total << " HCAL cells "  << std::endl;
00611 }
00612 
00613 unsigned HcalRecHitsMaker::noisifySubdet(std::vector<float>& theMap, std::vector<int>& theHits, const std::vector<int>& thecells, unsigned ncells, double hcalHotFraction,const GaussianTail *myGT,double sigma,double threshold)
00614 {
00615  // If the fraction of "hot " is small, use an optimized method to inject noise only in noisy cells. The 30% has not been tuned
00616   if(!noiseFromDb_ && hcalHotFraction==0.) return 0;
00617   if(hcalHotFraction<0.3 && !noiseFromDb_)
00618     {
00619       double mean = (double)(ncells-theHits.size())*hcalHotFraction;
00620       unsigned nhcal = random_->poissonShoot(mean);
00621   
00622       unsigned ncell=0;
00623       unsigned cellindex=0;
00624       uint32_t cellhashedindex=0;
00625       
00626       while(ncell < nhcal)
00627         {
00628           cellindex = (unsigned)(random_->flatShoot()*ncells);
00629           cellhashedindex = thecells[cellindex];
00630 
00631           if(hcalRecHits_[cellhashedindex]==0.) // new cell
00632             {
00633               hcalRecHits_[cellhashedindex]=myGT->shoot();
00634               theHits.push_back(cellhashedindex);
00635               ++ncell;
00636             }
00637         }
00638       return ncell;
00639     }
00640   else // otherwise, inject noise everywhere
00641     {
00642       uint32_t cellhashedindex=0;
00643       unsigned nhcal=thecells.size();
00644 
00645 
00646       for(unsigned ncell=0;ncell<nhcal;++ncell)
00647         {
00648           cellhashedindex = thecells[ncell];
00649           if(hcalRecHits_[cellhashedindex]==0.) // new cell
00650             {
00651               
00652               sigma=noisesigma_[cellhashedindex];
00653 
00654               double noise =random_->gaussShoot(0.,sigma);
00655               if(noise>threshold)
00656                 {
00657                   hcalRecHits_[cellhashedindex]=noise;              
00658                   theHits.push_back(cellhashedindex);
00659                 }
00660             }
00661         }
00662       return nhcal;
00663     }
00664   return 0;
00665 }
00666 
00667 void HcalRecHitsMaker::clean()
00668 {
00669   cleanSubDet(hcalRecHits_,firedCells_);
00670 }
00671 
00672 void HcalRecHitsMaker::cleanSubDet(std::vector<float>& hits,std::vector<int>& cells)
00673 {
00674   unsigned size=cells.size();
00675   // Reset the energies
00676   for(unsigned ic=0;ic<size;++ic)
00677     {
00678       hits[cells[ic]] = 0.;
00679     }
00680   // Clear the list of fired cells 
00681   cells.clear();
00682 }
00683 
00684 // fC to ADC conversion
00685 int HcalRecHitsMaker::fCtoAdc(double fc) const
00686 {
00687   if(fc<0.) return 0;
00688   if(fc>9985.) return 127;
00689   return fctoadc_[(unsigned)floor(fc)];
00690 }
00691 
00692 double HcalRecHitsMaker::noiseInfCfromDB(const HcalDbService * conditions,const HcalDetId & detId)
00693 {
00694   // method from Salavat
00695   // fetch pedestal widths (noise sigmas for all 4 CapID)
00696   const HcalPedestalWidth* pedWidth =
00697     conditions-> getPedestalWidth(detId); 
00698   double ssqq_1 = pedWidth->getSigma(0,0);
00699   double ssqq_2 = pedWidth->getSigma(1,1);
00700   double ssqq_3 = pedWidth->getSigma(2,2);
00701   double ssqq_4 = pedWidth->getSigma(3,3);
00702 
00703   // correction factors (hb,he,ho,hf)
00704   static float corrfac[4]={1.39,1.32,1.17,3.76};
00705 
00706   int sub   = detId.subdet();
00707 
00708   // HO: only Ring#0 matters 
00709   int ieta  = detId.ieta();
00710   if (sub == 3 && abs (ieta) > 4) return 0.;   
00711 
00712   // effective RecHits (for this particular detId) noise calculation :
00713   
00714   double sig_sq_mean =  0.25 * ( ssqq_1 + ssqq_2 + ssqq_3 + ssqq_4);
00715   
00716   // f - external parameter (currently set to 0.5 in the FullSim) !!!
00717   double f=0.5;
00718 
00719   double term  = sqrt (1. + sqrt(1. - 2.*f*f));
00720   double alpha = sqrt (0.5) * term;
00721   double beta  = sqrt (0.5) * f / term;
00722 
00723   //  double RMS1   = sqrt(sig_sq_mean) * sqrt (2.*beta*beta + alpha*alpha) ;
00724   double RMS4   = sqrt(sig_sq_mean) * sqrt (2.*beta*beta + 2.*(alpha-beta)*(alpha-beta) + 2.*(alpha-2.*beta)*(alpha-2.*beta)) ;
00725 
00726   double noise_rms_fC;
00727 
00728   //  if(sub == 4)  noise_rms_fC = RMS1;
00729   //  else          noise_rms_fC = RMS4;
00730   noise_rms_fC = RMS4;
00731 
00732   noise_rms_fC *= corrfac[sub-1];
00733 
00734   // to convert from above fC to GeV - multiply by gain (GeV/fC)        
00735   //  const HcalGain*  gain = conditions->getGain(detId); 
00736   //  double noise_rms_GeV = noise_rms_fC * gain->getValue(0); // Noise RMS (GeV) for detId channel
00737   return noise_rms_fC;
00738 }
00739