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