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