CMS 3D CMS Logo

GEMSignalModel.cc
Go to the documentation of this file.
7 #include "CLHEP/Random/RandFlat.h"
8 #include "CLHEP/Random/RandPoissonQ.h"
9 #include "CLHEP/Random/RandGaussQ.h"
10 #include "CLHEP/Units/GlobalPhysicalConstants.h"
12 #include <cmath>
13 #include <utility>
14 #include <map>
15 
18  averageEfficiency_(config.getParameter<double>("averageEfficiency")),
19  averageShapingTime_(config.getParameter<double>("averageShapingTime")),
20  timeResolution_(config.getParameter<double>("timeResolution")),
21  timeJitter_(config.getParameter<double>("timeJitter")),
22  signalPropagationSpeed_(config.getParameter<double>("signalPropagationSpeed")),
23  resolutionX_(config.getParameter<double>("resolutionX")),
24  cspeed(geant_units::operators::convertMmToCm(CLHEP::c_light)),
25  // average energy required to remove an electron due to ionization for an Ar/CO2 gas mixture (in the ratio of 70/30) is 28.1 eV
26  energyMinCut(28.1e-09) {}
27 
29 
32  CLHEP::HepRandomEngine* engine,
33  Strips& strips_,
34  DetectorHitMap& detectorHitMap_) {
35  const GEMStripTopology* top(dynamic_cast<const GEMStripTopology*>(&(roll->topology())));
36  for (const auto& hit : simHits) {
37  if (hit.energyLoss() < energyMinCut)
38  continue;
39  const int bx(getSimHitBx(&hit, engine));
40  const std::vector<std::pair<int, int> >& cluster(simulateClustering(top, &hit, bx, engine));
41  for (const auto& digi : cluster) {
42  detectorHitMap_.emplace(digi, &hit);
43  strips_.emplace(digi);
44  }
45  }
46 }
47 
48 int GEMSignalModel::getSimHitBx(const PSimHit* simhit, CLHEP::HepRandomEngine* engine) {
49  int bx = -999;
50  const LocalPoint simHitPos(simhit->localPosition());
51  const float tof(simhit->timeOfFlight());
52  // random Gaussian time correction due to electronics jitter
53  float randomJitterTime = CLHEP::RandGaussQ::shoot(engine, 0., timeJitter_);
54  const GEMDetId id(simhit->detUnitId());
56  if (!roll) {
57  throw cms::Exception("Geometry") << "GEMSignalModel::getSimHitBx() - GEM simhit id does not match any GEM roll id: "
58  << id << "\n";
59  return 999;
60  }
61  if (roll->id().region() == 0) {
62  throw cms::Exception("Geometry")
63  << "GEMSignalModel::getSimHitBx() - this GEM id is from barrel, which cannot happen: " << roll->id() << "\n";
64  }
65  const int nstrips = roll->nstrips();
66  float middleStrip = nstrips / 2.;
67  const LocalPoint& middleOfRoll = roll->centreOfStrip(middleStrip);
68  const GlobalPoint& globMiddleRol = roll->toGlobal(middleOfRoll);
69  double muRadius = sqrt(globMiddleRol.x() * globMiddleRol.x() + globMiddleRol.y() * globMiddleRol.y() +
70  globMiddleRol.z() * globMiddleRol.z());
71  double timeCalibrationOffset_ = muRadius / cspeed; //[ns]
72 
73  const GEMStripTopology* top(dynamic_cast<const GEMStripTopology*>(&(roll->topology())));
74  const float halfStripLength(0.5 * top->stripLength());
75  const float distanceFromEdge(halfStripLength - simHitPos.y());
76 
77  // signal propagation speed in material in [cm/ns]
78  double signalPropagationSpeedTrue = signalPropagationSpeed_ * cspeed;
79 
80  // average time for the signal to propagate from the SimHit to the top of a strip
81  const float averagePropagationTime(distanceFromEdge / signalPropagationSpeedTrue);
82  // random Gaussian time correction due to the finite timing resolution of the detector
83  float randomResolutionTime = CLHEP::RandGaussQ::shoot(engine, 0., timeResolution_);
84  const float simhitTime(tof + averageShapingTime_ + randomResolutionTime + averagePropagationTime + randomJitterTime);
85  float referenceTime = 0.;
86  referenceTime = timeCalibrationOffset_ + halfStripLength / signalPropagationSpeedTrue + averageShapingTime_;
87  const float timeDifference(simhitTime - referenceTime);
88  // assign the bunch crossing
89  bx = static_cast<int>(std::round((timeDifference) / 25.));
90 
91  // check time
92  LogDebug("GEMDigiProducer") << "checktime "
93  << "bx = " << bx << "\tdeltaT = " << timeDifference << "\tsimT = " << simhitTime
94  << "\trefT = " << referenceTime << "\ttof = " << tof
95  << "\tavePropT = " << averagePropagationTime
96  << "\taveRefPropT = " << halfStripLength / signalPropagationSpeedTrue << "\n";
97  return bx;
98 }
99 
100 std::vector<std::pair<int, int> > GEMSignalModel::simulateClustering(const GEMStripTopology* top,
101  const PSimHit* simHit,
102  const int bx,
103  CLHEP::HepRandomEngine* engine) {
104  const LocalPoint& hit_entry(simHit->entryPoint());
105  const LocalPoint& hit_exit(simHit->exitPoint());
106 
107  LocalPoint start_point, end_point;
108  if (hit_entry.x() < hit_exit.x()) {
109  start_point = hit_entry;
110  end_point = hit_exit;
111  } else {
112  start_point = hit_exit;
113  end_point = hit_entry;
114  }
115 
116  // Add Gaussian noise to the points towards outside.
117  float smeared_start_x = start_point.x() - std::abs(CLHEP::RandGaussQ::shoot(engine, 0, resolutionX_));
118  float smeared_end_x = end_point.x() + std::abs(CLHEP::RandGaussQ::shoot(engine, 0, resolutionX_));
119 
120  LocalPoint smeared_start_point(smeared_start_x, start_point.y(), start_point.z());
121  LocalPoint smeared_end_point(smeared_end_x, end_point.y(), end_point.z());
122 
123  int cluster_start = top->channel(smeared_start_point);
124  int cluster_end = top->channel(smeared_end_point);
125 
126  std::vector<std::pair<int, int> > cluster;
127  for (int strip = cluster_start; strip <= cluster_end; strip++) {
128  cluster.emplace_back(strip, bx);
129  }
130 
131  return cluster;
132 }
const GEMEtaPartition * etaPartition(GEMDetId id) const
Return a GEMEtaPartition given its id.
Definition: GEMGeometry.cc:77
unsigned int detUnitId() const
Definition: PSimHit.h:99
T z() const
Definition: PV3DBase.h:61
std::vector< std::pair< int, int > > simulateClustering(const GEMStripTopology *, const PSimHit *, const int, CLHEP::HepRandomEngine *)
int channel(const LocalPoint &) const override
const double cspeed
Definition: config.py:1
double signalPropagationSpeed_
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
const double energyMinCut
T sqrt(T t)
Definition: SSEVec.h:19
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void simulate(const GEMEtaPartition *, const edm::PSimHitContainer &, CLHEP::HepRandomEngine *, Strips &, DetectorHitMap &) override
double timeResolution_
constexpr NumType convertMmToCm(NumType millimeters)
Definition: angle_units.h:44
int getSimHitBx(const PSimHit *, CLHEP::HepRandomEngine *)
Local3DPoint localPosition() const
Definition: PSimHit.h:54
std::multimap< std::pair< unsigned int, int >, const PSimHit *, std::less< std::pair< unsigned int, int > > > DetectorHitMap
Definition: GEMDigiModel.h:35
std::set< std::pair< int, int > > Strips
Definition: GEMDigiModel.h:31
const GEMGeometry * geometry_
Definition: GEMDigiModel.h:47
float timeOfFlight() const
Definition: PSimHit.h:75
std::vector< PSimHit > PSimHitContainer
~GEMSignalModel() override
double averageShapingTime_
GEMSignalModel(const edm::ParameterSet &)
#define LogDebug(id)