]>
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" | |
f6449cc0 | 40 | #include <iostream> |
41 | #include <iomanip> | |
57c3c593 | 42 | |
43 | //____________________________________________________________________ | |
44 | ClassImp(AliFMDAltroMapping) | |
45 | #if 0 | |
46 | ; // This is here to keep Emacs for indenting the next line | |
47 | #endif | |
48 | ||
49 | //_____________________________________________________________________________ | |
50 | AliFMDAltroMapping::AliFMDAltroMapping() | |
9f662337 | 51 | { |
52 | // Constructor | |
53 | } | |
57c3c593 | 54 | |
55 | ||
56 | //_____________________________________________________________________________ | |
57 | Bool_t | |
58 | AliFMDAltroMapping::ReadMapping() | |
59 | { | |
9f662337 | 60 | // Read map from file - not used |
57c3c593 | 61 | return kTRUE; |
62 | } | |
63 | ||
64 | //_____________________________________________________________________________ | |
573322da | 65 | Bool_t |
66 | AliFMDAltroMapping::CreateInvMapping() | |
9f662337 | 67 | { |
573322da | 68 | // Create inverse mapping - not used |
69 | return kTRUE; | |
9f662337 | 70 | } |
57c3c593 | 71 | |
72 | //____________________________________________________________________ | |
73 | Bool_t | |
74 | AliFMDAltroMapping::Hardware2Detector(UInt_t ddl, UInt_t addr, | |
75 | UShort_t& det, Char_t& ring, | |
76 | UShort_t& sec, UShort_t& str) const | |
f6449cc0 | 77 | { |
78 | // Translate a hardware address to detector coordinates. | |
79 | // | |
80 | // See also Hardware2Detector that accepts 4 inputs | |
81 | UInt_t board = (addr >> 7) & 0x1F; | |
82 | UInt_t altro = (addr >> 4) & 0x7; | |
83 | UInt_t chan = (addr & 0xf); | |
84 | return Hardware2Detector(ddl, board, altro, chan, det, ring, sec, str); | |
85 | } | |
86 | ||
87 | //____________________________________________________________________ | |
88 | Bool_t | |
89 | AliFMDAltroMapping::Hardware2Detector(UInt_t ddl, UInt_t board, | |
90 | UInt_t altro, UInt_t chan, | |
91 | UShort_t& det, Char_t& ring, | |
92 | UShort_t& sec, UShort_t& str) const | |
57c3c593 | 93 | { |
94 | // Translate a hardware address to detector coordinates. | |
95 | // The detector is simply | |
96 | // | |
362c9d61 | 97 | // ddl + 1 |
57c3c593 | 98 | // |
99 | // The ring number, sector, and strip number is given by the addr | |
100 | // argument. The address argument, has the following format | |
101 | // | |
102 | // 12 7 4 0 | |
103 | // +-------------+----------+----------+ | |
104 | // | Board | ALTRO | Channel | | |
105 | // +-------------+----------+----------+ | |
106 | // | |
107 | // The board number identifier among other things the ring. There's | |
a9579262 | 108 | // up to 4 boards per DDL, and the two first (0 and 16) corresponds |
109 | // to the inner rings, while the two last (1 and 17) corresponds to | |
57c3c593 | 110 | // the outer rings. |
111 | // | |
112 | // The board number and ALTRO number together identifies the sensor, | |
113 | // and hence. The lower board number (0 or 2) are the first N / 2 | |
114 | // sensors (where N is the number of sensors in the ring). | |
115 | // | |
116 | // There are 3 ALTRO's per card, and each ALTRO serves up to 4 | |
117 | // sensors. Which of sensor is determined by the channel number. | |
118 | // For the inner rings, the map is | |
119 | // | |
120 | // ALTRO 0, Channel 0 to 7 -> Sensor 0 or 5 | |
121 | // ALTRO 0, Channel 8 to 15 -> Sensor 1 or 6 | |
122 | // ALTRO 1, Channel 0 to 7 -> Sensor 2 or 7 | |
123 | // ALTRO 2, Channel 0 to 7 -> Sensor 3 or 8 | |
124 | // ALTRO 2, Channel 8 to 15 -> Sensor 4 or 9 | |
125 | // | |
126 | // For the outer rings, the map is | |
127 | // | |
128 | // ALTRO 0, Channel 0 to 3 -> Sensor 0 or 10 | |
129 | // ALTRO 0, Channel 4 to 7 -> Sensor 1 or 11 | |
130 | // ALTRO 0, Channel 8 to 11 -> Sensor 2 or 12 | |
131 | // ALTRO 0, Channel 12 to 15 -> Sensor 3 or 13 | |
132 | // ALTRO 1, Channel 0 to 3 -> Sensor 4 or 14 | |
133 | // ALTRO 1, Channel 4 to 7 -> Sensor 5 or 15 | |
134 | // ALTRO 2, Channel 0 to 3 -> Sensor 6 or 16 | |
135 | // ALTRO 2, Channel 4 to 7 -> Sensor 7 or 17 | |
136 | // ALTRO 2, Channel 8 to 11 -> Sensor 8 or 18 | |
137 | // ALTRO 2, Channel 12 to 15 -> Sensor 9 or 19 | |
138 | // | |
139 | // Which divison of the sensor we're in, depends on the channel | |
140 | // number only. For the inner rings, the map is | |
141 | // | |
142 | // Channel 0 -> Sector 0, strips 0-127 | |
143 | // Channel 1 -> Sector 1, strips 0-127 | |
144 | // Channel 3 -> Sector 0, strips 128-255 | |
145 | // Channel 4 -> Sector 1, strips 128-255 | |
146 | // Channel 5 -> Sector 0, strips 256-383 | |
147 | // Channel 6 -> Sector 1, strips 256-383 | |
148 | // Channel 7 -> Sector 0, strips 384-511 | |
149 | // Channel 8 -> Sector 1, strips 384-511 | |
150 | // | |
151 | // There are only half as many strips in the outer sensors, so there | |
152 | // only 4 channels are used for a full sensor. The map is | |
153 | // | |
154 | // Channel 0 -> Sector 0, strips 0-127 | |
155 | // Channel 1 -> Sector 1, strips 0-127 | |
156 | // Channel 3 -> Sector 0, strips 128-255 | |
157 | // Channel 4 -> Sector 1, strips 128-255 | |
158 | // | |
159 | // With this information, we can decode the hardware address to give | |
160 | // us detector coordinates, unique at least up a 128 strips. We | |
161 | // return the first strip in the given range. | |
162 | // | |
362c9d61 | 163 | det = ddl + 1; |
a9579262 | 164 | ring = (board % 2) == 0 ? 'I' : 'O'; |
165 | switch (ring) { | |
166 | case 'i': | |
167 | case 'I': | |
168 | sec = ((board / 16) * 10 + (altro < 1 ? 0 : altro < 2 ? 4 : 6) | |
169 | + 2 * (chan / 8) + chan % 2); | |
170 | str = ((chan % 8) / 2) * 128; | |
171 | break; | |
172 | case 'o': | |
173 | case 'O': | |
174 | sec = ((board / 16) * 20 + (altro < 1 ? 0 : altro < 2 ? 8 : 12) | |
175 | + 2 * (chan / 4) + chan % 2); | |
176 | str = ((chan % 4) / 2) * 128; | |
177 | break; | |
57c3c593 | 178 | } |
57c3c593 | 179 | return kTRUE; |
180 | } | |
181 | ||
182 | //____________________________________________________________________ | |
183 | Bool_t | |
f6449cc0 | 184 | AliFMDAltroMapping::Detector2Hardware(UShort_t det, Char_t ring, |
185 | UShort_t sec, UShort_t str, | |
186 | UInt_t& ddl, UInt_t& board, | |
187 | UInt_t& altro, UInt_t& chan) const | |
57c3c593 | 188 | { |
189 | // Translate detector coordinates to a hardware address. | |
190 | // The ddl is simply | |
191 | // | |
362c9d61 | 192 | // (det - 1) |
57c3c593 | 193 | // |
194 | // The ring number, sector, and strip number must be encoded into a | |
195 | // hardware address. The address argument, will have the following | |
196 | // format on output | |
197 | // | |
198 | // 12 7 4 0 | |
199 | // +-------------+----------+----------+ | |
200 | // | Board | ALTRO | Channel | | |
201 | // +-------------+----------+----------+ | |
202 | // | |
203 | // The board number is given by the ring and sector. The inner | |
a9579262 | 204 | // rings board 0 and 16, while the outer are 1 and 17. Which of these |
57c3c593 | 205 | // depends on the sector. The map is |
206 | // | |
207 | // Ring I, sector 0- 9 -> board 0 | |
a9579262 | 208 | // Ring I, sector 10-19 -> board 16 |
209 | // Ring O, sector 0-19 -> board 1 | |
210 | // Ring O, sector 20-39 -> board 17 | |
57c3c593 | 211 | // |
212 | // There are 3 ALTRO's per board. The ALTRO number is given by the | |
213 | // sector number. For the inner rings, these are given by | |
214 | // | |
215 | // Sector 0- 3 or 10-13 -> ALTRO 0 | |
216 | // Sector 4- 5 or 14-15 -> ALTRO 1 | |
217 | // Sector 6- 9 or 16-19 -> ALTRO 2 | |
218 | // | |
219 | // For the outers, it's given by | |
220 | // | |
221 | // Sector 0- 7 or 20-27 -> ALTRO 0 | |
222 | // Sector 8-11 or 28-31 -> ALTRO 1 | |
223 | // Sector 12-19 or 32-39 -> ALTRO 2 | |
224 | // | |
225 | // The channel number is given by the sector and strip number. For | |
226 | // the inners, the map is | |
227 | // | |
228 | // Sector 0, strips 0-127 -> Channel 0 | |
229 | // Sector 0, strips 128-255 -> Channel 2 | |
230 | // Sector 0, strips 256-383 -> Channel 4 | |
231 | // Sector 0, strips 384-511 -> Channel 6 | |
232 | // Sector 1, strips 0-127 -> Channel 1 | |
233 | // Sector 1, strips 128-255 -> Channel 3 | |
234 | // Sector 1, strips 256-383 -> Channel 5 | |
235 | // Sector 1, strips 384-511 -> Channel 7 | |
236 | // Sector 2, strips 0-127 -> Channel 8 | |
237 | // Sector 2, strips 128-255 -> Channel 10 | |
238 | // Sector 2, strips 256-383 -> Channel 12 | |
239 | // Sector 2, strips 384-511 -> Channel 14 | |
240 | // Sector 3, strips 0-127 -> Channel 9 | |
241 | // Sector 3, strips 128-255 -> Channel 11 | |
242 | // Sector 3, strips 256-383 -> Channel 13 | |
243 | // Sector 3, strips 384-511 -> Channel 15 | |
244 | // | |
245 | // and so on, up to sector 19. For the outer, the map is | |
246 | // | |
247 | // Sector 0, strips 0-127 -> Channel 0 | |
248 | // Sector 0, strips 128-255 -> Channel 2 | |
249 | // Sector 1, strips 0-127 -> Channel 1 | |
250 | // Sector 1, strips 128-255 -> Channel 3 | |
251 | // Sector 2, strips 0-127 -> Channel 4 | |
252 | // Sector 2, strips 128-255 -> Channel 6 | |
253 | // Sector 3, strips 0-127 -> Channel 5 | |
254 | // Sector 3, strips 128-255 -> Channel 7 | |
255 | // Sector 4, strips 0-127 -> Channel 8 | |
256 | // Sector 4, strips 128-255 -> Channel 10 | |
257 | // Sector 5, strips 0-127 -> Channel 9 | |
258 | // Sector 5, strips 128-255 -> Channel 11 | |
259 | // Sector 6, strips 0-127 -> Channel 12 | |
260 | // Sector 6, strips 128-255 -> Channel 14 | |
261 | // Sector 7, strips 0-127 -> Channel 13 | |
262 | // Sector 7, strips 128-255 -> Channel 15 | |
263 | // | |
264 | // and so on upto sector 40. | |
265 | // | |
266 | // With this information, we can decode the detector coordinates to | |
267 | // give us a unique hardware address | |
268 | // | |
362c9d61 | 269 | ddl = (det - 1); |
a9579262 | 270 | UInt_t tmp = 0; |
271 | switch (ring) { | |
272 | case 'I': | |
273 | case 'i': | |
f6449cc0 | 274 | board = (sec / 10) * 16; |
a9579262 | 275 | altro = (sec % 10) < 4 ? 0 : (sec % 10) < 6 ? 1 : 2; |
276 | tmp = (sec % 10) - (altro == 0 ? 0 : altro == 1 ? 4 : 6); | |
277 | chan = 2 * (str / 128) + (sec % 2) + ((tmp / 2) % 2) * 8; | |
278 | break; | |
279 | case 'O': | |
280 | case 'o': | |
f6449cc0 | 281 | board = (sec / 20) * 16 + 1; |
a9579262 | 282 | altro = (sec % 20) < 8 ? 0 : (sec % 20) < 12 ? 1 : 2; |
283 | tmp = (sec % 20) - (altro == 0 ? 0 : altro == 1 ? 8 : 12); | |
284 | chan = 2 * (str / 128) + (sec % 2) + ((tmp / 2) % 4) * 4; | |
285 | break; | |
286 | } | |
f6449cc0 | 287 | return kTRUE; |
288 | } | |
289 | ||
290 | //____________________________________________________________________ | |
291 | Bool_t | |
292 | AliFMDAltroMapping::Detector2Hardware(UShort_t det, Char_t ring, | |
293 | UShort_t sec, UShort_t str, | |
294 | UInt_t& ddl, UInt_t& addr) const | |
295 | { | |
296 | // Translate detector coordinates to a hardware address. | |
297 | // | |
298 | // See also Detector2Hardware that returns 4 parameters. | |
299 | UInt_t board = 0; | |
300 | UInt_t altro = 0; | |
301 | UInt_t chan = 0; | |
302 | if (!Detector2Hardware(det,ring,sec,str,ddl,board,altro,chan)) return kFALSE; | |
303 | addr = chan + (altro << 4) + (board << 7); | |
57c3c593 | 304 | return kTRUE; |
305 | } | |
306 | ||
307 | //____________________________________________________________________ | |
308 | Int_t | |
573322da | 309 | AliFMDAltroMapping::GetHWAddress(Int_t sec, Int_t str, Int_t ring) |
57c3c593 | 310 | { |
311 | // Return hardware address corresponding to sector sec, strip str, | |
312 | // and ring ring. Mapping from TPC to FMD coordinates are | |
313 | // | |
314 | // TPC | FMD | |
315 | // --------+------ | |
316 | // padrow | sector | |
317 | // pad | strip | |
318 | // sector | ring | |
319 | // | |
320 | UInt_t ddl, hwaddr; | |
321 | Char_t r = Char_t(ring); | |
322 | if (!Detector2Hardware(1, r, sec, str, ddl, hwaddr)) | |
323 | return -1; | |
324 | return hwaddr; | |
325 | } | |
326 | ||
327 | //____________________________________________________________________ | |
328 | Int_t | |
329 | AliFMDAltroMapping::GetPadRow(Int_t hwaddr) const | |
330 | { | |
331 | // Return sector corresponding to hardware address hwaddr. Mapping | |
332 | // from TPC to FMD coordinates are | |
333 | // | |
334 | // TPC | FMD | |
335 | // --------+------ | |
336 | // padrow | sector | |
337 | // pad | strip | |
338 | // sector | ring | |
339 | // | |
340 | UShort_t det; | |
341 | Char_t ring; | |
342 | UShort_t sec; | |
343 | UShort_t str; | |
362c9d61 | 344 | Int_t ddl = 0; |
57c3c593 | 345 | if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1; |
346 | return Int_t(sec); | |
347 | } | |
348 | ||
349 | //____________________________________________________________________ | |
350 | Int_t | |
351 | AliFMDAltroMapping::GetPad(Int_t hwaddr) const | |
352 | { | |
353 | // Return strip corresponding to hardware address hwaddr. Mapping | |
354 | // from TPC to FMD coordinates are | |
355 | // | |
356 | // TPC | FMD | |
357 | // --------+------ | |
358 | // padrow | sector | |
359 | // pad | strip | |
360 | // sector | ring | |
361 | // | |
362 | UShort_t det; | |
363 | Char_t ring; | |
364 | UShort_t sec; | |
365 | UShort_t str; | |
362c9d61 | 366 | Int_t ddl = 0; |
57c3c593 | 367 | if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1; |
368 | return Int_t(str); | |
369 | } | |
370 | ||
371 | //____________________________________________________________________ | |
372 | Int_t | |
373 | AliFMDAltroMapping::GetSector(Int_t hwaddr) const | |
374 | { | |
375 | // Return ring corresponding to hardware address hwaddr. Mapping | |
376 | // from TPC to FMD coordinates are | |
377 | // | |
378 | // TPC | FMD | |
379 | // --------+------ | |
380 | // padrow | sector | |
381 | // pad | strip | |
382 | // sector | ring | |
383 | // | |
384 | UShort_t det; | |
385 | Char_t ring; | |
386 | UShort_t sec; | |
387 | UShort_t str; | |
362c9d61 | 388 | Int_t ddl = 0; |
57c3c593 | 389 | if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1; |
390 | return Int_t(ring); | |
391 | } | |
392 | ||
f6449cc0 | 393 | //____________________________________________________________________ |
394 | void | |
395 | AliFMDAltroMapping::Print(Option_t* option) const | |
396 | { | |
397 | TString opt(option); | |
398 | opt.ToLower(); | |
399 | UInt_t ddl, board, chip, chan, addr; | |
400 | UShort_t det, sec, str; | |
401 | Char_t rng; | |
402 | ||
403 | if (opt.Contains("hw") || opt.Contains("hardware")) { | |
404 | std::cout << " DDL | Board | Chip | Chan | Address | Detector\n" | |
405 | << "=====+=======+======+======+=========+===============" | |
406 | << std::endl; | |
407 | for (ddl = 0; ddl <= 2; ddl++) { | |
408 | Int_t boards[] = { 0, 16, (ddl == 0 ? 32 : 1), 17, 32}; | |
409 | Int_t* ptr = boards; | |
410 | while ((board = *(ptr++)) < 32) { | |
411 | for (chip = 0; chip <= 2; chip++) { | |
412 | UInt_t nchan = (chip == 1 ? 8 : 16); | |
413 | for (chan = 0; chan < nchan; chan++) { | |
414 | Hardware2Detector(ddl, board, chip, chan, det, rng, sec, str); | |
415 | addr = ((board & 0x1f) << 7) | ((chip & 0x7) << 4) | (chan & 0xf); | |
416 | std::cout << " " | |
417 | << std::setw(3) << ddl << " | " | |
418 | << std::setfill('0') << std::hex << " 0x" | |
419 | << std::setw(2) << board << " | 0x" | |
420 | << std::setw(1) << chip << " | 0x" | |
421 | << std::setw(1) << chan << " | 0x" | |
422 | << std::setw(3) << addr << " | " | |
423 | << std::setfill(' ') << std::dec << " FMD" | |
424 | << std::setw(1) << det << rng << "[" | |
425 | << std::setw(2) << sec << "," << std::setw(3) << str | |
426 | << "]" << std::endl; | |
427 | } // for chan ... | |
428 | if (chip == 2 && *ptr >= 32) continue; | |
429 | std::cout << " + + + + + " | |
430 | << std::endl; | |
431 | } // for chip ... | |
432 | } // while board | |
433 | std::cout << "-----+-------+------+------+---------+---------------" | |
434 | << std::endl; | |
435 | } // for ddl ... | |
436 | } // if hw | |
437 | if (opt.Contains("det")) { | |
438 | std::cout << " Detector | DDL | Board | Chip | Chan | Address\n" | |
439 | << "===============+=====+=======+======+======+========" | |
440 | << std::endl; | |
441 | for (det = 1; det <= 3; det++) { | |
442 | Char_t rings[] = { 'I', (det == 1 ? '\0' : 'O'),'\0' }; | |
443 | Char_t* ptr = rings; | |
444 | while ((rng = *(ptr++)) != '\0') { | |
445 | UShort_t nsec = (rng == 'I' ? 20 : 40); | |
446 | UShort_t nstr = (rng == 'I' ? 512 : 256); | |
447 | for (sec = 0; sec < nsec; sec++) { | |
448 | for (str = 0; str < nstr; str += 128) { | |
449 | ddl = board = chip = chan; | |
450 | Detector2Hardware(det,rng,sec,str,ddl,board,chip,chan); | |
451 | addr = ((board & 0x1f) << 7) | ((chip & 0x7) << 4) | (chan & 0xf); | |
452 | std::cout << std::setfill(' ') << std::dec << " FMD" | |
453 | << std::setw(1) << det << rng << "[" | |
454 | << std::setw(2) << sec << "," | |
455 | << std::setw(3) << str << "] | " | |
456 | << std::setw(3) << ddl << " | 0x" | |
457 | << std::setfill('0') << std::hex | |
458 | << std::setw(2) << board << " | 0x" | |
459 | << std::setw(1) << chip << " | 0x" | |
460 | << std::setw(1) << chan << " | 0x" | |
461 | << std::setw(3) << addr << std::endl; | |
462 | } // for str ... | |
463 | } // for sec ... | |
464 | if (*ptr == '\0') continue; | |
465 | std::cout << " + + + + + " | |
466 | << std::endl; | |
467 | } // while rng ... | |
468 | std::cout << "---------------+-----+-------+------+------+--------" | |
469 | << std::endl; | |
470 | ||
471 | } // for det ... | |
472 | } // if det | |
473 | } | |
474 | ||
57c3c593 | 475 | //_____________________________________________________________________________ |
476 | // | |
477 | // EOF | |
478 | // |