CMS 3D CMS Logo

ME0SimpleModel.cc
Go to the documentation of this file.
1 #include "CLHEP/Units/defs.h"
2 #include "CLHEP/Units/SystemOfUnits.h"
3 #include "CLHEP/Units/GlobalPhysicalConstants.h"
10 #include "CLHEP/Random/RandFlat.h"
11 #include "CLHEP/Random/RandPoissonQ.h"
12 #include "CLHEP/Random/RandGaussQ.h"
13 #include <cmath>
14 #include <utility>
15 #include <map>
16 
19  averageEfficiency_(config.getParameter<double>("averageEfficiency")),
20  averageShapingTime_(config.getParameter<double>("averageShapingTime")),
21  timeResolution_(config.getParameter<double>("timeResolution")),
22  timeJitter_(config.getParameter<double>("timeJitter")),
23  averageNoiseRate_(config.getParameter<double>("averageNoiseRate")),
24  signalPropagationSpeed_(config.getParameter<double>("signalPropagationSpeed")),
25  bxwidth_(config.getParameter<int>("bxwidth")),
26  minBunch_(config.getParameter<int>("minBunch")),
27  maxBunch_(config.getParameter<int>("maxBunch")),
28  digitizeOnlyMuons_(config.getParameter<bool>("digitizeOnlyMuons")),
29  doBkgNoise_(config.getParameter<bool>("doBkgNoise")),
30  doNoiseCLS_(config.getParameter<bool>("doNoiseCLS")),
31  fixedRollRadius_(config.getParameter<bool>("fixedRollRadius")),
32  simulateElectronBkg_(config.getParameter<bool>("simulateElectronBkg")),
33  instLumi_(config.getParameter<double>("instLumi")),
34  rateFact_(config.getParameter<double>("rateFact")),
35  referenceInstLumi_(config.getParameter<double>("referenceInstLumi")),
36  ME0ElecBkgParam0_(config.getParameter<double>("ME0ElecBkgParam0")),
37  ME0ElecBkgParam1_(config.getParameter<double>("ME0ElecBkgParam1")),
38  ME0ElecBkgParam2_(config.getParameter<double>("ME0ElecBkgParam2")),
39  ME0ElecBkgParam3_(config.getParameter<double>("ME0ElecBkgParam3")),
40  ME0NeuBkgParam0_(config.getParameter<double>("ME0NeuBkgParam0")),
41  ME0NeuBkgParam1_(config.getParameter<double>("ME0NeuBkgParam1")),
42  ME0NeuBkgParam2_(config.getParameter<double>("ME0NeuBkgParam2")),
43  ME0NeuBkgParam3_(config.getParameter<double>("ME0NeuBkgParam3")) {}
44 
46 
47 void ME0SimpleModel::setup() { return; }
48 
51  CLHEP::HepRandomEngine* engine) {
53  detectorHitMap_.clear();
55 
58  bool digiMuon = false;
59  bool digiElec = false;
60  for (const auto& hit : simHits) {
61  if (std::abs(hit.particleType()) != 13 && digitizeOnlyMuons_)
62  continue;
63  double elecEff = 0.;
64  double partMom = hit.pabs();
65  double checkMuonEff = CLHEP::RandFlat::shoot(engine, 0., 1.);
66  double checkElecEff = CLHEP::RandFlat::shoot(engine, 0., 1.);
67  if (std::abs(hit.particleType()) == 13 && checkMuonEff < averageEfficiency_)
68  digiMuon = true;
69  if (std::abs(hit.particleType()) != 13) //consider all non muon particles with me0 efficiency to electrons
70  {
71  if (partMom <= 1.95e-03)
72  elecEff = 1.7e-05 * std::exp(2.1 * partMom * 1000.);
73  if (partMom > 1.95e-03 && partMom < 10.e-03)
74  elecEff =
75  1.34 * log(7.96e-01 * partMom * 1000. - 5.75e-01) / (1.34 + log(7.96e-01 * partMom * 1000. - 5.75e-01));
76  if (partMom > 10.e-03)
77  elecEff = 1.;
78  if (checkElecEff < elecEff)
79  digiElec = true;
80  }
81  if (!(digiMuon || digiElec))
82  continue;
83  const int bx(getSimHitBx(&hit, engine));
84  const std::vector<std::pair<int, int> >& cluster(simulateClustering(roll, &hit, bx, engine));
85  for (const auto& digi : cluster) {
86  detectorHitMap_.emplace(digi, &hit);
87  strips_.emplace(digi);
88  }
89  }
90 }
91 
92 int ME0SimpleModel::getSimHitBx(const PSimHit* simhit, CLHEP::HepRandomEngine* engine) {
93  int bx = -999;
94  const LocalPoint& simHitPos(simhit->localPosition());
95  const float tof(simhit->timeOfFlight());
96  // random Gaussian time correction due to electronics jitter
97  float randomJitterTime = CLHEP::RandGaussQ::shoot(engine, 0., timeJitter_);
98  const ME0DetId& id(simhit->detUnitId());
99  const ME0EtaPartition* roll(geometry_->etaPartition(id));
100  if (!roll) {
101  throw cms::Exception("Geometry") << "ME0SimpleModel::getSimHitBx() - ME0 simhit id does not match any ME0 roll id: "
102  << id << "\n";
103  return 999;
104  }
105  if (roll->id().region() == 0) {
106  throw cms::Exception("Geometry")
107  << "ME0SimpleModel::getSimHitBx() - this ME0 id is from barrel, which cannot happen: " << roll->id() << "\n";
108  }
109  const int nstrips = roll->nstrips();
110  float middleStrip = nstrips / 2.;
111  const LocalPoint& middleOfRoll = roll->centreOfStrip(middleStrip);
112  const GlobalPoint& globMiddleRol = roll->toGlobal(middleOfRoll);
113  double muRadius = sqrt(globMiddleRol.x() * globMiddleRol.x() + globMiddleRol.y() * globMiddleRol.y() +
114  globMiddleRol.z() * globMiddleRol.z());
115  double timeCalibrationOffset_ = (muRadius * CLHEP::ns * CLHEP::cm) / (CLHEP::c_light); //[cm/ns]
116  const TrapezoidalStripTopology* top(dynamic_cast<const TrapezoidalStripTopology*>(&(roll->topology())));
117  const float halfStripLength(0.5 * top->stripLength());
118  const float distanceFromEdge(halfStripLength - simHitPos.y());
119 
120  // signal propagation speed in material in [cm/ns]
121  double signalPropagationSpeedTrue = signalPropagationSpeed_ * CLHEP::c_light / (CLHEP::ns * CLHEP::cm);
122  // average time for the signal to propagate from the SimHit to the top of a strip
123  const float averagePropagationTime(distanceFromEdge / signalPropagationSpeedTrue);
124  // random Gaussian time correction due to the finite timing resolution of the detector
125  float randomResolutionTime = CLHEP::RandGaussQ::shoot(engine, 0., timeResolution_);
126  const float simhitTime(tof + averageShapingTime_ + randomResolutionTime + averagePropagationTime + randomJitterTime);
127  float referenceTime = 0.;
128  referenceTime = timeCalibrationOffset_ + halfStripLength / signalPropagationSpeedTrue + averageShapingTime_;
129  const float timeDifference(simhitTime - referenceTime);
130  // assign the bunch crossing
131  bx = static_cast<int>(std::round((timeDifference) / bxwidth_));
132 
133  // check time
134  const bool debug(false);
135  if (debug) {
136  LogDebug("ME0SimpleModel") << "checktime "
137  << "bx = " << bx << "\tdeltaT = " << timeDifference << "\tsimT = " << simhitTime
138  << "\trefT = " << referenceTime << "\ttof = " << tof
139  << "\tavePropT = " << averagePropagationTime
140  << "\taveRefPropT = " << halfStripLength / signalPropagationSpeedTrue << std::endl;
141  }
142  return bx;
143 }
144 
145 void ME0SimpleModel::simulateNoise(const ME0EtaPartition* roll, CLHEP::HepRandomEngine* engine) {
146  if (!doBkgNoise_)
147  return;
148  const ME0DetId me0Id(roll->id());
149  const int nstrips(roll->nstrips());
150  double trArea(0.0);
151  double trStripArea(0.0);
152 
153  if (me0Id.region() == 0) {
154  throw cms::Exception("Geometry")
155  << "ME0Synchronizer::simulateNoise() - this ME0 id is from barrel, which cannot happen.";
156  }
157  const TrapezoidalStripTopology* top_(dynamic_cast<const TrapezoidalStripTopology*>(&(roll->topology())));
158  const float striplength(top_->stripLength());
159  trStripArea = (roll->pitch()) * striplength;
160  trArea = trStripArea * nstrips;
161  const int nBxing(maxBunch_ - minBunch_ + 1);
162  const float rollRadius(
164  ? top_->radius()
165  : top_->radius() + CLHEP::RandFlat::shoot(engine, -1. * top_->stripLength() / 2., top_->stripLength() / 2.));
166 
167  const float rSqrtR = rollRadius * sqrt(rollRadius);
168 
169  //calculate noise from model
170  double averageNeutralNoiseRatePerRoll = 0.;
171  double averageNoiseElectronRatePerRoll = 0.;
172  double averageNoiseRatePerRoll = 0.;
173  if (me0Id.station() != 1) {
174  throw cms::Exception("Geometry")
175  << "ME0SimpleModel::simulateNoise() - this ME0 id is from station 1, which cannot happen: " << roll->id()
176  << "\n";
177  } else {
178  averageNeutralNoiseRatePerRoll = ME0NeuBkgParam0_ * rollRadius * std::exp(ME0NeuBkgParam1_ / rSqrtR) +
179  ME0NeuBkgParam2_ / rSqrtR + ME0NeuBkgParam3_ / (sqrt(rollRadius));
180  //simulate electron background for ME0
182  averageNoiseElectronRatePerRoll = ME0ElecBkgParam0_ * rSqrtR * std::exp(ME0ElecBkgParam1_ / rSqrtR) +
183  ME0ElecBkgParam2_ / rSqrtR + ME0ElecBkgParam3_ / (sqrt(rollRadius));
184  averageNoiseRatePerRoll = averageNeutralNoiseRatePerRoll + averageNoiseElectronRatePerRoll;
185  averageNoiseRatePerRoll *= instLumi_ * rateFact_ * 1.0 / referenceInstLumi_;
186  }
187 
188  //simulate intrinsic noise
190  const double aveIntrinsicNoisePerStrip(averageNoiseRate_ * nBxing * bxwidth_ * trStripArea * 1.0e-9);
191  for (int j = 0; j < nstrips; ++j) {
192  int randPoissonQ = CLHEP::RandPoissonQ::shoot(engine, aveIntrinsicNoisePerStrip);
193 
194  for (int k = 0; k < randPoissonQ; k++) {
195  const int time_hit(static_cast<int>(CLHEP::RandFlat::shoot(engine, nBxing)) + minBunch_);
196  strips_.emplace(k + 1, time_hit);
197  }
198  }
199  } //end simulate intrinsic noise
200 
201  //simulate bkg contribution
202  const double averageNoise(averageNoiseRatePerRoll * nBxing * bxwidth_ * trArea * 1.0e-9);
203  int randPoissonQ = CLHEP::RandPoissonQ::shoot(engine, averageNoise);
204 
205  for (int i = 0; i < randPoissonQ; ++i) {
206  const int centralStrip(static_cast<int>(CLHEP::RandFlat::shoot(engine, 1, nstrips)));
207  const int time_hit(static_cast<int>(CLHEP::RandFlat::shoot(engine, nBxing)) + minBunch_);
208  if (doNoiseCLS_) {
209  std::vector<std::pair<int, int> > cluster;
210  cluster.emplace_back(centralStrip, time_hit);
211  int clusterSize((CLHEP::RandFlat::shoot(engine)) <= 0.53 ? 1 : 2);
212  if (clusterSize == 2) {
213  if (CLHEP::RandFlat::shoot(engine) < 0.5) {
214  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip - 1 > 0))
215  cluster.emplace_back(centralStrip - 1, time_hit);
216  } else {
217  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip + 1 <= nstrips))
218  cluster.emplace_back(centralStrip + 1, time_hit);
219  }
220  }
221  for (const auto& digi : cluster) {
222  strips_.emplace(digi);
223  }
224  } //end doNoiseCLS_
225  else {
226  strips_.emplace(centralStrip, time_hit);
227  }
228  }
229  return;
230 }
231 
232 std::vector<std::pair<int, int> > ME0SimpleModel::simulateClustering(const ME0EtaPartition* roll,
233  const PSimHit* simHit,
234  const int bx,
235  CLHEP::HepRandomEngine* engine) {
236  const StripTopology& topology = roll->specificTopology();
237  const LocalPoint& hit_position(simHit->localPosition());
238  const int nstrips(roll->nstrips());
239  int centralStrip = 0;
240  if (!(topology.channel(hit_position) + 1 > nstrips))
241  centralStrip = topology.channel(hit_position) + 1;
242  else
243  centralStrip = topology.channel(hit_position);
244  const GlobalPoint& pointSimHit = roll->toGlobal(hit_position);
245  const GlobalPoint& pointDigiHit = roll->toGlobal(roll->centreOfStrip(centralStrip));
246  double deltaX = pointSimHit.x() - pointDigiHit.x();
247 
248  // Add central digi to cluster vector
249  std::vector<std::pair<int, int> > cluster;
250  cluster.clear();
251  cluster.emplace_back(centralStrip, bx);
252 
253  //simulate cross talk
254  int clusterSize((CLHEP::RandFlat::shoot(engine)) <= 0.53 ? 1 : 2);
255  if (clusterSize == 2) {
256  if (deltaX <= 0) {
257  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip - 1 > 0))
258  cluster.emplace_back(centralStrip - 1, bx);
259  } else {
260  if (CLHEP::RandFlat::shoot(engine) < averageEfficiency_ && (centralStrip + 1 <= nstrips))
261  cluster.emplace_back(centralStrip + 1, bx);
262  }
263  }
264  return cluster;
265 }
double averageShapingTime_
void setup() override
unsigned int detUnitId() const
Definition: PSimHit.h:97
ME0SimpleModel(const edm::ParameterSet &)
edm::DetSet< ME0DigiSimLink > ME0DigiSimLinks
Definition: ME0DigiModel.h:35
T z() const
Definition: PV3DBase.h:61
double ME0NeuBkgParam2_
double averageEfficiency_
bool simulateElectronBkg_
StripDigiSimLinks stripDigiSimLinks_
Definition: ME0DigiModel.h:75
Definition: config.py:1
int getSimHitBx(const PSimHit *, CLHEP::HepRandomEngine *)
const ME0Geometry * geometry_
Definition: ME0DigiModel.h:62
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
double averageNoiseRate_
T sqrt(T t)
Definition: SSEVec.h:19
double ME0ElecBkgParam0_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
virtual int channel(const LocalPoint &p) const =0
double referenceInstLumi_
double ME0NeuBkgParam0_
ME0DetId id() const
LocalPoint centreOfStrip(int strip) const
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
float pitch() const
double ME0ElecBkgParam2_
ME0DigiSimLinks theME0DigiSimLinks_
Definition: ME0DigiModel.h:76
#define debug
Definition: HDRShower.cc:19
std::set< std::pair< int, int > > strips_
Definition: ME0DigiModel.h:64
double ME0NeuBkgParam3_
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
Local3DPoint localPosition() const
Definition: PSimHit.h:52
double signalPropagationSpeed_
double ME0ElecBkgParam3_
void simulateNoise(const ME0EtaPartition *, CLHEP::HepRandomEngine *) override
std::vector< std::pair< int, int > > simulateClustering(const ME0EtaPartition *, const PSimHit *, const int, CLHEP::HepRandomEngine *) override
const ME0EtaPartition * etaPartition(ME0DetId id) const
Return a etaPartition given its id.
Definition: ME0Geometry.cc:35
~ME0SimpleModel() override
const Topology & topology() const override
const StripTopology & specificTopology() const
bool simulateIntrinsicNoise_
DetectorHitMap detectorHitMap_
Definition: ME0DigiModel.h:74
void clear()
Definition: DetSet.h:71
edm::DetSet< StripDigiSimLink > StripDigiSimLinks
Definition: ME0DigiModel.h:34
float timeOfFlight() const
Definition: PSimHit.h:73
std::vector< PSimHit > PSimHitContainer
void simulateSignal(const ME0EtaPartition *, const edm::PSimHitContainer &, CLHEP::HepRandomEngine *) override
double ME0ElecBkgParam1_
int nstrips() const
Return the chamber this roll belongs to.
double ME0NeuBkgParam1_
double timeResolution_
#define LogDebug(id)