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
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
00072 if(it->second.second) continue;
00073
00074 if(it->second.first<threshold_) continue;
00075 ESDetId detid(it->first);
00076
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
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
00131
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
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())
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
00165 }
00166
00167
00168
00169 void EcalPreshowerRecHitsMaker::Fill(uint32_t id,float energy, std::map<uint32_t,std::pair<float,bool> >& myHits,bool signal)
00170 {
00171
00172 if(signal)
00173 {
00174
00175
00176
00177 energy += random_->gaussShoot(0.,noise_);
00178 std::pair<float,bool> hit(energy,false);
00179
00180
00181 if(signal)
00182 myHits.insert(myHits.end(),std::pair<uint32_t,std::pair<float,bool> >(id,hit));
00183 }
00184 else
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
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214