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