skip clusters when the roc voltage is funny
[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 {
1772       AliError(Form("No Graph or too few points found for HV sensor of ROC %d",iROC));
1773     }
1774   }
1775
1776   delete [] vSampled;
1777   vSampled=0x0;
1778   
1779   // get median deviation from all chambers (detect e.g. -50V)
1780   const Double_t medianIROC=TMath::Median( 36, chamberMedianDeviation );
1781   const Double_t medianOROC=TMath::Median( 36, chamberMedianDeviation+36 );
1782   
1783   // Define current default voltages
1784   for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
1785     const Float_t averageDeviation=(iROC<36)?medianIROC:medianOROC;
1786     fCurrentNominalVoltage[iROC]=fParam->GetNominalVoltage(iROC)+averageDeviation;
1787   }
1788
1789   //
1790   // Check HV status
1791   //
1792   for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
1793     fChamberHVStatus[iROC]=kTRUE;
1794
1795     //a. Deviation of median from current nominal voltage
1796     //   allow larger than nominal voltages
1797     if (fCurrentNominalVoltage[iROC]-fChamberHVmedian[iROC] >  maxVdiff) fChamberHVStatus[iROC]=kFALSE;
1798
1799     //b. Fraction of bad hv values
1800     if ( 1-fChamberHVgoodFraction[iROC] > maxFracHVbad ) fChamberHVStatus[iROC]=kFALSE;
1801   }
1802 }
1803
1804 Float_t AliTPCcalibDB::GetChamberHighVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits, Bool_t current) {
1805   //
1806   // return the chamber HV for given run and time: 0-35 IROC, 36-72 OROC
1807   // if timeStamp==-1 return mean value
1808   //
1809   Float_t val=0;
1810   TString sensorName="";
1811   TTimeStamp stamp(timeStamp);
1812   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1813   if (!voltageArray || (sector<0) || (sector>71)) return val;
1814   Char_t sideName='A';
1815   if ((sector/18)%2==1) sideName='C';
1816   if (sector<36){
1817     //IROC
1818     sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
1819   }else{
1820     //OROC
1821     sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
1822   }
1823   if (current){
1824     if (sector<36){
1825       //IROC
1826       sensorName=Form("TPC_ANODE_I_%c%02d_IMEAS",sideName,sector%18);
1827     }else{
1828       //OROC
1829       sensorName=Form("TPC_ANODE_O_%c%02d_0_IMEAS",sideName,sector%18);
1830     }
1831     
1832   }
1833   if (timeStamp==-1){
1834     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1835   } else {
1836     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1837   }
1838   return val;
1839 }
1840 Float_t AliTPCcalibDB::GetSkirtVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1841 {
1842   //
1843   // Get the skirt voltage for 'run' at 'timeStamp' and 'sector': 0-35 IROC, 36-72 OROC
1844   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1845   // if timeStamp==-1 return the mean value for the run
1846   //
1847   Float_t val=0;
1848   TString sensorName="";
1849   TTimeStamp stamp(timeStamp);
1850   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1851   if (!voltageArray || (sector<0) || (sector>71)) return val;
1852   Char_t sideName='A';
1853   if ((sector/18)%2==1) sideName='C';
1854   sensorName=Form("TPC_SKIRT_%c_VMEAS",sideName);
1855   if (timeStamp==-1){
1856     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1857   } else {
1858     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1859   }
1860   return val;
1861 }
1862
1863 Float_t AliTPCcalibDB::GetCoverVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1864 {
1865   //
1866   // Get the cover voltage for run 'run' at time 'timeStamp'
1867   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1868   // if timeStamp==-1 return the mean value for the run
1869   //
1870   Float_t val=0;
1871   TString sensorName="";
1872   TTimeStamp stamp(timeStamp);
1873   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1874   if (!voltageArray || (sector<0) || (sector>71)) return val;
1875   Char_t sideName='A';
1876   if ((sector/18)%2==1) sideName='C';
1877   if (sector<36){
1878     //IROC
1879     sensorName=Form("TPC_COVER_I_%c_VMEAS",sideName);
1880   }else{
1881     //OROC
1882     sensorName=Form("TPC_COVER_O_%c_VMEAS",sideName);
1883   }
1884   if (timeStamp==-1){
1885     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1886   } else {
1887     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1888   }
1889   return val;
1890 }
1891
1892 Float_t AliTPCcalibDB::GetGGoffsetVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1893 {
1894   //
1895   // Get the GG offset voltage for run 'run' at time 'timeStamp'
1896   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1897   // if timeStamp==-1 return the mean value for the run
1898   //
1899   Float_t val=0;
1900   TString sensorName="";
1901   TTimeStamp stamp(timeStamp);
1902   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1903   if (!voltageArray || (sector<0) || (sector>71)) return val;
1904   Char_t sideName='A';
1905   if ((sector/18)%2==1) sideName='C';
1906   if (sector<36){
1907     //IROC
1908     sensorName=Form("TPC_GATE_I_%c_OFF_VMEAS",sideName);
1909   }else{
1910     //OROC
1911     sensorName=Form("TPC_GATE_O_%c_OFF_VMEAS",sideName);
1912   }
1913   if (timeStamp==-1){
1914     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1915   } else {
1916     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1917   }
1918   return val;
1919 }
1920
1921 Float_t AliTPCcalibDB::GetGGnegVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1922 {
1923   //
1924   // Get the GG offset voltage for run 'run' at time 'timeStamp'
1925   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1926   // if timeStamp==-1 return the mean value for the run
1927   //
1928   Float_t val=0;
1929   TString sensorName="";
1930   TTimeStamp stamp(timeStamp);
1931   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1932   if (!voltageArray || (sector<0) || (sector>71)) return val;
1933   Char_t sideName='A';
1934   if ((sector/18)%2==1) sideName='C';
1935   if (sector<36){
1936     //IROC
1937     sensorName=Form("TPC_GATE_I_%c_NEG_VMEAS",sideName);
1938   }else{
1939     //OROC
1940     sensorName=Form("TPC_GATE_O_%c_NEG_VMEAS",sideName);
1941   }
1942   if (timeStamp==-1){
1943     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1944   } else {
1945     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1946   }
1947   return val;
1948 }
1949
1950 Float_t AliTPCcalibDB::GetGGposVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1951 {
1952   //
1953   // Get the GG offset voltage for run 'run' at time 'timeStamp'
1954   // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1955   // if timeStamp==-1 return the mean value for the run
1956   //
1957   Float_t val=0;
1958   TString sensorName="";
1959   TTimeStamp stamp(timeStamp);
1960   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1961   if (!voltageArray || (sector<0) || (sector>71)) return val;
1962   Char_t sideName='A';
1963   if ((sector/18)%2==1) sideName='C';
1964   if (sector<36){
1965     //IROC
1966     sensorName=Form("TPC_GATE_I_%c_POS_VMEAS",sideName);
1967   }else{
1968     //OROC
1969     sensorName=Form("TPC_GATE_O_%c_POS_VMEAS",sideName);
1970   }
1971   if (timeStamp==-1){
1972     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1973   } else {
1974     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1975   }
1976   return val;
1977 }
1978
1979 Float_t AliTPCcalibDB::GetPressure(Int_t timeStamp, Int_t run, Int_t type){
1980   //
1981   // GetPressure for given time stamp and runt
1982   //
1983   TTimeStamp stamp(timeStamp);
1984   AliDCSSensor * sensor = Instance()->GetPressureSensor(run,type);
1985   if (!sensor) return 0;
1986   return sensor->GetValue(stamp);
1987 }
1988
1989 Float_t AliTPCcalibDB::GetL3Current(Int_t run, Int_t statType){
1990   //
1991   // return L3 current
1992   // stat type is: AliGRPObject::Stats: kMean = 0, kTruncMean = 1, kMedian = 2, kSDMean = 3, kSDMedian = 4
1993   //
1994   Float_t current=-1;
1995   AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
1996   if (grp) current=grp->GetL3Current((AliGRPObject::Stats)statType);
1997   return current;
1998 }
1999
2000 Float_t AliTPCcalibDB::GetBz(Int_t run){
2001   //
2002   // calculate BZ in T from L3 current
2003   //
2004   Float_t bz=-1;
2005   Float_t current=AliTPCcalibDB::GetL3Current(run);
2006   if (current>-1) bz=5*current/30000.*.1;
2007   return bz;
2008 }
2009
2010 Char_t  AliTPCcalibDB::GetL3Polarity(Int_t run) {
2011   //
2012   // get l3 polarity from GRP
2013   //
2014   Char_t pol=-100;
2015   AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2016   if (grp) pol=grp->GetL3Polarity();
2017   return pol;
2018 }
2019
2020 TString AliTPCcalibDB::GetRunType(Int_t run){
2021   //
2022   // return run type from grp
2023   //
2024
2025 //   TString type("UNKNOWN");
2026   AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2027   if (grp) return grp->GetRunType();
2028   return "UNKNOWN";
2029 }
2030
2031 Float_t AliTPCcalibDB::GetValueGoofie(Int_t timeStamp, Int_t run, Int_t type){
2032   //
2033   // GetPressure for given time stamp and runt
2034   //
2035   TTimeStamp stamp(timeStamp);
2036   AliDCSSensorArray* goofieArray = AliTPCcalibDB::Instance()->GetGoofieSensors(run);
2037   if (!goofieArray) return 0;
2038   AliDCSSensor *sensor = goofieArray->GetSensor(type);
2039   return sensor->GetValue(stamp);
2040 }
2041
2042
2043
2044
2045
2046
2047 Bool_t  AliTPCcalibDB::GetTemperatureFit(Int_t timeStamp, Int_t run, Int_t side,TVectorD& fit){
2048   //
2049   // GetTmeparature fit at parameter for given time stamp
2050   //
2051   TTimeStamp tstamp(timeStamp);
2052   AliTPCSensorTempArray* tempArray  = Instance()->GetTemperatureSensor(run);
2053   if (! tempArray) return kFALSE;
2054   AliTPCTempMap * tempMap = new AliTPCTempMap(tempArray);
2055   TLinearFitter * fitter = tempMap->GetLinearFitter(3,side,tstamp);
2056   if (fitter){
2057     fitter->Eval(); 
2058     fitter->GetParameters(fit);
2059   }
2060   delete fitter;
2061   delete tempMap;
2062   if (!fitter) return kFALSE;
2063   return kTRUE;
2064 }
2065
2066 Float_t AliTPCcalibDB::GetTemperature(Int_t timeStamp, Int_t run, Int_t side){
2067   //
2068   // Get mean temperature
2069   // 
2070   TVectorD vec(5);
2071   if (side==0) {
2072     GetTemperatureFit(timeStamp,run,0,vec);
2073     return vec[0];
2074   }
2075   if (side==1){
2076     GetTemperatureFit(timeStamp,run,0,vec);
2077     return vec[0];
2078   }
2079   return 0;
2080 }
2081
2082
2083 Double_t AliTPCcalibDB::GetPTRelative(UInt_t timeSec, Int_t run, Int_t side){
2084   //
2085   // Get relative P/T 
2086   // time - absolute time
2087   // run  - run number
2088   // side - 0 - A side   1-C side
2089   AliTPCCalibVdrift * vdrift =  Instance()->GetVdrift(run);
2090   if (!vdrift) return 0;
2091   return vdrift->GetPTRelative(timeSec,side);
2092 }
2093
2094 AliGRPObject * AliTPCcalibDB::MakeGRPObjectFromMap(TMap *map){
2095   //
2096   // Function to covert old GRP run information from TMap to GRPObject
2097   //
2098   //  TMap * map = AliTPCcalibDB::GetGRPMap(52406);
2099   if (!map) return 0;
2100   AliDCSSensor * sensor = 0;
2101   TObject *osensor=0;
2102   osensor = ((*map)("fP2Pressure"));
2103   sensor  =dynamic_cast<AliDCSSensor *>(osensor); 
2104   //
2105   if (!sensor) return 0;
2106   //
2107   AliDCSSensor * sensor2 = new AliDCSSensor(*sensor);
2108   osensor = ((*map)("fCavernPressure"));
2109   TGraph * gr = new TGraph(2);
2110   gr->GetX()[0]= -100000.;
2111   gr->GetX()[1]= 1000000.;
2112   gr->GetY()[0]= atof(osensor->GetName());
2113   gr->GetY()[1]= atof(osensor->GetName());
2114   sensor2->SetGraph(gr);
2115   sensor2->SetFit(0);
2116   
2117
2118   AliGRPObject *grpRun = new AliGRPObject; 
2119   grpRun->ReadValuesFromMap(map);
2120   grpRun->SetCavernAtmosPressure(sensor2);
2121   grpRun->SetCavernAtmosPressure(sensor2);
2122   grpRun->SetSurfaceAtmosPressure(sensor);
2123   return grpRun;
2124 }
2125
2126 Bool_t AliTPCcalibDB::CreateGUITree(Int_t run, const char* filename)
2127 {
2128   //
2129   // Create a gui tree for run number 'run'
2130   //
2131
2132   if (!AliCDBManager::Instance()->GetDefaultStorage()){
2133     AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
2134                     MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
2135     return kFALSE;
2136   }
2137   //db instance
2138   AliTPCcalibDB *db=AliTPCcalibDB::Instance();
2139   // retrieve cal pad objects
2140   db->SetRun(run);
2141   db->CreateGUITree(filename);
2142   return kTRUE;
2143 }
2144
2145 Bool_t AliTPCcalibDB::CreateGUITree(const char* filename){
2146   //
2147   //
2148   //
2149   if (!AliCDBManager::Instance()->GetDefaultStorage()){
2150     AliError("Default Storage not set. Cannot create calibration Tree!");
2151     return kFALSE;
2152   }
2153   UpdateNonRec();  // load all infromation now
2154
2155   AliTPCPreprocessorOnline prep;
2156   //noise and pedestals
2157   if (GetPedestals()) prep.AddComponent(new AliTPCCalPad(*(GetPedestals())));
2158   if (GetPadNoise() ) prep.AddComponent(new AliTPCCalPad(*(GetPadNoise())));
2159   //pulser data
2160   if (GetPulserTmean()) prep.AddComponent(new AliTPCCalPad(*(GetPulserTmean())));
2161   if (GetPulserTrms() ) prep.AddComponent(new AliTPCCalPad(*(GetPulserTrms())));
2162   if (GetPulserQmean()) prep.AddComponent(new AliTPCCalPad(*(GetPulserQmean())));
2163   //CE data
2164   if (GetCETmean()) prep.AddComponent(new AliTPCCalPad(*(GetCETmean())));
2165   if (GetCETrms() ) prep.AddComponent(new AliTPCCalPad(*(GetCETrms())));
2166   if (GetCEQmean()) prep.AddComponent(new AliTPCCalPad(*(GetCEQmean())));
2167   //Altro data
2168   if (GetALTROAcqStart() ) prep.AddComponent(new AliTPCCalPad(*(GetALTROAcqStart() )));
2169   if (GetALTROZsThr()    ) prep.AddComponent(new AliTPCCalPad(*(GetALTROZsThr()    )));
2170   if (GetALTROFPED()     ) prep.AddComponent(new AliTPCCalPad(*(GetALTROFPED()     )));
2171   if (GetALTROAcqStop()  ) prep.AddComponent(new AliTPCCalPad(*(GetALTROAcqStop()  )));
2172   if (GetALTROMasked()   ) prep.AddComponent(new AliTPCCalPad(*(GetALTROMasked()   )));
2173   //QA
2174   AliTPCdataQA *dataQA=GetDataQA();
2175   if (dataQA) {
2176     if (dataQA->GetNLocalMaxima())
2177       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNLocalMaxima())));
2178     if (dataQA->GetMaxCharge())
2179       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMaxCharge())));
2180     if (dataQA->GetMeanCharge())
2181       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMeanCharge())));
2182     if (dataQA->GetNoThreshold())
2183       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNoThreshold())));
2184     if (dataQA->GetNTimeBins())
2185       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNTimeBins())));
2186     if (dataQA->GetNPads())
2187       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNPads())));
2188     if (dataQA->GetTimePosition())
2189       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetTimePosition())));
2190   }
2191   
2192   //
2193   TString file(filename);
2194   if (file.IsNull()) file=Form("guiTreeRun_%i.root",fRun);
2195   prep.DumpToFile(file.Data());
2196   return kTRUE;
2197 }
2198
2199 Bool_t AliTPCcalibDB::CreateRefFile(Int_t run, const char* filename)
2200 {
2201   //
2202   // Create a gui tree for run number 'run'
2203   //
2204   
2205   if (!AliCDBManager::Instance()->GetDefaultStorage()){
2206     AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
2207                     MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
2208     return kFALSE;
2209   }
2210   TString file(filename);
2211   if (file.IsNull()) file=Form("RefCalPads_%d.root",run);
2212   TDirectory *currDir=gDirectory;
2213   //db instance
2214   AliTPCcalibDB *db=AliTPCcalibDB::Instance();
2215   // retrieve cal pad objects
2216   db->SetRun(run);
2217   //open file
2218   TFile f(file.Data(),"recreate");
2219   //noise and pedestals
2220   db->GetPedestals()->Write("Pedestals");
2221   db->GetPadNoise()->Write("PadNoise");
2222   //pulser data
2223   db->GetPulserTmean()->Write("PulserTmean");
2224   db->GetPulserTrms()->Write("PulserTrms");
2225   db->GetPulserQmean()->Write("PulserQmean");
2226   //CE data
2227   db->GetCETmean()->Write("CETmean");
2228   db->GetCETrms()->Write("CETrms");
2229   db->GetCEQmean()->Write("CEQmean");
2230   //Altro data
2231   db->GetALTROAcqStart() ->Write("ALTROAcqStart");
2232   db->GetALTROZsThr()    ->Write("ALTROZsThr");
2233   db->GetALTROFPED()     ->Write("ALTROFPED");
2234   db->GetALTROAcqStop()  ->Write("ALTROAcqStop");
2235   db->GetALTROMasked()   ->Write("ALTROMasked");
2236   //
2237   f.Close();
2238   currDir->cd();
2239   return kTRUE;
2240 }
2241
2242
2243
2244 Double_t AliTPCcalibDB::GetVDriftCorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
2245   //
2246   // Get time dependent drift velocity correction
2247   // multiplication factor        vd = vdnom *(1+vdriftcorr)
2248   // Arguments:
2249   // mode determines the algorith how to combine the Laser Track, LaserCE and physics tracks
2250   // timestamp - timestamp
2251   // run       - run number
2252   // side      - the drift velocity per side (possible for laser and CE)
2253   //
2254   // Notice - Extrapolation outside of calibration range  - using constant function
2255   //
2256   Double_t result=0;
2257   // mode 1  automatic mode - according to the distance to the valid calibration
2258   //                        -  
2259   Double_t deltaP=0,  driftP=0,      wP  = 0.;
2260   Double_t deltaITS=0,driftITS=0,    wITS= 0.;
2261   Double_t deltaLT=0, driftLT=0,     wLT = 0.;
2262   Double_t deltaCE=0, driftCE=0,     wCE = 0.;
2263   driftP  = fDButil->GetVDriftTPC(deltaP,run,timeStamp); 
2264   driftITS= fDButil->GetVDriftTPCITS(deltaITS,run,timeStamp);
2265   driftCE = fDButil->GetVDriftTPCCE(deltaCE, run,timeStamp,36000,2);
2266   driftLT = fDButil->GetVDriftTPCLaserTracks(deltaLT,run,timeStamp,36000,2);
2267   deltaITS = TMath::Abs(deltaITS);
2268   deltaP   = TMath::Abs(deltaP);
2269   deltaLT  = TMath::Abs(deltaLT);
2270   deltaCE  = TMath::Abs(deltaCE);
2271   if (mode==1) {
2272     const Double_t kEpsilon=0.00000000001;
2273     const Double_t kdeltaT=360.; // 10 minutes
2274     if(TMath::Abs(deltaITS) < 12*kdeltaT) {
2275       result = driftITS;
2276     } else {
2277     wITS  = 64.*kdeltaT/(deltaITS +kdeltaT);
2278     wLT   = 16.*kdeltaT/(deltaLT  +kdeltaT);
2279     wP    = 0. *kdeltaT/(deltaP   +kdeltaT);
2280     wCE   = 1. *kdeltaT/(deltaCE  +kdeltaT);
2281     //
2282     //
2283     if (TMath::Abs(driftP)<kEpsilon)  wP=0;  // invalid calibration
2284     if (TMath::Abs(driftITS)<kEpsilon)wITS=0;  // invalid calibration
2285     if (TMath::Abs(driftLT)<kEpsilon) wLT=0;  // invalid calibration
2286     if (TMath::Abs(driftCE)<kEpsilon) wCE=0;  // invalid calibration
2287     if (wP+wITS+wLT+wCE<kEpsilon) return 0;
2288     result = (driftP*wP+driftITS*wITS+driftLT*wLT+driftCE*wCE)/(wP+wITS+wLT+wCE);
2289    }
2290    
2291
2292   }
2293
2294   return result;
2295 }
2296
2297 Double_t AliTPCcalibDB::GetTime0CorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
2298   //
2299   // Get time dependent time 0 (trigger delay in cm) correction
2300   // additive correction        time0 = time0+ GetTime0CorrectionTime
2301   // Value etracted combining the vdrift correction using laser tracks and CE and the physics track matchin
2302   // Arguments:
2303   // mode determines the algorith how to combine the Laser Track and physics tracks
2304   // timestamp - timestamp
2305   // run       - run number
2306   // side      - the drift velocity per side (possible for laser and CE)
2307   //
2308   // Notice - Extrapolation outside of calibration range  - using constant function
2309   //
2310   Double_t result=0;
2311   if (mode==2) {
2312     // TPC-TPC mode
2313     result=fDButil->GetTriggerOffsetTPC(run,timeStamp);    
2314     result  *=fParam->GetZLength();
2315   }
2316   if (mode==1){
2317     // TPC-ITS mode
2318     Double_t dist=0;
2319     result= -fDButil->GetTime0TPCITS(dist, run, timeStamp)*fParam->GetDriftV()/1000000.;
2320   }
2321   return result;
2322
2323 }
2324
2325
2326
2327
2328 Double_t AliTPCcalibDB::GetVDriftCorrectionGy(Int_t timeStamp, Int_t run, Int_t side, Int_t /*mode*/){
2329   //
2330   // Get global y correction drift velocity correction factor
2331   // additive factor        vd = vdnom*(1+GetVDriftCorrectionGy *gy)
2332   // Value etracted combining the vdrift correction using laser tracks and CE or TPC-ITS
2333   // Arguments:
2334   // mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
2335   // timestamp - timestamp
2336   // run       - run number
2337   // side      - the drift velocity gy correction per side (CE and Laser tracks)
2338   //
2339   // Notice - Extrapolation outside of calibration range  - using constant function
2340   // 
2341   if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
2342   UpdateRunInformations(run,kFALSE);
2343   TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2344   if (!array) return 0;
2345   Double_t result=0;
2346
2347   // use TPC-ITS if present
2348   TGraphErrors *gr= (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_VDGY");
2349   if (!gr) gr = (TGraphErrors*)array->FindObject("ALIGN_TOFB_TPC_VDGY");
2350   if(gr) { 
2351     result = AliTPCcalibDButil::EvalGraphConst(gr,timeStamp);
2352
2353     // transform from [(cm/mus)/ m] to [1/cm]
2354     result /= (fParam->GetDriftV()/1000000.);
2355     result /= 100.;
2356
2357     //printf("result %e \n", result);
2358     return result; 
2359   }
2360
2361   // use laser if ITS-TPC not present
2362   TGraphErrors *laserA= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_A");
2363   TGraphErrors *laserC= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_C");
2364   
2365   if (laserA && laserC){
2366    result= (laserA->Eval(timeStamp)+laserC->Eval(timeStamp))*0.5;
2367   }
2368   if (laserA && side==0){
2369     result = (laserA->Eval(timeStamp));
2370   }
2371   if (laserC &&side==1){
2372     result = (laserC->Eval(timeStamp));
2373   }
2374   //printf("laser result %e \n", -result/250.);
2375
2376   return -result/250.; //normalized before
2377 }
2378
2379
2380 Double_t AliTPCcalibDB::GetVDriftCorrectionDeltaZ(Int_t /*timeStamp*/, Int_t run, Int_t /*side*/, Int_t /*mode*/){
2381   //
2382   // Get deltaZ run/by/run  correction - as fitted together with drift velocity
2383   // Value extracted  form the TPC-ITS, mean value is used
2384   
2385   // Arguments:
2386   // mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
2387   // timestamp - not used
2388   // run       - run number
2389   // side      - common for boith sides
2390   //
2391   if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
2392   UpdateRunInformations(run,kFALSE);
2393   TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2394   if (!array) return 0;
2395   Double_t result=0;
2396
2397   // use TPC-ITS if present
2398   TGraphErrors *gr= (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_DELTAZ");
2399   if(gr) { 
2400     result = TMath::Mean(gr->GetN(), gr->GetY());
2401   }
2402   return result;
2403 }
2404
2405
2406
2407
2408 AliTPCCalPad* AliTPCcalibDB::MakeDeadMap(Double_t notInMap, const char* nameMappingFile) {
2409 //
2410 //   Read list of active DDLs from OCDB entry
2411 //   Generate and return AliTPCCalPad containing 1 for all pads in active DDLs,
2412 //   0 for all pads in non-active DDLs. 
2413 //   For DDLs with missing status information (no DCS input point to Shuttle),
2414 //     the value of the AliTPCCalPad entry is determined by the parameter
2415 //     notInMap (default value 1)
2416 //
2417   char chinfo[1000];
2418    
2419   TFile *fileMapping = new TFile(nameMappingFile, "read");
2420   AliTPCmapper *mapping = (AliTPCmapper*) fileMapping->Get("tpcMapping");
2421   if (!mapping) {
2422     snprintf(chinfo,1000,"Failed to get mapping object from %s.  ...\n", nameMappingFile);
2423     AliError (chinfo);
2424     return 0;
2425   }
2426   
2427   AliTPCCalPad *deadMap = new AliTPCCalPad("deadMap","deadMap");
2428   if (!deadMap) {
2429      AliError("Failed to allocate dead map AliTPCCalPad");
2430      return 0;
2431   }  
2432   
2433   /// get list of active DDLs from OCDB entry
2434   Int_t idDDL=0;
2435   if (!fALTROConfigData ) {
2436      AliError("No ALTRO config OCDB entry available");
2437      return 0; 
2438   }
2439   TMap *activeDDL = (TMap*)fALTROConfigData->FindObject("DDLArray");
2440   TObjString *ddlArray=0;
2441   if (activeDDL) {
2442     ddlArray = (TObjString*)activeDDL->GetValue("DDLArray");
2443     if (!ddlArray) {
2444       AliError("Empty list of active DDLs in OCDB entry");
2445       return 0;
2446     }
2447   } else { 
2448     AliError("List of active DDLs not available in OCDB entry");
2449     return 0;
2450   }
2451   TString arrDDL=ddlArray->GetString();
2452   Int_t offset = mapping->GetTpcDdlOffset();
2453   Double_t active;
2454   for (Int_t i=0; i<mapping->GetNumDdl(); i++) {
2455     idDDL= i+offset;
2456     if (idDDL<0) continue;
2457     Int_t patch = mapping->GetPatchFromEquipmentID(idDDL);   
2458     if (patch<0) continue;
2459     Int_t roc=mapping->GetRocFromEquipmentID(idDDL);
2460     if (roc<0) continue;
2461     AliTPCCalROC *calRoc=deadMap->GetCalROC(roc);
2462     if (calRoc) {
2463      for ( Int_t branch = 0; branch < 2; branch++ ) {
2464       for ( Int_t fec = 0; fec < mapping->GetNfec(patch, branch); fec++ ) {
2465         for ( Int_t altro = 0; altro < 8; altro++ ) {
2466          for ( Int_t channel = 0; channel < 16; channel++ ) {
2467            Int_t hwadd     = mapping->CodeHWAddress(branch, fec, altro, channel);
2468            Int_t row       = mapping->GetPadRow(patch, hwadd);        // row in a ROC (IROC or OROC)
2469 //              Int_t globalrow = mapping.GetGlobalPadRow(patch, hwadd);  // row in full sector (IROC plus OROC)
2470            Int_t pad       = mapping->GetPad(patch, hwadd);
2471            if (!TString(arrDDL[i]).IsDigit()) {
2472               active = notInMap;
2473            } else { 
2474               active=TString(arrDDL[i]).Atof();
2475            }
2476            calRoc->SetValue(row,pad,active);
2477          } // end channel for loop
2478         } // end altro for loop
2479       } // end fec for loop
2480      } // end branch for loop
2481     } // valid calROC 
2482    } // end loop on active DDLs
2483    return deadMap;
2484 }
2485
2486
2487
2488 AliTPCCorrection * AliTPCcalibDB::GetTPCComposedCorrection(Float_t field) const{
2489   //
2490   // GetComposed correction for given field setting
2491   // If not specific correction for field used return correction for all field
2492   //        - Complication needed to gaurantee OCDB back compatibility 
2493   //        - Not neeeded for the new space point correction 
2494   if (!fComposedCorrectionArray) return 0;
2495   if (field>0.1 && fComposedCorrectionArray->At(1)) {   
2496     return (AliTPCCorrection *)fComposedCorrectionArray->At(1);
2497   }
2498   if (field<-0.1 &&fComposedCorrectionArray->At(2)) {
2499     return (AliTPCCorrection *)fComposedCorrectionArray->At(2);
2500   }
2501   return (AliTPCCorrection *)fComposedCorrectionArray->At(0);
2502   
2503 }
2504
2505
2506 AliTPCCorrection * AliTPCcalibDB::GetTPCComposedCorrectionDelta() const{
2507   //
2508   // GetComposedCorrection delta
2509   // Delta is time dependent - taken form the CalibTime OCDB entry
2510   //
2511   if (!fComposedCorrectionArray) return 0;
2512   if (fRun<0) return 0;
2513   if (fDriftCorrectionArray.GetValue(Form("%i",fRun))==0) return 0;
2514   if (fComposedCorrectionArray->GetEntriesFast()<=4) {
2515     fComposedCorrectionArray->Expand(5);
2516     TObjArray * timeArray =(TObjArray*)(fDriftCorrectionArray.GetValue(Form("%i",fRun)));
2517      AliTPCCorrection * correctionTime = (AliTPCCorrection *)timeArray->FindObject("FitCorrectionTime");
2518      if (correctionTime){
2519        correctionTime->Init();
2520        fComposedCorrectionArray->AddAt(correctionTime,4); //add time dependent c
2521      }
2522   }
2523   return (AliTPCCorrection *)fComposedCorrectionArray->At(4);  //
2524 }
2525
2526 Double_t AliTPCcalibDB::GetGainCorrectionHVandPT(Int_t timeStamp, Int_t run, Int_t sector, Int_t deltaCache, Int_t mode){
2527   //
2528   // Correction for  changes of gain caused by change of the HV and by relative change of the gas density
2529   // Function is slow some kind of caching needed
2530   // Cache implemented using the static TVectorD
2531   //
2532   // Input paremeters:
2533   //  deltaCache - maximal time differnce above which the cache is recaclulated
2534   //  mode       - mode==0 by default return combined correction 
2535   //                       actual HV and Pt correction has to be present in the run calibration otherwise it is ignored.
2536   //                      
2537   //               mode==1 return combined correction ( important for calibration pass)
2538   //
2539   //               mode==2 return HV correction
2540   //               mode==3 return P/T correction
2541   //  Usage in the simulation/reconstruction
2542   //  MC:     Qcorr  = Qorig*GetGainCorrectionHVandPT   ( in AliTPC.cxx ) 
2543   //  Rec:    dEdx   = dEdx/GetGainCorrectionHVandPT    ( in aliTPCseed.cxx )
2544   //
2545   static Float_t gGainCorrection[72];
2546   static Float_t gGainCorrectionPT[72];
2547   static Float_t gGainCorrectionHV[72];
2548   static Int_t    gTimeStamp=0;
2549   static Bool_t   hasTimeDependent=kFALSE; 
2550   if ( TMath::Abs(timeStamp-gTimeStamp)> deltaCache){    
2551     //
2552     TGraphErrors * graphGHV = 0;
2553     TGraphErrors * graphGPT = 0;
2554     TObjArray *timeGainSplines = GetTimeGainSplinesRun(run);
2555     if (timeGainSplines){
2556       graphGHV  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesHV");
2557       graphGPT  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesPT");
2558       if (graphGHV) hasTimeDependent=kTRUE;
2559     }
2560     if (!graphGHV) graphGHV = fParam->GetGainSlopesHV();
2561     if (!graphGPT) graphGPT = fParam->GetGainSlopesPT();
2562     //
2563     for (Int_t isec=0; isec<72; isec++){
2564       Double_t deltaHV= GetChamberHighVoltage(run,isec, timeStamp) - fParam->GetNominalVoltage(isec);
2565       Double_t deltaGHV=0;
2566       Double_t deltaGPT=0;
2567       if (graphGHV) deltaGHV = graphGHV->GetY()[isec]*deltaHV;
2568       if (graphGPT) deltaGPT = graphGPT->GetY()[isec]*GetPTRelative(timeStamp,run,0);
2569       gGainCorrection[isec]=(1.+deltaGHV)*(1.+deltaGPT);
2570       gGainCorrectionPT[isec]=1+deltaGPT;
2571       gGainCorrectionHV[isec]=1+deltaGHV;
2572     }    
2573     gTimeStamp=timeStamp;
2574   }
2575   if (mode==0){
2576     if (hasTimeDependent) return gGainCorrection[sector];
2577     if (!hasTimeDependent) return 1;
2578   }
2579   if (mode==1) return gGainCorrection[sector];
2580   if (mode==2) return gGainCorrectionPT[sector];
2581   if (mode==3) return gGainCorrectionHV[sector];
2582   return 1;
2583 }