CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GEMSimpleModel.cc
Go to the documentation of this file.
6 #include "CLHEP/Random/RandFlat.h"
7 #include "CLHEP/Random/RandPoissonQ.h"
8 #include "CLHEP/Random/RandGaussQ.h"
9 #include <cmath>
10 #include <utility>
11 #include <map>
12 #include "TMath.h" /* exp */
13 
14 namespace
15 {
16  // "magic" parameter for cosmics
17  const double COSMIC_PAR(37.62);
18 }
19 
21 GEMDigiModel(config)
22 , averageEfficiency_(config.getParameter<double> ("averageEfficiency"))
23 , averageShapingTime_(config.getParameter<double> ("averageShapingTime"))
24 , timeResolution_(config.getParameter<double> ("timeResolution"))
25 , timeJitter_(config.getParameter<double> ("timeJitter"))
26 , averageNoiseRate_(config.getParameter<double> ("averageNoiseRate"))
27 , signalPropagationSpeed_(config.getParameter<double> ("signalPropagationSpeed"))
28 , cosmics_(config.getParameter<bool> ("cosmics"))
29 , bxwidth_(config.getParameter<int> ("bxwidth"))
30 , minBunch_(config.getParameter<int> ("minBunch"))
31 , maxBunch_(config.getParameter<int> ("maxBunch"))
32 , digitizeOnlyMuons_(config.getParameter<bool> ("digitizeOnlyMuons"))
33 , doBkgNoise_(config.getParameter<bool> ("doBkgNoise"))
34 , doNoiseCLS_(config.getParameter<bool> ("doNoiseCLS"))
35 , fixedRollRadius_(config.getParameter<bool> ("fixedRollRadius"))
36 , simulateElectronBkg_(config.getParameter<bool> ("simulateElectronBkg"))
37 , simulateLowNeutralRate_(config.getParameter<bool>("simulateLowNeutralRate"))
38 {
39 //initialise parameters from the fit:
40 //params for pol3 model of electron bkg for GE1/1:
41  GE11ElecBkgParam0 = 3402.63;
42  GE11ElecBkgParam1 = -42.9979;
43  GE11ElecBkgParam2 = 0.188475;
44  GE11ElecBkgParam3 = -0.0002822;
45 //params for expo model of electron bkg for GE2/1:
46  constElecGE21 = 9.74156e+02;
47  slopeElecGE21 = -1.18398e-02;
48 //Neutral Bkg
49 //Low Rate model L=10^{34}cm^{-2}s^{-1}
50 //const and slope for the expo model of neutral bkg for GE1/1:
51  constNeuGE11 = 807.;
52  slopeNeuGE11 = -0.01443;
53 //params for the simple pol5 model of neutral bkg for GE2/1:
54  GE21NeuBkgParam0 = 2954.04;
55  GE21NeuBkgParam1 = -58.7558;
56  GE21NeuBkgParam2 = 0.473481;
57  GE21NeuBkgParam3 = -0.00188292;
58  GE21NeuBkgParam4 = 3.67041e-06;
59  GE21NeuBkgParam5 = -2.80261e-09;
60 //High Rate model L=5x10^{34}cm^{-2}s^{-1}
61 //params for expo model of neutral bkg for GE1/1:
62  constNeuGE11_highRate = 1.02603e+04;
63  slopeNeuGE11_highRate = -1.62806e-02;
64 //params for pol5 model of neutral bkg for GE2/1:
65  GE21ModNeuBkgParam0 = 21583.2;
66  GE21ModNeuBkgParam1 = -476.59;
67  GE21ModNeuBkgParam2 = 4.24037;
68  GE21ModNeuBkgParam3 = -0.0185558;
69  GE21ModNeuBkgParam4 = 3.97809e-05;
70  GE21ModNeuBkgParam5 = -3.34575e-08;
71 }
72 
74 {
75 }
76 
78 {
79  return;
80 }
81 
82 void GEMSimpleModel::simulateSignal(const GEMEtaPartition* roll, const edm::PSimHitContainer& simHits, CLHEP::HepRandomEngine* engine)
83 {
85  detectorHitMap_.clear();
87  bool digiMuon = false;
88  bool digiElec = false;
89  for (edm::PSimHitContainer::const_iterator hit = simHits.begin(); hit != simHits.end(); ++hit)
90  {
91  if (std::abs(hit->particleType()) != 13 && digitizeOnlyMuons_)
92  continue;
93  double elecEff = 0.;
94  double partMom = hit->pabs();
95  double checkMuonEff = CLHEP::RandFlat::shoot(engine, 0., 1.);
96  double checkElecEff = CLHEP::RandFlat::shoot(engine, 0., 1.);
97  if (std::abs(hit->particleType()) == 13 && checkMuonEff < averageEfficiency_)
98  digiMuon = true;
99  if (std::abs(hit->particleType()) != 13) //consider all non muon particles with gem efficiency to electrons
100  {
101  if (partMom <= 1.95e-03)
102  elecEff = 1.7e-05 * TMath::Exp(2.1 * partMom * 1000.);
103  if (partMom > 1.95e-03 && partMom < 10.e-03)
104  elecEff = 1.34 * log(7.96e-01 * partMom * 1000. - 5.75e-01)
105  / (1.34 + log(7.96e-01 * partMom * 1000. - 5.75e-01));
106  if (partMom > 10.e-03)
107  elecEff = 1.;
108  if (checkElecEff < elecEff)
109  digiElec = true;
110  }
111  if (!(digiMuon || digiElec))
112  continue;
113  const int bx(getSimHitBx(&(*hit), engine));
114  const std::vector<std::pair<int, int> > cluster(simulateClustering(roll, &(*hit), bx, engine));
115  for (auto & digi : cluster)
116  {
118  strips_.insert(digi);
119  }
120  }
121 }
122 
123 int GEMSimpleModel::getSimHitBx(const PSimHit* simhit, CLHEP::HepRandomEngine* engine)
124 {
125  int bx = -999;
126  const LocalPoint simHitPos(simhit->localPosition());
127  const float tof(simhit->timeOfFlight());
128  // random Gaussian time correction due to electronics jitter
129  float randomJitterTime = CLHEP::RandGaussQ::shoot(engine, 0., timeJitter_);
130  const GEMDetId id(simhit->detUnitId());
131  const GEMEtaPartition* roll(geometry_->etaPartition(id));
132  if (!roll)
133  {
134  throw cms::Exception("Geometry")<< "GEMSimpleModel::getSimHitBx() - GEM simhit id does not match any GEM roll id: " << id << "\n";
135  return 999;
136  }
137  if (roll->id().region() == 0)
138  {
139  throw cms::Exception("Geometry") << "GEMSimpleModel::getSimHitBx() - this GEM id is from barrel, which cannot happen: " << roll->id() << "\n";
140  }
141  const double cspeed = 299792458; // signal propagation speed in vacuum in [m/s]
142  const int nstrips = roll->nstrips();
143  float middleStrip = nstrips/2.;
144  LocalPoint middleOfRoll = roll->centreOfStrip(middleStrip);
145  GlobalPoint globMiddleRol = roll->toGlobal(middleOfRoll);
146  double muRadius = sqrt(globMiddleRol.x()*globMiddleRol.x() + globMiddleRol.y()*globMiddleRol.y() +globMiddleRol.z()*globMiddleRol.z());
147  double timeCalibrationOffset_ = (muRadius *1e+9)/(cspeed*1e+2); //[ns]
148 
149  const TrapezoidalStripTopology* top(dynamic_cast<const TrapezoidalStripTopology*> (&(roll->topology())));
150  const float halfStripLength(0.5 * top->stripLength());
151  const float distanceFromEdge(halfStripLength - simHitPos.y());
152 
153  // signal propagation speed in material in [cm/ns]
154  double signalPropagationSpeedTrue = signalPropagationSpeed_ * cspeed * 1e-7; // 1e+2 * 1e-9;
155 
156  // average time for the signal to propagate from the SimHit to the top of a strip
157  const float averagePropagationTime(distanceFromEdge / signalPropagationSpeedTrue);
158  // random Gaussian time correction due to the finite timing resolution of the detector
159  float randomResolutionTime = CLHEP::RandGaussQ::shoot(engine, 0., timeResolution_);
160  const float simhitTime(tof + averageShapingTime_ + randomResolutionTime + averagePropagationTime + randomJitterTime);
161  float referenceTime = 0.;
162  referenceTime = timeCalibrationOffset_ + halfStripLength / signalPropagationSpeedTrue + averageShapingTime_;
163  const float timeDifference(cosmics_ ? (simhitTime - referenceTime) / COSMIC_PAR : simhitTime - referenceTime);
164  // assign the bunch crossing
165  bx = static_cast<int> (std::round((timeDifference) / bxwidth_));
166 
167  // check time
168  const bool debug(false);
169  if (debug)
170  {
171  std::cout << "checktime " << "bx = " << bx << "\tdeltaT = " << timeDifference << "\tsimT = " << simhitTime
172  << "\trefT = " << referenceTime << "\ttof = " << tof << "\tavePropT = " << averagePropagationTime
173  << "\taveRefPropT = " << halfStripLength / signalPropagationSpeedTrue << std::endl;
174  }
175  return bx;
176 }
177 
178 void GEMSimpleModel::simulateNoise(const GEMEtaPartition* roll, CLHEP::HepRandomEngine* engine)
179 //void GEMSimpleModel::simulateNoise(const GEMEtaPartition* roll)
180 {
181  if (!doBkgNoise_)
182  return;
183  const GEMDetId gemId(roll->id());
184  const int nstrips(roll->nstrips());
185  double trArea(0.0);
186  double trStripArea(0.0);
187  if (gemId.region() == 0)
188  {
189  throw cms::Exception("Geometry")
190  << "GEMSynchronizer::simulateNoise() - this GEM id is from barrel, which cannot happen.";
191  }
192  const TrapezoidalStripTopology* top_(dynamic_cast<const TrapezoidalStripTopology*>(&(roll->topology())));
193  const float striplength(top_->stripLength());
194  trStripArea = (roll->pitch()) * striplength;
195  trArea = trStripArea * nstrips;
196  const int nBxing(maxBunch_ - minBunch_ + 1);
197  const float rollRadius(fixedRollRadius_ ? top_->radius() :
198  top_->radius() + CLHEP::RandFlat::shoot(engine, -1.*top_->stripLength()/2., top_->stripLength()/2.));
199 
200 //calculate noise from model
201  double averageNeutralNoiseRatePerRoll = 0.;
202  double averageNoiseElectronRatePerRoll = 0.;
203  double averageNoiseRatePerRoll = 0.;
204  if (gemId.station() == 1)
205  {
206 //simulate neutral background for GE1/1
208  averageNeutralNoiseRatePerRoll = constNeuGE11 * TMath::Exp(slopeNeuGE11 * rollRadius);
209  else
210  averageNeutralNoiseRatePerRoll = constNeuGE11_highRate * TMath::Exp(slopeNeuGE11_highRate * rollRadius);
211 //simulate electron background for GE1/1
213  averageNoiseElectronRatePerRoll = GE11ElecBkgParam0
214  + GE11ElecBkgParam1 * rollRadius
215  + GE11ElecBkgParam2 * rollRadius * rollRadius
216  + GE11ElecBkgParam3 * rollRadius * rollRadius * rollRadius;
217  averageNoiseRatePerRoll = averageNeutralNoiseRatePerRoll + averageNoiseElectronRatePerRoll;
218  }
219  if (gemId.station() == 2 || gemId.station() == 3)
220  {
221 //simulate neutral background for GE2/1
223  averageNeutralNoiseRatePerRoll = GE21NeuBkgParam0
224  + GE21NeuBkgParam1 * rollRadius
225  + GE21NeuBkgParam2 * rollRadius * rollRadius
226  + GE21NeuBkgParam3 * rollRadius * rollRadius * rollRadius
227  + GE21NeuBkgParam4 * rollRadius * rollRadius * rollRadius * rollRadius
228  + GE21NeuBkgParam5 * rollRadius * rollRadius * rollRadius * rollRadius * rollRadius;
229  else
230  averageNeutralNoiseRatePerRoll = GE21ModNeuBkgParam0
231  + GE21ModNeuBkgParam1 * rollRadius
232  + GE21ModNeuBkgParam2 * rollRadius * rollRadius
233  + GE21ModNeuBkgParam3 * rollRadius * rollRadius * rollRadius
234  + GE21ModNeuBkgParam4 * rollRadius * rollRadius * rollRadius * rollRadius
235  + GE21ModNeuBkgParam5 * rollRadius * rollRadius * rollRadius * rollRadius * rollRadius;
236 //simulate electron background for GE2/1
238  averageNoiseElectronRatePerRoll = constElecGE21 * TMath::Exp(slopeElecGE21 * rollRadius);
239  averageNoiseRatePerRoll = averageNeutralNoiseRatePerRoll + averageNoiseElectronRatePerRoll;
240  }
241 //simulate intrinsic noise
243  {
244  const double aveIntrinsicNoisePerStrip(averageNoiseRate_ * nBxing * bxwidth_ * trStripArea * 1.0e-9);
245  for(int j = 0; j < nstrips; ++j)
246  {
247  CLHEP::RandPoissonQ randPoissonQ(*engine, aveIntrinsicNoisePerStrip);
248  const int n_intrHits(randPoissonQ.fire());
249 
250  for (int k = 0; k < n_intrHits; k++ )
251  {
252  const int time_hit(static_cast<int>(CLHEP::RandFlat::shoot(engine, nBxing)) + minBunch_);
253  std::pair<int, int> digi(k+1,time_hit);
254  strips_.insert(digi);
255  }
256  }
257  }//end simulate intrinsic noise
258 //simulate bkg contribution
259  const double averageNoise(averageNoiseRatePerRoll * nBxing * bxwidth_ * trArea * 1.0e-9);
260  CLHEP::RandPoissonQ randPoissonQ(*engine, averageNoise);
261  const int n_hits(randPoissonQ.fire());
262  for (int i = 0; i < n_hits; ++i)
263  {
264  const int centralStrip(static_cast<int> (CLHEP::RandFlat::shoot(engine, 1, nstrips)));
265  const int time_hit(static_cast<int>(CLHEP::RandFlat::shoot(engine, nBxing)) + minBunch_);
266  if (doNoiseCLS_)
267  {
268  std::vector < std::pair<int, int> > cluster_;
269  cluster_.clear();
270  cluster_.push_back(std::pair<int, int>(centralStrip, time_hit));
271  int clusterSize((CLHEP::RandFlat::shoot(engine)) <= 0.53 ? 1 : 2);
272  if (clusterSize == 2)
273  {
274  if(CLHEP::RandFlat::shoot(engine) < 0.5)
275  {
276  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip - 1 > 0))
277  cluster_.push_back(std::pair<int, int>(centralStrip - 1, time_hit));
278  }
279  else
280  {
281  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip + 1 <= nstrips))
282  cluster_.push_back(std::pair<int, int>(centralStrip + 1, time_hit));
283  }
284  }
285  for (auto & digi : cluster_)
286  {
287  strips_.insert(digi);
288  }
289  } //end doNoiseCLS_
290  else
291  {
292  std::pair<int, int> digi(centralStrip, time_hit);
293  strips_.insert(digi);
294  }
295  }
296  return;
297 }
298 
299 std::vector<std::pair<int, int> > GEMSimpleModel::simulateClustering(const GEMEtaPartition* roll,
300  const PSimHit* simHit, const int bx, CLHEP::HepRandomEngine* engine)
301 {
302  const StripTopology& topology = roll->specificTopology(); // const LocalPoint& entry(simHit->entryPoint());
303  const LocalPoint& hit_position(simHit->localPosition());
304  const int nstrips(roll->nstrips());
305  int centralStrip = 0;
306  if (!(topology.channel(hit_position) + 1 > nstrips))
307  centralStrip = topology.channel(hit_position) + 1;
308  else
309  centralStrip = topology.channel(hit_position);
310  GlobalPoint pointSimHit = roll->toGlobal(hit_position);
311  GlobalPoint pointDigiHit = roll->toGlobal(roll->centreOfStrip(centralStrip));
312  double deltaX = pointSimHit.x() - pointDigiHit.x();
313 // Add central digi to cluster vector
314  std::vector < std::pair<int, int> > cluster_;
315  cluster_.clear();
316  cluster_.push_back(std::pair<int, int>(centralStrip, bx));
317 //simulate cross talk
318  int clusterSize((CLHEP::RandFlat::shoot(engine)) <= 0.53 ? 1 : 2);
319  if (clusterSize == 2)
320  {
321  if (deltaX <= 0)
322  {
323  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip - 1 > 0))
324  cluster_.push_back(std::pair<int, int>(centralStrip - 1, bx));
325  }
326  else
327  {
328  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip + 1 <= nstrips))
329  cluster_.push_back(std::pair<int, int>(centralStrip + 1, bx));
330  }
331  }
332  return cluster_;
333 }
double GE21ModNeuBkgParam1
int i
Definition: DBlmapReader.cc:9
double signalPropagationSpeed_
double GE21ModNeuBkgParam4
double slopeNeuGE11_highRate
CaloTopology const * topology(0)
double constNeuGE11_highRate
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
double averageNoiseRate_
T y() const
Definition: PV3DBase.h:63
int getSimHitBx(const PSimHit *, CLHEP::HepRandomEngine *)
double slopeElecGE21
const Topology & topology() const
const GEMEtaPartition * etaPartition(GEMDetId id) const
Return a GEMEtaPartition given its id.
Definition: GEMGeometry.cc:103
double GE21ModNeuBkgParam5
GEMDetId id() const
LocalPoint centreOfStrip(int strip) const
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
int nstrips() const
number of readout strips in partition
double GE11ElecBkgParam2
float timeOfFlight() const
Definition: PSimHit.h:69
double GE11ElecBkgParam0
bool simulateIntrinsicNoise_
double GE11ElecBkgParam3
Local3DPoint localPosition() const
Definition: PSimHit.h:44
T sqrt(T t)
Definition: SSEVec.h:48
double averageEfficiency_
T z() const
Definition: PV3DBase.h:64
double GE11ElecBkgParam1
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
std::vector< std::pair< int, int > > simulateClustering(const GEMEtaPartition *, const PSimHit *, const int, CLHEP::HepRandomEngine *) override
virtual int channel(const LocalPoint &p) const =0
const StripTopology & specificTopology() const
bool simulateLowNeutralRate_
GEMSimpleModel(const edm::ParameterSet &)
Container::value_type value_type
float pitch() const
double GE21NeuBkgParam2
bool simulateElectronBkg_
double GE21ModNeuBkgParam2
#define debug
Definition: HDRShower.cc:19
double GE21ModNeuBkgParam0
double constElecGE21
double GE21NeuBkgParam4
double GE21ModNeuBkgParam3
double GE21NeuBkgParam3
double GE21NeuBkgParam0
tuple simHits
Definition: trackerHits.py:16
void simulateNoise(const GEMEtaPartition *, CLHEP::HepRandomEngine *) override
const GEMGeometry * geometry_
Definition: GEMDigiModel.h:60
double GE21NeuBkgParam5
double averageShapingTime_
std::set< std::pair< int, int > > strips_
Definition: GEMDigiModel.h:62
void clear()
Definition: DetSet.h:69
DetectorHitMap detectorHitMap_
Definition: GEMDigiModel.h:74
double timeResolution_
tuple cout
Definition: gather_cfg.py:121
std::vector< PSimHit > PSimHitContainer
StripDigiSimLinks stripDigiSimLinks_
Definition: GEMDigiModel.h:75
double GE21NeuBkgParam1
edm::DetSet< StripDigiSimLink > StripDigiSimLinks
Definition: GEMDigiModel.h:35
T x() const
Definition: PV3DBase.h:62
void simulateSignal(const GEMEtaPartition *, const edm::PSimHitContainer &, CLHEP::HepRandomEngine *) override
unsigned int detUnitId() const
Definition: PSimHit.h:93