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