]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/Base/AliTPCcalibDB.cxx
ATO-97, ATO-78 - implemented convolution of calibration parameters. Used in order...
[u/mrichter/AliRoot.git] / TPC / Base / AliTPCcalibDB.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
17 ///////////////////////////////////////////////////////////////////////////////
18 //                                                                           //
19 // Class providing the calibration parameters by accessing the CDB           //
20 //                                                                           //
21 // Request an instance with AliTPCcalibDB::Instance()                        //
22 // If a new event is processed set the event number with SetRun              //
23 // Then request the calibration data                                         ////
24 //
25 //
26 // Calibration data:
27 // 0.)  Altro mapping
28 //          Simulation      - not yet 
29 //          Reconstruction  - AliTPCclusterer::Digits2Clusters(AliRawReader* rawReader)
30 //
31 // 1.)  pad by pad calibration -  AliTPCCalPad
32 //      
33 //      a.) fPadGainFactor
34 //          Simulation: AliTPCDigitizer::ExecFast - Multiply by gain
35 //          Reconstruction : AliTPCclusterer::Digits2Clusters - Divide by gain  
36 //
37 //      b.) fPadNoise -
38 //          Simulation:        AliTPCDigitizer::ExecFast
39 //          Reconstruction:    AliTPCclusterer::FindClusters(AliTPCCalROC * noiseROC)
40 //                             Noise depending cut on clusters charge (n sigma)
41 //      c.) fPedestal:
42 //          Simulation:     Not used yet - To be impleneted - Rounding to the nearest integer
43 //          Reconstruction: Used in AliTPCclusterer::Digits2Clusters(AliRawReader* rawReader) 
44 //                          if data taken without zero suppression  
45 //                          Currently switch in  fRecoParam->GetCalcPedestal();
46 //      
47 //      d.) fPadTime0
48 //          Simulation:      applied in the AliTPC::MakeSector - adding offset
49 //          Reconstruction:  AliTPCTransform::Transform() - remove offset
50 //                           AliTPCTransform::Transform() - to be called
51 //                           in AliTPCtracker::Transform()      
52 //
53 // 
54 // 2.)  Space points transformation:
55 //
56 //      a.) General coordinate tranformation - AliTPCtransform (see $ALICE_ROOT/TPC/AliTPCtransform.cxx)
57 //          Created on fly - use the other calibration components
58 //                 Unisochronity  - (substract time0 - pad by pad)
59 //                 Drift velocity - Currently common drift velocity - functionality of AliTPCParam
60 //                 ExB effect    
61 //          Simulation     - Not used directly (the effects are applied one by one (see AliTPC::MakeSector)
62 //          Reconstruction - 
63 //                           AliTPCclusterer::AddCluster
64 //                           AliTPCtracker::Transform
65 //      b.) ExB effect calibration - 
66 //             classes (base class AliTPCExB, implementation- AliTPCExBExact.h  AliTPCExBFirst.h)
67 //             a.a) Simulation:   applied in the AliTPC::MakeSector - 
68 //                                calib->GetExB()->CorrectInverse(dxyz0,dxyz1);
69 //             a.b) Reconstruction -  
70 //                  
71 //                  in AliTPCtransform::Correct() - called calib->GetExB()->Correct(dxyz0,dxyz1)
72 //
73 //  3.)   cluster error, shape and Q parameterization
74 //
75 //
76 //
77 ///////////////////////////////////////////////////////////////////////////////
78
79 #include <iostream>
80 #include <fstream>
81
82
83 #include <AliCDBManager.h>
84 #include <AliCDBEntry.h>
85 #include <AliCDBId.h>
86 #include <AliLog.h>
87 #include <AliMagF.h>
88 #include <AliSplineFit.h>
89 #include <AliCTPTimeParams.h>
90
91 #include "TGraphErrors.h"
92 #include "AliTPCcalibDB.h"
93 #include "AliTPCdataQA.h"
94 #include "AliTPCcalibDButil.h"
95 #include "AliTPCAltroMapping.h"
96 #include "AliTPCExB.h"
97
98 #include "AliTPCCalROC.h"
99 #include "AliTPCCalPad.h"
100 #include "AliTPCSensorTempArray.h"
101 #include "AliGRPObject.h"
102 #include "AliTPCTransform.h"
103 #include "AliTPCmapper.h"
104
105 class AliCDBStorage;
106 class AliTPCCalDet;
107 //
108 //
109
110 #include "TFile.h"
111 #include "TKey.h"
112 #include "TGraphErrors.h"
113
114 #include "TObjArray.h"
115 #include "TObjString.h"
116 #include "TString.h"
117 #include "TDirectory.h"
118 #include "TArrayI.h"
119 #include "AliTPCCalPad.h"
120 #include "AliTPCCalibPulser.h"
121 #include "AliTPCCalibPedestal.h"
122 #include "AliTPCCalibCE.h"
123 #include "AliTPCExBFirst.h"
124 #include "AliTPCTempMap.h"
125 #include "AliTPCCalibVdrift.h"
126 #include "AliTPCCalibRaw.h"
127 #include "AliTPCParam.h"
128 #include "AliTPCCorrection.h"
129 #include "AliTPCComposedCorrection.h"
130 #include "AliTPCPreprocessorOnline.h"
131 #include "AliTimeStamp.h"
132 #include "AliTriggerRunScalers.h"
133 #include "AliTriggerScalers.h"
134 #include "AliTriggerScalersRecord.h"
135
136 ClassImp(AliTPCcalibDB)
137
138 AliTPCcalibDB* AliTPCcalibDB::fgInstance = 0;
139 Bool_t AliTPCcalibDB::fgTerminated = kFALSE;
140 TObjArray    AliTPCcalibDB::fgExBArray;    // array of ExB corrections
141
142
143 //_ singleton implementation __________________________________________________
144 AliTPCcalibDB* AliTPCcalibDB::Instance()
145 {
146   //
147   // Singleton implementation
148   // Returns an instance of this class, it is created if necessary
149   //
150   
151   if (fgTerminated != kFALSE)
152     return 0;
153
154   if (fgInstance == 0)
155     fgInstance = new AliTPCcalibDB();
156   
157   return fgInstance;
158 }
159
160 void AliTPCcalibDB::Terminate()
161 {
162   //
163   // Singleton implementation
164   // Deletes the instance of this class and sets the terminated flag, instances cannot be requested anymore
165   // This function can be called several times.
166   //
167   
168   fgTerminated = kTRUE;
169   
170   if (fgInstance != 0)
171   {
172     delete fgInstance;
173     fgInstance = 0;
174   }
175 }
176
177 //_____________________________________________________________________________
178 AliTPCcalibDB::AliTPCcalibDB():
179   TObject(),
180   fRun(-1),
181   fTransform(0),
182   fExB(0),
183   fPadGainFactor(0),
184   fActiveChannelMap(0),
185   fDedxGainFactor(0),
186   fPadTime0(0),
187   fDistortionMap(0),
188   fComposedCorrection(0),
189   fComposedCorrectionArray(0),
190   fPadNoise(0),
191   fPedestals(0),
192   fCalibRaw(0),
193   fDataQA(0),
194   fALTROConfigData(0),
195   fIonTailArray(0),
196   fPulserData(0),
197   fCEData(0),
198   fHVsensors(),
199   fGrRunState(0x0),
200   fTemperature(0),
201   fMapping(0),
202   fParam(0),
203   fClusterParam(0),
204   fRecoParamList(0),
205   fTimeGainSplines(0),
206   fTimeGainSplinesArray(1),
207   fGRPArray(1),            //! array of GRPs  -  per run  - JUST for calibration studies
208   fGRPMaps(1),            //! array of GRPs  -  per run  - JUST for calibration studies
209   fGoofieArray(1),         //! array of GOOFIE values -per run - Just for calibration studies
210   fVoltageArray(1),
211   fTemperatureArray(1),    //! array of temperature sensors - per run - Just for calibration studies
212   fVdriftArray(1),                 //! array of v drift interfaces
213   fDriftCorrectionArray(1),  //! array of drift correction
214   fRunList(1),              //! run list - indicates try to get the run param 
215   fBHasAlignmentOCDB(kFALSE),    // Flag  - has the alignment on the composed correction ?
216   fDButil(0),
217   fCTPTimeParams(0),
218   fMode(-1)
219 {
220   //
221   // constructor
222   //  
223   //
224   fgInstance=this;
225   for (Int_t i=0;i<72;++i){
226     fChamberHVStatus[i]=kTRUE;
227     fChamberHVmedian[i]=-1;
228     fCurrentNominalVoltage[i]=0.;
229     fChamberHVgoodFraction[i]=0.;
230   }
231   Update();    // temporary
232   fTimeGainSplinesArray.SetOwner(); //own the keys
233   fGRPArray.SetOwner(); //own the keys
234   fGRPMaps.SetOwner(); //own the keys
235   fGoofieArray.SetOwner(); //own the keys
236   fVoltageArray.SetOwner(); //own the keys
237   fTemperatureArray.SetOwner(); //own the keys
238   fVdriftArray.SetOwner(); //own the keys
239   fDriftCorrectionArray.SetOwner(); //own the keys
240 }
241
242 AliTPCcalibDB::AliTPCcalibDB(const AliTPCcalibDB& ):
243   TObject(),
244   fRun(-1),
245   fTransform(0),
246   fExB(0),
247   fPadGainFactor(0),
248   fActiveChannelMap(0),
249   fDedxGainFactor(0),
250   fPadTime0(0),
251   fDistortionMap(0),
252   fComposedCorrection(0),
253   fComposedCorrectionArray(0),
254   fPadNoise(0),
255   fPedestals(0),
256   fCalibRaw(0),
257   fDataQA(0),
258   fALTROConfigData(0),
259   fIonTailArray(0),
260   fPulserData(0),
261   fCEData(0),
262   fHVsensors(),
263   fGrRunState(0x0),
264   fTemperature(0),
265   fMapping(0),
266   fParam(0),
267   fClusterParam(0),
268   fRecoParamList(0),
269   fTimeGainSplines(0),
270   fTimeGainSplinesArray(1),
271   fGRPArray(0),          //! array of GRPs  -  per run  - JUST for calibration studies
272   fGRPMaps(0),          //! array of GRPs  -  per run  - JUST for calibration studies
273   fGoofieArray(0),        //! array of GOOFIE values -per run - Just for calibration studies
274   fVoltageArray(0),
275   fTemperatureArray(0),   //! array of temperature sensors - per run - Just for calibration studies
276   fVdriftArray(0),         //! array of v drift interfaces
277   fDriftCorrectionArray(0), //! array of v drift corrections
278   fRunList(0),              //! run list - indicates try to get the run param 
279   fBHasAlignmentOCDB(kFALSE),    // Flag  - has the alignment on the composed correction ?
280   fDButil(0),
281   fCTPTimeParams(0),
282   fMode(-1)
283 {
284   //
285   // Copy constructor invalid -- singleton implementation
286   //
287   Error("copy constructor","invalid -- singleton implementation");
288   for (Int_t i=0;i<72;++i){
289     fChamberHVStatus[i]=kTRUE;
290     fChamberHVmedian[i]=-1;
291     fCurrentNominalVoltage[i]=0.;
292     fChamberHVgoodFraction[i]=0.;
293   }
294   fTimeGainSplinesArray.SetOwner(); //own the keys
295   fGRPArray.SetOwner(); //own the keys
296   fGRPMaps.SetOwner(); //own the keys
297   fGoofieArray.SetOwner(); //own the keys
298   fVoltageArray.SetOwner(); //own the keys
299   fTemperatureArray.SetOwner(); //own the keys
300   fVdriftArray.SetOwner(); //own the keys
301   fDriftCorrectionArray.SetOwner(); //own the keys
302 }
303
304 AliTPCcalibDB& AliTPCcalibDB::operator= (const AliTPCcalibDB& )
305 {
306 //
307 // Singleton implementation - no assignment operator
308 //
309   Error("operator =", "assignment operator not implemented");
310   return *this;
311 }
312
313
314
315 //_____________________________________________________________________________
316 AliTPCcalibDB::~AliTPCcalibDB() 
317 {
318   //
319   // destructor
320   //
321   //delete fIonTailArray; 
322   delete fActiveChannelMap;
323   delete fGrRunState;
324   fgInstance = 0;
325 }
326
327 AliTPCCalPad* AliTPCcalibDB::GetDistortionMap(Int_t i) const {
328   //
329   // get distortion map - due E field distortions
330   //
331   return (fDistortionMap) ? (AliTPCCalPad*)fDistortionMap->At(i):0;
332 }
333
334 AliTPCRecoParam* AliTPCcalibDB::GetRecoParam(Int_t i) const {
335   return (fRecoParamList) ? (AliTPCRecoParam*)fRecoParamList->At(i):0;
336 }
337
338 //_____________________________________________________________________________
339 AliCDBEntry* AliTPCcalibDB::GetCDBEntry(const char* cdbPath)
340 {
341   // 
342   // Retrieves an entry with path <cdbPath> from the CDB.
343   //
344   char chinfo[1000];
345     
346   AliCDBEntry* entry = AliCDBManager::Instance()->Get(cdbPath, fRun); 
347   if (!entry) 
348   { 
349     snprintf(chinfo,1000,"AliTPCcalibDB: Failed to get entry:\t%s ", cdbPath);
350     AliError(chinfo); 
351     return 0; 
352   }
353   return entry;
354 }
355
356
357 //_____________________________________________________________________________
358 void AliTPCcalibDB::SetRun(Long64_t run)
359 {
360   //
361   // Sets current run number. Calibration data is read from the corresponding file. 
362   //  
363   if (fRun == run)
364     return;  
365         fRun = run;
366   Update();
367 }
368   
369
370
371 void AliTPCcalibDB::Update(){
372   //
373   // cache the OCDB entries for simulation, reconstruction, calibration
374   //  
375   //
376   AliCDBEntry * entry=0;
377   Bool_t cdbCache = AliCDBManager::Instance()->GetCacheFlag(); // save cache status
378   AliCDBManager::Instance()->SetCacheFlag(kTRUE); // activate CDB cache
379   fDButil = new AliTPCcalibDButil;   
380   //
381   fRun = AliCDBManager::Instance()->GetRun();
382
383   entry          = GetCDBEntry("TPC/Calib/PadGainFactor");
384   if (entry){
385     //if (fPadGainFactor) delete fPadGainFactor;
386     entry->SetOwner(kTRUE);
387     fPadGainFactor = (AliTPCCalPad*)entry->GetObject();
388   }else{
389     AliFatal("TPC - Missing calibration entry TPC/Calib/PadGainFactor");
390   }
391   //
392   entry          = GetCDBEntry("TPC/Calib/TimeGain");
393   if (entry){
394     //if (fTimeGainSplines) delete fTimeGainSplines;
395     entry->SetOwner(kTRUE);
396     fTimeGainSplines = (TObjArray*)entry->GetObject();
397   }else{
398     AliFatal("TPC - Missing calibration entry TPC/Calib/Timegain");
399   }
400   //
401   entry          = GetCDBEntry("TPC/Calib/GainFactorDedx");
402   if (entry){
403     entry->SetOwner(kTRUE);
404     fDedxGainFactor = (AliTPCCalPad*)entry->GetObject();
405   }else{
406     AliFatal("TPC - Missing calibration entry TPC/Calib/gainFactordEdx");
407   }
408   //
409   entry          = GetCDBEntry("TPC/Calib/PadTime0");
410   if (entry){
411     //if (fPadTime0) delete fPadTime0;
412     entry->SetOwner(kTRUE);
413     fPadTime0 = (AliTPCCalPad*)entry->GetObject();
414   }else{
415     AliFatal("TPC - Missing calibration entry");
416   }
417
418   entry          = GetCDBEntry("TPC/Calib/Distortion");
419   if (entry){
420     //if (fPadTime0) delete fPadTime0;
421     entry->SetOwner(kTRUE);
422     fDistortionMap =dynamic_cast<TObjArray*>(entry->GetObject());
423   }else{
424     //AliFatal("TPC - Missing calibration entry")
425   }
426
427
428   //
429   //
430   entry          = GetCDBEntry("TPC/Calib/PadNoise");
431   if (entry){
432     //if (fPadNoise) delete fPadNoise;
433     entry->SetOwner(kTRUE);
434     fPadNoise = (AliTPCCalPad*)entry->GetObject();
435   }else{
436     AliFatal("TPC - Missing calibration entry");
437   }
438
439   entry          = GetCDBEntry("TPC/Calib/Pedestals");
440   if (entry){
441     //if (fPedestals) delete fPedestals;
442     entry->SetOwner(kTRUE);
443     fPedestals = (AliTPCCalPad*)entry->GetObject();
444   }
445
446   entry          = GetCDBEntry("TPC/Calib/Temperature");
447   if (entry){
448     //if (fTemperature) delete fTemperature;
449     entry->SetOwner(kTRUE);
450     fTemperature = (AliTPCSensorTempArray*)entry->GetObject();
451   }
452
453   entry          = GetCDBEntry("TPC/Calib/Parameters");
454   if (entry){
455     //if (fPadNoise) delete fPadNoise;
456     entry->SetOwner(kTRUE);
457     fParam = (AliTPCParam*)(entry->GetObject());
458   }else{
459     AliFatal("TPC - Missing calibration entry TPC/Calib/Parameters");
460   }
461
462   entry          = GetCDBEntry("TPC/Calib/ClusterParam");
463   if (entry){
464     entry->SetOwner(kTRUE);
465     fClusterParam = (AliTPCClusterParam*)(entry->GetObject());
466   }else{
467     AliFatal("TPC - Missing calibration entry");
468   }
469
470   entry          = GetCDBEntry("TPC/Calib/RecoParam");
471   if (entry){
472     //PH    entry->SetOwner(kTRUE);
473     fRecoParamList = dynamic_cast<TObjArray*>(entry->GetObject());
474
475   }else{
476     AliFatal("TPC - Missing calibration entry TPC/Calib/RecoParam");
477   }
478
479
480   //ALTRO configuration data
481   entry          = GetCDBEntry("TPC/Calib/AltroConfig");
482   if (entry){
483     entry->SetOwner(kTRUE);
484     fALTROConfigData=(TObjArray*)(entry->GetObject());
485   }else{
486     AliFatal("TPC - Missing calibration entry");
487   }
488   
489   //Calibration Pulser data
490   entry          = GetCDBEntry("TPC/Calib/Pulser");
491   if (entry){
492     entry->SetOwner(kTRUE);
493     fPulserData=(TObjArray*)(entry->GetObject());
494   }
495   
496   //Calibration ION tail data
497   entry          = GetCDBEntry("TPC/Calib/IonTail");
498   if (entry){
499     //delete fIonTailArray; fIonTailArray=NULL;
500     entry->SetOwner(kTRUE);
501      fIonTailArray=(TObjArray*)(entry->GetObject());
502      fIonTailArray->SetOwner(); //own the keys
503   }
504   
505   //CE data
506   entry          = GetCDBEntry("TPC/Calib/CE");
507   if (entry){
508     entry->SetOwner(kTRUE);
509     fCEData=(TObjArray*)(entry->GetObject());
510   }
511   //RAW calibration data
512  //  entry          = GetCDBEntry("TPC/Calib/Raw");
513
514   entry          = GetCDBEntry("TPC/Calib/Mapping");
515   if (entry){
516     //if (fPadNoise) delete fPadNoise;
517     entry->SetOwner(kTRUE);
518     TObjArray * array = dynamic_cast<TObjArray*>(entry->GetObject());
519     if (array && array->GetEntriesFast()==6){
520       fMapping = new AliTPCAltroMapping*[6];
521       for (Int_t i=0; i<6; i++){
522         fMapping[i] =  dynamic_cast<AliTPCAltroMapping*>(array->At(i));
523       }
524     }
525   }
526
527   //CTP calibration data
528   entry          = GetCDBEntry("GRP/CTP/CTPtiming");
529   if (entry){
530     //entry->SetOwner(kTRUE);
531     fCTPTimeParams=dynamic_cast<AliCTPTimeParams*>(entry->GetObject());
532   }else{
533     AliError("TPC - Missing calibration entry");
534   }  
535   //TPC space point correction data
536   entry          = GetCDBEntry("TPC/Calib/Correction");
537   if (entry){
538     //entry->SetOwner(kTRUE);
539     fComposedCorrection=dynamic_cast<AliTPCCorrection*>(entry->GetObject());
540     if (fComposedCorrection) fComposedCorrection->Init();
541     fComposedCorrectionArray=dynamic_cast<TObjArray*>(entry->GetObject());
542     if (fComposedCorrectionArray){
543       for (Int_t i=0; i<fComposedCorrectionArray->GetEntries(); i++){
544         AliTPCComposedCorrection* composedCorrection= dynamic_cast<AliTPCComposedCorrection*>(fComposedCorrectionArray->At(i));
545         if (composedCorrection) {
546           composedCorrection->Init();
547           if (composedCorrection->GetCorrections()){
548             if (composedCorrection->GetCorrections()->FindObject("FitAlignTPC")){
549               fBHasAlignmentOCDB=kTRUE;
550             }
551           }
552         }
553       }
554     }  
555   }else{
556     AliError("TPC - Missing calibration entry-  TPC/Calib/Correction");
557   } 
558   //RCU trigger config mode
559   fMode=GetRCUTriggerConfig();
560   //
561   if (!fTransform) {
562     fTransform=new AliTPCTransform(); 
563     fTransform->SetCurrentRun(AliCDBManager::Instance()->GetRun());
564   }
565
566   // Chamber HV data
567   // needs to be called before InitDeadMap
568   UpdateChamberHighVoltageData();
569   
570   // Create Dead Channel Map
571   InitDeadMap();
572
573   //
574   AliCDBManager::Instance()->SetCacheFlag(cdbCache); // reset original CDB cache
575 }
576
577 void AliTPCcalibDB::UpdateNonRec(){
578   //
579   // Update/Load the parameters which are important for QA studies
580   // and not used yet for the reconstruction
581   //
582    //RAW calibration data
583   AliCDBEntry * entry=0;
584   entry          = GetCDBEntry("TPC/Calib/Raw");
585   if (entry){
586     entry->SetOwner(kTRUE);
587     TObjArray *arr=dynamic_cast<TObjArray*>(entry->GetObject());
588     if (arr) fCalibRaw=(AliTPCCalibRaw*)arr->At(0);
589     else fCalibRaw = (AliTPCCalibRaw*)(entry->GetObject());
590   }
591   //QA calibration data
592   entry          = GetCDBEntry("TPC/Calib/QA");
593   if (entry){
594     entry->SetOwner(kTRUE);
595     fDataQA=dynamic_cast<AliTPCdataQA*>(entry->GetObject());
596   }
597   // High voltage
598   if (fRun>=0 && !fVoltageArray.GetValue(Form("%i",fRun))){
599     entry = AliCDBManager::Instance()->Get("TPC/Calib/HighVoltage",fRun);
600     if (entry)  {
601       fVoltageArray.Add(new TObjString(Form("%i",fRun)),entry->GetObject());
602     }
603   }
604
605 }
606
607 Bool_t AliTPCcalibDB::GetTailcancelationGraphs(Int_t sector, TGraphErrors ** graphRes, Float_t * indexAmpGraphs){
608  
609 // 
610 //   Read OCDB entry object of Iontail (TObjArray of TGraphErrors of TRFs)
611 //   Naming of the TRF objects is: "gr_<chamber_type>_<voltage>_<laser_track_angle>_<distance_to_COG>" --> "gr_iroc_1240_1_1" 
612 //   
613   
614   //Int_t run = fTransform->GetCurrentRunNumber();
615   //SetRun(run);
616   //Float_t rocVoltage = GetChamberHighVoltage(run,sector, -1);      // Get the voltage from OCDB with a getter (old function)
617 //   Float_t rocVoltage=GetChamberHighVoltageMedian(sector);                      // Get the voltage from OCDB, new function from Jens
618  
619   Int_t nominalVoltage = (sector<36) ? 1240 : 1470 ;     // nominal voltage of 2012 when the TRF functions were produced
620
621   Float_t rocVoltage = nominalVoltage;
622
623   if ( rocVoltage < nominalVoltage/2. || rocVoltage > nominalVoltage*2. )
624   {
625     AliInfo(Form("rocVoltage out of range: roc: %.2f, nominal: %i", rocVoltage, nominalVoltage));
626     return kFALSE;
627   }
628
629   Int_t tempVoltage = 0;                                 
630   Int_t trackAngle  = 4;                                 // (1=first, 2=second, 3=third, 4=first+second, 5=all tracks) note: 3rd is distorted by low freq
631   TString rocType   = (sector<36) ? "iroc" : "oroc";     
632   const Int_t ngraph=fIonTailArray->GetLast();
633   
634   // create array of voltages in order to select the proper TRF with closest voltage  
635   Int_t voltages[ngraph];     // array of voltages
636   for (Int_t i=0; i<ngraph; i++){
637     voltages[i]=0;
638   }
639     
640   // loop over response functions in the TObjarray
641   Int_t nvoltages=0;
642   for (Int_t i=0;i<=ngraph;i++){
643     
644     // read the TRF object name in order to select proper TRF for the given sector
645     TString objname(fIonTailArray->At(i)->GetName());
646     if (!objname.Contains(rocType)) continue;
647
648     TObjArray *objArr = objname.Tokenize("_");
649     
650     // select the roc type (IROC or OROC) and the trackAngle
651     if ( atoi(static_cast<TObjString*>(objArr->At(3))->GetName())==trackAngle )
652     { 
653       // Create the voltage array for proper voltage value selection
654       voltages[nvoltages]=atoi(static_cast<TObjString*>(objArr->At(2))->GetName());
655       nvoltages++;
656     }
657     delete objArr;
658   }
659     
660   // find closest voltage value to ROC voltage (among the TRF' voltage array --> to select proper t.r.f.)
661   Int_t ampIndex     = 0;
662   Int_t diffVoltage  = TMath::Abs(rocVoltage - voltages[0]);
663   for (Int_t k=0;k<ngraph;k++) {
664     if (diffVoltage >= TMath::Abs(rocVoltage-voltages[k]) && voltages[k]!=0)
665       {
666         diffVoltage    = TMath::Abs(rocVoltage-voltages[k]);
667         ampIndex   = k;
668       }     
669   }
670   tempVoltage = voltages[ampIndex];    // use closest voltage to current voltage
671   //if (run<140000) tempVoltage = nominalVoltage;    // for 2010 data
672   
673   // assign TGraphErrors   
674   Int_t igraph=0;
675   for (Int_t i=0; i<=ngraph; i++){
676    
677     // read TRFs for TObjArray and select the roc type (IROC or OROC) and the trackAngle
678     TGraphErrors * trfObj = static_cast<TGraphErrors*>(fIonTailArray->At(i));
679     TString objname(trfObj->GetName());
680     if (!objname.Contains(rocType)) continue; //choose ROC type
681     
682     TObjArray *objArr1 = objname.Tokenize("_");
683      
684     // TRF eleminations
685     TObjString* angleString = static_cast<TObjString*>(objArr1->At(3));
686     TObjString* voltageString = static_cast<TObjString*>(objArr1->At(2));
687     //choose angle and voltage
688     if ((atoi(angleString->GetName())==trackAngle) && (atoi(voltageString->GetName())==tempVoltage) )
689     {
690       // Apply Voltage scaling
691       Int_t voltage       = atoi(voltageString->GetName());
692       Double_t voltageScaled = 1;
693       if (rocVoltage>0)  voltageScaled = Double_t(voltage)/Double_t(rocVoltage); // for jens how it can happen that we have clusters at 0 HV ?
694       const Int_t nScaled          = TMath::Nint(voltageScaled*trfObj->GetN())-1; 
695       Double_t x;
696       Double_t y;
697       
698       delete graphRes[igraph];
699       graphRes[igraph]       = new TGraphErrors(nScaled);
700       
701       for (Int_t j=0; j<nScaled; j++){
702         x = TMath::Nint(j*(voltageScaled));
703         y = (j<trfObj->GetN()) ? (1./voltageScaled)*trfObj->GetY()[j] : 0.;
704         graphRes[igraph]->SetPoint(j,x,y);
705       }
706
707       // fill arrays for proper position and amplitude selections
708       TObjString* distanceToCenterOfGravity = static_cast<TObjString*>(objArr1->At(4));
709       indexAmpGraphs[igraph] = (distanceToCenterOfGravity->GetString().Atof())/10.;
710       // smooth voltage scaled graph 
711       for (Int_t m=1; m<nScaled;m++){
712         if (graphRes[igraph]->GetY()[m]==0) graphRes[igraph]->GetY()[m] = graphRes[igraph]->GetY()[m-1];
713       }
714       igraph++;
715     }
716   delete objArr1;
717   }
718   return kTRUE;
719 }
720
721 void AliTPCcalibDB::CreateObjectList(const Char_t *filename, TObjArray *calibObjects)
722 {
723 //
724 // Create calibration objects and read contents from OCDB
725 //
726    if ( calibObjects == 0x0 ) return;
727    ifstream in;
728    in.open(filename);
729    if ( !in.is_open() ){
730       fprintf(stderr,"Error: cannot open list file '%s'", filename);
731       return;
732    }
733    
734    AliTPCCalPad *calPad=0x0;
735    
736    TString sFile;
737    sFile.ReadFile(in);
738    in.close();
739    
740    TObjArray *arrFileLine = sFile.Tokenize("\n");
741    
742    TIter nextLine(arrFileLine);
743    
744    TObjString *sObjLine=0x0;
745    while ( (sObjLine = (TObjString*)nextLine()) ){
746       TString sLine(sObjLine->GetString());
747       
748       TObjArray *arrNextCol = sLine.Tokenize("\t");
749       
750       TObjString *sObjType     = (TObjString*)(arrNextCol->At(0));
751       TObjString *sObjFileName = (TObjString*)(arrNextCol->At(1));
752       delete arrNextCol;
753
754       if ( !sObjType || ! sObjFileName ) continue;
755       TString sType(sObjType->GetString());
756       TString sFileName(sObjFileName->GetString());
757 //       printf("%s\t%s\n",sType.Data(),sFileName.Data());
758       
759       TFile *fIn = TFile::Open(sFileName);
760       if ( !fIn ){
761          fprintf(stderr,"File not found: '%s'", sFileName.Data());
762          continue;
763       }
764       
765       if ( sType == "CE" ){
766          AliTPCCalibCE *ce = (AliTPCCalibCE*)fIn->Get("AliTPCCalibCE");
767          
768          calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadT0());         
769          calPad->SetNameTitle("CETmean","CETmean");
770          calibObjects->Add(calPad);
771          
772          calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadQ());         
773          calPad->SetNameTitle("CEQmean","CEQmean");
774          calibObjects->Add(calPad);        
775          
776          calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadRMS());
777          calPad->SetNameTitle("CETrms","CETrms");
778          calibObjects->Add(calPad);         
779                   
780       } else if ( sType == "Pulser") {
781          AliTPCCalibPulser *sig = (AliTPCCalibPulser*)fIn->Get("AliTPCCalibPulser");
782          
783          calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadT0());         
784          calPad->SetNameTitle("PulserTmean","PulserTmean");
785          calibObjects->Add(calPad);
786          
787          calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadQ());         
788          calPad->SetNameTitle("PulserQmean","PulserQmean");
789          calibObjects->Add(calPad);        
790          
791          calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadRMS());
792          calPad->SetNameTitle("PulserTrms","PulserTrms");
793          calibObjects->Add(calPad);         
794       
795       } else if ( sType == "Pedestals") {
796          AliTPCCalibPedestal *ped = (AliTPCCalibPedestal*)fIn->Get("AliTPCCalibPedestal");
797          
798          calPad = new AliTPCCalPad((TObjArray*)ped->GetCalPadPedestal());         
799          calPad->SetNameTitle("Pedestals","Pedestals");
800          calibObjects->Add(calPad);
801          
802          calPad = new AliTPCCalPad((TObjArray*)ped->GetCalPadRMS());         
803          calPad->SetNameTitle("Noise","Noise");
804          calibObjects->Add(calPad);        
805      
806       } else {
807          fprintf(stderr,"Undefined Type: '%s'",sType.Data());
808          
809       }
810       delete fIn;
811    }
812    delete arrFileLine;
813 }
814
815 Int_t AliTPCcalibDB::InitDeadMap() {
816   // Initialize DeadChannel Map 
817   // Source of information:
818   // -  HV (see UpdateChamberHighVoltageData())
819   // -  Altro disabled channels. Noisy channels.
820   // -  DDL list
821
822   // check necessary information
823   const Int_t run=GetRun();
824   if (run<0){
825     AliError("run not set in CDB manager. Cannot create active channel map");
826     return 0;
827   }
828   AliDCSSensorArray* voltageArray = GetVoltageSensors(run);
829   AliTPCCalPad*          altroMap = GetALTROMasked();
830   TMap*                    mapddl = GetDDLMap();
831
832   if (!voltageArray && !altroMap && !mapddl) {
833     AliError("All necessary information to create the activate channel are map missing.");
834     return 0;
835   }
836   
837   //=============================================================
838   // Setup DDL map
839
840   Bool_t ddlMap[216]={0};
841   for (Int_t iddl=0; iddl<216; ++iddl) ddlMap[iddl]=1;
842   if (mapddl){
843     TObjString *s = (TObjString*)mapddl->GetValue("DDLArray");
844     if (s){
845       for (Int_t iddl=0; iddl<216; ++iddl) ddlMap[iddl]=TString(s->GetString()(iddl))!="0";
846     }
847   } else {
848     AliError("DDL map missing. ActiveChannelMap can only be created with parts of the information.");
849   }
850   // Setup DDL map done
851   // ============================================================
852
853   //=============================================================
854   // Setup active chnnel map
855   //
856
857   if (!fActiveChannelMap) fActiveChannelMap=new AliTPCCalPad("ActiveChannelMap","ActiveChannelMap");
858
859   AliTPCmapper map(gSystem->ExpandPathName("$ALICE_ROOT/TPC/mapping/"));
860
861   if (!altroMap) AliError("ALTRO dead channel map missing. ActiveChannelMap can only be created with parts of the information.");
862   
863   for (Int_t iROC=0;iROC<AliTPCCalPad::kNsec;++iROC){
864     AliTPCCalROC *roc=fActiveChannelMap->GetCalROC(iROC);
865     if (!roc){
866       AliError(Form("No ROC %d in active channel map",iROC));
867       continue;
868     }
869     
870     // check for bad voltage
871     // see UpdateChamberHighVoltageData()
872     if (!fChamberHVStatus[iROC]){
873       roc->Multiply(0.);
874       continue;
875     }
876     
877     AliTPCCalROC *masked=0x0;
878     if (altroMap) masked=altroMap->GetCalROC(iROC);
879     
880     for (UInt_t irow=0; irow<roc->GetNrows(); ++irow){
881       for (UInt_t ipad=0; ipad<roc->GetNPads(irow); ++ipad){
882         //per default the channel is on
883         roc->SetValue(irow,ipad,1);
884         // apply altro dead channel mask (inverse logik, it is not active, but inactive channles)
885         if (masked && masked->GetValue(irow, ipad)) roc->SetValue(irow, ipad ,0);
886         // mask channels if a DDL is inactive
887         Int_t ddlId=map.GetEquipmentID(iROC, irow, ipad)-768;
888         if (ddlId>=0 && !ddlMap[ddlId]) roc->SetValue(irow, ipad ,0);
889       }
890     }
891   }
892   
893   return 1;
894 }
895
896 void AliTPCcalibDB::MakeTree(const char * fileName, TObjArray * array, const char * mapFileName, AliTPCCalPad* outlierPad, Float_t ltmFraction) {
897   //
898   // Write a tree with all available information
899   // if mapFileName is specified, the Map information are also written to the tree
900   // pads specified in outlierPad are not used for calculating statistics
901   //  - the same function as AliTPCCalPad::MakeTree - 
902   //
903    AliTPCROC* tpcROCinstance = AliTPCROC::Instance();
904
905    TObjArray* mapIROCs = 0;
906    TObjArray* mapOROCs = 0;
907    TVectorF *mapIROCArray = 0;
908    TVectorF *mapOROCArray = 0;
909    Int_t mapEntries = 0;
910    TString* mapNames = 0;
911    
912    if (mapFileName) {
913       TFile mapFile(mapFileName, "read");
914       
915       TList* listOfROCs = mapFile.GetListOfKeys();
916       mapEntries = listOfROCs->GetEntries()/2;
917       mapIROCs = new TObjArray(mapEntries*2);
918       mapOROCs = new TObjArray(mapEntries*2);
919       mapIROCArray = new TVectorF[mapEntries];
920       mapOROCArray = new TVectorF[mapEntries];
921       
922       mapNames = new TString[mapEntries];
923       for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
924         TString nameROC(((TKey*)(listOfROCs->At(ivalue*2)))->GetName());
925          nameROC.Remove(nameROC.Length()-4, 4);
926          mapIROCs->AddAt((AliTPCCalROC*)mapFile.Get((nameROC + "IROC").Data()), ivalue);
927          mapOROCs->AddAt((AliTPCCalROC*)mapFile.Get((nameROC + "OROC").Data()), ivalue);
928          mapNames[ivalue].Append(nameROC);
929       }
930       
931       for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
932          mapIROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(0));
933          mapOROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(36));
934       
935          for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(0); ichannel++)
936             (mapIROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapIROCs->At(ivalue)))->GetValue(ichannel);
937          for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(36); ichannel++)
938             (mapOROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapOROCs->At(ivalue)))->GetValue(ichannel);
939       }
940
941    } //  if (mapFileName)
942   
943    TTreeSRedirector cstream(fileName);
944    Int_t arrayEntries = array->GetEntries();
945    
946    TString* names = new TString[arrayEntries];
947    for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
948       names[ivalue].Append(((AliTPCCalPad*)array->At(ivalue))->GetName());
949
950    for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++) {
951       //
952       // get statistic for given sector
953       //
954       TVectorF median(arrayEntries);
955       TVectorF mean(arrayEntries);
956       TVectorF rms(arrayEntries);
957       TVectorF ltm(arrayEntries);
958       TVectorF ltmrms(arrayEntries);
959       TVectorF medianWithOut(arrayEntries);
960       TVectorF meanWithOut(arrayEntries);
961       TVectorF rmsWithOut(arrayEntries);
962       TVectorF ltmWithOut(arrayEntries);
963       TVectorF ltmrmsWithOut(arrayEntries);
964       
965       TVectorF *vectorArray = new TVectorF[arrayEntries];
966       for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
967          vectorArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
968       
969       for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
970          AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
971          AliTPCCalROC* calROC = calPad->GetCalROC(isector);
972          AliTPCCalROC* outlierROC = 0;
973          if (outlierPad) outlierROC = outlierPad->GetCalROC(isector);
974          if (calROC) {
975             median[ivalue] = calROC->GetMedian();
976             mean[ivalue] = calROC->GetMean();
977             rms[ivalue] = calROC->GetRMS();
978             Double_t ltmrmsValue = 0;
979             ltm[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction);
980             ltmrms[ivalue] = ltmrmsValue;
981             if (outlierROC) {
982                medianWithOut[ivalue] = calROC->GetMedian(outlierROC);
983                meanWithOut[ivalue] = calROC->GetMean(outlierROC);
984                rmsWithOut[ivalue] = calROC->GetRMS(outlierROC);
985                ltmrmsValue = 0;
986                ltmWithOut[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction, outlierROC);
987                ltmrmsWithOut[ivalue] = ltmrmsValue;
988             }
989          }
990          else {
991             median[ivalue] = 0.;
992             mean[ivalue] = 0.;
993             rms[ivalue] = 0.;
994             ltm[ivalue] = 0.;
995             ltmrms[ivalue] = 0.;
996             medianWithOut[ivalue] = 0.;
997             meanWithOut[ivalue] = 0.;
998             rmsWithOut[ivalue] = 0.;
999             ltmWithOut[ivalue] = 0.;
1000             ltmrmsWithOut[ivalue] = 0.;
1001          }
1002       }
1003       
1004       //
1005       // fill vectors of variable per pad
1006       //
1007       TVectorF *posArray = new TVectorF[8];
1008       for (Int_t ivalue = 0; ivalue < 8; ivalue++)
1009          posArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
1010
1011       Float_t posG[3] = {0};
1012       Float_t posL[3] = {0};
1013       Int_t ichannel = 0;
1014       for (UInt_t irow = 0; irow < tpcROCinstance->GetNRows(isector); irow++) {
1015          for (UInt_t ipad = 0; ipad < tpcROCinstance->GetNPads(isector, irow); ipad++) {
1016             tpcROCinstance->GetPositionLocal(isector, irow, ipad, posL);
1017             tpcROCinstance->GetPositionGlobal(isector, irow, ipad, posG);
1018             posArray[0][ichannel] = irow;
1019             posArray[1][ichannel] = ipad;
1020             posArray[2][ichannel] = posL[0];
1021             posArray[3][ichannel] = posL[1];
1022             posArray[4][ichannel] = posG[0];
1023             posArray[5][ichannel] = posG[1];
1024             posArray[6][ichannel] = (Int_t)(ipad - (Double_t)(tpcROCinstance->GetNPads(isector, irow))/2);
1025             posArray[7][ichannel] = ichannel;
1026             
1027             // loop over array containing AliTPCCalPads
1028             for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
1029                AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
1030                AliTPCCalROC* calROC = calPad->GetCalROC(isector);
1031                if (calROC)
1032                   (vectorArray[ivalue])[ichannel] = calROC->GetValue(irow, ipad);
1033                else
1034                   (vectorArray[ivalue])[ichannel] = 0;
1035             }
1036             ichannel++;
1037          }
1038       }
1039       
1040       cstream << "calPads" <<
1041          "sector=" << isector;
1042       
1043       for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
1044          cstream << "calPads" <<
1045             (Char_t*)((names[ivalue] + "_Median=").Data()) << median[ivalue] <<
1046             (Char_t*)((names[ivalue] + "_Mean=").Data()) << mean[ivalue] <<
1047             (Char_t*)((names[ivalue] + "_RMS=").Data()) << rms[ivalue] <<
1048             (Char_t*)((names[ivalue] + "_LTM=").Data()) << ltm[ivalue] <<
1049             (Char_t*)((names[ivalue] + "_RMS_LTM=").Data()) << ltmrms[ivalue];
1050          if (outlierPad) {
1051             cstream << "calPads" <<
1052                (Char_t*)((names[ivalue] + "_Median_OutlierCutted=").Data()) << medianWithOut[ivalue] <<
1053                (Char_t*)((names[ivalue] + "_Mean_OutlierCutted=").Data()) << meanWithOut[ivalue] <<
1054                (Char_t*)((names[ivalue] + "_RMS_OutlierCutted=").Data()) << rmsWithOut[ivalue] <<
1055                (Char_t*)((names[ivalue] + "_LTM_OutlierCutted=").Data()) << ltmWithOut[ivalue] <<
1056                (Char_t*)((names[ivalue] + "_RMS_LTM_OutlierCutted=").Data()) << ltmrmsWithOut[ivalue];
1057          }
1058       }
1059
1060       for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
1061          cstream << "calPads" <<
1062             (Char_t*)((names[ivalue] + ".=").Data()) << &vectorArray[ivalue];
1063       }
1064
1065       if (mapFileName) {
1066          for  (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
1067             if (isector < 36)
1068                cstream << "calPads" <<
1069                   (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapIROCArray[ivalue];
1070             else
1071                cstream << "calPads" <<
1072                   (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapOROCArray[ivalue];
1073          }
1074       }
1075
1076       cstream << "calPads" <<
1077          "row.=" << &posArray[0] <<
1078          "pad.=" << &posArray[1] <<
1079          "lx.=" << &posArray[2] <<
1080          "ly.=" << &posArray[3] <<
1081          "gx.=" << &posArray[4] <<
1082          "gy.=" << &posArray[5] <<
1083          "rpad.=" << &posArray[6] <<
1084          "channel.=" << &posArray[7];
1085          
1086       cstream << "calPads" <<
1087          "\n";
1088
1089       delete[] posArray;
1090       delete[] vectorArray;
1091    }
1092    
1093
1094    delete[] names;
1095    if (mapFileName) {
1096       delete mapIROCs;
1097       delete mapOROCs;
1098       delete[] mapIROCArray;
1099       delete[] mapOROCArray;
1100       delete[] mapNames;
1101    }
1102 }
1103
1104 Int_t AliTPCcalibDB::GetRCUTriggerConfig() const
1105 {
1106   //
1107   // return the RCU trigger configuration register
1108   //
1109   TMap *map=GetRCUconfig();
1110   if (!map) return -1;
1111   TVectorF *v=(TVectorF*)map->GetValue("TRGCONF_TRG_MODE");
1112   Float_t mode=-1;
1113   for (Int_t i=0; i<v->GetNrows(); ++i){
1114     Float_t newmode=v->GetMatrixArray()[i];
1115     if (newmode>-1){
1116       if (mode>-1&&newmode!=mode) AliWarning("Found different RCU trigger configurations!!!");
1117       mode=newmode;
1118     }
1119   }
1120   return (Int_t)mode;
1121 }
1122
1123 Bool_t AliTPCcalibDB::IsTrgL0() 
1124 {
1125   //
1126   // return if the FEE readout was triggered on L0
1127   //
1128   if (fMode<0) return kFALSE;
1129   return (fMode==1);
1130 }
1131
1132 Bool_t AliTPCcalibDB::IsTrgL1()
1133 {
1134   //
1135   // return if the FEE readout was triggered on L1
1136   //
1137   if (fMode<0) return kFALSE;
1138   return (fMode==0);
1139 }
1140
1141 void AliTPCcalibDB::RegisterExB(Int_t index, Float_t bz, Bool_t bdelete){
1142   //
1143   // Register static ExB correction map
1144   // index - registration index - used for visualization
1145   // bz    - bz field in kGaus
1146
1147   //  Float_t factor =  bz/(-5.);  // default b filed in Cheb with minus sign
1148   Float_t factor =  bz/(5.);  // default b filed in Cheb with minus sign
1149                               // was chenged in the Revision ???? (Ruben can you add here number)
1150   
1151   AliMagF*   bmap = new AliMagF("MapsExB","MapsExB", factor,TMath::Sign(1.f,factor),AliMagF::k5kG);
1152   
1153   AliTPCExBFirst *exb  = new  AliTPCExBFirst(bmap,0.88*2.6400e+04,50,50,50);
1154   AliTPCExB::SetInstance(exb);
1155   
1156   if (bdelete){
1157     delete bmap;
1158   }else{
1159     AliTPCExB::RegisterField(index,bmap);
1160   }
1161   if (index>=fgExBArray.GetEntries()) fgExBArray.Expand((index+1)*2+11);
1162   fgExBArray.AddAt(exb,index);
1163 }
1164
1165
1166 AliTPCExB*    AliTPCcalibDB::GetExB(Float_t bz, Bool_t deleteB) {
1167   //
1168   // bz filed in KGaus not in tesla
1169   // Get ExB correction map
1170   // if doesn't exist - create it
1171   //
1172   Int_t index = TMath::Nint(5+bz);
1173   if (index>fgExBArray.GetEntries()) fgExBArray.Expand((index+1)*2+11);
1174   if (!fgExBArray.At(index)) AliTPCcalibDB::RegisterExB(index,bz,deleteB);
1175   return (AliTPCExB*)fgExBArray.At(index);
1176 }
1177
1178
1179 void  AliTPCcalibDB::SetExBField(Float_t bz){
1180   //
1181   // Set magnetic filed for ExB correction
1182   //
1183   fExB = GetExB(bz,kFALSE);
1184 }
1185
1186 void  AliTPCcalibDB::SetExBField(const AliMagF*   bmap){
1187   //
1188   // Set magnetic field for ExB correction
1189   //
1190   AliTPCExBFirst *exb  = new  AliTPCExBFirst(bmap,0.88*2.6400e+04,50,50,50);
1191   AliTPCExB::SetInstance(exb);
1192   fExB=exb;
1193 }
1194
1195
1196
1197 void AliTPCcalibDB::UpdateRunInformations( Int_t run, Bool_t force){
1198   //
1199   // - > Don't use it for reconstruction - Only for Calibration studies
1200   //
1201   if (run<=0) return;
1202   TObjString runstr(Form("%i",run));
1203   fRun=run;
1204   AliCDBEntry * entry = 0;
1205   if (run>= fRunList.fN){
1206     fRunList.Set(run*2+1);
1207     //
1208     //
1209     fALTROConfigData->Expand(run*2+1);    // ALTRO configuration data
1210     fPulserData->Expand(run*2+1);         // Calibration Pulser data
1211     fCEData->Expand(run*2+1);             // CE data
1212     if (!fTimeGainSplines) fTimeGainSplines = new TObjArray(run*2+1);
1213     fTimeGainSplines->Expand(run*2+1); // Array of AliSplineFits: at 0 MIP position in
1214   }
1215   if (fRunList[run]>0 &&force==kFALSE) return;
1216
1217   fRunList[run]=1;  // sign as used
1218
1219   //
1220   entry = AliCDBManager::Instance()->Get("GRP/GRP/Data",run);
1221   if (entry)  {
1222     AliGRPObject * grpRun = dynamic_cast<AliGRPObject*>(entry->GetObject());
1223     if (!grpRun){
1224       TMap* map = dynamic_cast<TMap*>(entry->GetObject());
1225       if (map){
1226         //grpRun = new AliGRPObject; 
1227         //grpRun->ReadValuesFromMap(map);
1228         grpRun =  MakeGRPObjectFromMap(map);
1229
1230         fGRPMaps.Add(new TObjString(runstr),map);
1231       }
1232     }
1233     fGRPArray.Add(new TObjString(runstr),grpRun);
1234   }
1235   entry = AliCDBManager::Instance()->Get("TPC/Calib/Goofie",run);
1236   if (entry){
1237     fGoofieArray.Add(new TObjString(runstr),entry->GetObject());
1238   }
1239   //
1240   
1241   //
1242   entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeGain",run);
1243   if (entry)  {
1244     fTimeGainSplinesArray.Add(new TObjString(runstr),entry->GetObject());
1245   }else{
1246     AliFatal("TPC - Missing calibration entry TimeGain");
1247   }
1248   //
1249   entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeDrift",run);
1250   if (entry)  {
1251     TObjArray * timeArray = (TObjArray*)entry->GetObject();    
1252     fDriftCorrectionArray.Add(new TObjString(runstr),entry->GetObject());  
1253     AliTPCCorrection * correctionTime = (AliTPCCorrection *)timeArray->FindObject("FitCorrectionTime");
1254     if (correctionTime && fComposedCorrectionArray){
1255       correctionTime->Init();
1256       if (fComposedCorrectionArray->GetEntriesFast()<4) fComposedCorrectionArray->Expand(40);
1257       fComposedCorrectionArray->AddAt(correctionTime,4); //add time dependent correction to the list of available corrections
1258     }
1259   }else{
1260     AliFatal("TPC - Missing calibration entry TimeDrift");
1261   }
1262   //
1263   entry = AliCDBManager::Instance()->Get("TPC/Calib/Temperature",run);
1264   if (entry)  {
1265     fTemperatureArray.Add(new TObjString(runstr),entry->GetObject());
1266   }
1267
1268   // High voltage
1269   entry = AliCDBManager::Instance()->Get("TPC/Calib/HighVoltage",run);
1270   if (!fVoltageArray.GetValue(runstr.GetName()) && entry)  {
1271     fVoltageArray.Add(new TObjString(runstr),entry->GetObject());
1272   }
1273
1274   //apply fDButil filters
1275
1276   fDButil->UpdateFromCalibDB();
1277   if (fTemperature) fDButil->FilterTemperature(fTemperature);
1278
1279   AliDCSSensor * press = GetPressureSensor(run,0);
1280   AliTPCSensorTempArray * temp = GetTemperatureSensor(run);
1281   Bool_t accept=kTRUE;
1282   if (temp) {
1283     accept = fDButil->FilterTemperature(temp)>0.1;
1284   }
1285   if (press) {
1286     const Double_t kMinP=900.;
1287     const Double_t kMaxP=1050.;
1288     const Double_t kMaxdP=10.;
1289     const Double_t kSigmaCut=4.;
1290     fDButil->FilterSensor(press,kMinP,kMaxP,kMaxdP,kSigmaCut);
1291     if (press->GetFit()==0) accept=kFALSE;
1292   }
1293
1294   if (press && temp &&accept){
1295     AliTPCCalibVdrift * vdrift = new AliTPCCalibVdrift(temp, press,0);
1296     fVdriftArray.Add(new TObjString(runstr),vdrift);
1297   }
1298
1299   fDButil->FilterCE(120., 3., 4.,0);
1300   fDButil->FilterTracks(run, 10.,0);
1301
1302 }
1303
1304
1305 Float_t AliTPCcalibDB::GetGain(Int_t sector, Int_t row, Int_t pad){
1306   //
1307   // Get Gain factor for given pad
1308   //
1309   AliTPCCalPad *calPad = Instance()->fDedxGainFactor;;
1310   if (!calPad) return 0;
1311   return calPad->GetCalROC(sector)->GetValue(row,pad);
1312 }
1313
1314 AliSplineFit* AliTPCcalibDB::GetVdriftSplineFit(const char* name, Int_t run){
1315   //
1316   // GetDrift velocity spline fit
1317   //
1318   TObjArray *arr=GetTimeVdriftSplineRun(run);
1319   if (!arr) return 0;
1320   return dynamic_cast<AliSplineFit*>(arr->FindObject(name));
1321 }
1322
1323 AliSplineFit* AliTPCcalibDB::CreateVdriftSplineFit(const char* graphName, Int_t run){
1324   //
1325   // create spline fit from the drift time graph in TimeDrift
1326   //
1327   TObjArray *arr=GetTimeVdriftSplineRun(run);
1328   if (!arr) return 0;
1329   TGraph *graph=dynamic_cast<TGraph*>(arr->FindObject(graphName));
1330   if (!graph) return 0;
1331   AliSplineFit *fit = new AliSplineFit();
1332   fit->SetGraph(graph);
1333   fit->SetMinPoints(graph->GetN()+1);
1334   fit->InitKnots(graph,2,0,0.001);
1335   fit->SplineFit(0);
1336   return fit;
1337 }
1338
1339 AliGRPObject *AliTPCcalibDB::GetGRP(Int_t run){
1340   //
1341   // Get GRP object for given run 
1342   //
1343   AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>((Instance()->fGRPArray).GetValue(Form("%i",run)));
1344   if (!grpRun) {
1345     Instance()->UpdateRunInformations(run);
1346     grpRun = dynamic_cast<AliGRPObject *>(Instance()->fGRPArray.GetValue(Form("%i",run)));
1347     if (!grpRun) return 0; 
1348   }
1349   return grpRun;
1350 }
1351
1352 TMap *  AliTPCcalibDB::GetGRPMap(Int_t run){
1353   //
1354   // Get GRP map for given run
1355   //
1356   TMap * grpRun = dynamic_cast<TMap *>((Instance()->fGRPMaps).GetValue(Form("%i",run)));
1357   if (!grpRun) {
1358     Instance()->UpdateRunInformations(run);
1359     grpRun = dynamic_cast<TMap *>(Instance()->fGRPMaps.GetValue(Form("%i",run)));
1360     if (!grpRun) return 0; 
1361   }
1362   return grpRun;
1363 }
1364
1365
1366 AliDCSSensor * AliTPCcalibDB::GetPressureSensor(Int_t run, Int_t type){
1367   //
1368   // Get Pressure sensor
1369   // run  = run number
1370   // type = 0 - Cavern pressure
1371   //        1 - Suface pressure
1372   // First try to get if trom map - if existing  (Old format of data storing)
1373   //
1374
1375
1376   TMap *map = GetGRPMap(run);  
1377   if (map){
1378     AliDCSSensor * sensor = 0;
1379     TObject *osensor=0;
1380     if (type==0) osensor = ((*map)("fCavernPressure"));
1381     if (type==1) osensor = ((*map)("fP2Pressure"));
1382     sensor =dynamic_cast<AliDCSSensor *>(osensor); 
1383     if (sensor) return sensor;
1384   }
1385   //
1386   // If not map try to get it from the GRPObject
1387   //
1388   AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.GetValue(Form("%i",run))); 
1389   if (!grpRun) {
1390     UpdateRunInformations(run);
1391     grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.GetValue(Form("%i",run)));
1392     if (!grpRun) return 0; 
1393   }
1394   AliDCSSensor * sensor = grpRun->GetCavernAtmosPressure();
1395   if (type==1) sensor = grpRun->GetSurfaceAtmosPressure();
1396   return sensor; 
1397 }
1398
1399 AliTPCSensorTempArray * AliTPCcalibDB::GetTemperatureSensor(Int_t run){
1400   //
1401   // Get temperature sensor array
1402   //
1403   AliTPCSensorTempArray * tempArray = (AliTPCSensorTempArray *)fTemperatureArray.GetValue(Form("%i",run));
1404   if (!tempArray) {
1405     UpdateRunInformations(run);
1406     tempArray = (AliTPCSensorTempArray *)fTemperatureArray.GetValue(Form("%i",run));
1407   }
1408   return tempArray;
1409 }
1410
1411
1412 TObjArray * AliTPCcalibDB::GetTimeGainSplinesRun(Int_t run){
1413   //
1414   // Get temperature sensor array
1415   //
1416   TObjArray * gainSplines = (TObjArray *)fTimeGainSplinesArray.GetValue(Form("%i",run));
1417   if (!gainSplines) {
1418     UpdateRunInformations(run);
1419     gainSplines = (TObjArray *)fTimeGainSplinesArray.GetValue(Form("%i",run));
1420   }
1421   return gainSplines;
1422 }
1423
1424 TObjArray * AliTPCcalibDB::GetTimeVdriftSplineRun(Int_t run){
1425   //
1426   // Get drift spline array
1427   //
1428   TObjArray * driftSplines = (TObjArray *)fDriftCorrectionArray.GetValue(Form("%i",run));
1429   if (!driftSplines) {
1430     UpdateRunInformations(run);
1431     driftSplines = (TObjArray *)fDriftCorrectionArray.GetValue(Form("%i",run));
1432   }
1433   return driftSplines;
1434 }
1435
1436 AliDCSSensorArray * AliTPCcalibDB::GetVoltageSensors(Int_t run){
1437   //
1438   // Get temperature sensor array
1439   //
1440   AliDCSSensorArray * voltageArray = (AliDCSSensorArray *)fVoltageArray.GetValue(Form("%i",run));
1441   if (!voltageArray) {
1442     UpdateRunInformations(run);
1443     voltageArray = (AliDCSSensorArray *)fVoltageArray.GetValue(Form("%i",run));
1444   }
1445   return voltageArray;
1446 }
1447
1448 AliDCSSensorArray * AliTPCcalibDB::GetGoofieSensors(Int_t run){
1449   //
1450   // Get temperature sensor array
1451   //
1452   AliDCSSensorArray * goofieArray = (AliDCSSensorArray *)fGoofieArray.GetValue(Form("%i",run));
1453   if (!goofieArray) {
1454     UpdateRunInformations(run);
1455     goofieArray = (AliDCSSensorArray *)fGoofieArray.GetValue(Form("%i",run));
1456   }
1457   return goofieArray;
1458 }
1459
1460
1461
1462 AliTPCCalibVdrift *     AliTPCcalibDB::GetVdrift(Int_t run){
1463   //
1464   // Get the interface to the the vdrift 
1465   //
1466   AliTPCCalibVdrift  * vdrift = (AliTPCCalibVdrift*)fVdriftArray.GetValue(Form("%i",run));
1467   if (!vdrift) {
1468     UpdateRunInformations(run);
1469     vdrift= (AliTPCCalibVdrift*)fVdriftArray.GetValue(Form("%i",run));
1470   }
1471   return vdrift;
1472 }
1473
1474 Float_t AliTPCcalibDB::GetCEdriftTime(Int_t run, Int_t sector, Double_t timeStamp, Int_t *entries)
1475 {
1476   //
1477   // GetCE drift time information for 'sector'
1478   // sector 72 is the mean drift time of the A-Side
1479   // sector 73 is the mean drift time of the C-Side
1480   // it timestamp==-1 return mean value
1481   //
1482   AliTPCcalibDB::Instance()->SetRun(run);
1483   TGraph *gr=AliTPCcalibDB::Instance()->GetCErocTgraph(sector);
1484   if (!gr||sector<0||sector>73) {
1485     if (entries) *entries=0;
1486     return 0.;
1487   }
1488   Float_t val=0.;
1489   if (timeStamp==-1.){
1490     val=gr->GetMean(2);
1491   }else{
1492     for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1493       Double_t x,y;
1494       gr->GetPoint(ipoint,x,y);
1495       if (x<timeStamp) continue;
1496       val=y;
1497       break;
1498     }
1499   }
1500   return val;
1501 }
1502   
1503 Float_t AliTPCcalibDB::GetCEchargeTime(Int_t run, Int_t sector, Double_t timeStamp, Int_t *entries)
1504 {
1505   //
1506   // GetCE mean charge for 'sector'
1507   // it timestamp==-1 return mean value
1508   //
1509   AliTPCcalibDB::Instance()->SetRun(run);
1510   TGraph *gr=AliTPCcalibDB::Instance()->GetCErocQgraph(sector);
1511   if (!gr||sector<0||sector>71) {
1512     if (entries) *entries=0;
1513     return 0.;
1514   }
1515   Float_t val=0.;
1516   if (timeStamp==-1.){
1517     val=gr->GetMean(2);
1518   }else{
1519     for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1520       Double_t x,y;
1521       gr->GetPoint(ipoint,x,y);
1522       if (x<timeStamp) continue;
1523       val=y;
1524       break;
1525     }
1526   }
1527   return val;
1528 }
1529
1530 Float_t AliTPCcalibDB::GetDCSSensorValue(AliDCSSensorArray *arr, Int_t timeStamp, const char * sensorName, Int_t sigDigits)
1531 {
1532   //
1533   // Get Value for a DCS sensor 'sensorName', run 'run' at time 'timeStamp'
1534   //
1535   Float_t val=0;
1536   const TString sensorNameString(sensorName);
1537   AliDCSSensor *sensor = arr->GetSensor(sensorNameString);
1538   if (!sensor) return val;
1539   //use the dcs graph if possible
1540   TGraph *gr=sensor->GetGraph();
1541   if (gr){
1542     for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1543       Double_t x,y;
1544       gr->GetPoint(ipoint,x,y);
1545       Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
1546       if (time<timeStamp) continue;
1547       val=y;
1548       break;
1549     }
1550     //if val is still 0, test if if the requested time if within 5min of the first/last
1551     //data point. If this is the case return the firs/last entry
1552     //the timestamps might not be syncronised for all calibration types, sometimes a 'pre'
1553     //and 'pos' period is requested. Especially to the HV this is not the case!
1554     //first point
1555     if (val==0 ){
1556       Double_t x,y;
1557       gr->GetPoint(0,x,y);
1558       const Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
1559       const Int_t dtime=time-timeStamp;
1560       if ( (dtime>0) && (dtime<5*60) ) val=y;
1561     }
1562     //last point
1563     if (val==0 ){
1564       Double_t x,y;
1565       gr->GetPoint(gr->GetN()-1,x,y);
1566       const Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
1567       const Int_t dtime=timeStamp-time;
1568       if ( (dtime>0) && (dtime<5*60) ) val=y;
1569     }
1570   } else {
1571     val=sensor->GetValue(timeStamp);
1572   }
1573   if (sigDigits>=0){
1574     val=(Float_t)TMath::Floor(val * TMath::Power(10., sigDigits) + .5) / TMath::Power(10., sigDigits);
1575   }
1576   return val;
1577 }
1578
1579 Float_t AliTPCcalibDB::GetDCSSensorMeanValue(AliDCSSensorArray *arr, const char * sensorName, Int_t sigDigits)
1580 {
1581   //
1582   // Get mean Value for a DCS sensor 'sensorName' during run 'run'
1583   //
1584   Float_t val=0;
1585   const TString sensorNameString(sensorName);
1586   AliDCSSensor *sensor = arr->GetSensor(sensorNameString);
1587   if (!sensor) return val;
1588
1589   //use dcs graph if it exists
1590   TGraph *gr=sensor->GetGraph();
1591   if (gr){
1592     val=gr->GetMean(2);
1593   } else {
1594     //if we don't have the dcs graph, try to get some meaningful information
1595     if (!sensor->GetFit()) return val;
1596     Int_t nKnots=sensor->GetFit()->GetKnots();
1597     Double_t tMid=(sensor->GetEndTime()-sensor->GetStartTime())/2.;
1598     for (Int_t iKnot=0;iKnot<nKnots;++iKnot){
1599       if (sensor->GetFit()->GetX()[iKnot]>tMid/3600.) break;
1600       val=(Float_t)sensor->GetFit()->GetY0()[iKnot];
1601     }
1602   }
1603   if (sigDigits>=0){
1604     // val/=10;
1605     val=(Float_t)TMath::Floor(val * TMath::Power(10., sigDigits) + .5) / TMath::Power(10., sigDigits);
1606     //    val*=10;
1607   }
1608   return val;
1609 }
1610
1611 Bool_t AliTPCcalibDB::IsDataTakingActive(time_t timeStamp)
1612 {
1613   if (!fGrRunState) return kFALSE;
1614   Double_t time=Double_t(timeStamp);
1615   Int_t currentPoint=0;
1616   Bool_t currentVal=fGrRunState->GetY()[currentPoint]>0.5;
1617   Bool_t retVal=currentVal;
1618   Double_t currentTime=fGrRunState->GetX()[currentPoint];
1619   
1620   while (time>currentTime){
1621     retVal=currentVal;
1622     if (currentPoint==fGrRunState->GetN()) break;
1623     currentVal=fGrRunState->GetY()[currentPoint]>0.5;
1624     currentTime=fGrRunState->GetX()[currentPoint];
1625     ++currentPoint;
1626   }
1627
1628   return retVal;
1629 }
1630
1631 void AliTPCcalibDB::UpdateChamberHighVoltageData()
1632 {
1633   //
1634   // set chamber high voltage data
1635   // 1. Robust median (sampling the hv graphs over time)
1636   // 2. Current nominal voltages (nominal voltage corrected for common HV offset)
1637   // 3. Fraction of good HV values over time (deviation from robust median)
1638   // 4. HV status, based on the above
1639   //
1640
1641   // start and end time of the run
1642   const Int_t run=GetRun();
1643   if (run<0) return;
1644
1645   // if no valid run information - return
1646   AliGRPObject* grp = GetGRP(run);
1647   if (!grp) return;
1648
1649   const Int_t startTimeGRP = grp->GetTimeStart();
1650   const Int_t stopTimeGRP  = grp->GetTimeEnd();
1651
1652   //
1653   // In case we use a generated GRP we cannot make use of the start time and end time information
1654   // therefore we cannot calculate proper HV information and will skip this
1655   //
1656   if (startTimeGRP==0 && stopTimeGRP==0) {
1657     AliWarning("Using a generated GRP with 'GetTimeStart()' and 'GetTimeEnd()' == 0. Cannot calculate HV information.");
1658     return;
1659   }
1660
1661   //
1662   // check active state by analysing the scalers
1663   //
1664   // initialise graph with active running
1665   AliCDBEntry *entry = GetCDBEntry("GRP/CTP/Scalers");
1666   if (!entry) return;
1667   // entry->SetOwner(kTRUE);
1668   AliTriggerRunScalers *sca = (AliTriggerRunScalers*)entry->GetObject();
1669   Int_t nchannels = sca->GetNumClasses(); // number of scaler channels (i.e. trigger classes)
1670   Int_t npoints = sca->GetScalersRecords()->GetEntries(); // number of samples
1671
1672   delete fGrRunState;
1673   fGrRunState=new TGraph;
1674   fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(startTimeGRP)-.001,0);
1675   fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(startTimeGRP),1);
1676   ULong64_t lastSum=0;
1677   Double_t timeLast=0.;
1678   Bool_t active=kTRUE;
1679   for (int i=0; i<npoints; i++) {
1680     AliTriggerScalersRecord *rec = (AliTriggerScalersRecord *) sca->GetScalersRecord(i);
1681     Double_t time = ((AliTimeStamp*) rec->GetTimeStamp())->GetSeconds();
1682     ULong64_t sum=0;
1683     for (int j=0; j<nchannels; j++) sum += ((AliTriggerScalers*) rec->GetTriggerScalers()->At(j))->GetL2CA();
1684     if (TMath::Abs(time-timeLast)<.001 && sum==lastSum ) continue;
1685     if (active && sum==lastSum){
1686       fGrRunState->SetPoint(fGrRunState->GetN(),timeLast-.01,1);
1687       fGrRunState->SetPoint(fGrRunState->GetN(),timeLast,0);
1688       active=kFALSE;
1689     } else if (!active && sum>lastSum ){
1690       fGrRunState->SetPoint(fGrRunState->GetN(),timeLast-.01,0);
1691       fGrRunState->SetPoint(fGrRunState->GetN(),timeLast,1);
1692       active=kTRUE;
1693     }
1694     lastSum=sum;
1695     timeLast=time;
1696   }
1697   fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(stopTimeGRP),active);
1698   fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(stopTimeGRP)+.001,0);
1699   
1700   
1701   
1702   // reset all values
1703   for (Int_t iROC=0;iROC<72;++iROC) {
1704     fChamberHVmedian[iROC]       = -1;
1705     fChamberHVgoodFraction[iROC] = 0.;
1706     fCurrentNominalVoltage[iROC] = -999.;
1707     fChamberHVStatus[iROC]       = kFALSE;
1708   }
1709   
1710   AliDCSSensorArray* voltageArray = GetVoltageSensors(run);
1711   if (!voltageArray) {
1712     AliError("Voltage Array missing. Cannot calculate HV information!");
1713     return;
1714   }
1715
1716   // max HV diffs before a chamber is masked
1717   const Float_t maxVdiff      = fParam->GetMaxVoltageDeviation();
1718   const Float_t maxDipVoltage = fParam->GetMaxDipVoltage();
1719   const Float_t maxFracHVbad  = fParam->GetMaxFractionHVbad();
1720
1721   const Int_t samplingPeriod=1;
1722
1723   // array with sampled voltages
1724   const Int_t maxSamples=(stopTimeGRP-startTimeGRP)/samplingPeriod + 10*samplingPeriod;
1725   Float_t *vSampled = new Float_t[maxSamples];
1726
1727   // deviation of the median from the nominal voltage
1728   Double_t chamberMedianDeviation[72]={0.};
1729
1730   for (Int_t iROC=0; iROC<72; ++iROC){
1731     chamberMedianDeviation[iROC]=0.;
1732     TString sensorName="";
1733     Char_t sideName='A';
1734     if ((iROC/18)%2==1) sideName='C';
1735     if (iROC<36) sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,iROC%18);
1736     else        sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,iROC%18);
1737
1738     AliDCSSensor *sensor = voltageArray->GetSensor(sensorName);
1739
1740     fHVsensors[iROC]=sensor;
1741     if (!sensor) continue;
1742
1743     Int_t nPointsSampled=0;
1744     
1745     TGraph *gr=sensor->GetGraph();
1746     if ( gr && gr->GetN()>1 ){
1747       //1. sample voltage over time
1748       //   get a robust median
1749       //   buffer sampled voltages
1750       
1751       // current sampling time
1752       Int_t time=startTimeGRP;
1753       
1754       // input graph sampling point
1755       const Int_t nGraph=gr->GetN();
1756       Int_t pointGraph=0;
1757       
1758       //initialise graph information
1759       Int_t timeGraph=TMath::Nint(gr->GetX()[pointGraph+1]*3600+sensor->GetStartTime());
1760       Double_t sampledHV=gr->GetY()[pointGraph++];
1761
1762       while (time<stopTimeGRP){
1763         while (timeGraph<=time && pointGraph+1<nGraph){
1764           timeGraph=TMath::Nint(gr->GetX()[pointGraph+1]*3600+sensor->GetStartTime());
1765           sampledHV=gr->GetY()[pointGraph++];
1766         }
1767         time+=samplingPeriod;
1768         if (!IsDataTakingActive(time-samplingPeriod)) continue;
1769         vSampled[nPointsSampled++]=sampledHV;
1770       }
1771
1772       if (nPointsSampled<1) continue;
1773       
1774       fChamberHVmedian[iROC]=TMath::Median(nPointsSampled,vSampled);
1775       chamberMedianDeviation[iROC]=fChamberHVmedian[iROC]-fParam->GetNominalVoltage(iROC);
1776
1777       //2. calculate good HV fraction
1778       Int_t ngood=0;
1779       for (Int_t ipoint=0; ipoint<nPointsSampled; ++ipoint) {
1780         if (TMath::Abs(vSampled[ipoint]-fChamberHVmedian[iROC])<maxDipVoltage) ++ngood;
1781       }
1782
1783       fChamberHVgoodFraction[iROC]=Float_t(ngood)/Float_t(nPointsSampled);
1784     } else if (!gr && !sensor->GetFit() ){
1785       // This is an exception handling.
1786       // It was observed that for some rund in the 2010 data taking no HV info is available
1787       //    for some sectors. However they were active. So take care about this
1788       fChamberHVmedian[iROC]       = fParam->GetNominalVoltage(iROC);
1789       fChamberHVgoodFraction[iROC] = 1.;
1790       AliWarning(Form("ROC %d detected without HV Splines and HV graph. Will set median HV to nominal voltage",iROC));
1791     } else {
1792       AliError(Form("No Graph or too few points found for HV sensor of ROC %d",iROC));
1793     }
1794   }
1795
1796   delete [] vSampled;
1797   vSampled=0x0;
1798   
1799   // get median deviation from all chambers (detect e.g. -50V)
1800   const Double_t medianIROC=TMath::Median( 36, chamberMedianDeviation );
1801   const Double_t medianOROC=TMath::Median( 36, chamberMedianDeviation+36 );
1802   
1803   // Define current default voltages
1804   for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
1805     const Float_t averageDeviation=(iROC<36)?medianIROC:medianOROC;
1806     fCurrentNominalVoltage[iROC]=fParam->GetNominalVoltage(iROC)+averageDeviation;
1807   }
1808
1809   //
1810   // Check HV status
1811   //
1812   for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
1813     fChamberHVStatus[iROC]=kTRUE;
1814
1815     //a. Deviation of median from current nominal voltage
1816     //   allow larger than nominal voltages
1817     if (fCurrentNominalVoltage[iROC]-fChamberHVmedian[iROC] >  maxVdiff) fChamberHVStatus[iROC]=kFALSE;
1818
1819     //b. Fraction of bad hv values
1820     if ( 1-fChamberHVgoodFraction[iROC] > maxFracHVbad ) fChamberHVStatus[iROC]=kFALSE;
1821   }
1822 }
1823
1824 Float_t AliTPCcalibDB::GetChamberHighVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits, Bool_t current) {
1825   //
1826   // return the chamber HV for given run and time: 0-35 IROC, 36-72 OROC
1827   // if timeStamp==-1 return mean value
1828   //
1829   Float_t val=0;
1830   TString sensorName="";
1831   TTimeStamp stamp(timeStamp);
1832   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1833   if (!voltageArray || (sector<0) || (sector>71)) return val;
1834   Char_t sideName='A';
1835   if ((sector/18)%2==1) sideName='C';
1836   if (sector<36){
1837     //IROC
1838     sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
1839   }else{
1840     //OROC
1841     sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
1842   }
1843   if (current){
1844     if (sector<36){
1845       //IROC
1846       sensorName=Form("TPC_ANODE_I_%c%02d_IMEAS",sideName,sector%18);
1847     }else{
1848       //OROC
1849       sensorName=Form("TPC_ANODE_O_%c%02d_0_IMEAS",sideName,sector%18);
1850     }
1851     
1852   }
1853   if (timeStamp==-1){
1854     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1855   } else {
1856     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1857   }
1858   return val;
1859 }
1860 Float_t AliTPCcalibDB::GetSkirtVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1861 {
1862   //
1863   // Get the skirt voltage for 'run' at 'timeStamp' and 'sector': 0-35 IROC, 36-72 OROC
1864   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1865   // if timeStamp==-1 return the mean value for the run
1866   //
1867   Float_t val=0;
1868   TString sensorName="";
1869   TTimeStamp stamp(timeStamp);
1870   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1871   if (!voltageArray || (sector<0) || (sector>71)) return val;
1872   Char_t sideName='A';
1873   if ((sector/18)%2==1) sideName='C';
1874   sensorName=Form("TPC_SKIRT_%c_VMEAS",sideName);
1875   if (timeStamp==-1){
1876     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1877   } else {
1878     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1879   }
1880   return val;
1881 }
1882
1883 Float_t AliTPCcalibDB::GetCoverVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1884 {
1885   //
1886   // Get the cover voltage for run 'run' at time 'timeStamp'
1887   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1888   // if timeStamp==-1 return the mean value for the run
1889   //
1890   Float_t val=0;
1891   TString sensorName="";
1892   TTimeStamp stamp(timeStamp);
1893   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1894   if (!voltageArray || (sector<0) || (sector>71)) return val;
1895   Char_t sideName='A';
1896   if ((sector/18)%2==1) sideName='C';
1897   if (sector<36){
1898     //IROC
1899     sensorName=Form("TPC_COVER_I_%c_VMEAS",sideName);
1900   }else{
1901     //OROC
1902     sensorName=Form("TPC_COVER_O_%c_VMEAS",sideName);
1903   }
1904   if (timeStamp==-1){
1905     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1906   } else {
1907     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1908   }
1909   return val;
1910 }
1911
1912 Float_t AliTPCcalibDB::GetGGoffsetVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1913 {
1914   //
1915   // Get the GG offset voltage for run 'run' at time 'timeStamp'
1916   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1917   // if timeStamp==-1 return the mean value for the run
1918   //
1919   Float_t val=0;
1920   TString sensorName="";
1921   TTimeStamp stamp(timeStamp);
1922   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1923   if (!voltageArray || (sector<0) || (sector>71)) return val;
1924   Char_t sideName='A';
1925   if ((sector/18)%2==1) sideName='C';
1926   if (sector<36){
1927     //IROC
1928     sensorName=Form("TPC_GATE_I_%c_OFF_VMEAS",sideName);
1929   }else{
1930     //OROC
1931     sensorName=Form("TPC_GATE_O_%c_OFF_VMEAS",sideName);
1932   }
1933   if (timeStamp==-1){
1934     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1935   } else {
1936     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1937   }
1938   return val;
1939 }
1940
1941 Float_t AliTPCcalibDB::GetGGnegVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1942 {
1943   //
1944   // Get the GG offset voltage for run 'run' at time 'timeStamp'
1945   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1946   // if timeStamp==-1 return the mean value for the run
1947   //
1948   Float_t val=0;
1949   TString sensorName="";
1950   TTimeStamp stamp(timeStamp);
1951   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1952   if (!voltageArray || (sector<0) || (sector>71)) return val;
1953   Char_t sideName='A';
1954   if ((sector/18)%2==1) sideName='C';
1955   if (sector<36){
1956     //IROC
1957     sensorName=Form("TPC_GATE_I_%c_NEG_VMEAS",sideName);
1958   }else{
1959     //OROC
1960     sensorName=Form("TPC_GATE_O_%c_NEG_VMEAS",sideName);
1961   }
1962   if (timeStamp==-1){
1963     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1964   } else {
1965     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1966   }
1967   return val;
1968 }
1969
1970 Float_t AliTPCcalibDB::GetGGposVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1971 {
1972   //
1973   // Get the GG offset voltage for run 'run' at time 'timeStamp'
1974   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1975   // if timeStamp==-1 return the mean value for the run
1976   //
1977   Float_t val=0;
1978   TString sensorName="";
1979   TTimeStamp stamp(timeStamp);
1980   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1981   if (!voltageArray || (sector<0) || (sector>71)) return val;
1982   Char_t sideName='A';
1983   if ((sector/18)%2==1) sideName='C';
1984   if (sector<36){
1985     //IROC
1986     sensorName=Form("TPC_GATE_I_%c_POS_VMEAS",sideName);
1987   }else{
1988     //OROC
1989     sensorName=Form("TPC_GATE_O_%c_POS_VMEAS",sideName);
1990   }
1991   if (timeStamp==-1){
1992     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1993   } else {
1994     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1995   }
1996   return val;
1997 }
1998
1999 Float_t AliTPCcalibDB::GetPressure(Int_t timeStamp, Int_t run, Int_t type){
2000   //
2001   // GetPressure for given time stamp and runt
2002   //
2003   TTimeStamp stamp(timeStamp);
2004   AliDCSSensor * sensor = Instance()->GetPressureSensor(run,type);
2005   if (!sensor) return 0;
2006   return sensor->GetValue(stamp);
2007 }
2008
2009 Float_t AliTPCcalibDB::GetL3Current(Int_t run, Int_t statType){
2010   //
2011   // return L3 current
2012   // stat type is: AliGRPObject::Stats: kMean = 0, kTruncMean = 1, kMedian = 2, kSDMean = 3, kSDMedian = 4
2013   //
2014   Float_t current=-1;
2015   AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2016   if (grp) current=grp->GetL3Current((AliGRPObject::Stats)statType);
2017   return current;
2018 }
2019
2020 Float_t AliTPCcalibDB::GetBz(Int_t run){
2021   //
2022   // calculate BZ in T from L3 current
2023   //
2024   Float_t bz=-1;
2025   Float_t current=AliTPCcalibDB::GetL3Current(run);
2026   if (current>-1) bz=5*current/30000.*.1;
2027   return bz;
2028 }
2029
2030 Char_t  AliTPCcalibDB::GetL3Polarity(Int_t run) {
2031   //
2032   // get l3 polarity from GRP
2033   //
2034   Char_t pol=-100;
2035   AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2036   if (grp) pol=grp->GetL3Polarity();
2037   return pol;
2038 }
2039
2040 TString AliTPCcalibDB::GetRunType(Int_t run){
2041   //
2042   // return run type from grp
2043   //
2044
2045 //   TString type("UNKNOWN");
2046   AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2047   if (grp) return grp->GetRunType();
2048   return "UNKNOWN";
2049 }
2050
2051 Float_t AliTPCcalibDB::GetValueGoofie(Int_t timeStamp, Int_t run, Int_t type){
2052   //
2053   // GetPressure for given time stamp and runt
2054   //
2055   TTimeStamp stamp(timeStamp);
2056   AliDCSSensorArray* goofieArray = AliTPCcalibDB::Instance()->GetGoofieSensors(run);
2057   if (!goofieArray) return 0;
2058   AliDCSSensor *sensor = goofieArray->GetSensor(type);
2059   return sensor->GetValue(stamp);
2060 }
2061
2062
2063
2064
2065
2066
2067 Bool_t  AliTPCcalibDB::GetTemperatureFit(Int_t timeStamp, Int_t run, Int_t side,TVectorD& fit){
2068   //
2069   // GetTmeparature fit at parameter for given time stamp
2070   //
2071   TTimeStamp tstamp(timeStamp);
2072   AliTPCSensorTempArray* tempArray  = Instance()->GetTemperatureSensor(run);
2073   if (! tempArray) return kFALSE;
2074   AliTPCTempMap * tempMap = new AliTPCTempMap(tempArray);
2075   TLinearFitter * fitter = tempMap->GetLinearFitter(3,side,tstamp);
2076   if (fitter){
2077     fitter->Eval(); 
2078     fitter->GetParameters(fit);
2079   }
2080   delete fitter;
2081   delete tempMap;
2082   if (!fitter) return kFALSE;
2083   return kTRUE;
2084 }
2085
2086 Float_t AliTPCcalibDB::GetTemperature(Int_t timeStamp, Int_t run, Int_t side){
2087   //
2088   // Get mean temperature
2089   // 
2090   TVectorD vec(5);
2091   if (side==0) {
2092     GetTemperatureFit(timeStamp,run,0,vec);
2093     return vec[0];
2094   }
2095   if (side==1){
2096     GetTemperatureFit(timeStamp,run,0,vec);
2097     return vec[0];
2098   }
2099   return 0;
2100 }
2101
2102
2103 Double_t AliTPCcalibDB::GetPTRelative(UInt_t timeSec, Int_t run, Int_t side){
2104   //
2105   // Get relative P/T 
2106   // time - absolute time
2107   // run  - run number
2108   // side - 0 - A side   1-C side
2109   AliTPCCalibVdrift * vdrift =  Instance()->GetVdrift(run);
2110   if (!vdrift) return 0;
2111   return vdrift->GetPTRelative(timeSec,side);
2112 }
2113
2114 AliGRPObject * AliTPCcalibDB::MakeGRPObjectFromMap(TMap *map){
2115   //
2116   // Function to covert old GRP run information from TMap to GRPObject
2117   //
2118   //  TMap * map = AliTPCcalibDB::GetGRPMap(52406);
2119   if (!map) return 0;
2120   AliDCSSensor * sensor = 0;
2121   TObject *osensor=0;
2122   osensor = ((*map)("fP2Pressure"));
2123   sensor  =dynamic_cast<AliDCSSensor *>(osensor); 
2124   //
2125   if (!sensor) return 0;
2126   //
2127   AliDCSSensor * sensor2 = new AliDCSSensor(*sensor);
2128   osensor = ((*map)("fCavernPressure"));
2129   TGraph * gr = new TGraph(2);
2130   gr->GetX()[0]= -100000.;
2131   gr->GetX()[1]= 1000000.;
2132   gr->GetY()[0]= atof(osensor->GetName());
2133   gr->GetY()[1]= atof(osensor->GetName());
2134   sensor2->SetGraph(gr);
2135   sensor2->SetFit(0);
2136   
2137
2138   AliGRPObject *grpRun = new AliGRPObject; 
2139   grpRun->ReadValuesFromMap(map);
2140   grpRun->SetCavernAtmosPressure(sensor2);
2141   grpRun->SetCavernAtmosPressure(sensor2);
2142   grpRun->SetSurfaceAtmosPressure(sensor);
2143   return grpRun;
2144 }
2145
2146 Bool_t AliTPCcalibDB::CreateGUITree(Int_t run, const char* filename)
2147 {
2148   //
2149   // Create a gui tree for run number 'run'
2150   //
2151
2152   if (!AliCDBManager::Instance()->GetDefaultStorage()){
2153     AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
2154                     MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
2155     return kFALSE;
2156   }
2157   //db instance
2158   AliTPCcalibDB *db=AliTPCcalibDB::Instance();
2159   // retrieve cal pad objects
2160   db->SetRun(run);
2161   db->CreateGUITree(filename);
2162   return kTRUE;
2163 }
2164
2165 Bool_t AliTPCcalibDB::CreateGUITree(const char* filename){
2166   //
2167   //
2168   //
2169   if (!AliCDBManager::Instance()->GetDefaultStorage()){
2170     AliError("Default Storage not set. Cannot create calibration Tree!");
2171     return kFALSE;
2172   }
2173   UpdateNonRec();  // load all infromation now
2174
2175   AliTPCPreprocessorOnline prep;
2176   if (GetActiveChannelMap()) prep.AddComponent(new AliTPCCalPad(*GetActiveChannelMap()));
2177
2178   // gain map
2179   if (GetDedxGainFactor()) prep.AddComponent(new AliTPCCalPad(*GetDedxGainFactor()));
2180   //noise and pedestals
2181   if (GetPedestals()) prep.AddComponent(new AliTPCCalPad(*(GetPedestals())));
2182   if (GetPadNoise() ) prep.AddComponent(new AliTPCCalPad(*(GetPadNoise())));
2183   //pulser data
2184   if (GetPulserTmean()) prep.AddComponent(new AliTPCCalPad(*(GetPulserTmean())));
2185   if (GetPulserTrms() ) prep.AddComponent(new AliTPCCalPad(*(GetPulserTrms())));
2186   if (GetPulserQmean()) prep.AddComponent(new AliTPCCalPad(*(GetPulserQmean())));
2187   //CE data
2188   if (GetCETmean()) prep.AddComponent(new AliTPCCalPad(*(GetCETmean())));
2189   if (GetCETrms() ) prep.AddComponent(new AliTPCCalPad(*(GetCETrms())));
2190   if (GetCEQmean()) prep.AddComponent(new AliTPCCalPad(*(GetCEQmean())));
2191   //Altro data
2192   if (GetALTROAcqStart() ) prep.AddComponent(new AliTPCCalPad(*(GetALTROAcqStart() )));
2193   if (GetALTROZsThr()    ) prep.AddComponent(new AliTPCCalPad(*(GetALTROZsThr()    )));
2194   if (GetALTROFPED()     ) prep.AddComponent(new AliTPCCalPad(*(GetALTROFPED()     )));
2195   if (GetALTROAcqStop()  ) prep.AddComponent(new AliTPCCalPad(*(GetALTROAcqStop()  )));
2196   if (GetALTROMasked()   ) prep.AddComponent(new AliTPCCalPad(*(GetALTROMasked()   )));
2197   //QA
2198   AliTPCdataQA *dataQA=GetDataQA();
2199   if (dataQA) {
2200     if (dataQA->GetNLocalMaxima())
2201       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNLocalMaxima())));
2202     if (dataQA->GetMaxCharge())
2203       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMaxCharge())));
2204     if (dataQA->GetMeanCharge())
2205       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMeanCharge())));
2206     if (dataQA->GetNoThreshold())
2207       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNoThreshold())));
2208     if (dataQA->GetNTimeBins())
2209       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNTimeBins())));
2210     if (dataQA->GetNPads())
2211       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNPads())));
2212     if (dataQA->GetTimePosition())
2213       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetTimePosition())));
2214   }
2215   
2216   //
2217   TString file(filename);
2218   if (file.IsNull()) file=Form("guiTreeRun_%i.root",fRun);
2219   prep.DumpToFile(file.Data());
2220   return kTRUE;
2221 }
2222
2223 Bool_t AliTPCcalibDB::CreateRefFile(Int_t run, const char* filename)
2224 {
2225   //
2226   // Create a gui tree for run number 'run'
2227   //
2228   
2229   if (!AliCDBManager::Instance()->GetDefaultStorage()){
2230     AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
2231                     MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
2232     return kFALSE;
2233   }
2234   TString file(filename);
2235   if (file.IsNull()) file=Form("RefCalPads_%d.root",run);
2236   TDirectory *currDir=gDirectory;
2237   //db instance
2238   AliTPCcalibDB *db=AliTPCcalibDB::Instance();
2239   // retrieve cal pad objects
2240   db->SetRun(run);
2241   //open file
2242   TFile f(file.Data(),"recreate");
2243   //noise and pedestals
2244   db->GetPedestals()->Write("Pedestals");
2245   db->GetPadNoise()->Write("PadNoise");
2246   //pulser data
2247   db->GetPulserTmean()->Write("PulserTmean");
2248   db->GetPulserTrms()->Write("PulserTrms");
2249   db->GetPulserQmean()->Write("PulserQmean");
2250   //CE data
2251   db->GetCETmean()->Write("CETmean");
2252   db->GetCETrms()->Write("CETrms");
2253   db->GetCEQmean()->Write("CEQmean");
2254   //Altro data
2255   db->GetALTROAcqStart() ->Write("ALTROAcqStart");
2256   db->GetALTROZsThr()    ->Write("ALTROZsThr");
2257   db->GetALTROFPED()     ->Write("ALTROFPED");
2258   db->GetALTROAcqStop()  ->Write("ALTROAcqStop");
2259   db->GetALTROMasked()   ->Write("ALTROMasked");
2260   //
2261   f.Close();
2262   currDir->cd();
2263   return kTRUE;
2264 }
2265
2266
2267
2268 Double_t AliTPCcalibDB::GetVDriftCorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
2269   //
2270   // Get time dependent drift velocity correction
2271   // multiplication factor        vd = vdnom *(1+vdriftcorr)
2272   // Arguments:
2273   // mode determines the algorith how to combine the Laser Track, LaserCE and physics tracks
2274   // timestamp - timestamp
2275   // run       - run number
2276   // side      - the drift velocity per side (possible for laser and CE)
2277   //
2278   // Notice - Extrapolation outside of calibration range  - using constant function
2279   //
2280   Double_t result=0;
2281   // mode 1  automatic mode - according to the distance to the valid calibration
2282   //                        -  
2283   Double_t deltaP=0,  driftP=0,      wP  = 0.;
2284   Double_t deltaITS=0,driftITS=0,    wITS= 0.;
2285   Double_t deltaLT=0, driftLT=0,     wLT = 0.;
2286   Double_t deltaCE=0, driftCE=0,     wCE = 0.;
2287   driftP  = fDButil->GetVDriftTPC(deltaP,run,timeStamp); 
2288   driftITS= fDButil->GetVDriftTPCITS(deltaITS,run,timeStamp);
2289   driftCE = fDButil->GetVDriftTPCCE(deltaCE, run,timeStamp,36000,2);
2290   driftLT = fDButil->GetVDriftTPCLaserTracks(deltaLT,run,timeStamp,36000,2);
2291   deltaITS = TMath::Abs(deltaITS);
2292   deltaP   = TMath::Abs(deltaP);
2293   deltaLT  = TMath::Abs(deltaLT);
2294   deltaCE  = TMath::Abs(deltaCE);
2295   if (mode==1) {
2296     const Double_t kEpsilon=0.00000000001;
2297     const Double_t kdeltaT=360.; // 10 minutes
2298     if(TMath::Abs(deltaITS) < 12*kdeltaT) {
2299       result = driftITS;
2300     } else {
2301     wITS  = 64.*kdeltaT/(deltaITS +kdeltaT);
2302     wLT   = 16.*kdeltaT/(deltaLT  +kdeltaT);
2303     wP    = 0. *kdeltaT/(deltaP   +kdeltaT);
2304     wCE   = 1. *kdeltaT/(deltaCE  +kdeltaT);
2305     //
2306     //
2307     if (TMath::Abs(driftP)<kEpsilon)  wP=0;  // invalid calibration
2308     if (TMath::Abs(driftITS)<kEpsilon)wITS=0;  // invalid calibration
2309     if (TMath::Abs(driftLT)<kEpsilon) wLT=0;  // invalid calibration
2310     if (TMath::Abs(driftCE)<kEpsilon) wCE=0;  // invalid calibration
2311     if (wP+wITS+wLT+wCE<kEpsilon) return 0;
2312     result = (driftP*wP+driftITS*wITS+driftLT*wLT+driftCE*wCE)/(wP+wITS+wLT+wCE);
2313    }
2314    
2315
2316   }
2317
2318   return result;
2319 }
2320
2321 Double_t AliTPCcalibDB::GetTime0CorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
2322   //
2323   // Get time dependent time 0 (trigger delay in cm) correction
2324   // additive correction        time0 = time0+ GetTime0CorrectionTime
2325   // Value etracted combining the vdrift correction using laser tracks and CE and the physics track matchin
2326   // Arguments:
2327   // mode determines the algorith how to combine the Laser Track and physics tracks
2328   // timestamp - timestamp
2329   // run       - run number
2330   // side      - the drift velocity per side (possible for laser and CE)
2331   //
2332   // Notice - Extrapolation outside of calibration range  - using constant function
2333   //
2334   Double_t result=0;
2335   if (mode==2) {
2336     // TPC-TPC mode
2337     result=fDButil->GetTriggerOffsetTPC(run,timeStamp);    
2338     result  *=fParam->GetZLength();
2339   }
2340   if (mode==1){
2341     // TPC-ITS mode
2342     Double_t dist=0;
2343     result= -fDButil->GetTime0TPCITS(dist, run, timeStamp)*fParam->GetDriftV()/1000000.;
2344   }
2345   return result;
2346
2347 }
2348
2349
2350
2351
2352 Double_t AliTPCcalibDB::GetVDriftCorrectionGy(Int_t timeStamp, Int_t run, Int_t side, Int_t /*mode*/){
2353   //
2354   // Get global y correction drift velocity correction factor
2355   // additive factor        vd = vdnom*(1+GetVDriftCorrectionGy *gy)
2356   // Value etracted combining the vdrift correction using laser tracks and CE or TPC-ITS
2357   // Arguments:
2358   // mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
2359   // timestamp - timestamp
2360   // run       - run number
2361   // side      - the drift velocity gy correction per side (CE and Laser tracks)
2362   //
2363   // Notice - Extrapolation outside of calibration range  - using constant function
2364   // 
2365   if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
2366   UpdateRunInformations(run,kFALSE);
2367   TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2368   if (!array) return 0;
2369   Double_t result=0;
2370
2371   // use TPC-ITS if present
2372   TGraphErrors *gr= (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_VDGY");
2373   if (!gr) gr = (TGraphErrors*)array->FindObject("ALIGN_TOFB_TPC_VDGY");
2374   if(gr) { 
2375     result = AliTPCcalibDButil::EvalGraphConst(gr,timeStamp);
2376
2377     // transform from [(cm/mus)/ m] to [1/cm]
2378     result /= (fParam->GetDriftV()/1000000.);
2379     result /= 100.;
2380
2381     //printf("result %e \n", result);
2382     return result; 
2383   }
2384
2385   // use laser if ITS-TPC not present
2386   TGraphErrors *laserA= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_A");
2387   TGraphErrors *laserC= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_C");
2388   
2389   if (laserA && laserC){
2390    result= (laserA->Eval(timeStamp)+laserC->Eval(timeStamp))*0.5;
2391   }
2392   if (laserA && side==0){
2393     result = (laserA->Eval(timeStamp));
2394   }
2395   if (laserC &&side==1){
2396     result = (laserC->Eval(timeStamp));
2397   }
2398   //printf("laser result %e \n", -result/250.);
2399
2400   return -result/250.; //normalized before
2401 }
2402
2403
2404 Double_t AliTPCcalibDB::GetVDriftCorrectionDeltaZ(Int_t /*timeStamp*/, Int_t run, Int_t /*side*/, Int_t /*mode*/){
2405   //
2406   // Get deltaZ run/by/run  correction - as fitted together with drift velocity
2407   // Value extracted  form the TPC-ITS, mean value is used
2408   
2409   // Arguments:
2410   // mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
2411   // timestamp - not used
2412   // run       - run number
2413   // side      - common for boith sides
2414   //
2415   if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
2416   UpdateRunInformations(run,kFALSE);
2417   TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2418   if (!array) return 0;
2419   Double_t result=0;
2420
2421   // use TPC-ITS if present
2422   TGraphErrors *gr= (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_DELTAZ");
2423   if(gr) { 
2424     result = TMath::Mean(gr->GetN(), gr->GetY());
2425   }
2426   return result;
2427 }
2428
2429
2430
2431
2432 AliTPCCalPad* AliTPCcalibDB::MakeDeadMap(Double_t notInMap, const char* nameMappingFile) {
2433 //
2434 //   Read list of active DDLs from OCDB entry
2435 //   Generate and return AliTPCCalPad containing 1 for all pads in active DDLs,
2436 //   0 for all pads in non-active DDLs. 
2437 //   For DDLs with missing status information (no DCS input point to Shuttle),
2438 //     the value of the AliTPCCalPad entry is determined by the parameter
2439 //     notInMap (default value 1)
2440 //
2441   char chinfo[1000];
2442    
2443   TFile *fileMapping = new TFile(nameMappingFile, "read");
2444   AliTPCmapper *mapping = (AliTPCmapper*) fileMapping->Get("tpcMapping");
2445   if (!mapping) {
2446     snprintf(chinfo,1000,"Failed to get mapping object from %s.  ...\n", nameMappingFile);
2447     AliError (chinfo);
2448     return 0;
2449   }
2450   
2451   AliTPCCalPad *deadMap = new AliTPCCalPad("deadMap","deadMap");
2452   if (!deadMap) {
2453      AliError("Failed to allocate dead map AliTPCCalPad");
2454      return 0;
2455   }  
2456   
2457   /// get list of active DDLs from OCDB entry
2458   Int_t idDDL=0;
2459   if (!fALTROConfigData ) {
2460      AliError("No ALTRO config OCDB entry available");
2461      return 0; 
2462   }
2463   TMap *activeDDL = (TMap*)fALTROConfigData->FindObject("DDLArray");
2464   TObjString *ddlArray=0;
2465   if (activeDDL) {
2466     ddlArray = (TObjString*)activeDDL->GetValue("DDLArray");
2467     if (!ddlArray) {
2468       AliError("Empty list of active DDLs in OCDB entry");
2469       return 0;
2470     }
2471   } else { 
2472     AliError("List of active DDLs not available in OCDB entry");
2473     return 0;
2474   }
2475   TString arrDDL=ddlArray->GetString();
2476   Int_t offset = mapping->GetTpcDdlOffset();
2477   Double_t active;
2478   for (Int_t i=0; i<mapping->GetNumDdl(); i++) {
2479     idDDL= i+offset;
2480     if (idDDL<0) continue;
2481     Int_t patch = mapping->GetPatchFromEquipmentID(idDDL);   
2482     if (patch<0) continue;
2483     Int_t roc=mapping->GetRocFromEquipmentID(idDDL);
2484     if (roc<0) continue;
2485     AliTPCCalROC *calRoc=deadMap->GetCalROC(roc);
2486     if (calRoc) {
2487      for ( Int_t branch = 0; branch < 2; branch++ ) {
2488       for ( Int_t fec = 0; fec < mapping->GetNfec(patch, branch); fec++ ) {
2489         for ( Int_t altro = 0; altro < 8; altro++ ) {
2490          for ( Int_t channel = 0; channel < 16; channel++ ) {
2491            Int_t hwadd     = mapping->CodeHWAddress(branch, fec, altro, channel);
2492            Int_t row       = mapping->GetPadRow(patch, hwadd);        // row in a ROC (IROC or OROC)
2493 //              Int_t globalrow = mapping.GetGlobalPadRow(patch, hwadd);  // row in full sector (IROC plus OROC)
2494            Int_t pad       = mapping->GetPad(patch, hwadd);
2495            if (!TString(arrDDL[i]).IsDigit()) {
2496               active = notInMap;
2497            } else { 
2498               active=TString(arrDDL[i]).Atof();
2499            }
2500            calRoc->SetValue(row,pad,active);
2501          } // end channel for loop
2502         } // end altro for loop
2503       } // end fec for loop
2504      } // end branch for loop
2505     } // valid calROC 
2506    } // end loop on active DDLs
2507    return deadMap;
2508 }
2509
2510
2511
2512 AliTPCCorrection * AliTPCcalibDB::GetTPCComposedCorrection(Float_t field) const{
2513   //
2514   // GetComposed correction for given field setting
2515   // If not specific correction for field used return correction for all field
2516   //        - Complication needed to gaurantee OCDB back compatibility 
2517   //        - Not neeeded for the new space point correction 
2518   if (!fComposedCorrectionArray) return 0;
2519   if (field>0.1 && fComposedCorrectionArray->At(1)) {   
2520     return (AliTPCCorrection *)fComposedCorrectionArray->At(1);
2521   }
2522   if (field<-0.1 &&fComposedCorrectionArray->At(2)) {
2523     return (AliTPCCorrection *)fComposedCorrectionArray->At(2);
2524   }
2525   return (AliTPCCorrection *)fComposedCorrectionArray->At(0);
2526   
2527 }
2528
2529
2530 AliTPCCorrection * AliTPCcalibDB::GetTPCComposedCorrectionDelta() const{
2531   //
2532   // GetComposedCorrection delta
2533   // Delta is time dependent - taken form the CalibTime OCDB entry
2534   //
2535   if (!fComposedCorrectionArray) return 0;
2536   if (fRun<0) return 0;
2537   if (fDriftCorrectionArray.GetValue(Form("%i",fRun))==0) return 0;
2538   if (fComposedCorrectionArray->GetEntriesFast()<=4) {
2539     fComposedCorrectionArray->Expand(5);
2540     TObjArray * timeArray =(TObjArray*)(fDriftCorrectionArray.GetValue(Form("%i",fRun)));
2541      AliTPCCorrection * correctionTime = (AliTPCCorrection *)timeArray->FindObject("FitCorrectionTime");
2542      if (correctionTime){
2543        correctionTime->Init();
2544        fComposedCorrectionArray->AddAt(correctionTime,4); //add time dependent c
2545      }
2546   }
2547   return (AliTPCCorrection *)fComposedCorrectionArray->At(4);  //
2548 }
2549
2550 Double_t AliTPCcalibDB::GetGainCorrectionHVandPT(Int_t timeStamp, Int_t run, Int_t sector, Int_t deltaCache, Int_t mode){
2551   //
2552   // Correction for  changes of gain caused by change of the HV and by relative change of the gas density
2553   // Function is slow some kind of caching needed
2554   // Cache implemented using the static TVectorD
2555   //
2556   // Input paremeters:
2557   //  deltaCache - maximal time differnce above which the cache is recaclulated
2558   //  mode       - mode==0 by default return combined correction 
2559   //                       actual HV and Pt correction has to be present in the run calibration otherwise it is ignored.
2560   //                       (retrun value differnt than 1 only in case calibration present in the OCDB entry CalibTimeGain
2561   //               mode==1 return combined correction ( important for calibration pass)
2562   //                       (in case thereis  no calibration in  CalibTimeGain, default value from the AliTPCParam (Parameters) is used
2563   //                       this mode is used in the CPass0
2564   //               mode==2 return HV correction
2565   //               mode==3 return P/T correction
2566   //  Usage in the simulation/reconstruction
2567   //  MC:     Qcorr  = Qorig*GetGainCorrectionHVandPT   ( in AliTPC.cxx ) 
2568   //  Rec:    dEdx   = dEdx/GetGainCorrectionHVandPT    ( in aliTPCseed.cxx )
2569   //
2570   static Float_t gGainCorrection[72];
2571   static Float_t gGainCorrectionPT[72];
2572   static Float_t gGainCorrectionHV[72];
2573   static Int_t    gTimeStamp=-99999999;
2574   static Bool_t   hasTimeDependent=kFALSE; 
2575   if ( TMath::Abs(timeStamp-gTimeStamp)> deltaCache){    
2576     //
2577     TGraphErrors * graphGHV = 0;
2578     TGraphErrors * graphGPT = 0;
2579     TObjArray *timeGainSplines = GetTimeGainSplinesRun(run);
2580     if (timeGainSplines){
2581       graphGHV  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesHV");
2582       graphGPT  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesPT");
2583       if (graphGHV) hasTimeDependent=kTRUE;
2584     }
2585     if (!graphGHV) graphGHV = fParam->GetGainSlopesHV();
2586     if (!graphGPT) graphGPT = fParam->GetGainSlopesPT();
2587     //
2588     for (Int_t isec=0; isec<72; isec++){
2589       Double_t deltaHV= GetChamberHighVoltage(run,isec, timeStamp) - fParam->GetNominalVoltage(isec);
2590       Double_t deltaGHV=0;
2591       Double_t deltaGPT=0;
2592       if (graphGHV) deltaGHV = graphGHV->GetY()[isec]*deltaHV;
2593       if (graphGPT) deltaGPT = graphGPT->GetY()[isec]*GetPTRelative(timeStamp,run,0);
2594       gGainCorrection[isec]=(1.+deltaGHV)*(1.+deltaGPT);
2595       gGainCorrectionPT[isec]=1+deltaGPT;
2596       gGainCorrectionHV[isec]=1+deltaGHV;
2597     }    
2598     gTimeStamp=timeStamp;
2599   }
2600   if (mode==0){
2601     if (hasTimeDependent) return gGainCorrection[sector];
2602     if (!hasTimeDependent) return 1;
2603   }
2604   if (mode==1) return gGainCorrection[sector];
2605   if (mode==2) return gGainCorrectionPT[sector];
2606   if (mode==3) return gGainCorrectionHV[sector];
2607   return 1;
2608 }