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