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