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