BmnRoot
Loading...
Searching...
No Matches
CbmStsSensor.cxx
Go to the documentation of this file.
1// -------------------------------------------------------------------------
2// ----- CbmStsStripSensor source file -----
3// ----- Created 01/07/2008 by R. Karabowicz -----
4// -------------------------------------------------------------------------
5
6#include "CbmStsSensor.h"
7
9
10#include "TGeoManager.h" //AZ
11#include "TMath.h"
12#include "TRandom.h"
13
14#include <iostream>
15#include <list>
16#include <vector>
17
18using std::cout;
19using std::endl;
20using std::pair;
21using std::vector;
22
23
24// ----- Default constructor -------------------------------------------
26 :
27 fDetectorId(0),
28 fType(0),
29 fX0(0.),
30 fY0(0.),
31 fZ0(0.),
32 fRotation(0.),
33 fLx(0.),
34 fLy(0.),
35 fDx(0.),
36 fDy(0.),
37 fStereoF(0.),
38 fStereoB(0.),
39 fD(0.),
40 fNChannelsFront(0),
41 fNChannelsBack(0),
42 fBackStripShift(0.),
43 fFrontStripShift(0.),
44 fSigmaX(0.),
45 fSigmaY(0.),
46 fSigmaXY(0.),
47 fXSmearWidth(0.0005),
48 fZSmearSlope(0.04),
49 fFrontLorentzShift(0.132),
50 fBackLorentzShift(0.026),
51 fFrontActive(),
52 fBackActive(),
53 fTrueHits()
54{
55 cout << "-W- CbmStsSensor: Do not use this constructor! " << endl;
56}
57// -------------------------------------------------------------------------
58
59
60
61// ----- Enhanced constructor (by z0 and d) ------------------------------------------
62CbmStsSensor::CbmStsSensor(TString tempName, Int_t detId, Int_t iType, Double_t x0, Double_t y0, Double_t z0,
63 Double_t rotation, Double_t lx, Double_t ly,
64 Double_t d, Double_t dx, Double_t dy, Double_t stereoF, Double_t stereoB)
65 :
66 TNamed(tempName.Data(), ""),
67 fDetectorId(0),
68 fType(0),
69 fX0(0.),
70 fY0(0.),
71 fZ0(0.),
72 fRotation(0.),
73 fLx(0.),
74 fLy(0.),
75 fDx(0.),
76 fDy(0.),
77 fStereoF(0.),
78 fStereoB(0.),
79 fD(0.),
80 fNChannelsFront(0),
81 fNChannelsBack(0),
82 fBackStripShift(0.),
83 fFrontStripShift(0.),
84 fSigmaX(0.),
85 fSigmaY(0.),
86 fSigmaXY(0.),
87 fXSmearWidth(0.0005),
88 fZSmearSlope(0.04),
89 fFrontLorentzShift(0.132),
90 fBackLorentzShift(0.026),
91 fFrontActive(),
92 fBackActive(),
93 fTrueHits()
94{
95 fName = tempName.Data();
96 fDetectorId = detId;
97 fType = iType;
98 fX0 = x0;
99 fY0 = y0;
100 fZ0 = z0; // z position of the station
101 fRotation = rotation;
102 fLx = lx;
103 fLy = ly;
104 fD = d; // thickness of the station
105 fDx = dx;
106 fDy = dy;
107 fStereoF = stereoF;
108 fStereoB = stereoB;
109 fBackStripShift = 0.;
110 fFrontStripShift = 0.;
111 Double_t dbNoX = fLx / fDx;
112 //AZ
113 fTanF = TMath::Tan (fStereoF);
114 fTanB = TMath::Tan (fStereoB);
115 fSinRot = TMath::Sin(fRotation);
116 fCosRot = TMath::Cos(fRotation);
117
118 // Calculate number of channels
119 if ( fType == 1 ) { // Pixel sensor
120 Double_t dbNoY = fLy / fDy;
121 fNChannelsFront = Int_t( TMath::Ceil ( dbNoX )
122 *TMath::Ceil ( dbNoY ));
123 fNChannelsBack = 0;
124 }
125 else if ( fType == 2 ) { // strip sensor
126 fNChannelsFront = Int_t(TMath::Ceil ( dbNoX ));
127 Double_t aPlus = TMath::Abs( fLy * TMath::Tan(fStereoB) );
128 //AZ Double_t dbNoB = ( fLx + aPlus ) / fDx ;
129 Double_t dbNoB = ( fLx + aPlus ) / fDy ;
130 fNChannelsBack = Int_t(TMath::Ceil ( dbNoB ));
131 }
132 else if ( fType == 3 ) { // strip sensor with double metal layer
133 fNChannelsFront = Int_t(TMath::Ceil ( dbNoX ));
134 if (fStereoB*180/TMath::Pi()>80) {
135 fNChannelsBack = Int_t(TMath::Ceil ( fLy / fDy ));
136 }
137 else {
138 fNChannelsBack = fNChannelsFront;
139 }
140 }
141 else {
142 cout << "-E- CbmStsSensor: Illegal sensor type " << fType << endl;
143 Fatal("", "Illegal sensor type");
144 }
145
146 // Calculate errors and covariance
147 if ( fType == 1 ) {
148 fSigmaX = fDx / TMath::Sqrt(12);
149 fSigmaY = fDy / TMath::Sqrt(12);
150 fSigmaXY = 0.;
151 }
152 else if ( fType == 2 || fType == 3 ) {
153
154 if (fStereoF==0. && fStereoB*180/TMath::Pi()<80 ) {
155 fSigmaX = fDx / TMath::Sqrt(12);
156 fSigmaY = fDx / (TMath::Sqrt(6)*TMath::Tan(fStereoB));
157 fSigmaXY = (-1. * fDx * fDx)/(12.*TMath::Tan(fStereoB));
158 }
159 else if (fStereoF==0. && fStereoB*180/TMath::Pi()>80 ) {
160 fSigmaX = fDx / TMath::Sqrt(12);
161 fSigmaY = fDy / TMath::Sqrt(12);
162 fSigmaXY = 0.;
163 }
164 else {
165 fSigmaX = fDx / TMath::Sqrt(24);
166 fSigmaY = fDx / (TMath::Sqrt(24)*TMath::Tan(fStereoB));
167 fSigmaXY = 0.;
168 }
169
170 Int_t sensorNumber = ( fDetectorId & (7<<1) ) >> 1;
171
172 if ( sensorNumber == 1 ) {
173 fBackStripShift = 0.;
174 fFrontStripShift = 0.;
175 if (fStereoB < 0) fBackStripShift = fLy * TMath::Tan(-fStereoB); //AZ
176 }
177 else if ( sensorNumber == 2 ) {
178 if (fStereoB*180/TMath::Pi()>80) {
179 fBackStripShift = 0.;
180 fFrontStripShift = 1. * fLy * TMath::Tan(fStereoF);
181 }
182 else {
183 fBackStripShift = 1. * fLy * TMath::Tan(fStereoB);
184 fFrontStripShift = 1. * fLy * TMath::Tan(fStereoF);
185 }
186 }
187 else if ( sensorNumber == 3 ){
188 if (fStereoB*180/TMath::Pi()>80) {
189 fBackStripShift = 0.;
190 fFrontStripShift = 2. * fLy * TMath::Tan(fStereoF);
191 }
192 else {
193 fBackStripShift = 2. * fLy * TMath::Tan(fStereoB);
194 fFrontStripShift = 2. * fLy * TMath::Tan(fStereoF);
195 }
196 }
197
198 }
199 else {
200 cout << "-E- CbmStsSensor: Illegal sensor type " << fType << endl;
201 Fatal("", "Illegal sensor type");
202 }
203
204 // Transform errors to global c.s.
205 Double_t cosRot = TMath::Cos(fRotation);
206 Double_t sinRot = TMath::Sin(fRotation);
207 Double_t vX = cosRot * cosRot * fSigmaX * fSigmaX
208 - 2. * cosRot * sinRot * fSigmaXY
209 + sinRot * sinRot * fSigmaY * fSigmaY;
210 Double_t vY = sinRot * sinRot * fSigmaX * fSigmaX
211 + 2. * cosRot * sinRot * fSigmaXY
212 + cosRot * cosRot * fSigmaY * fSigmaY;
213 Double_t vXY = cosRot * sinRot * fSigmaX * fSigmaX
214 + ( cosRot*cosRot - sinRot*sinRot ) * fSigmaXY
215 - cosRot * sinRot * fSigmaY * fSigmaY;
216 fSigmaX = TMath::Sqrt(vX);
217 fSigmaY = TMath::Sqrt(vY);
218 fSigmaXY = vXY;
219
220 fXSmearWidth = 0.0005;
221 fZSmearSlope = 0.04;
222
223 fFrontLorentzShift = 0.132;
224 fBackLorentzShift = 0.026;
225 fFrontLorentzShift = fBackLorentzShift = 0.0; //AZ
226}
227// -------------------------------------------------------------------------
228
229// ----- Standard constructor ------------------------------------------
230CbmStsSensor::CbmStsSensor(Int_t detId, Int_t iType, Double_t x0,
231 Double_t y0, Double_t rotation, Double_t lx,
232 Double_t ly, Double_t dx, Double_t dy,
233 Double_t stereoF, Double_t stereoB)
234 :
235 fDetectorId(0),
236 fType(0),
237 fX0(0.),
238 fY0(0.),
239 fZ0(0.),
240 fRotation(0.),
241 fLx(0.),
242 fLy(0.),
243 fDx(0.),
244 fDy(0.),
245 fStereoF(0.),
246 fStereoB(0.),
247 fD(0.),
248 fNChannelsFront(0),
249 fNChannelsBack(0),
250 fBackStripShift(0.),
251 fFrontStripShift(0.),
252 fSigmaX(0.),
253 fSigmaY(0.),
254 fSigmaXY(0.),
255 fXSmearWidth(0.0005),
256 fZSmearSlope(0.04),
257 fFrontLorentzShift(0.132),
258 fBackLorentzShift(0.026),
259 fFrontActive(),
260 fBackActive(),
261 fTrueHits()
262{
263 fDetectorId = detId;
264 fType = iType;
265 fX0 = x0;
266 fY0 = y0;
267 fRotation = rotation;
268 fLx = lx;
269 fLy = ly;
270 fDx = dx;
271 fDy = dy;
272 fStereoF = stereoF;
273 fStereoB = stereoB;
274 fBackStripShift = 0.;
275 fFrontStripShift = 0.;
276 Double_t dbNoX = fLx / fDx;
277 //AZ
278 fTanF = TMath::Tan (fStereoF);
279 fTanB = TMath::Tan (fStereoB);
280 fSinRot = TMath::Sin(fRotation);
281 fCosRot = TMath::Cos(fRotation);
282
283 // Calculate number of channels
284 if ( fType == 1 ) { // Pixel sensor
285 Double_t dbNoY = fLy / fDy;
286 fNChannelsFront = Int_t( TMath::Ceil ( dbNoX )
287 *TMath::Ceil ( dbNoY ));
288 fNChannelsBack = 0;
289 }
290 else if ( fType == 2 ) { // strip sensor
291 fNChannelsFront = Int_t(TMath::Ceil ( dbNoX ));
292 Double_t aPlus = TMath::Abs( fLy * TMath::Tan(fStereoB) );
293 //AZ Double_t dbNoB = ( fLx + aPlus ) / fDx ;
294 Double_t dbNoB = ( fLx + aPlus ) / fDy ;
295 fNChannelsBack = Int_t(TMath::Ceil ( dbNoB ));
296 }
297 else if ( fType == 3 ) { // strip sensor with double metal layer
298 fNChannelsFront = Int_t(TMath::Ceil ( dbNoX ));
299 fNChannelsBack = fNChannelsFront;
300 }
301 else {
302 cout << "-E- CbmStsSensor: Illegal sensor type " << fType << endl;
303 Fatal("", "Illegal sensor type");
304 }
305
306 // Calculate errors and covariance
307 if ( fType == 1 ) {
308 fSigmaX = fDx / TMath::Sqrt(12);
309 fSigmaY = fDy / TMath::Sqrt(12);
310 fSigmaXY = 0.;
311 }
312 else if ( fType == 2 || fType == 3 ) {
313 if (fStereoF==0. && fStereoB*180/TMath::Pi()<80 ) {
314 fSigmaX = fDx / TMath::Sqrt(12);
315 fSigmaY = fDx / (TMath::Sqrt(6)*TMath::Tan(fStereoB));
316 fSigmaXY = (-1. * fDx * fDx)/(12.*TMath::Tan(fStereoB));
317 }
318 else if (fStereoF==0. && fStereoB*180/TMath::Pi()>80 ) {
319 fSigmaX = fDx / TMath::Sqrt(12);
320 fSigmaY = fDy / TMath::Sqrt(12);
321 fSigmaXY = 0.;
322 }
323 else {
324 fSigmaX = fDx / TMath::Sqrt(24);
325 fSigmaY = fDx / (TMath::Sqrt(24)*TMath::Tan(fStereoB));
326 fSigmaXY = 0.;
327 }
328
329 Int_t sensorNumber = ( fDetectorId & (7<<1) ) >> 1;
330 if ( sensorNumber == 1 ) {
331 fBackStripShift = 0.;
332 fFrontStripShift = 0.;
333 if (fStereoB < 0) fBackStripShift = fLy * TMath::Tan(-fStereoB); //AZ
334 }
335 else if ( sensorNumber == 2 ) {
336 if (fStereoB*180/TMath::Pi()>80) {
337 fBackStripShift = 0.;
338 fFrontStripShift = 1. * fLy * TMath::Tan(fStereoF);
339 }
340 else {
341 fBackStripShift = 1. * fLy * TMath::Tan(fStereoB);
342 fFrontStripShift = 1. * fLy * TMath::Tan(fStereoF);
343 }
344 }
345 else if ( sensorNumber == 3 ){
346 if (fStereoB*180/TMath::Pi()>80) {
347 fBackStripShift = 0.;
348 fFrontStripShift = 2. * fLy * TMath::Tan(fStereoF);
349 }
350 else {
351 fBackStripShift = 2. * fLy * TMath::Tan(fStereoB);
352 fFrontStripShift = 2. * fLy * TMath::Tan(fStereoF);
353 }
354 }
355
356 }
357 else {
358 cout << "-E- CbmStsSensor: Illegal sensor type " << fType << endl;
359 Fatal("", "Illegal sensor type");
360 }
361
362 // Transform errors to global c.s.
363 Double_t cosRot = TMath::Cos(fRotation);
364 Double_t sinRot = TMath::Sin(fRotation);
365 Double_t vX = cosRot * cosRot * fSigmaX * fSigmaX
366 - 2. * cosRot * sinRot * fSigmaXY
367 + sinRot * sinRot * fSigmaY * fSigmaY;
368 Double_t vY = sinRot * sinRot * fSigmaX * fSigmaX
369 + 2. * cosRot * sinRot * fSigmaXY
370 + cosRot * cosRot * fSigmaY * fSigmaY;
371 Double_t vXY = cosRot * sinRot * fSigmaX * fSigmaX
372 + ( cosRot*cosRot - sinRot*sinRot ) * fSigmaXY
373 - cosRot * sinRot * fSigmaY * fSigmaY;
374 fSigmaX = TMath::Sqrt(vX);
375 fSigmaY = TMath::Sqrt(vY);
376 fSigmaXY = vXY;
377
378 fXSmearWidth = 0.0005;
379 fZSmearSlope = 0.04;
380
381 fFrontLorentzShift = 0.132;
382 fBackLorentzShift = 0.026;
383}
384// -------------------------------------------------------------------------
385
386
387
388// ----- Destructor ----------------------------------------------------
390// -------------------------------------------------------------------------
391
392
393
394// ----- Public method GetChannel --------------------------------------
395Int_t CbmStsSensor::GetChannel(Double_t x, Double_t y, Int_t iSide) {
396
397 // Check iSide
398 if (iSide !=0 && iSide != 1) {
399 cout << "-W- CbmStsSensor::GetChannel: Illegal side number "
400 << iSide << endl;
401 return -1;
402 }
403
404 // Calculate internal coordinates. Return -1 if outside sensor.
405 Double_t xint = 0;
406 Double_t yint = 0;
407 if ( ! IntCoord(x, y, xint, yint) ) return -1;
408 Int_t iChan = 0;
409
410 Double_t dbNoX = fLx / fDx;
411 // Case pixel sensor: iChannel = iRow * nColumns + iColumn
412 if ( fType == 1 ) {
413 Int_t nCol = Int_t(TMath::Ceil( dbNoX));
414 Int_t iCol = Int_t(xint / fDx);
415 Int_t iRow = Int_t(yint / fDy);
416 iChan = iRow * nCol + iCol;
417 if ( iChan < 0 || iChan > fNChannelsFront ) {
418 cout << "-E- CbmStsSensor::GetChannel: "
419 << "Channel number " << iChan << " exceeds limit "
420 << fNChannelsFront << endl;
421 cout << GetStationNr() << " " << GetSensorNr() << endl;
422 cout << x << " " << y << " " << iSide << endl;
423 Fatal("GetChannel", "illegal channel number");
424 }
425 }
426
427 // Case strip sensor 1
428 else if ( fType == 2 ) {
429 if ( iSide == 0 )
430 { // Front side
431 iChan = Int_t ( xint / fDx );
432 if ( iChan < 0 || iChan > fNChannelsFront )
433 {
434 cout << "-E- CbmStsSensor::GetChannel: "
435 << "Front channel number " << iChan << " exceeds limit "
436 << fNChannelsFront << endl;
437 Fatal("GetChannel", "illegal channel number");
438 }
439 }
440 else { // Back side
441 // Project point along backside strip to y=0
442 Double_t xp = xint + yint * TMath::Tan(fStereoB);
443 // Digitise
444 iChan = Int_t ( xp / fDx );
445 if ( iChan < 0 || iChan > fNChannelsBack ) {
446 cout << "-E- CbmStsSensor::GetChannel: "
447 << "Back channel number " << iChan << " exceeds limit "
448 << fNChannelsBack << endl;
449 cout << " Sensor " << GetSensorNr() << " of station "
450 << GetStationNr() << endl;
451 cout << " Point coordinates: (" << x << ", " << y
452 << ") cm" << endl;
453 Fatal("GetChannel", "illegal channel number");
454 }
455 }
456 }
457
458 // Case strip sensor 2 (with double metal layer)
459 else if ( fType == 3 ) {
460 if ( iSide == 0 ) { // Front side
461 Double_t xf = xint + fFrontStripShift + yint * TMath::Tan(fStereoF);
462 xf = xf - TMath::Floor(xf/fLx) * fLx;
463 iChan = Int_t ( xf / fDx );
464 if ( iChan < 0 || iChan > fNChannelsFront ) {
465 cout << "-E- CbmStsSensor::GetChannel: "
466 << "Front channel number " << iChan << " exceeds limit "
467 << fNChannelsFront << endl;
468 Fatal("GetChannel", "illegal channel number");
469 }
470 }
471 else { // Back side
472 if (fStereoB*180/TMath::Pi()>80) {
473 Double_t xp = yint;
474 xp = xp - TMath::Floor(xp/fLy) * fLy;
475 iChan = Int_t( xp / fDy );
476 }
477 else {
478 // Project point along backside strip to y = 0
479 Double_t xp = xint + fBackStripShift + yint * TMath::Tan(fStereoB);
480 // Calculate modulo w.r.t. sensor x width
481 xp = xp - TMath::Floor(xp/fLx) * fLx;
482 // Digitise
483 iChan = Int_t( xp / fDx );
484 }
485
486 if ( iChan < 0 || iChan > fNChannelsBack ) {
487 cout << "-E- CbmStsSensor::GetChannel: "
488 << "Back channel number " << iChan << " exceeds limit "
489 << fNChannelsBack << endl;
490 cout << " Sensor " << GetSensorNr() << " of station "
491 << GetStationNr() << endl;
492 cout << " Point coordinates: (" << x << ", " << y
493 << ") cm" << endl;
494 Fatal("GetChannel", "illegal channel number");
495 }
496 }
497 }
498
499 return iChan;
500}
501// -------------------------------------------------------------------------
502
503
504// ----- Public method GetChannel --------------------------------------
505Float_t CbmStsSensor::GetChannelPlus(Double_t x, Double_t y, Int_t iSide) {
506
507 // Check iSide
508 if (iSide !=0 && iSide != 1) {
509 cout << "-W- CbmStsSensor::GetChannel: Illegal side number "
510 << iSide << endl;
511 return -1;
512 }
513
514 // Calculate internal coordinates. Return -1 if outside sensor.
515 Double_t xint = 0;
516 Double_t yint = 0;
517 if ( ! IntCoord(x, y, xint, yint) ) return -1;
518 Float_t iChan = 0;
519
520 Double_t dbNoX = fLx / fDx;
521 // Case pixel sensor: iChannel = iRow * nColumns + iColumn
522 if ( fType == 1 ) {
523 Int_t nCol = Int_t(TMath::Ceil( dbNoX));
524 Int_t iCol = Int_t(xint / fDx);
525 Int_t iRow = Int_t(yint / fDy);
526 iChan = iRow * nCol + iCol;
527 if ( iChan < 0 || iChan > fNChannelsFront ) {
528 cout << "-E- CbmStsSensor::GetChannel: "
529 << "Channel number " << iChan << " exceeds limit "
530 << fNChannelsFront << endl;
531 cout << GetStationNr() << " " << GetSensorNr() << endl;
532 cout << x << " " << y << " " << iSide << endl;
533 Fatal("GetChannel", "illegal channel number");
534 }
535 }
536
537 // Case strip sensor 1
538 else if ( fType == 2 ) {
539 if ( iSide == 0 ) { // Front side
540 iChan = Int_t ( xint / fDx );
541 if ( iChan < 0 || iChan > fNChannelsFront ) {
542 cout << "-E- CbmStsSensor::GetChannel: "
543 << "Front channel number " << iChan << " exceeds limit "
544 << fNChannelsFront << endl;
545 Fatal("GetChannel", "illegal channel number");
546 }
547 }
548 else { // Back side
549 // Project point along backside strip to y=0
550 //AZ Double_t xp = xint + yint * TMath::Tan(fStereoB);
551 Double_t xp = xint + yint * TMath::Tan(fStereoB) + fBackStripShift; //AZ
552 // Digitise
553 iChan = Int_t ( xp / fDx );
554 if ( iChan < 0 || iChan > fNChannelsBack ) {
555 cout << "-E- CbmStsSensor::GetChannel: "
556 << "Back channel number " << iChan << " exceeds limit "
557 << fNChannelsBack << endl;
558 cout << " Sensor " << GetSensorNr() << " of station "
559 << GetStationNr() << endl;
560 cout << " Point coordinates: (" << x << ", " << y
561 << ") cm" << endl;
562 Fatal("GetChannel", "illegal channel number");
563 }
564 }
565 }
566
567 // Case strip sensor 2 (with double metal layer)
568 else if ( fType == 3 ) {
569
570 if ( iSide == 0 ) { // Front side
571 Double_t xf = xint + fFrontStripShift + yint * TMath::Tan(fStereoF);
572 xf = xf - TMath::Floor(xf/fLx) * fLx;
573 iChan = xf / fDx;
574 if ( iChan < 0 || iChan > fNChannelsFront ) {
575 cout << "-E- CbmStsSensor::GetChannel: "
576 << "Front channel number " << iChan << " exceeds limit "
577 << fNChannelsFront << endl;
578 Fatal("GetChannel", "illegal channel number");
579 }
580 }
581 else { // Back side
582
583 if (fStereoB*180/TMath::Pi()>80) {
584 Double_t xp = yint;
585 xp = xp - TMath::Floor(xp/fLy) * fLy;
586 iChan = xp / fDy;
587 }
588 else {
589 Double_t xp = xint + fBackStripShift + yint * TMath::Tan(fStereoB);
590 xp = xp - TMath::Floor(xp/fLx) * fLx;
591 iChan = xp / fDx;
592 }
593
594 if ( iChan < 0 || iChan > fNChannelsBack ) {
595 cout << "-E- CbmStsSensor::GetChannel: "
596 << "Back channel number " << iChan << " exceeds limit "
597 << fNChannelsBack << endl;
598 cout << " Sensor " << GetSensorNr() << " of station "
599 << GetStationNr() << endl;
600 cout << " Point coordinates: (" << x << ", " << y
601 << ") cm" << endl;
602 Fatal("GetChannel", "illegal channel number");
603 }
604 }
605 }
606
607 return iChan;
608}
609// -------------------------------------------------------------------------
610
611
612// ----- Public method GetFrontChannel ---------------------------------
613//Int_t CbmStsSensor::GetFrontChannel(Double_t x, Double_t y, Double_t z) {
614Int_t CbmStsSensor::GetFrontChannel(Double_t x, Double_t y, Double_t z, Double_t &dPitch) { //AZ
615 //cout << "frontchannel for " << x << " " << y << " " << z << " (" << fZ0-fD/2. << " " << fZ0+fD/2.<<")" << endl;
616 z = z - fZ0 + fD/2.;
617 //cout << " temp z = " << z << endl;
618 if ( z > fD ) return -1;
619 if ( z < 0. ) return -1;
620
621 // Lorentz shift due to movement of the charges in the magnetic field
622 // translates into an angle: 8.5 deg for electrons
623 x += fFrontLorentzShift*z;
624
625 // Calculate internal coordinates. Return -1 if outside sensor.
626 Double_t xint = 0;
627 Double_t yint = 0;
628 if ( ! IntCoord(x, y, xint, yint) ) return -1;
629 Int_t iChan = 0;
630
631// xint += gRandom->Gaus(0.,fXSmearWidth+fZSmearSlope*z);
632// yint += gRandom->Gaus(0.,fXSmearWidth+fZSmearSlope*z);
633
634 Double_t xf = xint + fFrontStripShift + yint * TMath::Tan(fStereoF);
635 //AZ xf = xf - TMath::Floor(xf/fLx) * fLx;
636 if (fType != 2) xf = xf - TMath::Floor(xf/fLx) * fLx;
637
638 //AZ iChan = (Int_t)(xf/fDx);
639 iChan = TMath::Nint(xf/fDx); //AZ
640
641 if ( iChan < 0 || iChan > fNChannelsFront ) return -1;
642 dPitch = xf - iChan * fDx; //AZ
643 return iChan;
644}
645// -------------------------------------------------------------------------
646
647
648// ----- Public method GetBackChannel ----------------------------------
649//Int_t CbmStsSensor::GetBackChannel (Double_t x, Double_t y, Double_t z) {
650Int_t CbmStsSensor::GetBackChannel (Double_t x, Double_t y, Double_t z, Double_t &dPitch) {
651
652 z = fZ0 + fD/2. - z;
653 if ( z > fD ) return -1;
654 if ( z < 0. ) return -1;
655
656 // Lorentz shift due to movement of the charges in the magnetic field
657 // translates into an angle: 1.5 deg for electrons
658 x += fBackLorentzShift*z;
659
660 // Calculate internal coordinates. Return -1 if outside sensor.
661 Double_t xint = 0;
662 Double_t yint = 0;
663 Double_t xp = 0;
664 if ( ! IntCoord(x, y, xint, yint) ) return -1;
665 Int_t iChan = 0;
666
667// xint += gRandom->Gaus(0.,fXSmearWidth+fZSmearSlope*z);
668// yint += gRandom->Gaus(0.,fXSmearWidth+fZSmearSlope*z);
669 if (fStereoB*180/TMath::Pi()>80) {
670 xp = yint;
671 xp = xp - TMath::Floor(xp/fLy) * fLy;
672 iChan = (Int_t)(xp/fDy);
673 }
674 else {
675 xp = xint + fBackStripShift + yint * TMath::Tan(fStereoB);
676 //AZ xp = xp - TMath::Floor(xp/fLx) * fLx;
677 if (fType != 2) xp = xp - TMath::Floor(xp/fLx) * fLx;
678 //AZ iChan = (Int_t)(xp/fDx);
679 //AZ iChan = (Int_t)(xp/fDy);
680 iChan = TMath::Nint(xp/fDy); //AZ
681 }
682
683
684 //if (fZ0 < 25) cout << " " << xint << " " << yint << " -> " << xp << " -> " << iChan << " " << fNChannelsBack << endl;
685 if ( iChan < 0 || iChan > fNChannelsBack ) return -1;
686 //AZ dPitch = xp - iChan * fDx; //AZ
687 dPitch = xp - iChan * fDy; //AZ
688 return iChan;
689}
690// -------------------------------------------------------------------------
691
692
693// ----- Public method Inside ------------------------------------------
694Bool_t CbmStsSensor::Inside(Double_t x, Double_t y) {
695 Double_t xint, yint;
696 return IntCoord(x, y, xint, yint);
697}
698// -------------------------------------------------------------------------
699
700
701// ----- Public method ActivateChannels --------------------------------
703 Double_t x, Double_t y) {
704
705 Int_t iFront = FrontStripNumber(x, y);
706 if (iFront < 0) return kFALSE;
707 Int_t iBack = BackStripNumber(x, y);
708 if (iBack < 0) {
709 cout << "-W- CbmStsSensor::ActivateChannels: "
710 << "No back strip number!" << endl;
711 cout << " Coordinates: (" << x << ", " << y << ")" << endl;
712 cout << " Sensor: " << fDetectorId << ", Front Strip: "
713 << iFront << endl;
714 return kFALSE;
715 }
716
717 fFrontActive.insert(iFront);
718 fBackActive.insert(iBack);
719 pair<Int_t,Int_t> a(iFront,iBack);
720 fTrueHits[a] = ipt;
721
722 return kTRUE;
723}
724// -------------------------------------------------------------------------
725
726
727
728
729// ----- Public method Intersect ---------------------------------------
730Int_t CbmStsSensor::Intersect(Int_t iFStrip, Int_t iBStrip,
731 vector<Double_t>& xCross,
732 vector<Double_t>& yCross) {
733
734 // Reset STL vector of intersection y coordinates
735 xCross.clear();
736 yCross.clear();
737
738 // Check for strip numbers
739 if ( iFStrip < 0 || iFStrip > fNChannelsFront) {
740 cout << "-W- CbmStsSensor::Intersect: "
741 << "Invalid front channel number ! "
742 << iFStrip << " " << fNChannelsFront << endl;
743 return 0;
744 }
745 if ( iBStrip < 0 || iBStrip > fNChannelsBack) {
746 cout << "-W- CbmStsSensor::Intersect: "
747 << "Invalid back channel number ! "
748 << iBStrip << " " << fNChannelsBack << endl;
749 return 0;
750 }
751
752 // x coordinate of centre of front side strip readout pad
753 Double_t xF = Double_t( iFStrip + 0.5 ) * fDx;
754
755 // x coordinate of centre of back side strip readout pad
756 Double_t xB = Double_t( iBStrip + 0.5 ) * fDx;
757
758 Double_t x;
759 Double_t y;
760 // Maximal number of back & front strip segments
761 Int_t nSegB = Int_t ( fLy * TMath::Tan(fStereoB) / fLx ) + 2;
762 Int_t nSegF = Int_t ( fLy * TMath::Tan(fStereoF) / fLx ) + 2;
763
764 for (Int_t iSegB=0; iSegB<nSegB; iSegB++) {
765
766 for (Int_t iSegF=0; iSegF<nSegF; iSegF++) {
767
768 x = ((-1./TMath::Tan(fStereoB)) * (xB - Double_t(iSegB)*fLx) + ((1./TMath::Tan(fStereoF)) * (xF - Double_t(iSegF)*fLx)))/((1./TMath::Tan(fStereoF))-(1./TMath::Tan(fStereoB)));
769 y = (-1./TMath::Tan(fStereoB)) * x + (1./TMath::Tan(fStereoB)) * (xB - fBackStripShift + Double_t(iSegB)*fLx);
770 // y & x coordinate of intersection of back strip segment with front strip
771 //Double_t y = (xB - x - Double_t(iSegB) * fLx) / TMath::Tan(fStereoB);
772
773 if ( y < 0. || y > fLy ) continue;
774 if ( x < 0. || x > fLx ) continue;
775
776 // Transform x and y coordinates to the global c.s.
777 Double_t xHit = x * TMath::Cos(fRotation) - y * TMath::Sin(fRotation);
778 Double_t yHit = y * TMath::Cos(fRotation) + x * TMath::Sin(fRotation);
779
780 // Fill coordinates in return arrays
781 xCross.push_back(xHit);
782 yCross.push_back(yHit);
783 }
784 }
785
786 return xCross.size();
787
788}
789// -------------------------------------------------------------------------
790
791// ----- Public method Intersect ---------------------------------------
792Int_t CbmStsSensor::Intersect(Int_t iFStrip, Int_t iBStrip,
793 Double_t& xCross, Double_t& yCross, Double_t& zCross) {
794
795 // Check for strip numbers
796 if ( iFStrip < 0 || iFStrip > fNChannelsFront) {
797 cout << "-W- CbmStsSensor::Intersect: "
798 << "Invalid front channel number ! "
799 << iFStrip << " " << fNChannelsFront << endl;
800 return -1;
801 }
802 if ( iBStrip < 0 || iBStrip > fNChannelsBack) {
803 cout << "-W- CbmStsSensor::Intersect: "
804 << "Invalid back channel number ! "
805 << iBStrip << " " << fNChannelsBack << endl;
806 return -1;
807 }
808 Double_t xPoint = xCross, yPoint = yCross; //AZ
809 xCross = 0.;
810 yCross = 0.;
811 zCross = 0.;
812
813 // x coordinate of centre of front side strip readout pad
814 Double_t xint = ( Double_t(iFStrip) + 0.5 ) * fDx;
815
816 Double_t sinrot = TMath::Sin(fRotation);
817 Double_t cosrot = TMath::Cos(fRotation);
818 Double_t tanstrB = 0.0, sterB = fStereoB * TMath::RadToDeg();
819 if (!(TMath::Abs(sterB-90.) < 1 || TMath::Abs(sterB+90.) < 1)) tanstrB = TMath::Tan(fStereoB);
820 Double_t tanstrF = TMath::Tan(fStereoF);
821 Int_t nStripMaxB = ( fStereoB<0. ? 0 : Int_t(fLy*(tanstrB)/fLx)+1 ); // max. number of strips
822 Int_t nStripBegB = ( fStereoB>0. ? 0 : -Int_t(fLy*(tanstrB)/fLx)-1 );
823
824 //Int_t nStripMaxF = ( fStereoF<=0. ? 0 : Int_t(fLy*(tanstrF)/fLx)+1 ); // max. number of strips
825 //Int_t nStripBegF = ( fStereoF>0. ? 0 : -Int_t(fLy*(tanstrF)/fLx)-1 );
826
827 Double_t x0 = ( Double_t(iBStrip) + 0.5 ) * fDx;
828
829 Double_t yint;
830 Double_t x;
831
832 Double_t xtemp, ytemp;
833
834 //AZ Y and X strips (0 and 90 degs)
835 if (tanstrF==0. && tanstrB == 0.0) {
836 yint = ( Double_t(iBStrip) + 0.5 ) * fDy;
837
838 // Translation to centre of sector
839 xtemp = xint - fLx/2.;
840 ytemp = yint - fLy/2.;
841
842 // Rotation around sector centre
843 xCross = xtemp * cosrot - ytemp * sinrot;
844 yCross = xtemp * sinrot + ytemp * cosrot;
845
846 // Translation into global c.s.
847 xCross = xCross + fX0;
848 yCross = yCross + fY0;
849 zCross = fZ0;
850
851 } else if (tanstrF==0.) {
852
853 for (Int_t iStrip=nStripBegB; iStrip<=nStripMaxB; iStrip++) {
854
855 yint = ( x0 - xint - fBackStripShift + Double_t(iStrip) * fLx ) / tanstrB;
856
857 if ( ! ( yint>0. && yint<fLy ) ) continue;
858
859 if ( zCross > 0.001 ) {
860 Fatal("Intersect","Intersection of two strips in two different points not valid");
861 return -1;
862 }
863
864 // Translation to centre of sector
865 xtemp = xint - fLx/2.;
866 ytemp = yint - fLy/2.;
867
868 // Rotation around sector centre
869 xCross = xtemp * cosrot - ytemp * sinrot;
870 yCross = xtemp * sinrot + ytemp * cosrot;
871
872 // Translation into global c.s.
873 xCross = xCross + fX0;
874 yCross = yCross + fY0;
875 zCross = fZ0;
876 }
877 }
878 else {
879
880 for (Int_t iStripB=0; iStripB<=1; iStripB++) {
881
882 for (Int_t iStripF=-1; iStripF<=0; iStripF++) {
883
884 x = ((-1./tanstrB) * (x0 - fBackStripShift + Double_t(iStripB)*fLx) + (1./tanstrF) * (xint - fFrontStripShift + Double_t(iStripF)*fLx))/((1./tanstrF)-(1./tanstrB));
885 yint = (-1./tanstrB) * x + (1./tanstrB) * (x0 - fBackStripShift + Double_t(iStripB)*fLx);
886
887 if ( ! ( yint>0. && yint<fLy ) ) continue;
888 if ( ! ( x>0. && x<fLx ) ) continue;
889
890 if ( zCross > 0.001 ) {
891 //AZ Fatal("Intersect","1 Intersection of two strips in two different points not valid");
892 //AZ return -1;
893 Warning("Intersect","1 Intersection of two strips in two different points not valid");
894 }
895
896 // Translation to centre of sector
897 xtemp = x - fLx/2.;
898 ytemp = yint - fLy/2.;
899
900 // Rotation around sector centre
901 //AZ xCross = xtemp * cosrot - ytemp * sinrot;
902 //AZ yCross = xtemp * sinrot + ytemp * cosrot;
903 Double_t xCross1 = xtemp * cosrot - ytemp * sinrot;
904 Double_t yCross1 = xtemp * sinrot + ytemp * cosrot;
905
906 // Translation into global c.s.
907 //AZ xCross = xCross + fX0;
908 //AZ yCross = yCross + fY0;
909 xCross1 += fX0;
910 yCross1 += fY0;
911 zCross = fZ0;
912
913 //AZ - pixel simulation
914 if (TMath::Abs(TMath::Abs(fStereoF-fStereoB)*TMath::RadToDeg()-90) < 0.1) {
915 if (TMath::Abs(xCross1-xPoint) > 0.5 || TMath::Abs(yCross1-yPoint) > 0.5) continue;
916 } //
917 xCross = xCross1; //AZ
918 yCross = yCross1; //AZ
919 }
920 }
921 }
922 // No intersection found
923 if ( zCross < 0.001 ) return -1;
924
925 return fDetectorId;
926}
927// -------------------------------------------------------------------------
928
929// ----- Public method Intersect ---------------------------------------
930Int_t CbmStsSensor::IntersectClusters(Double_t fChan, Double_t bChan,
931 Double_t& xCross, Double_t& yCross, Double_t& zCross) {
932
933 // Check for strip numbers
934 if ( fChan < 0 || fChan > fNChannelsFront) {
935 cout << "-W- CbmStsSensor::Intersect: "
936 << "Invalid front channel number ! "
937 << fChan << " " << fNChannelsFront << endl;
938 return -1;
939 }
940 if ( bChan < 0 || bChan > fNChannelsBack) {
941 cout << "-W- CbmStsSensor::Intersect: "
942 << "Invalid back channel number ! "
943 << bChan << " " << fNChannelsBack << endl;
944 return -1;
945 }
946
947 xCross = 0.;
948 yCross = 0.;
949 zCross = 0.;
950
951 Double_t sinrot = TMath::Sin(fRotation);
952 Double_t cosrot = TMath::Cos(fRotation);
953
954 //AZ Double_t xint = ( fChan + 0.5 ) * fDx - cosrot*fFrontLorentzShift*fD/2.;
955 Double_t xint = ( fChan + 0.0 ) * fDx - cosrot*fFrontLorentzShift*fD/2.;
956
957 //AZ Double_t x0 = ( bChan + 0.5 ) * fDx - cosrot*fBackLorentzShift*fD/2. ;
958 //AZ Double_t x0 = ( bChan + 0.5 ) * fDy - cosrot*fBackLorentzShift*fD/2. ;
959 Double_t x0 = ( bChan + 0.0 ) * fDy - cosrot*fBackLorentzShift*fD/2. ;
960
961 Double_t yint;
962 Double_t x;
963
964 Double_t xtemp, ytemp;
965
966 if (fStereoF==0.&&fStereoB*180/TMath::Pi()<80) {
967 //exit(0); //AZ-220322
968 Double_t tanstrB = TMath::Tan(fStereoB);
969 //Double_t tanstrF = TMath::Tan(fStereoF);
970 Int_t nStripMaxB = ( fStereoB<0. ? 0 : Int_t(fLy*tanstrB/fLx)+1 ); // max. number of BSts
971 Int_t nStripBegB = ( fStereoB>0. ? 0 : -Int_t(fLy*tanstrB/fLx)-1 );
972
973 //Int_t nStripMaxF = ( fStereoF<=0. ? 0 : Int_t(fLy*tanstrF/fLx)+1 ); // max. number of Fstrips
974 //Int_t nStripBegF = ( fStereoF>0. ? 0 : -Int_t(fLy*tanstrF/fLx)-1 );
975 if (fType == 2) nStripBegB = nStripMaxB = 0; //AZ
976
977 for (Int_t iStrip=nStripBegB; iStrip<=nStripMaxB; iStrip++) {
978
979 yint = ( x0 - xint - fBackStripShift + Double_t(iStrip) * fLx ) / tanstrB;
980
981 if ( ! ( yint>0. && yint<fLy ) ) continue;
982
983 if ( zCross > 0.001 ) {
984 Fatal("Intersect","Intersection of two strips in two different points not valid");
985 return -1;
986 }
987
988 // Translation to centre of sector
989 xtemp = xint - fLx/2.;
990 ytemp = yint - fLy/2.;
991
992 // Rotation around sector centre
993 xCross = xtemp * cosrot - ytemp * sinrot;
994 yCross = xtemp * sinrot + ytemp * cosrot;
995
996 // Translation into global c.s.
997 xCross = xCross + fX0;
998 yCross = yCross + fY0;
999 zCross = fZ0;
1000 }
1001 }
1002 else if (fStereoB*180/TMath::Pi()>80) {
1003 yint = ( bChan + 0.5 ) * fDy;
1004
1005 if ( zCross > 0.001 ) {
1006 Fatal("Intersect","Intersection of two strips in two different points not valid");
1007 return -1;
1008 }
1009
1010 // Translation to centre of sector
1011 xtemp = xint - fLx/2.;
1012 ytemp = yint - fLy/2.;
1013
1014 // Rotation around sector centre
1015 xCross = xtemp * cosrot - ytemp * sinrot;
1016 yCross = xtemp * sinrot + ytemp * cosrot;
1017
1018 // Translation into global c.s.
1019 xCross = xCross + fX0;
1020 yCross = yCross + fY0;
1021 zCross = fZ0;
1022 }
1023 else {
1024 Double_t tanstrB = TMath::Tan(fStereoB);
1025 Double_t tanstrF = TMath::Tan(fStereoF);
1026 Int_t nStripMaxB = ( fStereoB<0. ? 0 : Int_t(fLy*tanstrB/fLx)+1 ); // max. number of Bstrips
1027 Int_t nStripBegB = ( fStereoB>0. ? 0 : -Int_t(fLy*tanstrB/fLx)-1 );
1028
1029 Int_t nStripMaxF = ( fStereoF<=0. ? 0 : Int_t(fLy*tanstrF/fLx)+1 ); // max. number of Fstrips
1030 Int_t nStripBegF = ( fStereoF>0. ? 0 : -Int_t(fLy*tanstrF/fLx)-1 );
1031
1032 //AZ for (Int_t iStripB=0; iStripB<=1; iStripB++) {
1033
1034 //AZ for (Int_t iStripF=-1; iStripF<=0; iStripF++) {
1035
1036 //AZ
1037 if (fType == 2) {
1038 nStripBegB = nStripMaxB = 0;
1039 nStripBegF = nStripMaxF = 0;
1040 } else {
1041 nStripBegB = 0;
1042 nStripMaxB = 1;
1043 nStripBegF = -1;
1044 nStripMaxF = 0;
1045 }
1046 for (Int_t iStripB = nStripBegB; iStripB <= nStripMaxB; ++iStripB) {
1047
1048 for (Int_t iStripF = nStripBegF; iStripF <= nStripMaxF; ++iStripF) {
1049 //AZ
1050
1051 //x = ((-1./tanstrB) * (x0 - fBackStripShift + Double_t(iStripB)*fLx) + (1./tanstrF) * (xint - fFrontStripShift + Double_t(iStripF)*fLx))/((1./tanstrF)-(1./tanstrB));
1052 x = ((1./tanstrB) * (x0 - fBackStripShift + Double_t(iStripB)*fLx) + (1./tanstrF) * (xint - fFrontStripShift + Double_t(iStripF)*fLx))/((1./tanstrF)+(1./tanstrB)); //AZ
1053 //yint = (-1./tanstrB) * x + (1./tanstrB) * (x0 - fBackStripShift + Double_t(iStripB)*fLx);
1054 yint = (1./tanstrB) * x + (1./tanstrB) * (x0 - fBackStripShift + Double_t(iStripB)*fLx); //AZ
1055
1056 if ( ! ( yint>0. && yint<fLy ) ) continue;
1057 if ( ! ( x>0. && x<fLx ) ) continue;
1058
1059 if ( zCross > 0.001 ) {
1060 Fatal("Intersect","2 Intersection of two strips in two different points not valid");
1061 return -1;
1062 }
1063
1064 // Translation to centre of sector
1065 xtemp = x - fLx/2.;
1066 ytemp = yint - fLy/2.;
1067
1068 // Rotation around sector centre
1069 xCross = xtemp * cosrot - ytemp * sinrot;
1070 yCross = xtemp * sinrot + ytemp * cosrot;
1071
1072 // Translation into global c.s.
1073 xCross = xCross + fX0;
1074 yCross = yCross + fY0;
1075 zCross = fZ0;
1076 }
1077 }
1078 }
1079
1080 // No intersection found
1081 if ( zCross < 0.001 ) return -1;
1082
1083 //AZ - Reject points outside of the sensor boundaries (for complex geometries)
1084 // AZ!!! - add extra smearing (for tests)
1085 //Double_t sigmaEx = 0.02; // 200 um
1086 //xCross += sigmaEx * gRandom->Gaus();
1087 //
1088 //AZ 15.02.2019 - add some safety margin around sensor (edge effect)
1089 Double_t safety = 0.3;
1090 Double_t glob[3] = {xCross, yCross, zCross}, loc[3] = {0};
1091 gGeoManager->cd(fName);
1092 gGeoManager->MasterToLocal(glob, loc);
1093 //cout << loc[0] << " " << loc[1] << " " << fLx << " " << fLy << endl;
1094 if (TMath::Abs(loc[0])-fLx/2 > safety || TMath::Abs(loc[1])-fLy/2 > safety) return -1;
1095 //*
1096 if (fLx > 20.0 && abs(loc[0]) < fLx/2 && abs(loc[1]) < fLy/2) {
1097 // GEMs - inner boundaries of hot and cold zones
1098 TString where = gGeoManager->FindNode(xCross+TMath::Sign(safety,fX0), yCross+TMath::Sign(safety,fY0), zCross)->GetName();
1099 if (!where.Contains("sens",TString::kIgnoreCase)) return -1;
1100 if (!fName.Contains(where)) {
1101 if (fName.Contains("sens",TString::kIgnoreCase) && !fName.Contains(where)) return -1; // GEMS
1102 }
1103 }
1104 //*/
1105 //AZ-180322 - Exclude beam hole for BM@N "virtual" hot zones
1106 if (fName.Contains("Sensor_hot")) {
1107 gGeoManager->cd(fName);
1108 gGeoManager->CdUp();
1109 TString where = gGeoManager->FindNode(xCross+TMath::Sign(safety,fX0), yCross+TMath::Sign(safety,fY0), zCross)->GetName();
1110 //cout << " WHERE: " << where << " " << fName << endl;
1111 if (!where.Contains("hot")) return -1;
1112 }
1113 return fDetectorId;
1114}
1115
1116// -------------------------------------------------------------------------
1117
1118
1119// ----- Public method PointIndex --------------------------------------
1120Int_t CbmStsSensor::PointIndex(Int_t iFStrip, Int_t iBStrip) {
1121 pair<Int_t,Int_t> a(iFStrip, iBStrip);
1122 if (fTrueHits.find(a) == fTrueHits.end()) return -1;
1123 return fTrueHits[a];
1124}
1125// -------------------------------------------------------------------------
1126
1127
1128
1129// ----- Public method Reset -------------------------------------------
1131 fFrontActive.clear();
1132 fBackActive.clear();
1133 fTrueHits.clear();
1134}
1135// -------------------------------------------------------------------------
1136
1137
1138
1139// ----- Public method Print -------------------------------------------
1141 cout << " Sensor Nr. ";
1142 cout.width(3);
1143 cout << GetSensorNr() << ", Type ";
1144 cout.width(1);
1145 cout << fType << ", centre (";
1146 cout.width(6);
1147 cout << fX0 << ", ";
1148 cout.width(6);
1149 cout << fY0 << ") cm, rotation " ;
1150 cout.width(6);
1151 cout << fRotation*180./TMath::Pi() << " deg., lx = ";
1152 cout.width(3);
1153 cout << fLx << " cm, ly = ";
1154 cout.width(3);
1155 cout << fLy << " cm, channels: " << GetNChannels() << endl;
1156}
1157// -------------------------------------------------------------------------
1158
1159
1160
1161// ----- Private method FrontStripNumber -------------------------------
1162Int_t CbmStsSensor::FrontStripNumber(Double_t x, Double_t y) const {
1163
1164 Double_t xint = 0., yint = 0.;
1165
1166 // Calculate internal coordinates.
1167 // If point is inside sensor, return strip number
1168 if ( IntCoord(x, y, xint, yint) ) {
1169 // Double_t xf = xint + fFrontStripShift + yint * TMath::Tan(fStereoF);
1170 Double_t xf = xint + fFrontStripShift + yint * fTanF; //AZ
1171 xf = xf - TMath::Floor(xf/fLx) * fLx;
1172 Int_t iStrip = Int_t( xf / fDx );
1173
1174 if (iStrip < 0 || iStrip > fNChannelsFront) {
1175 cout << "-E- CbmStsSensor::FrontStripNumber: Invalid strip number"
1176 << " " << iStrip << endl;
1177 cout << " Sensor " << fDetectorId << ", x = " << xint << ", y = "
1178 << yint << endl;
1179 Fatal("FrontStripNumber", "Invalid strip number" );
1180 }
1181 return iStrip;
1182 }
1183
1184 // Return -1 if point is outside sensor
1185 return -1;
1186
1187}
1188// -------------------------------------------------------------------------
1189
1190
1191
1192// ----- Private method BackStripNumber --------------------------------
1193Int_t CbmStsSensor::BackStripNumber(Double_t x, Double_t y) const {
1194
1195 Double_t xint = 0., yint = 0.;
1196
1197 // Calculate internal coordinates.
1198 // If point is inside sensor, calculate projection onto readout line
1199 // and determine channel number
1200 if ( IntCoord(x, y, xint, yint) ) {
1201 if (fStereoB*180/TMath::Pi()>80) {
1202 Double_t xp = yint;
1203 xp = xp - TMath::Floor(xp/fLy) * fLy;
1204 Int_t iStrip = (Int_t) ( xp / fDy );
1205 if (iStrip < 0 || iStrip > fNChannelsBack) {
1206 cout << "-E- CbmStsSensor::BackStripNumber: Invalid strip number"
1207 << " " << iStrip << endl;
1208 cout << " Sensor " << fDetectorId << ", x = " << xint << ", y = "
1209 << yint << endl;
1210 Fatal("BackStripNumber", "Invalid strip number" );
1211 }
1212 return iStrip;
1213 }
1214 else {
1215 // Project point along backside strip to y = 0
1216 //Double_t xp = xint + fBackStripShift + yint * TMath::Tan(fStereoB);
1217 Double_t xp = xint + fBackStripShift + yint * fTanB; //AZ
1218 // Calculate modulo w.r.t. sensor x width
1219 xp = xp - TMath::Floor(xp/fLx) * fLx;
1220 // Digitise
1221 Int_t iStrip = (Int_t) ( xp / fDx );
1222 if (iStrip < 0 || iStrip > fNChannelsBack) {
1223 cout << "-E- CbmStsSensor::BackStripNumber: Invalid strip number"
1224 << " " << iStrip << endl;
1225 cout << " Sensor " << fDetectorId << ", x = " << xint << ", y = "
1226 << yint << endl;
1227 Fatal("BackStripNumber", "Invalid strip number" );
1228 }
1229 return iStrip;
1230 }
1231
1232
1233 }
1234
1235 // Return -1 if point is outside sensor
1236 return -1;
1237
1238}
1239// -------------------------------------------------------------------------
1240
1241
1242
1243// ----- Private method IntCoord ---------------------------------------
1244Bool_t CbmStsSensor::IntCoord(Double_t x, Double_t y,
1245 Double_t& xint, Double_t& yint) const {
1246
1247 // Translation into sensor centre system
1248 x = x - fX0;
1249 y = y - fY0;
1250
1251 // Rotation around the sensor centre
1252 //xint = x * TMath::Cos(fRotation) + y * TMath::Sin(fRotation);
1253 //yint = y * TMath::Cos(fRotation) - x * TMath::Sin(fRotation);
1254 xint = x * fCosRot + y * fSinRot; //AZ
1255 yint = y * fCosRot - x * fSinRot; //AZ
1256
1257 // Translation into sensor corner system
1258 xint = xint + fLx/2.;
1259 yint = yint + fLy/2.;
1260
1261 // Check whether point is inside the sensor
1262 if ( ! IsInside(xint, yint) ) {
1263 xint = yint = 0.;
1264 return kFALSE;
1265 }
1266
1267 return kTRUE;
1268
1269}
1270// -------------------------------------------------------------------------
1271
1272
1273// ----- Private method IntCoord ---------------------------------------
1274Bool_t CbmStsSensor::IntCoord(Double_t x, Double_t y, Double_t z,
1275 Double_t& xint, Double_t& yint, Double_t& zint) const {
1276
1277 // Translation into sensor centre system
1278 x = x - fX0;
1279 y = y - fY0;
1280
1281 // Rotation around the sensor centre
1282 xint = x * TMath::Cos(fRotation) + y * TMath::Sin(fRotation);
1283 yint = y * TMath::Cos(fRotation) - x * TMath::Sin(fRotation);
1284
1285 // Translation into sensor corner system
1286 xint = xint + fLx/2.;
1287 yint = yint + fLy/2.;
1288
1289 // Check whether point is inside the sensor
1290 if ( ! IsInside(xint, yint) ) {
1291 xint = yint = 0.;
1292 return kFALSE;
1293 }
1294
1295 return kTRUE;
1296
1297}
1298// -------------------------------------------------------------------------
1299
1300
1301
1302// ----- Private method IsInside ---------------------------------------
1303Bool_t CbmStsSensor::IsInside(Double_t xint, Double_t yint) const {
1304 if ( xint < 0. ) return kFALSE;
1305 if ( xint > fLx ) return kFALSE;
1306 if ( yint < 0. ) return kFALSE;
1307 if ( yint > fLy ) return kFALSE;
1308 return kTRUE;
1309}
1310// -------------------------------------------------------------------------
const Float_t d
Z-ccordinate of the first GEM-station.
Definition BmnMwpcHit.cxx:7
const Float_t z0
Definition BmnMwpcHit.cxx:6
Float_t GetChannelPlus(Double_t x, Double_t y, Int_t iSide)
Int_t IntersectClusters(Double_t fChan, Double_t bChan, Double_t &xCross, Double_t &yCross, Double_t &zCross)
Int_t Intersect(Int_t iFStrip, Int_t iBStrip, std::vector< Double_t > &xCross, std::vector< Double_t > &yCross)
Bool_t Inside(Double_t x, Double_t y)
Int_t GetFrontChannel(Double_t x, Double_t y, Double_t z, Double_t &dPitch)
Int_t GetNChannels() const
Int_t GetBackChannel(Double_t x, Double_t y, Double_t z, Double_t &dPitch)
Bool_t ActivateChannels(Int_t ipt, Double_t x, Double_t y)
Int_t GetStationNr() const
Int_t PointIndex(Int_t iFStrip, Int_t IBStrip)
virtual ~CbmStsSensor()
Int_t GetChannel(Double_t x, Double_t y, Int_t iSide)
Int_t GetSensorNr() const
vector< string > glob(const string &path)