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