CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/FastSimulation/CaloRecHitsProducer/src/EcalPreshowerRecHitsMaker.cc

Go to the documentation of this file.
00001 #include "FastSimulation/CaloRecHitsProducer/interface/EcalPreshowerRecHitsMaker.h"
00002 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h"
00003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00004 #include "FWCore/Framework/interface/ESHandle.h"
00005 #include "DataFormats/Common/interface/Handle.h"
00006 #include "FWCore/Framework/interface/Event.h"
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"        
00010 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
00011 #include "DataFormats/EcalDetId/interface/ESDetId.h"
00012 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00013 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00014 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00015 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00016 
00017 #include "CLHEP/GenericFunctions/Erf.hh"
00018 
00019 EcalPreshowerRecHitsMaker::EcalPreshowerRecHitsMaker(
00020   edm::ParameterSet const & p, 
00021   const RandomEngine * myrandom)
00022   :
00023   random_(myrandom),
00024   myGaussianTailGenerator_(0)
00025 {
00026   edm::ParameterSet RecHitsParameters 
00027     = p.getParameter<edm::ParameterSet>("ECALPreshower");
00028   noise_ = RecHitsParameters.getParameter<double>("Noise");
00029   threshold_ = RecHitsParameters.getParameter<double>("Threshold");
00030   inputCol_=RecHitsParameters.getParameter<edm::InputTag>("MixedSimHits");
00031 
00032   initialized_=false;
00033 
00034   Genfun::Erf myErf;
00035   if(  noise_>0. ) {
00036     preshowerHotFraction_ = 0.5-0.5*myErf(threshold_/noise_/sqrt(2.));
00037     myGaussianTailGenerator_ = new GaussianTail(random_, noise_, threshold_);
00038   } else {
00039     preshowerHotFraction_ =0.;
00040   }
00041 }
00042 
00043 EcalPreshowerRecHitsMaker::~EcalPreshowerRecHitsMaker()
00044 {
00045   initialized_=false;
00046   delete myGaussianTailGenerator_;
00047 }
00048 
00049 void EcalPreshowerRecHitsMaker::clean()
00050 {
00051 
00052   ecalsRecHits_.clear();
00053 }
00054 
00055 
00056 void EcalPreshowerRecHitsMaker::loadEcalPreshowerRecHits(edm::Event &iEvent,ESRecHitCollection & ecalHits)
00057 {
00058   // if no preshower, do nothing
00059 
00060   if(ncells_==0) return;
00061   loadPCaloHits(iEvent);
00062   if( myGaussianTailGenerator_ ) noisify();
00063 
00064   std::map<uint32_t,std::pair<float,bool> >::const_iterator 
00065     it=ecalsRecHits_.begin();
00066   std::map<uint32_t,std::pair<float,bool> >::const_iterator 
00067     itend=ecalsRecHits_.end();
00068 
00069   for(;it!=itend;++it)
00070     {
00071       // check if the hit has been killed 
00072       if(it->second.second) continue;
00073       // check if it is above the threshold
00074       if(it->second.first<threshold_) continue;
00075       ESDetId detid(it->first);
00076       //  std::cout << detid << " " << it->second.first << std::endl;
00077       ecalHits.push_back(EcalRecHit(detid,it->second.first,0.)); 
00078     }
00079 }
00080 
00081 void EcalPreshowerRecHitsMaker::loadPCaloHits(const edm::Event & iEvent)
00082 {
00083 
00084   clean();
00085 
00086   edm::Handle<CrossingFrame<PCaloHit> > cf;
00087   iEvent.getByLabel(inputCol_,cf);
00088   std::auto_ptr<MixCollection<PCaloHit> > colcalo(new MixCollection<PCaloHit>(cf.product(),std::pair<int,int>(0,0) ));
00089 
00090   MixCollection<PCaloHit>::iterator it=colcalo->begin();
00091   MixCollection<PCaloHit>::iterator itend=colcalo->end();
00092   for(;it!=itend;++it)
00093     {
00094       Fill(it->id(),it->energy(),ecalsRecHits_,it.getTrigger());
00095       //      Fill(it->id(),it->energy(),ecalsRecHits_);
00096     }
00097 }
00098 
00099 void EcalPreshowerRecHitsMaker::init(const edm::EventSetup &es)
00100 {
00101   if(initialized_) return;
00102   ncells_=createVectorsOfCells(es);
00103   edm::LogInfo("CaloRecHitsProducer") << "Total number of cells in Preshower " << ncells_ << std::endl;
00104   initialized_=true;
00105 }
00106 
00107 unsigned EcalPreshowerRecHitsMaker::createVectorsOfCells(const edm::EventSetup &es)
00108 {
00109     edm::ESHandle<CaloGeometry> pG;
00110     es.get<CaloGeometryRecord>().get(pG);     
00111     unsigned total=0;
00112 
00113     escells_.reserve(137728);
00114 
00115     const CaloSubdetectorGeometry* geom=pG->getSubdetectorGeometry(DetId::Ecal,EcalPreshower);  
00116     if(geom==0) return 0;
00117     const std::vector<DetId>& ids(geom->getValidDetIds(DetId::Ecal,EcalPreshower));  
00118     for (std::vector<DetId>::const_iterator i=ids.begin(); i!=ids.end(); i++) 
00119       {
00120         escells_.push_back(i->rawId());
00121         ++total;
00122       }
00123     return escells_.size();
00124 }
00125 
00126 void EcalPreshowerRecHitsMaker::noisify()
00127 {
00128   if(ecalsRecHits_.size()<ncells_) 
00129     {
00130       // Not needed anymore, the noise is added when loading the PCaloHits
00131       // noisifySignal(ecalsRecHits_);
00132       noisifySubdet(ecalsRecHits_,escells_,ncells_);
00133     }
00134   else
00135     edm::LogWarning("CaloRecHitsProducer") << "All Preshower cells on ! " << std::endl;
00136 }
00137 
00138 
00139 void EcalPreshowerRecHitsMaker::noisifySubdet(std::map<uint32_t,std::pair<float,bool> >& theMap, const std::vector<uint32_t>& thecells, unsigned ncells)
00140 {
00141   // noise won't be injected in cells that contain signal
00142   double mean = (double)(ncells-theMap.size())*preshowerHotFraction_;
00143   unsigned nps = random_->poissonShoot(mean);
00144   
00145   unsigned ncell=0;
00146   unsigned cellindex=0;
00147   uint32_t cellnumber=0;
00148   std::map<uint32_t,std::pair<float,bool> >::const_iterator itcheck;
00149 
00150   while(ncell < nps)
00151     {
00152       cellindex = (unsigned)(random_->flatShoot()*ncells);
00153       cellnumber = thecells[cellindex];
00154       itcheck=theMap.find(cellnumber);
00155       if(itcheck==theMap.end()) // inject only in empty cells
00156         {
00157           std::pair <float,bool> noisehit(myGaussianTailGenerator_->shoot(),
00158                                           false);
00159           theMap.insert(std::pair<uint32_t,std::pair<float,bool> >
00160                         (cellnumber,noisehit));
00161           ++ncell;
00162         }
00163     }
00164   //  edm::LogInfo("CaloRecHitsProducer") << "CaloRecHitsProducer : added noise in "<<  ncell << " HCAL cells "  << std::endl;
00165 }
00166 
00167 
00168 // Takes a hit (from a PSimHit) and fills a map 
00169 void EcalPreshowerRecHitsMaker::Fill(uint32_t id,float energy, std::map<uint32_t,std::pair<float,bool> >& myHits,bool signal)
00170 {
00171   // The signal hits are singletons (no need to look into a map)
00172   if(signal)
00173     {
00174       // a new hit is created
00175       // we can give a hint for the insert
00176       // Add the noise at this point. We are sure that it won't be added several times
00177       energy += random_->gaussShoot(0.,noise_);
00178       std::pair<float,bool> hit(energy,false); 
00179       // if it is signal, it is already ordered, so we can give a hint for the 
00180       // insert
00181       if(signal)
00182         myHits.insert(myHits.end(),std::pair<uint32_t,std::pair<float,bool> >(id,hit));
00183     }
00184   else       // In this case,there is a risk of duplication. Need to look into the map
00185     {
00186       std::map<uint32_t,std::pair<float,bool> >::iterator itcheck=myHits.find(id);
00187       if(itcheck==myHits.end())
00188         {
00189           energy += random_->gaussShoot(0.,noise_);
00190           std::pair<float,bool> hit(energy,false);        
00191           myHits.insert(std::pair<uint32_t,std::pair<float,bool> >(id,hit));
00192         }
00193       else
00194         {
00195           itcheck->second.first += energy;
00196         }
00197     }  
00198 }
00199 /*
00200 void EcalPreshowerRecHitsMaker::noisifySignal(std::map<uint32_t,std::pair<float,bool> >& theMap)
00201 {
00202   std::map<uint32_t,std::pair<float,bool> >::iterator it=theMap.begin();
00203   std::map<uint32_t,std::pair<float,bool> >::iterator itend=theMap.end();
00204   for(;it!=itend;++it)
00205     {
00206       it->second.first+= random_->gaussShoot(0.,noise_);
00207       if(it->second.first < threshold_)
00208         {
00209           it->second.second=true;
00210           it->second.first = 0.;
00211         }
00212     }
00213 }
00214 */