]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDParameters.cxx
0. General code clean-up, including messages, and the like.
[u/mrichter/AliRoot.git] / FMD / AliFMDParameters.cxx
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.  
24 // Eventually, this class will use the Conditions DB to get the
25 // various parameters, which code can then request from here.
26 //                                                       
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
34 #include <Riostream.h>
35
36 //====================================================================
37 ClassImp(AliFMDParameters)
38 #if 0
39   ; // This is here to keep Emacs for indenting the next line
40 #endif
41
42 //____________________________________________________________________
43 AliFMDParameters* AliFMDParameters::fgInstance = 0;
44
45 //____________________________________________________________________
46 AliFMDParameters* 
47 AliFMDParameters::Instance() 
48 {
49   // Get static instance 
50   if (!fgInstance) fgInstance = new AliFMDParameters;
51   return fgInstance;
52 }
53
54 //____________________________________________________________________
55 AliFMDParameters::AliFMDParameters() 
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)
64 {
65   // Default constructor 
66   SetVA1MipRange();
67   SetAltroChannelSize();
68   SetChannelsPerAltro();
69   SetZeroSuppression();
70   SetSampleRate();
71   SetPedestal();
72   SetPedestalWidth();
73   SetPedestalFactor();
74   SetThreshold();
75 }
76
77 //__________________________________________________________________
78 Float_t
79 AliFMDParameters::GetThreshold() const
80 {
81   if (!fPulseGain) return fFixedThreshold;
82   return fPulseGain->Threshold();
83 }
84
85 //__________________________________________________________________
86 Float_t
87 AliFMDParameters::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 //__________________________________________________________________
108 Bool_t
109 AliFMDParameters::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 //__________________________________________________________________
117 UShort_t
118 AliFMDParameters::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 //__________________________________________________________________
127 UShort_t
128 AliFMDParameters::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 }
134
135 //__________________________________________________________________
136 Float_t
137 AliFMDParameters::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 //__________________________________________________________________
145 Float_t
146 AliFMDParameters::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                               
154
155 //__________________________________________________________________
156 Float_t
157 AliFMDParameters::GetEdepMip() const 
158
159   // Get energy deposited by a MIP in the silicon sensors
160   if (fEdepMip <= 0){
161     AliFMDGeometry* fmd = AliFMDGeometry::Instance();
162     fEdepMip = (fSiDeDxMip 
163                 * fmd->GetRing('I')->GetSiThickness() 
164                 * fmd->GetSiDensity());
165   }
166   return fEdepMip;
167 }
168
169 //__________________________________________________________________
170 Bool_t
171 AliFMDParameters::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 //__________________________________________________________________
270 Bool_t
271 AliFMDParameters::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   
379 //____________________________________________________________________
380 //
381 // EOF
382 //