]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDAltroMapping.cxx
The Gain DA executable for FMD
[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//
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//____________________________________________________________________
44ClassImp(AliFMDAltroMapping)
45#if 0
46 ; // This is here to keep Emacs for indenting the next line
47#endif
48
49//_____________________________________________________________________________
50AliFMDAltroMapping::AliFMDAltroMapping()
9f662337 51{
52 // Constructor
53}
57c3c593 54
55
56//_____________________________________________________________________________
57Bool_t
58AliFMDAltroMapping::ReadMapping()
59{
9f662337 60 // Read map from file - not used
57c3c593 61 return kTRUE;
62}
63
64//_____________________________________________________________________________
573322da 65Bool_t
66AliFMDAltroMapping::CreateInvMapping()
9f662337 67{
573322da 68 // Create inverse mapping - not used
69 return kTRUE;
9f662337 70}
57c3c593 71
72//____________________________________________________________________
73Bool_t
74AliFMDAltroMapping::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//____________________________________________________________________
88Bool_t
89AliFMDAltroMapping::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//____________________________________________________________________
183Bool_t
f6449cc0 184AliFMDAltroMapping::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//____________________________________________________________________
291Bool_t
292AliFMDAltroMapping::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//____________________________________________________________________
308Int_t
573322da 309AliFMDAltroMapping::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//____________________________________________________________________
328Int_t
329AliFMDAltroMapping::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//____________________________________________________________________
350Int_t
351AliFMDAltroMapping::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//____________________________________________________________________
372Int_t
373AliFMDAltroMapping::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//____________________________________________________________________
394void
395AliFMDAltroMapping::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//