]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDAltroMapping.cxx
SDD QA updated in order to deal with acquisition through HLT (M. Siciliano)
[u/mrichter/AliRoot.git] / FMD / AliFMDAltroMapping.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 /* $Id$ */
16 /** @file    AliFMDAltroMapping.cxx
17     @author  Christian Holm Christensen <cholm@nbi.dk>
18     @date    Sun Mar 26 18:27:56 2006
19     @brief   Map HW to detector 
20 */
21 //____________________________________________________________________
22 //                                                                          
23 // Mapping of ALTRO hardware channel to detector coordinates 
24 //
25 // The hardware address consist of a DDL number and 12bits of ALTRO
26 // addresses.  The ALTRO address are formatted as follows. 
27 //
28 //    12              7         4            0
29 //    |---------------|---------|------------|
30 //    | Board #       | ALTRO # | Channel #  |
31 //    +---------------+---------+------------+
32 //
33 // The mapping is done purely by calculations.  In the future,
34 // however, we may need some hard-coded stuff, or an external file to
35 // read from.  
36 //
37 #include "AliFMDAltroMapping.h"         // ALIFMDALTROMAPPING_H
38 #include "AliFMDParameters.h"
39 #include "AliLog.h"
40 #include <iostream>
41 #include <iomanip>
42
43 //____________________________________________________________________
44 ClassImp(AliFMDAltroMapping)
45 #if 0
46   ; // This is here to keep Emacs for indenting the next line
47 #endif
48
49 //_____________________________________________________________________________
50 AliFMDAltroMapping::AliFMDAltroMapping()
51 {
52   // Constructor 
53 }
54
55
56 //_____________________________________________________________________________
57 Bool_t
58 AliFMDAltroMapping::ReadMapping()
59 {
60   // Read map from file - not used
61   return kTRUE;
62 }
63
64 //_____________________________________________________________________________
65 Bool_t
66 AliFMDAltroMapping::CreateInvMapping()
67 {
68   // Create inverse mapping - not used
69   return kTRUE;
70 }
71
72 //____________________________________________________________________
73 Bool_t 
74 AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl, UInt_t    addr, 
75                                       UShort_t& det, Char_t&   ring, 
76                                       UShort_t& sec, Short_t&  str) const
77 {
78   // Translate a hardware address to detector coordinates. 
79   // 
80   // See also Hardware2Detector that accepts 4 inputs 
81   UInt_t board =  (addr >> 7) & 0x1F;
82   UInt_t altro =  (addr >> 4) & 0x7;
83   UInt_t chan  =  (addr & 0xf);
84   return Hardware2Detector(ddl, board, altro, chan, det, ring, sec, str);
85 }
86
87 //____________________________________________________________________
88 Bool_t 
89 AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl,   UInt_t    board, 
90                                       UInt_t    altro, UInt_t    chan,
91                                       UShort_t& det,   Char_t&   ring, 
92                                       UShort_t& sec,   Short_t&  str) const
93 {
94   // Translate a hardware address to detector coordinates. 
95   // The detector is simply 
96   // 
97   //    ddl + 1
98   // 
99   // The ring number, sector, and strip number is given by the addr
100   // argument.  The address argument, has the following format 
101   // 
102   //   12            7          4          0
103   //   +-------------+----------+----------+
104   //   | Board       | ALTRO    | Channel  |
105   //   +-------------+----------+----------+
106   // 
107   // The board number identifier among other things the ring.  There's
108   // up to 4 boards per DDL, and the two first (0 and 16) corresponds
109   // to the inner rings, while the two last (1 and 17) corresponds to
110   // the outer rings. 
111   // 
112   // The board number and ALTRO number together identifies the sensor,
113   // and hence.  The lower board number (0 or 16) are the first N / 2
114   // sensors (where N is the number of sensors in the ring).  
115   // 
116   // There are 3 ALTRO's per card, and each ALTRO serves up to 4
117   // sensors.  Which of sensor is determined by the channel number.
118   // For the inner rings, the map is
119   // 
120   //    ALTRO 0, Channel  0 to  7   -> Sensor 0 or 5
121   //    ALTRO 0, Channel  8 to 15   -> Sensor 1 or 6
122   //    ALTRO 1, Channel  0 to  7   -> Sensor 2 or 7 
123   //    ALTRO 2, Channel  0 to  7   -> Sensor 3 or 8
124   //    ALTRO 2, Channel  8 to 15   -> Sensor 4 or 9
125   // 
126   // For the outer rings, the map is 
127   // 
128   //    ALTRO 0, Channel  0 to  3   -> Sensor 0 or 10
129   //    ALTRO 0, Channel  4 to  7   -> Sensor 1 or 11
130   //    ALTRO 0, Channel  8 to 11   -> Sensor 2 or 12
131   //    ALTRO 0, Channel 12 to 15   -> Sensor 3 or 13
132   //    ALTRO 1, Channel  0 to  3   -> Sensor 4 or 14
133   //    ALTRO 1, Channel  4 to  7   -> Sensor 5 or 15
134   //    ALTRO 2, Channel  0 to  3   -> Sensor 6 or 16
135   //    ALTRO 2, Channel  4 to  7   -> Sensor 7 or 17
136   //    ALTRO 2, Channel  8 to 11   -> Sensor 8 or 18
137   //    ALTRO 2, Channel 12 to 15   -> Sensor 9 or 19
138   // 
139   // Which divison of the sensor we're in, depends on the channel
140   // number only.  For the inner rings, the map is 
141   // 
142   //    Channel 0                   -> Sector 0, strips   0-127
143   //    Channel 1                   -> Sector 1, strips 127-0
144   //    Channel 3                   -> Sector 0, strips 128-255
145   //    Channel 4                   -> Sector 1, strips 255-128
146   //    Channel 5                   -> Sector 0, strips 256-383
147   //    Channel 6                   -> Sector 1, strips 383-256
148   //    Channel 7                   -> Sector 0, strips 384-511
149   //    Channel 8                   -> Sector 1, strips 511-384
150   // 
151   // There are only half as many strips in the outer sensors, so there
152   // only 4 channels are used for a full sensor.  The map is 
153   // 
154   //    Channel 0                   -> Sector 0, strips   0-127
155   //    Channel 1                   -> Sector 1, strips 127-0
156   //    Channel 3                   -> Sector 0, strips 128-255
157   //    Channel 4                   -> Sector 1, strips 255-128
158   // 
159   // With this information, we can decode the hardware address to give
160   // us detector coordinates, unique at least up a 128 strips.  We
161   // return the first strip, as seen by the ALTRO channel, in the
162   // given range.  
163   //
164   det          =  ddl + 1;
165   ring         =  (board % 2) == 0 ? 'I' : 'O';
166   switch (ring) {
167   case 'i':
168   case 'I':
169     sec = ((board / 16) * 10 + (altro < 1 ? 0 : altro < 2 ? 4 : 6) 
170            + 2 * (chan / 8) + chan % 2);
171     str = ((chan % 8) / 2) * 128;
172     break;
173   case 'o':
174   case 'O': 
175     sec = ((board / 16) * 20 + (altro < 1 ? 0 : altro < 2 ? 8 : 12) 
176            + 2 * (chan / 4) + chan % 2);
177     str = ((chan % 4) / 2) * 128;
178     break;
179   }
180   if (sec % 2) str += 127;
181   return kTRUE;
182 }
183
184 //____________________________________________________________________
185 Bool_t 
186 AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl,       UInt_t   addr,
187                                       UShort_t  timebin,   UShort_t preSamples, 
188                                       UShort_t  sampleRate,
189                                       UShort_t& det,       Char_t&   ring, 
190                                       UShort_t& sec,       Short_t&  str,
191                                       UShort_t& sam) const
192 {
193   // Translate a hardware address to detector coordinates. 
194   // 
195   // See also Hardware2Detector that accepts 4 inputs 
196   UInt_t board =  (addr >> 7) & 0x1F;
197   UInt_t altro =  (addr >> 4) & 0x7;
198   UInt_t chan  =  (addr & 0xf);
199   return Hardware2Detector(ddl, board, altro, chan, 
200                            timebin, preSamples, sampleRate, 
201                            det, ring, sec, str, sam);
202 }
203
204 //____________________________________________________________________
205 Bool_t 
206 AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl,     UInt_t    board, 
207                                       UInt_t    altro,   UInt_t    chan,
208                                       UInt_t    timebin, UInt_t    preSamples,
209                                       UInt_t    sampleRate,
210                                       UShort_t& det,     Char_t&   ring, 
211                                       UShort_t& sec,     Short_t&  str,
212                                       UShort_t& sam) const
213 {
214   // Full conversion from hardware address, including timebin number,
215   // to detector coordinates and sample number.  Note, that this
216   // conversion depends on the oversampling rate and the number of
217   // pre-samples 
218   if (!Hardware2Detector(ddl, board, altro, chan, det, ring, sec, str))
219     return kFALSE;
220   UShort_t t =  (timebin - preSamples);
221   sam        =  (t % sampleRate);
222   t          -= sam;
223   str        += (sec % 2 ? -1 : 1) * t / sampleRate;
224   // if (sec % 2) sam = sampleRate - 1 - sam;
225 #if 0
226   AliFMDDebug(3, ("%d/0x%02x/0x%x/0x%x/%04d -> FMD%d%c[%02d,%03d]-%d"
227                   " (pre=%2d, rate=%d)", 
228                   ddl, board, altro, chan, timebin, 
229                   det, ring, sec, str, sam, preSamples, sampleRate));
230 #endif
231   return kTRUE;
232 }
233
234
235 //____________________________________________________________________
236 Bool_t 
237 AliFMDAltroMapping::Detector2Hardware(UShort_t  det,   Char_t    ring, 
238                                       UShort_t  sec,   UShort_t  str,
239                                       UInt_t&   ddl,   UInt_t&   board,
240                                       UInt_t&   altro, UInt_t&   chan) const
241 {
242   // Translate detector coordinates to a hardware address.
243   // The ddl is simply 
244   // 
245   //    (det - 1)
246   // 
247   // The ring number, sector, and strip number must be encoded into a
248   // hardware address.  The address argument, will have the following
249   // format on output
250   // 
251   //   12            7          4          0
252   //   +-------------+----------+----------+
253   //   | Board       | ALTRO    | Channel  |
254   //   +-------------+----------+----------+
255   // 
256   // The board number is given by the ring and sector.  The inner
257   // rings board 0 and 16, while the outer are 1 and 17.  Which of these
258   // depends on the sector.  The map is 
259   // 
260   //    Ring I, sector  0- 9       ->   board 0 
261   //    Ring I, sector 10-19       ->   board 16
262   //    Ring O, sector  0-19       ->   board 1 
263   //    Ring O, sector 20-39       ->   board 17
264   // 
265   // There are 3 ALTRO's per board.  The ALTRO number is given by the
266   // sector number.  For the inner rings, these are given by
267   // 
268   //    Sector  0- 3  or  10-13    ->   ALTRO 0 
269   //    Sector  4- 5  or  14-15    ->   ALTRO 1 
270   //    Sector  6- 9  or  16-19    ->   ALTRO 2 
271   // 
272   // For the outers, it's given by 
273   // 
274   //    Sector  0- 7  or  20-27    ->   ALTRO 0 
275   //    Sector  8-11  or  28-31    ->   ALTRO 1 
276   //    Sector 12-19  or  32-39    ->   ALTRO 2 
277   //
278   // The channel number is given by the sector and strip number.  For
279   // the inners, the map is 
280   // 
281   //    Sector  0, strips   0-127  ->   Channel  0
282   //    Sector  0, strips 128-255  ->   Channel  2
283   //    Sector  0, strips 256-383  ->   Channel  4
284   //    Sector  0, strips 384-511  ->   Channel  6
285   //    Sector  1, strips 127-  0  ->   Channel  1
286   //    Sector  1, strips 255-128  ->   Channel  3
287   //    Sector  1, strips 383-256  ->   Channel  5
288   //    Sector  1, strips 511-384  ->   Channel  7
289   //    Sector  2, strips   0-127  ->   Channel  8
290   //    Sector  2, strips 128-255  ->   Channel 10
291   //    Sector  2, strips 256-383  ->   Channel 12
292   //    Sector  2, strips 384-511  ->   Channel 14
293   //    Sector  3, strips 127-  0  ->   Channel  9
294   //    Sector  3, strips 255-128  ->   Channel 11
295   //    Sector  3, strips 383-256  ->   Channel 13
296   //    Sector  3, strips 511-384  ->   Channel 15
297   // 
298   // and so on, up to sector 19.  For the outer, the map is 
299   // 
300   //    Sector  0, strips   0-127  ->   Channel  0
301   //    Sector  0, strips 128-255  ->   Channel  2
302   //    Sector  1, strips 127-  0  ->   Channel  1
303   //    Sector  1, strips 255-128  ->   Channel  3
304   //    Sector  2, strips   0-127  ->   Channel  4
305   //    Sector  2, strips 128-255  ->   Channel  6
306   //    Sector  3, strips 127-  0  ->   Channel  5
307   //    Sector  3, strips 255-128  ->   Channel  7
308   //    Sector  4, strips   0-127  ->   Channel  8
309   //    Sector  4, strips 128-255  ->   Channel 10
310   //    Sector  5, strips 127-  0  ->   Channel  9
311   //    Sector  5, strips 255-128  ->   Channel 11
312   //    Sector  6, strips   0-127  ->   Channel 12
313   //    Sector  6, strips 128-255  ->   Channel 14
314   //    Sector  7, strips 127-  0  ->   Channel 13
315   //    Sector  7, strips 255-128  ->   Channel 15
316   // 
317   // and so on upto sector 40. 
318   // 
319   // With this information, we can decode the detector coordinates to
320   // give us a unique hardware address 
321   //
322   ddl          =  (det - 1);
323   UInt_t tmp   = 0;
324   switch (ring) {
325   case 'I':
326   case 'i':
327     board =  (sec / 10) * 16;
328     altro =  (sec % 10) < 4 ? 0 : (sec % 10) < 6 ? 1 : 2;
329     tmp   =  (sec % 10) - (altro == 0 ? 0 : altro == 1 ? 4 : 6);
330     chan  =  2  * (str / 128) + (sec % 2) + ((tmp / 2) % 2) * 8;
331     break;
332   case 'O':
333   case 'o':
334     board =  (sec / 20) * 16 + 1;
335     altro =  (sec % 20) < 8 ? 0 : (sec % 20) < 12 ? 1 : 2;
336     tmp   =  (sec % 20) - (altro == 0 ? 0 : altro == 1 ? 8 : 12);
337     chan  =  2 * (str / 128) + (sec % 2) + ((tmp / 2) % 4) * 4;
338     break;
339   }
340   return kTRUE;
341 }
342
343 //____________________________________________________________________
344 Bool_t 
345 AliFMDAltroMapping::Detector2Hardware(UShort_t  det, Char_t    ring, 
346                                       UShort_t  sec, UShort_t  str,
347                                       UInt_t&   ddl, UInt_t&   addr) const
348 {
349   // Translate detector coordinates to a hardware address.  
350   // 
351   // See also Detector2Hardware that returns 4 parameters.  
352   UInt_t board = 0;
353   UInt_t altro = 0;
354   UInt_t chan  = 0;
355   if (!Detector2Hardware(det,ring,sec,str,ddl,board,altro,chan)) return kFALSE;
356   addr =  chan + (altro << 4) + (board << 7);
357   return kTRUE;
358 }
359
360 //____________________________________________________________________
361 Bool_t 
362 AliFMDAltroMapping::Detector2Hardware(UShort_t  det,        Char_t    ring, 
363                                       UShort_t  sec,        UShort_t  str,
364                                       UShort_t  sam, 
365                                       UShort_t  preSamples, UShort_t sampleRate,
366                                       UInt_t&   ddl,        UInt_t&   board, 
367                                       UInt_t&   altro,      UInt_t&   channel, 
368                                       UShort_t& timebin) const
369 {
370   if (!Detector2Hardware(det,ring,sec,str,ddl,board,altro,channel)) 
371     return kFALSE;
372   timebin = preSamples;
373   if (sec % 2) 
374     timebin += (127 - (str % 128)) * sampleRate;
375   else 
376     timebin += (str % 128) * sampleRate;
377   timebin += sam;
378   return kTRUE;
379 }
380
381
382 //____________________________________________________________________
383 Bool_t 
384 AliFMDAltroMapping::Detector2Hardware(UShort_t  det,        Char_t   ring, 
385                                       UShort_t  sec,        UShort_t str,
386                                       UShort_t  sam, 
387                                       UShort_t  preSamples, UShort_t sampleRate,
388                                       UInt_t&   ddl,        UInt_t&  hwaddr, 
389                                       UShort_t& timebin) const
390 {
391   UInt_t board = 0;
392   UInt_t altro = 0;
393   UInt_t chan  = 0;
394   if (!Detector2Hardware(det, ring, sec, str, sam, 
395                          preSamples, sampleRate, 
396                          ddl, board, altro, chan, timebin)) return kFALSE;
397   hwaddr =  chan + (altro << 4) + (board << 7);
398   return kTRUE;
399 }
400
401       
402
403 //____________________________________________________________________
404 Int_t
405 AliFMDAltroMapping::GetHWAddress(Int_t sec, Int_t str, Int_t ring)
406 {
407   // Return hardware address corresponding to sector sec, strip str,
408   // and ring ring.   Mapping from TPC to FMD coordinates are 
409   // 
410   //   TPC     | FMD
411   //   --------+------
412   //   padrow  | sector
413   //   pad     | strip
414   //   sector  | ring 
415   //
416   UInt_t ddl, hwaddr;
417   Char_t r = Char_t(ring);
418   if (!Detector2Hardware(1, r, sec, str, ddl, hwaddr)) 
419     return -1;
420   return hwaddr;
421 }
422
423 //____________________________________________________________________
424 Int_t
425 AliFMDAltroMapping::GetPadRow(Int_t hwaddr) const
426 {
427   // Return sector corresponding to hardware address hwaddr.  Mapping
428   // from TPC to FMD coordinates are  
429   // 
430   //   TPC     | FMD
431   //   --------+------
432   //   padrow  | sector
433   //   pad     | strip
434   //   sector  | ring 
435   //
436   UShort_t det;
437   Char_t   ring;
438   UShort_t sec;
439   Short_t  str;
440   Int_t    ddl = 0;
441   if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1;
442   return Int_t(sec);
443 }
444
445 //____________________________________________________________________
446 Int_t
447 AliFMDAltroMapping::GetPad(Int_t hwaddr) const
448 {
449   // Return strip corresponding to hardware address hwaddr.  Mapping
450   // from TPC to FMD coordinates are  
451   // 
452   //   TPC     | FMD
453   //   --------+------
454   //   padrow  | sector
455   //   pad     | strip
456   //   sector  | ring 
457   //
458   UShort_t det;
459   Char_t   ring;
460   UShort_t sec;
461   Short_t  str;
462   Int_t    ddl = 0;
463   if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1;
464   return Int_t(str);
465 }
466   
467 //____________________________________________________________________
468 Int_t
469 AliFMDAltroMapping::GetSector(Int_t hwaddr) const
470 {
471   // Return ring corresponding to hardware address hwaddr.  Mapping
472   // from TPC to FMD coordinates are  
473   // 
474   //   TPC     | FMD
475   //   --------+------
476   //   padrow  | sector
477   //   pad     | strip
478   //   sector  | ring 
479   //
480   UShort_t det;
481   Char_t   ring;
482   UShort_t sec;
483   Short_t  str;
484   Int_t    ddl = 0;
485   if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1;
486   return Int_t(ring);
487 }
488
489 //____________________________________________________________________
490 void
491 AliFMDAltroMapping::Print(Option_t* option) const
492 {
493   TString opt(option);
494   opt.ToLower();
495   UInt_t ddl, board, chip, chan, addr;
496   UShort_t det, sec;
497   Short_t str;
498   Char_t   rng;
499   
500   if (opt.Contains("hw") || opt.Contains("hardware")) { 
501     std::cout << " DDL | Board | Chip | Chan | Address | Detector\n"
502               << "=====+=======+======+======+=========+===============" 
503               << std::endl;
504     for (ddl = 0; ddl <= 2; ddl++) { 
505       Int_t  boards[] = { 0, 16, (ddl == 0 ? 32 : 1), 17, 32};
506       Int_t* ptr      = boards;
507       while ((board = *(ptr++)) < 32) { 
508         for (chip = 0; chip <= 2; chip++) { 
509           UInt_t nchan = (chip == 1 ? 8 : 16);
510           for (chan = 0; chan < nchan; chan++) { 
511             Hardware2Detector(ddl, board, chip, chan, det, rng, sec, str);
512             addr = ((board & 0x1f) << 7) | ((chip & 0x7) << 4) | (chan & 0xf);
513             std::cout << " "  
514                       << std::setw(3) << ddl   << " | " 
515                       << std::setfill('0')     << std::hex << " 0x"
516                       << std::setw(2) << board << " |  0x"
517                       << std::setw(1) << chip  << " |  0x"
518                       << std::setw(1) << chan  << " |   0x" 
519                       << std::setw(3) << addr  << " | " 
520                       << std::setfill(' ')     << std::dec << " FMD" 
521                       << std::setw(1) << det << rng << "[" 
522                       << std::setw(2) << sec << "," << std::setw(3) << str
523                       << "]" << std::endl;
524           } // for chan ...
525           if (chip == 2 && *ptr >= 32) continue;
526           std::cout << "     +       +      +      +         +              " 
527                     << std::endl;
528         } // for chip ... 
529       } // while board 
530       std::cout << "-----+-------+------+------+---------+---------------" 
531                 << std::endl;
532     } // for ddl ... 
533   } // if hw 
534   if (opt.Contains("det")) { 
535     std::cout << " Detector      | DDL | Board | Chip | Chan | Address\n"
536               << "===============+=====+=======+======+======+========"
537               << std::endl;
538     for (det = 1; det <= 3; det++) { 
539       Char_t  rings[] = { 'I', (det == 1 ? '\0' : 'O'),'\0' };
540       Char_t* ptr     = rings;
541       while ((rng = *(ptr++)) != '\0') { 
542         UShort_t nsec = (rng == 'I' ?  20 :  40);
543         UShort_t nstr = (rng == 'I' ? 512 : 256);
544         for (sec = 0; sec < nsec; sec++) { 
545           for (str = 0; str < nstr; str += 128) {
546             ddl = board = chip = chan;
547             Detector2Hardware(det,rng,sec,str,ddl,board,chip,chan);
548             addr = ((board & 0x1f) << 7) | ((chip & 0x7) << 4) | (chan & 0xf);
549             std::cout << std::setfill(' ')     << std::dec << " FMD" 
550                       << std::setw(1) << det   << rng      << "[" 
551                       << std::setw(2) << sec   << "," 
552                       << std::setw(3) << str   << "] | " 
553                       << std::setw(3) << ddl   << " |  0x"
554                       << std::setfill('0')     << std::hex  
555                       << std::setw(2) << board << " |  0x"
556                       << std::setw(1) << chip  << " |  0x"
557                       << std::setw(1) << chan  << " |   0x" 
558                       << std::setw(3) << addr  << std::endl;
559           } // for str ...
560         } // for sec ... 
561         if (*ptr == '\0') continue;
562         std::cout << "               +     +       +      +      +        " 
563                   << std::endl;
564       } // while rng ... 
565       std::cout << "---------------+-----+-------+------+------+--------" 
566                 << std::endl;
567
568     } // for det ... 
569   } // if det 
570 }
571
572 //_____________________________________________________________________________
573 //
574 // EOF
575 //