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