removing printouts from previous checkins
[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 "AliFMDDebug.h"
41 #include <iostream>
42 #include <iomanip>
43
44 //____________________________________________________________________
45 ClassImp(AliFMDAltroMapping)
46 #if 0
47   ; // This is here to keep Emacs for indenting the next line
48 #endif
49
50 //_____________________________________________________________________________
51 AliFMDAltroMapping::AliFMDAltroMapping()
52 {
53   // Constructor 
54 }
55
56
57 //_____________________________________________________________________________
58 Bool_t
59 AliFMDAltroMapping::ReadMapping()
60 {
61   // Read map from file - not used
62   return kTRUE;
63 }
64
65 //_____________________________________________________________________________
66 Bool_t
67 AliFMDAltroMapping::CreateInvMapping()
68 {
69   // Create inverse mapping - not used
70   return kTRUE;
71 }
72
73
74 //____________________________________________________________________
75 Bool_t 
76 AliFMDAltroMapping::Channel2StripBase(UShort_t  board, UShort_t  altro, 
77                                       UShort_t  chan,  Char_t&   ring, 
78                                       UShort_t& sec,   Short_t&  str) const
79 {
80   // Translate a hardware address to detector coordinates. 
81   // The detector is simply 
82   // 
83   //    ddl + 1
84   // 
85   // The ring number, sector, and strip number is given by the addr
86   // argument.  The address argument, has the following format 
87   // 
88   //   12            7          4          0
89   //   +-------------+----------+----------+
90   //   | Board       | ALTRO    | Channel  |
91   //   +-------------+----------+----------+
92   // 
93   // The board number identifier among other things the ring.  There's
94   // up to 4 boards per DDL, and the two first (0 and 16) corresponds
95   // to the inner rings, while the two last (1 and 17) corresponds to
96   // the outer rings. 
97   // 
98   // The board number and ALTRO number together identifies the sensor,
99   // and hence.  The lower board number (0 or 16) are the first N / 2
100   // sensors (where N is the number of sensors in the ring).  
101   // 
102   // There are 3 ALTRO's per card, and each ALTRO serves up to 4
103   // sensors.  Which of sensor is determined by the channel number.
104   // For the inner rings, the map is
105   // 
106   //    ALTRO 0, Channel  0 to  7   -> Sensor 0 or 5
107   //    ALTRO 0, Channel  8 to 15   -> Sensor 1 or 6
108   //    ALTRO 1, Channel  0 to  7   -> Sensor 2 or 7 
109   //    ALTRO 2, Channel  0 to  7   -> Sensor 3 or 8
110   //    ALTRO 2, Channel  8 to 15   -> Sensor 4 or 9
111   // 
112   // For the outer rings, the map is 
113   // 
114   //    ALTRO 0, Channel  0 to  3   -> Sensor 0 or 10
115   //    ALTRO 0, Channel  4 to  7   -> Sensor 1 or 11
116   //    ALTRO 0, Channel  8 to 11   -> Sensor 2 or 12
117   //    ALTRO 0, Channel 12 to 15   -> Sensor 3 or 13
118   //    ALTRO 1, Channel  0 to  3   -> Sensor 4 or 14
119   //    ALTRO 1, Channel  4 to  7   -> Sensor 5 or 15
120   //    ALTRO 2, Channel  0 to  3   -> Sensor 6 or 16
121   //    ALTRO 2, Channel  4 to  7   -> Sensor 7 or 17
122   //    ALTRO 2, Channel  8 to 11   -> Sensor 8 or 18
123   //    ALTRO 2, Channel 12 to 15   -> Sensor 9 or 19
124   // 
125   // Which divison of the sensor we're in, depends on the channel
126   // number only.  For the inner rings, the map is 
127   // 
128   //    Channel 0                   -> Sector 0, strips   0-127
129   //    Channel 1                   -> Sector 1, strips 127-0
130   //    Channel 3                   -> Sector 0, strips 128-255
131   //    Channel 4                   -> Sector 1, strips 255-128
132   //    Channel 5                   -> Sector 0, strips 256-383
133   //    Channel 6                   -> Sector 1, strips 383-256
134   //    Channel 7                   -> Sector 0, strips 384-511
135   //    Channel 8                   -> Sector 1, strips 511-384
136   // 
137   // There are only half as many strips in the outer sensors, so there
138   // only 4 channels are used for a full sensor.  The map is 
139   // 
140   //    Channel 0                   -> Sector 0, strips   0-127
141   //    Channel 1                   -> Sector 1, strips 127-0
142   //    Channel 3                   -> Sector 0, strips 128-255
143   //    Channel 4                   -> Sector 1, strips 255-128
144   // 
145   // With this information, we can decode the hardware address to give
146   // us detector coordinates, unique at least up a 128 strips.  We
147   // return the first strip, as seen by the ALTRO channel, in the
148   // given range.  
149   //
150   ring          =  Board2Ring(board);
151   UShort_t fsec =  board < 16 ? 1 : 0;
152   switch (ring) {
153   case 'i':
154   case 'I':
155     sec = (fsec * 10 + (altro < 1 ? 0 : altro < 2 ? 4 : 6) 
156            + 2 * (chan / 8) + chan % 2);
157     str = ((chan % 8) / 2) * 128;
158     break;
159   case 'o':
160   case 'O': 
161     sec = (fsec * 20 + (altro < 1 ? 0 : altro < 2 ? 8 : 12) 
162            + 2 * (chan / 4) + chan % 2);
163     str = ((chan % 4) / 2) * 128;
164     break;
165   }
166   if (sec % 2) str += 127;
167   // AliFMDDebug(1, ("%02x/%x/%x Base strip = %d", board, altro, chan, str));
168   return kTRUE;
169 }
170
171 //____________________________________________________________________
172 void
173 AliFMDAltroMapping::Timebin2Strip(UShort_t  sec,         
174                                   UShort_t  timebin,
175                                   UShort_t  preSamples, 
176                                   UShort_t  sampleRate, 
177                                   Short_t&  stripOff,      
178                                   UShort_t& sample) const
179 {
180   // Compute the strip off-set in the current channel from the sector
181   // and timebin.   Also needed for this computation is the basic
182   // offset in timebins, as well as the sample rat. 
183   UShort_t t =  (timebin - preSamples);
184   sample     =  (t % sampleRate);
185   t          -= sample;
186   stripOff   =  (sec % 2 ? -1 : 1) * t / sampleRate;
187 }
188
189 #if 0
190 //____________________________________________________________________
191 Bool_t 
192 AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl,   UInt_t    board, 
193                                       UInt_t    altro, UInt_t    chan,
194                                       UShort_t& det,   Char_t&   ring, 
195                                       UShort_t& sec,   Short_t&  str) const
196 {
197   // See also Hardware2Detector that requires 3 inputs 
198   det = DDL2Detector(ddl);
199   return Channel2StripBase(board, altro, chan, ring, sec, str);
200 }
201
202
203 //____________________________________________________________________
204 Bool_t 
205 AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl, UInt_t    addr, 
206                                       UShort_t& det, Char_t&   ring, 
207                                       UShort_t& sec, Short_t&  str) const
208 {
209   // Translate a hardware address to detector coordinates. 
210   // 
211   // See also Hardware2Detector that accepts 4 inputs 
212   UShort_t board, altro, chan;
213   ChannelAddress(addr, board, altro, chan);
214   return Hardware2Detector(ddl,board, altro, chan, det,ring, sec, str);
215 }
216 #endif 
217
218 //____________________________________________________________________
219 Bool_t 
220 AliFMDAltroMapping::Hardware2Detector(UShort_t  ddl,     UShort_t    board, 
221                                       UShort_t  altro,   UShort_t    chan,
222                                       UShort_t  timebin, UShort_t    preSamples,
223                                       UShort_t  sampleRate,
224                                       UShort_t& det,     Char_t&   ring, 
225                                       UShort_t& sec,     Short_t&  str,
226                                       UShort_t& sam) const
227 {
228   // Full conversion from hardware address, including timebin number,
229   // to detector coordinates and sample number.  Note, that this
230   // conversion depends on the oversampling rate and the number of
231   // pre-samples 
232   Short_t  baseStrip, stripOffset, tdet  = DDL2Detector(ddl);
233   if (tdet < 0) return kFALSE;
234   det = tdet;
235   if (!Channel2StripBase(board, altro, chan, ring, sec, baseStrip)) 
236     return kFALSE;
237   Timebin2Strip(sec, timebin, preSamples, sampleRate, stripOffset, sam);
238 #if 0
239   AliFMDDebug(1, ("0x%x/0x%02x/0x%x/0x%x/%04d -> FMD%d%c[%2d,%3d]-%d "
240                   "(pre=%d,rate=%d,base=%3d,off=%3d)", 
241                   ddl, 
242                   board, 
243                   altro, 
244                   chan, 
245                   timebin, 
246                   det, 
247                   ring, 
248                   sec, 
249                   str, 
250                   sam,
251                   preSamples, 
252                   sampleRate,
253                   baseStrip, 
254                   stripOffset));
255 #endif
256   str = baseStrip + stripOffset;
257   return kTRUE;
258 }
259
260 //____________________________________________________________________
261 Bool_t 
262 AliFMDAltroMapping::Hardware2Detector(UShort_t  ddl,       UShort_t addr,
263                                       UShort_t  timebin,   UShort_t preSamples, 
264                                       UShort_t  sampleRate,
265                                       UShort_t& det,       Char_t&   ring, 
266                                       UShort_t& sec,       Short_t&  str,
267                                       UShort_t& sam) const
268 {
269   // Translate a hardware address to detector coordinates. 
270   // 
271   // See also Hardware2Detector that accepts 4 inputs 
272   UShort_t board, altro, chan;
273   ChannelAddress(addr, board, altro, chan);
274   return Hardware2Detector(ddl, board, altro, chan, 
275                            timebin, preSamples, sampleRate, 
276                            det, ring, sec, str, sam);
277 }
278
279
280 //____________________________________________________________________
281 Short_t
282 AliFMDAltroMapping::Sector2Board(Char_t ring, UShort_t sec) const
283 {
284   switch (ring) { 
285   case 'I': 
286   case 'i':
287     return (sec / 10) * 16;
288   case 'O': 
289   case 'o': 
290     return (sec / 20) * 16 + 1;
291   }
292   return -1;
293 }
294
295 //_____________________________________________ _______________________
296 Bool_t
297 AliFMDAltroMapping::Strip2Channel(Char_t    ring,  UShort_t  sec,   
298                                   UShort_t  str,   UShort_t& board,
299                                   UShort_t& altro, UShort_t& chan) const
300 {
301   // Translate detector coordinates to a hardware address.
302   // The ddl is simply 
303   // 
304   //    (det - 1)
305   // 
306   // The ring number, sector, and strip number must be encoded into a
307   // hardware address.  The address argument, will have the following
308   // format on output
309   // 
310   //   12            7          4          0
311   //   +-------------+----------+----------+
312   //   | Board       | ALTRO    | Channel  |
313   //   +-------------+----------+----------+
314   // 
315   // The board number is given by the ring and sector.  The inner
316   // rings board 0 and 16, while the outer are 1 and 17.  Which of these
317   // depends on the sector.  The map is 
318   // 
319   //    Ring I, sector  0- 9       ->   board 0 
320   //    Ring I, sector 10-19       ->   board 16
321   //    Ring O, sector  0-19       ->   board 1 
322   //    Ring O, sector 20-39       ->   board 17
323   // 
324   // There are 3 ALTRO's per board.  The ALTRO number is given by the
325   // sector number.  For the inner rings, these are given by
326   // 
327   //    Sector  0- 3  or  10-13    ->   ALTRO 0 
328   //    Sector  4- 5  or  14-15    ->   ALTRO 1 
329   //    Sector  6- 9  or  16-19    ->   ALTRO 2 
330   // 
331   // For the outers, it's given by 
332   // 
333   //    Sector  0- 7  or  20-27    ->   ALTRO 0 
334   //    Sector  8-11  or  28-31    ->   ALTRO 1 
335   //    Sector 12-19  or  32-39    ->   ALTRO 2 
336   //
337   // The channel number is given by the sector and strip number.  For
338   // the inners, the map is 
339   // 
340   //    Sector  0, strips   0-127  ->   Channel  0
341   //    Sector  0, strips 128-255  ->   Channel  2
342   //    Sector  0, strips 256-383  ->   Channel  4
343   //    Sector  0, strips 384-511  ->   Channel  6
344   //    Sector  1, strips 127-  0  ->   Channel  1
345   //    Sector  1, strips 255-128  ->   Channel  3
346   //    Sector  1, strips 383-256  ->   Channel  5
347   //    Sector  1, strips 511-384  ->   Channel  7
348   //    Sector  2, strips   0-127  ->   Channel  8
349   //    Sector  2, strips 128-255  ->   Channel 10
350   //    Sector  2, strips 256-383  ->   Channel 12
351   //    Sector  2, strips 384-511  ->   Channel 14
352   //    Sector  3, strips 127-  0  ->   Channel  9
353   //    Sector  3, strips 255-128  ->   Channel 11
354   //    Sector  3, strips 383-256  ->   Channel 13
355   //    Sector  3, strips 511-384  ->   Channel 15
356   // 
357   // and so on, up to sector 19.  For the outer, the map is 
358   // 
359   //    Sector  0, strips   0-127  ->   Channel  0
360   //    Sector  0, strips 128-255  ->   Channel  2
361   //    Sector  1, strips 127-  0  ->   Channel  1
362   //    Sector  1, strips 255-128  ->   Channel  3
363   //    Sector  2, strips   0-127  ->   Channel  4
364   //    Sector  2, strips 128-255  ->   Channel  6
365   //    Sector  3, strips 127-  0  ->   Channel  5
366   //    Sector  3, strips 255-128  ->   Channel  7
367   //    Sector  4, strips   0-127  ->   Channel  8
368   //    Sector  4, strips 128-255  ->   Channel 10
369   //    Sector  5, strips 127-  0  ->   Channel  9
370   //    Sector  5, strips 255-128  ->   Channel 11
371   //    Sector  6, strips   0-127  ->   Channel 12
372   //    Sector  6, strips 128-255  ->   Channel 14
373   //    Sector  7, strips 127-  0  ->   Channel 13
374   //    Sector  7, strips 255-128  ->   Channel 15
375   // 
376   // and so on upto sector 40. 
377   // 
378   // With this information, we can decode the detector coordinates to
379   // give us a unique hardware address 
380   //
381   UInt_t   tmp    = 0;
382   UShort_t fboard = 0;
383   switch (ring) {
384   case 'I':
385   case 'i':
386     fboard =  sec < 10 ? 1 : 0;
387     board  =  fboard * 16;
388     altro  =  (sec % 10) < 4 ? 0 : (sec % 10) < 6 ? 1 : 2;
389     tmp    =  (sec % 10) - (altro == 0 ? 0 : altro == 1 ? 4 : 6);
390     chan   =  2  * (str / 128) + (sec % 2) + ((tmp / 2) % 2) * 8;
391     break;
392   case 'O':
393   case 'o':
394     fboard =  sec < 20 ? 1 : 0;
395     board  =  fboard * 16 + 1;
396     altro  =  (sec % 20) < 8 ? 0 : (sec % 20) < 12 ? 1 : 2;
397     tmp    =  (sec % 20) - (altro == 0 ? 0 : altro == 1 ? 8 : 12);
398     chan   =  2 * (str / 128) + (sec % 2) + ((tmp / 2) % 4) * 4;
399     break;
400   }
401   return kTRUE;
402 }
403
404 //_____________________________________________ _______________________
405 UShort_t
406 AliFMDAltroMapping::Strip2Timebin(UShort_t sec, UShort_t strip, 
407                                   UShort_t sam, UShort_t preSamples, 
408                                   UShort_t sampleRate) const
409 {
410   UShort_t timebin = preSamples;
411   if (sec % 2)  timebin += (127 - (strip % 128)) * sampleRate;
412   else          timebin += (strip % 128) * sampleRate;
413   timebin += sam;
414   return timebin;
415 }
416
417 #if 0
418 //_____________________________________________ _______________________
419 Bool_t 
420 AliFMDAltroMapping::Detector2Hardware(UShort_t  det,   Char_t    ring, 
421                                       UShort_t  sec,   UShort_t  str,
422                                       UShort_t& ddl,   UShort_t& board,
423                                       UShort_t& altro, UShort_t& chan) const
424 {
425   ddl =  Detector2DDL(det);
426   return Strip2Channel(ring, sec, str, board, altro, chan);
427 }
428
429
430 //____________________________________________________________________
431 Bool_t 
432 AliFMDAltroMapping::Detector2Hardware(UShort_t  det, Char_t    ring, 
433                                       UShort_t  sec, UShort_t  str,
434                                       UShort_t& ddl, UShort_t& addr) const
435 {
436   // Translate detector coordinates to a hardware address.  
437   // 
438   // See also Detector2Hardware that returns 4 parameters.  
439   UShort_t board = 0;
440   UShort_t altro = 0;
441   UShort_t chan  = 0;
442   if (!Detector2Hardware(det,ring,sec,str,ddl,board,altro,chan)) return kFALSE;
443   addr =  ChannelAddress(board, altro, chan);
444   return kTRUE;
445 }
446 #endif
447
448 //____________________________________________________________________
449 Bool_t 
450 AliFMDAltroMapping::Detector2Hardware(UShort_t  det,        Char_t    ring, 
451                                       UShort_t  sec,        UShort_t  str,
452                                       UShort_t  sam, 
453                                       UShort_t  preSamples, 
454                                       UShort_t  sampleRate,
455                                       UShort_t& ddl,        UShort_t& board, 
456                                       UShort_t& altro,      UShort_t& channel, 
457                                       UShort_t& timebin) const
458 {
459   ddl = Detector2DDL(det);
460   if (!Strip2Channel(ring,sec,str,board,altro,channel)) return kFALSE;
461   timebin = Strip2Timebin(sec, str, sam, preSamples, sampleRate);
462   return kTRUE;
463 }
464
465
466 //____________________________________________________________________
467 Bool_t 
468 AliFMDAltroMapping::Detector2Hardware(UShort_t  det,        Char_t   ring, 
469                                       UShort_t  sec,        UShort_t str,
470                                       UShort_t  sam, 
471                                       UShort_t  preSamples, UShort_t sampleRate,
472                                       UShort_t& ddl,        UShort_t&  hwaddr, 
473                                       UShort_t& timebin) const
474 {
475   UShort_t board = 0;
476   UShort_t altro = 0;
477   UShort_t chan  = 0;
478   if (!Detector2Hardware(det, ring, sec, str, sam, 
479                          preSamples, sampleRate, 
480                          ddl, board, altro, chan, timebin)) return kFALSE;
481   hwaddr =  ChannelAddress(board, altro, chan);
482   return kTRUE;
483 }
484
485       
486 //____________________________________________________________________
487 UInt_t 
488 AliFMDAltroMapping::ChannelAddress(UShort_t board, UShort_t altro, 
489                                    UShort_t channel) const
490 {
491   return (((board & 0x1F) << 7) | ((altro & 0x7) << 4) | (channel & 0xF));
492 }
493
494 //____________________________________________________________________
495 void 
496 AliFMDAltroMapping::ChannelAddress(UShort_t hwaddr, UShort_t& board, 
497                                    UShort_t& altro, UShort_t& channel) const
498 {
499   board   = ((hwaddr >> 7) & 0x1F);
500   altro   = ((hwaddr >> 4) & 0x07);
501   channel = ((hwaddr >> 0) & 0x0F);
502 }
503
504 //____________________________________________________________________
505 Int_t
506 AliFMDAltroMapping::GetHWAddress(Int_t sec, Int_t str, Int_t ring)
507 {
508   // Return hardware address corresponding to sector sec, strip str,
509   // and ring ring.   Mapping from TPC to FMD coordinates are 
510   // 
511   //   TPC     | FMD
512   //   --------+------
513   //   padrow  | sector
514   //   pad     | strip
515   //   sector  | ring 
516   //
517   Char_t r = Char_t(ring);
518   UShort_t board, altro, channel;
519   Strip2Channel(r, sec, str, board, altro, channel);
520   return ChannelAddress(board, altro, channel);
521 }
522
523 //____________________________________________________________________
524 Int_t
525 AliFMDAltroMapping::GetPadRow(Int_t hwaddr) const
526 {
527   // Return sector corresponding to hardware address hwaddr.  Mapping
528   // from TPC to FMD coordinates are  
529   // 
530   //   TPC     | FMD
531   //   --------+------
532   //   padrow  | sector
533   //   pad     | strip
534   //   sector  | ring 
535   //
536   Char_t   ring;
537   UShort_t board, altro, channel, sector;
538   Short_t  baseStrip;
539   ChannelAddress(hwaddr, board, altro, channel);
540   if (!Channel2StripBase(board, altro, channel, ring, sector, baseStrip))
541     return -1;
542   return Int_t(sector);
543 }
544
545 //____________________________________________________________________
546 Int_t
547 AliFMDAltroMapping::GetPad(Int_t hwaddr) const
548 {
549   // Return strip corresponding to hardware address hwaddr.  Mapping
550   // from TPC to FMD coordinates are  
551   // 
552   //   TPC     | FMD
553   //   --------+------
554   //   padrow  | sector
555   //   pad     | strip
556   //   sector  | ring 
557   //
558   Char_t   ring;
559   UShort_t board, altro, channel, sector;
560   Short_t  baseStrip;
561   ChannelAddress(hwaddr, board, altro, channel);
562   if (!Channel2StripBase(board, altro, channel, ring, sector, baseStrip))
563     return -1;
564   return Int_t(baseStrip);
565 }
566   
567 //____________________________________________________________________
568 Int_t
569 AliFMDAltroMapping::GetSector(Int_t hwaddr) const
570 {
571   // Return ring corresponding to hardware address hwaddr.  Mapping
572   // from TPC to FMD coordinates are  
573   // 
574   //   TPC     | FMD
575   //   --------+------
576   //   padrow  | sector
577   //   pad     | strip
578   //   sector  | ring 
579   //
580   Char_t   ring;
581   UShort_t board, altro, channel, sector;
582   Short_t  baseStrip;
583   ChannelAddress(hwaddr, board, altro, channel);
584   if (!Channel2StripBase(board, altro, channel, ring, sector, baseStrip))
585     return -1;
586   return Int_t(ring);
587 }
588
589 //____________________________________________________________________
590 void
591 AliFMDAltroMapping::Print(Option_t* option) const
592 {
593   TString opt(option);
594   opt.ToLower();
595   UShort_t ddl, board, chip, chan, addr;
596   UShort_t det, sec;
597   Short_t  strBase;
598   Char_t   rng;
599   
600   if (opt.Contains("hw") || opt.Contains("hardware")) { 
601     std::cout << " DDL | Board | Chip | Chan | Address | Detector\n"
602               << "=====+=======+======+======+=========+===============" 
603               << std::endl;
604     for (ddl = 0; ddl <= 2; ddl++) { 
605       Int_t  boards[] = { 0, 16, (ddl == 0 ? 32 : 1), 17, 32};
606       Int_t* ptr      = boards;
607       det             = DDL2Detector(ddl);
608       while ((board = *(ptr++)) < 32) { 
609         for (chip = 0; chip <= 2; chip++) { 
610           UShort_t nchan = (chip == 1 ? 8 : 16);
611           for (chan = 0; chan < nchan; chan++) { 
612             Channel2StripBase(board, chip, chan, rng, sec, strBase);
613             addr = ChannelAddress(board, chip, chan);
614             std::cout << " "  
615                       << std::setw(3) << ddl     << " | " 
616                       << std::setfill('0')       << std::hex << " 0x"
617                       << std::setw(2) << board   << " |  0x"
618                       << std::setw(1) << chip    << " |  0x"
619                       << std::setw(1) << chan    << " |   0x" 
620                       << std::setw(3) << addr    << " | " 
621                       << std::setfill(' ')       << std::dec << " FMD" 
622                       << std::setw(1) << det     << rng << "[" 
623                       << std::setw(2) << sec     << "," 
624                       << std::setw(3) << strBase << "]" << std::endl;
625           } // for chan ...
626           if (chip == 2 && *ptr >= 32) continue;
627           std::cout << "     +       +      +      +         +              " 
628                     << std::endl;
629         } // for chip ... 
630       } // while board 
631       std::cout << "-----+-------+------+------+---------+---------------" 
632                 << std::endl;
633     } // for ddl ... 
634   } // if hw 
635   if (opt.Contains("det")) { 
636     std::cout << " Detector      | DDL | Board | Chip | Chan | Address\n"
637               << "===============+=====+=======+======+======+========"
638               << std::endl;
639     for (det = 1; det <= 3; det++) { 
640       Char_t  rings[] = { 'I', (det == 1 ? '\0' : 'O'),'\0' };
641       Char_t* ptr     = rings;
642       ddl             = Detector2DDL(det);
643       while ((rng = *(ptr++)) != '\0') { 
644         UShort_t nsec = (rng == 'I' ?  20 :  40);
645         UShort_t nstr = (rng == 'I' ? 512 : 256);
646         for (sec = 0; sec < nsec; sec++) { 
647           for (strBase = 0; strBase < nstr; strBase += 128) {
648             Strip2Channel(rng, sec, strBase, board, chip, chan);
649             addr = ChannelAddress(board, chip, chan);
650             std::cout << std::setfill(' ')         << std::dec << " FMD" 
651                       << std::setw(1) << det       << rng      << "[" 
652                       << std::setw(2) << sec       << "," 
653                       << std::setw(3) << strBase   << "] | " 
654                       << std::setw(3) << ddl       << " |  0x"
655                       << std::setfill('0')         << std::hex  
656                       << std::setw(2) << board     << " |  0x"
657                       << std::setw(1) << chip      << " |  0x"
658                       << std::setw(1) << chan      << " |   0x" 
659                       << std::setw(3) << addr      << std::endl;
660           } // for str ...
661         } // for sec ... 
662         if (*ptr == '\0') continue;
663         std::cout << "               +     +       +      +      +        " 
664                   << std::endl;
665       } // while rng ... 
666       std::cout << "---------------+-----+-------+------+------+--------" 
667                 << std::endl;
668
669     } // for det ... 
670   } // if det 
671 }
672
673 //_____________________________________________________________________________
674 //
675 // EOF
676 //