00001 #include "Geometry/RPCGeometry/interface/RPCRoll.h"
00002 #include "Geometry/RPCGeometry/interface/RPCRollSpecs.h"
00003 #include "SimMuon/RPCDigitizer/src/RPCSimParam.h"
00004 #include "Geometry/CommonTopologies/interface/RectangularStripTopology.h"
00005 #include "Geometry/CommonTopologies/interface/TrapezoidalStripTopology.h"
00006
00007 #include "FWCore/ServiceRegistry/interface/Service.h"
00008 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 #include "CLHEP/Random/RandomEngine.h"
00011 #include "CLHEP/Random/RandFlat.h"
00012 #include <cmath>
00013
00014 #include "CLHEP/config/CLHEP.h"
00015 #include "CLHEP/Random/Random.h"
00016 #include "CLHEP/Random/RandFlat.h"
00017 #include "CLHEP/Random/RandPoissonQ.h"
00018
00019 RPCSimParam::RPCSimParam(const edm::ParameterSet& config) : RPCSim(config){
00020 aveEff = config.getParameter<double>("averageEfficiency");
00021 aveCls = config.getParameter<double>("averageClusterSize");
00022 resRPC = config.getParameter<double>("timeResolution");
00023 timOff = config.getParameter<double>("timingRPCOffset");
00024 dtimCs = config.getParameter<double>("deltatimeAdjacentStrip");
00025 resEle = config.getParameter<double>("timeJitter");
00026 sspeed = config.getParameter<double>("signalPropagationSpeed");
00027 lbGate = config.getParameter<double>("linkGateWidth");
00028 rpcdigiprint = config.getParameter<bool>("printOutDigitizer");
00029
00030 rate=config.getParameter<double>("Rate");
00031 nbxing=config.getParameter<int>("Nbxing");
00032 gate=config.getParameter<double>("Gate");
00033
00034 if (rpcdigiprint) {
00035 std::cout <<"Average Efficiency = "<<aveEff<<std::endl;
00036 std::cout <<"Average Cluster Size = "<<aveCls<<" strips"<<std::endl;
00037 std::cout <<"RPC Time Resolution = "<<resRPC<<" ns"<<std::endl;
00038 std::cout <<"RPC Signal formation time = "<<timOff<<" ns"<<std::endl;
00039 std::cout <<"RPC adjacent strip delay = "<<dtimCs<<" ns"<<std::endl;
00040 std::cout <<"Electronic Jitter = "<<resEle<<" ns"<<std::endl;
00041 std::cout <<"Signal propagation time = "<<sspeed<<" x c"<<std::endl;
00042 std::cout <<"Link Board Gate Width = "<<lbGate<<" ns"<<std::endl;
00043 }
00044 edm::Service<edm::RandomNumberGenerator> rng;
00045 if ( ! rng.isAvailable()) {
00046 throw cms::Exception("Configuration")
00047 << "RPCDigitizer requires the RandomNumberGeneratorService\n"
00048 "which is not present in the configuration file. You must add the service\n"
00049 "in the configuration file or remove the modules that require it.";
00050 }
00051
00052 _rpcSync = new RPCSynchronizer(config);
00053
00054 rndEngine = &(rng->getEngine());
00055 flatDistribution = new CLHEP::RandFlat(rndEngine);
00056 }
00057
00058
00059 void
00060 RPCSimParam::simulate(const RPCRoll* roll,
00061 const edm::PSimHitContainer& rpcHits)
00062 {
00063 _rpcSync->setRPCSimSetUp(getRPCSimSetUp());
00064 theRpcDigiSimLinks.clear();
00065 theDetectorHitMap.clear();
00066 theRpcDigiSimLinks = RPCDigiSimLinks(roll->id().rawId());
00067
00068 const Topology& topology=roll->specs()->topology();
00069
00070 for (edm::PSimHitContainer::const_iterator _hit = rpcHits.begin();
00071 _hit != rpcHits.end(); ++_hit){
00072
00073
00074 const LocalPoint& entr=_hit->entryPoint();
00075 int time_hit = _rpcSync->getSimHitBx(&(*_hit));
00076
00077
00078 float eff = flatDistribution->fire(1);
00079 if (eff < aveEff) {
00080
00081 int centralStrip = topology.channel(entr)+1;
00082 int fstrip=centralStrip;
00083 int lstrip=centralStrip;
00084
00085 double w = flatDistribution->fire(1);
00086 if (w < 1.e-10) w=1.e-10;
00087 int clsize = static_cast<int>( -1.*aveCls*log(w)+1.);
00088 std::vector<int> cls;
00089 cls.push_back(centralStrip);
00090 if (clsize > 1){
00091 for (int cl = 0; cl < (clsize-1)/2; cl++)
00092 if (centralStrip - cl -1 >= 1 ){
00093 fstrip = centralStrip-cl-1;
00094 cls.push_back(fstrip);
00095 }
00096 for (int cl = 0; cl < (clsize-1)/2; cl++)
00097 if (centralStrip + cl + 1 <= roll->nstrips() ){
00098 lstrip = centralStrip+cl+1;
00099 cls.push_back(lstrip);
00100 }
00101 if (clsize%2 == 0 ){
00102
00103
00104 double deltaw=roll->centreOfStrip(centralStrip).x()-entr.x();
00105 if (deltaw<0.) {
00106 if (lstrip < roll->nstrips() ){
00107 lstrip++;
00108 cls.push_back(lstrip);
00109 }
00110 }else{
00111 if (fstrip > 1 ){
00112 fstrip--;
00113 cls.push_back(fstrip);
00114 }
00115 }
00116 }
00117 }
00118
00119 for (std::vector<int>::iterator i=cls.begin(); i!=cls.end();i++){
00120
00121 std::pair<unsigned int, int> digi(*i,time_hit);
00122
00123 theDetectorHitMap.insert(DetectorHitMap::value_type(digi,&(*_hit)));
00124 strips.insert(digi);
00125 }
00126 }
00127 }
00128 }
00129
00130 RPCSimParam::~RPCSimParam(){}
00131
00132 void RPCSimParam::simulateNoise(const RPCRoll* roll)
00133 {
00134
00135 RPCDetId rpcId = roll->id();
00136 int nstrips = roll->nstrips();
00137 double area = 0.0;
00138
00139 if ( rpcId.region() == 0 )
00140 {
00141 const RectangularStripTopology* top_ = dynamic_cast<const
00142 RectangularStripTopology*>(&(roll->topology()));
00143 float xmin = (top_->localPosition(0.)).x();
00144 float xmax = (top_->localPosition((float)roll->nstrips())).x();
00145 float striplength = (top_->stripLength());
00146 area = striplength*(xmax-xmin);
00147 }
00148 else
00149 {
00150 const TrapezoidalStripTopology* top_=dynamic_cast<const TrapezoidalStripTopology*>(&(roll->topology()));
00151 float xmin = (top_->localPosition(0.)).x();
00152 float xmax = (top_->localPosition((float)roll->nstrips())).x();
00153 float striplength = (top_->stripLength());
00154 area = striplength*(xmax-xmin);
00155 }
00156
00157 double ave = rate*nbxing*gate*area*1.0e-9;
00158 poissonDistribution_ = new CLHEP::RandPoissonQ(rndEngine, ave);
00159 N_hits = poissonDistribution_->fire();
00160
00161 for (int i = 0; i < N_hits; i++ ){
00162
00163 flatDistribution = new CLHEP::RandFlat(rndEngine, 1, nstrips);
00164 int strip = static_cast<int>(flatDistribution->fire());
00165 int time_hit;
00166
00167 flatDistribution = new CLHEP::RandFlat(rndEngine, (nbxing*gate)/gate);
00168 time_hit = (static_cast<int>(flatDistribution->fire())) - nbxing/2;
00169
00170 std::pair<int, int> digi(strip,time_hit);
00171 strips.insert(digi);
00172 }
00173
00174 }