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