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