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