]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDcalibDB.cxx
Correct implementation of SM, chamber, pad, and MCM status in digitization
[u/mrichter/AliRoot.git] / TRD / AliTRDcalibDB.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 // Class providing the calibration parameters by accessing the CDB           //
21 //                                                                           //
22 // Request an instance with AliTRDcalibDB::Instance()                        //
23 // If a new event is processed set the event number with SetRun              //
24 // Then request the calibration data                                         // 
25 //                                                                           //
26 // Author:                                                                   //
27 //   Jan Fiete Grosse-Oetringhaus (Jan.Fiete.Grosse-Oetringhaus@cern.ch)     //
28 //                                                                           //
29 ///////////////////////////////////////////////////////////////////////////////
30
31 #include <TRandom.h>
32
33 #include "AliCDBManager.h"
34 #include "AliCDBStorage.h"
35 #include "AliCDBEntry.h"
36 #include "AliLog.h"
37
38 #include "AliTRDcalibDB.h"
39 #include "AliTRDgeometry.h"
40 #include "AliTRDpadPlane.h"
41 #include "AliTRDCommonParam.h"
42
43 #include "Cal/AliTRDCalROC.h"
44 #include "Cal/AliTRDCalPad.h"
45 #include "Cal/AliTRDCalDet.h"
46 #include "Cal/AliTRDCalGlobals.h"
47 #include "Cal/AliTRDCalPIDLQ.h"
48 #include "Cal/AliTRDCalMonitoring.h"
49 #include "Cal/AliTRDCalSuperModuleStatus.h"
50 #include "Cal/AliTRDCalChamberStatus.h"
51 #include "Cal/AliTRDCalMCMStatus.h"
52 #include "Cal/AliTRDCalPadStatus.h"
53 #include "Cal/AliTRDCalSingleChamberStatus.h"
54
55 ClassImp(AliTRDcalibDB)
56
57 AliTRDcalibDB *AliTRDcalibDB::fgInstance   = 0;
58 Bool_t         AliTRDcalibDB::fgTerminated = kFALSE;
59
60 //_ singleton implementation __________________________________________________
61 AliTRDcalibDB* AliTRDcalibDB::Instance()
62 {
63   //
64   // Singleton implementation
65   // Returns an instance of this class, it is created if neccessary
66   //
67   
68   if (fgTerminated != kFALSE) {
69     return 0;
70   }
71
72   if (fgInstance == 0) {
73     fgInstance = new AliTRDcalibDB();
74   }
75
76   return fgInstance;
77
78 }
79
80 //_____________________________________________________________________________
81 void AliTRDcalibDB::Terminate()
82 {
83   //
84   // Singleton implementation
85   // Deletes the instance of this class and sets the terminated flag,
86   // instances cannot be requested anymore
87   // This function can be called several times.
88   //
89   
90   fgTerminated = kTRUE;
91   
92   if (fgInstance != 0) {
93     delete fgInstance;
94     fgInstance = 0;
95   }
96
97 }
98
99 //_____________________________________________________________________________
100 AliTRDcalibDB::AliTRDcalibDB()
101   :TObject()
102   ,fRun(-1)
103   ,fPRFsmp(0)
104   ,fPRFbin(0)
105   ,fPRFlo(0)
106   ,fPRFhi(0)
107   ,fPRFwid(0)
108   ,fPRFpad(0)
109 {
110   //
111   // Default constructor
112   //
113   // TODO Default runnumber is set to 0, this should be changed later
114   //      to an invalid value (e.g. -1) to prevent
115   // TODO invalid calibration data to be used.
116   //
117
118   for (Int_t i = 0; i < kCDBCacheSize; ++i) {
119     fCDBCache[i]   = 0;
120     fCDBEntries[i] = 0;
121   }
122   
123   // Create the sampled PRF
124   SamplePRF();
125
126 }
127
128 //_____________________________________________________________________________
129 AliTRDcalibDB::AliTRDcalibDB(const AliTRDcalibDB &c)
130   :TObject(c)
131   ,fRun(-1)
132   ,fPRFsmp(0)
133   ,fPRFbin(0)
134   ,fPRFlo(0)
135   ,fPRFhi(0)
136   ,fPRFwid(0)
137   ,fPRFpad(0)
138 {
139   //
140   // Copy constructor (not that it make any sense for a singleton...)
141   //
142
143   for (Int_t i = 0; i < kCDBCacheSize; ++i) {
144     fCDBCache[i]   = 0;
145     fCDBEntries[i] = 0;
146   }
147   
148   // Create the sampled PRF
149   SamplePRF();
150
151 }
152
153 //_____________________________________________________________________________
154 AliTRDcalibDB &AliTRDcalibDB::operator=(const AliTRDcalibDB &c) 
155 {
156   //
157   // Assignment operator (same as above ...)
158   //
159
160   if (this != &c) {
161     AliFatal("No assignment operator defined");
162   }
163
164   return *this;
165
166 }
167
168 //_____________________________________________________________________________
169 AliTRDcalibDB::~AliTRDcalibDB() 
170 {
171   //
172   // destructor
173   //
174   
175   if (fPRFsmp) {
176     delete [] fPRFsmp;
177     fPRFsmp = 0;
178   }
179
180   Invalidate();
181
182 }
183
184 //_caching functions____________________________________________________________
185 const TObject *AliTRDcalibDB::GetCachedCDBObject(Int_t id)
186 {
187   //
188   // Retrieves a cdb object with the given id. The objects are cached as
189   // long as the run number is not changed.
190   //
191   // Put together the available objects here by using the lines
192   //   a) For usual calibration objects:
193   //      case kID<Name> : 
194   //        return CacheCDBEntry(kID<Name>,"TRD/Calib/<Path>"); 
195   //        break;
196   //      See function CacheCDBEntry for details.
197   //   and
198   //   b) For calibration data which depends on two objects: One containing 
199   //      a value per detector and one the local fluctuations per pad:
200   //      case kID<Name> :
201   //        return CacheMergeCDBEntry(kID<Name>,"TRD/Calib/<padPath>","TRD/Calib/<chamberPath>"); 
202   //        break;
203   //      See function CacheMergeCDBEntry for details.
204   //
205     
206   switch (id) {
207
208     // Parameters defined per pad and chamber
209     case kIDVdriftPad : 
210       return CacheCDBEntry(kIDVdriftPad         ,"TRD/Calib/LocalVdrift"); 
211       break;
212     case kIDVdriftChamber : 
213       return CacheCDBEntry(kIDVdriftChamber     ,"TRD/Calib/ChamberVdrift"); 
214       break;
215     case kIDT0Pad : 
216       return CacheCDBEntry(kIDT0Pad             ,"TRD/Calib/LocalT0"); 
217       break;
218     case kIDT0Chamber : 
219       return CacheCDBEntry(kIDT0Chamber         ,"TRD/Calib/ChamberT0"); 
220       break;
221     case kIDGainFactorPad : 
222       return CacheCDBEntry(kIDGainFactorPad     ,"TRD/Calib/LocalGainFactor"); 
223       break;
224     case kIDGainFactorChamber : 
225       return CacheCDBEntry(kIDGainFactorChamber ,"TRD/Calib/ChamberGainFactor"); 
226       break;
227
228     // Parameters defined per pad
229     case kIDPRFWidth : 
230       return CacheCDBEntry(kIDPRFWidth          ,"TRD/Calib/PRFWidth"); 
231       break;
232
233     // Status values
234     case kIDSuperModuleStatus : 
235       return CacheCDBEntry(kIDSuperModuleStatus ,"TRD/Calib/SuperModuleStatus"); 
236       break;
237     case kIDChamberStatus : 
238       return CacheCDBEntry(kIDChamberStatus     ,"TRD/Calib/ChamberStatus"); 
239       break;
240     case kIDMCMStatus : 
241       return CacheCDBEntry(kIDMCMStatus         ,"TRD/Calib/MCMStatus"); 
242       break;
243     case kIDPadStatus : 
244       return CacheCDBEntry(kIDPadStatus         ,"TRD/Calib/PadStatus"); 
245       break;
246
247     // Global parameters
248     case kIDMonitoringData : 
249       return CacheCDBEntry(kIDMonitoringData    ,"TRD/Calib/MonitoringData"); 
250       break;
251     case kIDGlobals : 
252       return CacheCDBEntry(kIDGlobals           ,"TRD/Calib/Globals"); 
253       break;
254     case kIDPIDLQ : 
255       return CacheCDBEntry(kIDPIDLQ             ,"TRD/Calib/PIDLQ"); 
256       break;
257
258   }
259
260   return 0;
261
262 }
263
264 //_____________________________________________________________________________
265 AliCDBEntry *AliTRDcalibDB::GetCDBEntry(const char *cdbPath)
266 {
267   // 
268   // Retrieves an entry with path <cdbPath> from the CDB.
269   //
270     
271   AliCDBEntry *entry = AliCDBManager::Instance()->Get(cdbPath,fRun);
272   if (!entry) { 
273     AliError(Form("Failed to get entry: %s",cdbPath));
274     return 0; 
275   }
276   
277   return entry;
278
279 }
280
281 //_____________________________________________________________________________
282 const TObject *AliTRDcalibDB::CacheCDBEntry(Int_t id, const char *cdbPath)
283 {
284   //
285   // Caches the entry <id> with cdb path <cdbPath>
286   //
287   
288   if (!fCDBCache[id]) {
289     fCDBEntries[id] = GetCDBEntry(cdbPath);
290     if (fCDBEntries[id]) {
291       fCDBCache[id] = fCDBEntries[id]->GetObject();
292     }
293   }
294
295   return fCDBCache[id];
296
297 }
298
299 //_____________________________________________________________________________
300 void AliTRDcalibDB::SetRun(Long64_t run)
301 {
302   //
303   // Sets current run number. Calibration data is read from the corresponding file.
304   // When the run number changes the caching is invalidated.
305   //
306
307   if (fRun == run) {
308     return;
309   }
310
311   fRun = run;
312
313   Invalidate();
314
315 }
316
317 //_____________________________________________________________________________
318 void AliTRDcalibDB::Invalidate()
319 {
320   //
321   // Invalidates cache (when run number is changed).
322   //
323   
324   for (Int_t i = 0; i < kCDBCacheSize; ++i) {
325     if (fCDBEntries[i]) {
326       if (AliCDBManager::Instance()->GetCacheFlag() == kFALSE) {
327         if ((fCDBEntries[i]->IsOwner() == kFALSE) && fCDBCache[i]) {
328           delete fCDBCache[i];
329         }
330         delete fCDBEntries[i];
331       }
332       fCDBEntries[i] = 0;
333       fCDBCache[i]   = 0;
334     }
335   }
336
337 }
338
339 //_____________________________________________________________________________
340 Float_t AliTRDcalibDB::GetVdrift(Int_t det, Int_t col, Int_t row)
341 {
342   //
343   // Returns the drift velocity for the given pad.
344   //
345
346   const AliTRDCalPad *calPad     = dynamic_cast<const AliTRDCalPad *> 
347                                    (GetCachedCDBObject(kIDVdriftPad));
348   if (!calPad) {
349     return -1;
350   }
351
352   AliTRDCalROC       *roc        = calPad->GetCalROC(det);
353   if (!roc) {
354     return -1;
355   }
356
357   const AliTRDCalDet *calChamber = dynamic_cast<const AliTRDCalDet *> 
358                                    (GetCachedCDBObject(kIDVdriftChamber));
359   if (!calChamber) {
360     return -1;
361   }
362
363   return calChamber->GetValue(det) * roc->GetValue(col,row);
364
365 }
366
367 //_____________________________________________________________________________
368 Float_t AliTRDcalibDB::GetVdriftAverage(Int_t det)
369 {
370   //
371   // Returns the average drift velocity for the given detector
372   //
373
374   const AliTRDCalDet *calDet     = dynamic_cast<const AliTRDCalDet *> 
375                                    (GetCachedCDBObject(kIDVdriftChamber));
376   if (!calDet) {
377     return -1;
378   }
379
380   return calDet->GetValue(det);
381
382 }
383
384 //_____________________________________________________________________________
385 Float_t AliTRDcalibDB::GetT0(Int_t det, Int_t col, Int_t row)
386 {
387   //
388   // Returns t0 for the given pad.
389   //
390   
391   const AliTRDCalPad *calPad     = dynamic_cast<const AliTRDCalPad *> 
392                                    (GetCachedCDBObject(kIDT0Pad));
393   if (!calPad) {
394     return -1;
395   }
396
397   AliTRDCalROC       *roc        = calPad->GetCalROC(det);
398   if (!roc) {
399     return -1;
400   }
401
402   const AliTRDCalDet *calChamber = dynamic_cast<const AliTRDCalDet *> 
403                                    (GetCachedCDBObject(kIDT0Chamber));
404   if (!calChamber) {
405     return -1;
406   }
407
408   return calChamber->GetValue(det) * roc->GetValue(col,row);
409
410 }
411
412 //_____________________________________________________________________________
413 Float_t AliTRDcalibDB::GetT0Average(Int_t det)
414 {
415   //
416   // Returns the average t0 for the given detector
417   //
418
419   const AliTRDCalDet *calDet     = dynamic_cast<const AliTRDCalDet *> 
420                                    (GetCachedCDBObject(kIDT0Chamber));
421   if (!calDet) {
422     return -1;
423   }
424
425   return calDet->GetValue(det);
426
427 }
428
429 //_____________________________________________________________________________
430 Float_t AliTRDcalibDB::GetGainFactor(Int_t det, Int_t col, Int_t row)
431 {
432   //
433   // Returns the gain factor for the given pad.
434   //
435   
436   const AliTRDCalPad *calPad     = dynamic_cast<const AliTRDCalPad *> 
437                                    (GetCachedCDBObject(kIDGainFactorPad));
438   if (!calPad) {
439     return -1;
440   }
441
442   AliTRDCalROC       *roc        = calPad->GetCalROC(det);
443   if (!roc)
444     return -1;
445
446   const AliTRDCalDet *calChamber = dynamic_cast<const AliTRDCalDet *> 
447                                    (GetCachedCDBObject(kIDGainFactorChamber));
448   if (!calChamber) {
449     return -1;
450   }
451
452   return calChamber->GetValue(det) * roc->GetValue(col,row);
453
454 }
455
456 //_____________________________________________________________________________
457 Float_t AliTRDcalibDB::GetGainFactorAverage(Int_t det)
458 {
459   //
460   // Returns the average gain factor for the given detector
461   //
462
463   const AliTRDCalDet *calDet     = dynamic_cast<const AliTRDCalDet *> 
464                                    (GetCachedCDBObject(kIDGainFactorChamber));
465   if (!calDet) {
466     return -1;
467   }
468
469   return calDet->GetValue(det);
470
471 }
472
473 //_____________________________________________________________________________
474 Float_t AliTRDcalibDB::GetPRFWidth(Int_t det, Int_t col, Int_t row)
475 {
476   //
477   // Returns the PRF width for the given pad.
478   //
479   
480   const AliTRDCalPad *calPad     = dynamic_cast<const AliTRDCalPad *> 
481                                    (GetCachedCDBObject(kIDPRFWidth));
482   if (!calPad) {
483     return -1;
484   }
485
486   AliTRDCalROC       *roc        = calPad->GetCalROC(det);
487   if (!roc) {
488     return -1;
489   }
490
491   return roc->GetValue(col,row);
492
493 }
494
495 //_____________________________________________________________________________
496 Float_t AliTRDcalibDB::GetSamplingFrequency()
497 {
498   //
499   // Returns the sampling frequency of the TRD read-out.
500   //
501   
502   const AliTRDCalGlobals *calGlobal = dynamic_cast<const AliTRDCalGlobals *> 
503                                       (GetCachedCDBObject(kIDGlobals));
504   if (!calGlobal) {
505     return -1;  
506   }  
507
508   return calGlobal->GetSamplingFrequency();
509
510 }
511   
512 //_____________________________________________________________________________
513 Int_t AliTRDcalibDB::GetNumberOfTimeBins()
514 {
515   //
516   // Returns the number of time bins which are read-out.
517   //
518
519   const AliTRDCalGlobals *calGlobal = dynamic_cast<const AliTRDCalGlobals *> 
520                                       (GetCachedCDBObject(kIDGlobals));
521   if (!calGlobal) {
522     return -1;
523   }
524
525   return calGlobal->GetNumberOfTimeBins();
526
527 }
528
529 //_____________________________________________________________________________
530 Char_t AliTRDcalibDB::GetPadStatus(Int_t det, Int_t col, Int_t row)
531 {
532   //
533   // Returns the status of the given pad
534   //
535
536   const AliTRDCalPadStatus *cal     = dynamic_cast<const AliTRDCalPadStatus *> 
537                                       (GetCachedCDBObject(kIDPadStatus));
538   if (!cal) {
539     return -1;
540   }
541
542   const AliTRDCalSingleChamberStatus *roc = cal->GetCalROC(det);
543   if (!roc) {
544     return -1;
545   }
546
547   return roc->GetStatus(col,row);
548
549 }
550
551 //_____________________________________________________________________________
552 Char_t AliTRDcalibDB::GetMCMStatus(Int_t det, Int_t col, Int_t row)
553 {
554   //
555   // Returns the status of the given MCM
556   //
557
558   const AliTRDCalMCMStatus *cal     = dynamic_cast<const AliTRDCalMCMStatus *> 
559                                       (GetCachedCDBObject(kIDMCMStatus));
560   if (!cal) {
561     return -1;
562   }
563
564   return cal->GetStatus(det,col,row);
565
566 }
567
568 //_____________________________________________________________________________
569 Char_t AliTRDcalibDB::GetChamberStatus(Int_t det)
570 {
571   //
572   // Returns the status of the given chamber
573   //
574
575   const AliTRDCalChamberStatus *cal = dynamic_cast<const AliTRDCalChamberStatus *> 
576                                       (GetCachedCDBObject(kIDChamberStatus));
577   if (!cal) {
578     return -1;
579   }
580
581   return cal->GetStatus(det);
582
583 }
584
585 //_____________________________________________________________________________
586 Char_t AliTRDcalibDB::GetSuperModuleStatus(Int_t sm)
587 {
588   //
589   // Returns the status of the given chamber
590   //
591
592   const AliTRDCalSuperModuleStatus *cal = dynamic_cast<const AliTRDCalSuperModuleStatus *> 
593                                           (GetCachedCDBObject(kIDSuperModuleStatus));
594   if (!cal) {
595     return -1;
596   }
597
598   return cal->GetStatus(sm);
599
600 }
601
602 //_____________________________________________________________________________
603 Bool_t AliTRDcalibDB::IsPadMasked(Int_t det, Int_t col, Int_t row)
604 {
605   //
606   // Returns status, see name of functions for details ;-)
607   //
608
609   const AliTRDCalPadStatus         *cal = dynamic_cast<const AliTRDCalPadStatus *> 
610                                           (GetCachedCDBObject(kIDPadStatus));
611   if (!cal) {
612     return -1;
613   }
614
615   return cal->IsMasked(det,col,row);
616
617 }
618
619 //_____________________________________________________________________________
620 Bool_t AliTRDcalibDB::IsPadBridgedLeft(Int_t det, Int_t col, Int_t row)
621 {
622   //
623   // Returns status, see name of functions for details ;-)
624   //
625
626   const AliTRDCalPadStatus         *cal = dynamic_cast<const AliTRDCalPadStatus *> 
627                                           (GetCachedCDBObject(kIDPadStatus));
628   if (!cal) {
629     return -1;
630   }
631
632   return cal->IsBridgedLeft(det,col,row);
633
634 }
635
636 //_____________________________________________________________________________
637 Bool_t AliTRDcalibDB::IsPadBridgedRight(Int_t det, Int_t col, Int_t row)
638 {
639   //
640   // Returns status, see name of functions for details ;-)
641   //
642
643   const AliTRDCalPadStatus         * cal = dynamic_cast<const AliTRDCalPadStatus *> 
644                                            (GetCachedCDBObject(kIDPadStatus));
645   if (!cal) {
646     return -1;
647   }
648
649   return cal->IsBridgedRight(det,col,row);
650
651 }
652
653 //_____________________________________________________________________________
654 Bool_t AliTRDcalibDB::IsMCMMasked(Int_t det, Int_t col, Int_t row)
655 {
656   //
657   // Returns status, see name of functions for details ;-)
658   //
659
660   const AliTRDCalMCMStatus         * cal = dynamic_cast<const AliTRDCalMCMStatus *> 
661                                            (GetCachedCDBObject(kIDMCMStatus));
662   if (!cal) {
663     return -1;
664   }
665
666   return cal->IsMasked(det,col,row);
667
668 }
669
670 //_____________________________________________________________________________
671 Bool_t AliTRDcalibDB::IsChamberInstalled(Int_t det)
672 {
673   //
674   // Returns status, see name of functions for details ;-)
675   //
676
677   const AliTRDCalChamberStatus     * cal = dynamic_cast<const AliTRDCalChamberStatus *> 
678                                            (GetCachedCDBObject(kIDChamberStatus));
679   if (!cal) {
680     return -1;
681   }
682
683   return cal->IsInstalled(det);
684
685 }
686
687 //_____________________________________________________________________________
688 Bool_t AliTRDcalibDB::IsChamberMasked(Int_t det)
689 {
690   //
691   // Returns status, see name of functions for details ;-)
692   //
693
694   const AliTRDCalChamberStatus     * cal = dynamic_cast<const AliTRDCalChamberStatus *> 
695                                            (GetCachedCDBObject(kIDChamberStatus));
696   if (!cal) {
697     return -1;
698   }
699
700   return cal->IsMasked(det);
701
702 }
703
704 //_____________________________________________________________________________
705 Bool_t AliTRDcalibDB::IsSuperModuleInstalled(Int_t det)
706 {
707   //
708   // Returns status, see name of functions for details ;-)
709   //
710
711   const AliTRDCalSuperModuleStatus * cal = dynamic_cast<const AliTRDCalSuperModuleStatus *> 
712                                            (GetCachedCDBObject(kIDSuperModuleStatus));
713   if (!cal) {
714     return -1;
715   }
716
717   return cal->IsInstalled(det);
718
719 }
720
721 //_____________________________________________________________________________
722 Bool_t AliTRDcalibDB::IsSuperModuleMasked(Int_t det)
723 {
724   //
725   // Returns status, see name of functions for details ;-)
726   //
727
728   const AliTRDCalSuperModuleStatus * cal = dynamic_cast<const AliTRDCalSuperModuleStatus *> 
729                                            (GetCachedCDBObject(kIDSuperModuleStatus));
730   if (!cal) {
731     return -1;
732   }
733
734   return cal->IsMasked(det);
735
736 }
737
738 //_____________________________________________________________________________
739 const AliTRDCalPIDLQ* AliTRDcalibDB::GetPIDLQObject()
740 {
741   //
742   // Returns the object storing the distributions for PID with likelihood
743   //
744
745   return dynamic_cast<const AliTRDCalPIDLQ *> (GetCachedCDBObject(kIDPIDLQ));
746
747 }
748
749 //_____________________________________________________________________________
750 const AliTRDCalMonitoring* AliTRDcalibDB::GetMonitoringObject()
751 {
752   //
753   // Returns the object storing the monitoring data
754   //
755
756   return dynamic_cast<const AliTRDCalMonitoring *> (GetCachedCDBObject(kIDMonitoringData));
757    
758 }
759
760 //_____________________________________________________________________________
761 Float_t AliTRDcalibDB::GetOmegaTau(Float_t vdrift, Float_t bz)
762 {
763   //
764   // Returns omega*tau (tan(Lorentz-angle)) for a given drift velocity <vdrift> 
765   // and a B-field <bz> for Xe/CO2 (15%).
766   // The values are according to a GARFIELD simulation.
767   //
768   // This function basically does not belong to the calibration class.
769   // It should be moved somewhere else. 
770   // However, currently it is in use by simulation and reconstruction.
771   //
772   
773   Float_t fieldAbs = TMath::Abs(bz);
774   Float_t fieldSgn = (bz > 0.0) ? 1.0 : -1.0;
775
776   const Int_t kNb = 5;
777   Float_t p0[kNb] = {  0.004810,  0.007412,  0.010252,  0.013409,  0.016888 };
778   Float_t p1[kNb] = {  0.054875,  0.081534,  0.107333,  0.131983,  0.155455 };
779   Float_t p2[kNb] = { -0.008682, -0.012896, -0.016987, -0.020880, -0.024623 };
780   Float_t p3[kNb] = {  0.000155,  0.000238,  0.000330,  0.000428,  0.000541 };
781
782   Int_t ib = ((Int_t) (10 * (fieldAbs - 0.15)));
783   ib       = TMath::Max(  0,ib);
784   ib       = TMath::Min(kNb,ib);
785
786   Float_t alphaL = p0[ib] 
787                  + p1[ib] * vdrift
788                  + p2[ib] * vdrift*vdrift
789                  + p3[ib] * vdrift*vdrift*vdrift;
790
791   return TMath::Tan(fieldSgn * alphaL);
792
793 }
794
795 //_____________________________________________________________________________
796 void AliTRDcalibDB::SamplePRF()
797 {
798   //
799   // Samples the pad response function (should maybe go somewhere else ...)
800   //
801
802   const Int_t kPRFbin = 61;
803
804   Float_t prf[kNplan][kPRFbin] = { 
805                    {2.9037e-02, 3.3608e-02, 3.9020e-02, 4.5292e-02,
806                     5.2694e-02, 6.1362e-02, 7.1461e-02, 8.3362e-02,
807                     9.7063e-02, 1.1307e-01, 1.3140e-01, 1.5235e-01,
808                     1.7623e-01, 2.0290e-01, 2.3294e-01, 2.6586e-01,
809                     3.0177e-01, 3.4028e-01, 3.8077e-01, 4.2267e-01,
810                     4.6493e-01, 5.0657e-01, 5.4655e-01, 5.8397e-01,
811                     6.1767e-01, 6.4744e-01, 6.7212e-01, 6.9188e-01,
812                     7.0627e-01, 7.1499e-01, 7.1851e-01, 7.1499e-01,
813                     7.0627e-01, 6.9188e-01, 6.7212e-01, 6.4744e-01,
814                     6.1767e-01, 5.8397e-01, 5.4655e-01, 5.0657e-01,
815                     4.6493e-01, 4.2267e-01, 3.8077e-01, 3.4028e-01,
816                     3.0177e-01, 2.6586e-01, 2.3294e-01, 2.0290e-01,
817                     1.7623e-01, 1.5235e-01, 1.3140e-01, 1.1307e-01,
818                     9.7063e-02, 8.3362e-02, 7.1461e-02, 6.1362e-02,
819                     5.2694e-02, 4.5292e-02, 3.9020e-02, 3.3608e-02,
820                     2.9037e-02},
821                    {2.5478e-02, 2.9695e-02, 3.4655e-02, 4.0454e-02,
822                     4.7342e-02, 5.5487e-02, 6.5038e-02, 7.6378e-02,
823                     8.9696e-02, 1.0516e-01, 1.2327e-01, 1.4415e-01,
824                     1.6794e-01, 1.9516e-01, 2.2573e-01, 2.5959e-01,
825                     2.9694e-01, 3.3719e-01, 3.7978e-01, 4.2407e-01,
826                     4.6889e-01, 5.1322e-01, 5.5569e-01, 5.9535e-01,
827                     6.3141e-01, 6.6259e-01, 6.8882e-01, 7.0983e-01,
828                     7.2471e-01, 7.3398e-01, 7.3761e-01, 7.3398e-01,
829                     7.2471e-01, 7.0983e-01, 6.8882e-01, 6.6259e-01,
830                     6.3141e-01, 5.9535e-01, 5.5569e-01, 5.1322e-01,
831                     4.6889e-01, 4.2407e-01, 3.7978e-01, 3.3719e-01,
832                     2.9694e-01, 2.5959e-01, 2.2573e-01, 1.9516e-01,
833                     1.6794e-01, 1.4415e-01, 1.2327e-01, 1.0516e-01,
834                     8.9696e-02, 7.6378e-02, 6.5038e-02, 5.5487e-02,
835                     4.7342e-02, 4.0454e-02, 3.4655e-02, 2.9695e-02,
836                     2.5478e-02},
837                    {2.2363e-02, 2.6233e-02, 3.0782e-02, 3.6140e-02,
838                     4.2535e-02, 5.0157e-02, 5.9197e-02, 6.9900e-02,
839                     8.2707e-02, 9.7811e-02, 1.1548e-01, 1.3601e-01,
840                     1.5998e-01, 1.8739e-01, 2.1840e-01, 2.5318e-01,
841                     2.9182e-01, 3.3373e-01, 3.7837e-01, 4.2498e-01,
842                     4.7235e-01, 5.1918e-01, 5.6426e-01, 6.0621e-01,
843                     6.4399e-01, 6.7700e-01, 7.0472e-01, 7.2637e-01,
844                     7.4206e-01, 7.5179e-01, 7.5551e-01, 7.5179e-01,
845                     7.4206e-01, 7.2637e-01, 7.0472e-01, 6.7700e-01,
846                     6.4399e-01, 6.0621e-01, 5.6426e-01, 5.1918e-01,
847                     4.7235e-01, 4.2498e-01, 3.7837e-01, 3.3373e-01,
848                     2.9182e-01, 2.5318e-01, 2.1840e-01, 1.8739e-01,
849                     1.5998e-01, 1.3601e-01, 1.1548e-01, 9.7811e-02,
850                     8.2707e-02, 6.9900e-02, 5.9197e-02, 5.0157e-02,
851                     4.2535e-02, 3.6140e-02, 3.0782e-02, 2.6233e-02,
852                     2.2363e-02},
853                    {1.9635e-02, 2.3167e-02, 2.7343e-02, 3.2293e-02,
854                     3.8224e-02, 4.5335e-02, 5.3849e-02, 6.4039e-02,
855                     7.6210e-02, 9.0739e-02, 1.0805e-01, 1.2841e-01,
856                     1.5216e-01, 1.7960e-01, 2.1099e-01, 2.4671e-01,
857                     2.8647e-01, 3.2996e-01, 3.7660e-01, 4.2547e-01,
858                     4.7536e-01, 5.2473e-01, 5.7215e-01, 6.1632e-01,
859                     6.5616e-01, 6.9075e-01, 7.1939e-01, 7.4199e-01,
860                     7.5838e-01, 7.6848e-01, 7.7227e-01, 7.6848e-01,
861                     7.5838e-01, 7.4199e-01, 7.1939e-01, 6.9075e-01,
862                     6.5616e-01, 6.1632e-01, 5.7215e-01, 5.2473e-01,
863                     4.7536e-01, 4.2547e-01, 3.7660e-01, 3.2996e-01,
864                     2.8647e-01, 2.4671e-01, 2.1099e-01, 1.7960e-01,
865                     1.5216e-01, 1.2841e-01, 1.0805e-01, 9.0739e-02,
866                     7.6210e-02, 6.4039e-02, 5.3849e-02, 4.5335e-02,
867                     3.8224e-02, 3.2293e-02, 2.7343e-02, 2.3167e-02,
868                     1.9635e-02},
869                    {1.7224e-02, 2.0450e-02, 2.4286e-02, 2.8860e-02,
870                     3.4357e-02, 4.0979e-02, 4.8966e-02, 5.8612e-02,
871                     7.0253e-02, 8.4257e-02, 1.0102e-01, 1.2094e-01,
872                     1.4442e-01, 1.7196e-01, 2.0381e-01, 2.4013e-01,
873                     2.8093e-01, 3.2594e-01, 3.7450e-01, 4.2563e-01,
874                     4.7796e-01, 5.2991e-01, 5.7974e-01, 6.2599e-01,
875                     6.6750e-01, 7.0344e-01, 7.3329e-01, 7.5676e-01,
876                     7.7371e-01, 7.8410e-01, 7.8793e-01, 7.8410e-01,
877                     7.7371e-01, 7.5676e-01, 7.3329e-01, 7.0344e-01,
878                     6.6750e-01, 6.2599e-01, 5.7974e-01, 5.2991e-01,
879                     4.7796e-01, 4.2563e-01, 3.7450e-01, 3.2594e-01,
880                     2.8093e-01, 2.4013e-01, 2.0381e-01, 1.7196e-01,
881                     1.4442e-01, 1.2094e-01, 1.0102e-01, 8.4257e-02,
882                     7.0253e-02, 5.8612e-02, 4.8966e-02, 4.0979e-02,
883                     3.4357e-02, 2.8860e-02, 2.4286e-02, 2.0450e-02,
884                     1.7224e-02},
885                    {1.5096e-02, 1.8041e-02, 2.1566e-02, 2.5793e-02,
886                     3.0886e-02, 3.7044e-02, 4.4515e-02, 5.3604e-02,
887                     6.4668e-02, 7.8109e-02, 9.4364e-02, 1.1389e-01,
888                     1.3716e-01, 1.6461e-01, 1.9663e-01, 2.3350e-01,
889                     2.7527e-01, 3.2170e-01, 3.7214e-01, 4.2549e-01,
890                     4.8024e-01, 5.3460e-01, 5.8677e-01, 6.3512e-01,
891                     6.7838e-01, 7.1569e-01, 7.4655e-01, 7.7071e-01,
892                     7.8810e-01, 7.9871e-01, 8.0255e-01, 7.9871e-01,
893                     7.8810e-01, 7.7071e-01, 7.4655e-01, 7.1569e-01,
894                     6.7838e-01, 6.3512e-01, 5.8677e-01, 5.3460e-01,
895                     4.8024e-01, 4.2549e-01, 3.7214e-01, 3.2170e-01,
896                     2.7527e-01, 2.3350e-01, 1.9663e-01, 1.6461e-01,
897                     1.3716e-01, 1.1389e-01, 9.4364e-02, 7.8109e-02,
898                     6.4668e-02, 5.3604e-02, 4.4515e-02, 3.7044e-02,
899                     3.0886e-02, 2.5793e-02, 2.1566e-02, 1.8041e-02,
900                     1.5096e-02}};
901
902   // More sampling precision with linear interpolation
903   fPRFlo  = -1.5;
904   fPRFhi  =  1.5;
905   Float_t pad[kPRFbin];
906   Int_t   sPRFbin = kPRFbin;  
907   Float_t sPRFwid = (fPRFhi - fPRFlo) / ((Float_t) sPRFbin);
908   for (Int_t iPad = 0; iPad < sPRFbin; iPad++) {
909     pad[iPad] = ((Float_t) iPad + 0.5) * sPRFwid + fPRFlo;
910   }
911   fPRFbin = 500;  
912   fPRFwid = (fPRFhi - fPRFlo) / ((Float_t) fPRFbin);
913   fPRFpad = ((Int_t) (1.0 / fPRFwid));
914
915   if (fPRFsmp) delete [] fPRFsmp;
916   fPRFsmp = new Float_t[kNplan*fPRFbin];
917
918   Int_t   ipos1;
919   Int_t   ipos2;
920   Float_t diff;
921
922   for (Int_t iPla = 0; iPla < kNplan; iPla++) {
923
924     for (Int_t iBin = 0; iBin < fPRFbin; iBin++) {
925
926       Float_t bin = (((Float_t) iBin) + 0.5) * fPRFwid + fPRFlo;
927       ipos1 = ipos2 = 0;
928       diff  = 0;
929       do {
930         diff = bin - pad[ipos2++];
931       } while ((diff > 0) && (ipos2 < kPRFbin));
932       if      (ipos2 == kPRFbin) {
933         fPRFsmp[iPla*fPRFbin+iBin] = prf[iPla][ipos2-1];
934       }
935       else if (ipos2 == 1) {
936         fPRFsmp[iPla*fPRFbin+iBin] = prf[iPla][ipos2-1];
937       }
938       else {
939         ipos2--;
940         if (ipos2 >= kPRFbin) ipos2 = kPRFbin - 1;
941         ipos1 = ipos2 - 1;
942         fPRFsmp[iPla*fPRFbin+iBin] = prf[iPla][ipos2] 
943                                    + diff * (prf[iPla][ipos2] - prf[iPla][ipos1]) 
944                                           / sPRFwid;
945       }
946
947     }
948   } 
949
950 }
951
952 //_____________________________________________________________________________
953 Int_t AliTRDcalibDB::PadResponse(Double_t signal, Double_t dist
954                                 , Int_t plane, Double_t *pad) const
955 {
956   //
957   // Applies the pad response
958   //
959
960   Int_t iBin  = ((Int_t) (( - dist - fPRFlo) / fPRFwid));
961   Int_t iOff  = plane * fPRFbin;
962
963   Int_t iBin0 = iBin - fPRFpad + iOff;
964   Int_t iBin1 = iBin           + iOff;
965   Int_t iBin2 = iBin + fPRFpad + iOff;
966
967   pad[0] = 0.0;
968   pad[1] = 0.0;
969   pad[2] = 0.0;
970   if ((iBin1 >= 0) && (iBin1 < (fPRFbin*kNplan))) {
971
972     if (iBin0 >= 0) {
973       pad[0] = signal * fPRFsmp[iBin0];
974     }
975     pad[1] = signal * fPRFsmp[iBin1];
976     if (iBin2 < (fPRFbin*kNplan)) {
977       pad[2] = signal * fPRFsmp[iBin2];
978     }
979
980     return 1;
981
982   }
983   else {
984
985     return 0;
986
987   }
988
989 }
990