Non-implemented function commented out
[u/mrichter/AliRoot.git] / FMD / AliFMDParameters.cxx
CommitLineData
1a1fdef7 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// Forward Multiplicity Detector based on Silicon wafers.
21//
22// This class is a singleton that handles various parameters of
23// the FMD detectors.
088f8e79 24// Eventually, this class will use the Conditions DB to get the
25// various parameters, which code can then request from here.
1a1fdef7 26//
8f6ee336 27#include "AliLog.h" // ALILOG_H
28#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
29#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
30#include "AliFMDRing.h" // ALIFMDRING_H
31#include "AliFMDCalibGain.h" // ALIFMDCALIBGAIN_H
32#include "AliFMDCalibPedestal.h" // ALIFMDCALIBPEDESTAL_H
33#include "AliFMDCalibSampleRate.h" // ALIFMDCALIBPEDESTAL_H
1a1fdef7 34#include <Riostream.h>
35
36//====================================================================
37ClassImp(AliFMDParameters)
38#if 0
39 ; // This is here to keep Emacs for indenting the next line
40#endif
41
42//____________________________________________________________________
43AliFMDParameters* AliFMDParameters::fgInstance = 0;
44
45//____________________________________________________________________
46AliFMDParameters*
47AliFMDParameters::Instance()
48{
49 // Get static instance
50 if (!fgInstance) fgInstance = new AliFMDParameters;
51 return fgInstance;
52}
53
54//____________________________________________________________________
55AliFMDParameters::AliFMDParameters()
8f6ee336 56 : fSiDeDxMip(1.664),
57 fFixedPulseGain(0),
58 fEdepMip(0),
59 fZeroSuppression(0),
60 fSampleRate(0),
61 fPedestal(0),
62 fPulseGain(0),
63 fDeadMap(0)
1a1fdef7 64{
65 // Default constructor
66 SetVA1MipRange();
67 SetAltroChannelSize();
68 SetChannelsPerAltro();
69 SetZeroSuppression();
70 SetSampleRate();
71 SetPedestal();
72 SetPedestalWidth();
73 SetPedestalFactor();
8f6ee336 74 SetThreshold();
1a1fdef7 75}
76
8f6ee336 77//__________________________________________________________________
78Float_t
79AliFMDParameters::GetThreshold() const
80{
81 if (!fPulseGain) return fFixedThreshold;
82 return fPulseGain->Threshold();
83}
84
85//__________________________________________________________________
86Float_t
87AliFMDParameters::GetPulseGain(UShort_t detector, Char_t ring,
88 UShort_t sector, UShort_t strip) const
89{
90 // Returns the pulser calibrated gain for strip # strip in sector #
91 // sector or ring id ring of detector # detector.
92 //
93 // For simulation, this is normally set to
94 //
95 // VA1_MIP_Range
96 // ------------------ * MIP_Energy_Loss
97 // ALTRO_channel_size
98 //
99 if (!fPulseGain) {
100 if (fFixedPulseGain <= 0)
101 fFixedPulseGain = fVA1MipRange * GetEdepMip() / fAltroChannelSize;
102 return fFixedPulseGain;
103 }
104 return fPulseGain->Value(detector, ring, sector, strip);
105}
106
107//__________________________________________________________________
108Bool_t
109AliFMDParameters::IsDead(UShort_t detector, Char_t ring,
110 UShort_t sector, UShort_t strip) const
111{
112 if (!fDeadMap) return kFALSE;
113 return fDeadMap->operator()(detector, ring, sector, strip);
114}
115
116//__________________________________________________________________
117UShort_t
118AliFMDParameters::GetZeroSuppression(UShort_t detector, Char_t ring,
119 UShort_t sector, UShort_t strip) const
120{
121 if (!fZeroSuppression) return fFixedZeroSuppression;
122 // Need to map strip to ALTRO chip.
123 return fZeroSuppression->operator()(detector, ring, sector, strip/128);
124}
125
126//__________________________________________________________________
127UShort_t
128AliFMDParameters::GetSampleRate(UShort_t ddl) const
129{
130 if (!fSampleRate) return fFixedSampleRate;
131 // Need to map sector to digitizier card.
132 return fSampleRate->Rate(ddl);
133}
1a1fdef7 134
8f6ee336 135//__________________________________________________________________
136Float_t
137AliFMDParameters::GetPedestal(UShort_t detector, Char_t ring,
138 UShort_t sector, UShort_t strip) const
139{
140 if (!fPedestal) return fFixedPedestal;
141 return fPedestal->Value(detector, ring, sector, strip);
142}
143
144//__________________________________________________________________
145Float_t
146AliFMDParameters::GetPedestalWidth(UShort_t detector, Char_t ring,
147 UShort_t sector, UShort_t strip) const
148{
149 if (!fPedestal) return fFixedPedestalWidth;
150 return fPedestal->Width(detector, ring, sector, strip);
151}
152
153
1a1fdef7 154
155//__________________________________________________________________
156Float_t
157AliFMDParameters::GetEdepMip() const
158{
159 // Get energy deposited by a MIP in the silicon sensors
8f6ee336 160 if (fEdepMip <= 0){
161 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
162 fEdepMip = (fSiDeDxMip
163 * fmd->GetRing('I')->GetSiThickness()
164 * fmd->GetSiDensity());
165 }
166 return fEdepMip;
1a1fdef7 167}
168
bf000c32 169//__________________________________________________________________
170Bool_t
171AliFMDParameters::Hardware2Detector(UInt_t ddl, UInt_t addr, UShort_t& det,
172 Char_t& ring, UShort_t& sec,
173 UShort_t& str) const
174{
175 // Translate a hardware address to detector coordinates.
176 // The detector is simply
177 //
178 // ddl - kBaseDDL + 1
179 //
180 // The ring number, sector, and strip number is given by the addr
181 // argument. The address argument, has the following format
182 //
183 // 12 7 4 0
184 // +-------------+----------+----------+
185 // | Board | ALTRO | Channel |
186 // +-------------+----------+----------+
187 //
188 // The board number identifier among other things the ring. There's
189 // up to 4 boards per DDL, and the two first (0 and 1) corresponds
190 // to the inner rings, while the two last (2 and 3) corresponds to
191 // the outer rings.
192 //
193 // The board number and ALTRO number together identifies the sensor,
194 // and hence. The lower board number (0 or 2) are the first N / 2
195 // sensors (where N is the number of sensors in the ring).
196 //
197 // There are 3 ALTRO's per card, and each ALTRO serves up to 4
198 // sensors. Which of sensor is determined by the channel number.
199 // For the inner rings, the map is
200 //
201 // ALTRO 0, Channel 0 to 7 -> Sensor 0 or 5
202 // ALTRO 0, Channel 8 to 15 -> Sensor 1 or 6
203 // ALTRO 1, Channel 0 to 7 -> Sensor 2 or 7
204 // ALTRO 2, Channel 0 to 7 -> Sensor 3 or 8
205 // ALTRO 2, Channel 8 to 15 -> Sensor 4 or 9
206 //
207 // For the outer rings, the map is
208 //
209 // ALTRO 0, Channel 0 to 3 -> Sensor 0 or 10
210 // ALTRO 0, Channel 4 to 7 -> Sensor 1 or 11
211 // ALTRO 0, Channel 8 to 11 -> Sensor 2 or 12
212 // ALTRO 0, Channel 12 to 15 -> Sensor 3 or 13
213 // ALTRO 1, Channel 0 to 3 -> Sensor 4 or 14
214 // ALTRO 1, Channel 4 to 7 -> Sensor 5 or 15
215 // ALTRO 2, Channel 0 to 3 -> Sensor 6 or 16
216 // ALTRO 2, Channel 4 to 7 -> Sensor 7 or 17
217 // ALTRO 2, Channel 8 to 11 -> Sensor 8 or 18
218 // ALTRO 2, Channel 12 to 15 -> Sensor 9 or 19
219 //
220 // Which divison of the sensor we're in, depends on the channel
221 // number only. For the inner rings, the map is
222 //
223 // Channel 0 -> Sector 0, strips 0-127
224 // Channel 1 -> Sector 1, strips 0-127
225 // Channel 3 -> Sector 0, strips 128-255
226 // Channel 4 -> Sector 1, strips 128-255
227 // Channel 5 -> Sector 0, strips 256-383
228 // Channel 6 -> Sector 1, strips 256-383
229 // Channel 7 -> Sector 0, strips 384-511
230 // Channel 8 -> Sector 1, strips 384-511
231 //
232 // There are only half as many strips in the outer sensors, so there
233 // only 4 channels are used for a full sensor. The map is
234 //
235 // Channel 0 -> Sector 0, strips 0-127
236 // Channel 1 -> Sector 1, strips 0-127
237 // Channel 3 -> Sector 0, strips 128-255
238 // Channel 4 -> Sector 1, strips 128-255
239 //
240 // With this information, we can decode the hardware address to give
241 // us detector coordinates, unique at least up a 128 strips. We
242 // return the first strip in the given range.
243 //
244 det = (ddl - kBaseDDL) + 1;
245 UInt_t board = (addr >> 7) & 0x1F;
246 UInt_t altro = (addr >> 4) & 0x7;
247 UInt_t chan = (addr & 0xf);
248 if (board > 3) {
249 AliError(Form("Invalid board address %d for the FMD", board));
250 return kFALSE;
251 }
252 if (altro > 2) {
253 AliError(Form("Invalid ALTRO address %d for the FMD digitizer %d",
254 altro, board));
255 return kFALSE;
256 }
257 ring = (board > 1 ? 'O' : 'I');
258 UInt_t nsen = (ring == 'I' ? 10 : 20);
259 UInt_t nsa = (ring == 'I' ? 2 : 4); // Sensors per ALTRO
260 UInt_t ncs = (ring == 'I' ? 8 : 4); // Channels per sensor
261 UInt_t sen = (board % 2) * nsen / 2; // Base for half-ring
262 sen += chan / ncs + (altro == 0 ? 0 :
263 altro == 1 ? nsa : UInt_t(1.5 * nsa));
264 sec = 2 * sen + (chan % 2);
265 str = (chan % ncs) / 2 * 128;
266 return kTRUE;
267}
268
269//__________________________________________________________________
270Bool_t
271AliFMDParameters::Detector2Hardware(UShort_t det, Char_t ring, UShort_t sec,
272 UShort_t str, UInt_t& ddl, UInt_t& addr)
273 const
274{
275 // Translate detector coordinates to a hardware address.
276 // The ddl is simply
277 //
278 // kBaseDDL + (det - 1)
279 //
280 // The ring number, sector, and strip number must be encoded into a
281 // hardware address. The address argument, will have the following
282 // format on output
283 //
284 // 12 7 4 0
285 // +-------------+----------+----------+
286 // | Board | ALTRO | Channel |
287 // +-------------+----------+----------+
288 //
289 // The board number is given by the ring and sector. The inner
290 // rings board 0 and 1, while the outer are 2 and 3. Which of these
291 // depends on the sector. The map is
292 //
293 // Ring I, sector 0- 9 -> board 0
294 // Ring I, sector 10-19 -> board 1
295 // Ring O, sector 0-19 -> board 2
296 // Ring O, sector 20-39 -> board 3
297 //
298 // There are 3 ALTRO's per board. The ALTRO number is given by the
299 // sector number. For the inner rings, these are given by
300 //
301 // Sector 0- 3 or 10-13 -> ALTRO 0
302 // Sector 4- 5 or 14-15 -> ALTRO 1
303 // Sector 6- 9 or 16-19 -> ALTRO 2
304 //
305 // For the outers, it's given by
306 //
307 // Sector 0- 7 or 20-27 -> ALTRO 0
308 // Sector 8-11 or 28-31 -> ALTRO 1
309 // Sector 12-19 or 32-39 -> ALTRO 2
310 //
311 // The channel number is given by the sector and strip number. For
312 // the inners, the map is
313 //
314 // Sector 0, strips 0-127 -> Channel 0
315 // Sector 0, strips 128-255 -> Channel 2
316 // Sector 0, strips 256-383 -> Channel 4
317 // Sector 0, strips 384-511 -> Channel 6
318 // Sector 1, strips 0-127 -> Channel 1
319 // Sector 1, strips 128-255 -> Channel 3
320 // Sector 1, strips 256-383 -> Channel 5
321 // Sector 1, strips 384-511 -> Channel 7
322 // Sector 2, strips 0-127 -> Channel 8
323 // Sector 2, strips 128-255 -> Channel 10
324 // Sector 2, strips 256-383 -> Channel 12
325 // Sector 2, strips 384-511 -> Channel 14
326 // Sector 3, strips 0-127 -> Channel 9
327 // Sector 3, strips 128-255 -> Channel 11
328 // Sector 3, strips 256-383 -> Channel 13
329 // Sector 3, strips 384-511 -> Channel 15
330 //
331 // and so on, up to sector 19. For the outer, the map is
332 //
333 // Sector 0, strips 0-127 -> Channel 0
334 // Sector 0, strips 128-255 -> Channel 2
335 // Sector 1, strips 0-127 -> Channel 1
336 // Sector 1, strips 128-255 -> Channel 3
337 // Sector 2, strips 0-127 -> Channel 4
338 // Sector 2, strips 128-255 -> Channel 6
339 // Sector 3, strips 0-127 -> Channel 5
340 // Sector 3, strips 128-255 -> Channel 7
341 // Sector 4, strips 0-127 -> Channel 8
342 // Sector 4, strips 128-255 -> Channel 10
343 // Sector 5, strips 0-127 -> Channel 9
344 // Sector 5, strips 128-255 -> Channel 11
345 // Sector 6, strips 0-127 -> Channel 12
346 // Sector 6, strips 128-255 -> Channel 14
347 // Sector 7, strips 0-127 -> Channel 13
348 // Sector 7, strips 128-255 -> Channel 15
349 //
350 // and so on upto sector 40.
351 //
352 // With this information, we can decode the detector coordinates to
353 // give us a unique hardware address
354 //
355 ddl = kBaseDDL + (det - 1);
356 UInt_t nsen = (ring == 'I' ? 10 : 20);
357 UInt_t nsa = (ring == 'I' ? 2 : 4); // Sensors per ALTRO
358 UInt_t ncs = (ring == 'I' ? 8 : 4); // Channels per sensor
359 UInt_t bbase = (ring == 'I' ? 0 : 2);
360 UInt_t board = bbase + sec / nsen;
361 UInt_t lsen = (sec - (board - bbase) * nsen);
362 UInt_t altro = (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 1 : 2));
363 UInt_t sbase = (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 2*nsa : 3*nsa));
364 UInt_t chan = (sec % 2) + (lsen-sbase) / 2 * ncs + 2 * str / 128;
365 AliDebug(40, Form("\n"
366 " chan = (%d %% 2) + (%d-%d) / %d * %d + 2 * %d / 128\n"
367 " = %d + %d + %d = %d",
368 sec, lsen, sbase, 2, ncs, str,
369 (sec % 2), (lsen - sbase) / 2 * ncs,
370 2 * str / 128, chan));
371 addr = chan + (altro << 4) + (board << 7);
372
373 return kTRUE;
374}
375
376
377
378
1a1fdef7 379//____________________________________________________________________
380//
381// EOF
382//