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