]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDAltroMapping.cxx
AddAlignableVolumes added
[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
41 //____________________________________________________________________
42 ClassImp(AliFMDAltroMapping)
43 #if 0
44   ; // This is here to keep Emacs for indenting the next line
45 #endif
46
47 //_____________________________________________________________________________
48 AliFMDAltroMapping::AliFMDAltroMapping()
49 {
50   // Constructor 
51 }
52
53
54 //_____________________________________________________________________________
55 Bool_t
56 AliFMDAltroMapping::ReadMapping()
57 {
58   // Read map from file - not used
59   return kTRUE;
60 }
61
62 //_____________________________________________________________________________
63 void
64 AliFMDAltroMapping::DeleteMappingArrays()
65 {
66   // Clear map in memory 
67 }
68
69 //____________________________________________________________________
70 Bool_t 
71 AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl, UInt_t    addr, 
72                                       UShort_t& det, Char_t&   ring, 
73                                       UShort_t& sec, UShort_t& str) const
74 {
75   // Translate a hardware address to detector coordinates. 
76   // The detector is simply 
77   // 
78   //    ddl + 1
79   // 
80   // The ring number, sector, and strip number is given by the addr
81   // argument.  The address argument, has the following format 
82   // 
83   //   12            7          4          0
84   //   +-------------+----------+----------+
85   //   | Board       | ALTRO    | Channel  |
86   //   +-------------+----------+----------+
87   // 
88   // The board number identifier among other things the ring.  There's
89   // up to 4 boards per DDL, and the two first (0 and 1) corresponds
90   // to the inner rings, while the two last (2 and 3) corresponds to
91   // the outer rings. 
92   // 
93   // The board number and ALTRO number together identifies the sensor,
94   // and hence.  The lower board number (0 or 2) are the first N / 2
95   // sensors (where N is the number of sensors in the ring).  
96   // 
97   // There are 3 ALTRO's per card, and each ALTRO serves up to 4
98   // sensors.  Which of sensor is determined by the channel number.
99   // For the inner rings, the map is
100   // 
101   //    ALTRO 0, Channel  0 to  7   -> Sensor 0 or 5
102   //    ALTRO 0, Channel  8 to 15   -> Sensor 1 or 6
103   //    ALTRO 1, Channel  0 to  7   -> Sensor 2 or 7 
104   //    ALTRO 2, Channel  0 to  7   -> Sensor 3 or 8
105   //    ALTRO 2, Channel  8 to 15   -> Sensor 4 or 9
106   // 
107   // For the outer rings, the map is 
108   // 
109   //    ALTRO 0, Channel  0 to  3   -> Sensor 0 or 10
110   //    ALTRO 0, Channel  4 to  7   -> Sensor 1 or 11
111   //    ALTRO 0, Channel  8 to 11   -> Sensor 2 or 12
112   //    ALTRO 0, Channel 12 to 15   -> Sensor 3 or 13
113   //    ALTRO 1, Channel  0 to  3   -> Sensor 4 or 14
114   //    ALTRO 1, Channel  4 to  7   -> Sensor 5 or 15
115   //    ALTRO 2, Channel  0 to  3   -> Sensor 6 or 16
116   //    ALTRO 2, Channel  4 to  7   -> Sensor 7 or 17
117   //    ALTRO 2, Channel  8 to 11   -> Sensor 8 or 18
118   //    ALTRO 2, Channel 12 to 15   -> Sensor 9 or 19
119   // 
120   // Which divison of the sensor we're in, depends on the channel
121   // number only.  For the inner rings, the map is 
122   // 
123   //    Channel 0                   -> Sector 0, strips   0-127
124   //    Channel 1                   -> Sector 1, strips   0-127
125   //    Channel 3                   -> Sector 0, strips 128-255
126   //    Channel 4                   -> Sector 1, strips 128-255
127   //    Channel 5                   -> Sector 0, strips 256-383
128   //    Channel 6                   -> Sector 1, strips 256-383
129   //    Channel 7                   -> Sector 0, strips 384-511
130   //    Channel 8                   -> Sector 1, strips 384-511 
131   // 
132   // There are only half as many strips in the outer sensors, so there
133   // only 4 channels are used for a full sensor.  The map is 
134   // 
135   //    Channel 0                   -> Sector 0, strips   0-127
136   //    Channel 1                   -> Sector 1, strips   0-127
137   //    Channel 3                   -> Sector 0, strips 128-255
138   //    Channel 4                   -> Sector 1, strips 128-255
139   // 
140   // With this information, we can decode the hardware address to give
141   // us detector coordinates, unique at least up a 128 strips.  We
142   // return the first strip in the given range. 
143   //
144   det          =  ddl + 1;
145   UInt_t board =  (addr >> 7) & 0x1F;
146   UInt_t altro =  (addr >> 4) & 0x7;
147   UInt_t chan  =  (addr & 0xf);
148   if (board > 3) {
149     AliError(Form("Invalid board address %d for the FMD", board));
150     return kFALSE;
151   }
152   if (altro > 2) {
153     AliError(Form("Invalid ALTRO address %d for the FMD digitizer %d", 
154                   altro, board));
155     return kFALSE;
156   }
157   ring         =  (board > 1 ? 'O' : 'I');
158   UInt_t nsen  =  (ring == 'I' ? 10 : 20);
159   UInt_t nsa   =  (ring == 'I' ? 2 : 4);   // Sensors per ALTRO
160   UInt_t ncs   =  (ring == 'I' ? 8 : 4);   // Channels per sensor 
161   UInt_t sen   =  (board % 2) * nsen / 2;  // Base for half-ring
162   sen          += chan / ncs + (altro == 0 ? 0   : 
163                                 altro == 1 ? nsa : UInt_t(1.5 * nsa));
164   sec          =  2 * sen + (chan % 2);
165   str          =  (chan % ncs) / 2 * 128;
166   return kTRUE;
167 }
168
169 //____________________________________________________________________
170 Bool_t 
171 AliFMDAltroMapping::Detector2Hardware(UShort_t  det, Char_t    ring, 
172                                       UShort_t  sec, UShort_t  str,
173                                       UInt_t&   ddl, UInt_t&   addr) const
174 {
175   // Translate detector coordinates to a hardware address.
176   // The ddl is simply 
177   // 
178   //    (det - 1)
179   // 
180   // The ring number, sector, and strip number must be encoded into a
181   // hardware address.  The address argument, will have the following
182   // format on output
183   // 
184   //   12            7          4          0
185   //   +-------------+----------+----------+
186   //   | Board       | ALTRO    | Channel  |
187   //   +-------------+----------+----------+
188   // 
189   // The board number is given by the ring and sector.  The inner
190   // rings board 0 and 1, while the outer are 2 and 3.  Which of these
191   // depends on the sector.  The map is 
192   // 
193   //    Ring I, sector  0- 9       ->   board 0 
194   //    Ring I, sector 10-19       ->   board 1
195   //    Ring O, sector  0-19       ->   board 2 
196   //    Ring O, sector 20-39       ->   board 3
197   // 
198   // There are 3 ALTRO's per board.  The ALTRO number is given by the
199   // sector number.  For the inner rings, these are given by
200   // 
201   //    Sector  0- 3  or  10-13    ->   ALTRO 0 
202   //    Sector  4- 5  or  14-15    ->   ALTRO 1 
203   //    Sector  6- 9  or  16-19    ->   ALTRO 2 
204   // 
205   // For the outers, it's given by 
206   // 
207   //    Sector  0- 7  or  20-27    ->   ALTRO 0 
208   //    Sector  8-11  or  28-31    ->   ALTRO 1 
209   //    Sector 12-19  or  32-39    ->   ALTRO 2 
210   //
211   // The channel number is given by the sector and strip number.  For
212   // the inners, the map is 
213   // 
214   //    Sector  0, strips   0-127  ->   Channel  0
215   //    Sector  0, strips 128-255  ->   Channel  2
216   //    Sector  0, strips 256-383  ->   Channel  4
217   //    Sector  0, strips 384-511  ->   Channel  6
218   //    Sector  1, strips   0-127  ->   Channel  1
219   //    Sector  1, strips 128-255  ->   Channel  3
220   //    Sector  1, strips 256-383  ->   Channel  5
221   //    Sector  1, strips 384-511  ->   Channel  7
222   //    Sector  2, strips   0-127  ->   Channel  8
223   //    Sector  2, strips 128-255  ->   Channel 10
224   //    Sector  2, strips 256-383  ->   Channel 12
225   //    Sector  2, strips 384-511  ->   Channel 14
226   //    Sector  3, strips   0-127  ->   Channel  9
227   //    Sector  3, strips 128-255  ->   Channel 11
228   //    Sector  3, strips 256-383  ->   Channel 13
229   //    Sector  3, strips 384-511  ->   Channel 15
230   // 
231   // and so on, up to sector 19.  For the outer, the map is 
232   // 
233   //    Sector  0, strips   0-127  ->   Channel  0
234   //    Sector  0, strips 128-255  ->   Channel  2
235   //    Sector  1, strips   0-127  ->   Channel  1
236   //    Sector  1, strips 128-255  ->   Channel  3
237   //    Sector  2, strips   0-127  ->   Channel  4
238   //    Sector  2, strips 128-255  ->   Channel  6
239   //    Sector  3, strips   0-127  ->   Channel  5
240   //    Sector  3, strips 128-255  ->   Channel  7
241   //    Sector  4, strips   0-127  ->   Channel  8
242   //    Sector  4, strips 128-255  ->   Channel 10
243   //    Sector  5, strips   0-127  ->   Channel  9
244   //    Sector  5, strips 128-255  ->   Channel 11
245   //    Sector  6, strips   0-127  ->   Channel 12
246   //    Sector  6, strips 128-255  ->   Channel 14
247   //    Sector  7, strips   0-127  ->   Channel 13
248   //    Sector  7, strips 128-255  ->   Channel 15
249   // 
250   // and so on upto sector 40. 
251   // 
252   // With this information, we can decode the detector coordinates to
253   // give us a unique hardware address 
254   //
255   ddl          =  (det - 1);
256   UInt_t nsen  =  (ring == 'I' ? 10 : 20);
257   UInt_t nsa   =  (ring == 'I' ? 2 : 4);   // Sensors per ALTRO
258   UInt_t ncs   =  (ring == 'I' ? 8 : 4);   // Channels per sensor 
259   UInt_t bbase =  (ring == 'I' ? 0 : 2);
260   UInt_t board =  bbase + sec / nsen;
261   UInt_t lsec  =  (sec - (board - bbase) * nsen); // Local sec in half-ring
262   UInt_t altro =  (lsec < 2 * nsa ? 0 : (lsec < 3 * nsa ? 1       : 2));
263   UInt_t sbase =  (altro == 0     ? 0 : altro == 1      ? 2 * nsa : 3 * nsa);
264   UInt_t chan  =  (sec % 2) + (lsec-sbase) / 2 * ncs + 2 * (str / 128);
265   AliDebug(40, Form("\n"
266                     "  chan = (%d %% 2) + (%d-%d) / %d * %d + 2 * %d / 128\n"
267                     "       = %d + %d + %d = %d", 
268                     sec, lsec, sbase, 2, ncs, str, 
269                     (sec % 2), (lsec - sbase) / 2 * ncs, 
270                     2 * (str / 128), chan));
271   addr         =  chan + (altro << 4) + (board << 7);
272   
273   return kTRUE;
274 }
275
276 //____________________________________________________________________
277 Int_t
278 AliFMDAltroMapping::GetHWAddress(Int_t sec, Int_t str, Int_t ring) const
279 {
280   // Return hardware address corresponding to sector sec, strip str,
281   // and ring ring.   Mapping from TPC to FMD coordinates are 
282   // 
283   //   TPC     | FMD
284   //   --------+------
285   //   padrow  | sector
286   //   pad     | strip
287   //   sector  | ring 
288   //
289   UInt_t ddl, hwaddr;
290   Char_t r = Char_t(ring);
291   if (!Detector2Hardware(1, r, sec, str, ddl, hwaddr)) 
292     return -1;
293   return hwaddr;
294 }
295
296 //____________________________________________________________________
297 Int_t
298 AliFMDAltroMapping::GetPadRow(Int_t hwaddr) const
299 {
300   // Return sector corresponding to hardware address hwaddr.  Mapping
301   // from TPC to FMD coordinates are  
302   // 
303   //   TPC     | FMD
304   //   --------+------
305   //   padrow  | sector
306   //   pad     | strip
307   //   sector  | ring 
308   //
309   UShort_t det;
310   Char_t   ring;
311   UShort_t sec;
312   UShort_t str;
313   Int_t    ddl = 0;
314   if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1;
315   return Int_t(sec);
316 }
317
318 //____________________________________________________________________
319 Int_t
320 AliFMDAltroMapping::GetPad(Int_t hwaddr) const
321 {
322   // Return strip corresponding to hardware address hwaddr.  Mapping
323   // from TPC to FMD coordinates are  
324   // 
325   //   TPC     | FMD
326   //   --------+------
327   //   padrow  | sector
328   //   pad     | strip
329   //   sector  | ring 
330   //
331   UShort_t det;
332   Char_t   ring;
333   UShort_t sec;
334   UShort_t str;
335   Int_t    ddl = 0;
336   if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1;
337   return Int_t(str);
338 }
339   
340 //____________________________________________________________________
341 Int_t
342 AliFMDAltroMapping::GetSector(Int_t hwaddr) const
343 {
344   // Return ring corresponding to hardware address hwaddr.  Mapping
345   // from TPC to FMD coordinates are  
346   // 
347   //   TPC     | FMD
348   //   --------+------
349   //   padrow  | sector
350   //   pad     | strip
351   //   sector  | ring 
352   //
353   UShort_t det;
354   Char_t   ring;
355   UShort_t sec;
356   UShort_t str;
357   Int_t    ddl = 0;
358   if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1;
359   return Int_t(ring);
360 }
361
362 //_____________________________________________________________________________
363 //
364 // EOF
365 //