Coding conventions (Christian)
[u/mrichter/AliRoot.git] / FMD / AliFMDAltroMapping.cxx
CommitLineData
57c3c593 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 **************************************************************************/
57c3c593 15/* $Id$ */
c2fc1258 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*/
57c3c593 21//____________________________________________________________________
22//
23// Mapping of ALTRO hardware channel to detector coordinates
24//
02a27b50 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//
57c3c593 35#include "AliFMDAltroMapping.h" // ALIFMDALTROMAPPING_H
36#include "AliFMDParameters.h"
37#include "AliLog.h"
38
39//____________________________________________________________________
40ClassImp(AliFMDAltroMapping)
41#if 0
42 ; // This is here to keep Emacs for indenting the next line
43#endif
44
45//_____________________________________________________________________________
46AliFMDAltroMapping::AliFMDAltroMapping()
9f662337 47{
48 // Constructor
49}
57c3c593 50
51
52//_____________________________________________________________________________
53Bool_t
54AliFMDAltroMapping::ReadMapping()
55{
9f662337 56 // Read map from file - not used
57c3c593 57 return kTRUE;
58}
59
60//_____________________________________________________________________________
61void
62AliFMDAltroMapping::DeleteMappingArrays()
9f662337 63{
64 // Clear map in memory
65}
57c3c593 66
67//____________________________________________________________________
68Bool_t
69AliFMDAltroMapping::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//____________________________________________________________________
168Bool_t
169AliFMDAltroMapping::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;
1e8f773e 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);
57c3c593 263 AliDebug(40, Form("\n"
264 " chan = (%d %% 2) + (%d-%d) / %d * %d + 2 * %d / 128\n"
265 " = %d + %d + %d = %d",
1e8f773e 266 sec, lsec, sbase, 2, ncs, str,
267 (sec % 2), (lsec - sbase) / 2 * ncs,
268 2 * (str / 128), chan));
57c3c593 269 addr = chan + (altro << 4) + (board << 7);
270
271 return kTRUE;
272}
273
274//____________________________________________________________________
275Int_t
276AliFMDAltroMapping::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//____________________________________________________________________
295Int_t
296AliFMDAltroMapping::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//____________________________________________________________________
317Int_t
318AliFMDAltroMapping::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//____________________________________________________________________
339Int_t
340AliFMDAltroMapping::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//