635feb098155ce401489e62e65eb5566db13b2c8
[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   /// Initialize DeadChannel Map
795   /// Source of information:
796   /// -  HV (see UpdateChamberHighVoltageData())
797   /// -  Altro disabled channels. Noisy channels.
798   /// -  DDL list
799
800   // check necessary information
801   const Int_t run=GetRun();
802   if (run<0){
803     AliError("run not set in CDB manager. Cannot create active channel map");
804     return 0;
805   }
806   AliDCSSensorArray* voltageArray = GetVoltageSensors(run);
807   AliTPCCalPad*          altroMap = GetALTROMasked();
808   TMap*                    mapddl = GetDDLMap();
809
810   if (!voltageArray && !altroMap && !mapddl) {
811     AliError("All necessary information to create the activate channel are map missing.");
812     return 0;
813   }
814
815   //=============================================================
816   // Setup DDL map
817
818   Bool_t ddlMap[216]={0};
819   for (Int_t iddl=0; iddl<216; ++iddl) ddlMap[iddl]=1;
820   if (mapddl){
821     TObjString *s = (TObjString*)mapddl->GetValue("DDLArray");
822     if (s){
823       for (Int_t iddl=0; iddl<216; ++iddl) ddlMap[iddl]=TString(s->GetString()(iddl))!="0";
824     }
825   } else {
826     AliError("DDL map missing. ActiveChannelMap can only be created with parts of the information.");
827   }
828   // Setup DDL map done
829   // ============================================================
830
831   //=============================================================
832   // Setup active chnnel map
833   //
834
835   if (!fActiveChannelMap) fActiveChannelMap=new AliTPCCalPad("ActiveChannelMap","ActiveChannelMap");
836
837   AliTPCmapper map(gSystem->ExpandPathName("$ALICE_ROOT/TPC/mapping/"));
838
839   if (!altroMap) AliError("ALTRO dead channel map missing. ActiveChannelMap can only be created with parts of the information.");
840
841   for (Int_t iROC=0;iROC<AliTPCCalPad::kNsec;++iROC){
842     AliTPCCalROC *roc=fActiveChannelMap->GetCalROC(iROC);
843     if (!roc){
844       AliError(Form("No ROC %d in active channel map",iROC));
845       continue;
846     }
847
848     // check for bad voltage
849     // see UpdateChamberHighVoltageData()
850     if (!fChamberHVStatus[iROC]){
851       roc->Multiply(0.);
852       AliInfo(Form("Turning off all channels of ROC %2d due to a bad HV status", iROC));
853       continue;
854     }
855
856     AliTPCCalROC *masked=0x0;
857     if (altroMap) masked=altroMap->GetCalROC(iROC);
858
859     Int_t numberOfDeactivatedChannels=0;
860     for (UInt_t irow=0; irow<roc->GetNrows(); ++irow){
861       for (UInt_t ipad=0; ipad<roc->GetNPads(irow); ++ipad){
862         //per default the channel is on
863         roc->SetValue(irow,ipad,1);
864         // apply altro dead channel mask (inverse logik, it is not active, but inactive channles)
865         if (masked && masked->GetValue(irow, ipad)) roc->SetValue(irow, ipad ,0);
866         // mask channels if a DDL is inactive
867         Int_t ddlId=map.GetEquipmentID(iROC, irow, ipad)-768;
868         if (ddlId>=0 && !ddlMap[ddlId]) roc->SetValue(irow, ipad ,0);
869
870         if (roc->GetValue(irow, ipad)<0.0001) {
871           ++numberOfDeactivatedChannels;
872         }
873       }
874     }
875
876     if (numberOfDeactivatedChannels>0) {
877       AliInfo(Form("Deactivated %4d channels in ROC %2d due to altro and DDL map states",
878                    numberOfDeactivatedChannels, iROC));
879     }
880   }
881
882   return 1;
883 }
884
885 void AliTPCcalibDB::MakeTree(const char * fileName, TObjArray * array, const char * mapFileName, AliTPCCalPad* outlierPad, Float_t ltmFraction) {
886   /// Write a tree with all available information
887   /// if mapFileName is specified, the Map information are also written to the tree
888   /// pads specified in outlierPad are not used for calculating statistics
889   ///  - the same function as AliTPCCalPad::MakeTree -
890
891    AliTPCROC* tpcROCinstance = AliTPCROC::Instance();
892
893    TObjArray* mapIROCs = 0;
894    TObjArray* mapOROCs = 0;
895    TVectorF *mapIROCArray = 0;
896    TVectorF *mapOROCArray = 0;
897    Int_t mapEntries = 0;
898    TString* mapNames = 0;
899
900    if (mapFileName) {
901       TFile mapFile(mapFileName, "read");
902
903       TList* listOfROCs = mapFile.GetListOfKeys();
904       mapEntries = listOfROCs->GetEntries()/2;
905       mapIROCs = new TObjArray(mapEntries*2);
906       mapOROCs = new TObjArray(mapEntries*2);
907       mapIROCArray = new TVectorF[mapEntries];
908       mapOROCArray = new TVectorF[mapEntries];
909
910       mapNames = new TString[mapEntries];
911       for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
912         TString nameROC(((TKey*)(listOfROCs->At(ivalue*2)))->GetName());
913          nameROC.Remove(nameROC.Length()-4, 4);
914          mapIROCs->AddAt((AliTPCCalROC*)mapFile.Get((nameROC + "IROC").Data()), ivalue);
915          mapOROCs->AddAt((AliTPCCalROC*)mapFile.Get((nameROC + "OROC").Data()), ivalue);
916          mapNames[ivalue].Append(nameROC);
917       }
918
919       for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
920          mapIROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(0));
921          mapOROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(36));
922
923          for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(0); ichannel++)
924             (mapIROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapIROCs->At(ivalue)))->GetValue(ichannel);
925          for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(36); ichannel++)
926             (mapOROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapOROCs->At(ivalue)))->GetValue(ichannel);
927       }
928
929    } //  if (mapFileName)
930
931    TTreeSRedirector cstream(fileName);
932    Int_t arrayEntries = array->GetEntries();
933
934    TString* names = new TString[arrayEntries];
935    for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
936       names[ivalue].Append(((AliTPCCalPad*)array->At(ivalue))->GetName());
937
938    for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++) {
939       //
940       // get statistic for given sector
941       //
942       TVectorF median(arrayEntries);
943       TVectorF mean(arrayEntries);
944       TVectorF rms(arrayEntries);
945       TVectorF ltm(arrayEntries);
946       TVectorF ltmrms(arrayEntries);
947       TVectorF medianWithOut(arrayEntries);
948       TVectorF meanWithOut(arrayEntries);
949       TVectorF rmsWithOut(arrayEntries);
950       TVectorF ltmWithOut(arrayEntries);
951       TVectorF ltmrmsWithOut(arrayEntries);
952
953       TVectorF *vectorArray = new TVectorF[arrayEntries];
954       for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
955          vectorArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
956
957       for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
958          AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
959          AliTPCCalROC* calROC = calPad->GetCalROC(isector);
960          AliTPCCalROC* outlierROC = 0;
961          if (outlierPad) outlierROC = outlierPad->GetCalROC(isector);
962          if (calROC) {
963             median[ivalue] = calROC->GetMedian();
964             mean[ivalue] = calROC->GetMean();
965             rms[ivalue] = calROC->GetRMS();
966             Double_t ltmrmsValue = 0;
967             ltm[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction);
968             ltmrms[ivalue] = ltmrmsValue;
969             if (outlierROC) {
970                medianWithOut[ivalue] = calROC->GetMedian(outlierROC);
971                meanWithOut[ivalue] = calROC->GetMean(outlierROC);
972                rmsWithOut[ivalue] = calROC->GetRMS(outlierROC);
973                ltmrmsValue = 0;
974                ltmWithOut[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction, outlierROC);
975                ltmrmsWithOut[ivalue] = ltmrmsValue;
976             }
977          }
978          else {
979             median[ivalue] = 0.;
980             mean[ivalue] = 0.;
981             rms[ivalue] = 0.;
982             ltm[ivalue] = 0.;
983             ltmrms[ivalue] = 0.;
984             medianWithOut[ivalue] = 0.;
985             meanWithOut[ivalue] = 0.;
986             rmsWithOut[ivalue] = 0.;
987             ltmWithOut[ivalue] = 0.;
988             ltmrmsWithOut[ivalue] = 0.;
989          }
990       }
991
992       //
993       // fill vectors of variable per pad
994       //
995       TVectorF *posArray = new TVectorF[8];
996       for (Int_t ivalue = 0; ivalue < 8; ivalue++)
997          posArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
998
999       Float_t posG[3] = {0};
1000       Float_t posL[3] = {0};
1001       Int_t ichannel = 0;
1002       for (UInt_t irow = 0; irow < tpcROCinstance->GetNRows(isector); irow++) {
1003          for (UInt_t ipad = 0; ipad < tpcROCinstance->GetNPads(isector, irow); ipad++) {
1004             tpcROCinstance->GetPositionLocal(isector, irow, ipad, posL);
1005             tpcROCinstance->GetPositionGlobal(isector, irow, ipad, posG);
1006             posArray[0][ichannel] = irow;
1007             posArray[1][ichannel] = ipad;
1008             posArray[2][ichannel] = posL[0];
1009             posArray[3][ichannel] = posL[1];
1010             posArray[4][ichannel] = posG[0];
1011             posArray[5][ichannel] = posG[1];
1012             posArray[6][ichannel] = (Int_t)(ipad - (Double_t)(tpcROCinstance->GetNPads(isector, irow))/2);
1013             posArray[7][ichannel] = ichannel;
1014
1015             // loop over array containing AliTPCCalPads
1016             for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
1017                AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
1018                AliTPCCalROC* calROC = calPad->GetCalROC(isector);
1019                if (calROC)
1020                   (vectorArray[ivalue])[ichannel] = calROC->GetValue(irow, ipad);
1021                else
1022                   (vectorArray[ivalue])[ichannel] = 0;
1023             }
1024             ichannel++;
1025          }
1026       }
1027
1028       cstream << "calPads" <<
1029          "sector=" << isector;
1030
1031       for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
1032          cstream << "calPads" <<
1033             (Char_t*)((names[ivalue] + "_Median=").Data()) << median[ivalue] <<
1034             (Char_t*)((names[ivalue] + "_Mean=").Data()) << mean[ivalue] <<
1035             (Char_t*)((names[ivalue] + "_RMS=").Data()) << rms[ivalue] <<
1036             (Char_t*)((names[ivalue] + "_LTM=").Data()) << ltm[ivalue] <<
1037             (Char_t*)((names[ivalue] + "_RMS_LTM=").Data()) << ltmrms[ivalue];
1038          if (outlierPad) {
1039             cstream << "calPads" <<
1040                (Char_t*)((names[ivalue] + "_Median_OutlierCutted=").Data()) << medianWithOut[ivalue] <<
1041                (Char_t*)((names[ivalue] + "_Mean_OutlierCutted=").Data()) << meanWithOut[ivalue] <<
1042                (Char_t*)((names[ivalue] + "_RMS_OutlierCutted=").Data()) << rmsWithOut[ivalue] <<
1043                (Char_t*)((names[ivalue] + "_LTM_OutlierCutted=").Data()) << ltmWithOut[ivalue] <<
1044                (Char_t*)((names[ivalue] + "_RMS_LTM_OutlierCutted=").Data()) << ltmrmsWithOut[ivalue];
1045          }
1046       }
1047
1048       for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
1049          cstream << "calPads" <<
1050             (Char_t*)((names[ivalue] + ".=").Data()) << &vectorArray[ivalue];
1051       }
1052
1053       if (mapFileName) {
1054          for  (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
1055             if (isector < 36)
1056                cstream << "calPads" <<
1057                   (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapIROCArray[ivalue];
1058             else
1059                cstream << "calPads" <<
1060                   (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapOROCArray[ivalue];
1061          }
1062       }
1063
1064       cstream << "calPads" <<
1065          "row.=" << &posArray[0] <<
1066          "pad.=" << &posArray[1] <<
1067          "lx.=" << &posArray[2] <<
1068          "ly.=" << &posArray[3] <<
1069          "gx.=" << &posArray[4] <<
1070          "gy.=" << &posArray[5] <<
1071          "rpad.=" << &posArray[6] <<
1072          "channel.=" << &posArray[7];
1073
1074       cstream << "calPads" <<
1075          "\n";
1076
1077       delete[] posArray;
1078       delete[] vectorArray;
1079    }
1080
1081
1082    delete[] names;
1083    if (mapFileName) {
1084       delete mapIROCs;
1085       delete mapOROCs;
1086       delete[] mapIROCArray;
1087       delete[] mapOROCArray;
1088       delete[] mapNames;
1089    }
1090 }
1091
1092 Int_t AliTPCcalibDB::GetRCUTriggerConfig() const
1093 {
1094   /// return the RCU trigger configuration register
1095
1096   TMap *map=GetRCUconfig();
1097   if (!map) return -1;
1098   TVectorF *v=(TVectorF*)map->GetValue("TRGCONF_TRG_MODE");
1099   Float_t mode=-1;
1100   for (Int_t i=0; i<v->GetNrows(); ++i){
1101     Float_t newmode=v->GetMatrixArray()[i];
1102     if (newmode>-1){
1103       if (mode>-1&&newmode!=mode) AliWarning("Found different RCU trigger configurations!!!");
1104       mode=newmode;
1105     }
1106   }
1107   return (Int_t)mode;
1108 }
1109
1110 Bool_t AliTPCcalibDB::IsTrgL0()
1111 {
1112   /// return if the FEE readout was triggered on L0
1113
1114   if (fMode<0) return kFALSE;
1115   return (fMode==1);
1116 }
1117
1118 Bool_t AliTPCcalibDB::IsTrgL1()
1119 {
1120   /// return if the FEE readout was triggered on L1
1121
1122   if (fMode<0) return kFALSE;
1123   return (fMode==0);
1124 }
1125
1126 void AliTPCcalibDB::RegisterExB(Int_t index, Float_t bz, Bool_t bdelete){
1127   /// Register static ExB correction map
1128   /// index - registration index - used for visualization
1129   /// bz    - bz field in kGaus
1130
1131   //  Float_t factor =  bz/(-5.);  // default b filed in Cheb with minus sign
1132   Float_t factor =  bz/(5.);  // default b filed in Cheb with minus sign
1133                               // was chenged in the Revision ???? (Ruben can you add here number)
1134
1135   AliMagF*   bmap = new AliMagF("MapsExB","MapsExB", factor,TMath::Sign(1.f,factor),AliMagF::k5kG);
1136
1137   AliTPCExBFirst *exb  = new  AliTPCExBFirst(bmap,0.88*2.6400e+04,50,50,50);
1138   AliTPCExB::SetInstance(exb);
1139
1140   if (bdelete){
1141     delete bmap;
1142   }else{
1143     AliTPCExB::RegisterField(index,bmap);
1144   }
1145   if (index>=fgExBArray.GetEntries()) fgExBArray.Expand((index+1)*2+11);
1146   fgExBArray.AddAt(exb,index);
1147 }
1148
1149
1150 AliTPCExB*    AliTPCcalibDB::GetExB(Float_t bz, Bool_t deleteB) {
1151   /// bz filed in KGaus not in tesla
1152   /// Get ExB correction map
1153   /// if doesn't exist - create it
1154
1155   Int_t index = TMath::Nint(5+bz);
1156   if (index>fgExBArray.GetEntries()) fgExBArray.Expand((index+1)*2+11);
1157   if (!fgExBArray.At(index)) AliTPCcalibDB::RegisterExB(index,bz,deleteB);
1158   return (AliTPCExB*)fgExBArray.At(index);
1159 }
1160
1161
1162 void  AliTPCcalibDB::SetExBField(Float_t bz){
1163   /// Set magnetic filed for ExB correction
1164
1165   fExB = GetExB(bz,kFALSE);
1166 }
1167
1168 void  AliTPCcalibDB::SetExBField(const AliMagF*   bmap){
1169   /// Set magnetic field for ExB correction
1170
1171   AliTPCExBFirst *exb  = new  AliTPCExBFirst(bmap,0.88*2.6400e+04,50,50,50);
1172   AliTPCExB::SetInstance(exb);
1173   fExB=exb;
1174 }
1175
1176
1177
1178 void AliTPCcalibDB::UpdateRunInformations( Int_t run, Bool_t force){
1179   /// - > Don't use it for reconstruction - Only for Calibration studies
1180
1181   if (run<=0) return;
1182   TObjString runstr(Form("%i",run));
1183   fRun=run;
1184   AliCDBEntry * entry = 0;
1185   if (run>= fRunList.fN){
1186     fRunList.Set(run*2+1);
1187     //
1188     //
1189     fALTROConfigData->Expand(run*2+1);    // ALTRO configuration data
1190     fPulserData->Expand(run*2+1);         // Calibration Pulser data
1191     fCEData->Expand(run*2+1);             // CE data
1192     if (!fTimeGainSplines) fTimeGainSplines = new TObjArray(run*2+1);
1193     fTimeGainSplines->Expand(run*2+1); // Array of AliSplineFits: at 0 MIP position in
1194   }
1195   if (fRunList[run]>0 &&force==kFALSE) return;
1196
1197   fRunList[run]=1;  // sign as used
1198
1199   //
1200   entry = AliCDBManager::Instance()->Get("GRP/GRP/Data",run);
1201   if (entry)  {
1202     AliGRPObject * grpRun = dynamic_cast<AliGRPObject*>(entry->GetObject());
1203     if (!grpRun){
1204       TMap* map = dynamic_cast<TMap*>(entry->GetObject());
1205       if (map){
1206         //grpRun = new AliGRPObject;
1207         //grpRun->ReadValuesFromMap(map);
1208         grpRun =  MakeGRPObjectFromMap(map);
1209
1210         fGRPMaps.Add(new TObjString(runstr),map);
1211       }
1212     }
1213     fGRPArray.Add(new TObjString(runstr),grpRun);
1214   }
1215   entry = AliCDBManager::Instance()->Get("TPC/Calib/Goofie",run);
1216   if (entry){
1217     fGoofieArray.Add(new TObjString(runstr),entry->GetObject());
1218   }
1219   //
1220
1221   //
1222   entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeGain",run);
1223   if (entry)  {
1224     fTimeGainSplinesArray.Add(new TObjString(runstr),entry->GetObject());
1225   }else{
1226     AliFatal("TPC - Missing calibration entry TimeGain");
1227   }
1228   //
1229   entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeDrift",run);
1230   if (entry)  {
1231     TObjArray * timeArray = (TObjArray*)entry->GetObject();
1232     fDriftCorrectionArray.Add(new TObjString(runstr),entry->GetObject());
1233     AliTPCCorrection * correctionTime = (AliTPCCorrection *)timeArray->FindObject("FitCorrectionTime");
1234     if (correctionTime && fComposedCorrectionArray){
1235       correctionTime->Init();
1236       if (fComposedCorrectionArray->GetEntriesFast()<4) fComposedCorrectionArray->Expand(40);
1237       fComposedCorrectionArray->AddAt(correctionTime,4); //add time dependent correction to the list of available corrections
1238     }
1239   }else{
1240     AliFatal("TPC - Missing calibration entry TimeDrift");
1241   }
1242   //
1243   entry = AliCDBManager::Instance()->Get("TPC/Calib/Temperature",run);
1244   if (entry)  {
1245     fTemperatureArray.Add(new TObjString(runstr),entry->GetObject());
1246   }
1247
1248   // High voltage
1249   entry = AliCDBManager::Instance()->Get("TPC/Calib/HighVoltage",run);
1250   if (!fVoltageArray.GetValue(runstr.GetName()) && entry)  {
1251     fVoltageArray.Add(new TObjString(runstr),entry->GetObject());
1252   }
1253
1254   //apply fDButil filters
1255
1256   fDButil->UpdateFromCalibDB();
1257   if (fTemperature) fDButil->FilterTemperature(fTemperature);
1258
1259   AliDCSSensor * press = GetPressureSensor(run,0);
1260   AliTPCSensorTempArray * temp = GetTemperatureSensor(run);
1261   Bool_t accept=kTRUE;
1262   if (temp) {
1263     accept = fDButil->FilterTemperature(temp)>0.1;
1264   }
1265   if (press) {
1266     const Double_t kMinP=900.;
1267     const Double_t kMaxP=1050.;
1268     const Double_t kMaxdP=10.;
1269     const Double_t kSigmaCut=4.;
1270     fDButil->FilterSensor(press,kMinP,kMaxP,kMaxdP,kSigmaCut);
1271     if (press->GetFit()==0) accept=kFALSE;
1272   }
1273
1274   if (press && temp &&accept){
1275     AliTPCCalibVdrift * vdrift = new AliTPCCalibVdrift(temp, press,0);
1276     fVdriftArray.Add(new TObjString(runstr),vdrift);
1277   }
1278
1279   fDButil->FilterCE(120., 3., 4.,0);
1280   fDButil->FilterTracks(run, 10.,0);
1281
1282 }
1283
1284
1285 Float_t AliTPCcalibDB::GetGain(Int_t sector, Int_t row, Int_t pad){
1286   /// Get Gain factor for given pad
1287
1288   AliTPCCalPad *calPad = Instance()->fDedxGainFactor;;
1289   if (!calPad) return 0;
1290   return calPad->GetCalROC(sector)->GetValue(row,pad);
1291 }
1292
1293 AliSplineFit* AliTPCcalibDB::GetVdriftSplineFit(const char* name, Int_t run){
1294   /// GetDrift velocity spline fit
1295
1296   TObjArray *arr=GetTimeVdriftSplineRun(run);
1297   if (!arr) return 0;
1298   return dynamic_cast<AliSplineFit*>(arr->FindObject(name));
1299 }
1300
1301 AliSplineFit* AliTPCcalibDB::CreateVdriftSplineFit(const char* graphName, Int_t run){
1302   /// create spline fit from the drift time graph in TimeDrift
1303
1304   TObjArray *arr=GetTimeVdriftSplineRun(run);
1305   if (!arr) return 0;
1306   TGraph *graph=dynamic_cast<TGraph*>(arr->FindObject(graphName));
1307   if (!graph) return 0;
1308   AliSplineFit *fit = new AliSplineFit();
1309   fit->SetGraph(graph);
1310   fit->SetMinPoints(graph->GetN()+1);
1311   fit->InitKnots(graph,2,0,0.001);
1312   fit->SplineFit(0);
1313   return fit;
1314 }
1315
1316 AliGRPObject *AliTPCcalibDB::GetGRP(Int_t run){
1317   /// Get GRP object for given run
1318
1319   AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>((Instance()->fGRPArray).GetValue(Form("%i",run)));
1320   if (!grpRun) {
1321     Instance()->UpdateRunInformations(run);
1322     grpRun = dynamic_cast<AliGRPObject *>(Instance()->fGRPArray.GetValue(Form("%i",run)));
1323     if (!grpRun) return 0;
1324   }
1325   return grpRun;
1326 }
1327
1328 TMap *  AliTPCcalibDB::GetGRPMap(Int_t run){
1329   /// Get GRP map for given run
1330
1331   TMap * grpRun = dynamic_cast<TMap *>((Instance()->fGRPMaps).GetValue(Form("%i",run)));
1332   if (!grpRun) {
1333     Instance()->UpdateRunInformations(run);
1334     grpRun = dynamic_cast<TMap *>(Instance()->fGRPMaps.GetValue(Form("%i",run)));
1335     if (!grpRun) return 0;
1336   }
1337   return grpRun;
1338 }
1339
1340
1341 AliDCSSensor * AliTPCcalibDB::GetPressureSensor(Int_t run, Int_t type){
1342   /// Get Pressure sensor
1343   /// run  = run number
1344   /// type = 0 - Cavern pressure
1345   ///        1 - Suface pressure
1346   /// First try to get if trom map - if existing  (Old format of data storing)
1347
1348
1349   TMap *map = GetGRPMap(run);
1350   if (map){
1351     AliDCSSensor * sensor = 0;
1352     TObject *osensor=0;
1353     if (type==0) osensor = ((*map)("fCavernPressure"));
1354     if (type==1) osensor = ((*map)("fP2Pressure"));
1355     sensor =dynamic_cast<AliDCSSensor *>(osensor);
1356     if (sensor) return sensor;
1357   }
1358   //
1359   // If not map try to get it from the GRPObject
1360   //
1361   AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.GetValue(Form("%i",run)));
1362   if (!grpRun) {
1363     UpdateRunInformations(run);
1364     grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.GetValue(Form("%i",run)));
1365     if (!grpRun) return 0;
1366   }
1367   AliDCSSensor * sensor = grpRun->GetCavernAtmosPressure();
1368   if (type==1) sensor = grpRun->GetSurfaceAtmosPressure();
1369   return sensor;
1370 }
1371
1372 AliTPCSensorTempArray * AliTPCcalibDB::GetTemperatureSensor(Int_t run){
1373   /// Get temperature sensor array
1374
1375   AliTPCSensorTempArray * tempArray = (AliTPCSensorTempArray *)fTemperatureArray.GetValue(Form("%i",run));
1376   if (!tempArray) {
1377     UpdateRunInformations(run);
1378     tempArray = (AliTPCSensorTempArray *)fTemperatureArray.GetValue(Form("%i",run));
1379   }
1380   return tempArray;
1381 }
1382
1383
1384 TObjArray * AliTPCcalibDB::GetTimeGainSplinesRun(Int_t run){
1385   /// Get temperature sensor array
1386
1387   TObjArray * gainSplines = (TObjArray *)fTimeGainSplinesArray.GetValue(Form("%i",run));
1388   if (!gainSplines) {
1389     UpdateRunInformations(run);
1390     gainSplines = (TObjArray *)fTimeGainSplinesArray.GetValue(Form("%i",run));
1391   }
1392   return gainSplines;
1393 }
1394
1395 TObjArray * AliTPCcalibDB::GetTimeVdriftSplineRun(Int_t run){
1396   /// Get drift spline array
1397
1398   TObjArray * driftSplines = (TObjArray *)fDriftCorrectionArray.GetValue(Form("%i",run));
1399   if (!driftSplines) {
1400     UpdateRunInformations(run);
1401     driftSplines = (TObjArray *)fDriftCorrectionArray.GetValue(Form("%i",run));
1402   }
1403   return driftSplines;
1404 }
1405
1406 AliDCSSensorArray * AliTPCcalibDB::GetVoltageSensors(Int_t run){
1407   /// Get temperature sensor array
1408
1409   AliDCSSensorArray * voltageArray = (AliDCSSensorArray *)fVoltageArray.GetValue(Form("%i",run));
1410   if (!voltageArray) {
1411     UpdateRunInformations(run);
1412     voltageArray = (AliDCSSensorArray *)fVoltageArray.GetValue(Form("%i",run));
1413   }
1414   return voltageArray;
1415 }
1416
1417 AliDCSSensorArray * AliTPCcalibDB::GetGoofieSensors(Int_t run){
1418   /// Get temperature sensor array
1419
1420   AliDCSSensorArray * goofieArray = (AliDCSSensorArray *)fGoofieArray.GetValue(Form("%i",run));
1421   if (!goofieArray) {
1422     UpdateRunInformations(run);
1423     goofieArray = (AliDCSSensorArray *)fGoofieArray.GetValue(Form("%i",run));
1424   }
1425   return goofieArray;
1426 }
1427
1428
1429
1430 AliTPCCalibVdrift *     AliTPCcalibDB::GetVdrift(Int_t run){
1431   /// Get the interface to the the vdrift
1432
1433   AliTPCCalibVdrift  * vdrift = (AliTPCCalibVdrift*)fVdriftArray.GetValue(Form("%i",run));
1434   if (!vdrift) {
1435     UpdateRunInformations(run);
1436     vdrift= (AliTPCCalibVdrift*)fVdriftArray.GetValue(Form("%i",run));
1437   }
1438   return vdrift;
1439 }
1440
1441 Float_t AliTPCcalibDB::GetCEdriftTime(Int_t run, Int_t sector, Double_t timeStamp, Int_t *entries)
1442 {
1443   /// GetCE drift time information for 'sector'
1444   /// sector 72 is the mean drift time of the A-Side
1445   /// sector 73 is the mean drift time of the C-Side
1446   /// it timestamp==-1 return mean value
1447
1448   AliTPCcalibDB::Instance()->SetRun(run);
1449   TGraph *gr=AliTPCcalibDB::Instance()->GetCErocTgraph(sector);
1450   if (!gr||sector<0||sector>73) {
1451     if (entries) *entries=0;
1452     return 0.;
1453   }
1454   Float_t val=0.;
1455   if (timeStamp==-1.){
1456     val=gr->GetMean(2);
1457   }else{
1458     for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1459       Double_t x,y;
1460       gr->GetPoint(ipoint,x,y);
1461       if (x<timeStamp) continue;
1462       val=y;
1463       break;
1464     }
1465   }
1466   return val;
1467 }
1468
1469 Float_t AliTPCcalibDB::GetCEchargeTime(Int_t run, Int_t sector, Double_t timeStamp, Int_t *entries)
1470 {
1471   /// GetCE mean charge for 'sector'
1472   /// it timestamp==-1 return mean value
1473
1474   AliTPCcalibDB::Instance()->SetRun(run);
1475   TGraph *gr=AliTPCcalibDB::Instance()->GetCErocQgraph(sector);
1476   if (!gr||sector<0||sector>71) {
1477     if (entries) *entries=0;
1478     return 0.;
1479   }
1480   Float_t val=0.;
1481   if (timeStamp==-1.){
1482     val=gr->GetMean(2);
1483   }else{
1484     for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1485       Double_t x,y;
1486       gr->GetPoint(ipoint,x,y);
1487       if (x<timeStamp) continue;
1488       val=y;
1489       break;
1490     }
1491   }
1492   return val;
1493 }
1494
1495 Float_t AliTPCcalibDB::GetDCSSensorValue(AliDCSSensorArray *arr, Int_t timeStamp, const char * sensorName, Int_t sigDigits)
1496 {
1497   /// Get Value for a DCS sensor 'sensorName', run 'run' at time 'timeStamp'
1498
1499   Float_t val=0;
1500   const TString sensorNameString(sensorName);
1501   AliDCSSensor *sensor = arr->GetSensor(sensorNameString);
1502   if (!sensor) return val;
1503   //use the dcs graph if possible
1504   TGraph *gr=sensor->GetGraph();
1505   if (gr){
1506     for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1507       Double_t x,y;
1508       gr->GetPoint(ipoint,x,y);
1509       Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
1510       if (time<timeStamp) continue;
1511       val=y;
1512       break;
1513     }
1514     //if val is still 0, test if if the requested time if within 5min of the first/last
1515     //data point. If this is the case return the firs/last entry
1516     //the timestamps might not be syncronised for all calibration types, sometimes a 'pre'
1517     //and 'pos' period is requested. Especially to the HV this is not the case!
1518     //first point
1519     if (val==0 ){
1520       Double_t x,y;
1521       gr->GetPoint(0,x,y);
1522       const Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
1523       const Int_t dtime=time-timeStamp;
1524       if ( (dtime>0) && (dtime<5*60) ) val=y;
1525     }
1526     //last point
1527     if (val==0 ){
1528       Double_t x,y;
1529       gr->GetPoint(gr->GetN()-1,x,y);
1530       const Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
1531       const Int_t dtime=timeStamp-time;
1532       if ( (dtime>0) && (dtime<5*60) ) val=y;
1533     }
1534   } else {
1535     val=sensor->GetValue(timeStamp);
1536   }
1537   if (sigDigits>=0){
1538     val=(Float_t)TMath::Floor(val * TMath::Power(10., sigDigits) + .5) / TMath::Power(10., sigDigits);
1539   }
1540   return val;
1541 }
1542
1543 Float_t AliTPCcalibDB::GetDCSSensorMeanValue(AliDCSSensorArray *arr, const char * sensorName, Int_t sigDigits)
1544 {
1545   /// Get mean Value for a DCS sensor 'sensorName' during run 'run'
1546
1547   Float_t val=0;
1548   const TString sensorNameString(sensorName);
1549   AliDCSSensor *sensor = arr->GetSensor(sensorNameString);
1550   if (!sensor) return val;
1551
1552   //use dcs graph if it exists
1553   TGraph *gr=sensor->GetGraph();
1554   if (gr){
1555     val=gr->GetMean(2);
1556   } else {
1557     //if we don't have the dcs graph, try to get some meaningful information
1558     if (!sensor->GetFit()) return val;
1559     Int_t nKnots=sensor->GetFit()->GetKnots();
1560     Double_t tMid=(sensor->GetEndTime()-sensor->GetStartTime())/2.;
1561     for (Int_t iKnot=0;iKnot<nKnots;++iKnot){
1562       if (sensor->GetFit()->GetX()[iKnot]>tMid/3600.) break;
1563       val=(Float_t)sensor->GetFit()->GetY0()[iKnot];
1564     }
1565   }
1566   if (sigDigits>=0){
1567     // val/=10;
1568     val=(Float_t)TMath::Floor(val * TMath::Power(10., sigDigits) + .5) / TMath::Power(10., sigDigits);
1569     //    val*=10;
1570   }
1571   return val;
1572 }
1573
1574 Bool_t AliTPCcalibDB::IsDataTakingActive(time_t timeStamp)
1575 {
1576   if (!fGrRunState) return kFALSE;
1577   Double_t time=Double_t(timeStamp);
1578   Int_t currentPoint=0;
1579   Bool_t currentVal=fGrRunState->GetY()[currentPoint]>0.5;
1580   Bool_t retVal=currentVal;
1581   Double_t currentTime=fGrRunState->GetX()[currentPoint];
1582
1583   while (time>currentTime){
1584     retVal=currentVal;
1585     if (currentPoint==fGrRunState->GetN()) break;
1586     currentVal=fGrRunState->GetY()[currentPoint]>0.5;
1587     currentTime=fGrRunState->GetX()[currentPoint];
1588     ++currentPoint;
1589   }
1590
1591   return retVal;
1592 }
1593
1594 void AliTPCcalibDB::UpdateChamberHighVoltageData()
1595 {
1596   /// set chamber high voltage data
1597   /// 1. Robust median (sampling the hv graphs over time)
1598   /// 2. Current nominal voltages (nominal voltage corrected for common HV offset)
1599   /// 3. Fraction of good HV values over time (deviation from robust median)
1600   /// 4. HV status, based on the above
1601
1602   // start and end time of the run
1603   const Int_t run=GetRun();
1604   if (run<0) return;
1605
1606   // if no valid run information - return
1607   AliGRPObject* grp = GetGRP(run);
1608   if (!grp) return;
1609
1610   const Int_t startTimeGRP = grp->GetTimeStart();
1611   const Int_t stopTimeGRP  = grp->GetTimeEnd();
1612
1613   //
1614   // In case we use a generated GRP we cannot make use of the start time and end time information
1615   // therefore we cannot calculate proper HV information and will skip this
1616   //
1617   if (startTimeGRP==0 && stopTimeGRP==0) {
1618     AliWarning("Using a generated GRP with 'GetTimeStart()' and 'GetTimeEnd()' == 0. Cannot calculate HV information.");
1619     return;
1620   }
1621
1622   //
1623   // check active state by analysing the scalers
1624   //
1625   // initialise graph with active running
1626   AliCDBEntry *entry = GetCDBEntry("GRP/CTP/Scalers");
1627   if (!entry) return;
1628   // entry->SetOwner(kTRUE);
1629   AliTriggerRunScalers *sca = (AliTriggerRunScalers*)entry->GetObject();
1630   Int_t nchannels = sca->GetNumClasses(); // number of scaler channels (i.e. trigger classes)
1631   Int_t npoints = sca->GetScalersRecords()->GetEntries(); // number of samples
1632
1633   delete fGrRunState;
1634   fGrRunState=new TGraph;
1635   fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(startTimeGRP)-.001,0);
1636   fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(startTimeGRP),1);
1637   ULong64_t lastSum=0;
1638   Double_t timeLast=0.;
1639   Bool_t active=kTRUE;
1640   for (int i=0; i<npoints; i++) {
1641     AliTriggerScalersRecord *rec = (AliTriggerScalersRecord *) sca->GetScalersRecord(i);
1642     Double_t time = ((AliTimeStamp*) rec->GetTimeStamp())->GetSeconds();
1643     // check if time is inside the grp times. For dummy scaler entries the time might be compatible with 0
1644     if ( time<startTimeGRP || time>stopTimeGRP ){
1645       AliWarning(Form("Time of scaler record %d: %.0f is outside the GRP times (%d, %d). Skipping this record.", i, time, startTimeGRP, stopTimeGRP));
1646       continue;
1647     }
1648     ULong64_t sum=0;
1649     for (int j=0; j<nchannels; j++) sum += ((AliTriggerScalers*) rec->GetTriggerScalers()->At(j))->GetL2CA();
1650     if (TMath::Abs(time-timeLast)<.001 && sum==lastSum ) continue;
1651     if (active && sum==lastSum){
1652       fGrRunState->SetPoint(fGrRunState->GetN(),timeLast-.01,1);
1653       fGrRunState->SetPoint(fGrRunState->GetN(),timeLast,0);
1654       active=kFALSE;
1655     } else if (!active && sum>lastSum ){
1656       fGrRunState->SetPoint(fGrRunState->GetN(),timeLast-.01,0);
1657       fGrRunState->SetPoint(fGrRunState->GetN(),timeLast,1);
1658       active=kTRUE;
1659     }
1660     lastSum=sum;
1661     timeLast=time;
1662   }
1663   fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(stopTimeGRP),active);
1664   fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(stopTimeGRP)+.001,0);
1665
1666
1667
1668   // reset all values
1669   for (Int_t iROC=0;iROC<72;++iROC) {
1670     fChamberHVmedian[iROC]       = -1;
1671     fChamberHVgoodFraction[iROC] = 0.;
1672     fCurrentNominalVoltage[iROC] = -999.;
1673     fChamberHVStatus[iROC]       = kFALSE;
1674   }
1675
1676   AliDCSSensorArray* voltageArray = GetVoltageSensors(run);
1677   if (!voltageArray) {
1678     AliError("Voltage Array missing. Cannot calculate HV information!");
1679     return;
1680   }
1681
1682   // max HV diffs before a chamber is masked
1683   const Float_t maxVdiff      = fParam->GetMaxVoltageDeviation();
1684   const Float_t maxDipVoltage = fParam->GetMaxDipVoltage();
1685   const Float_t maxFracHVbad  = fParam->GetMaxFractionHVbad();
1686
1687   const Int_t samplingPeriod=1;
1688
1689   // array with sampled voltages
1690   const Int_t maxSamples=(stopTimeGRP-startTimeGRP)/samplingPeriod + 10*samplingPeriod;
1691   Float_t *vSampled = new Float_t[maxSamples];
1692
1693   // deviation of the median from the nominal voltage
1694   Double_t chamberMedianDeviation[72]={0.};
1695
1696   for (Int_t iROC=0; iROC<72; ++iROC){
1697     chamberMedianDeviation[iROC]=0.;
1698     TString sensorName="";
1699     Char_t sideName='A';
1700     if ((iROC/18)%2==1) sideName='C';
1701     if (iROC<36) sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,iROC%18);
1702     else        sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,iROC%18);
1703
1704     AliDCSSensor *sensor = voltageArray->GetSensor(sensorName);
1705
1706     fHVsensors[iROC]=sensor;
1707     if (!sensor) continue;
1708
1709     Int_t nPointsSampled=0;
1710
1711     TGraph *gr=sensor->GetGraph();
1712     if ( gr && gr->GetN()>1 ){
1713       //1. sample voltage over time
1714       //   get a robust median
1715       //   buffer sampled voltages
1716
1717       // current sampling time
1718       Int_t time=startTimeGRP;
1719
1720       // input graph sampling point
1721       const Int_t nGraph=gr->GetN();
1722       Int_t pointGraph=0;
1723
1724       //initialise graph information
1725       Int_t timeGraph=TMath::Nint(gr->GetX()[pointGraph+1]*3600+sensor->GetStartTime());
1726       Double_t sampledHV=gr->GetY()[pointGraph++];
1727
1728       while (time<stopTimeGRP){
1729         while (timeGraph<=time && pointGraph+1<nGraph){
1730           timeGraph=TMath::Nint(gr->GetX()[pointGraph+1]*3600+sensor->GetStartTime());
1731           sampledHV=gr->GetY()[pointGraph++];
1732         }
1733         time+=samplingPeriod;
1734         if (!IsDataTakingActive(time-samplingPeriod)) continue;
1735         vSampled[nPointsSampled++]=sampledHV;
1736       }
1737
1738       if (nPointsSampled<1) continue;
1739
1740       fChamberHVmedian[iROC]=TMath::Median(nPointsSampled,vSampled);
1741       chamberMedianDeviation[iROC]=fChamberHVmedian[iROC]-fParam->GetNominalVoltage(iROC);
1742
1743       //2. calculate good HV fraction
1744       Int_t ngood=0;
1745       for (Int_t ipoint=0; ipoint<nPointsSampled; ++ipoint) {
1746         if (TMath::Abs(vSampled[ipoint]-fChamberHVmedian[iROC])<maxDipVoltage) ++ngood;
1747       }
1748
1749       fChamberHVgoodFraction[iROC]=Float_t(ngood)/Float_t(nPointsSampled);
1750     } else if (!gr && !sensor->GetFit() ){
1751       // This is an exception handling.
1752       // It was observed that for some rund in the 2010 data taking no HV info is available
1753       //    for some sectors. However they were active. So take care about this
1754       fChamberHVmedian[iROC]       = fParam->GetNominalVoltage(iROC);
1755       fChamberHVgoodFraction[iROC] = 1.;
1756       AliWarning(Form("ROC %d detected without HV Splines and HV graph. Will set median HV to nominal voltage",iROC));
1757     } else {
1758       AliError(Form("No Graph or too few points found for HV sensor of ROC %d",iROC));
1759     }
1760   }
1761
1762   delete [] vSampled;
1763   vSampled=0x0;
1764
1765   // get median deviation from all chambers (detect e.g. -50V)
1766   const Double_t medianIROC=TMath::Median( 36, chamberMedianDeviation );
1767   const Double_t medianOROC=TMath::Median( 36, chamberMedianDeviation+36 );
1768
1769   // Define current default voltages
1770   for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
1771     const Float_t averageDeviation=(iROC<36)?medianIROC:medianOROC;
1772     fCurrentNominalVoltage[iROC]=fParam->GetNominalVoltage(iROC)+averageDeviation;
1773   }
1774
1775   //
1776   // Check HV status
1777   //
1778   Int_t nbad=0;
1779   for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
1780     fChamberHVStatus[iROC]=kTRUE;
1781
1782     //a. Deviation of median from current nominal voltage
1783     //   allow larger than nominal voltages
1784     if (fCurrentNominalVoltage[iROC]-fChamberHVmedian[iROC] >  maxVdiff) {
1785       AliInfo(Form("Low voltage detected for ROC %2d, current nominal voltage - median voltage: %.2f-%.2f>%.2f",
1786                    iROC, fCurrentNominalVoltage[iROC],fChamberHVmedian[iROC],maxVdiff));
1787       fChamberHVStatus[iROC]=kFALSE;
1788     }
1789
1790     //b. Fraction of bad hv values
1791     if ( 1.-fChamberHVgoodFraction[iROC] > maxFracHVbad ) {
1792       AliInfo(Form("Large fraction of low HV readings detected in ROC %2d: %.2f > %.2f",
1793                    iROC, 1.-fChamberHVgoodFraction[iROC], maxFracHVbad));
1794       fChamberHVStatus[iROC]=kFALSE;
1795     }
1796
1797     if (!fChamberHVStatus[iROC]) {
1798       ++nbad;
1799     }
1800   }
1801
1802   // check if all chamber are off
1803   if (nbad==72) {
1804     AliFatal("Something went wrong in the chamber HV status calculation. All chambers would be deactivated!");
1805   }
1806 }
1807
1808 Float_t AliTPCcalibDB::GetChamberHighVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits, Bool_t current) {
1809   /// return the chamber HV for given run and time: 0-35 IROC, 36-72 OROC
1810   /// if timeStamp==-1 return mean value
1811
1812   Float_t val=0;
1813   TString sensorName="";
1814   TTimeStamp stamp(timeStamp);
1815   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1816   if (!voltageArray || (sector<0) || (sector>71)) return val;
1817   Char_t sideName='A';
1818   if ((sector/18)%2==1) sideName='C';
1819   if (sector<36){
1820     //IROC
1821     sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
1822   }else{
1823     //OROC
1824     sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
1825   }
1826   if (current){
1827     if (sector<36){
1828       //IROC
1829       sensorName=Form("TPC_ANODE_I_%c%02d_IMEAS",sideName,sector%18);
1830     }else{
1831       //OROC
1832       sensorName=Form("TPC_ANODE_O_%c%02d_0_IMEAS",sideName,sector%18);
1833     }
1834
1835   }
1836   if (timeStamp==-1){
1837     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1838   } else {
1839     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1840   }
1841   return val;
1842 }
1843 Float_t AliTPCcalibDB::GetSkirtVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1844 {
1845   /// Get the skirt voltage for 'run' at 'timeStamp' and 'sector': 0-35 IROC, 36-72 OROC
1846   /// type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1847   /// if timeStamp==-1 return the mean value for the run
1848
1849   Float_t val=0;
1850   TString sensorName="";
1851   TTimeStamp stamp(timeStamp);
1852   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1853   if (!voltageArray || (sector<0) || (sector>71)) return val;
1854   Char_t sideName='A';
1855   if ((sector/18)%2==1) sideName='C';
1856   sensorName=Form("TPC_SKIRT_%c_VMEAS",sideName);
1857   if (timeStamp==-1){
1858     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1859   } else {
1860     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1861   }
1862   return val;
1863 }
1864
1865 Float_t AliTPCcalibDB::GetCoverVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1866 {
1867   /// Get the cover voltage for run 'run' at time 'timeStamp'
1868   /// type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1869   /// if timeStamp==-1 return the mean value for the run
1870
1871   Float_t val=0;
1872   TString sensorName="";
1873   TTimeStamp stamp(timeStamp);
1874   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1875   if (!voltageArray || (sector<0) || (sector>71)) return val;
1876   Char_t sideName='A';
1877   if ((sector/18)%2==1) sideName='C';
1878   if (sector<36){
1879     //IROC
1880     sensorName=Form("TPC_COVER_I_%c_VMEAS",sideName);
1881   }else{
1882     //OROC
1883     sensorName=Form("TPC_COVER_O_%c_VMEAS",sideName);
1884   }
1885   if (timeStamp==-1){
1886     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1887   } else {
1888     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1889   }
1890   return val;
1891 }
1892
1893 Float_t AliTPCcalibDB::GetGGoffsetVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1894 {
1895   /// Get the GG offset voltage for run 'run' at time 'timeStamp'
1896   /// type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1897   /// if timeStamp==-1 return the mean value for the run
1898
1899   Float_t val=0;
1900   TString sensorName="";
1901   TTimeStamp stamp(timeStamp);
1902   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1903   if (!voltageArray || (sector<0) || (sector>71)) return val;
1904   Char_t sideName='A';
1905   if ((sector/18)%2==1) sideName='C';
1906   if (sector<36){
1907     //IROC
1908     sensorName=Form("TPC_GATE_I_%c_OFF_VMEAS",sideName);
1909   }else{
1910     //OROC
1911     sensorName=Form("TPC_GATE_O_%c_OFF_VMEAS",sideName);
1912   }
1913   if (timeStamp==-1){
1914     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1915   } else {
1916     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1917   }
1918   return val;
1919 }
1920
1921 Float_t AliTPCcalibDB::GetGGnegVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1922 {
1923   /// Get the GG offset voltage for run 'run' at time 'timeStamp'
1924   /// type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1925   /// if timeStamp==-1 return the mean value for the run
1926
1927   Float_t val=0;
1928   TString sensorName="";
1929   TTimeStamp stamp(timeStamp);
1930   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1931   if (!voltageArray || (sector<0) || (sector>71)) return val;
1932   Char_t sideName='A';
1933   if ((sector/18)%2==1) sideName='C';
1934   if (sector<36){
1935     //IROC
1936     sensorName=Form("TPC_GATE_I_%c_NEG_VMEAS",sideName);
1937   }else{
1938     //OROC
1939     sensorName=Form("TPC_GATE_O_%c_NEG_VMEAS",sideName);
1940   }
1941   if (timeStamp==-1){
1942     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1943   } else {
1944     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1945   }
1946   return val;
1947 }
1948
1949 Float_t AliTPCcalibDB::GetGGposVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1950 {
1951   /// Get the GG offset voltage for run 'run' at time 'timeStamp'
1952   /// type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1953   /// if timeStamp==-1 return the mean value for the run
1954
1955   Float_t val=0;
1956   TString sensorName="";
1957   TTimeStamp stamp(timeStamp);
1958   AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1959   if (!voltageArray || (sector<0) || (sector>71)) return val;
1960   Char_t sideName='A';
1961   if ((sector/18)%2==1) sideName='C';
1962   if (sector<36){
1963     //IROC
1964     sensorName=Form("TPC_GATE_I_%c_POS_VMEAS",sideName);
1965   }else{
1966     //OROC
1967     sensorName=Form("TPC_GATE_O_%c_POS_VMEAS",sideName);
1968   }
1969   if (timeStamp==-1){
1970     val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1971   } else {
1972     val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1973   }
1974   return val;
1975 }
1976
1977 Float_t AliTPCcalibDB::GetPressure(Int_t timeStamp, Int_t run, Int_t type){
1978   /// GetPressure for given time stamp and runt
1979
1980   TTimeStamp stamp(timeStamp);
1981   AliDCSSensor * sensor = Instance()->GetPressureSensor(run,type);
1982   if (!sensor) return 0;
1983   return sensor->GetValue(stamp);
1984 }
1985
1986 Float_t AliTPCcalibDB::GetL3Current(Int_t run, Int_t statType){
1987   /// return L3 current
1988   /// stat type is: AliGRPObject::Stats: kMean = 0, kTruncMean = 1, kMedian = 2, kSDMean = 3, kSDMedian = 4
1989
1990   Float_t current=-1;
1991   AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
1992   if (grp) current=grp->GetL3Current((AliGRPObject::Stats)statType);
1993   return current;
1994 }
1995
1996 Float_t AliTPCcalibDB::GetBz(Int_t run){
1997   /// calculate BZ in T from L3 current
1998
1999   Float_t bz=-1;
2000   Float_t current=AliTPCcalibDB::GetL3Current(run);
2001   if (current>-1) bz=5*current/30000.*.1;
2002   return bz;
2003 }
2004
2005 Char_t  AliTPCcalibDB::GetL3Polarity(Int_t run) {
2006   /// get l3 polarity from GRP
2007
2008   Char_t pol=-100;
2009   AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2010   if (grp) pol=grp->GetL3Polarity();
2011   return pol;
2012 }
2013
2014 TString AliTPCcalibDB::GetRunType(Int_t run){
2015   /// return run type from grp
2016
2017 //   TString type("UNKNOWN");
2018   AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2019   if (grp) return grp->GetRunType();
2020   return "UNKNOWN";
2021 }
2022
2023 Float_t AliTPCcalibDB::GetValueGoofie(Int_t timeStamp, Int_t run, Int_t type){
2024   /// GetPressure for given time stamp and runt
2025
2026   TTimeStamp stamp(timeStamp);
2027   AliDCSSensorArray* goofieArray = AliTPCcalibDB::Instance()->GetGoofieSensors(run);
2028   if (!goofieArray) return 0;
2029   AliDCSSensor *sensor = goofieArray->GetSensor(type);
2030   return sensor->GetValue(stamp);
2031 }
2032
2033
2034
2035
2036
2037
2038 Bool_t  AliTPCcalibDB::GetTemperatureFit(Int_t timeStamp, Int_t run, Int_t side,TVectorD& fit){
2039   /// GetTmeparature fit at parameter for given time stamp
2040
2041   TTimeStamp tstamp(timeStamp);
2042   AliTPCSensorTempArray* tempArray  = Instance()->GetTemperatureSensor(run);
2043   if (! tempArray) return kFALSE;
2044   AliTPCTempMap * tempMap = new AliTPCTempMap(tempArray);
2045   TLinearFitter * fitter = tempMap->GetLinearFitter(3,side,tstamp);
2046   if (fitter){
2047     fitter->Eval();
2048     fitter->GetParameters(fit);
2049   }
2050   delete fitter;
2051   delete tempMap;
2052   if (!fitter) return kFALSE;
2053   return kTRUE;
2054 }
2055
2056 Float_t AliTPCcalibDB::GetTemperature(Int_t timeStamp, Int_t run, Int_t side){
2057   /// Get mean temperature
2058
2059   TVectorD vec(5);
2060   if (side==0) {
2061     GetTemperatureFit(timeStamp,run,0,vec);
2062     return vec[0];
2063   }
2064   if (side==1){
2065     GetTemperatureFit(timeStamp,run,0,vec);
2066     return vec[0];
2067   }
2068   return 0;
2069 }
2070
2071
2072 Double_t AliTPCcalibDB::GetPTRelative(UInt_t timeSec, Int_t run, Int_t side){
2073   /// Get relative P/T
2074   /// time - absolute time
2075   /// run  - run number
2076   /// side - 0 - A side   1-C side
2077
2078   AliTPCCalibVdrift * vdrift =  Instance()->GetVdrift(run);
2079   if (!vdrift) return 0;
2080   return vdrift->GetPTRelative(timeSec,side);
2081 }
2082
2083 AliGRPObject * AliTPCcalibDB::MakeGRPObjectFromMap(TMap *map){
2084   /// Function to covert old GRP run information from TMap to GRPObject
2085   ///
2086   ///  TMap * map = AliTPCcalibDB::GetGRPMap(52406);
2087
2088   if (!map) return 0;
2089   AliDCSSensor * sensor = 0;
2090   TObject *osensor=0;
2091   osensor = ((*map)("fP2Pressure"));
2092   sensor  =dynamic_cast<AliDCSSensor *>(osensor);
2093   //
2094   if (!sensor) return 0;
2095   //
2096   AliDCSSensor * sensor2 = new AliDCSSensor(*sensor);
2097   osensor = ((*map)("fCavernPressure"));
2098   TGraph * gr = new TGraph(2);
2099   gr->GetX()[0]= -100000.;
2100   gr->GetX()[1]= 1000000.;
2101   gr->GetY()[0]= atof(osensor->GetName());
2102   gr->GetY()[1]= atof(osensor->GetName());
2103   sensor2->SetGraph(gr);
2104   sensor2->SetFit(0);
2105
2106
2107   AliGRPObject *grpRun = new AliGRPObject;
2108   grpRun->ReadValuesFromMap(map);
2109   grpRun->SetCavernAtmosPressure(sensor2);
2110   grpRun->SetCavernAtmosPressure(sensor2);
2111   grpRun->SetSurfaceAtmosPressure(sensor);
2112   return grpRun;
2113 }
2114
2115 Bool_t AliTPCcalibDB::CreateGUITree(Int_t run, const char* filename)
2116 {
2117   /// Create a gui tree for run number 'run'
2118
2119   if (!AliCDBManager::Instance()->GetDefaultStorage()){
2120     AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
2121                     MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
2122     return kFALSE;
2123   }
2124   //db instance
2125   AliTPCcalibDB *db=AliTPCcalibDB::Instance();
2126   // retrieve cal pad objects
2127   db->SetRun(run);
2128   db->CreateGUITree(filename);
2129   return kTRUE;
2130 }
2131
2132 Bool_t AliTPCcalibDB::CreateGUITree(const char* filename){
2133   ///
2134
2135   if (!AliCDBManager::Instance()->GetDefaultStorage()){
2136     AliError("Default Storage not set. Cannot create calibration Tree!");
2137     return kFALSE;
2138   }
2139   UpdateNonRec();  // load all infromation now
2140
2141   AliTPCPreprocessorOnline prep;
2142   if (GetActiveChannelMap()) prep.AddComponent(new AliTPCCalPad(*GetActiveChannelMap()));
2143
2144   // gain map
2145   if (GetDedxGainFactor()) prep.AddComponent(new AliTPCCalPad(*GetDedxGainFactor()));
2146   //noise and pedestals
2147   if (GetPedestals()) prep.AddComponent(new AliTPCCalPad(*(GetPedestals())));
2148   if (GetPadNoise() ) prep.AddComponent(new AliTPCCalPad(*(GetPadNoise())));
2149   //pulser data
2150   if (GetPulserTmean()) prep.AddComponent(new AliTPCCalPad(*(GetPulserTmean())));
2151   if (GetPulserTrms() ) prep.AddComponent(new AliTPCCalPad(*(GetPulserTrms())));
2152   if (GetPulserQmean()) prep.AddComponent(new AliTPCCalPad(*(GetPulserQmean())));
2153   //CE data
2154   if (GetCETmean()) prep.AddComponent(new AliTPCCalPad(*(GetCETmean())));
2155   if (GetCETrms() ) prep.AddComponent(new AliTPCCalPad(*(GetCETrms())));
2156   if (GetCEQmean()) prep.AddComponent(new AliTPCCalPad(*(GetCEQmean())));
2157   //Altro data
2158   if (GetALTROAcqStart() ) prep.AddComponent(new AliTPCCalPad(*(GetALTROAcqStart() )));
2159   if (GetALTROZsThr()    ) prep.AddComponent(new AliTPCCalPad(*(GetALTROZsThr()    )));
2160   if (GetALTROFPED()     ) prep.AddComponent(new AliTPCCalPad(*(GetALTROFPED()     )));
2161   if (GetALTROAcqStop()  ) prep.AddComponent(new AliTPCCalPad(*(GetALTROAcqStop()  )));
2162   if (GetALTROMasked()   ) prep.AddComponent(new AliTPCCalPad(*(GetALTROMasked()   )));
2163   //QA
2164   AliTPCdataQA *dataQA=GetDataQA();
2165   if (dataQA) {
2166     if (dataQA->GetNLocalMaxima())
2167       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNLocalMaxima())));
2168     if (dataQA->GetMaxCharge())
2169       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMaxCharge())));
2170     if (dataQA->GetMeanCharge())
2171       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMeanCharge())));
2172     if (dataQA->GetNoThreshold())
2173       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNoThreshold())));
2174     if (dataQA->GetNTimeBins())
2175       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNTimeBins())));
2176     if (dataQA->GetNPads())
2177       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNPads())));
2178     if (dataQA->GetTimePosition())
2179       prep.AddComponent(new AliTPCCalPad(*(dataQA->GetTimePosition())));
2180   }
2181
2182   //
2183   TString file(filename);
2184   if (file.IsNull()) file=Form("guiTreeRun_%i.root",fRun);
2185   prep.DumpToFile(file.Data());
2186   return kTRUE;
2187 }
2188
2189 Bool_t AliTPCcalibDB::CreateRefFile(Int_t run, const char* filename)
2190 {
2191   /// Create a gui tree for run number 'run'
2192
2193   if (!AliCDBManager::Instance()->GetDefaultStorage()){
2194     AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
2195                     MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
2196     return kFALSE;
2197   }
2198   TString file(filename);
2199   if (file.IsNull()) file=Form("RefCalPads_%d.root",run);
2200   TDirectory *currDir=gDirectory;
2201   //db instance
2202   AliTPCcalibDB *db=AliTPCcalibDB::Instance();
2203   // retrieve cal pad objects
2204   db->SetRun(run);
2205   //open file
2206   TFile f(file.Data(),"recreate");
2207   //noise and pedestals
2208   db->GetPedestals()->Write("Pedestals");
2209   db->GetPadNoise()->Write("PadNoise");
2210   //pulser data
2211   db->GetPulserTmean()->Write("PulserTmean");
2212   db->GetPulserTrms()->Write("PulserTrms");
2213   db->GetPulserQmean()->Write("PulserQmean");
2214   //CE data
2215   db->GetCETmean()->Write("CETmean");
2216   db->GetCETrms()->Write("CETrms");
2217   db->GetCEQmean()->Write("CEQmean");
2218   //Altro data
2219   db->GetALTROAcqStart() ->Write("ALTROAcqStart");
2220   db->GetALTROZsThr()    ->Write("ALTROZsThr");
2221   db->GetALTROFPED()     ->Write("ALTROFPED");
2222   db->GetALTROAcqStop()  ->Write("ALTROAcqStop");
2223   db->GetALTROMasked()   ->Write("ALTROMasked");
2224   //
2225   f.Close();
2226   currDir->cd();
2227   return kTRUE;
2228 }
2229
2230
2231
2232 Double_t AliTPCcalibDB::GetVDriftCorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
2233   /// Get time dependent drift velocity correction
2234   /// multiplication factor        vd = vdnom *(1+vdriftcorr)
2235   /// Arguments:
2236   /// mode determines the algorith how to combine the Laser Track, LaserCE and physics tracks
2237   /// timestamp - timestamp
2238   /// run       - run number
2239   /// side      - the drift velocity per side (possible for laser and CE)
2240   ///
2241   /// Notice - Extrapolation outside of calibration range  - using constant function
2242
2243   Double_t result=0;
2244   // mode 1  automatic mode - according to the distance to the valid calibration
2245   //                        -
2246   Double_t deltaP=0,  driftP=0,      wP  = 0.;
2247   Double_t deltaITS=0,driftITS=0,    wITS= 0.;
2248   Double_t deltaLT=0, driftLT=0,     wLT = 0.;
2249   Double_t deltaCE=0, driftCE=0,     wCE = 0.;
2250   driftP  = fDButil->GetVDriftTPC(deltaP,run,timeStamp);
2251   driftITS= fDButil->GetVDriftTPCITS(deltaITS,run,timeStamp);
2252   driftCE = fDButil->GetVDriftTPCCE(deltaCE, run,timeStamp,36000,2);
2253   driftLT = fDButil->GetVDriftTPCLaserTracks(deltaLT,run,timeStamp,36000,2);
2254   deltaITS = TMath::Abs(deltaITS);
2255   deltaP   = TMath::Abs(deltaP);
2256   deltaLT  = TMath::Abs(deltaLT);
2257   deltaCE  = TMath::Abs(deltaCE);
2258   if (mode==1) {
2259     const Double_t kEpsilon=0.00000000001;
2260     const Double_t kdeltaT=360.; // 10 minutes
2261     if(TMath::Abs(deltaITS) < 12*kdeltaT) {
2262       result = driftITS;
2263     } else {
2264     wITS  = 64.*kdeltaT/(deltaITS +kdeltaT);
2265     wLT   = 16.*kdeltaT/(deltaLT  +kdeltaT);
2266     wP    = 0. *kdeltaT/(deltaP   +kdeltaT);
2267     wCE   = 1. *kdeltaT/(deltaCE  +kdeltaT);
2268     //
2269     //
2270     if (TMath::Abs(driftP)<kEpsilon)  wP=0;  // invalid calibration
2271     if (TMath::Abs(driftITS)<kEpsilon)wITS=0;  // invalid calibration
2272     if (TMath::Abs(driftLT)<kEpsilon) wLT=0;  // invalid calibration
2273     if (TMath::Abs(driftCE)<kEpsilon) wCE=0;  // invalid calibration
2274     if (wP+wITS+wLT+wCE<kEpsilon) return 0;
2275     result = (driftP*wP+driftITS*wITS+driftLT*wLT+driftCE*wCE)/(wP+wITS+wLT+wCE);
2276    }
2277
2278
2279   }
2280
2281   return result;
2282 }
2283
2284 Double_t AliTPCcalibDB::GetTime0CorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
2285   /// Get time dependent time 0 (trigger delay in cm) correction
2286   /// additive correction        time0 = time0+ GetTime0CorrectionTime
2287   /// Value etracted combining the vdrift correction using laser tracks and CE and the physics track matchin
2288   /// Arguments:
2289   /// mode determines the algorith how to combine the Laser Track and physics tracks
2290   /// timestamp - timestamp
2291   /// run       - run number
2292   /// side      - the drift velocity per side (possible for laser and CE)
2293   ///
2294   /// Notice - Extrapolation outside of calibration range  - using constant function
2295
2296   Double_t result=0;
2297   if (mode==2) {
2298     // TPC-TPC mode
2299     result=fDButil->GetTriggerOffsetTPC(run,timeStamp);
2300     result  *=fParam->GetZLength();
2301   }
2302   if (mode==1){
2303     // TPC-ITS mode
2304     Double_t dist=0;
2305     result= -fDButil->GetTime0TPCITS(dist, run, timeStamp)*fParam->GetDriftV()/1000000.;
2306   }
2307   return result;
2308
2309 }
2310
2311
2312
2313
2314 Double_t AliTPCcalibDB::GetVDriftCorrectionGy(Int_t timeStamp, Int_t run, Int_t side, Int_t /*mode*/){
2315   /// Get global y correction drift velocity correction factor
2316   /// additive factor        vd = vdnom*(1+GetVDriftCorrectionGy *gy)
2317   /// Value etracted combining the vdrift correction using laser tracks and CE or TPC-ITS
2318   /// Arguments:
2319   /// mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
2320   /// timestamp - timestamp
2321   /// run       - run number
2322   /// side      - the drift velocity gy correction per side (CE and Laser tracks)
2323   ///
2324   /// Notice - Extrapolation outside of calibration range  - using constant function
2325
2326   if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
2327   UpdateRunInformations(run,kFALSE);
2328   TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2329   if (!array) return 0;
2330   Double_t result=0;
2331
2332   // use TPC-ITS if present
2333   TGraphErrors *gr= (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_VDGY");
2334   if (!gr) gr = (TGraphErrors*)array->FindObject("ALIGN_TOFB_TPC_VDGY");
2335   if(gr) {
2336     result = AliTPCcalibDButil::EvalGraphConst(gr,timeStamp);
2337
2338     // transform from [(cm/mus)/ m] to [1/cm]
2339     result /= (fParam->GetDriftV()/1000000.);
2340     result /= 100.;
2341
2342     //printf("result %e \n", result);
2343     return result;
2344   }
2345
2346   // use laser if ITS-TPC not present
2347   TGraphErrors *laserA= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_A");
2348   TGraphErrors *laserC= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_C");
2349
2350   if (laserA && laserC){
2351    result= (laserA->Eval(timeStamp)+laserC->Eval(timeStamp))*0.5;
2352   }
2353   if (laserA && side==0){
2354     result = (laserA->Eval(timeStamp));
2355   }
2356   if (laserC &&side==1){
2357     result = (laserC->Eval(timeStamp));
2358   }
2359   //printf("laser result %e \n", -result/250.);
2360
2361   return -result/250.; //normalized before
2362 }
2363
2364
2365 Double_t AliTPCcalibDB::GetVDriftCorrectionDeltaZ(Int_t /*timeStamp*/, Int_t run, Int_t /*side*/, Int_t /*mode*/){
2366   /// Get deltaZ run/by/run  correction - as fitted together with drift velocity
2367   /// Value extracted  form the TPC-ITS, mean value is used
2368
2369   // Arguments:
2370   // mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
2371   // timestamp - not used
2372   // run       - run number
2373   // side      - common for boith sides
2374   //
2375   if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
2376   UpdateRunInformations(run,kFALSE);
2377   TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2378   if (!array) return 0;
2379   Double_t result=0;
2380
2381   // use TPC-ITS if present
2382   TGraphErrors *gr= (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_DELTAZ");
2383   if(gr) {
2384     result = TMath::Mean(gr->GetN(), gr->GetY());
2385   }
2386   return result;
2387 }
2388
2389
2390
2391
2392 AliTPCCalPad* AliTPCcalibDB::MakeDeadMap(Double_t notInMap, const char* nameMappingFile) {
2393 ///   Read list of active DDLs from OCDB entry
2394 ///   Generate and return AliTPCCalPad containing 1 for all pads in active DDLs,
2395 ///   0 for all pads in non-active DDLs.
2396 ///   For DDLs with missing status information (no DCS input point to Shuttle),
2397 ///     the value of the AliTPCCalPad entry is determined by the parameter
2398 ///     notInMap (default value 1)
2399
2400   char chinfo[1000];
2401
2402   TFile *fileMapping = new TFile(nameMappingFile, "read");
2403   AliTPCmapper *mapping = (AliTPCmapper*) fileMapping->Get("tpcMapping");
2404   if (!mapping) {
2405     snprintf(chinfo,1000,"Failed to get mapping object from %s.  ...\n", nameMappingFile);
2406     AliError (chinfo);
2407     return 0;
2408   }
2409
2410   AliTPCCalPad *deadMap = new AliTPCCalPad("deadMap","deadMap");
2411   if (!deadMap) {
2412      AliError("Failed to allocate dead map AliTPCCalPad");
2413      return 0;
2414   }
2415
2416   /// get list of active DDLs from OCDB entry
2417   Int_t idDDL=0;
2418   if (!fALTROConfigData ) {
2419      AliError("No ALTRO config OCDB entry available");
2420      return 0;
2421   }
2422   TMap *activeDDL = (TMap*)fALTROConfigData->FindObject("DDLArray");
2423   TObjString *ddlArray=0;
2424   if (activeDDL) {
2425     ddlArray = (TObjString*)activeDDL->GetValue("DDLArray");
2426     if (!ddlArray) {
2427       AliError("Empty list of active DDLs in OCDB entry");
2428       return 0;
2429     }
2430   } else {
2431     AliError("List of active DDLs not available in OCDB entry");
2432     return 0;
2433   }
2434   TString arrDDL=ddlArray->GetString();
2435   Int_t offset = mapping->GetTpcDdlOffset();
2436   Double_t active;
2437   for (Int_t i=0; i<mapping->GetNumDdl(); i++) {
2438     idDDL= i+offset;
2439     if (idDDL<0) continue;
2440     Int_t patch = mapping->GetPatchFromEquipmentID(idDDL);
2441     if (patch<0) continue;
2442     Int_t roc=mapping->GetRocFromEquipmentID(idDDL);
2443     if (roc<0) continue;
2444     AliTPCCalROC *calRoc=deadMap->GetCalROC(roc);
2445     if (calRoc) {
2446      for ( Int_t branch = 0; branch < 2; branch++ ) {
2447       for ( Int_t fec = 0; fec < mapping->GetNfec(patch, branch); fec++ ) {
2448         for ( Int_t altro = 0; altro < 8; altro++ ) {
2449          for ( Int_t channel = 0; channel < 16; channel++ ) {
2450            Int_t hwadd     = mapping->CodeHWAddress(branch, fec, altro, channel);
2451            Int_t row       = mapping->GetPadRow(patch, hwadd);        // row in a ROC (IROC or OROC)
2452 //              Int_t globalrow = mapping.GetGlobalPadRow(patch, hwadd);  // row in full sector (IROC plus OROC)
2453            Int_t pad       = mapping->GetPad(patch, hwadd);
2454            if (!TString(arrDDL[i]).IsDigit()) {
2455               active = notInMap;
2456            } else {
2457               active=TString(arrDDL[i]).Atof();
2458            }
2459            calRoc->SetValue(row,pad,active);
2460          } // end channel for loop
2461         } // end altro for loop
2462       } // end fec for loop
2463      } // end branch for loop
2464     } // valid calROC
2465    } // end loop on active DDLs
2466    return deadMap;
2467 }
2468
2469
2470
2471 AliTPCCorrection * AliTPCcalibDB::GetTPCComposedCorrection(Float_t field) const{
2472   /// GetComposed correction for given field setting
2473   /// If not specific correction for field used return correction for all field
2474   ///        - Complication needed to gaurantee OCDB back compatibility
2475   ///        - Not neeeded for the new space point correction
2476
2477   if (!fComposedCorrectionArray) return 0;
2478   if (field>0.1 && fComposedCorrectionArray->At(1)) {
2479     return (AliTPCCorrection *)fComposedCorrectionArray->At(1);
2480   }
2481   if (field<-0.1 &&fComposedCorrectionArray->At(2)) {
2482     return (AliTPCCorrection *)fComposedCorrectionArray->At(2);
2483   }
2484   return (AliTPCCorrection *)fComposedCorrectionArray->At(0);
2485
2486 }
2487
2488
2489 AliTPCCorrection * AliTPCcalibDB::GetTPCComposedCorrectionDelta() const{
2490   /// GetComposedCorrection delta
2491   /// Delta is time dependent - taken form the CalibTime OCDB entry
2492
2493   if (!fComposedCorrectionArray) return 0;
2494   if (fRun<0) return 0;
2495   if (fDriftCorrectionArray.GetValue(Form("%i",fRun))==0) return 0;
2496   if (fComposedCorrectionArray->GetEntriesFast()<=4) {
2497     fComposedCorrectionArray->Expand(5);
2498     TObjArray * timeArray =(TObjArray*)(fDriftCorrectionArray.GetValue(Form("%i",fRun)));
2499      AliTPCCorrection * correctionTime = (AliTPCCorrection *)timeArray->FindObject("FitCorrectionTime");
2500      if (correctionTime){
2501        correctionTime->Init();
2502        fComposedCorrectionArray->AddAt(correctionTime,4); //add time dependent c
2503      }
2504   }
2505   return (AliTPCCorrection *)fComposedCorrectionArray->At(4);  //
2506 }
2507
2508 Double_t AliTPCcalibDB::GetGainCorrectionHVandPT(Int_t timeStamp, Int_t run, Int_t sector, Int_t deltaCache, Int_t mode){
2509   /// Correction for  changes of gain caused by change of the HV and by relative change of the gas density
2510   /// Function is slow some kind of caching needed
2511   /// Cache implemented using the static TVectorD
2512   ///
2513   /// Input paremeters:
2514   ///  deltaCache - maximal time differnce above which the cache is recaclulated
2515   ///  mode       - mode==0 by default return combined correction
2516   ///                       actual HV and Pt correction has to be present in the run calibration otherwise it is ignored.
2517   ///                       (retrun value differnt than 1 only in case calibration present in the OCDB entry CalibTimeGain
2518   ///               mode==1 return combined correction ( important for calibration pass)
2519   ///                       (in case thereis  no calibration in  CalibTimeGain, default value from the AliTPCParam (Parameters) is used
2520   ///                       this mode is used in the CPass0
2521   ///               mode==2 return HV correction
2522   ///               mode==3 return P/T correction
2523   ///  Usage in the simulation/reconstruction
2524   ///  MC:     Qcorr  = Qorig*GetGainCorrectionHVandPT   ( in AliTPC.cxx )
2525   ///  Rec:    dEdx   = dEdx/GetGainCorrectionHVandPT    ( in aliTPCseed.cxx )
2526
2527   static Float_t gGainCorrection[72];
2528   static Float_t gGainCorrectionPT[72];
2529   static Float_t gGainCorrectionHV[72];
2530   static Int_t    gTimeStamp=-99999999;
2531   static Bool_t   hasTimeDependent=kFALSE;
2532   if ( TMath::Abs(timeStamp-gTimeStamp)> deltaCache){
2533     //
2534     TGraphErrors * graphGHV = 0;
2535     TGraphErrors * graphGPT = 0;
2536     TObjArray *timeGainSplines = GetTimeGainSplinesRun(run);
2537     if (timeGainSplines){
2538       graphGHV  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesHV");
2539       graphGPT  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesPT");
2540       if (graphGHV) hasTimeDependent=kTRUE;
2541     }
2542     if (!graphGHV) graphGHV = fParam->GetGainSlopesHV();
2543     if (!graphGPT) graphGPT = fParam->GetGainSlopesPT();
2544     //
2545     for (Int_t isec=0; isec<72; isec++){
2546       Double_t deltaHV= GetChamberHighVoltage(run,isec, timeStamp) - fParam->GetNominalVoltage(isec);
2547       Double_t deltaGHV=0;
2548       Double_t deltaGPT=0;
2549       if (graphGHV) deltaGHV = graphGHV->GetY()[isec]*deltaHV;
2550       if (graphGPT) deltaGPT = graphGPT->GetY()[isec]*GetPTRelative(timeStamp,run,0);
2551       gGainCorrection[isec]=(1.+deltaGHV)*(1.+deltaGPT);
2552       gGainCorrectionPT[isec]=1+deltaGPT;
2553       gGainCorrectionHV[isec]=1+deltaGHV;
2554     }
2555     gTimeStamp=timeStamp;
2556   }
2557   if (mode==0){
2558     if (hasTimeDependent) return gGainCorrection[sector];
2559     if (!hasTimeDependent) return 1;
2560   }
2561   if (mode==1) return gGainCorrection[sector];
2562   if (mode==2) return gGainCorrectionPT[sector];
2563   if (mode==3) return gGainCorrectionHV[sector];
2564   return 1;
2565 }