BmnRoot
Loading...
Searching...
No Matches
BmnSsdSensorDssdStereo.cxx
Go to the documentation of this file.
1
8
9#include "TGeoBBox.h"
10#include "TMath.h"
11
12#include "BmnMatch.h"
14#include "BmnSsdPhysics.h"
15#include "BmnSsdSetup.h"
16
17
18using namespace std;
19
20
21// ----- Constructor ---------------------------------------------------
23 TGeoPhysicalNode* node,
24 BmnSsdElement* mother) :
25 BmnSsdSensorDssd(address, node, mother),
26 fNofStrips(0), fPitch(0.), fStereoF(100.), fStereoB(100.),
27 fTanStereo(), fCosStereo(), fStripShift(), fErrorFac(0.)
28{
29 SetTitle("DssdStereo");
30}
31// -------------------------------------------------------------------------
32
33
34
35// ----- Constructor ---------------------------------------------------
37 Double_t pitch,
38 Double_t stereoF,
39 Double_t stereoB) :
41 fNofStrips(nStrips),
42 fPitch(pitch),
43 fStereoF(stereoF),
44 fStereoB(stereoB),
45 fTanStereo(),
46 fCosStereo(),
47 fStripShift(),
48 fErrorFac(0.)
49{
50 SetTitle("DssdStereo");
51 fDy = dy;
52}
53// -------------------------------------------------------------------------
54
55
56
57// ----- Diffusion -----------------------------------------------------
58void BmnSsdSensorDssdStereo::Diffusion(Double_t x, Double_t y,
59 Double_t sigma, Int_t side,
60 Double_t& fracL, Double_t& fracC,
61 Double_t& fracR) {
62
63 // Check side qualifier
64 assert( side == 0 || side == 1);
65
66 // x coordinate at the readout edge (y = fDy/2 )
67 // This x is counted from the left edge.
68 Double_t xRo = x + fDx / 2. - ( fDy / 2. - y ) * fTanStereo[side];
69
70 // Centre strip number (w/o cross connection; may be negative or large than
71 // the number of strips)
72 Int_t iStrip = TMath::FloorNint(xRo / fPitch);
73
74 // Strip boundaries at the readout edge (y = fDy/2)
75 Double_t xLeftRo = Double_t(iStrip) * fPitch;
76 Double_t xRightRo = xLeftRo + fPitch;
77
78 // Distance from strip boundaries across the strip
79 Double_t dLeft = ( xRo - xLeftRo ) * fCosStereo[side];
80 Double_t dRight = ( xRightRo - xRo ) * fCosStereo[side];
81
82 // Charge fractions
83 // The value 0.707107 is 1/sqrt(2)
84 fracL = 0.;
85 if ( dLeft < 3. * sigma )
86 fracL = 0.5 * ( 1. - TMath::Erf( 0.707107 * dLeft / sigma) );
87 fracR = 0.;
88 if ( dRight < 3. * sigma )
89 fracR = 0.5 * ( 1. - TMath::Erf( 0.707107 * dRight / sigma) );
90 fracC = 1. - fracL - fracR;
91
92 LOG(debug4) << GetName() << ": Distances to next strip " << dLeft << " / "
93 << dRight << ", charge fractions " << fracL << " / " << fracC
94 << " / " << fracR;
95}
96// -------------------------------------------------------------------------
97
98
99
100// ----- Get channel number in module ----------------------------------
101Int_t BmnSsdSensorDssdStereo::GetModuleChannel(Int_t strip, Int_t side,
102 Int_t sensorId) const {
103
104 // --- Check side argument
105 assert( side == 0 || side == 1);
106
107 // --- Account for offset due to stereo angle
108 Int_t channel = strip - sensorId * fStripShift[side];
109
110 // --- Account for horizontal cross-connection of strips
111 while ( channel < 0 ) channel += fNofStrips;
112 while ( channel >= fNofStrips ) channel -= fNofStrips;
113
114 // --- Account for front or back side
115 if ( side ) channel += fNofStrips;
116
117 return channel;
118}
119// -------------------------------------------------------------------------
120
121
122
123// ----- Get strip and side from channel number ------------------------
124pair<Int_t, Int_t> BmnSsdSensorDssdStereo::GetStrip(Int_t channel,
125 Int_t sensorId) const {
126
127 Int_t stripNr = -1;
128 Int_t side = -1;
129
130 // --- Determine front or back side
131 if ( channel < fNofStrips ) { // front side
132 side = 0;
133 stripNr = channel;
134 }
135 else { // back side
136 side = 1;
137 stripNr = channel - fNofStrips;
138 }
139
140 // --- Offset due to stereo angle
141 stripNr += sensorId * fStripShift[side];
142
143 // --- Horizontal cross-connection
144 while ( stripNr < 0 ) stripNr += fNofStrips;
145 while ( stripNr >= fNofStrips ) stripNr -= fNofStrips;
146
147 return ( pair<Int_t, Int_t>(stripNr, side) );
148}
149// -------------------------------------------------------------------------
150
151
152
153// ----- Get strip number from coordinates -----------------------------
154Int_t BmnSsdSensorDssdStereo::GetStripNumber(Double_t x, Double_t y,
155 Int_t side) const {
156
157 // Cave: This implementation assumes that the centre of the sensor volume
158 // is also the centre of the active area, i.e. that the inactive borders
159 // (guard ring) are symmetric both and x and y (not necessarily the same
160 // in x and y).
161
162 // Check side
163 assert( side == 0 || side == 1);
164
165 // Check whether in active area (should have been caught before)
166 if ( TMath::Abs(x) > fDx / 2. ) {
167 LOG(error) << GetName() << ": Outside active area : x = "
168 << x << " cm";
169 return -1;
170 }
171 if ( TMath::Abs(y) > fDy / 2. ) {
172 LOG(error) << GetName() << ": Outside active area : y = "
173 << y << " cm";
174 return -1;
175 }
176
177 // Calculate distance from lower left corner of the active area.
178 // Note: the coordinates are given w.r.t. the centre of the volume.
179 Double_t xdist = x + 0.5 * fDx;
180 Double_t ydist = y + 0.5 * fDy;
181
182 // Project coordinates to readout (top) edge
183 Double_t xro = xdist - ( fDy - ydist ) * fTanStereo[side];
184
185 // Calculate corresponding strip number
186 Int_t iStrip = TMath::FloorNint( xro / fPitch );
187
188 // Account for horizontal cross-connection of strips
189 // not extending to the top edge
190 while ( iStrip < 0 ) iStrip += fNofStrips;
191 while ( iStrip >= fNofStrips ) iStrip -= fNofStrips;
192
193 return iStrip;
194}
195// -------------------------------------------------------------------------
196
197
198
199// ----- Initialise ----------------------------------------------------
201
202 // Check presence of node
203 if ( ! fNode ) {
204 LOG(error) << GetName() << ": No node assigned!";
205 return kFALSE;
206 }
207
208 // Check whether parameters are assigned
209 if ( fNofStrips <= 0 ) {
210 LOG(error) << GetName() << ": Parameters are not set!"
211 ;
212 return kFALSE;
213 }
214
215 // Geometric shape of the sensor volume
216 TGeoBBox* shape = dynamic_cast<TGeoBBox*>(fNode->GetShape());
217 assert(shape);
218
219 // Active size in x coordinate
220 fDx = Double_t(fNofStrips) * fPitch;
221 if ( fDx >= 2. * shape->GetDX() ) {
222 LOG(error) << GetName() << ": Active size in x ( " << fNofStrips << " x "
223 << fPitch << " cm exceeds volume extension " << 2. * shape->GetDX()
224 ;
225 return kFALSE;
226 }
227
228 // Active size in y coordinate
229 if ( fDy >= 2. * shape->GetDY() ) {
230 LOG(error) << GetName() << ": Active size in y ( " << fDy
231 << " cm exceeds volume extension " << 2. * shape->GetDY()
232 ;
233 return kFALSE;
234 }
235
236 // Active size in z coordinate
237 fDz = 2. * shape->GetDZ();
238
239 // Stereo angle front side must be between -85 and 85 degrees
240 if ( TMath::Abs(fStereoF) > 85. ) {
241 LOG(error) << GetName() << ": Stereo angle front side ( " << fStereoF
242 << "° exceeds maximum 85° ";
243 return kFALSE;
244 }
245
246 // Stereo angle back side must be between -85 and 85 degrees
247 if ( TMath::Abs(fStereoB) > 85. ) {
248 LOG(error) << GetName() << ": Stereo angle back side ( " << fStereoB
249 << "° exceeds maximum 85° ";
250 return kFALSE;
251 }
252
253 // Derived variables
254 fTanStereo[0] = TMath::Tan( fStereoF * TMath::DegToRad() );
255 fCosStereo[0] = TMath::Cos( fStereoF * TMath::DegToRad() );
256 fStripShift[0] = TMath::Nint(fDy * fTanStereo[0] / fPitch);
257 fTanStereo[1] = TMath::Tan( fStereoB * TMath::DegToRad() );
258 fCosStereo[1] = TMath::Cos( fStereoB * TMath::DegToRad() );
259 fStripShift[1] = TMath::Nint(fDy * fTanStereo[1] / fPitch);
260
261 // Set size of charge arrays
262 fStripCharge[0].Set(fNofStrips);
263 fStripCharge[1].Set(fNofStrips);
264
265 // Factor for the hit position error
266 fErrorFac = 1. / ( fTanStereo[1] - fTanStereo[0] )
267 / ( fTanStereo[1] - fTanStereo[0] );
268
269 // --- Flag parameters to be set if test is OK
270 fIsSet = SelfTest();
271
272 return fIsSet;
273}
274// -------------------------------------------------------------------------
275
276
277
278// ----- Intersection of two lines along the strips --------------------
279Bool_t BmnSsdSensorDssdStereo::Intersect(Double_t xF, Double_t exF,
280 Double_t xB, Double_t exB,
281 Double_t& x, Double_t& y,
282 Double_t& varX, Double_t& varY,
283 Double_t& varXY) {
284
285 // In the coordinate system with origin at the bottom left corner,
286 // a line along the strips with coordinate x0 at the top edge is
287 // given by the function y(x) = Dy - ( x - x0 ) / tan(phi), if
288 // the stereo angle phi does not vanish. Two lines yF(x), yB(x) with top
289 // edge coordinates xF, xB intersect at
290 // x = ( tan(phiB)*xF - tan(phiF)*xB ) / (tan(phiB) - tan(phiF)
291 // y = Dy + ( xB - xF ) / ( tan(phiB) - tan(phiF) )
292 // For the case that one of the stereo angles vanish (vertical strips),
293 // the calculation of the intersection is straightforward.
294
295 // --- First check whether stereo angles are different. Else there is
296 // --- no intersection.
297 if ( TMath::Abs(fStereoF-fStereoB) < 0.5 ) {
298 x = -1000.;
299 y = -1000.;
300 return kFALSE;
301 }
302
303 // --- Now treat vertical front strips
304 if ( TMath::Abs(fStereoF) < 0.001 ) {
305 x = xF;
306 y = fDy - ( xF - xB ) / fTanStereo[1];
307 varX = exF * exF;
308 varY = ( exF * exF + exB * exB ) / fTanStereo[1] / fTanStereo[1];
309 varXY = -1. * exF * exF / fTanStereo[1];
310 return IsInside(x-fDx/2., y-fDy/2.);
311 }
312
313 // --- Maybe the back side has vertical strips?
314 if ( TMath::Abs(fStereoB) < 0.001 ) {
315 x = xB;
316 y = fDy - ( xB - xF ) / fTanStereo[0];
317 varX = exB * exB;
318 varY = ( exF * exF + exB * exB) / fTanStereo[0] / fTanStereo[0];
319 varXY = -1. * exB * exB / fTanStereo[0];
320 return IsInside(x-fDx/2., y-fDy/2.);
321 }
322
323 // --- OK, both sides have stereo angle
324 x = ( fTanStereo[1] * xF - fTanStereo[0] * xB ) /
325 ( fTanStereo[1] - fTanStereo[0]);
326 y = fDy + ( xB - xF ) / ( fTanStereo[1] - fTanStereo[0]);
327 varX = fErrorFac * ( exF * exF * fTanStereo[1] * fTanStereo[1]
328 + exB * exB * fTanStereo[0] * fTanStereo[0] );
329 varY = fErrorFac * ( exF * exF + exB * exB );
330 varXY = -1. * fErrorFac * ( exF * exF * fTanStereo[1]
331 + exB * exB * fTanStereo[0] );
332
333 // --- Check for being in active area.
334 return IsInside(x-fDx/2., y-fDy/2.);
335
336}
337// -------------------------------------------------------------------------
338
339
340
341// ----- Create hits from two clusters ---------------------------------
343 BmnSsdCluster* clusterB) {
344 // --- Check pointer validity
345 assert(clusterF);
346 assert(clusterB);
347
348 // --- Ideal hit finder
349 if ( kFALSE ){ //TODO Proper implementation
350 LOG(debug3) << GetName() << ": ideal model of Hit Finder";
351
352 const BmnMatch *clusterFMatch, *clusterBMatch;
353
354 clusterFMatch = static_cast<const BmnMatch*>(clusterF -> GetMatch());
355 if (clusterFMatch){
356 LOG(debug4) << GetName() << ": front cluster exists";
357 if ((clusterFMatch -> GetNofLinks()) != 1) {
358 LOG(debug4) << GetName() << ": front cluster has more or less than 1 BmnLink";
359 return 0;
360 } else LOG(debug4) << GetName() << ": front cluster has " << clusterFMatch -> GetNofLinks() << " BmnLink";
361 } else return 0;
362
363 clusterBMatch = static_cast<const BmnMatch*> (clusterB -> GetMatch());
364 if (clusterBMatch){
365 LOG(debug4) << GetName() << ": back cluster exists";
366 if ((clusterBMatch -> GetNofLinks()) != 1){
367 LOG(debug4) << GetName() << ": back cluster has more or less than 1 BmnLink";
368 return 0;
369 } else LOG(debug4) << GetName() << ": back cluster has " << clusterBMatch -> GetNofLinks() << " BmnLink";
370 } else return 0;
371
372 if (clusterBMatch -> GetLink(0).GetIndex() != clusterFMatch -> GetLink(0).GetIndex()){
373 LOG(debug4) << GetName() << ": back and front clusters have different index of BmnLink";
374 return 0;
375 } else LOG(debug4) << GetName() << ": back and front clusters have the same index of BmnLink";
376 }
377
378 // --- Calculate cluster centre position on readout edge
379 Int_t side = -1;
380 Double_t xF = -1.;
381 Double_t xB = -1.;
382 GetClusterPosition(clusterF->GetPosition(), xF, side);
383 if ( side != 0 )
384 LOG(fatal) << GetName() << ": Inconsistent side qualifier " << side
385 << " for front side cluster! ";
386 Double_t exF = clusterF->GetPositionError() * fPitch;
387 Double_t du = exF * TMath::Cos(TMath::DegToRad() * fStereoF);
388 GetClusterPosition(clusterB->GetPosition(), xB, side);
389 if ( side != 1 )
390 LOG(fatal) << GetName() << ": Inconsistent side qualifier " << side
391 << " for back side cluster! ";
392 Double_t exB = clusterB->GetPositionError() * fPitch;
393 Double_t dv = exB * TMath::Cos(TMath::DegToRad() * fStereoB);
394
395 // --- Should be inside active area
396 if ( ! ( xF >= 0. || xF <= fDx) ) return 0;
397 if ( ! ( xB >= 0. || xB <= fDx) ) return 0;
398
399 // --- Hit counter
400 Int_t nHits = 0;
401
402 // --- Calculate number of line segments due to horizontal
403 // --- cross-connection. If x(y=0) does not fall on the bottom edge,
404 // --- the strip is connected to the one corresponding to the line
405 // --- with top edge coordinate xF' = xF +/- Dx. For odd combinations
406 // --- of stereo angle and sensor dimensions, this could even happen
407 // --- multiple times. For each of these lines, the intersection with
408 // --- the line on the other side is calculated. If inside the active area,
409 // --- a hit is created.
410 Int_t nF = Int_t( (xF + fDy * fTanStereo[0]) / fDx );
411 Int_t nB = Int_t( (xB + fDy * fTanStereo[1]) / fDx );
412
413 // --- If n is positive, all lines from 0 to n must be considered,
414 // --- if it is negative (phi negative), all lines from n to 0.
415 Int_t nF1 = TMath::Min(0, nF);
416 Int_t nF2 = TMath::Max(0, nF);
417 Int_t nB1 = TMath::Min(0, nB);
418 Int_t nB2 = TMath::Max(0, nB);
419
420 // --- Double loop over possible lines
421 Double_t xC = -1.; // x coordinate of intersection point
422 Double_t yC = -1.; // y coordinate of intersection point
423 Double_t varX = 0.; // variance of xC
424 Double_t varY = 0.; // variance of yC
425 Double_t varXY = 0.; // covariance xC-yC
426 for (Int_t iF = nF1; iF <= nF2; iF++) {
427 Double_t xFi = xF - Double_t(iF) * fDx;
428 for (Int_t iB = nB1; iB <= nB2; iB++) {
429 Double_t xBi = xB - Double_t(iB) * fDx;
430
431 // --- Intersect the two lines
432 Bool_t found = Intersect(xFi, exF, xBi, exB, xC, yC, varX, varY, varXY);
433 LOG(debug4) << GetName() << ": Trying " << xFi << ", " << xBi
434 << ", intersection ( " << xC << ", " << yC
435 << " ) " << ( found ? "TRUE" : "FALSE" )
436 ;
437 if ( found ) {
438
439 // --- Transform into sensor system with origin at sensor centre
440 xC -= 0.5 * fDx;
441 yC -= 0.5 * fDy;
442 // --- Create the hit
443 CreateHit(xC, yC, varX, varY, varXY, clusterF, clusterB, du, dv);
444 nHits++;
445
446 } //? Intersection of lines
447 } // lines on back side
448 } // lines on front side
449
450 return nHits;
451}
452// -------------------------------------------------------------------------
453
454
455
456// ----- Modify the strip pitch ----------------------------------------
458
459 assert(fIsSet); // Parameters should have been set before
460
461 // Set new pitch and re-calculate number of strips
462 fPitch = pitch;
463 fNofStrips = Int_t( fDx / pitch );
464 fDx = Double_t(fNofStrips) * pitch;
465
466 // Set size of charge arrays
467 fStripCharge[0].Set(fNofStrips);
468 fStripCharge[1].Set(fNofStrips);
469
470}
471// -------------------------------------------------------------------------
472
473
474
475// ----- Propagate charge to the readout strips ------------------------
476void BmnSsdSensorDssdStereo::PropagateCharge(Double_t x, Double_t y,
477 Double_t z, Double_t charge,
478 Double_t bY, Int_t side) {
479
480 // Check side qualifier
481 assert( side == 0 || side == 1);
482
483 Double_t xCharge = x;
484 Double_t yCharge = y;
485 Double_t zCharge = z;
486
487 // Debug
488 LOG(debug4) << GetName() << ": Propagating charge " << charge
489 << " from (" << x << ", " << y << ", " << z
490 << ") on side " << side << " of sensor " << GetName()
491 ;
492
493 // Lorentz shift on the drift to the readout plane
494 if ( BmnSsdSetup::Instance()->GetDigiParameters()->GetUseLorentzShift() ) {
495 xCharge += LorentzShift(z, side, bY);
496 LOG(debug4) << GetName() << ": After Lorentz shift: (" << xCharge << ", "
497 << yCharge << ", " << zCharge << ") cm";
498 }
499
500 // Stop is the charge after Lorentz shift is not in the active area.
501 // Diffusion into the active area is not treated.
502 if ( ! IsInside(xCharge, yCharge) ) {
503 LOG(debug4) << GetName() << ": Charge outside active area"
504 ;
505 return;
506 }
507
508 // No diffusion: all charge is in one strip
509 if ( ! BmnSsdSetup::Instance()->GetDigiParameters()->GetUseDiffusion() ) {
510 Int_t iStrip = GetStripNumber(xCharge, yCharge, side);
511 fStripCharge[side][iStrip] += charge;
512 LOG(debug4) << GetName() << ": Adding charge " << charge << " to strip "
513 << iStrip;
514 } //? Do not use diffusion
515
516 // Diffusion: charge is distributed over centre strip and neighbours
517 else {
518 // Calculate diffusion width
519 Double_t diffusionWidth =
520 BmnSsdPhysics::DiffusionWidth(z + fDz / 2., // distance from back side
521 fDz,
522 GetConditions()->GetVbias(),
523 GetConditions()->GetVfd(),
524 GetConditions()->GetTemperature(),
525 side);
526 assert (diffusionWidth >= 0.);
527 LOG(debug4) << GetName() << ": Diffusion width = " << diffusionWidth
528 << " cm";
529 // Calculate charge fractions in strips
530 Double_t fracL = 0.; // fraction of charge in left neighbour
531 Double_t fracC = 1.; // fraction of charge in centre strip
532 Double_t fracR = 0.; // fraction of charge in right neighbour
533 Diffusion(xCharge, yCharge, diffusionWidth, side, fracL, fracC, fracR);
534 // Calculate strip numbers
535 // Note: In this implementation, charge can diffuse out of the sensitive
536 // area only for vertical strips. In case of stereo angle (cross-connection
537 // of strips), all charge is assigned to some strip, so the edge effects
538 // are not treated optimally.
539 Int_t iStripC = GetStripNumber(xCharge, yCharge, side); // centre strip
540 Int_t iStripL = 0; // left neighbour
541 Int_t iStripR = 0; // right neighbour
542 if ( fTanStereo[side] < 0.0001 ) { // vertical strips, no cross connection
543 iStripL = iStripC - 1; // might be = -1
544 iStripR = iStripC + 1; // might be = nOfStrips
545 }
546 else { // stereo angle, cross connection
547 iStripL = ( iStripC == 0 ? fNofStrips - 1 : iStripC - 1);
548 iStripR = ( iStripC == fNofStrips - 1 ? 0 : iStripC + 1);
549 }
550 // Collect charge on the readout strips
551 if ( fracC > 0. ) {
552 fStripCharge[side][iStripC] += charge * fracC; // centre strip
553 LOG(debug4) << GetName() << ": Adding charge " << charge * fracC
554 << " to strip " << iStripC;
555 }
556 if ( fracL > 0. && iStripL >= 0 ) {
557 fStripCharge[side][iStripL] += charge * fracL; // right neighbour
558 LOG(debug4) << GetName() << ": Adding charge " << charge * fracL
559 << " to strip " << iStripL;
560 }
561 if ( fracR > 0. && iStripR < fNofStrips ) {
562 fStripCharge[side][iStripR] += charge * fracR; // left neighbour
563 LOG(debug4) << GetName() << ": Adding charge " << charge * fracR
564 << " to strip " << iStripR;
565 }
566 } //? Use diffusion
567
568}
569// -------------------------------------------------------------------------
570
571
572
573// ----- String output -------------------------------------------------
575 stringstream ss;
576 ss << "Sensor " << fName << " (" << GetTitle() << "): ";
577 if ( ! GetPnode() ) ss << "no node assigned; ";
578 else {
579 TGeoBBox* shape = dynamic_cast<TGeoBBox*>(GetPnode()->GetShape());
580 assert(shape);
581 ss << "Dimension (" << 2. * shape->GetDX() << ", "
582 << 2. * shape->GetDY() << ", " << 2. * shape->GetDZ() << ") cm, ";
583 }
584 ss << "dy " << fDy << " cm, ";
585 ss << "# strips " << fNofStrips << ", pitch " << fPitch << " cm, ";
586 ss << "stereo " << fStereoF << "/" << fStereoB << " degrees";
587 if ( fConditions) ss << "\n Conditions: " << fConditions->ToString();
588 return ss.str();
589}
590// -------------------------------------------------------------------------
Data class for SSD clusters.
Double_t GetPosition() const
Cluster position @value Cluster position in channel number units.
Double_t GetPositionError() const
Cluster position error @value Error (r.m.s.) of cluster position in channel number units.
Class representing an element of the SSD setup.
TGeoPhysicalNode * fNode
Pointer to geometry.
TGeoPhysicalNode * GetPnode() const
Int_t GetIndex() const
static Double_t DiffusionWidth(Double_t z, Double_t d, Double_t vBias, Double_t vFd, Double_t temperature, Int_t chargeType)
Int_t fNofStrips
Number of strips (same for front and back)
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.
Double_t fErrorFac
Shift in number of strips from bottom to top.
Double_t fCosStereo[2]
tangent of stereo angle front/back side
virtual std::pair< Int_t, Int_t > GetStrip(Int_t channel, Int_t sensorId) const
Double_t fStereoF
Stereo angle front side [degrees].
Bool_t Intersect(Double_t xF, Double_t exF, Double_t xB, Double_t exB, Double_t &x, Double_t &y, Double_t &varX, Double_t &varY, Double_t &varXY)
virtual Int_t IntersectClusters(BmnSsdCluster *clusterF, BmnSsdCluster *clusterB)
virtual void Diffusion(Double_t x, Double_t y, Double_t sigma, Int_t side, Double_t &fracL, Double_t &fracC, Double_t &fracR)
Used for calculation of hit errors.
Int_t fStripShift[2]
cosine of stereo angle front/back side
std::string ToString() const
Set the internal sensor parameters.
BmnSsdSensorDssdStereo(UInt_t address=0, TGeoPhysicalNode *node=nullptr, BmnSsdElement *mother=nullptr)
virtual Int_t GetStripNumber(Double_t x, Double_t y, Int_t side) const
Get strip number from point coordinates.
Double_t fPitch
Strip pitch /same for front and back)
Double_t fStereoB
Stereo angle front back side [degrees].
virtual void ModifyStripPitch(Double_t pitch)
Modify the strip pitch.
virtual Bool_t Init()
Initialisation @value kTRUE if parameters and node are consistent.
virtual void PropagateCharge(Double_t x, Double_t y, Double_t z, Double_t charge, Double_t bY, Int_t side)
Class describing double-sided silicon strip sensors.
Double_t fDz
Thickness in z [cm].
Bool_t fIsSet
Flag whether sensor is properly initialised.
Double_t fDx
Dimension of active area in x [cm].
Double_t fDy
Dimension of active area in y [cm].
Double_t LorentzShift(Double_t z, Int_t chargeType, Double_t bY) const
Lorentz shift in the x coordinate.
void GetClusterPosition(Double_t ClusterCentre, Double_t &xCluster, Int_t &side)
Bool_t IsInside(Double_t x, Double_t y)
void CreateHit(Double_t xLocal, Double_t yLocal, Double_t varX, Double_t varY, Double_t varXY, BmnSsdCluster *clusterF, BmnSsdCluster *clusterB, Double_t du=0., Double_t dv=0.)
const BmnSsdSensorConditions * GetConditions() const
BmnSsdSensorConditions * fConditions
Operating conditions.
static BmnSsdSetup * Instance()
STL namespace.