CbmRoot
CbmStsSimSensorDssd.cxx
Go to the documentation of this file.
1 
6 #include "CbmStsSimSensorDssd.h"
7 
8 #include <sstream>
9 
10 #include "CbmStsDefs.h"
11 #include "CbmStsDigitize.h"
12 #include "CbmStsParSensorCond.h"
13 #include "CbmStsParSim.h"
14 #include "CbmStsSensorPoint.h"
15 #include "CbmStsSetup.h"
16 #include "CbmStsSimModule.h"
17 
18 
19 using std::string;
20 using std::stringstream;
21 using namespace CbmSts;
22 
23 
24 // ----- Constructor ---------------------------------------------------
26  : CbmStsSimSensor(element) {}
27 // -------------------------------------------------------------------------
28 
29 
30 // ----- Process one MC Point -------------------------------------------
32 
33  // --- Catch if parameters are not set
34  assert(fIsSet);
35 
36  // --- Number of created charge signals (coded front/back side)
37  Int_t nSignals = 0;
38 
39  // --- Reset the strip charge arrays
40  fStripCharge[0].Reset(); // front side
41  fStripCharge[1].Reset(); // back side
42 
43  // --- Produce charge and propagate it to the readout strips
44  ProduceCharge(point);
45 
46  // --- Cross talk
47  if (fSettings->CrossTalk()) {
48  Double_t ctcoeff = GetConditions()->GetCrossTalkCoeff();
49  CrossTalk(ctcoeff);
50  }
51 
52  // --- Stop here if no module is connected (e.g. for test purposes)
53  if (!GetModule()) return 0;
54 
55  // --- Register charges in strips to the module
56  Int_t nCharges[2] = {0, 0};
57  for (Int_t side = 0; side < 2; side++) { // front and back side
58 
59  for (Int_t strip = 0; strip < GetNofStrips(side); strip++) {
60  if (fStripCharge[side][strip] > 0.) {
62  side, strip, fStripCharge[side][strip], point->GetTime());
63  nCharges[side]++;
64  } //? charge in strip
65  } //# strips
66 
67  } //# front and back side
68 
69  // Code number of signals
70  nSignals = 1000 * nCharges[0] + nCharges[1];
71 
72  return nSignals;
73 }
74 // -------------------------------------------------------------------------
75 
76 
77 // ----- Charge status -------------------------------------------------
79  stringstream ss;
80  ss << GetName() << ": Charge status: \n";
81  for (Int_t side = 0; side < 2; side++) {
82  for (Int_t strip = 0; strip < GetNofStrips(side); strip++) {
83  if (fStripCharge[side][strip] > 0.)
84  ss << " " << (side ? "Back " : "Front ") << "strip " << strip
85  << " charge " << fStripCharge[side][strip] << "\n";
86  } //# strips
87  } //# front and back side
88  ss << " Total: front side " << (fStripCharge[0]).GetSum()
89  << ", back side " << (fStripCharge[1]).GetSum();
90  return ss.str();
91 }
92 // -------------------------------------------------------------------------
93 
94 
95 // ----- Cross talk calculation ----------------------------------------
96 void CbmStsSimSensorDssd::CrossTalk(Double_t ctcoeff) {
97 
98  for (Int_t side = 0; side < 2; side++) { // front and back side
99 
100  // Number of strips for this side
101  Int_t nStrips = GetNofStrips(side);
102 
103  // First strip
104  Double_t qLeft = 0.;
105  Double_t qCurrent = fStripCharge[side][0];
106  fStripCharge[side][0] =
107  (1. - ctcoeff) * qCurrent + ctcoeff * fStripCharge[side][1];
108 
109  // Strips 1 to n-2
110  for (Int_t strip = 1; strip < nStrips - 1; strip++) {
111  qLeft = qCurrent;
112  qCurrent = fStripCharge[side][strip];
113  fStripCharge[side][strip] =
114  ctcoeff * (qLeft + fStripCharge[side][strip + 1])
115  + (1. - 2. * ctcoeff) * qCurrent;
116  } //# strips
117 
118  // Last strip
119  qLeft = qCurrent;
120  qCurrent = fStripCharge[side][nStrips - 1];
121  fStripCharge[side][nStrips - 1] =
122  ctcoeff * qLeft + (1. - ctcoeff) * qCurrent;
123 
124  } //# front and back side
125 }
126 // -------------------------------------------------------------------------
127 
128 
129 // ----- Check whether a point is inside the active area ---------------
130 Bool_t CbmStsSimSensorDssd::IsInside(Double_t x, Double_t y) {
131  if (x < -fDx / 2.) return kFALSE;
132  if (x > fDx / 2.) return kFALSE;
133  if (y < -fDy / 2.) return kFALSE;
134  if (y > fDy / 2.) return kFALSE;
135  return kTRUE;
136 }
137 // -------------------------------------------------------------------------
138 
139 
140 // ----- Lorentz shift -------------------------------------------------
142  Int_t chargeType,
143  Double_t bY) const {
144 
145  assert(chargeType == 0 || chargeType == 1);
146 
147  // --- Drift distance to readout plane
148  // Electrons drift to the front side (z = d/2), holes to the back side (z = -d/2)
149  assert(chargeType == 0 || chargeType == 1);
150  Double_t driftZ = 0.;
151  if (chargeType == 0)
152  driftZ = fDz / 2. - z; // electrons
153  else if (chargeType == 1)
154  driftZ = fDz / 2. + z; // holes
155  else
156  driftZ = 0.;
157 
158  // --- Hall mobility
159  Double_t vBias = GetConditions()->GetVbias();
160  Double_t vFd = GetConditions()->GetVfd();
161  Double_t eField = CbmStsPhysics::ElectricField(vBias, vFd, fDz, z + fDz / 2.);
162  Double_t eFieldMax = CbmStsPhysics::ElectricField(vBias, vFd, fDz, fDz);
163  Double_t eFieldMin = CbmStsPhysics::ElectricField(vBias, vFd, fDz, 0.);
164 
165  Double_t muHall;
166  if (chargeType == 0) // electrons
167  muHall =
168  GetConditions()->GetHallMobility((eField + eFieldMax) / 2., chargeType);
169  else // holes
170  muHall =
171  GetConditions()->GetHallMobility((eField + eFieldMin) / 2., chargeType);
172 
173  // --- The direction of the shift is the same for electrons and holes.
174  // --- Holes drift in negative z direction, the field is in
175  // --- positive y direction, thus the Lorentz force v x B acts in positive
176  // --- x direction. Electrons drift in the opposite (positive z) direction,
177  // --- but the have also the opposite charge sign, so the Lorentz force
178  // --- on them is also in the positive x direction.
179  Double_t shift = muHall * bY * driftZ * 1.e-4;
180  // The factor 1.e-4 is because bZ is in T = Vs/m**2, but muHall is in
181  // cm**2/(Vs) and z in cm.
182 
183  return shift;
184 }
185 // -------------------------------------------------------------------------
186 
187 
188 // ----- Produce charge and propagate it to the readout strips ---------
190 
191  // Energy-loss model
192  CbmStsELoss eLossModel = fSettings->ELossModel();
193 
194  // Total charge created in the sensor: is calculated from the energy loss
195  Double_t chargeTotal =
196  point->GetELoss() / CbmStsPhysics::PairCreationEnergy(); // in e
197 
198  // For ideal energy loss, just have all charge in the mid-point of the
199  // trajectory
200  if (eLossModel == CbmStsELoss::kIdeal) {
201  Double_t xP = 0.5 * (point->GetX1() + point->GetX2());
202  Double_t yP = 0.5 * (point->GetY1() + point->GetY2());
203  Double_t zP = 0.5 * (point->GetZ1() + point->GetZ2());
205  xP, yP, zP, chargeTotal, point->GetBy(), 0); // front side (n)
207  xP, yP, zP, chargeTotal, point->GetBy(), 1); // back side (p)
208  return;
209  }
210 
211  // Kinetic energy
212  Double_t mass = CbmStsPhysics::ParticleMass(point->GetPid());
213  Double_t eKin =
214  TMath::Sqrt(point->GetP() * point->GetP() + mass * mass) - mass;
215 
216  // Length of trajectory inside sensor and its projections
217  Double_t trajLx = point->GetX2() - point->GetX1();
218  Double_t trajLy = point->GetY2() - point->GetY1();
219  Double_t trajLz = point->GetZ2() - point->GetZ1();
220  Double_t trajLength =
221  TMath::Sqrt(trajLx * trajLx + trajLy * trajLy + trajLz * trajLz);
222 
223  // The trajectory is sub-divided into equidistant steps, with a step size
224  // close to 3 micrometer.
225  Double_t stepSizeTarget = 3.e-4; // targeted step size is 3 micrometer
226  Int_t nSteps = TMath::Nint(trajLength / stepSizeTarget);
227  if (nSteps == 0) nSteps = 1; // assure at least one step
228  Double_t stepSize = trajLength / nSteps;
229  Double_t stepSizeX = trajLx / nSteps;
230  Double_t stepSizeY = trajLy / nSteps;
231  Double_t stepSizeZ = trajLz / nSteps;
232 
233  // Average charge per step, used for uniform distribution
234  Double_t chargePerStep = chargeTotal / nSteps;
235 
236  // Stopping power, needed for energy loss fluctuations
237  Double_t dedx = 0.;
238 
239  if (eLossModel == CbmStsELoss::kUrban)
240  dedx = CbmStsPhysics::Instance()->StoppingPower(eKin, point->GetPid());
241 
242  // Stepping over the trajectory
243  Double_t chargeSum = 0.;
244  Double_t xStep = point->GetX1() - 0.5 * stepSizeX;
245  Double_t yStep = point->GetY1() - 0.5 * stepSizeY;
246  Double_t zStep = point->GetZ1() - 0.5 * stepSizeZ;
247  for (Int_t iStep = 0; iStep < nSteps; iStep++) {
248  xStep += stepSizeX;
249  yStep += stepSizeY;
250  zStep += stepSizeZ;
251 
252  // Charge for this step
253  Double_t chargeInStep = chargePerStep; // uniform energy loss
254  if (eLossModel == CbmStsELoss::kUrban) // energy loss fluctuations
255  chargeInStep =
256  CbmStsPhysics::Instance()->EnergyLoss(stepSize, mass, eKin, dedx)
258  chargeSum += chargeInStep;
259 
260  // Propagate charge to strips
262  xStep, yStep, zStep, chargeInStep, point->GetBy(), 0); // front
264  xStep, yStep, zStep, chargeInStep, point->GetBy(), 1); // back
265 
266  } //# steps of the trajectory
267 
268  // For fluctuations: normalise to the total charge from GEANT.
269  // Since the number of steps is finite (about 100), the average
270  // charge per step does not coincide with the expectation value.
271  // In order to be consistent with the transport, the charges are
272  // re-normalised.
273  if (eLossModel == CbmStsELoss::kUrban) {
274  for (Int_t side = 0; side < 2; side++) { // front and back side
275  for (Int_t strip = 0; strip < GetNofStrips(side); strip++)
276  fStripCharge[side][strip] *= (chargeTotal / chargeSum);
277  } //# front and back side
278  } //? E loss fluctuations
279 }
280 // -------------------------------------------------------------------------
281 
282 
283 // ----- Register charge to the module ----------------------------------
285  Int_t strip,
286  Double_t charge,
287  Double_t time) const {
288 
289  // --- Check existence of module
290  assert(GetModule());
291 
292  // --- Determine module channel for given sensor strip
293  Int_t channel = GetModuleChannel(strip, side, GetSensorId());
294 
295  // --- Get the MC link information
296  Int_t index = -1;
297  Int_t entry = -1;
298  Int_t file = -1;
299  if (GetCurrentLink()) {
300  index = GetCurrentLink()->GetIndex();
301  entry = GetCurrentLink()->GetEntry();
302  file = GetCurrentLink()->GetFile();
303  }
304 
305  // --- Send signal to module
306  GetModule()->AddSignal(channel, time, charge, index, entry, file);
307 }
308 // -------------------------------------------------------------------------
309 
310 
CbmStsParSensorCond::GetHallMobility
Double_t GetHallMobility(Double_t eField, Int_t chargeType) const
Hall mobility.
Definition: CbmStsParSensorCond.cxx:90
CbmSts
Definition: CbmStsDefs.h:15
CbmStsSetup.h
CbmStsSensorPoint::GetX2
Double_t GetX2() const
Exit x coordinate [cm].
Definition: CbmStsSensorPoint.h:59
CbmStsELoss::kUrban
@ kUrban
CbmStsSensorPoint::GetTime
Double_t GetTime() const
Time [ns].
Definition: CbmStsSensorPoint.h:64
CbmStsSimModule::AddSignal
void AddSignal(UShort_t channel, Double_t time, Double_t charge, Int_t index=0, Int_t entry=0, Int_t file=0)
Definition: CbmStsSimModule.cxx:41
CbmStsSimSensorDssd::fIsSet
Bool_t fIsSet
Flag whether sensor is properly initialised.
Definition: CbmStsSimSensorDssd.h:93
CbmStsSimSensor::fSettings
const CbmStsParSim * fSettings
Simulation module.
Definition: CbmStsSimSensor.h:168
CbmStsDigitize.h
CbmStsSensorPoint
Container class for a local point in a STS sensor.
Definition: CbmStsSensorPoint.h:19
CbmStsSimSensorDssd::fStripCharge
TArrayD fStripCharge[2]
Definition: CbmStsSimSensorDssd.h:97
CbmStsSimSensor
Class for the simulation of a sensor in the CBM-STS.
Definition: CbmStsSimSensor.h:32
CbmStsSimSensor::GetConditions
const CbmStsParSensorCond * GetConditions() const
Sensor conditions.
Definition: CbmStsSimSensor.h:63
CbmStsSimSensorDssd::LorentzShift
Double_t LorentzShift(Double_t z, Int_t chargeType, Double_t bY) const
Lorentz shift in the x coordinate.
Definition: CbmStsSimSensorDssd.cxx:141
CbmStsPhysics::StoppingPower
Double_t StoppingPower(Double_t eKin, Int_t pid)
Stopping power (average specific energy loss) in Silicon.
Definition: CbmStsPhysics.cxx:358
CbmStsParSensorCond.h
CbmStsPhysics::Instance
static CbmStsPhysics * Instance()
Accessor to singleton instance.
Definition: CbmStsPhysics.cxx:155
CbmStsSensorPoint::GetY2
Double_t GetY2() const
Exit y coordinate [cm].
Definition: CbmStsSensorPoint.h:60
CbmStsParSim::ELossModel
CbmStsELoss ELossModel() const
Energy loss model.
Definition: CbmStsParSim.h:57
CbmStsSimSensorDssd::fDy
Double_t fDy
Dimension of active area in y [cm].
Definition: CbmStsSimSensorDssd.h:91
CbmStsSimSensor::GetCurrentLink
CbmLink * GetCurrentLink() const
Current link object.
Definition: CbmStsSimSensor.h:69
CbmStsSensorPoint::GetX1
Double_t GetX1() const
Entry x coordinate [cm].
Definition: CbmStsSensorPoint.h:56
CbmStsParSim.h
CbmStsSimSensorDssd::RegisterCharge
void RegisterCharge(Int_t side, Int_t strip, Double_t charge, Double_t time) const
Register the produced charge in one strip to the module.
Definition: CbmStsSimSensorDssd.cxx:284
CbmStsSimSensorDssd::CalculateResponse
virtual Int_t CalculateResponse(CbmStsSensorPoint *point)
Analogue response to a track in the sensor.
Definition: CbmStsSimSensorDssd.cxx:31
CbmStsSensorPoint::GetPid
Int_t GetPid() const
Particle ID [PDG].
Definition: CbmStsSensorPoint.h:68
CbmStsDefs.h
CbmStsPhysics::ParticleMass
static Double_t ParticleMass(Int_t pid)
Particle mass from PDG particle ID.
Definition: CbmStsPhysics.cxx:217
CbmStsELoss
CbmStsELoss
Energy loss model used in simulation.
Definition: CbmStsDefs.h:43
CbmStsSimSensor::GetModule
CbmStsSimModule * GetModule() const
Simulation module.
Definition: CbmStsSimSensor.h:81
CbmStsSimSensorDssd::IsInside
Bool_t IsInside(Double_t x, Double_t y)
Definition: CbmStsSimSensorDssd.cxx:130
CbmStsPhysics::EnergyLoss
Double_t EnergyLoss(Double_t dz, Double_t mass, Double_t eKin, Double_t dedx) const
Energy loss in a Silicon layer.
Definition: CbmStsPhysics.cxx:112
ClassImp
ClassImp(CbmConverterManager) InitStatus CbmConverterManager
Definition: CbmConverterManager.cxx:12
CbmStsSimSensorDssd::CrossTalk
void CrossTalk(Double_t ctCoeff)
Definition: CbmStsSimSensorDssd.cxx:96
CbmStsSimSensorDssd.h
CbmStsSimSensorDssd::GetModuleChannel
virtual Int_t GetModuleChannel(Int_t strip, Int_t side, Int_t sensorId) const =0
Get the readout channel in the module for a given strip.
CbmStsSensorPoint::GetZ2
Double_t GetZ2() const
Exit z coordinate [cm].
Definition: CbmStsSensorPoint.h:61
CbmStsSensorPoint::GetBy
Double_t GetBy() const
By-Field at midpoint [T].
Definition: CbmStsSensorPoint.h:66
CbmStsParSensorCond::GetCrossTalkCoeff
Double_t GetCrossTalkCoeff() const
Cross-talk coefficient.
Definition: CbmStsParSensorCond.h:78
CbmStsSimSensorDssd
Abstract class for the simulation of double-sided silicon strip sensors.
Definition: CbmStsSimSensorDssd.h:45
CbmStsParSim::CrossTalk
Bool_t CrossTalk() const
Check whether cross-talk is applied.
Definition: CbmStsParSim.h:45
CbmStsSimSensorDssd::CbmStsSimSensorDssd
CbmStsSimSensorDssd(CbmStsElement *element=nullptr)
Standard constructor.
Definition: CbmStsSimSensorDssd.cxx:25
CbmStsSensorPoint::GetELoss
Double_t GetELoss() const
Energy loss [GeV].
Definition: CbmStsSensorPoint.h:63
CbmStsSensorPoint::GetP
Double_t GetP() const
Momentum magnitude.
Definition: CbmStsSensorPoint.h:62
CbmStsSimSensorDssd::PropagateCharge
virtual void PropagateCharge(Double_t x, Double_t y, Double_t z, Double_t charge, Double_t bY, Int_t side)=0
x
Double_t x
Definition: CbmMvdSensorDigiToHitTask.cxx:68
CbmStsSensorPoint::GetZ1
Double_t GetZ1() const
Entry z coordinate [cm].
Definition: CbmStsSensorPoint.h:58
CbmStsSimSensorDssd::ChargeStatus
std::string ChargeStatus() const
Print charge status.
Definition: CbmStsSimSensorDssd.cxx:78
y
Double_t y
Definition: CbmMvdSensorDigiToHitTask.cxx:68
CbmStsSensorPoint::GetY1
Double_t GetY1() const
Entry y coordinate [cm].
Definition: CbmStsSensorPoint.h:57
CbmStsParSensorCond::GetVbias
Double_t GetVbias() const
Bias voltage.
Definition: CbmStsParSensorCond.h:101
CbmStsSimSensorDssd::ProduceCharge
void ProduceCharge(CbmStsSensorPoint *point)
Generate charge as response to a sensor point.
Definition: CbmStsSimSensorDssd.cxx:189
CbmStsELoss::kIdeal
@ kIdeal
CbmStsSimSensor::GetSensorId
Int_t GetSensorId() const
Sensor ID.
Definition: CbmStsSimSensor.cxx:44
CbmStsPhysics::ElectricField
static Double_t ElectricField(Double_t vBias, Double_t vFd, Double_t dZ, Double_t z)
Electric field magnitude in a silicon sensor as function of z.
Definition: CbmStsPhysics.cxx:102
CbmStsSimSensorDssd::GetNofStrips
virtual Int_t GetNofStrips(Int_t side) const =0
Number of strips on front and back side.
CbmStsSimSensorDssd::fDz
Double_t fDz
Thickness in z [cm].
Definition: CbmStsSimSensorDssd.h:92
CbmStsSimModule.h
CbmStsParSensorCond::GetVfd
Double_t GetVfd() const
Definition: CbmStsParSensorCond.h:107
CbmStsSensorPoint.h
CbmStsElement
Class representing an element of the STS setup.
Definition: CbmStsElement.h:32
CbmStsSimSensorDssd::fDx
Double_t fDx
Dimension of active area in x [cm].
Definition: CbmStsSimSensorDssd.h:90
CbmStsPhysics::PairCreationEnergy
static Double_t PairCreationEnergy()
Energy for electron-hole pair creation in silicon.
Definition: CbmStsPhysics.h:97