BmnRoot
Loading...
Searching...
No Matches
CbmStsSensorDssdOrtho.cxx
Go to the documentation of this file.
1
7
8#include <cassert>
9
10#include "TGeoBBox.h"
11#include "TMath.h"
12
13#include "CbmStsDigitizeParameters.h"
14#include "CbmStsPhysics.h"
15#include "CbmStsSetup.h"
16
17
18using namespace std;
19
20
21// ----- Constructor ---------------------------------------------------
23 TGeoPhysicalNode* node,
24 CbmStsElement* mother) :
25 CbmStsSensorDssd(address, node, mother),
26 fNofStrips(), fPitch()
27{
28}
29// -------------------------------------------------------------------------
30
31
32
33// ----- Diffusion -----------------------------------------------------
34void CbmStsSensorDssdOrtho::Diffusion(Double_t x, Double_t y,
35 Double_t sigma, Int_t side,
36 Double_t& fracL, Double_t& fracC,
37 Double_t& fracR) {
38
39 // Check side qualifier
40 assert( side == 0 || side == 1);
41
42 // Coordinate at the readout edge (y = fDy/2 ).
43 // This x is counted from the left / bottom corner.
44 Double_t aRo = (side == 0 ? x + fDx / 2. : y + fDy / 2.);
45
46 // Centre strip number
47 Int_t iStrip = TMath::FloorNint(aRo / fPitch[side]);
48
49 // Strip boundaries at the readout edge
50 Double_t aLeftRo = Double_t(iStrip) * fPitch[side];
51 Double_t aRightRo = aLeftRo + fPitch[side];
52
53 // Distance from strip boundaries across the strip
54 Double_t dLeft = aRo - aLeftRo;
55 Double_t dRight = aRightRo - aRo;
56
57 // Charge fractions
58 // The value 0.707107 is 1/sqrt(2)
59 fracL = 0.;
60 if ( dLeft < 3. * sigma )
61 fracL = 0.5 * ( 1. - TMath::Erf( 0.707107 * dLeft / sigma) );
62 fracR = 0.;
63 if ( dRight < 3. * sigma )
64 fracR = 0.5 * ( 1. - TMath::Erf( 0.707107 * dRight / sigma) );
65 fracC = 1. - fracL - fracR;
66
67 LOG(debug4) << GetName() << ": Distances to next strip " << dLeft << " / "
68 << dRight << ", charge fractions " << fracL << " / " << fracC
69 << " / " << fracR;
70}
71// -------------------------------------------------------------------------
72
73
74
75// ----- Get channel number in module ----------------------------------
76Int_t CbmStsSensorDssdOrtho::GetModuleChannel(Int_t strip, Int_t side,
77 Int_t sensorId) const {
78
79 // --- Check side and sensor ID
80 assert( side == 0 || side == 1);
81 assert( sensorId == 0);
82
83 // --- Account for front or back side
84 Int_t channel = strip;
85 if ( side ) channel += fNofStrips[0];
86
87 return channel;
88}
89// -------------------------------------------------------------------------
90
91
92
93// ----- Get strip number from coordinates -----------------------------
94Int_t CbmStsSensorDssdOrtho::GetStripNumber(Double_t x, Double_t y,
95 Int_t side) const {
96
97 // Cave: This implementation assumes that the centre of the sensor volume
98 // is also the centre of the active area, i.e. that the inactive borders
99 // (guard ring) are symmetric both and x and y (not necessarily the same
100 // in x and y).
101
102 // Check side
103 assert( side == 0 || side == 1);
104
105 // Check whether in active area (should have been caught before)
106 assert ( TMath::Abs(x) < 0.5 * fDx );
107 assert ( TMath::Abs(y) < 0.5 * fDy );
108
109 // Calculate distance from lower left corner of the active area,
110 // in x for the front side, in y for the back side.
111 // Note: the coordinates are given w.r.t. the centre of the volume.
112 Double_t dist = ( side == 0 ? x + 0.5 * fDx : y + 0.5 * fDy);
113
114 // Calculate corresponding strip number
115 Int_t iStrip = TMath::FloorNint( dist / fPitch[side] );
116
117 return iStrip;
118}
119// -------------------------------------------------------------------------
120
121
122
123// ----- Modify the strip pitch ----------------------------------------
125
126 assert(fIsSet); // Parameters should have been set before
127
128 // Set new pitch and re-calculate number of strips on both sides
129 fPitch[0] = pitch;
130 fNofStrips[0] = Int_t( fDx / pitch );
131 fDx = Double_t(fNofStrips[0]) * pitch;
132 fPitch[1] = pitch;
133 fNofStrips[1] = Int_t( fDy / pitch );
134 fDy = Double_t(fNofStrips[1]) * pitch;
135
136 // Set size of charge arrays
137 fStripCharge[0].Set(fNofStrips[0]);
138 fStripCharge[1].Set(fNofStrips[1]);
139
140}
141// -------------------------------------------------------------------------
142
143
144
145// ----- Propagate charge to the readout strips ------------------------
146void CbmStsSensorDssdOrtho::PropagateCharge(Double_t x, Double_t y,
147 Double_t z, Double_t charge,
148 Double_t bY, Int_t side) {
149
150 // Check side qualifier
151 assert( side == 0 || side == 1);
152
153 Double_t xCharge = x;
154 Double_t yCharge = y;
155 Double_t zCharge = z;
156
157 // Debug
158 LOG(debug4) << GetName() << ": Propagating charge " << charge
159 << " from (" << x << ", " << y << ", " << z
160 << ") on side " << side << " of sensor " << GetName()
161 ;
162
163 // Lorentz shift on the drift to the readout plane
164 if ( CbmStsSetup::Instance()->GetDigiParameters()->GetUseLorentzShift() ) {
165 xCharge += LorentzShift(z, side, bY);
166 }
167 LOG(debug4) << GetName() << ": After Lorentz shift: (" << xCharge << ", "
168 << yCharge << ", " << zCharge << ") cm";
169
170 // Stop if the charge after Lorentz shift is not in the active area.
171 // Diffusion into the active area is not treated.
172 if ( ! IsInside(xCharge, yCharge) ) {
173 LOG(debug4) << GetName() << ": Charge outside active area"
174 ;
175 return;
176 }
177
178 // No diffusion: all charge is in one strip
179 if ( ! CbmStsSetup::Instance()->GetDigiParameters()->GetUseDiffusion() ) {
180 Int_t iStrip = GetStripNumber(xCharge, yCharge, side);
181 fStripCharge[side][iStrip] += charge;
182 LOG(debug4) << GetName() << ": Adding charge " << charge << " to strip "
183 << iStrip;
184 } //? Do not use diffusion
185
186 // Diffusion: charge is distributed over centre strip and neighbours
187 else {
188 // Calculate diffusion width
189 Double_t diffusionWidth =
190 CbmStsPhysics::DiffusionWidth(z + fDz / 2., // distance from back side
191 fDz,
192 GetConditions()->GetVbias(),
193 GetConditions()->GetVfd(),
194 GetConditions()->GetTemperature(),
195 side);
196 assert (diffusionWidth >= 0.);
197 LOG(debug4) << GetName() << ": Diffusion width = " << diffusionWidth
198 << " cm";
199 // Calculate charge fractions in strips
200 Double_t fracL = 0.; // fraction of charge in left neighbour
201 Double_t fracC = 1.; // fraction of charge in centre strip
202 Double_t fracR = 0.; // fraction of charge in right neighbour
203 Diffusion(xCharge, yCharge, diffusionWidth, side, fracL, fracC, fracR);
204 // Calculate strip numbers
205 // Note: In this implementation, charge can diffuse out of the sensitive
206 // area only for vertical strips. In case of stereo angle (cross-connection
207 // of strips), all charge is assigned to some strip, so the edge effects
208 // are not treated optimally.
209 Int_t iStripC = GetStripNumber(xCharge, yCharge, side); // centre strip
210 Int_t iStripL = iStripC - 1; // left neighbour
211 Int_t iStripR = iStripC + 1; // right neighbour
212 // Collect charge on the readout strips
213 if ( fracC > 0. ) {
214 fStripCharge[side][iStripC] += charge * fracC; // centre strip
215 LOG(debug4) << GetName() << ": Adding charge " << charge * fracC
216 << " to strip " << iStripC;
217 }
218 if ( fracL > 0. && iStripL >= 0 ) {
219 fStripCharge[side][iStripL] += charge * fracL; // right neighbour
220 LOG(debug4) << GetName() << ": Adding charge " << charge * fracL
221 << " to strip " << iStripL;
222 }
223 if ( fracR > 0. && iStripR < fNofStrips[side] ) {
224 fStripCharge[side][iStripR] += charge * fracR; // left neighbour
225 LOG(debug4) << GetName() << ": Adding charge " << charge * fracR
226 << " to strip " << iStripR;
227 }
228 } //? Use diffusion
229
230}
231// -------------------------------------------------------------------------
232
233
234
235// ----- Set internal sensor parameters --------------------------------
236Bool_t CbmStsSensorDssdOrtho::SetParameters(Int_t nStripsF, Double_t pitchF,
237 Int_t nStripsB, Double_t pitchB) {
238
239 // Geometric shape of the sensor volume
240 TGeoBBox* shape = dynamic_cast<TGeoBBox*>(GetPnode()->GetShape());
241
242 // Active size in x coordinate
243 fDx = Double_t(nStripsF) * pitchF;
244 assert( fDx < 2. * shape->GetDX() ); // The strips fit into the volume
245
246 // Active size in y coordinate
247 fDy = Double_t(nStripsB) * pitchB;
248 assert( fDy < 2. * shape->GetDY() );
249
250 // Active size in z coordinate
251 fDz = 2. * shape->GetDZ();
252
253 // Number of strips, pitch and stereo angles
254 fNofStrips[0] = nStripsF;
255 fPitch[0] = pitchF;
256 fNofStrips[1] = nStripsB;
257 fPitch[1] = pitchB;
258
259 // Set size of charge arrays
260 fStripCharge[0].Set(fNofStrips[0]);
261 fStripCharge[1].Set(fNofStrips[1]);
262
263 // Daisy chains are not allowed. Make sure that this is the only sensor
264 // connected to the module.
265 assert ( GetSensorId() == 0);
266
267 // --- Flag parameters to be set if test is ok
268 fIsSet = SelfTest();
269
270 return fIsSet;
271}
272// -------------------------------------------------------------------------
273
274
275
276// ----- String output -------------------------------------------------
278{
279 stringstream ss;
280 ss << "Sensor " << fName << "(type " << GetTitle() << "): ";
281 if ( ! fIsSet ) {
282 ss << "parameters are not set";
283 return ss.str();
284 }
285 ss << "Dimension (" << fDx << ", " << fDy << ", " << fDz << ") cm, ";
286 ss << "# strips " << fNofStrips[0] << "/" << fNofStrips[1] << ", ";
287 ss << "pitch " << fPitch[0] << "/" << fPitch[1] << " cm, ";
288 return ss.str();
289}
290// -------------------------------------------------------------------------
vector< Double_t > dist(vector< Double_t > qp, Double_t mu)
Definition BmnMath.cxx:869
Class representing an element of the STS setup.
virtual Int_t GetModuleChannel(Int_t strip, Int_t side, Int_t sensorId) const
Get the readout channel in the module for a given strip.
Bool_t SetParameters(Int_t nStripsF, Double_t pitchF, Int_t nStripsB, Double_t pitchB)
Set the internal sensor parameters.
virtual void ModifyStripPitch(Double_t pitch)
Modify the strip pitch.
virtual void Diffusion(Double_t x, Double_t y, Double_t sigma, Int_t side, Double_t &fracL, Double_t &fracC, Double_t &fracR)
Strip pitch front/back side [cm].
virtual Int_t GetStripNumber(Double_t x, Double_t y, Int_t side) const
Get strip number from point coordinates.
virtual void PropagateCharge(Double_t x, Double_t y, Double_t z, Double_t charge, Double_t bY, Int_t side)
CbmStsSensorDssdOrtho(UInt_t address=0, TGeoPhysicalNode *node=nullptr, CbmStsElement *mother=nullptr)
Int_t fNofStrips[2]
Number of strips on front/back side.
static CbmStsSetup * Instance()
STL namespace.