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