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