]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/FMDbase/AliFMDParameters.cxx
Debug msg
[u/mrichter/AliRoot.git] / FMD / FMDbase / 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  * $Id$ */
16 /**
17  * @file    AliFMDParameters.cxx
18  * @author  Christian Holm Christensen <cholm@nbi.dk>
19  * @date    Mon Mar 27 12:44:26 2006
20  * @brief   Manager of FMD parameters     
21  */
22 //____________________________________________________________________
23 //                                                                          
24 // Forward Multiplicity Detector based on Silicon wafers. 
25 //
26 // This class is a singleton that handles various parameters of
27 // the FMD detectors.  
28 // The manager normally serves the parameters from the Conditions
29 // Database (CDB).  These are retrivied by the member function
30 // `Init'.  Optionally, the class can serve hard-coded constants, if
31 // no CDB is available. 
32 //                                                       
33 #include "AliFMDDebug.h"                   // ALILOG_H
34 #include "AliFMDParameters.h"      // ALIFMDPARAMETERS_H
35 #include "AliFMDGeometry.h"        // ALIFMDGEOMETRY_H
36 #include "AliFMDRing.h"            // ALIFMDRING_H
37 #include "AliFMDCalibGain.h"       // ALIFMDCALIBGAIN_H
38 #include "AliFMDCalibPedestal.h"   // ALIFMDCALIBPEDESTAL_H
39 #include "AliFMDCalibSampleRate.h" // ALIFMDCALIBSAMPLERATE_H
40 #include "AliFMDCalibStripRange.h" // ALIFMDCALIBSTRIPRANGE_H
41 #include "AliFMDAltroMapping.h"    // ALIFMDALTROMAPPING_H
42 #include <AliCDBManager.h>         // ALICDBMANAGER_H
43 #include <AliCDBEntry.h>           // ALICDBMANAGER_H
44 #include <AliFMDPreprocessor.h>
45 #include <AliLog.h>
46 #include <Riostream.h>
47 #include <sstream>
48 #include <TSystem.h>
49 #include <TArrayF.h>
50 #include <TH2D.h>
51
52 //====================================================================
53 ClassImp(AliFMDParameters)
54 #if 0
55   ; // This is here to keep Emacs for indenting the next line
56 #endif
57
58 //____________________________________________________________________
59 AliFMDParameters* AliFMDParameters::fgInstance = 0;
60
61 //____________________________________________________________________
62 const char* AliFMDParameters::fgkPulseGain          = "FMD/Calib/PulseGain";
63 const char* AliFMDParameters::fgkPedestal           = "FMD/Calib/Pedestal";
64 const char* AliFMDParameters::fgkDead               = "FMD/Calib/Dead";
65 const char* AliFMDParameters::fgkSampleRate         = "FMD/Calib/SampleRate";
66 const char* AliFMDParameters::fgkAltroMap           = "FMD/Calib/AltroMap";
67 const char* AliFMDParameters::fgkZeroSuppression    = "FMD/Calib/ZeroSuppression";
68 const char* AliFMDParameters::fgkStripRange         = "FMD/Calib/StripRange";
69 const char* AliFMDParameters::fkPedestalShuttleID   = "pedestals";
70 const char* AliFMDParameters::fkGainShuttleID       = "gains";
71 const char* AliFMDParameters::fkConditionsShuttleID = "conditions";
72
73 //____________________________________________________________________
74 AliFMDParameters* 
75 AliFMDParameters::Instance() 
76 {
77   // 
78   // Get static instance 
79   //
80   if (!fgInstance) fgInstance = new AliFMDParameters;
81   return fgInstance;
82 }
83
84 //____________________________________________________________________
85 AliFMDParameters::AliFMDParameters() 
86   : fIsInit(kFALSE),
87     fkSiDeDxMip(1.664), 
88     fVA1MipRange(0),
89     fAltroChannelSize(0),
90     fChannelsPerAltro(0),
91     fPedestalFactor(0),
92     fZSPre(1),
93     fZSPost(1),
94     fZSPedSubtract(kTRUE),
95     fFixedPedestal(100),
96     fFixedPedestalWidth(2),
97     fFixedZeroSuppression(1),
98     fFixedSampleRate(2),
99     fFixedThreshold(0),
100     fFixedMinStrip(0),
101     fFixedMaxStrip(127),
102     fFixedPulseGain(2), 
103     fEdepMip(0),
104     fHasCompleteHeader(kTRUE),
105     fZeroSuppression(0), 
106     fSampleRate(0), 
107     fPedestal(0), 
108     fPulseGain(0), 
109     fDeadMap(0), 
110     fAltroMap(0), 
111   fStripRange(0),
112   fRunNo(-1)
113 {
114   //
115   // Default constructor 
116   //
117   SetVA1MipRange();
118   SetAltroChannelSize();
119   SetChannelsPerAltro();
120   SetZeroSuppression();
121   SetSampleRate();
122   SetPedestal();
123   SetPedestalWidth();
124   SetPedestalFactor();
125   SetThreshold();
126   SetStripRange();
127   SetGain();
128   fAltroMap = new AliFMDAltroMapping;
129   fAltroMap->SetBit(TObject::kCanDelete);
130 }
131
132 //__________________________________________________________________
133 Bool_t
134 AliFMDParameters::CheckForNewRun()
135 {
136   Int_t run = AliCDBManager::Instance()->GetRun();
137   if (run != fRunNo) { 
138     fIsInit = false;
139     fRunNo = run;
140   }
141   return run != fRunNo;
142 }
143
144 //__________________________________________________________________
145 UShort_t
146 AliFMDParameters::Init(Bool_t forceReInit, UInt_t what)
147 {
148   // 
149   // Initialize the manager.  This tries to read the parameters from
150   // CDB.  If that fails, the class uses the hard-coded parameters.
151   // 
152   // Parameters:
153   //    forceReInit Force (re-)initalize flag
154   //    what        What to initialize 
155   //
156   if (forceReInit) fIsInit = kFALSE;
157   CheckForNewRun();
158
159   if (fIsInit) return 0;
160
161   UShort_t errMask = 0;
162   if (what & kPulseGain)       errMask |= InitPulseGain();
163   if (what & kPedestal)        errMask |= InitPedestal();
164   if (what & kDeadMap)         errMask |= InitDeadMap();
165   if (what & kSampleRate)      errMask |= InitSampleRate();
166   if (what & kZeroSuppression) errMask |= InitZeroSuppression();
167   if (what & kAltroMap)        errMask |= InitAltroMap();
168   if (what & kStripRange)      errMask |= InitStripRange();
169   fIsInit = kTRUE;
170
171   return errMask;
172 }
173 //__________________________________________________________________
174 UShort_t
175 AliFMDParameters::Init(AliFMDPreprocessor* pp, Bool_t forceReInit, UInt_t what)
176 {
177   // 
178   // Initialize the manager.  This tries to read the parameters from
179   // CDB.  If that fails, the class uses the hard-coded parameters.
180   // 
181   // Parameters:
182   //    pp          Preprocessor 
183   //    forceReInit Force (re-)initalize flag
184   //    what        What to initialize 
185   //
186   if (forceReInit) fIsInit = kFALSE;
187   CheckForNewRun();
188
189   if (fIsInit) return 0;
190
191   UShort_t errMask = 0;
192   if (what & kPulseGain)       errMask |= InitPulseGain(pp);
193   if (what & kPedestal)        errMask |= InitPedestal(pp);
194   if (what & kDeadMap)         errMask |= InitDeadMap(pp);
195   if (what & kSampleRate)      errMask |= InitSampleRate(pp);
196   if (what & kZeroSuppression) errMask |= InitZeroSuppression(pp);
197   if (what & kAltroMap)        errMask |= InitAltroMap(pp);
198   if (what & kStripRange)      errMask |= InitStripRange(pp);
199   fIsInit = kTRUE;
200
201   return errMask;
202 }
203
204 //__________________________________________________________________
205 Bool_t
206 AliFMDParameters::CheckFile(const char* prefix, 
207                             const char* path, 
208                             int         number, 
209                             TString&    f) const
210 {
211   // 
212   // Check if the file <i>prefix</i><i>number</i> exists in @a path, 
213   // and write the full path to @a f.  
214   // 
215   // Parameters:
216   //    prefix  File prefix (cond, peds, gains, ...)
217   //    path    Path to files
218   //    number  Detector number (1, 2, or 3)
219   //    f       On return full path to file (if found)
220   // 
221   // Return:
222   //    @c true if file exists and is readable, @c false otherwise
223   //
224   f = (Form("%s%d.csv", prefix, number));
225   AliFMDDebug(5, ("Checking if %s exists in %s ...", f.Data(), path));
226   f = gSystem->Which(path, f.Data());
227   AliFMDDebug(5, ("Got back '%s'", f.Data()));
228   return !f.IsNull();
229 }
230
231 //__________________________________________________________________
232 UShort_t
233 AliFMDParameters::Init(const char* path, Bool_t forceReInit, UInt_t what)
234 {
235   // 
236   // Initialize the manager.  This will try to read some calibrations
237   // (sample rate, strip range, gains, pedestals) from local comma
238   // separated value (CSV) files in the directory pointed at by @a
239   // path.  If they are not found, then they will be retrieved from
240   // OCDB as appropriately.   Other calibrations are always read from
241   // OCDB.  
242   // 
243   // The CSV files should be named as 
244   // 
245   // - Pedestals: <tt>peds</tt><i>det_number</i><tt>.csv</tt>
246   // - Gains: <tt>gains</tt><i>det_number</i><tt>.csv</tt>
247   // - Sample Rate: <tt>conditions</tt><i>det_number</i><tt>.csv</tt>
248   // - Strip Range: <tt>conditions</tt><i>det_number</i><tt>.csv</tt>
249   //
250   // where <i>det_number</i> is the detector number (1, 2, or 3). 
251   // 
252   // Parameters:
253   //    path        Where to look for the CSV files
254   //    forceReInit Always reinitialise 
255   //    what        What calibrations to load. 
256   //  
257   if (forceReInit) fIsInit = kFALSE;
258   CheckForNewRun();
259
260   if (fIsInit) return 0;
261
262   AliFMDCalibStripRange*  range = 0;
263   AliFMDCalibSampleRate*  rate  = 0;
264   AliFMDCalibPedestal*    peds  = 0;
265   AliFMDCalibGain*        gains = 0;
266
267   for (Int_t i = 1; i <= 3; i++) { 
268     TString f;
269     if (((what & kSampleRate) || (what & kStripRange)) && 
270         CheckFile("conditions", path, i, f)) {
271       if (!rate  && (what & kSampleRate)) rate  = new AliFMDCalibSampleRate;
272       if (!range && (what & kStripRange)) range = new AliFMDCalibStripRange;
273       std::ifstream in(f.Data());
274       if (range) range->ReadFromFile(in);
275       if (rate)  rate->ReadFromFile(in);
276       in.close();
277     }
278     if ((what & kPedestal) && CheckFile("peds", path, i, f)) {
279       if (!peds) peds  = new AliFMDCalibPedestal;
280       std::ifstream in(f.Data());
281       peds->ReadFromFile(in);
282       in.close();
283     }
284     if ((what & kPulseGain) && CheckFile("gains", path, i, f)) { 
285       if (!gains) gains = new AliFMDCalibGain;
286       std::ifstream in(f.Data());
287       gains->ReadFromFile(in);
288       in.close();
289     }
290   }
291
292   if (range) what &= ~kStripRange;
293   if (rate)  what &= ~kSampleRate;
294   if (peds)  what &= ~kPedestal;
295   if (gains) what &= ~kPulseGain;
296
297   UShort_t ret = Init(kFALSE, what);
298   
299   if (range) SetStripRange(range);
300   if (rate)  SetSampleRate(rate);
301   if (peds)  SetPedestal(peds);
302   if (gains) SetGain(gains);
303
304   fIsInit = kTRUE;
305
306   return ret;
307 }
308
309 //__________________________________________________________________
310 void
311 AliFMDParameters::MakeDeadMap(Float_t maxNoise, 
312                               Float_t minGain, 
313                               Float_t maxGain)
314 {
315   // 
316   // Automatically generate a dead map from the pedestals and gains.
317   // A channel is marked as dead of the noise is too high (currently
318   // more than 10 ADC counts), or the gain is unreasonable (currently
319   // larger than 10, or smaller than 0.1). 
320   // 
321   // The procedure does not overwrite channels previously marked as
322   // dead - e.g., channels marked as dead in the calibration loaded
323   // from OCDB will continue to be marked as dead.  That is, this
324   // procedure will never make a channel un-dead. 
325   // 
326   // Parameters:
327   //    maxNoise  Maximum noise value before a channel is marked
328   // as dead. 
329   //    minGain   Minimum value of the calibrated gain before a
330   // channel is considered dead. 
331   //    maxGain   Maximum value of the calibrated gain before a
332   // channel is considered dead. 
333   //
334   if (fPedestal)  
335     fDeadMap = fPedestal->MakeDeadMap(maxNoise, fDeadMap);
336   if (fPulseGain) 
337     fDeadMap = fPulseGain->MakeDeadMap(minGain, maxGain, fDeadMap);
338 }
339 //__________________________________________________________________
340 #define DET2IDX(det,ring,sec,str) \
341   (det * 1000 + (ring == 'I' ? 0 : 512) + str)  
342   
343 //__________________________________________________________________
344 void
345 AliFMDParameters::Draw(Option_t* option)
346 {
347   // 
348   // Draw parameters. 
349   // 
350   // Parameters:
351   //    option What to draw. Should be one of 
352   // - dead       Dead channels
353   // - threshold Threshold
354   // - gain       Gain
355   // - pedestal  Pedestal
356   // - noise      Noise (or pedestal width)
357   // - zero       Zero suppression
358   // - rate       Sampling rate (VA1 clock / ALTRO clock)
359   // - min        Minimum strip read out
360   // - max        Maximum strip read out
361   // - map        hardware address
362   //
363   TString opt(option);
364   enum {
365     kLocalPulseGain,       // Path to PulseGain calib object
366     kLocalThreshold,       // Path to PulseGain calib object
367     kLocalPedestal,        // Path to Pedestal calib object
368     kLocalPedestalWidth,   // Path to Pedestal calib object
369     kLocalDead,            // Path to Dead calib object
370     kLocalSampleRate,      // Path to SampleRate calib object
371     kLocalAltroMap,        // Path to AltroMap calib object
372     kLocalZeroSuppression, // Path to ZeroSuppression cal object
373     kLocalMinStripRange,   // Path to strip range cal object
374     kLocalMaxStripRange    // Path to strip range cal object
375   } what;
376     
377   if      (opt.Contains("dead", TString::kIgnoreCase)) 
378     what = kLocalDead;
379   else if (opt.Contains("threshold",TString::kIgnoreCase)) 
380     what = kLocalThreshold;
381   else if (opt.Contains("gain",TString::kIgnoreCase)) 
382     what = kLocalPulseGain;
383   else if (opt.Contains("pedestal",TString::kIgnoreCase)) 
384     what = kLocalPedestal;
385   else if (opt.Contains("noise",TString::kIgnoreCase)) 
386     what = kLocalPedestalWidth;
387   else if (opt.Contains("zero",TString::kIgnoreCase)) 
388     what = kLocalZeroSuppression;
389   else if (opt.Contains("rate",TString::kIgnoreCase)) 
390     what = kLocalSampleRate;
391   else if (opt.Contains("min",TString::kIgnoreCase)) 
392     what = kLocalMinStripRange;
393   else if (opt.Contains("max",TString::kIgnoreCase)) 
394     what = kLocalMaxStripRange;
395   else if (opt.Contains("map",TString::kIgnoreCase)) 
396     what = kLocalAltroMap;
397   else {
398     Warning("Draw", "unknown parameter: %s\n\tShould be one of\n\t"
399             "dead, threshold, gain, pedestal, noise, zero, rate, "
400             "min, max, map",  
401             option); 
402     return;
403   }
404
405   TArrayD xbins(3 * 512 + 2 * 256 + 5);
406   Int_t i = 1;
407   Bool_t skip = kTRUE;
408   for (UShort_t det = 1; det <= 3; det++) {
409     UShort_t nRings = (det == 1 ? 1 : 2);
410     for (UShort_t iring = 0; iring < nRings; iring++) {
411       UShort_t nStrip  = (iring == 0 ? 512 : 256);
412       Char_t   ring    = (iring == 0 ? 'I' : 'O');
413       for (UShort_t str = 0; str < nStrip; str++) {
414         // UShort_t nSec    = (iring == 0 ? 20  : 40);
415         // Char_t   ring    = (iring == 0 ? 'I' : 'O');
416         // for (UShort_t sec = 0; sec < nSec; sec++) {
417         Int_t idx = DET2IDX(det, ring, 0, str);
418         // Int_t idx = DET2IDX(det, ring, sec, 0);
419         if (skip) {
420           xbins[i-1] = idx - .5;
421           skip  = kFALSE;
422         }
423         xbins[i] = idx + .5;
424         i++;
425       }
426       skip = kTRUE;
427       i++;
428     }
429   }
430   TArrayD ybins(41);
431   for (/*Int_t*/ i = 0; i < ybins.fN; i++) ybins[i] = Float_t(i - .5);
432   TH2D* hist = new TH2D("calib", Form("Calibration %s", option), 
433                         xbins.fN-1, xbins.fArray,  
434                         ybins.fN-1, ybins.fArray);
435   hist->GetXaxis()->SetTitle("1000 #times detector + 512 #times ring + strip");
436   hist->GetYaxis()->SetTitle("sector");
437   
438   // hist->Draw("Lego");
439   // return;
440   
441   for (UShort_t det = 1; det <= 3; det++) {
442     UShort_t nRings = (det == 1 ? 1 : 2);
443     for (UShort_t iring = 0; iring < nRings; iring++) {
444       UShort_t nSector = (iring == 0 ?  20 : 40);
445       UShort_t nStrip  = (iring == 0 ? 512 : 256);
446       Char_t   ring    = (iring == 0 ? 'I' : 'O');
447       for (UShort_t sec = 0; sec < nSector; sec++) {
448         for (UShort_t str = 0; str < nStrip; str++) {
449           Int_t idx = DET2IDX(det, ring, sec, str);
450           UShort_t ddl, addr, time, sam=0;
451           Double_t val = 0;
452           switch (what) {
453           case kLocalPulseGain:       // Path to PulseGain calib object
454             val = GetPulseGain(det,ring,sec,str); break;
455           case kLocalThreshold:       // Path to PulseGain calib object
456             val = GetThreshold(); break;
457           case kLocalPedestal:        // Path to Pedestal calib object
458             val = GetPedestal(det,ring,sec,str); break;
459           case kLocalPedestalWidth:   // Path to Pedestal calib object
460             val = GetPedestalWidth(det,ring,sec,str); break;
461           case kLocalDead:            // Path to Dead calib object
462             val = IsDead(det,ring,sec,str); break;
463           case kLocalSampleRate:      // Path to SampleRate calib object
464             val = GetSampleRate(det,ring,sec,str); break;
465           case kLocalAltroMap:        // Path to AltroMap calib object
466             Detector2Hardware(det,ring,sec,str,sam,ddl,addr,time); 
467             val = addr; break;
468           case kLocalZeroSuppression: // Path to ZeroSuppression cal object
469             val = GetZeroSuppression(det,ring,sec,str); break;
470           case kLocalMinStripRange:   // Path to strip range cal object
471             val = GetMinStrip(det,ring,sec,str); break;
472           case kLocalMaxStripRange:    // Path to strip range cal object
473             val = GetMaxStrip(det,ring,sec,str); break;
474           }
475           hist->Fill(idx,sec,val);
476           // hist->Fill(idx,str,val);
477         }
478       }
479     }
480   }
481   hist->Draw("lego");
482 }
483
484 //__________________________________________________________________
485 void
486 AliFMDParameters::Print(Option_t* option) const
487 {
488   // Print information. 
489   // If option contains an 'A' then everything is printed. 
490   // If the option contains the string "FMD" the function will search 
491   // for detector, ring, sector, and strip numbers to print, in the
492   // format 
493   // 
494   //    FMD<detector><ring>[<sector>,<string>] 
495   // 
496   // The wild card '*' means all of <detector>, <ring>, <sector>, or 
497   // <strip>. 
498   TString opt(option);
499   Bool_t showStrips  = opt.Contains("a", TString::kIgnoreCase);
500   UShort_t ds[]      = { 1, 2, 3, 0 };
501   Char_t   rs[]      = { 'I', 'O', '\0' };
502   UShort_t minStrip  = 0;
503   UShort_t maxStrip  = 512;
504   UShort_t minSector = 0;
505   UShort_t maxSector = 40;
506   
507   
508   if (opt.Contains("fmd",TString::kIgnoreCase)) {
509     Int_t   i    = opt.Index("fmd",TString::kIgnoreCase);
510     Int_t   j    = opt.Index("]",TString::kIgnoreCase);
511     if (j != kNPOS)
512       showStrips    = kTRUE;
513     else 
514       j = opt.Length();
515     enum {
516       kReadDet, 
517       kReadRing, 
518       kReadLbrack,
519       kReadSector,
520       kReadComma,
521       kReadStrip,
522       kReadRbrack, 
523       kEnd
524     } state = kReadDet;
525     std::stringstream s(opt(i+4, j-i-3).Data());
526     while (state != kEnd) {
527       Char_t tmp = s.peek();
528       if (tmp == ' ' || tmp == '\t') {
529         s.get();
530         continue;
531       }
532       switch (state) {
533       case kReadDet: { // First, try to kRead the detector 
534         if (tmp == '*') s.get();
535         else { 
536           UShort_t det;
537           s >> det;
538           if (!s.bad()) {
539             ds[0] = det;
540             ds[1] = 0;
541           }
542         }
543         state = (s.bad() ? kEnd : kReadRing);
544       } break;
545       case kReadRing: { // Then try to read the ring;
546         Char_t ring;
547         s >> ring;
548         if (ring != '*' && !s.bad()) {
549           rs[0] = ring;
550           rs[1] = '\0';
551         }
552         state = (s.bad() ? kEnd : kReadLbrack);
553       } break;
554       case kReadLbrack: { // Try to read a left bracket 
555         Char_t lbrack;
556         s >> lbrack;
557         state = (s.bad() ? kEnd : kReadSector);
558       } break;
559       case kReadSector: { // Try to read a sector 
560         if (tmp == '*') s.get();
561         else {
562           UShort_t sec;
563           s >> sec;
564           if (!s.bad()) {
565             minSector = sec;
566             maxSector = sec + 1;
567           }
568         }
569         state = (s.bad() ? kEnd : kReadComma);
570       } break;
571       case kReadComma: { // Try to read a left bracket 
572         Char_t comma;
573         s >> comma;
574         state = (s.bad() ? kEnd : kReadStrip);
575       } break;
576       case kReadStrip: { // Try to read a strip 
577         if (tmp == '*') s.get();
578         else {
579           UShort_t str;
580           s >> str;
581           if (!s.bad()) {
582             minStrip = str;
583             maxStrip = str + 1;
584           }
585         }
586         state = (s.bad() ? kEnd : kReadRbrack);
587       } break;
588       case kReadRbrack: { // Try to read a left bracket 
589         Char_t rbrack;
590         s >> rbrack;
591         state = kEnd;
592       } break;
593       case kEnd: 
594         break;
595       }
596     }
597   }
598   UShort_t* dp = ds;
599   UShort_t  det;
600   while ((det = *(dp++))) {
601
602     Char_t* rp = rs;
603     Char_t  ring;
604     while ((ring = *(rp++))) {
605       if (det == 1 && ring == 'O') continue;
606       UShort_t min  = GetMinStrip(det, ring, 0, 0);
607       UShort_t max  = GetMaxStrip(det, ring, 0, 0);
608       std::cout << "FMD" << det << ring 
609                 << "  Strip range: " 
610                 << std::setw(3) << min << "," 
611                 << std::setw(3) << max << std::endl;
612
613       UShort_t nSec = ( ring == 'I' ? 20  :  40 );
614       UShort_t nStr = ( ring == 'I' ? 512 : 256 );
615       for (UShort_t sec = minSector; sec < maxSector && sec < nSec; sec++) {
616
617         UShort_t rate = GetSampleRate(det, ring, sec, 0);
618         std::cout << "FMD" << det << ring << "[" << std::setw(2) << sec 
619                   << "] sample rate: " << rate << std::endl;
620
621         if (!showStrips) continue;
622         std::cout 
623           << "  Strip |     Pedestal      |    Gain    | ZS thr. | Address\n" 
624           << "--------+-------------------+------------+---------+---------" 
625           << std::endl;
626         for (UShort_t str = minStrip; str < nStr && str < maxStrip; str++) {
627           if (str == minStrip) std::cout << std::setw(3) << sec << ",";
628           else std::cout << "    ";
629           std::cout << std::setw(3) << str << " | ";
630           if (IsDead(det, ring, sec, str)) {
631             std::cout << "dead" << std::endl;
632             continue;
633           }
634           UShort_t ddl, addr, time, sam=0;
635           Detector2Hardware(det, ring, sec, str, sam, ddl, addr, time);
636           std::cout << std::setw(7) << GetPedestal(det, ring, sec, str) 
637                     << "+/-" << std::setw(7) 
638                     << GetPedestalWidth(det, ring, sec, str) 
639                     << " | " << std::setw(10) 
640                     << GetPulseGain(det, ring, sec, str) 
641                     << " | " << std::setw(7) 
642                     << GetZeroSuppression(det, ring, sec, str) 
643                     << " | 0x" << std::hex << std::setw(4) 
644                     << std::setfill('0') << ddl << ",0x" << std::setw(3) 
645                     << addr << std::dec << std::setfill(' ') << std::endl;
646         } // for (strip)
647       } // for (sector)
648       std::cout
649         << "=============================================================" 
650         << std::endl;
651     } // while (ring)
652   } // while (det)
653   
654 }
655
656 //__________________________________________________________________
657 AliCDBEntry*
658 AliFMDParameters::GetEntry(const char* path, AliFMDPreprocessor* pp, 
659                            Bool_t fatal) const
660 {
661   // 
662   // Get an entry from either global AliCDBManager or passed
663   // AliFMDPreprocessor. 
664   // 
665   // Parameters:
666   //    path  Path to CDB object. 
667   //    pp    AliFMDPreprocessor 
668   //    fatal If true, raise a fatal flag if we didn't get the entry.
669   // Return:
670   //    AliCDBEntry if found 
671   // 
672   AliCDBEntry* entry = 0;
673   if (!pp) {
674     AliCDBManager* cdb = AliCDBManager::Instance();
675     entry              = cdb->Get(path);
676   }
677   else {
678     const char* third  = gSystem->BaseName(path);
679     const char* second = gSystem->BaseName(gSystem->DirName(path));
680     entry              = pp->GetFromCDB(second, third);
681   }
682   if (!entry) { 
683     TString msg(Form("No %s found in CDB, perhaps you need to "
684                      "use AliFMDCalibFaker?", path));
685     if (fatal) { AliFatal(msg.Data()); }
686     else       AliLog::Message(AliLog::kWarning, msg.Data(), "FMD", 
687                                "AliFMDParameters", "GetEntry", __FILE__, 
688                                __LINE__);
689     return 0;
690   }
691   if (entry && AliLog::GetDebugLevel("FMD", "") > 0) { 
692     AliInfoF("Got entry %p for %s", entry, path);
693     entry->PrintId();
694     entry->PrintMetaData();                     
695     entry->Print();
696   }
697   return entry;
698 }
699
700     
701 //__________________________________________________________________
702 UShort_t
703 AliFMDParameters::InitPulseGain(AliFMDPreprocessor* pp)
704 {
705   // 
706   // Initialize gains.  Try to get them from CDB 
707   // 
708   // Parameters:
709   //    pp Pre-processor if called from shuttle
710   //
711   AliCDBEntry*   gain     = GetEntry(fgkPulseGain, pp);
712   if (!gain) return kPulseGain;
713   
714   AliFMDDebug(5, ("Got gain from CDB"));
715   fPulseGain = dynamic_cast<AliFMDCalibGain*>(gain->GetObject());
716   if (!fPulseGain) { 
717     AliError("Invalid pulser gain object from CDB");
718     return kPulseGain;
719   }
720   if (!fPulseGain->Values().Ptr()) {
721     AliError("Empty pulser gain object from CDB");
722     return kPulseGain;
723   }
724   return 0;
725 }
726 //__________________________________________________________________
727 UShort_t
728 AliFMDParameters::InitPedestal(AliFMDPreprocessor* pp)
729 {
730   //
731   // Initialize pedestals.  Try to get them from CDB
732   // 
733   // Parameters:
734   //    pp Pre-processor if called from shuttle
735   //
736   AliCDBEntry*   pedestal = GetEntry(fgkPedestal, pp);
737   if (!pedestal) return kPedestal;
738
739   AliFMDDebug(5, ("Got pedestal from CDB"));
740   fPedestal = dynamic_cast<AliFMDCalibPedestal*>(pedestal->GetObject());
741   if (!fPedestal) {
742     AliError("Invalid pedestal object from CDB");
743     return kPedestal;
744   }
745   if (!fPedestal->Values().Ptr()) {
746     AliError("Empty pedestal object from CDB");
747     return kPedestal;
748   }
749   return 0;
750 }
751
752 //__________________________________________________________________
753 UShort_t
754 AliFMDParameters::InitDeadMap(AliFMDPreprocessor* pp)
755 {
756   //
757   // Initialize dead map.  Try to get it from CDB
758   // 
759   // Parameters:
760   //    pp Pre-processor if called from shuttle
761   //
762   AliCDBEntry*   deadMap  = GetEntry(fgkDead, pp);
763   if (!deadMap) return kDeadMap;
764   
765   AliFMDDebug(5, ("Got dead map from CDB"));
766   fDeadMap = dynamic_cast<AliFMDCalibDeadMap*>(deadMap->GetObject());
767   if (!fDeadMap) { 
768     AliError("Invalid dead map object from CDB");
769     return kDeadMap;
770   }
771   if (!fDeadMap->Ptr()) {
772     AliError("Empty dead map object from CDB");
773     return kDeadMap;
774   }
775   return 0;
776 }
777
778 //__________________________________________________________________
779 UShort_t
780 AliFMDParameters::InitZeroSuppression(AliFMDPreprocessor* pp)
781 {
782   //
783   // Initialize zero suppression thresholds.  Try to get them from CDB
784   // 
785   // Parameters:
786   //    pp Pre-processor if called from shuttle
787   //
788   AliCDBEntry*   zeroSup  = GetEntry(fgkZeroSuppression, pp);
789   if (!zeroSup) return kZeroSuppression;
790
791   AliFMDDebug(5, ("Got zero suppression from CDB"));
792   fZeroSuppression = 
793     dynamic_cast<AliFMDCalibZeroSuppression*>(zeroSup->GetObject());
794   if (!fZeroSuppression) {
795     AliError("Invalid zero suppression object from CDB");
796     return kZeroSuppression;
797   }
798   if (!fZeroSuppression->Ptr()) {
799     AliWarningF("Empty zero suppression object from CDB, assuming %d",
800                 fFixedZeroSuppression);
801     AliCDBManager* cdbMan = AliCDBManager::Instance();
802     if(!cdbMan || !cdbMan->GetCacheFlag())
803       delete fZeroSuppression;
804     fZeroSuppression = 0;
805   }
806   return 0;
807 }
808
809 //__________________________________________________________________
810 UShort_t
811 AliFMDParameters::InitSampleRate(AliFMDPreprocessor* pp)
812 {
813   //
814   // Initialize sample rates.  Try to get them from CDB
815   // 
816   // Parameters:
817   //    pp Pre-processor if called from shuttle
818   //
819   AliCDBEntry*   sampRat  = GetEntry(fgkSampleRate, pp);
820   if (!sampRat) return kSampleRate;
821
822   AliFMDDebug(5, ("Got zero suppression from CDB"));
823   fSampleRate = dynamic_cast<AliFMDCalibSampleRate*>(sampRat->GetObject());
824   if (!fSampleRate) {
825     AliError("Invalid sample rate object from CDB");
826     return kSampleRate;
827   }
828   if (!fSampleRate->Rates().Ptr()) { 
829     AliError("empty sample rate object from CDB");
830     return kSampleRate;
831   }
832   return 0;
833 }
834
835 //__________________________________________________________________
836 UShort_t
837 AliFMDParameters::InitAltroMap(AliFMDPreprocessor* pp)
838 {
839   //
840   // Initialize hardware map.  Try to get it from CDB
841   // 
842   // Parameters:
843   //    pp Pre-processor if called from shuttle
844   //
845   if (fAltroMap && fAltroMap->TestBit(TObject::kCanDelete)) { 
846     delete fAltroMap;
847     fAltroMap = 0;
848   }
849   AliCDBEntry*   hwMap    = GetEntry(fgkAltroMap, pp, kFALSE);       
850   if (hwMap) {
851     AliFMDDebug(5, ("Got ALTRO map from CDB"));
852     fAltroMap = dynamic_cast<AliFMDAltroMapping*>(hwMap->GetObject());
853     if (fAltroMap) fAltroMap->ResetBit(TObject::kCanDelete);
854   }
855   if (!fAltroMap) {
856     AliError("Invalid ALTRO map object from CDB");
857     fAltroMap = new AliFMDAltroMapping;
858     fAltroMap->SetBit(TObject::kCanDelete);
859     // return kAltroMap;
860   }
861   return 0;
862 }
863
864 //__________________________________________________________________
865 UShort_t
866 AliFMDParameters::InitStripRange(AliFMDPreprocessor* pp)
867 {
868   //
869   // Initialize strip range.  Try to get it from CDB
870   // 
871   // Parameters:
872   //    pp Pre-processor if called from shuttle
873   //
874   AliCDBEntry*   range    = GetEntry(fgkStripRange, pp);
875   if (!range) return kStripRange;
876
877   AliFMDDebug(5, ("Got strip range from CDB"));
878   fStripRange = dynamic_cast<AliFMDCalibStripRange*>(range->GetObject());
879
880   if (!fStripRange) {
881     AliError("Invalid strip range object from CDB");
882     return kStripRange;
883   }
884   if (!fStripRange->Ranges().Ptr()) {
885     AliError("Empty strip range object from CDB");
886     return kStripRange;
887   }
888   return 0;
889 }
890
891
892 //__________________________________________________________________
893 Float_t
894 AliFMDParameters::GetThreshold() const
895 {
896   // 
897   // Get the threshold in the pulser gain 
898   // 
899   // 
900   // Return:
901   //    Threshold from pulser 
902   //
903   if (!fPulseGain) return fFixedThreshold;
904   return fPulseGain->Threshold();
905 }
906
907 //__________________________________________________________________
908 Float_t
909 AliFMDParameters::GetPulseGain(UShort_t detector, Char_t ring, 
910                                UShort_t sector, UShort_t strip) const
911 {
912   // 
913   // Gain of pre-amp. for strip, sector, ring, detector 
914   //
915   // For simulations this is normally set to 
916   //
917   // @f[ 
918   //  \frac{\mbox{VA1_MIP_Range}{\mbox{ALTRO_channel_size}}\mbox{MIP_Energy_Loss}
919   // @f]
920   // 
921   // 
922   // Parameters:
923   //    detector Detector # (1-3)
924   //    ring     Ring ID ('I' or 'O')
925   //    sector   Sector number (0-39)
926   //    strip    Strip number (0-511)
927   //
928   // Return:
929   //    Gain of pre-amp.  
930   //
931   if (!fPulseGain) { 
932     if (fFixedPulseGain <= 0)
933       fFixedPulseGain = fVA1MipRange * GetEdepMip() / fAltroChannelSize;
934     return fFixedPulseGain;
935   }  
936   AliFMDDebug(50, ("pulse gain for FMD%d%c[%2d,%3d]=%f",
937                     detector, ring, sector, strip,
938                     fPulseGain->Value(detector, ring, sector, strip)));
939   return fPulseGain->Value(detector, ring, sector, strip);
940 }
941
942 //__________________________________________________________________
943 Bool_t
944 AliFMDParameters::IsDead(UShort_t detector, Char_t ring, 
945                          UShort_t sector, UShort_t strip) const
946 {
947   // 
948   // Whether the strip is considered dead
949   // 
950   // Parameters:
951   //    detector Detector # (1-3)
952   //    ring     Ring ID ('I' or 'O')
953   //    sector   Sector number (0-39)
954   //    strip    Strip number (0-511)
955   //
956   // Return:
957   //    @c true if the strip is considered dead, @c false if it's
958   // OK.
959   //
960   if (!fDeadMap) return kFALSE;
961   AliFMDDebug(50, ("Dead for FMD%d%c[%2d,%3d]=%s",
962                     detector, ring, sector, strip,
963                     fDeadMap->operator()(detector, ring, sector, strip) ? 
964                     "no" : "yes"));
965   return fDeadMap->operator()(detector, ring, sector, strip);
966 }
967
968 //__________________________________________________________________
969 UShort_t
970 AliFMDParameters::GetZeroSuppression(UShort_t detector, Char_t ring, 
971                                      UShort_t sector, UShort_t strip) const
972 {
973   // 
974   // zero suppression threshold (in ADC counts)
975   // 
976   // Parameters:
977   //    detector Detector # (1-3)
978   //    ring     Ring ID ('I' or 'O')
979   //    sector   Sector number (0-39)
980   //    strip    Strip number (0-511)
981   //
982   // Return:
983   //    zero suppression threshold (in ADC counts) 
984   //
985   if (!fZeroSuppression) return fFixedZeroSuppression;
986
987   // In case of empty zero suppression objects. 
988   if (!fZeroSuppression->Ptr() || 
989       fZeroSuppression->MaxIndex() <= 0) return fFixedZeroSuppression;
990
991   // Need to map strip to ALTRO chip. 
992   AliFMDDebug(50, ("zero sup. for FMD%d%c[%2d,%3d]=%d",
993                     detector, ring, sector, strip,
994                     fZeroSuppression->operator()(detector, ring, 
995                                                  sector, strip)));
996   return fZeroSuppression->operator()(detector, ring, sector, strip/128);
997 }
998
999 //__________________________________________________________________
1000 UShort_t
1001 AliFMDParameters::GetSampleRate(UShort_t det, Char_t ring, UShort_t sector, 
1002                                 UShort_t str) const
1003 {
1004   // 
1005   // Get the sampling rate
1006   // 
1007   // Parameters:
1008   //    detector Detector # (1-3)
1009   //    ring     Ring ID ('I' or 'O')
1010   //    sector   Sector number (0-39)
1011   //    strip    Strip number (0-511)
1012   //
1013   // Return:
1014   //    The sampling rate 
1015   //
1016   if (!fSampleRate) return fFixedSampleRate;
1017   // Need to map sector to digitizier card. 
1018   UInt_t ret = fSampleRate->Rate(det, ring, sector, str);
1019   AliFMDDebug(50, ("Sample rate for FMD%d%c[%2d,%3d]=%d", 
1020                     det, ring, sector, str, ret));
1021   return ret;
1022 }
1023
1024 //__________________________________________________________________
1025 UShort_t
1026 AliFMDParameters::GetMinStrip(UShort_t det, Char_t ring, UShort_t sector, 
1027                               UShort_t str) const
1028 {
1029   // 
1030   // Get the minimum strip in the read-out range
1031   // 
1032   // Parameters:
1033   //    detector Detector # (1-3)
1034   //    ring     Ring ID ('I' or 'O')
1035   //    sector   Sector number (0-39)
1036   //    strip    Strip number (0-511)
1037   //
1038   // Return:
1039   //    Minimum strip 
1040   //
1041   if (!fStripRange) return fFixedMinStrip;
1042   // Need to map sector to digitizier card. 
1043   UInt_t ret = fStripRange->Min(det, ring, sector, str);
1044   AliFMDDebug(50, ("Min strip # for FMD%d%c[%2d,%3d]=%d", 
1045                     det, ring, sector, str, ret));
1046   return ret;
1047 }
1048
1049 //__________________________________________________________________
1050 UShort_t
1051 AliFMDParameters::GetMaxStrip(UShort_t det, Char_t ring, UShort_t sector, 
1052                               UShort_t str) const
1053 {
1054   // 
1055   // Get the maximum strip in the read-out range
1056   // 
1057   // Parameters:
1058   //    detector Detector # (1-3)
1059   //    ring     Ring ID ('I' or 'O')
1060   //    sector   Sector number (0-39)
1061   //    strip    Strip number (0-511)
1062   //
1063   // Return:
1064   //    Maximum strip 
1065   //
1066   if (!fStripRange) return fFixedMaxStrip;
1067   // Need to map sector to digitizier card. 
1068   UInt_t ret = fStripRange->Max(det, ring, sector, str);
1069   AliFMDDebug(50, ("Max strip # for FMD%d%c[%2d,%3d]=%d", 
1070                     det, ring, sector, str, ret));
1071   return ret;
1072 }
1073
1074 //__________________________________________________________________
1075 Float_t
1076 AliFMDParameters::GetPedestal(UShort_t detector, Char_t ring, 
1077                               UShort_t sector, UShort_t strip) const
1078 {
1079   // 
1080   // Get mean of pedestal
1081   // 
1082   // Parameters:
1083   //    detector Detector # (1-3)
1084   //    ring     Ring ID ('I' or 'O')
1085   //    sector   Sector number (0-39)
1086   //    strip    Strip number (0-511)
1087   //
1088   // Return:
1089   //    Mean of pedestal 
1090   //
1091   if (!fPedestal) return fFixedPedestal;
1092   AliFMDDebug(50, ("pedestal for FMD%d%c[%2d,%3d]=%f",
1093                     detector, ring, sector, strip,
1094                     fPedestal->Value(detector, ring, sector, strip)));
1095   return fPedestal->Value(detector, ring, sector, strip);
1096 }
1097
1098 //__________________________________________________________________
1099 Float_t
1100 AliFMDParameters::GetPedestalWidth(UShort_t detector, Char_t ring, 
1101                                    UShort_t sector, UShort_t strip) const
1102 {
1103   // 
1104   // Width of pedestal
1105   // 
1106   // Parameters:
1107   //    detector Detector # (1-3)
1108   //    ring     Ring ID ('I' or 'O')
1109   //    sector   Sector number (0-39)
1110   //    strip    Strip number (0-511)
1111   //
1112   // Return:
1113   //    Width of pedestal 
1114   //
1115   if (!fPedestal) return fFixedPedestalWidth;
1116   AliFMDDebug(50, ("pedetal width for FMD%d%c[%2d,%3d]=%f",
1117                     detector, ring, sector, strip,
1118                     fPedestal->Width(detector, ring, sector, strip)));
1119   return fPedestal->Width(detector, ring, sector, strip);
1120 }
1121   
1122 //__________________________________________________________________
1123 AliFMDAltroMapping*
1124 AliFMDParameters::GetAltroMap() const
1125 {
1126   // 
1127   // Get the map that translates hardware to detector coordinates 
1128   //
1129   // Return:
1130   //    Get the map that translates hardware to detector
1131   // coordinates 
1132   // 
1133   return fAltroMap;
1134 }
1135
1136
1137 //____________________________________________________________________
1138 Bool_t 
1139 AliFMDParameters::Hardware2Detector(UShort_t  ddl,       UShort_t addr,
1140                                     UShort_t  timebin,   
1141                                     UShort_t& det,       Char_t&  ring, 
1142                                     UShort_t& sec,       Short_t& str,
1143                                     UShort_t& sam) const
1144 {
1145   // 
1146   // Map a hardware address into a detector index. 
1147   // 
1148   // Parameters:
1149   //    ddl        Hardware DDL number 
1150   //    addr       Hardware address.  
1151   //    timebin    Timebin 
1152   //    det        On return, the detector #
1153   //    ring       On return, the ring ID
1154   //    sec        On return, the sector #
1155   //    str        On return, the base of strip #
1156   //    sam        On return, the sample number for this strip
1157   //
1158   // Return:
1159   //    @c true on success, false otherwise 
1160   //
1161   if (!fAltroMap) return kFALSE;
1162   UShort_t board, chip, chan;
1163   fAltroMap->ChannelAddress(addr, board, chip, chan);
1164   return Hardware2Detector(ddl,board,chip,chan,timebin,det,ring,sec,str,sam);
1165 }
1166 //____________________________________________________________________
1167 Bool_t 
1168 AliFMDParameters::Hardware2Detector(UShort_t  ddl,       UShort_t   board,
1169                                     UShort_t  chip,      UShort_t   chan,
1170                                     UShort_t  timebin,   
1171                                     UShort_t& det,       Char_t&   ring, 
1172                                     UShort_t& sec,       Short_t& str,
1173                                     UShort_t& sam) const
1174 {
1175   // 
1176   // Map a hardware address into a detector index. 
1177   // 
1178   // Parameters:
1179   //    ddl        Hardware DDL number 
1180   //    board      FEC number
1181   //    altro      ALTRO number 
1182   //    channel    Channel number 
1183   //    timebin    Timebin 
1184   //    det        On return, the detector #
1185   //    ring       On return, the ring ID
1186   //    sec        On return, the sector #
1187   //    str        On return, the base of strip #
1188   //    sam        On return, the sample number for this strip
1189   //
1190   // Return:
1191   //    @c true on success, false otherwise 
1192   //
1193   if (!fAltroMap) {
1194     AliFMDDebug(1, ("No ALTRO map available"));
1195     return kFALSE;
1196   }
1197   if (fAltroMap->DDL2Detector(ddl) < 0) { 
1198     AliFMDDebug(1, ("Invalid DDL number %d", ddl));
1199     return kFALSE;
1200   }
1201   det = fAltroMap->DDL2Detector(ddl);
1202   Short_t stripBase = 0;
1203   if (!fAltroMap->Channel2StripBase(board,chip,chan, ring, sec, stripBase)) {
1204     AliFMDDebug(1, ("Failed to translate  "
1205                     "%d/0x%02x/0x%x/0x%x/%04d -> "
1206                     "FMD%d%c[%2d,%3d] to detector", 
1207                     ddl, board, chip, chan, timebin, 
1208                     det, ring, sec, stripBase));
1209     return kFALSE;
1210   }
1211   UShort_t preSamples = GetPreSamples(det, ring, sec, stripBase);
1212   UShort_t sampleRate = GetSampleRate(det, ring, sec, stripBase);
1213   Short_t stripOff = 0;
1214   fAltroMap->Timebin2Strip(sec, timebin, preSamples, sampleRate, stripOff, sam);
1215   str = stripBase + stripOff;
1216   AliFMDDebug(50, ("%d/0x%02x/0x%x/0x%x/%04d -> FMD%d%c[%02d,%03d]-%d"
1217                   " (pre=%2d, rate=%d)", 
1218                    ddl, board, chip, chan, timebin, 
1219                    det, ring, sec, str, sam, preSamples, sampleRate));
1220   return kTRUE;
1221 }
1222
1223
1224 //____________________________________________________________________
1225 Bool_t 
1226 AliFMDParameters::Detector2Hardware(UShort_t  det,        Char_t    ring, 
1227                                     UShort_t  sec,        UShort_t  str,
1228                                     UShort_t  sam, 
1229                                     UShort_t& ddl,        UShort_t& board, 
1230                                     UShort_t& altro,      UShort_t& channel, 
1231                                     UShort_t& timebin) const
1232 {
1233   // 
1234   // Map a detector index into a hardware address. 
1235   // 
1236   // Parameters:
1237   //    det         The detector #
1238   //    ring        The ring ID
1239   //    sec         The sector #
1240   //    str         The strip #
1241   //    sam         The sample number 
1242   //    ddl         On return, hardware DDL number 
1243   //    board       On return, the FEC board address (local to DDL)
1244   //    altro       On return, the ALTRO number (local to FEC)
1245   //    channel     On return, the channel number (local to ALTRO)
1246   //    timebin     On return, the timebin number (local to ALTRO)
1247   //
1248   // Return:
1249   //    @c true on success, false otherwise 
1250   //
1251   if (!fAltroMap) { 
1252     AliFMDDebug(1, ("No ALTRO map available"));
1253     return kFALSE;
1254   }
1255   UShort_t preSamples = GetPreSamples(det, ring, sec, str);
1256   UShort_t sampleRate = GetSampleRate(det, ring, sec, str);
1257   UShort_t strip      = str - GetMinStrip(det,ring,sec,str);
1258   return fAltroMap->Detector2Hardware(det, ring, sec, strip, sam,
1259                                       preSamples, sampleRate,
1260                                       ddl, board, altro, channel, timebin);
1261 }
1262
1263   
1264
1265 //____________________________________________________________________
1266 Bool_t 
1267 AliFMDParameters::Detector2Hardware(UShort_t  det,        Char_t    ring, 
1268                                     UShort_t  sec,        UShort_t  str,
1269                                     UShort_t  sam, 
1270                                     UShort_t&   ddl,        UShort_t&   addr,
1271                                     UShort_t& timebin) const
1272 {
1273   // 
1274   // Map a detector index into a hardware address. 
1275   // 
1276   // Parameters:
1277   //    det         The detector #
1278   //    ring        The ring ID
1279   //    sec         The sector #
1280   //    str         The strip #
1281   //    sam         The sample number 
1282   //    ddl         On return, hardware DDL number 
1283   //    addr      On return, hardware address.  
1284   //    timebin     On return, the timebin number (local to ALTRO)
1285   //
1286   // Return:
1287   //    @c true on success, false otherwise 
1288   //
1289   if (!fAltroMap) return kFALSE;
1290   UShort_t preSamples = GetPreSamples(det, ring, sec, str);
1291   UShort_t sampleRate = GetSampleRate(det, ring, sec, str);
1292   UShort_t strip      = str - GetMinStrip(det,ring,sec,str);
1293   return fAltroMap->Detector2Hardware(det, ring, sec, strip, sam,
1294                                       preSamples, sampleRate,
1295                                       ddl, addr, timebin);
1296 }
1297
1298
1299 //__________________________________________________________________
1300 Float_t
1301 AliFMDParameters::GetEdepMip() const 
1302
1303   // 
1304   // Return:
1305   //    The average energy deposited by one MIP 
1306   //
1307   if (fEdepMip <= 0){
1308     AliFMDGeometry* fmd = AliFMDGeometry::Instance();
1309     fEdepMip = (fkSiDeDxMip 
1310                 * fmd->GetRing('I')->GetSiThickness() 
1311                 * fmd->GetSiDensity());
1312   }
1313   return fEdepMip;
1314 }
1315 //____________________________________________________________________
1316 Float_t  
1317 AliFMDParameters::GetDACPerMIP() const
1318 {
1319   // 
1320   // This is the conversion from Digital-to-Analog-Converter setting
1321   // to the number of MIPs. The number was measured in the NBI lab during
1322   // August 2008.
1323   //
1324   // Return:
1325   //    The conversion factor from DAC to ADC 
1326   //
1327   return 29.67;
1328   
1329 }
1330  
1331 //____________________________________________________________________
1332 //
1333 // EOF
1334 //