CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCDriftSim.cc
Go to the documentation of this file.
12 #include "Math/GenVector/RotationZ.h"
13 
14 #include "CLHEP/Random/RandFlat.h"
15 #include "CLHEP/Random/RandGaussQ.h"
16 #include "CLHEP/Units/GlobalPhysicalConstants.h"
17 #include "CLHEP/Units/GlobalSystemOfUnits.h"
18 
19 #include <cmath>
20 #include <iostream>
21 
22 static const int N_INTEGRAL_STEPS = 700;
23 
25 : bz(0.), // should make these local variables
26  ycell(0.),
27  zcell(0.),
28  dNdEIntegral(N_INTEGRAL_STEPS, 0.),
29  STEP_SIZE(0.01),
30  ELECTRON_DIFFUSION_COEFF(0.0161),
31  theMagneticField(0)
32 {
33  // just initialize avalanche sim. There has to be a better
34  // way to take the integral of a function!
35  double sum = 0.;
36  int i;
37  for(i = 0; i < N_INTEGRAL_STEPS; ++i) {
38  if(i > 1) {
39  double xx = STEP_SIZE * (double(i) - 0.5 );
40  double dNdE = pow( xx, 0.38) * exp(-1.38*xx);
41 
42  sum += dNdE;
43  }
44  // store this value in the map
45  dNdEIntegral[i] = sum;
46  }
47 
48  // now normalize the whole map
49  for(i = 0; i < N_INTEGRAL_STEPS; ++i) {
50  dNdEIntegral[i] /= sum;
51  }
52 }
53 
54 
56 {
57 }
58 
59 
61 CSCDriftSim::getWireHit(const Local3DPoint & pos, const CSCLayer * layer,
62  int nearestWire, const PSimHit & simHit,
63  CLHEP::HepRandomEngine* engine) {
64 
65  const CSCChamberSpecs * specs = layer->chamber()->specs();
66  const CSCLayerGeometry * geom = layer->geometry();
67  math::LocalPoint clusterPos(pos.x(), pos.y(), pos.z());
68  LogTrace("CSCDriftSim") << "CSCDriftSim: ionization cluster at: " << pos;
69  // set the coordinate system with the x-axis along the nearest wire,
70  // with the origin in the center of the chamber, on that wire.
71  math::LocalVector yShift(0, -1.*geom->yOfWire(nearestWire), 0.);
72  ROOT::Math::RotationZ rotation(-1.*geom->wireAngle());
73 
74  clusterPos = yShift + clusterPos;
75  clusterPos = rotation * clusterPos;
76  GlobalPoint globalPosition = layer->surface().toGlobal(pos);
77  assert(theMagneticField != 0);
78 
79  // bz = theMagneticField->inTesla(globalPosition).z() * 10.;
80 
81  // We need magnetic field in _local_ coordinates
82  // Interface now allows access in kGauss directly.
83  bz = layer->toLocal( theMagneticField->inKGauss( globalPosition ) ).z();
84 
85  // these subroutines label the coordinates in GEANT coords...
86  ycell = clusterPos.z() / specs->anodeCathodeSpacing();
87  zcell = 2.*clusterPos.y() / specs->wireSpacing();
88 
89  LogTrace("CSCDriftSim") << "CSCDriftSim: bz " << bz <<" avgDrift " << avgDrift()
90  << " wireAngle " << geom->wireAngle()
91  << " ycell " << ycell << " zcell " << zcell;
92 
93  double avgPathLength, pathSigma, avgDriftTime, driftTimeSigma;
94  static const float B_FIELD_CUT = 15.f;
95  if(fabs(bz) < B_FIELD_CUT) {
96  avgPathLength = avgPathLengthLowB();
97  pathSigma = pathSigmaLowB();
98  avgDriftTime = avgDriftTimeLowB();
99  driftTimeSigma = driftTimeSigmaLowB();
100  }
101  else {
102  avgPathLength = avgPathLengthHighB();
103  pathSigma = pathSigmaHighB();
104  avgDriftTime = avgDriftTimeHighB();
105  driftTimeSigma = driftTimeSigmaHighB();
106  }
107 
108  // electron drift path length
109  double pathLength = std::max(CLHEP::RandGaussQ::shoot(engine, avgPathLength, pathSigma), 0.);
110 
111  // electron drift distance along the anode wire, including diffusion
112  double diffusionSigma = ELECTRON_DIFFUSION_COEFF * sqrt(pathLength);
113  double x = clusterPos.x() + CLHEP::RandGaussQ::shoot(engine, avgDrift(), driftSigma())
114  + CLHEP::RandGaussQ::shoot(engine, 0., diffusionSigma);
115 
116  // electron drift time
117  double driftTime = std::max(CLHEP::RandGaussQ::shoot(engine, avgDriftTime, driftTimeSigma), 0.);
118 
119  //@@ Parameters which should be defined outside the code
120  // f_att is the fraction of drift electrons lost due to attachment
121  //static const double f_att = 0.5;
122  static const double f_collected = 0.82;
123 
124  // Avalanche charge, with fluctuation ('avalancheCharge()' is the fluctuation generator!)
125  //double charge = avalancheCharge() * f_att * f_collected * gasGain(layer->id()) * e_SI * 1.e15;
126  // doing fattachment by random chance of killing
127  double charge = avalancheCharge(engine) * f_collected * gasGain(layer->id()) * e_SI * 1.e15;
128 
129  float t = simHit.tof() + driftTime;
130  LogTrace("CSCDriftSim") << "CSCDriftSim: tof = " << simHit.tof() <<
131  " driftTime = " << driftTime <<
132  " MEDH = " << CSCDetectorHit(nearestWire, charge, x, t, &simHit);
133  return CSCDetectorHit(nearestWire, charge, x, t, &simHit);
134 }
135 
136 // Generate avalanche fluctuation
137 #include <algorithm>
138 double CSCDriftSim::avalancheCharge(CLHEP::HepRandomEngine* engine) {
139  double returnVal = 0.;
140  // pick a random value along the dNdE integral
141  double x = CLHEP::RandFlat::shoot(engine);
142  size_t i;
143  size_t isiz = dNdEIntegral.size();
144  /*
145  for(i = 0; i < isiz-1; ++i) {
146  if(dNdEIntegral[i] > x) break;
147  }
148  */
149  // return position of first element with a value >= x
150  std::vector<double>::const_iterator p=lower_bound(dNdEIntegral.begin(),dNdEIntegral.end(),x);
151  if (p==dNdEIntegral.end()) i=isiz-1;
152  else i = p-dNdEIntegral.begin();
153 
154 
155  // now extrapolate between values
156  if( i == isiz-1 ) {
157  //edm::LogInfo("CSCDriftSim") << "Funky integral in CSCDriftSim " << x;
158  returnVal = STEP_SIZE * double(i) * dNdEIntegral[i];
159  }
160  else {
161  double x1 = dNdEIntegral[i];
162  double x2 = dNdEIntegral[i+1];
163  returnVal = STEP_SIZE * (double(i) + (x-x1)/(x2-x1));
164  }
165  LogTrace("CSCDriftSim") << "CSCDriftSim: avalanche fluc " << returnVal << " " << x ;
166 
167  return returnVal;
168 }
169 
170 
171 double CSCDriftSim::gasGain(const CSCDetId & detId) const
172 {
173  double result = 130000.; // 1.30 E05
174  // if ME1/1, add some extra gas gain to compensate
175  // for a smaller gas gap
176  int ring = detId.ring();
177  if(detId.station() == 1 && (ring == 1 || ring == 4))
178  {
179  result = 213000.; // 2.13 E05 ( to match real world as of Jan-2011)
180  }
181  return result;
182 }
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:114
int i
Definition: DBlmapReader.cc:9
double avgDrift() const
Definition: CSCDriftParam.cc:8
float tof() const
deprecated name for timeOfFlight()
Definition: PSimHit.h:72
double zcell
Definition: CSCDriftSim.h:66
double pathSigmaHighB()
CSCDetId id() const
Definition: CSCLayer.h:42
CSCDetectorHit getWireHit(const Local3DPoint &ionClusterPosition, const CSCLayer *, int wire, const PSimHit &simHit, CLHEP::HepRandomEngine *)
Definition: CSCDriftSim.cc:61
T y() const
Definition: PV3DBase.h:63
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:62
const MagneticField * theMagneticField
Definition: CSCDriftSim.h:73
double avgPathLengthHighB()
const double STEP_SIZE
Definition: CSCDriftSim.h:69
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
double charge(const std::vector< uint8_t > &Ampls)
float float float z
double driftTimeSigmaLowB()
double driftTimeSigmaHighB()
float wireAngle() const
double avgDriftTimeHighB()
double avalancheCharge(CLHEP::HepRandomEngine *)
Definition: CSCDriftSim.cc:138
#define e_SI
double avgDriftTimeLowB()
const double ELECTRON_DIFFUSION_COEFF
Definition: CSCDriftSim.h:71
float yOfWire(float wire, float x=0.) const
const CSCChamberSpecs * specs() const
Definition: CSCChamber.h:42
const T & max(const T &a, const T &b)
double pathSigmaLowB()
T sqrt(T t)
Definition: SSEVec.h:48
T z() const
Definition: PV3DBase.h:64
tuple result
Definition: query.py:137
double ycell
Definition: CSCDriftSim.h:66
float wireSpacing() const
#define LogTrace(id)
static const int N_INTEGRAL_STEPS
Definition: CSCDriftSim.cc:22
int ring() const
Definition: CSCDetId.h:88
double avgPathLengthLowB()
GlobalVector inKGauss(const GlobalPoint &gp) const
Field value ad specified global point, in KGauss.
Definition: MagneticField.h:34
double driftSigma() const
std::vector< double > dNdEIntegral
Definition: CSCDriftSim.h:68
double gasGain(const CSCDetId &id) const
Definition: CSCDriftSim.cc:171
float anodeCathodeSpacing() const
int station() const
Definition: CSCDetId.h:99
Definition: DDAxes.h:10
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float >, ROOT::Math::LocalCoordinateSystemTag > LocalPoint
point in local coordinate system
Definition: Point3D.h:15
T x() const
Definition: PV3DBase.h:62
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< float >, ROOT::Math::LocalCoordinateSystemTag > LocalVector
vector in local coordinate system
Definition: Vector3D.h:25
const CSCChamber * chamber() const
Definition: CSCLayer.h:52
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:47
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40