00001 #include "SimMuon/GEMDigitizer/src/GEMSimAverage.h" 00002 #include "SimMuon/GEMDigitizer/src/GEMSimSetUp.h" 00003 #include "SimMuon/GEMDigitizer/src/GEMSynchronizer.h" 00004 00005 #include "Geometry/GEMGeometry/interface/GEMEtaPartitionSpecs.h" 00006 #include "Geometry/CommonTopologies/interface/TrapezoidalStripTopology.h" 00007 #include "Geometry/GEMGeometry/interface/GEMGeometry.h" 00008 00009 #include "FWCore/ServiceRegistry/interface/Service.h" 00010 #include "FWCore/Utilities/interface/RandomNumberGenerator.h" 00011 #include "FWCore/Utilities/interface/Exception.h" 00012 00013 #include "CLHEP/Random/RandomEngine.h" 00014 #include "CLHEP/Random/RandFlat.h" 00015 #include "CLHEP/Random/RandPoissonQ.h" 00016 00017 #include <cmath> 00018 #include <utility> 00019 #include <map> 00020 00021 00022 GEMSimAverage::GEMSimAverage(const edm::ParameterSet& config) : 00023 GEMSim(config) 00024 { 00025 averageEfficiency_ = config.getParameter<double>("averageEfficiency"); 00026 averageShapingTime_ = config.getParameter<double>("averageShapingTime"); 00027 averageNoiseRate_ = config.getParameter<double>("averageNoiseRate"); 00028 bxwidth_ = config.getParameter<double>("bxwidth"); 00029 minBunch_ = config.getParameter<int>("minBunch"); 00030 maxBunch_ = config.getParameter<int>("maxBunch"); 00031 00032 sync_ = new GEMSynchronizer(config); 00033 } 00034 00035 void GEMSimAverage::setRandomEngine(CLHEP::HepRandomEngine& eng) 00036 { 00037 flatDistr1_ = new CLHEP::RandFlat(eng); 00038 flatDistr2_ = new CLHEP::RandFlat(eng); 00039 poissonDistr_ = new CLHEP::RandPoissonQ(eng); 00040 sync_->setRandomEngine(eng); 00041 } 00042 00043 00044 GEMSimAverage::~GEMSimAverage() 00045 { 00046 if (flatDistr1_) delete flatDistr1_; 00047 if (flatDistr2_) delete flatDistr2_; 00048 if (poissonDistr_) delete poissonDistr_; 00049 delete sync_; 00050 } 00051 00052 void GEMSimAverage::simulate(const GEMEtaPartition* roll, 00053 const edm::PSimHitContainer& simHits) 00054 { 00055 sync_->setGEMSimSetUp(getGEMSimSetUp()); 00056 stripDigiSimLinks_.clear(); 00057 detectorHitMap_.clear(); 00058 stripDigiSimLinks_ = StripDigiSimLinks(roll->id().rawId()); 00059 00060 const Topology& topology = roll->specs()->topology(); 00061 00062 for (const auto & hit: simHits) 00063 { 00064 if (std::abs(hit.particleType()) != 13) continue; 00065 // Check GEM efficiency 00066 if (flatDistr1_->fire(1) > averageEfficiency_) continue; 00067 auto entry = hit.entryPoint(); 00068 00069 int time_hit = sync_->getSimHitBx(&hit); 00070 std::pair<int, int> digi(topology.channel(entry) + 1, time_hit); 00071 00072 detectorHitMap_.insert(DetectorHitMap::value_type(digi, &hit)); 00073 strips_.insert(digi); 00074 } 00075 } 00076 00077 00078 void GEMSimAverage::simulateNoise(const GEMEtaPartition* roll) 00079 { 00080 GEMDetId gemId = roll->id(); 00081 int nstrips = roll->nstrips(); 00082 double area = 0.0; 00083 00084 if ( gemId.region() == 0 ) 00085 { 00086 throw cms::Exception("Geometry") 00087 << "GEMSynchronizer::simulateNoise() - this GEM id is from barrel, which cannot happen."; 00088 } 00089 else 00090 { 00091 const TrapezoidalStripTopology* top_=dynamic_cast<const TrapezoidalStripTopology*>(&(roll->topology())); 00092 float xmin = (top_->localPosition(0.)).x(); 00093 float xmax = (top_->localPosition((float)roll->nstrips())).x(); 00094 float striplength = (top_->stripLength()); 00095 area = striplength*(xmax-xmin); 00096 } 00097 00098 const int nBxing = maxBunch_ - minBunch_ + 1; 00099 double averageNoise = averageNoiseRate_ * nBxing * bxwidth_ * area * 1.0e-9; 00100 00101 int n_hits = poissonDistr_->fire(averageNoise); 00102 00103 for (int i = 0; i < n_hits; i++ ){ 00104 int strip = static_cast<int>(flatDistr1_->fire(1,nstrips)); 00105 int time_hit = static_cast<int>(flatDistr2_->fire(nBxing)) + minBunch_; 00106 std::pair<int, int> digi(strip,time_hit); 00107 strips_.insert(digi); 00108 } 00109 }