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