00001 #include "Geometry/RPCGeometry/interface/RPCRoll.h"
00002 #include "Geometry/RPCGeometry/interface/RPCRollSpecs.h"
00003 #include "SimMuon/RPCDigitizer/src/RPCSimAverage.h"
00004
00005 #include "SimMuon/RPCDigitizer/src/RPCSynchronizer.h"
00006 #include "Geometry/CommonTopologies/interface/RectangularStripTopology.h"
00007 #include "Geometry/CommonTopologies/interface/TrapezoidalStripTopology.h"
00008
00009 #include <cmath>
00010 #include "FWCore/ServiceRegistry/interface/Service.h"
00011 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00012 #include "FWCore/Utilities/interface/Exception.h"
00013 #include "CLHEP/Random/RandomEngine.h"
00014 #include "CLHEP/Random/RandFlat.h"
00015 #include <CLHEP/Random/RandGaussQ.h>
00016 #include <CLHEP/Random/RandFlat.h>
00017
00018 #include <FWCore/Framework/interface/Frameworkfwd.h>
00019 #include <FWCore/Framework/interface/EventSetup.h>
00020 #include <FWCore/Framework/interface/EDAnalyzer.h>
00021 #include <FWCore/Framework/interface/Event.h>
00022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00023 #include <FWCore/Framework/interface/ESHandle.h>
00024
00025 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00026 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
00027 #include "Geometry/RPCGeometry/interface/RPCGeometry.h"
00028 #include <Geometry/Records/interface/MuonGeometryRecord.h>
00029 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
00030 #include "SimMuon/RPCDigitizer/src/RPCSimSetUp.h"
00031
00032 #include<cstring>
00033 #include<iostream>
00034 #include<fstream>
00035 #include<string>
00036 #include<vector>
00037 #include<stdlib.h>
00038 #include <utility>
00039 #include <map>
00040
00041 #include "CLHEP/config/CLHEP.h"
00042 #include "CLHEP/Random/Random.h"
00043 #include "CLHEP/Random/RandFlat.h"
00044 #include "CLHEP/Random/RandPoissonQ.h"
00045
00046 using namespace std;
00047
00048 RPCSimAverage::RPCSimAverage(const edm::ParameterSet& config) :
00049 RPCSim(config)
00050 {
00051
00052 _rpcSync = new RPCSynchronizer(config);
00053
00054 aveEff = config.getParameter<double>("averageEfficiency");
00055 aveCls = config.getParameter<double>("averageClusterSize");
00056 resRPC = config.getParameter<double>("timeResolution");
00057 timOff = config.getParameter<double>("timingRPCOffset");
00058 dtimCs = config.getParameter<double>("deltatimeAdjacentStrip");
00059 resEle = config.getParameter<double>("timeJitter");
00060 sspeed = config.getParameter<double>("signalPropagationSpeed");
00061 lbGate = config.getParameter<double>("linkGateWidth");
00062 rpcdigiprint = config.getParameter<bool>("printOutDigitizer");
00063 rate=config.getParameter<double>("Rate");
00064 nbxing=config.getParameter<int>("Nbxing");
00065 gate=config.getParameter<double>("Gate");
00066
00067 if (rpcdigiprint) {
00068 std::cout <<"Average Efficiency = "<<aveEff<<std::endl;
00069 std::cout <<"Average Cluster Size = "<<aveCls<<" strips"<<std::endl;
00070 std::cout <<"RPC Time Resolution = "<<resRPC<<" ns"<<std::endl;
00071 std::cout <<"RPC Signal formation time = "<<timOff<<" ns"<<std::endl;
00072 std::cout <<"RPC adjacent strip delay = "<<dtimCs<<" ns"<<std::endl;
00073 std::cout <<"Electronic Jitter = "<<resEle<<" ns"<<std::endl;
00074 std::cout <<"Signal propagation time = "<<sspeed<<" x c"<<std::endl;
00075 std::cout <<"Link Board Gate Width = "<<lbGate<<" ns"<<std::endl;
00076 }
00077
00078 edm::Service<edm::RandomNumberGenerator> rng;
00079 if ( ! rng.isAvailable()) {
00080 throw cms::Exception("Configuration")
00081 << "RPCDigitizer requires the RandomNumberGeneratorService\n"
00082 "which is not present in the configuration file. You must add the service\n"
00083 "in the configuration file or remove the modules that require it.";
00084 }
00085
00086 rndEngine = &(rng->getEngine());
00087 flatDistribution = new CLHEP::RandFlat(rndEngine);
00088 }
00089
00090 RPCSimAverage::~RPCSimAverage(){}
00091
00092 int RPCSimAverage::getClSize(float posX)
00093 {
00094
00095 std::map< int, std::vector<double> > clsMap = getRPCSimSetUp()->getClsMap();
00096
00097 int cnt = 1;
00098 int min = 1;
00099 int max = 1;
00100 double func=0.0;
00101 std::vector<double> sum_clsize;
00102
00103 double rr_cl = flatDistribution->fire(1);
00104 if(0.0 <= posX && posX < 0.2) {
00105 func = (clsMap[1])[(clsMap[1]).size()-1]*(rr_cl);
00106 sum_clsize = clsMap[1];
00107 }
00108 if(0.2 <= posX && posX < 0.4) {
00109 func = (clsMap[2])[(clsMap[2]).size()-1]*(rr_cl);
00110 sum_clsize = clsMap[2];
00111 }
00112 if(0.4 <= posX && posX < 0.6) {
00113 func = (clsMap[3])[(clsMap[3]).size()-1]*(rr_cl);
00114 sum_clsize = clsMap[3];
00115 }
00116 if(0.6 <= posX && posX < 0.8) {
00117 func = (clsMap[4])[(clsMap[4]).size()-1]*(rr_cl);
00118 sum_clsize = clsMap[4];
00119 }
00120 if(0.8 <= posX && posX < 1.0) {
00121 func = (clsMap[5])[(clsMap[5]).size()-1]*(rr_cl);
00122 sum_clsize = clsMap[5];
00123 }
00124
00125 for(vector<double>::iterator iter = sum_clsize.begin();
00126 iter != sum_clsize.end(); ++iter){
00127 cnt++;
00128 if(func > (*iter)){
00129 min = cnt;
00130 }
00131 else if(func < (*iter)){
00132 max = cnt;
00133 break;
00134 }
00135 }
00136 return min;
00137 }
00138
00139
00140 void
00141 RPCSimAverage::simulate(const RPCRoll* roll,
00142 const edm::PSimHitContainer& rpcHits)
00143 {
00144 _rpcSync->setRPCSimSetUp(getRPCSimSetUp());
00145 theRpcDigiSimLinks.clear();
00146 theDetectorHitMap.clear();
00147 theRpcDigiSimLinks = RPCDigiSimLinks(roll->id().rawId());
00148
00149 const Topology& topology=roll->specs()->topology();
00150
00151 for (edm::PSimHitContainer::const_iterator _hit = rpcHits.begin();
00152 _hit != rpcHits.end(); ++_hit){
00153
00154
00155 const LocalPoint& entr=_hit->entryPoint();
00156
00157
00158
00159 float posX = roll->strip(_hit->localPosition()) - static_cast<int>(roll->strip(_hit->localPosition()));
00160 int time_hit = _rpcSync->getSimHitBx(&(*_hit));
00161
00162
00163
00164 if (flatDistribution->fire(1) < aveEff) {
00165
00166 int centralStrip = topology.channel(entr)+1;
00167 int fstrip=centralStrip;
00168 int lstrip=centralStrip;
00169
00170 double w = flatDistribution->fire(1);
00171 if (w < 1.e-10) w=1.e-10;
00172 int clsize = this->getClSize(posX);
00173
00174 std::vector<int> cls;
00175 cls.push_back(centralStrip);
00176 if (clsize > 1){
00177 for (int cl = 0; cl < (clsize-1)/2; cl++)
00178 if (centralStrip - cl -1 >= 1 ){
00179 fstrip = centralStrip-cl-1;
00180 cls.push_back(fstrip);
00181 }
00182 for (int cl = 0; cl < (clsize-1)/2; cl++)
00183 if (centralStrip + cl + 1 <= roll->nstrips() ){
00184 lstrip = centralStrip+cl+1;
00185 cls.push_back(lstrip);
00186 }
00187 if (clsize%2 == 0 ){
00188
00189
00190 double deltaw=roll->centreOfStrip(centralStrip).x()-entr.x();
00191 if (deltaw<0.) {
00192 if (lstrip < roll->nstrips() ){
00193 lstrip++;
00194 cls.push_back(lstrip);
00195 }
00196 }else{
00197 if (fstrip > 1 ){
00198 fstrip--;
00199 cls.push_back(fstrip);
00200 }
00201 }
00202 }
00203 }
00204
00205 for (std::vector<int>::iterator i=cls.begin(); i!=cls.end();i++){
00206
00207 std::pair<int, int> digi(*i,time_hit);
00208 theDetectorHitMap.insert(DetectorHitMap::value_type(digi,&(*_hit)));
00209 strips.insert(digi);
00210 }
00211 }
00212 }
00213 }
00214
00215 void RPCSimAverage::simulateNoise(const RPCRoll* roll)
00216 {
00217
00218 RPCDetId rpcId = roll->id();
00219 int nstrips = roll->nstrips();
00220 double area = 0.0;
00221
00222 if ( rpcId.region() == 0 )
00223 {
00224 const RectangularStripTopology* top_ = dynamic_cast<const
00225 RectangularStripTopology*>(&(roll->topology()));
00226 float xmin = (top_->localPosition(0.)).x();
00227 float xmax = (top_->localPosition((float)roll->nstrips())).x();
00228 float striplength = (top_->stripLength());
00229 area = striplength*(xmax-xmin);
00230 }
00231 else
00232 {
00233 const TrapezoidalStripTopology* top_=dynamic_cast<const TrapezoidalStripTopology*>(&(roll->topology()));
00234 float xmin = (top_->localPosition(0.)).x();
00235 float xmax = (top_->localPosition((float)roll->nstrips())).x();
00236 float striplength = (top_->stripLength());
00237 area = striplength*(xmax-xmin);
00238 }
00239
00240 double ave = rate*nbxing*gate*area*1.0e-9;
00241 poissonDistribution_ = new CLHEP::RandPoissonQ(rndEngine, ave);
00242 N_hits = poissonDistribution_->fire();
00243
00244 for (int i = 0; i < N_hits; i++ ){
00245
00246 flatDistribution = new CLHEP::RandFlat(rndEngine, 1,nstrips);
00247 int strip = static_cast<int>(flatDistribution->fire());
00248 int time_hit;
00249
00250 flatDistribution = new CLHEP::RandFlat(rndEngine, (nbxing*gate)/gate);
00251 time_hit = (static_cast<int>(flatDistribution->fire())) - nbxing/2;
00252
00253 std::pair<int, int> digi(strip,time_hit);
00254 strips.insert(digi);
00255 }
00256
00257 }