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