DQM configure file
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerCircuit.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 /* $Id$ */
17
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONTriggerCircuit
20 /// Contains as data members the Y positions of the X declusturized strips and 
21 /// the X positions of the (doubled or not) Y strips.
22 /// This is used to associate the global positions to the fired strips of the 
23 /// local trigger output (see AliMUONTrackReconstructor::MakeTriggerTrack)
24 ///
25 /// \author Philippe Crochet (LPCCFd)
26 //-----------------------------------------------------------------------------
27
28 #include "AliMUONTriggerCircuit.h"
29 #include "AliMUONConstants.h"
30 #include "AliMUONGeometryTransformer.h"
31
32 #include "AliMpTrigger.h"
33 #include "AliMpSlat.h"
34 #include "AliMpPCB.h"
35 #include "AliMpSegmentation.h"
36 #include "AliMpVSegmentation.h"
37 #include "AliMpCathodType.h"
38 #include "AliMpDDLStore.h"
39 #include "AliMpLocalBoard.h"
40 #include "AliMpConstants.h"
41 #include "AliMpPad.h"
42 #include "AliMpEncodePair.h"
43
44 #include "AliRun.h"
45 #include "AliLog.h"
46
47 #include <TMath.h>
48 #include <Riostream.h>
49
50 using std::cout;
51 using std::endl;
52 /// \cond CLASSIMP
53 ClassImp(AliMUONTriggerCircuit)
54 /// \endcond
55
56 //----------------------------------------------------------------------
57 AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONGeometryTransformer* transformer)
58     : TObject(),
59       fkTransformer(transformer),
60       fkCurrentSeg(0x0),
61       fCurrentDetElem(0x0),
62       fCurrentLocalBoard(0x0)
63 {
64 /// Constructor
65   
66     for (Int_t i = 1; i < AliMpConstants::NofLocalBoards()+1; ++i) {
67       fXpos11[i].Set(16); 
68       fYpos11[i].Set(32);
69       fYpos21[i].Set(64);
70       fZpos11[i].Set(32);
71       fZpos21[i].Set(64);
72       fXwidth11[i].Set(16); 
73       fYwidth11[i].Set(32);
74       fYwidth21[i].Set(64);
75     }
76
77     for (Int_t i = 1; i < AliMpConstants::NofLocalBoards()+1; ++i) { // board begins at 1
78   
79     AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(i);
80
81     if (!localBoard)
82     {
83       AliError(Form("Did not get localboard %d",i));
84       continue;
85     }
86
87     LoadXPos(localBoard);
88     LoadYPos(localBoard);
89     /*
90     printf("LocalBoard %03d \n",i);
91     printf("fXpos11 \n");
92     for (Int_t i1 = 0; i1 < 16; i1++) 
93       printf("%02d   %7.2f \n",i1,fXpos11[i][i1]);
94     printf("fYpos11 \n");
95     for (Int_t i2 = 0; i2 < 32; i2++) 
96       printf("%02d   %7.2f \n",i2,fYpos11[i][i2]);
97     printf("fYpos21 \n");
98     for (Int_t i3 = 0; i3 < 64; i3++) 
99       printf("%02d   %7.2f \n",i3,fYpos21[i][i3]);
100     printf("fZpos11 \n");
101     for (Int_t i4 = 0; i4 < 32; i4++) 
102       printf("%02d   %8.2f \n",i4,fZpos11[i][i4]);
103     printf("fZpos21 \n");
104     for (Int_t i5 = 0; i5 < 64; i5++) 
105       printf("%02d   %8.2f \n",i5,fZpos21[i][i5]);
106     */
107   }
108
109 }
110
111 //----------------------------------------------------------------------
112 AliMUONTriggerCircuit::~AliMUONTriggerCircuit()
113 {
114 /// Destructor
115    for (Int_t i = 1; i < AliMpConstants::NofLocalBoards()+1; ++i) {
116      fXpos11[i].Reset();
117      fYpos11[i].Reset();
118      fYpos21[i].Reset();
119      fZpos11[i].Reset();
120      fZpos21[i].Reset();
121      fXwidth11[i].Reset();
122      fYwidth11[i].Reset();
123      fYwidth21[i].Reset();
124     }
125
126
127
128 //----------------------------------------------------------------------
129 AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONTriggerCircuit& circuit)
130     :  TObject(circuit),
131        fkTransformer(circuit.fkTransformer), // do not copy, just pointed to
132        fkCurrentSeg(circuit.fkCurrentSeg),
133        fCurrentDetElem(circuit.fCurrentDetElem),
134        fCurrentLocalBoard(circuit.fCurrentLocalBoard)
135 {
136 /// Copy constructor
137
138     for (Int_t i = 1; i < AliMpConstants::NofLocalBoards()+1; ++i) {
139       fXpos11[i] = circuit.fXpos11[i];
140       fYpos11[i] = circuit.fYpos11[i];
141       fYpos21[i] = circuit.fYpos21[i];
142       fZpos11[i] = circuit.fZpos11[i];
143       fZpos21[i] = circuit.fZpos21[i];
144       fXwidth11[i] = circuit.fXwidth11[i];
145       fYwidth11[i] = circuit.fYwidth11[i];
146       fYwidth21[i] = circuit.fYwidth21[i];
147     }
148
149 }
150 //----------------------------------------------------------------------
151 AliMUONTriggerCircuit& AliMUONTriggerCircuit::operator=(const AliMUONTriggerCircuit& circuit) 
152 {
153 /// Assignment operator
154
155   if (this == &circuit) return *this;
156
157   fkTransformer      = circuit.fkTransformer;
158   fkCurrentSeg       = circuit.fkCurrentSeg;
159   fCurrentDetElem    = circuit.fCurrentDetElem;
160   fCurrentLocalBoard = circuit.fCurrentLocalBoard;
161
162   for (Int_t i = 1; i < AliMpConstants::NofLocalBoards()+1; ++i) {
163     fXpos11[i] = circuit.fXpos11[i];
164     fYpos11[i] = circuit.fYpos11[i];
165     fYpos21[i] = circuit.fYpos21[i];
166     fZpos11[i] = circuit.fZpos11[i];
167     fZpos21[i] = circuit.fZpos21[i];
168     fXwidth11[i] = circuit.fXwidth11[i];
169     fYwidth11[i] = circuit.fYwidth11[i];
170     fYwidth21[i] = circuit.fYwidth21[i];
171   }
172
173   return *this;
174
175 }
176
177 //---------------------------------------------------------------------
178 void AliMUONTriggerCircuit::LoadYPos(AliMpLocalBoard* const localBoard)
179 {
180 /// fill fYpos11 and fYpos21 -> y position of X declusterized strips
181   
182   fCurrentLocalBoard = localBoard->GetId();
183   Int_t ichamber = 0;
184   Int_t icathode = 0;    
185     
186   Int_t zeroDown = localBoard->GetSwitch(AliMpLocalBoard::kZeroDown);
187   Int_t zeroUp   = localBoard->GetSwitch(AliMpLocalBoard::kZeroUp);
188  
189   Int_t iline = AliMp::PairFirst(localBoard->GetPosition());
190   Int_t icol  = AliMp::PairSecond(localBoard->GetPosition());
191   if ( iline == 5 ) --icol;
192
193   //--- first plane 
194   ichamber = 10;
195   fCurrentDetElem = AliMpDDLStore::Instance()->GetDEfromLocalBoard(fCurrentLocalBoard, ichamber);
196
197   fkCurrentSeg = AliMpSegmentation::Instance()
198         ->GetMpSegmentation(fCurrentDetElem, AliMp::GetCathodType(icathode));  
199
200   Int_t iFirstStrip = FirstStrip(localBoard);
201   Int_t iLastStrip  = iFirstStrip + 16;    
202   Int_t iStripCircuit = 0;
203
204   FillXstrips(icol, iFirstStrip, iLastStrip, 
205               iStripCircuit, kTRUE);
206   
207   //--- second plane 
208   ichamber = 12;
209   fCurrentDetElem = AliMpDDLStore::Instance()->GetDEfromLocalBoard(fCurrentLocalBoard, ichamber);
210
211   fkCurrentSeg = AliMpSegmentation::Instance()
212         ->GetMpSegmentation(fCurrentDetElem, AliMp::GetCathodType(icathode));  
213
214   // second plane middle part
215   Int_t iFirstStripMiddle = FirstStrip(localBoard);
216   Int_t iLastStripMiddle  = iFirstStrip + 16;
217   iStripCircuit = 8;
218
219   FillXstrips(icol, iFirstStripMiddle, iLastStripMiddle,
220               iStripCircuit, kFALSE);
221   
222   // second plane upper part
223   if (zeroUp == 0) { // something up
224     Int_t iFirstStripUp;
225     Int_t iLastStripUp;
226     Int_t icolUp = icol;
227
228     // check if we need to move to another detElemId
229     AliMpPad pad = fkCurrentSeg->PadByIndices(icol-1,iLastStripMiddle+1,kFALSE);
230
231     if (pad.IsValid()) { // upper strips within same detElemId
232       iFirstStripUp = iLastStripMiddle;
233       iLastStripUp  = iFirstStripUp + 8;
234
235     } else {             // upper strips in another detElemId
236       fCurrentDetElem = AliMpDDLStore::Instance()->
237                    GetNextDEfromLocalBoard(fCurrentLocalBoard, ichamber);
238
239       fkCurrentSeg = AliMpSegmentation::Instance()
240             ->GetMpSegmentation(fCurrentDetElem, AliMp::GetCathodType(icathode));  
241
242       iFirstStripUp = 0;
243       iLastStripUp  = iFirstStripUp + 8;
244       if (iline == 4) icolUp = icol - 1; // special case
245       if (iline == 5) icolUp = icol + 1; // special case
246     }
247     
248     iStripCircuit = 24;
249     FillXstrips(icolUp, iFirstStripUp, iLastStripUp,
250                 iStripCircuit, kFALSE);
251     
252     // fill strip between middle and upper part
253     fYpos21[fCurrentLocalBoard][47] = (fYpos21[fCurrentLocalBoard][46] + 
254                                        fYpos21[fCurrentLocalBoard][48])/2.;
255     fZpos21[fCurrentLocalBoard][47] = (fZpos21[fCurrentLocalBoard][46] + 
256                                        fZpos21[fCurrentLocalBoard][48])/2.;
257     fYwidth21[fCurrentLocalBoard][47] = (fYwidth21[fCurrentLocalBoard][46] + 
258                                          fYwidth21[fCurrentLocalBoard][48])/2.;
259   } // end of something up
260   
261   // restore current detElemId & segmentation
262   fCurrentDetElem = AliMpDDLStore::Instance()->GetDEfromLocalBoard(fCurrentLocalBoard, ichamber);
263   fkCurrentSeg = AliMpSegmentation::Instance()
264       ->GetMpSegmentation(fCurrentDetElem, AliMp::GetCathodType(icathode));  
265
266   // second plane lower part
267   if (zeroDown == 0) { // something down
268     Int_t iFirstStripDo;
269     Int_t iLastStripDo;
270     Int_t icolDo = icol;
271     
272     // check if we need to move to another detElemId      
273     AliMpPad pad = fkCurrentSeg->PadByIndices(icol-1,iFirstStripMiddle-1,kFALSE);
274     if (pad.IsValid()) { // lower strips within same detElemId
275       iFirstStripDo = iFirstStripMiddle - 8;
276       iLastStripDo  = iFirstStripDo + 8;              
277
278     } else {             // lower strips in another detElemId 
279       fCurrentDetElem = AliMpDDLStore::Instance()
280           ->GetPreviousDEfromLocalBoard(fCurrentLocalBoard, ichamber);
281
282       fkCurrentSeg = AliMpSegmentation::Instance()
283           ->GetMpSegmentation(fCurrentDetElem, AliMp::GetCathodType(icathode));  
284
285       // get iFirstStrip in this module 
286       const AliMpTrigger* t = AliMpSegmentation::Instance()->GetTrigger(fkCurrentSeg);
287       const AliMpSlat* slat = t->GetLayer(0);
288
289       if (iline == 5) icolDo = icol + 1; // special case
290       if (iline == 6) icolDo = icol - 1; // special case
291             
292       const AliMpPCB* pcb = slat->GetPCB(icolDo-1);
293       iFirstStripDo = (pcb->Iymax() + 1) - 8;
294       iLastStripDo =  iFirstStripDo + 8;
295     }  
296     
297     iStripCircuit = 0;
298     FillXstrips(icolDo, iFirstStripDo, iLastStripDo,
299                 iStripCircuit, kFALSE);
300     
301     // fill strip between middle and upper part
302     fYpos21[fCurrentLocalBoard][15] = (fYpos21[fCurrentLocalBoard][14] + 
303                                        fYpos21[fCurrentLocalBoard][16])/2.;
304     fZpos21[fCurrentLocalBoard][15] = (fZpos21[fCurrentLocalBoard][14] + 
305                                        fZpos21[fCurrentLocalBoard][16])/2.;
306     fYwidth21[fCurrentLocalBoard][15] = (fYwidth21[fCurrentLocalBoard][14] + 
307                                          fYwidth21[fCurrentLocalBoard][16])/2.;
308   } // end of something down
309   
310 }
311
312 //----------------------------------------------------------------------
313 void AliMUONTriggerCircuit::FillXstrips(const Int_t icol, 
314                                         const Int_t iFirstStrip, const Int_t iLastStrip, 
315                                         Int_t liStripCircuit, const Bool_t is11)
316 {    
317 /// fill 
318   TArrayF& ypos   = (is11) ? fYpos11[fCurrentLocalBoard] : fYpos21[fCurrentLocalBoard];
319   TArrayF& zpos   = (is11) ? fZpos11[fCurrentLocalBoard] : fZpos21[fCurrentLocalBoard];
320   TArrayF& ywidth = (is11) ? fYwidth11[fCurrentLocalBoard] : fYwidth21[fCurrentLocalBoard];
321
322   Double_t xyGlobal[3] = {0.};
323   for (Int_t istrip = iFirstStrip; istrip < iLastStrip; ++istrip) {
324
325     AliMpPad pad = fkCurrentSeg->PadByIndices(icol-1,istrip,kTRUE);
326     if ( !pad.IsValid() ) {
327       StdoutToAliError(cout << "Pad not found in seg " << endl;
328                        fkCurrentSeg->Print();
329                        cout << " ix,iy=" << icol-1 << "," << istrip << endl;
330                        );
331     }
332     Float_t yDim = pad.GetDimensionY(); // half size! 
333
334     XYGlobal(pad,xyGlobal);
335     
336     ypos[2*liStripCircuit] = xyGlobal[1];
337     zpos[2*liStripCircuit] = xyGlobal[2];
338     ywidth[2*liStripCircuit] = 2. * yDim;
339     if (istrip != (iLastStrip - 1)) {
340       ypos[2*liStripCircuit+1] = xyGlobal[1] + yDim;
341       zpos[2*liStripCircuit+1] = xyGlobal[2];
342       ywidth[2*liStripCircuit+1] = 2. * yDim;
343     }
344     liStripCircuit++;
345   }    
346 }
347
348
349 //----------------------------------------------------------------------
350 void AliMUONTriggerCircuit::LoadXPos(AliMpLocalBoard* const localBoard)
351 {
352 /// fill fXpos11 -> x position of Y strips for the first plane only
353 /// fXpos11 contains the x position of Y strip for the current circuit
354 /// taking into account whether or nor not part(s) of the circuit
355 /// (middle, up or down) has(have) 16 strips (handdled by means of switchs)
356
357   fCurrentLocalBoard = localBoard->GetId();
358
359   Int_t ichamber = 10;
360   Int_t icathode = 1;
361   
362   Int_t x2u = localBoard->GetSwitch(AliMpLocalBoard::kX2u);
363   Int_t x2m = localBoard->GetSwitch(AliMpLocalBoard::kX2m);
364   Int_t x2d = localBoard->GetSwitch(AliMpLocalBoard::kX2d);
365   Int_t zeroAllYLSB = localBoard->GetSwitch(AliMpLocalBoard::kZeroAllYLSB);
366
367   Int_t  iStripCircuit = 0;
368   Int_t  iFirstStrip   = 0;
369   Int_t  iLastStrip    = 0;
370   Bool_t doubling      = kFALSE;
371   
372   Int_t iline = AliMp::PairFirst(localBoard->GetPosition());
373   Int_t icol  = AliMp::PairSecond(localBoard->GetPosition());
374   if ( iline == 5 ) --icol;
375
376   fCurrentDetElem = AliMpDDLStore::Instance()->GetDEfromLocalBoard(fCurrentLocalBoard, ichamber);
377
378   fkCurrentSeg = AliMpSegmentation::Instance()
379         ->GetMpSegmentation(fCurrentDetElem, AliMp::GetCathodType(icathode));  
380
381   // check if one needs a strip doubling or not
382   if ( (x2u || x2m || x2d ) && x2m ) doubling = kTRUE;
383   
384
385   // check if one starts at strip = 0 or 8 (boards 26-29 and 143-146)
386   if (zeroAllYLSB) iStripCircuit = 8;
387   
388   // get iFirstStrip in this module 
389   const AliMpTrigger* t = AliMpSegmentation::Instance()->GetTrigger(fkCurrentSeg);
390   const AliMpSlat* slat = t->GetLayer(0);
391   
392   const AliMpPCB* pcb = slat->GetPCB(icol-1);
393   iFirstStrip = pcb->Ixmin();
394   
395
396   if (doubling || zeroAllYLSB == 1) iLastStrip = iFirstStrip + 8;
397   else iLastStrip = iFirstStrip + 16;
398   
399   FillYstrips(iFirstStrip, iLastStrip, iStripCircuit, doubling);  
400 }
401
402 //----------------------------------------------------------------------
403 void AliMUONTriggerCircuit::FillYstrips(const Int_t iFirstStrip, const Int_t iLastStrip, 
404                                         Int_t liStripCircuit,
405                                         const Bool_t doubling)
406 {    
407 /// fill
408   Double_t xyGlobal[3] = {0.};
409
410   for (Int_t istrip = iFirstStrip; istrip < iLastStrip; ++istrip) {
411
412     AliMpPad pad = fkCurrentSeg->PadByIndices(istrip,0,kTRUE);
413
414     if ( !pad.IsValid() )
415     {
416         StdoutToAliError(cout << "Pad not found in seg " << endl;
417                          fkCurrentSeg->Print();
418                          cout << " ix,iy=" << istrip << "," << 0 << endl;
419                          );
420     }
421     Float_t xDim = pad.GetDimensionX(); // half size!
422
423     XYGlobal(pad,xyGlobal);
424     
425     if (!doubling) {    
426       fXpos11[fCurrentLocalBoard].AddAt(xyGlobal[0], liStripCircuit);
427       fXwidth11[fCurrentLocalBoard].AddAt(2. * xDim, liStripCircuit);
428     } else if (doubling) {
429
430       fXpos11[fCurrentLocalBoard].AddAt(TMath::Sign(1.,xyGlobal[0]) * 
431                                   (TMath::Abs(xyGlobal[0]) - xDim/2.), 2*liStripCircuit);
432       fXwidth11[fCurrentLocalBoard].AddAt(2. * xDim, 2*liStripCircuit);
433
434       fXpos11[fCurrentLocalBoard].AddAt(TMath::Sign(1.,xyGlobal[0]) *
435                                   (TMath::Abs(fXpos11[fCurrentLocalBoard][2*liStripCircuit]) + xDim),
436                                         2*liStripCircuit + 1); 
437       fXwidth11[fCurrentLocalBoard].AddAt(2. * xDim, 2*liStripCircuit + 1);
438     }
439
440     liStripCircuit++;
441   }    
442 }
443
444 //----------------------------------------------------------------------
445 void AliMUONTriggerCircuit::XYGlobal(const AliMpPad& pad,
446                                      Double_t* xyGlobal)
447 {
448 /// returns pad x & y positions and x & y pad dimensions in global coordinates
449 /// note: no need for transformation for pad dimensions
450   
451   // get the pad position and dimensions
452   Double_t xl1 = pad.GetPositionX();
453   Double_t yl1 = pad.GetPositionY();
454   
455   // positions from local to global 
456   fkTransformer->Local2Global(fCurrentDetElem, xl1, yl1, 0, 
457                                  xyGlobal[0], xyGlobal[1], xyGlobal[2]);
458 }
459
460
461 //----------------------------------------------------------------------
462 //--- methods which return member data related info
463 //----------------------------------------------------------------------
464 //----------------------------------------------------------------------
465 Float_t AliMUONTriggerCircuit::GetX11Pos(Int_t localBoardId, Int_t istrip) const 
466 {
467 /// returns X position of Y strip istrip in MC11
468   return fXpos11[localBoardId][istrip];
469 }
470 Float_t AliMUONTriggerCircuit::GetY11Pos(Int_t localBoardId, Int_t istrip) const 
471 {
472 /// returns Y position of X strip istrip in MC11
473   return fYpos11[localBoardId][istrip];
474 }
475 //----------------------------------------------------------------------
476 Float_t AliMUONTriggerCircuit::GetY21Pos(Int_t localBoardId, Int_t istrip) const 
477 {
478 /// returns Y position of X strip istrip in MC21
479   return fYpos21[localBoardId][istrip];
480 }
481 //----------------------------------------------------------------------
482 Float_t AliMUONTriggerCircuit::GetZ11Pos(Int_t localBoardId, Int_t istrip) const 
483 {
484 /// returns Z position of X strip istrip in MC11
485   return fZpos11[localBoardId][istrip];
486 }
487 //----------------------------------------------------------------------
488 Float_t AliMUONTriggerCircuit::GetZ21Pos(Int_t localBoardId, Int_t istrip) const 
489 {
490 /// returns Z position of X strip istrip in MC21
491   return fZpos21[localBoardId][istrip];
492 }
493 Float_t AliMUONTriggerCircuit::GetX11Width(Int_t localBoardId, Int_t istrip) const 
494 {
495 /// returns width of Y strip istrip in MC11
496   return fXwidth11[localBoardId][istrip];
497 }
498 Float_t AliMUONTriggerCircuit::GetY11Width(Int_t localBoardId, Int_t istrip) const 
499 {
500 /// returns width of X strip istrip in MC11
501   return fYwidth11[localBoardId][istrip];
502 }
503 //----------------------------------------------------------------------
504 Float_t AliMUONTriggerCircuit::GetY21Width(Int_t localBoardId, Int_t istrip) const 
505 {
506 /// returns width of X strip istrip in MC21
507   return fYwidth21[localBoardId][istrip];
508 }
509
510 //----------------------------------------------------------------------
511 Int_t AliMUONTriggerCircuit::FirstStrip(AliMpLocalBoard* localBoard)
512 {
513 /// returns the first strip from mapping for board boardName
514 /// take care of special case for boards RC1L6B12 & LC1L6B12
515   Int_t iFirstStrip = -1;
516   Int_t boardNumber = atoi(localBoard->GetName()+6);
517
518   Int_t iline = AliMp::PairFirst(localBoard->GetPosition());
519   Int_t icol  = AliMp::PairSecond(localBoard->GetPosition());
520   if ( iline == 5 ) --icol;
521
522   switch (boardNumber)
523   {
524     case 12:
525       iFirstStrip = 0;
526       break;            
527     case 34:
528       iFirstStrip = 16;
529       break;            
530     case 56:
531       iFirstStrip = 32;
532       break;            
533     case 78:
534       iFirstStrip = 48;
535       break;            
536   }
537   if (icol == 1 && iline == 6) iFirstStrip += 16; // special case
538   return iFirstStrip;
539 }
540
541 //----------------------------------------------------------------------
542 Float_t AliMUONTriggerCircuit::PtCal(Int_t localBoardId, Int_t istripX, Int_t idev, Int_t istripY) const{
543 /// returns calculated pt for circuit/istripX/idev/istripY according 
544 /// to the formula of the TRD. Note : idev (input) is in [0+30]
545
546   Int_t istripX2=istripX+idev+1; // find istripX2 using istripX and idev
547
548   Float_t yPosX1=fYpos11[localBoardId][istripX];
549   Float_t yPosX2=fYpos21[localBoardId][istripX2];
550   Float_t xPosY1=fXpos11[localBoardId][istripY];
551
552 // Z distance between IP and center of dipole
553   Float_t zf= 0.5 *(AliMUONConstants::CoilZ() + AliMUONConstants::YokeZ());
554   Float_t z1=fZpos11[localBoardId][istripX];
555   Float_t z2=fZpos21[localBoardId][istripX2];
556   Float_t thetaDev=(1./TMath::Abs(zf))*(yPosX1*z2-yPosX2*z1)/(z2-z1);
557   Float_t xf=xPosY1*zf/z1; 
558   Float_t yf=yPosX2-((yPosX2-yPosX1)*(z2-zf))/(z2-z1);
559   return (3.*0.3/TMath::Abs(thetaDev)) * TMath::Sqrt(xf*xf+yf*yf)/TMath::Abs(zf);
560 }