]>
Commit | Line | Data |
---|---|---|
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 | // | |
6169f936 | 25 | // The hardware address consist of a DDL number and 12bits of ALTRO |
26 | // addresses. The ALTRO address are formatted as follows. | |
02a27b50 | 27 | // |
28 | // 12 7 4 0 | |
29 | // |---------------|---------|------------| | |
30 | // | Board # | ALTRO # | Channel # | | |
31 | // +---------------+---------+------------+ | |
32 | // | |
6169f936 | 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. | |
02a27b50 | 36 | // |
57c3c593 | 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() | |
9f662337 | 49 | { |
50 | // Constructor | |
51 | } | |
57c3c593 | 52 | |
53 | ||
54 | //_____________________________________________________________________________ | |
55 | Bool_t | |
56 | AliFMDAltroMapping::ReadMapping() | |
57 | { | |
9f662337 | 58 | // Read map from file - not used |
57c3c593 | 59 | return kTRUE; |
60 | } | |
61 | ||
62 | //_____________________________________________________________________________ | |
63 | void | |
64 | AliFMDAltroMapping::DeleteMappingArrays() | |
9f662337 | 65 | { |
66 | // Clear map in memory | |
67 | } | |
57c3c593 | 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 - kBaseDDL + 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 - AliFMDParameters::kBaseDDL) + 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 | // kBaseDDL + (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 = AliFMDParameters::kBaseDDL + (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; | |
1e8f773e | 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); | |
57c3c593 | 265 | AliDebug(40, Form("\n" |
266 | " chan = (%d %% 2) + (%d-%d) / %d * %d + 2 * %d / 128\n" | |
267 | " = %d + %d + %d = %d", | |
1e8f773e | 268 | sec, lsec, sbase, 2, ncs, str, |
269 | (sec % 2), (lsec - sbase) / 2 * ncs, | |
270 | 2 * (str / 128), chan)); | |
57c3c593 | 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 = AliFMDParameters::kBaseDDL; | |
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 = AliFMDParameters::kBaseDDL; | |
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 = AliFMDParameters::kBaseDDL; | |
358 | if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1; | |
359 | return Int_t(ring); | |
360 | } | |
361 | ||
362 | //_____________________________________________________________________________ | |
363 | // | |
364 | // EOF | |
365 | // |