Including pedestal calibration for time bins
[u/mrichter/AliRoot.git] / TPC / AliTPCmapper.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 //-------------------------------------------------------------------------
17 //
18 // AliTPCmapper
19 // Authors: Christian.Lippmann@cern.ch, J.Wiechula@gsi.de
20 // Class to map detector coordinates (row, pad, sector, ...) to
21 // hardware coordinates (RCU, Branch, FEC, Altro, channel, Equipment ID, ...)
22 // 
23 // There are two different ways to number padrows:
24 // 1) local padrow: for each ROC, 0 ... 62 for an IROC, 0 ... 95 for an OROC,
25 // 2) global padrow: for each sector, from 0 ... 158.
26 // If the global numbering is used, it is denoted by the variable name
27 // globalpadrow in this class.
28 //
29 // There are two different ways to number sectors:
30 // 1) Sectors contain one IROC and one OROC and are counted from 0 to 17 on
31 //    each of the two sides (A=0 and C=1),
32 // 2) ROCs are numbered from 0 to 71 where the ROCs 0 ... 35 are IROCS and
33 //    ROCs 36 ... 71 are OROCs. A ROC is often named "sector" in aliroot,
34 //    which can be very confusing!
35 //
36 //-------------------------------------------------------------------------
37
38 #include <TMath.h>
39 #include <TSystem.h>
40 #include <TString.h>
41
42 #include "AliTPCmapper.h"
43 #include "AliTPCAltroMapping.h"
44 #include "AliTPCROC.h"
45 #include "AliLog.h"
46 #include "AliDAQ.h"
47
48 ClassImp(AliTPCmapper)
49
50 //______________________________________________________________
51 AliTPCmapper::AliTPCmapper() :
52   fNside(0),
53   fNsector(0),
54   fNrcu(0),
55   fNbranch(0),
56   fNaltro(0),
57   fNchannel(0),
58   fNpadrow(0),
59   fNpadrowIROC(0),
60   fNpadrowOROC(0),
61   fTpcDdlOffset(0),
62   fROC(NULL)
63 {
64   // Constructor
65   Init();
66 }
67
68 //______________________________________________________________
69 AliTPCmapper::~AliTPCmapper()
70 {
71   // Destructor
72
73   delete fROC;
74
75   for ( Int_t i = 0; i < fNrcu; i++ ) {
76     delete fMapping[i];
77     fMapping[i] = 0;
78   }
79 }
80
81
82 //_____________________________________________________________________________
83 AliTPCmapper::AliTPCmapper(const AliTPCmapper& mapper) :
84   TObject(mapper),
85   fNside(mapper.fNside),
86   fNsector(mapper.fNsector),
87   fNrcu(mapper.fNrcu),
88   fNbranch(mapper.fNbranch),
89   fNaltro(mapper.fNaltro),
90   fNchannel(mapper.fNchannel),
91   fNpadrow(mapper.fNpadrow),
92   fNpadrowIROC(mapper.fNpadrowIROC),
93   fNpadrowOROC(mapper.fNpadrowOROC),
94   fTpcDdlOffset(mapper.fTpcDdlOffset),
95   fROC(mapper.fROC)
96 {
97   // Copy Constructor
98   for ( Int_t i = 0; i < fNrcu; i++ ) fMapping[i] = mapper.fMapping[i];
99 }
100
101 //_____________________________________________________________________________
102 AliTPCmapper& AliTPCmapper::operator = (const AliTPCmapper& mapper)
103 {
104   // Assignment operator
105
106   if(&mapper == this) return *this;
107   ((TObject *)this)->operator=(mapper);
108
109   for ( Int_t i = 0; i < fNrcu; i++ ) fMapping[i] = mapper.fMapping[i];
110   fROC = mapper.fROC;
111
112   fNside = mapper.fNside;
113   fNsector = mapper.fNsector;
114   fNrcu = mapper.fNrcu;
115   fNbranch = mapper.fNbranch;
116   fNaltro = mapper.fNaltro;
117   fNchannel = mapper.fNchannel;
118   fNpadrow = mapper.fNpadrow;
119   fNpadrowIROC = mapper.fNpadrowIROC;
120   fNpadrowOROC = mapper.fNpadrowOROC;
121   fTpcDdlOffset = mapper.fTpcDdlOffset;
122
123   return *this;
124 }
125
126 //______________________________________________________________
127 void AliTPCmapper::Init()
128 {
129   // Initialize all
130   fNside    = 2;
131   fNsector  = 18;
132   fNrcu     = 6;
133   fNbranch  = 2;
134   fNaltro   = 8;
135   fNchannel = 15;
136
137   // Load and read mapping files. AliTPCAltroMapping contains the mapping for
138   // each patch (rcu).
139   TString path = gSystem->Getenv("ALICE_ROOT");
140   path += "/TPC/mapping/Patch";
141   TString path2;
142   for(Int_t i = 0; i < fNrcu; i++) {
143     path2 = path;
144     path2 += i;
145     path2 += ".data";
146     fMapping[i] = new AliTPCAltroMapping(path2.Data());
147   }
148
149   // Create instance of AliTPCROC object
150   fROC = AliTPCROC::Instance();
151
152   fNpadrowIROC = fROC->GetNRows(0);
153   fNpadrowOROC = fROC->GetNRows(36);
154   fNpadrow = fNpadrowIROC+fNpadrowOROC;
155
156   AliDAQ daq;
157   fTpcDdlOffset = daq.DdlIDOffset("TPC");
158
159 }
160
161
162 //_____________________________________________________________________________
163 Int_t AliTPCmapper::GetHWAddress(Int_t roc, Int_t padrow, Int_t pad) const
164 {
165   // Get the hardware address from pad coordinates for a given ROC
166   Int_t patch = GetPatch(roc, padrow, pad);
167   if ( (patch >= fNrcu) || (patch < 0) ) return -1;
168   return fMapping[patch]->GetHWAddress(padrow, pad, roc);
169 }
170
171
172 //_____________________________________________________________________________
173 Int_t AliTPCmapper::GetHWAddressSector(Int_t globalpadrow, Int_t pad) const
174 {
175   // Get the hardware address from pad coordinates
176   Int_t patch = 0;
177   if ( globalpadrow < fNpadrowIROC   ) {
178     patch = GetPatch(0,  globalpadrow, pad);
179     return fMapping[patch]->GetHWAddress(globalpadrow, pad, 0);
180   } else if ( globalpadrow < fNpadrow ) {
181     patch = GetPatch(36, globalpadrow - fNpadrowIROC, pad);
182     return fMapping[patch]->GetHWAddress(globalpadrow - fNpadrowIROC,
183                                          pad, 36);
184   } else {
185     AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
186     return -1;
187   }
188 }
189
190
191 //_____________________________________________________________________________
192 Int_t AliTPCmapper::GetRcu(Int_t roc, Int_t padrow, Int_t pad) const
193 {
194   // Get the patch (rcu) index from the pad coordinates. The Roc index is
195   // needed as well to determine if it is IROC or OROC. 
196   return GetPatch(roc, padrow, pad);
197 }
198
199
200 //_____________________________________________________________________________
201 Int_t AliTPCmapper::GetPatch(Int_t roc, Int_t padrow, Int_t pad) const
202 {
203   // Get the patch (rcu) index from the pad coordinates. The Roc index is
204   // needed as well to determine if it is IROC or OROC. 
205
206   if ( (padrow < 0) || (pad < 0) || (roc < 0) ) {
207     AliWarning(Form("Pad coordinates outside range (padrow %d, pad %d, roc %d) !", padrow, pad, roc));
208     return -1;
209   }
210
211   if ( roc < 36 ) {
212     // IROC (0 ... 35)
213     Int_t padsInRow = GetNpads(padrow);
214     if ( (padsInRow < 0) || (pad >= padsInRow) ) {
215       AliWarning(Form("Pad index outside range (padrow %d, pad %d, roc %d) !", padrow, pad, roc));
216       return -1;
217     }
218     if ( padrow < 30 ) {                  return 0;
219     } else if ( padrow == 30 ) {          // padrow 30 is shared between rcus 0 and 1
220       if ( (pad < 37) || (pad > 48) )     return 1;
221       else                                return 0;
222     } else if ( padrow < fNpadrowIROC ) { return 1;
223     } else {
224       AliWarning(Form("Padrow outside range (padrow %d, roc %d) !", padrow, roc));
225       return -1;
226     }
227   } else if ( roc < 72 ) {
228     // OROC (36 ... 71)
229     Int_t padsInRow = GetNpads(fNpadrowIROC+padrow);
230     if ( (padsInRow < 0) || (pad >= padsInRow) ) {
231       AliWarning(Form("Pad index outside range (padrow %d, pad %d, roc %d) !", padrow, pad, roc));
232       return -1;
233     }
234     if ( padrow < 27 ) {                  return 2;
235     } else if ( padrow == 27 ) {          // padrow 27 is shared between rcus 2 and 3
236       if ( (pad >= 43) && (pad <= 46) )   return 3;
237       else                                return 2;
238     } else if ( padrow < 54 ) {           return 3;
239     } else if ( padrow < 76 ) {           return 4;
240     } else if ( padrow == 76) {           // padrow 76 is shared between rcus 4 and 5
241       if ( (pad >= 33) && (pad <= 88) )   return 5;
242       else                                return 4;
243     } else if ( padrow < fNpadrowOROC ) { return 5;
244     } else {
245       AliWarning(Form("Padrow outside range (padrow %d, roc %d) !", padrow, roc));
246       return -1;
247     }
248   }
249   return -1;
250 }
251
252
253 //_____________________________________________________________________________
254 Int_t AliTPCmapper::GetRcuSector(Int_t globalpadrow, Int_t pad) const
255 {
256   // Get the patch (rcu) index from the pad coordinates for a sector
257   return GetPatchSector(globalpadrow, pad);
258 }
259
260
261 //_____________________________________________________________________________
262 Int_t AliTPCmapper::GetPatchSector(Int_t globalpadrow, Int_t pad) const
263 {
264   // Get the patch (rcu) index from the pad coordinates for a sector
265   if ( globalpadrow >= fNpadrow ) {
266     AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
267     return -1;
268   }
269   if ( globalpadrow < fNpadrowIROC ) return GetPatch(0,  globalpadrow, pad);
270   else                               return GetPatch(36, globalpadrow-fNpadrowIROC, pad);
271 }
272
273
274 //_____________________________________________________________________________
275 Int_t AliTPCmapper::GetPadRow(Int_t patch, Int_t hwAddress) const
276 {
277   // Get Pad Row (for a ROC) from the hardware address
278   if ( (patch >= fNrcu) || (patch < 0) ) {
279     AliWarning(Form("Patch index outside range (patch %d) !", patch));
280     return -1;
281   }
282   return fMapping[patch]->GetPadRow(hwAddress);
283 }
284
285
286 //_____________________________________________________________________________
287   Int_t AliTPCmapper::GetGlobalPadRow(Int_t patch, Int_t hwAddress) const
288 {
289   // Get Pad Row (for full sector) from the hardware address
290   if ( patch < 2 ) return GetPadRow(patch, hwAddress);
291   else             return GetPadRow(patch, hwAddress) + fNpadrowIROC;
292 }
293
294
295 //_____________________________________________________________________________
296 Int_t AliTPCmapper::GetPad(Int_t patch, Int_t hwAddress) const
297 {
298   // Get Pad index from the hardware address
299   if ( (patch >= fNrcu) || (patch < 0) ) {
300     AliWarning(Form("Patch index outside range (patch %d) !", patch));
301     return -1;
302   }
303   return fMapping[patch]->GetPad(hwAddress);
304 }
305
306
307 //_____________________________________________________________________________
308 Int_t AliTPCmapper::GetPadRow(Int_t patch, Int_t branch, Int_t fec, Int_t chip,
309                               Int_t channel) const
310 {
311   // Get pad row (for a ROC) from hardware coordinates
312   if ( (patch >= fNrcu) || (branch >= fNbranch) || (chip >= fNaltro) || (channel >= fNchannel)
313        || (patch < 0) || (branch < 0) || (chip < 0) || (channel < 0) ) {
314     AliWarning(Form("Coordinates outside range (patch %d, branch %d, fec %d, chip %d, channel %d)) !",
315                     patch, branch, fec, chip, channel));
316     return -1;
317   }
318   return GetPadRow(patch, CodeHWAddress(branch, fec, chip, channel));
319 }
320
321
322 //_____________________________________________________________________________
323 Int_t AliTPCmapper::GetGlobalPadRow(Int_t patch, Int_t branch, Int_t fec, Int_t chip,
324                                     Int_t channel) const
325 {
326   // Get Pad Row (for full sector) from the hardware address
327   if ( (patch >= fNrcu) || (branch >= fNbranch) || (chip >= fNaltro) || (channel >= fNchannel)
328        || (patch < 0) || (branch < 0) || (chip < 0) || (channel < 0) ) {
329     AliWarning(Form("Coordinates outside range (patch %d, branch %d, fec %d, chip %d, channel %d)) !",
330                     patch, branch, fec, chip, channel));
331     return -1;
332   }
333   if ( patch < 2 ) return GetPadRow(patch, branch, fec, chip, channel);
334   else             return GetPadRow(patch, branch, fec, chip, channel) + fNpadrowIROC;
335 }
336
337
338 //_____________________________________________________________________________
339   Int_t AliTPCmapper::GetPad(Int_t patch, Int_t branch, Int_t fec, Int_t chip, Int_t channel) const
340 {
341   // Get pad from hardware coordinates
342   if ( (patch >= fNrcu) || (branch >= fNbranch) || (chip >= fNaltro) || (channel >= fNchannel)
343        || (patch < 0) || (branch < 0) || (chip < 0) || (channel < 0) ) {
344     AliWarning(Form("Coordinates outside range (patch %d, branch %d, fec %d, chip %d, channel %d)) !",
345                     patch, branch, fec, chip, channel));
346     return -1;
347   }
348   return GetPad(patch, CodeHWAddress(branch, fec, chip, channel));
349 }
350
351
352 //_____________________________________________________________________________
353 Int_t AliTPCmapper::GetBranch(Int_t roc, Int_t padrow, Int_t pad) const
354 {
355   // Get the branch to which this pad is connected. The FECs connected to
356   // one RCU are divided into two branches: A(=0) and B(=1). This information
357   // can be extracted from the hardware address.
358   return DecodedHWAddressBranch(GetHWAddress(roc, padrow, pad));
359 }
360
361
362 //_____________________________________________________________________________
363 Int_t AliTPCmapper::GetBranchSector(Int_t globalpadrow, Int_t pad) const
364 {
365   // Get Branch from pad coordinates, where globalpadrow is counted
366   // for a full sector (0 ... 158)
367   return DecodedHWAddressBranch(GetHWAddressSector(globalpadrow, pad));
368 }
369
370
371 //_____________________________________________________________________________
372 Int_t AliTPCmapper::GetFEChw(Int_t roc, Int_t padrow, Int_t pad) const
373 {
374   // Get the FEC number in hardware numbering. The FECs are numbered from 0 (in the
375   // center of the partition) to 8 (partition 3, 4, 5), 9 (partition 0, 2), 11
376   // (partition 1, branch A) or 12 (partition 1, branch B). This information
377   // can be extracted from the hardware address.
378   return DecodedHWAddressFECaddr(GetHWAddress(roc, padrow, pad));
379 }
380
381
382 //_____________________________________________________________________________
383 Int_t AliTPCmapper::GetFEChwSector(Int_t globalpadrow, Int_t pad) const
384 {
385   // Get the FEC number in hardware numbering from pad coordinates, where 
386   // globalpadrow is counted for a full sector (0 ... 158)
387   return DecodedHWAddressFECaddr(GetHWAddressSector(globalpadrow, pad));
388 }
389
390
391 //_____________________________________________________________________________
392 Int_t AliTPCmapper::GetFEC(Int_t roc, Int_t padrow, Int_t pad) const
393 {
394   // Get the FEC number in offline-oriented numbering. The FECs are numbered from 0
395   // 17 (partition 3, 4, 5), 19 (partition 0, 2) or 24 (partition 1).
396   Int_t patch  = GetPatch(roc, padrow, pad);
397   Int_t fec    = DecodedHWAddressFECaddr(GetHWAddress(roc, padrow, pad));
398   Int_t branch = DecodedHWAddressBranch(GetHWAddress(roc, padrow, pad));
399   if ( (fec < 0) || (branch < 0) || (patch < 0) ) return -1;
400   return HwToOffline(patch, branch, fec);
401 }
402
403
404 //_____________________________________________________________________________
405 Int_t AliTPCmapper::GetFECSector(Int_t globalpadrow, Int_t pad) const
406 {
407   // Get the FEC number in offline-oriented numbering. globalpadrow is
408   // counted for a full sector (0 ... 158)
409   Int_t patch  = GetPatchSector(globalpadrow, pad);
410   Int_t fec    = DecodedHWAddressFECaddr(GetHWAddressSector(globalpadrow, pad));
411   Int_t branch = DecodedHWAddressBranch(GetHWAddressSector(globalpadrow, pad));
412   if ( (fec < 0) || (branch < 0) || (patch < 0) ) return -1;
413   return HwToOffline(patch, branch, fec);
414 }
415
416
417 //_____________________________________________________________________________
418 Int_t AliTPCmapper::GetChip(Int_t roc, Int_t padrow, Int_t pad) const
419 {
420   // Get Chip (ALTRO) index (0 ... 7) from pad coordinates
421   return DecodedHWAddressChipaddr(GetHWAddress(roc, padrow, pad));
422 }
423
424
425 //_____________________________________________________________________________
426 Int_t AliTPCmapper::GetChipSector(Int_t globalpadrow, Int_t pad) const
427 {
428   // Get Chip (ALTRO) index (0 ... 7) from pad coordinates, where 
429   // globalpadrow is counted for a full sector (0 ... 158)
430   return DecodedHWAddressChipaddr(GetHWAddressSector(globalpadrow, pad));
431 }
432
433
434 //_____________________________________________________________________________
435 Int_t AliTPCmapper::GetChannel(Int_t roc, Int_t padrow, Int_t pad) const
436 {
437   // Get Channel index (0 ... 15) from pad coordinates
438   return DecodedHWAddressChanneladdr(GetHWAddress(roc, padrow, pad));
439 }
440
441
442 //_____________________________________________________________________________
443 Int_t AliTPCmapper::GetChannelSector(Int_t globalpadrow, Int_t pad) const
444 {
445   // Get Channel index (0 ... 15) from pad coordinates, where 
446   // globalpadrow is counted for a full sector (0 ... 158)
447   return DecodedHWAddressChanneladdr(GetHWAddressSector(globalpadrow, pad));
448 }
449
450
451 //_____________________________________________________________________________
452 Int_t AliTPCmapper::CodeHWAddress(Int_t branch, Int_t fec, Int_t chip, Int_t channel) const
453 {
454   // Get Hardware address from channel, altro, fec and branch coordinates
455   return ((branch&1)<<11) + ((fec&0xf)<<7) + ((chip&0x7)<<4) + (channel&0xf);
456 }
457
458
459 //_____________________________________________________________________________
460 Int_t AliTPCmapper::DecodedHWAddressBranch(Int_t hwAddress) const
461 {
462   // Get branch index (0, 1) from hardware address
463   if ( hwAddress < 0 ) return -1;
464   return ((hwAddress>>11)&1);
465 }
466
467
468 //_____________________________________________________________________________
469 Int_t AliTPCmapper::DecodedHWAddressFECaddr(Int_t hwAddress) const
470 {
471   // Get FEC index (0 ... 12) from hardware address
472   if ( hwAddress < 0 ) return -1;
473   return ((hwAddress>>7)&0xf);
474 }
475
476
477 //_____________________________________________________________________________
478 Int_t AliTPCmapper::DecodedHWAddressChipaddr(Int_t hwAddress) const
479 {
480   // Get ALTRO index (0 ... 7) from hardware address
481   if ( hwAddress < 0 ) return -1;
482   return ((hwAddress>>4)&0x7);
483 }
484
485
486 //_____________________________________________________________________________
487 Int_t AliTPCmapper::DecodedHWAddressChanneladdr(Int_t hwAddress) const
488 {
489   // Get channel index (0 ... 15) from hardware address
490   if ( hwAddress < 0 ) return -1;
491   return ((hwAddress&0xf));
492 }
493
494
495 //______________________________________________________________
496 Int_t AliTPCmapper::GetNpads(Int_t roc, Int_t padrow) const{
497   // Get number of pads in padrow for this ROC.
498   return fROC->GetNPads((UInt_t)roc, (UInt_t)padrow);
499 }
500
501
502 //______________________________________________________________
503 Int_t AliTPCmapper::GetNpads(Int_t globalpadrow) const{
504   // Get number of pads in padrow, where globalpadrow is counted for a full sector (0 ... 158)
505
506   if ( globalpadrow >= fNpadrow ) {
507     AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
508     return -1;
509   }
510   if ( globalpadrow < fNpadrowIROC ) return GetNpads(0,  globalpadrow);  // IROC
511   else  return GetNpads(36, globalpadrow - fNpadrowIROC);                // OROC
512
513   return -1;
514 }
515
516
517 //______________________________________________________________
518 Int_t AliTPCmapper::GetNpadrows(Int_t roc) const
519 {
520   // Get number of padrows
521   return fROC->GetNRows(roc);
522 }
523
524
525 //______________________________________________________________
526 /*
527 Double_t AliTPCmapper::GetPadXlocal(Int_t globalpadrow) const
528 {
529   // Get local x coordinate of pad, where globalpadrow is counted for a full sector (0 ... 158)
530
531   if ( globalpadrow >= fNpadrow ) {
532     AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
533     return -1.0;
534   }
535
536   //IROC
537   if ( globalpadrow < fNpadrowIROC )
538     return (852.25 + 7.5*(Double_t)globalpadrow)/10.; //divide by 10 to get cm
539
540   globalpadrow -= fNpadrowIROC;
541
542   if ( globalpadrow < 64 ) //OROC inner part
543     return (10.* globalpadrow + 1351.)/10.;         //divide by 10 to get cm
544
545   //OROC outer part
546   return (15.*(globalpadrow - 64) + 1993.5)/10.;    //divide by 10 to get cm
547 }
548 */
549
550 //______________________________________________________________
551 /*
552 Double_t AliTPCmapper::GetPadYlocal(Int_t globalpadrow, Int_t pad) const
553 {
554   // Get local y coordinate of pad, where globalpadrow is counted for a full sector (0 ... 158)
555
556   if ( globalpadrow >= fNpadrow ) {
557     AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
558     return -1.0;
559   }
560
561   Int_t padsInRow = GetNpads(globalpadrow);
562   if ( (padsInRow < 0) || (pad >= padsInRow) ) {
563     AliWarning(Form("Pad index outside range (pad %d) !", pad));
564     return -1.0;
565   }
566
567   //IROC
568   if ( globalpadrow < fNpadrowIROC )
569     return (2.* padsInRow - 4.*pad - 2.)*1.e-1;  //divide by 10 to get cm
570
571   //OROC
572   return (3.* padsInRow -6.*pad - 3.)*1.e-1;  //divide by 10 to get cm
573 }
574 */
575
576 //______________________________________________________________
577 /*
578 Double_t AliTPCmapper::GetPadXglobal(Int_t globalpadrow, Int_t pad, Int_t sector) const
579 {
580   // Get global x coordinate of pad, where globalpadrow is counted for a full sector (0 ... 158)
581
582   if ( globalpadrow >= fNpadrow ) {
583     AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
584     return -1.0;
585   }
586
587   Int_t padsInRow = GetNpads(globalpadrow);
588   if ( (padsInRow < 0) || (pad >= padsInRow) ) {
589     AliWarning(Form("Pad index outside range (pad %d) !", pad));
590     return -1.0;
591   }
592
593   Double_t angle = (Double_t)(( sector * 20. ) + 10. ) * TMath::DegToRad();
594   return GetPadXlocal(globalpadrow) * TMath::Cos(angle) -
595     GetPadYlocal(globalpadrow, pad) * TMath::Sin(angle);
596 }
597 */
598
599 //______________________________________________________________
600 /*
601 Double_t AliTPCmapper::GetPadYglobal(Int_t globalpadrow, Int_t pad,Int_t sector) const
602 {
603   // Get global y coordinate of pad, where globalpadrow is counted for a full sector (0 ... 158)
604
605   if ( globalpadrow >= fNpadrow ) {
606     AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
607     return -1.0;
608   }
609
610   Int_t padsInRow = GetNpads(globalpadrow);
611   if ( (padsInRow < 0) || (pad >= padsInRow) ) {
612     AliWarning(Form("Pad index outside range (pad %d) !", pad));
613     return -1.0;
614   }
615
616   Double_t angle = (Double_t)(( sector * 20. ) + 10. ) * TMath::DegToRad();
617   return GetPadXlocal(globalpadrow) * TMath::Sin(angle) +
618     GetPadYlocal(globalpadrow, pad) * TMath::Cos(angle);
619 }
620 */
621
622 //______________________________________________________________
623 /*
624 Double_t AliTPCmapper::GetPadWidth(Int_t globalpadrow) const
625 {
626   //  Get pad width, where globalpadrow is counted for a full sector (0 ... 158)
627
628   if ( globalpadrow >= fNpadrow ) {
629     AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
630     return -1.0;
631   }
632
633   if (globalpadrow < fNpadrowIROC ) // IROC
634     return 0.4;
635   return 0.6;
636 }
637 */
638
639 //______________________________________________________________
640 /*
641 Double_t AliTPCmapper::GetPadLength(Int_t globalpadrow) const
642 {
643   // Get pad length, where globalpadrow is counted for a full sector (0 ... 158)
644
645   if ( globalpadrow >= fNpadrow ) {
646     AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
647     return -1.0;
648   }
649
650   if ( globalpadrow < fNpadrowIROC ) return  0.75;
651   if ( globalpadrow < 127 )          return 1.0;
652   return 1.5;
653 }
654 */
655
656 //_____________________________________________________________________________
657 Int_t AliTPCmapper::GetNfec(Int_t patch) const
658 {
659   // Get size of readout partition (number of FECs) for this rcu (patch) index (0 ... 5)
660   Int_t retval = 0;
661   switch(patch){
662   case(0):
663     retval = 18;
664     break;
665   case(1):
666     retval = 25;
667     break;
668   case(2):
669     retval = 18;
670     break;
671   case(3):
672     retval = 20;
673     break;
674   case(4):
675     retval = 20;
676     break;
677   case(5):
678     retval = 20;
679     break;
680   };
681   return retval;
682 }
683
684
685 //_____________________________________________________________________________
686 Int_t AliTPCmapper::GetNfec(Int_t patch, Int_t branch) const
687 {
688   // Get size of readout partition (number of FECs) for this branch
689   Int_t retval = 0;
690   switch(patch){
691   case(0):
692     retval = 9;
693     break;
694   case(1):
695     retval = 13;
696     break;
697   case(2):
698     retval = 9;
699     break;
700   case(3):
701     retval = 10;
702     break;
703   case(4):
704     retval = 10;
705     break;
706   case(5):
707     retval = 10;
708     break;
709   };
710   
711   if( (branch == 1) && (patch == 1) ){
712     retval = 12;
713   }
714   return retval;
715 }
716
717
718 //_____________________________________________________________________________
719 Int_t AliTPCmapper::OfflineToHwFec(Int_t patch, Int_t fec) const
720 {
721   // Convert FEC position in offline-like numbering to hardware numbering (fec).
722
723   if ( (patch < 0) || (fec < 0) ) {
724     AliWarning(Form("Patch (%d) or Fec number (%d) outside range !", patch, fec));
725     return -1;
726   }
727   if ( (patch > 5) || (fec >= GetNfec(patch)) ) {
728     AliWarning(Form("Patch (%d) or Fec number (%d) outside range !", patch, fec));
729     return -1;
730   }
731
732   Int_t fecsInBranchA = GetNfec(patch, 0);
733   if ( fec < fecsInBranchA ) // branch A
734     return (fecsInBranchA - 1 - fec);
735   else                       // branch B
736     return (fec - fecsInBranchA);
737
738   return -1;
739 }
740
741
742 //_____________________________________________________________________________
743 Int_t AliTPCmapper::OfflineToHwBranch(Int_t patch, Int_t fec) const
744 {
745   // Convert fec position in offline-like numbering to hardware numbering (branch).
746
747   if ( (patch < 0) || (fec < 0) ) {
748     AliWarning(Form("Patch (%d) or Fec number (%d) outside range !", patch, fec));
749     return -1;
750   }
751   if ( (patch > 5) || (fec >= GetNfec(patch)) ) {
752     AliWarning(Form("Patch (%d) or Fec number (%d) outside range !", patch, fec));
753     return -1;
754   }
755   if ( fec < GetNfec(patch, 0) ) return 0; // branch A
756   else                                         return 1; // branch B
757
758   return -1;
759 }
760
761
762 //_____________________________________________________________________________
763 Int_t AliTPCmapper::HwToOffline(Int_t patch, Int_t branch, Int_t fec) const
764 {
765   // Convert hardware FEC position (branch, fec) to the offline-oriented numbering
766
767   if ( (patch < 0) || (fec < 0) || (branch < 0) ) {
768     AliWarning(Form("Patch (%d), branch (%d) or Fec number (%d) outside range !", patch, branch, fec));
769     return -1;
770   }
771   if ( (patch > 5) || (branch > 1) || (fec >= GetNfec(patch, branch)) ) {
772     AliWarning(Form("Patch (%d), branch (%d) or Fec number (%d) outside range !", patch, branch, fec));
773     return -1;
774   }
775   Int_t fecsInBranchA = GetNfec(patch, 0);
776   if ( branch == 0 )  // branch A
777     return (fecsInBranchA - 1 - fec);
778   else                // branch B
779     return (fec + fecsInBranchA);
780
781   return -1;
782 }
783
784
785 //_____________________________________________________________________________
786 Int_t AliTPCmapper::GetEquipmentID(Int_t roc, Int_t padrow, Int_t pad) const
787 {
788   // Get EqID from pad coordinate. The Roc index is
789   // needed as well to determine if it is IROC or OROC. 
790
791   Int_t side = GetSideFromRoc(roc);
792   if ( side < 0 ) return -1;
793   Int_t sector = GetSectorFromRoc(roc);
794   if ( sector < 0 ) return -1;
795   Int_t patch = GetPatch(roc, padrow, pad);
796   if ( patch < 0 ) return -1;
797   return GetEquipmentIDfromPatch(side, sector, patch);
798 }
799
800
801 //_____________________________________________________________________________
802 Int_t AliTPCmapper::GetEquipmentIDsector(Int_t side, Int_t sector, Int_t globalpadrow, Int_t pad) const
803 {
804   // Get EqID from pad coordinate, where padrow is counted for a full sector (0 ... 158)
805   Int_t patch = GetPatchSector(globalpadrow, pad);
806   if ( patch < 0 ) return -1;
807   Int_t roc = GetRocFromPatch(side, sector, patch);
808   if ( roc < 0 ) return -1;
809
810   if ( globalpadrow < fNpadrowIROC )
811     return GetEquipmentID(roc, globalpadrow, pad);
812   else
813     return GetEquipmentID(roc, globalpadrow-fNpadrowIROC, pad);
814 }
815
816
817 //_____________________________________________________________________________
818 Int_t AliTPCmapper::GetEquipmentIDfromPatch(Int_t side, Int_t sector, Int_t patch) const
819 {
820   // Get EqID from patch (rcu).
821
822   Int_t roc = GetRocFromPatch(side, sector, patch);
823   Int_t ddl = 0;
824   if (patch < 2)  // IROC
825     ddl = roc*2 + patch;
826   else            // OROC
827     ddl = (roc-36)*4 + 36*2 + (patch-2);
828   // Add offset. TPC has detectorID = 3
829   return ddl+fTpcDdlOffset;
830 }
831
832
833 //_____________________________________________________________________________
834 Int_t AliTPCmapper::GetPatchFromEquipmentID(Int_t equipmentID) const
835 {
836   // Get rcu (patch) index (0 ... 5) from equipment ID
837   Int_t retval = 0;
838
839   if ( (equipmentID < fTpcDdlOffset) || (equipmentID > 983) ) {
840     AliWarning(Form("Equipment ID (%d) outside range !", equipmentID));
841     return -1;
842   }
843   if ( ( (int)equipmentID - 840 ) < 0) retval = (equipmentID-768)%2;
844   else                                 retval = (equipmentID-840)%4 + 2;
845   return retval;
846 }
847
848
849 //_____________________________________________________________________________
850 Int_t AliTPCmapper::GetSideFromEquipmentID(Int_t equipmentID) const
851 {
852   // Get side from Eq ID
853   if ( equipmentID < fTpcDdlOffset ) {
854     AliWarning(Form("Equipment ID (%d) outside range !", equipmentID));
855     return -1;
856   }
857   if      ( equipmentID < 804 ) return 0;
858   else if ( equipmentID < 840 ) return 1;
859   else if ( equipmentID < 912 ) return 0;
860   else if ( equipmentID < 984 ) return 1;
861   else {
862     AliWarning(Form("Equipment ID (%d) outside range !", equipmentID));
863     return -1;
864   }
865 }
866
867
868 //_____________________________________________________________________________
869 Int_t AliTPCmapper::GetSectorFromEquipmentID(Int_t equipmentID) const
870 {
871   // Get sector index (0 ... 17) from equipment ID
872   Int_t retval = 0;
873
874   if ( (equipmentID < fTpcDdlOffset) || (equipmentID > 983) ) {
875     AliWarning(Form("Equipment ID (%d) outside range !", equipmentID));
876     return -1;
877   }
878   if ( (equipmentID - 840) < 0 ) retval = (equipmentID-768)/2;
879   else                           retval = (equipmentID-840)/4;
880   return retval;
881 }
882
883
884 //_____________________________________________________________________________
885 Int_t AliTPCmapper::GetRocFromEquipmentID(Int_t equipmentID) const
886 {
887   // Get ROC index (0 ... 71) from equipment ID
888   Int_t side   = GetSideFromEquipmentID(equipmentID);
889   if ( side < 0 ) return -1;
890   Int_t sector = GetSectorFromEquipmentID(equipmentID);
891   if ( sector < 0 ) return -1;
892   Int_t patch  = GetPatchFromEquipmentID(equipmentID);
893   if ( patch < 0 ) return -1;
894
895   return GetRocFromPatch(side, sector, patch);
896 }
897
898
899 //_____________________________________________________________________________
900 Int_t AliTPCmapper::GetSectorFromRoc(Int_t roc) const
901 {
902   // get the sector number (0 ... 17) from the roc number (0 ... 71)
903
904   if ( roc < 0 ) {
905     AliWarning(Form("Roc outside range (roc %d) !", roc));
906     return -1;
907   } else if ( roc < 18 ) {   // inner sector, A side
908     return roc;
909   } else if ( roc < 36 ) {   // inner sector, C side
910     return (roc-18);
911   } else if ( roc < 54 ) {   // outer sector, A side
912     return (roc-36);
913   } else if ( roc < 72 ) {   // outer sector, C side
914     return (roc-54);
915   } else {
916     AliWarning(Form("Roc outside range (roc %d) !", roc));
917     return -1;
918   }
919 }
920
921
922 //_____________________________________________________________________________
923 Int_t AliTPCmapper::GetSideFromRoc(Int_t roc) const
924 {
925   // get the side (0, 1) from the roc number (0 ... 71)
926
927   if ( roc < 0 ) {
928     AliWarning(Form("Roc outside range (roc %d) !", roc));
929     return -1;
930   } else if ( roc < 18 ) {   // inner sector, A side
931     return 0;
932   } else if ( roc < 36 ) {   // inner sector, C side
933     return 1;
934   } else if ( roc < 54 ) {   // outer sector, A side
935     return 0;
936   } else if ( roc < 72 ) {   // outer sector, C side
937     return 1;
938   } else { 
939     AliWarning(Form("Roc outside range (roc %d) !", roc));
940     return -1;
941   } 
942 }
943
944
945 //_____________________________________________________________________________
946 Int_t AliTPCmapper::GetRocFromPatch(Int_t side, Int_t sector, Int_t patch) const
947 {
948   // Get Roc (0 ... 71) from side (0, 1), sector (0 ... 17) and patch (0 ... 5)
949
950   if ( (side < 0) || (side >= fNside) ) {
951     AliWarning(Form("Side outside range (side %d) !", side));
952     return -1;
953   }
954   if ( (sector < 0) || (sector >= fNsector) ) {
955     AliWarning(Form("Sector outside range (sector %d) !", sector));
956     return -1;
957   }
958   if ( (patch < 0) || (patch >= fNrcu) ) {
959     AliWarning(Form("Patch (rcu) outside range (patch %d) !", patch));
960     return -1;
961   }
962
963   if ( side == 0 ) { // A side
964     if ( patch < 2 ) return sector;         // IROC
965     else             return 36+sector;      // OROC
966   } else {           // C side
967     if ( patch < 2 ) return 18+(17-sector); // IROC
968     else             return 54+(17-sector); // OROC
969   }
970 }
971
972
973 //_____________________________________________________________________________
974 Int_t AliTPCmapper::GetRoc(Int_t side, Int_t sector, Int_t globalpadrow, Int_t pad) const
975 {
976   // Get Roc (0 ... 71) from side (0, 1), sector (0 ... 17) and pad coordinates
977
978   Int_t patch = GetPatchSector(globalpadrow, pad);
979   if ( patch < 0 ) return -1;
980   return GetRocFromPatch(side, sector, patch);
981 }
982
983
984 //_____________________________________________________________________________
985   Bool_t AliTPCmapper::IsIROC(Int_t roc) const
986 {
987   // Is this ROC an IROC?
988   if ( roc < 0 ) {
989     AliWarning(Form("Roc outside range (roc %d) !", roc));
990     return -1;
991   } else if ( roc < 36 ) {   // inner sector
992     return true;
993   } else if ( roc < 72 ) {   // outer sector, C side
994     return false;
995   } else {
996     AliWarning(Form("Roc outside range (roc %d) !", roc));
997     return -1;
998   }
999 }
1000
1001
1002 //_____________________________________________________________________________
1003   Bool_t AliTPCmapper::IsOROC(Int_t roc) const
1004 {
1005   // Is this ROC an OROC?
1006   if ( roc < 0 ) {
1007     AliWarning(Form("Roc outside range (roc %d) !", roc));
1008     return -1;
1009   } else if ( roc < 36 ) {   // inner sector
1010     return false;
1011   } else if ( roc < 72 ) {   // outer sector, C side
1012     return true;
1013   } else {
1014     AliWarning(Form("Roc outside range (roc %d) !", roc));
1015     return -1;
1016   }
1017 }
1018
1019 // EOF