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();
89  bool digiMuon = false;
90  bool digiElec = false;
91  for (edm::PSimHitContainer::const_iterator hit = simHits.begin(); hit != simHits.end(); ++hit)
92  {
93  if (std::abs(hit->particleType()) != 13 && digitizeOnlyMuons_)
94  continue;
95  double elecEff = 0.;
96  double partMom = hit->pabs();
97  double checkMuonEff = CLHEP::RandFlat::shoot(engine, 0., 1.);
98  double checkElecEff = CLHEP::RandFlat::shoot(engine, 0., 1.);
99  if (std::abs(hit->particleType()) == 13 && checkMuonEff < averageEfficiency_)
100  digiMuon = true;
101  if (std::abs(hit->particleType()) != 13) //consider all non muon particles with gem efficiency to electrons
102  {
103  if (partMom <= 1.95e-03)
104  elecEff = 1.7e-05 * TMath::Exp(2.1 * partMom * 1000.);
105  if (partMom > 1.95e-03 && partMom < 10.e-03)
106  elecEff = 1.34 * log(7.96e-01 * partMom * 1000. - 5.75e-01)
107  / (1.34 + log(7.96e-01 * partMom * 1000. - 5.75e-01));
108  if (partMom > 10.e-03)
109  elecEff = 1.;
110  if (checkElecEff < elecEff)
111  digiElec = true;
112  }
113  if (!(digiMuon || digiElec))
114  continue;
115  const int bx(getSimHitBx(&(*hit), engine));
116  const std::vector<std::pair<int, int> > cluster(simulateClustering(roll, &(*hit), bx, engine));
117  for (auto & digi : cluster)
118  {
120  strips_.insert(digi);
121  }
122  }
123 }
124 
125 int GEMSimpleModel::getSimHitBx(const PSimHit* simhit, CLHEP::HepRandomEngine* engine)
126 {
127  int bx = -999;
128  const LocalPoint simHitPos(simhit->localPosition());
129  const float tof(simhit->timeOfFlight());
130  // random Gaussian time correction due to electronics jitter
131  float randomJitterTime = CLHEP::RandGaussQ::shoot(engine, 0., timeJitter_);
132  const GEMDetId id(simhit->detUnitId());
133  const GEMEtaPartition* roll(geometry_->etaPartition(id));
134  if (!roll)
135  {
136  throw cms::Exception("Geometry")<< "GEMSimpleModel::getSimHitBx() - GEM simhit id does not match any GEM roll id: " << id << "\n";
137  return 999;
138  }
139  if (roll->id().region() == 0)
140  {
141  throw cms::Exception("Geometry") << "GEMSimpleModel::getSimHitBx() - this GEM id is from barrel, which cannot happen: " << roll->id() << "\n";
142  }
143  const double cspeed = 299792458; // signal propagation speed in vacuum in [m/s]
144  const int nstrips = roll->nstrips();
145  float middleStrip = nstrips/2.;
146  LocalPoint middleOfRoll = roll->centreOfStrip(middleStrip);
147  GlobalPoint globMiddleRol = roll->toGlobal(middleOfRoll);
148  double muRadius = sqrt(globMiddleRol.x()*globMiddleRol.x() + globMiddleRol.y()*globMiddleRol.y() +globMiddleRol.z()*globMiddleRol.z());
149  double timeCalibrationOffset_ = (muRadius *1e+9)/(cspeed*1e+2); //[ns]
150 
151  const TrapezoidalStripTopology* top(dynamic_cast<const TrapezoidalStripTopology*> (&(roll->topology())));
152  const float halfStripLength(0.5 * top->stripLength());
153  const float distanceFromEdge(halfStripLength - simHitPos.y());
154 
155  // signal propagation speed in material in [cm/ns]
156  double signalPropagationSpeedTrue = signalPropagationSpeed_ * cspeed * 1e-7; // 1e+2 * 1e-9;
157 
158  // average time for the signal to propagate from the SimHit to the top of a strip
159  const float averagePropagationTime(distanceFromEdge / signalPropagationSpeedTrue);
160  // random Gaussian time correction due to the finite timing resolution of the detector
161  float randomResolutionTime = CLHEP::RandGaussQ::shoot(engine, 0., timeResolution_);
162  const float simhitTime(tof + averageShapingTime_ + randomResolutionTime + averagePropagationTime + randomJitterTime);
163  float referenceTime = 0.;
164  referenceTime = timeCalibrationOffset_ + halfStripLength / signalPropagationSpeedTrue + averageShapingTime_;
165  const float timeDifference(cosmics_ ? (simhitTime - referenceTime) / COSMIC_PAR : simhitTime - referenceTime);
166  // assign the bunch crossing
167  bx = static_cast<int> (std::round((timeDifference) / bxwidth_));
168 
169  // check time
170  const bool debug(false);
171  if (debug)
172  {
173  std::cout << "checktime " << "bx = " << bx << "\tdeltaT = " << timeDifference << "\tsimT = " << simhitTime
174  << "\trefT = " << referenceTime << "\ttof = " << tof << "\tavePropT = " << averagePropagationTime
175  << "\taveRefPropT = " << halfStripLength / signalPropagationSpeedTrue << std::endl;
176  }
177  return bx;
178 }
179 
180 void GEMSimpleModel::simulateNoise(const GEMEtaPartition* roll, CLHEP::HepRandomEngine* engine)
181 //void GEMSimpleModel::simulateNoise(const GEMEtaPartition* roll)
182 {
183  if (!doBkgNoise_)
184  return;
185  const GEMDetId gemId(roll->id());
186  const int nstrips(roll->nstrips());
187  double trArea(0.0);
188  double trStripArea(0.0);
189  if (gemId.region() == 0)
190  {
191  throw cms::Exception("Geometry")
192  << "GEMSynchronizer::simulateNoise() - this GEM id is from barrel, which cannot happen.";
193  }
194  const TrapezoidalStripTopology* top_(dynamic_cast<const TrapezoidalStripTopology*>(&(roll->topology())));
195  const float striplength(top_->stripLength());
196  trStripArea = (roll->pitch()) * striplength;
197  trArea = trStripArea * nstrips;
198  const int nBxing(maxBunch_ - minBunch_ + 1);
199  const float rollRadius(fixedRollRadius_ ? top_->radius() :
200  top_->radius() + CLHEP::RandFlat::shoot(engine, -1.*top_->stripLength()/2., top_->stripLength()/2.));
201 
202 //calculate noise from model
203  double averageNeutralNoiseRatePerRoll = 0.;
204  double averageNoiseElectronRatePerRoll = 0.;
205  double averageNoiseRatePerRoll = 0.;
206  if (gemId.station() == 1)
207  {
208 //simulate neutral background for GE1/1
210  averageNeutralNoiseRatePerRoll = constNeuGE11 * TMath::Exp(slopeNeuGE11 * rollRadius);
211  else
212  averageNeutralNoiseRatePerRoll = constNeuGE11_highRate * TMath::Exp(slopeNeuGE11_highRate * rollRadius);
213 //simulate electron background for GE1/1
215  averageNoiseElectronRatePerRoll = GE11ElecBkgParam0
216  + GE11ElecBkgParam1 * rollRadius
217  + GE11ElecBkgParam2 * rollRadius * rollRadius
218  + GE11ElecBkgParam3 * rollRadius * rollRadius * rollRadius;
219  averageNoiseRatePerRoll = averageNeutralNoiseRatePerRoll + averageNoiseElectronRatePerRoll;
220  }
221  if (gemId.station() == 2)
222  {
223 //simulate neutral background for GE2/1
225  averageNeutralNoiseRatePerRoll = GE21NeuBkgParam0
226  + GE21NeuBkgParam1 * rollRadius
227  + GE21NeuBkgParam2 * rollRadius * rollRadius
228  + GE21NeuBkgParam3 * rollRadius * rollRadius * rollRadius
229  + GE21NeuBkgParam4 * rollRadius * rollRadius * rollRadius * rollRadius
230  + GE21NeuBkgParam5 * rollRadius * rollRadius * rollRadius * rollRadius * rollRadius;
231  else
232  averageNeutralNoiseRatePerRoll = GE21ModNeuBkgParam0
233  + GE21ModNeuBkgParam1 * rollRadius
234  + GE21ModNeuBkgParam2 * rollRadius * rollRadius
235  + GE21ModNeuBkgParam3 * rollRadius * rollRadius * rollRadius
236  + GE21ModNeuBkgParam4 * rollRadius * rollRadius * rollRadius * rollRadius
237  + GE21ModNeuBkgParam5 * rollRadius * rollRadius * rollRadius * rollRadius * rollRadius;
238 //simulate electron background for GE2/1
240  averageNoiseElectronRatePerRoll = constElecGE21 * TMath::Exp(slopeElecGE21 * rollRadius);
241  averageNoiseRatePerRoll = averageNeutralNoiseRatePerRoll + averageNoiseElectronRatePerRoll;
242  }
243 //simulate intrinsic noise
245  {
246  const double aveIntrinsicNoisePerStrip(averageNoiseRate_ * nBxing * bxwidth_ * trStripArea * 1.0e-9);
247  for(int j = 0; j < nstrips; ++j)
248  {
249  CLHEP::RandPoissonQ randPoissonQ(*engine, aveIntrinsicNoisePerStrip);
250  const int n_intrHits(randPoissonQ.fire());
251 
252  for (int k = 0; k < n_intrHits; k++ )
253  {
254  const int time_hit(static_cast<int>(CLHEP::RandFlat::shoot(engine, nBxing)) + minBunch_);
255  std::pair<int, int> digi(k+1,time_hit);
256  strips_.insert(digi);
257  }
258  }
259  }//end simulate intrinsic noise
260 //simulate bkg contribution
261  const double averageNoise(averageNoiseRatePerRoll * nBxing * bxwidth_ * trArea * 1.0e-9);
262  CLHEP::RandPoissonQ randPoissonQ(*engine, averageNoise);
263  const int n_hits(randPoissonQ.fire());
264  for (int i = 0; i < n_hits; ++i)
265  {
266  const int centralStrip(static_cast<int> (CLHEP::RandFlat::shoot(engine, 1, nstrips)));
267  const int time_hit(static_cast<int>(CLHEP::RandFlat::shoot(engine, nBxing)) + minBunch_);
268  if (doNoiseCLS_)
269  {
270  std::vector < std::pair<int, int> > cluster_;
271  cluster_.clear();
272  cluster_.push_back(std::pair<int, int>(centralStrip, time_hit));
273  int clusterSize((CLHEP::RandFlat::shoot(engine)) <= 0.53 ? 1 : 2);
274  if (clusterSize == 2)
275  {
276  if(CLHEP::RandFlat::shoot(engine) < 0.5)
277  {
278  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip - 1 > 0))
279  cluster_.push_back(std::pair<int, int>(centralStrip - 1, time_hit));
280  }
281  else
282  {
283  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip + 1 <= nstrips))
284  cluster_.push_back(std::pair<int, int>(centralStrip + 1, time_hit));
285  }
286  }
287  for (auto & digi : cluster_)
288  {
289  strips_.insert(digi);
290  }
291  } //end doNoiseCLS_
292  else
293  {
294  std::pair<int, int> digi(centralStrip, time_hit);
295  strips_.insert(digi);
296  }
297  }
298  return;
299 }
300 
301 std::vector<std::pair<int, int> > GEMSimpleModel::simulateClustering(const GEMEtaPartition* roll,
302  const PSimHit* simHit, const int bx, CLHEP::HepRandomEngine* engine)
303 {
304  const StripTopology& topology = roll->specificTopology(); // const LocalPoint& entry(simHit->entryPoint());
305  const LocalPoint& hit_position(simHit->localPosition());
306  const int nstrips(roll->nstrips());
307  int centralStrip = 0;
308  if (!(topology.channel(hit_position) + 1 > nstrips))
309  centralStrip = topology.channel(hit_position) + 1;
310  else
311  centralStrip = topology.channel(hit_position);
312  GlobalPoint pointSimHit = roll->toGlobal(hit_position);
313  GlobalPoint pointDigiHit = roll->toGlobal(roll->centreOfStrip(centralStrip));
314  double deltaX = pointSimHit.x() - pointDigiHit.x();
315 // Add central digi to cluster vector
316  std::vector < std::pair<int, int> > cluster_;
317  cluster_.clear();
318  cluster_.push_back(std::pair<int, int>(centralStrip, bx));
319 //simulate cross talk
320  int clusterSize((CLHEP::RandFlat::shoot(engine)) <= 0.53 ? 1 : 2);
321  if (clusterSize == 2)
322  {
323  if (deltaX <= 0)
324  {
325  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip - 1 > 0))
326  cluster_.push_back(std::pair<int, int>(centralStrip - 1, bx));
327  }
328  else
329  {
330  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip + 1 <= nstrips))
331  cluster_.push_back(std::pair<int, int>(centralStrip + 1, bx));
332  }
333  }
334  return cluster_;
335 }
double GE21ModNeuBkgParam1
int i
Definition: DBlmapReader.cc:9
double signalPropagationSpeed_
double GE21ModNeuBkgParam4
edm::DetSet< GEMDigiSimLink > GEMDigiSimLinks
Definition: GEMDigiModel.h:37
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:54
double averageNoiseRate_
T y() const
Definition: PV3DBase.h:63
int getSimHitBx(const PSimHit *, CLHEP::HepRandomEngine *)
void setup() override
GEMDigiSimLinks theGemDigiSimLinks_
Definition: GEMDigiModel.h:80
double slopeElecGE21
const Topology & topology() const
const GEMEtaPartition * etaPartition(GEMDetId id) const
Return a GEMEtaPartition given its id.
Definition: GEMGeometry.cc:99
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:18
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 &)
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:63
double GE21NeuBkgParam5
double averageShapingTime_
std::set< std::pair< int, int > > strips_
Definition: GEMDigiModel.h:65
void clear()
Definition: DetSet.h:69
DetectorHitMap detectorHitMap_
Definition: GEMDigiModel.h:78
double timeResolution_
tuple cout
Definition: gather_cfg.py:145
std::vector< PSimHit > PSimHitContainer
StripDigiSimLinks stripDigiSimLinks_
Definition: GEMDigiModel.h:79
double GE21NeuBkgParam1
edm::DetSet< StripDigiSimLink > StripDigiSimLinks
Definition: GEMDigiModel.h:36
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