bugfix: moving call to AliTPCcalibDB::SetExBField to DoInit() It was not executed...
[u/mrichter/AliRoot.git] / TPC / AliTPCcalibDB.cxx
CommitLineData
c5bbaa2c 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 //
1ac191a6 23// Then request the calibration data ////
f5344549 24//
25//
1ac191a6 26// Calibration data:
8cd9634d 27// 0.) Altro mapping
28// Simulation - not yet
29// Reconstruction - AliTPCclustererMI::Digits2Clusters(AliRawReader* rawReader)
30//
1ac191a6 31// 1.) pad by pad calibration - AliTPCCalPad
f5344549 32//
1ac191a6 33// a.) fPadGainFactor
34// Simulation: AliTPCDigitizer::ExecFast - Multiply by gain
35// Reconstruction : AliTPCclustererMI::Digits2Clusters - Divide by gain
f5344549 36//
1ac191a6 37// b.) fPadNoise -
38// Simulation: AliTPCDigitizer::ExecFast
39// Reconstruction: AliTPCclustererMI::FindClusters(AliTPCCalROC * noiseROC)
8cd9634d 40// Noise depending cut on clusters charge (n sigma)
f5344549 41// c.) fPedestal:
42// Simulation: Not used yet - To be impleneted - Rounding to the nearest integer
43// Reconstruction: Used in AliTPCclustererMI::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()
8cd9634d 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// AliTPCclustererMI::AddCluster
64// AliTPCtrackerMI::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//
96305e49 73// 3.) cluster error, shape and Q parameterization
74//
75//
8cd9634d 76//
c5bbaa2c 77///////////////////////////////////////////////////////////////////////////////
78
418bbcaf 79#include <iostream>
80#include <fstream>
81
c5bbaa2c 82
83#include <AliCDBManager.h>
c5bbaa2c 84#include <AliCDBEntry.h>
85#include <AliLog.h>
3ac615eb 86#include <AliMagF.h>
7fff7612 87#include <AliSplineFit.h>
c5bbaa2c 88
89#include "AliTPCcalibDB.h"
817766d5 90#include "AliTPCcalibDButil.h"
d6834f5f 91#include "AliTPCAltroMapping.h"
418bbcaf 92#include "AliTPCExB.h"
c5bbaa2c 93
94#include "AliTPCCalROC.h"
95#include "AliTPCCalPad.h"
54472e4f 96#include "AliTPCSensorTempArray.h"
bf85fe4d 97#include "AliGRPObject.h"
418bbcaf 98#include "AliTPCTransform.h"
d6834f5f 99
418bbcaf 100class AliCDBStorage;
101class AliTPCCalDet;
86df2b3a 102//
103//
104
86df2b3a 105#include "TFile.h"
106#include "TKey.h"
43a74775 107#include "TGraphErrors.h"
86df2b3a 108
109#include "TObjArray.h"
110#include "TObjString.h"
111#include "TString.h"
7390f655 112#include "TDirectory.h"
86df2b3a 113#include "AliTPCCalPad.h"
0fe7645c 114#include "AliTPCCalibPulser.h"
86df2b3a 115#include "AliTPCCalibPedestal.h"
116#include "AliTPCCalibCE.h"
3ac615eb 117#include "AliTPCExBFirst.h"
bf85fe4d 118#include "AliTPCTempMap.h"
da6c0bc9 119#include "AliTPCCalibVdrift.h"
6e7d7dc4 120#include "AliTPCCalibRaw.h"
43a74775 121#include "AliTPCParam.h"
86df2b3a 122
5312f439 123#include "AliTPCPreprocessorOnline.h"
86df2b3a 124
c5bbaa2c 125
126ClassImp(AliTPCcalibDB)
127
128AliTPCcalibDB* AliTPCcalibDB::fgInstance = 0;
129Bool_t AliTPCcalibDB::fgTerminated = kFALSE;
3ac615eb 130TObjArray AliTPCcalibDB::fgExBArray; // array of ExB corrections
c5bbaa2c 131
132
133//_ singleton implementation __________________________________________________
134AliTPCcalibDB* AliTPCcalibDB::Instance()
135{
136 //
137 // Singleton implementation
138 // Returns an instance of this class, it is created if neccessary
139 //
140
141 if (fgTerminated != kFALSE)
142 return 0;
143
144 if (fgInstance == 0)
145 fgInstance = new AliTPCcalibDB();
146
147 return fgInstance;
148}
149
150void AliTPCcalibDB::Terminate()
151{
152 //
153 // Singleton implementation
154 // Deletes the instance of this class and sets the terminated flag, instances cannot be requested anymore
155 // This function can be called several times.
156 //
157
158 fgTerminated = kTRUE;
159
160 if (fgInstance != 0)
161 {
162 delete fgInstance;
163 fgInstance = 0;
164 }
165}
166
167//_____________________________________________________________________________
e4dce695 168AliTPCcalibDB::AliTPCcalibDB():
9389f9a4 169 TObject(),
e4dce695 170 fRun(-1),
f5344549 171 fTransform(0),
481f877b 172 fExB(0),
e4dce695 173 fPadGainFactor(0),
9f6e9f81 174 fDedxGainFactor(0),
e4dce695 175 fPadTime0(0),
e4dce695 176 fPadNoise(0),
177 fPedestals(0),
6e7d7dc4 178 fCalibRaw(0),
5312f439 179 fALTROConfigData(0),
180 fPulserData(0),
181 fCEData(0),
e4dce695 182 fTemperature(0),
d6834f5f 183 fMapping(0),
96305e49 184 fParam(0),
a2c3785e 185 fClusterParam(0),
186 fTimeGainSplines(0),
187 fTimeGainSplinesArray(100000),
da6c0bc9 188 fGRPArray(100000), //! array of GRPs - per run - JUST for calibration studies
0231c65f 189 fGRPMaps(100000), //! array of GRPs - per run - JUST for calibration studies
da6c0bc9 190 fGoofieArray(100000), //! array of GOOFIE values -per run - Just for calibration studies
e2914767 191 fVoltageArray(100000),
da6c0bc9 192 fTemperatureArray(100000), //! array of temperature sensors - per run - Just for calibration studies
193 fVdriftArray(100000), //! array of v drift interfaces
5e1215d4 194 fDriftCorrectionArray(100000), //! array of drift correction
1e722a63 195 fRunList(100000), //! run list - indicates try to get the run param
196 fDButil(0)
c5bbaa2c 197{
198 //
199 // constructor
200 //
54472e4f 201 //
c5bbaa2c 202 Update(); // temporary
203}
204
9389f9a4 205AliTPCcalibDB::AliTPCcalibDB(const AliTPCcalibDB& ):
206 TObject(),
207 fRun(-1),
208 fTransform(0),
209 fExB(0),
210 fPadGainFactor(0),
9f6e9f81 211 fDedxGainFactor(0),
9389f9a4 212 fPadTime0(0),
213 fPadNoise(0),
214 fPedestals(0),
6e7d7dc4 215 fCalibRaw(0),
5312f439 216 fALTROConfigData(0),
217 fPulserData(0),
218 fCEData(0),
9389f9a4 219 fTemperature(0),
220 fMapping(0),
9389f9a4 221 fParam(0),
bf85fe4d 222 fClusterParam(0),
a2c3785e 223 fTimeGainSplines(0),
224 fTimeGainSplinesArray(100000),
bf85fe4d 225 fGRPArray(0), //! array of GRPs - per run - JUST for calibration studies
0231c65f 226 fGRPMaps(0), //! array of GRPs - per run - JUST for calibration studies
bf85fe4d 227 fGoofieArray(0), //! array of GOOFIE values -per run - Just for calibration studies
e2914767 228 fVoltageArray(0),
bf85fe4d 229 fTemperatureArray(0), //! array of temperature sensors - per run - Just for calibration studies
da6c0bc9 230 fVdriftArray(0), //! array of v drift interfaces
5e1215d4 231 fDriftCorrectionArray(0), //! array of v drift interfaces
1e722a63 232 fRunList(0), //! run list - indicates try to get the run param
233 fDButil(0)
9389f9a4 234{
235 //
236 // Copy constructor invalid -- singleton implementation
237 //
238 Error("copy constructor","invalid -- singleton implementation");
239}
240
241AliTPCcalibDB& AliTPCcalibDB::operator= (const AliTPCcalibDB& )
242{
243//
244// Singleton implementation - no assignment operator
245//
246 Error("operator =", "assignment operator not implemented");
247 return *this;
248}
249
250
251
c5bbaa2c 252//_____________________________________________________________________________
253AliTPCcalibDB::~AliTPCcalibDB()
254{
255 //
256 // destructor
257 //
68751c2c 258
259 // don't delete anything, CDB cache is active!
260 //if (fPadGainFactor) delete fPadGainFactor;
261 //if (fPadTime0) delete fPadTime0;
68751c2c 262 //if (fPadNoise) delete fPadNoise;
c5bbaa2c 263}
264
265
266//_____________________________________________________________________________
267AliCDBEntry* AliTPCcalibDB::GetCDBEntry(const char* cdbPath)
268{
269 //
270 // Retrieves an entry with path <cdbPath> from the CDB.
271 //
272 char chinfo[1000];
273
68751c2c 274 AliCDBEntry* entry = AliCDBManager::Instance()->Get(cdbPath, fRun);
c5bbaa2c 275 if (!entry)
276 {
277 sprintf(chinfo,"AliTPCcalibDB: Failed to get entry:\t%s ", cdbPath);
278 AliError(chinfo);
279 return 0;
280 }
281 return entry;
282}
283
284
285//_____________________________________________________________________________
286void AliTPCcalibDB::SetRun(Long64_t run)
287{
288 //
289 // Sets current run number. Calibration data is read from the corresponding file.
290 //
291 if (fRun == run)
292 return;
a2c3785e 293 fRun = run;
c5bbaa2c 294 Update();
295}
296
297
298
299void AliTPCcalibDB::Update(){
a2c3785e 300 //
a8f8b6a1 301 AliCDBEntry * entry=0;
68751c2c 302 Bool_t cdbCache = AliCDBManager::Instance()->GetCacheFlag(); // save cache status
303 AliCDBManager::Instance()->SetCacheFlag(kTRUE); // activate CDB cache
1e722a63 304 fDButil = new AliTPCcalibDButil;
c5bbaa2c 305 //
306 entry = GetCDBEntry("TPC/Calib/PadGainFactor");
307 if (entry){
68751c2c 308 //if (fPadGainFactor) delete fPadGainFactor;
c5bbaa2c 309 entry->SetOwner(kTRUE);
310 fPadGainFactor = (AliTPCCalPad*)entry->GetObject();
311 }
312 //
3af3fbc4 313 entry = GetCDBEntry("TPC/Calib/TimeGain");
314 if (entry){
315 //if (fTimeGainSplines) delete fTimeGainSplines;
316 entry->SetOwner(kTRUE);
317 fTimeGainSplines = (TObjArray*)entry->GetObject();
318 }
319 //
9f6e9f81 320 entry = GetCDBEntry("TPC/Calib/GainFactorDedx");
321 if (entry){
322 entry->SetOwner(kTRUE);
323 fDedxGainFactor = (AliTPCCalPad*)entry->GetObject();
324 }
325 //
c5bbaa2c 326 entry = GetCDBEntry("TPC/Calib/PadTime0");
327 if (entry){
68751c2c 328 //if (fPadTime0) delete fPadTime0;
c5bbaa2c 329 entry->SetOwner(kTRUE);
330 fPadTime0 = (AliTPCCalPad*)entry->GetObject();
331 }
332 //
c5bbaa2c 333 //
334 entry = GetCDBEntry("TPC/Calib/PadNoise");
335 if (entry){
68751c2c 336 //if (fPadNoise) delete fPadNoise;
c5bbaa2c 337 entry->SetOwner(kTRUE);
338 fPadNoise = (AliTPCCalPad*)entry->GetObject();
339 }
8477f500 340
341 entry = GetCDBEntry("TPC/Calib/Pedestals");
342 if (entry){
343 //if (fPedestals) delete fPedestals;
344 entry->SetOwner(kTRUE);
345 fPedestals = (AliTPCCalPad*)entry->GetObject();
346 }
347
54472e4f 348 entry = GetCDBEntry("TPC/Calib/Temperature");
349 if (entry){
350 //if (fTemperature) delete fTemperature;
351 entry->SetOwner(kTRUE);
352 fTemperature = (AliTPCSensorTempArray*)entry->GetObject();
353 }
354
8477f500 355 entry = GetCDBEntry("TPC/Calib/Parameters");
356 if (entry){
54472e4f 357 //if (fPadNoise) delete fPadNoise;
8477f500 358 entry->SetOwner(kTRUE);
a778f7e3 359 fParam = (AliTPCParam*)(entry->GetObject()->Clone());
8477f500 360 }
361
96305e49 362 entry = GetCDBEntry("TPC/Calib/ClusterParam");
363 if (entry){
96305e49 364 entry->SetOwner(kTRUE);
365 fClusterParam = (AliTPCClusterParam*)(entry->GetObject()->Clone());
366 }
367
5312f439 368 //ALTRO configuration data
369 entry = GetCDBEntry("TPC/Calib/AltroConfig");
370 if (entry){
371 entry->SetOwner(kTRUE);
372 fALTROConfigData=(TObjArray*)(entry->GetObject());
373 }
374
375 //Calibration Pulser data
376 entry = GetCDBEntry("TPC/Calib/Pulser");
377 if (entry){
378 entry->SetOwner(kTRUE);
379 fPulserData=(TObjArray*)(entry->GetObject());
380 }
381
382 //CE data
383 entry = GetCDBEntry("TPC/Calib/CE");
384 if (entry){
385 entry->SetOwner(kTRUE);
386 fCEData=(TObjArray*)(entry->GetObject());
387 }
6e7d7dc4 388 //RAW calibration data
389 entry = GetCDBEntry("TPC/Calib/Raw");
390 if (entry){
391 entry->SetOwner(kTRUE);
392 TObjArray *arr=(TObjArray*)(entry->GetObject());
393 if (arr) fCalibRaw=(AliTPCCalibRaw*)arr->At(0);
394 }
5312f439 395
d6834f5f 396 entry = GetCDBEntry("TPC/Calib/Mapping");
397 if (entry){
398 //if (fPadNoise) delete fPadNoise;
399 entry->SetOwner(kTRUE);
400 TObjArray * array = dynamic_cast<TObjArray*>(entry->GetObject());
401 if (array && array->GetEntriesFast()==6){
402 fMapping = new AliTPCAltroMapping*[6];
403 for (Int_t i=0; i<6; i++){
5312f439 404 fMapping[i] = dynamic_cast<AliTPCAltroMapping*>(array->At(i));
d6834f5f 405 }
406 }
407 }
408
409
410
3ac615eb 411 //entry = GetCDBEntry("TPC/Calib/ExB");
412 //if (entry) {
413 // entry->SetOwner(kTRUE);
414 // fExB=dynamic_cast<AliTPCExB*>(entry->GetObject()->Clone());
415 //}
416 //
3a3318d5 417 // ExB - calculate during initialization - in simulation /reconstruction
418 // - not invoked here anymore
419 //fExB = GetExB(-5,kTRUE);
f4d5fd21 420 //
f5344549 421 if (!fTransform) {
422 fTransform=new AliTPCTransform();
bfec3eeb 423 fTransform->SetCurrentRun(AliCDBManager::Instance()->GetRun());
f5344549 424 }
8477f500 425
c5bbaa2c 426 //
68751c2c 427 AliCDBManager::Instance()->SetCacheFlag(cdbCache); // reset original CDB cache
c5bbaa2c 428}
e4dce695 429
86df2b3a 430
431
432void AliTPCcalibDB::CreateObjectList(const Char_t *filename, TObjArray *calibObjects)
433{
418bbcaf 434//
435// Create calibration objects and read contents from OCDB
436//
86df2b3a 437 if ( calibObjects == 0x0 ) return;
438 ifstream in;
439 in.open(filename);
440 if ( !in.is_open() ){
441 fprintf(stderr,"Error: cannot open list file '%s'", filename);
442 return;
443 }
444
445 AliTPCCalPad *calPad=0x0;
446
447 TString sFile;
448 sFile.ReadFile(in);
449 in.close();
450
451 TObjArray *arrFileLine = sFile.Tokenize("\n");
452
453 TIter nextLine(arrFileLine);
454
455 TObjString *sObjLine=0x0;
2c632057 456 while ( (sObjLine = (TObjString*)nextLine()) ){
86df2b3a 457 TString sLine(sObjLine->GetString());
458
459 TObjArray *arrNextCol = sLine.Tokenize("\t");
460
461 TObjString *sObjType = (TObjString*)(arrNextCol->At(0));
462 TObjString *sObjFileName = (TObjString*)(arrNextCol->At(1));
463
464 if ( !sObjType || ! sObjFileName ) continue;
465 TString sType(sObjType->GetString());
466 TString sFileName(sObjFileName->GetString());
467 printf("%s\t%s\n",sType.Data(),sFileName.Data());
468
469 TFile *fIn = TFile::Open(sFileName);
470 if ( !fIn ){
471 fprintf(stderr,"File not found: '%s'", sFileName.Data());
472 continue;
473 }
474
475 if ( sType == "CE" ){
476 AliTPCCalibCE *ce = (AliTPCCalibCE*)fIn->Get("AliTPCCalibCE");
477
478 calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadT0());
479 calPad->SetNameTitle("CETmean","CETmean");
480 calibObjects->Add(calPad);
481
482 calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadQ());
483 calPad->SetNameTitle("CEQmean","CEQmean");
484 calibObjects->Add(calPad);
485
486 calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadRMS());
487 calPad->SetNameTitle("CETrms","CETrms");
488 calibObjects->Add(calPad);
489
490 } else if ( sType == "Pulser") {
0fe7645c 491 AliTPCCalibPulser *sig = (AliTPCCalibPulser*)fIn->Get("AliTPCCalibPulser");
86df2b3a 492
493 calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadT0());
494 calPad->SetNameTitle("PulserTmean","PulserTmean");
495 calibObjects->Add(calPad);
496
497 calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadQ());
498 calPad->SetNameTitle("PulserQmean","PulserQmean");
499 calibObjects->Add(calPad);
500
501 calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadRMS());
502 calPad->SetNameTitle("PulserTrms","PulserTrms");
503 calibObjects->Add(calPad);
504
505 } else if ( sType == "Pedestals") {
506 AliTPCCalibPedestal *ped = (AliTPCCalibPedestal*)fIn->Get("AliTPCCalibPedestal");
507
508 calPad = new AliTPCCalPad((TObjArray*)ped->GetCalPadPedestal());
509 calPad->SetNameTitle("Pedestals","Pedestals");
510 calibObjects->Add(calPad);
511
512 calPad = new AliTPCCalPad((TObjArray*)ped->GetCalPadRMS());
513 calPad->SetNameTitle("Noise","Noise");
514 calibObjects->Add(calPad);
515
516 } else {
517 fprintf(stderr,"Undefined Type: '%s'",sType.Data());
518
519 }
520 delete fIn;
521 }
522}
523
524
525
526void AliTPCcalibDB::MakeTree(const char * fileName, TObjArray * array, const char * mapFileName, AliTPCCalPad* outlierPad, Float_t ltmFraction) {
527 //
528 // Write a tree with all available information
418bbcaf 529 // if mapFileName is specified, the Map information are also written to the tree
86df2b3a 530 // pads specified in outlierPad are not used for calculating statistics
531 // - the same function as AliTPCCalPad::MakeTree -
532 //
533 AliTPCROC* tpcROCinstance = AliTPCROC::Instance();
534
535 TObjArray* mapIROCs = 0;
536 TObjArray* mapOROCs = 0;
537 TVectorF *mapIROCArray = 0;
538 TVectorF *mapOROCArray = 0;
539 Int_t mapEntries = 0;
540 TString* mapNames = 0;
541
542 if (mapFileName) {
543 TFile mapFile(mapFileName, "read");
544
545 TList* listOfROCs = mapFile.GetListOfKeys();
546 mapEntries = listOfROCs->GetEntries()/2;
547 mapIROCs = new TObjArray(mapEntries*2);
548 mapOROCs = new TObjArray(mapEntries*2);
549 mapIROCArray = new TVectorF[mapEntries];
550 mapOROCArray = new TVectorF[mapEntries];
551
552 mapNames = new TString[mapEntries];
553 for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
418bbcaf 554 TString nameROC(((TKey*)(listOfROCs->At(ivalue*2)))->GetName());
555 nameROC.Remove(nameROC.Length()-4, 4);
556 mapIROCs->AddAt((AliTPCCalROC*)mapFile.Get((nameROC + "IROC").Data()), ivalue);
557 mapOROCs->AddAt((AliTPCCalROC*)mapFile.Get((nameROC + "OROC").Data()), ivalue);
558 mapNames[ivalue].Append(nameROC);
86df2b3a 559 }
560
561 for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
562 mapIROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(0));
563 mapOROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(36));
564
565 for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(0); ichannel++)
566 (mapIROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapIROCs->At(ivalue)))->GetValue(ichannel);
567 for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(36); ichannel++)
568 (mapOROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapOROCs->At(ivalue)))->GetValue(ichannel);
569 }
570
571 } // if (mapFileName)
572
573 TTreeSRedirector cstream(fileName);
574 Int_t arrayEntries = array->GetEntries();
575
576 TString* names = new TString[arrayEntries];
577 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
578 names[ivalue].Append(((AliTPCCalPad*)array->At(ivalue))->GetName());
579
580 for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++) {
581 //
582 // get statistic for given sector
583 //
584 TVectorF median(arrayEntries);
585 TVectorF mean(arrayEntries);
586 TVectorF rms(arrayEntries);
587 TVectorF ltm(arrayEntries);
588 TVectorF ltmrms(arrayEntries);
589 TVectorF medianWithOut(arrayEntries);
590 TVectorF meanWithOut(arrayEntries);
591 TVectorF rmsWithOut(arrayEntries);
592 TVectorF ltmWithOut(arrayEntries);
593 TVectorF ltmrmsWithOut(arrayEntries);
594
595 TVectorF *vectorArray = new TVectorF[arrayEntries];
596 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
597 vectorArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
598
599 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
600 AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
601 AliTPCCalROC* calROC = calPad->GetCalROC(isector);
602 AliTPCCalROC* outlierROC = 0;
603 if (outlierPad) outlierROC = outlierPad->GetCalROC(isector);
604 if (calROC) {
605 median[ivalue] = calROC->GetMedian();
606 mean[ivalue] = calROC->GetMean();
607 rms[ivalue] = calROC->GetRMS();
608 Double_t ltmrmsValue = 0;
609 ltm[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction);
610 ltmrms[ivalue] = ltmrmsValue;
611 if (outlierROC) {
612 medianWithOut[ivalue] = calROC->GetMedian(outlierROC);
613 meanWithOut[ivalue] = calROC->GetMean(outlierROC);
614 rmsWithOut[ivalue] = calROC->GetRMS(outlierROC);
615 ltmrmsValue = 0;
616 ltmWithOut[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction, outlierROC);
617 ltmrmsWithOut[ivalue] = ltmrmsValue;
618 }
619 }
620 else {
621 median[ivalue] = 0.;
622 mean[ivalue] = 0.;
623 rms[ivalue] = 0.;
624 ltm[ivalue] = 0.;
625 ltmrms[ivalue] = 0.;
626 medianWithOut[ivalue] = 0.;
627 meanWithOut[ivalue] = 0.;
628 rmsWithOut[ivalue] = 0.;
629 ltmWithOut[ivalue] = 0.;
630 ltmrmsWithOut[ivalue] = 0.;
631 }
632 }
633
634 //
635 // fill vectors of variable per pad
636 //
637 TVectorF *posArray = new TVectorF[8];
638 for (Int_t ivalue = 0; ivalue < 8; ivalue++)
639 posArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
640
641 Float_t posG[3] = {0};
642 Float_t posL[3] = {0};
643 Int_t ichannel = 0;
644 for (UInt_t irow = 0; irow < tpcROCinstance->GetNRows(isector); irow++) {
645 for (UInt_t ipad = 0; ipad < tpcROCinstance->GetNPads(isector, irow); ipad++) {
646 tpcROCinstance->GetPositionLocal(isector, irow, ipad, posL);
647 tpcROCinstance->GetPositionGlobal(isector, irow, ipad, posG);
648 posArray[0][ichannel] = irow;
649 posArray[1][ichannel] = ipad;
650 posArray[2][ichannel] = posL[0];
651 posArray[3][ichannel] = posL[1];
652 posArray[4][ichannel] = posG[0];
653 posArray[5][ichannel] = posG[1];
654 posArray[6][ichannel] = (Int_t)(ipad - (Double_t)(tpcROCinstance->GetNPads(isector, irow))/2);
655 posArray[7][ichannel] = ichannel;
656
657 // loop over array containing AliTPCCalPads
658 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
659 AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
660 AliTPCCalROC* calROC = calPad->GetCalROC(isector);
661 if (calROC)
662 (vectorArray[ivalue])[ichannel] = calROC->GetValue(irow, ipad);
663 else
664 (vectorArray[ivalue])[ichannel] = 0;
665 }
666 ichannel++;
667 }
668 }
669
670 cstream << "calPads" <<
671 "sector=" << isector;
672
673 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
674 cstream << "calPads" <<
675 (Char_t*)((names[ivalue] + "_Median=").Data()) << median[ivalue] <<
676 (Char_t*)((names[ivalue] + "_Mean=").Data()) << mean[ivalue] <<
677 (Char_t*)((names[ivalue] + "_RMS=").Data()) << rms[ivalue] <<
678 (Char_t*)((names[ivalue] + "_LTM=").Data()) << ltm[ivalue] <<
679 (Char_t*)((names[ivalue] + "_RMS_LTM=").Data()) << ltmrms[ivalue];
680 if (outlierPad) {
681 cstream << "calPads" <<
682 (Char_t*)((names[ivalue] + "_Median_OutlierCutted=").Data()) << medianWithOut[ivalue] <<
683 (Char_t*)((names[ivalue] + "_Mean_OutlierCutted=").Data()) << meanWithOut[ivalue] <<
684 (Char_t*)((names[ivalue] + "_RMS_OutlierCutted=").Data()) << rmsWithOut[ivalue] <<
685 (Char_t*)((names[ivalue] + "_LTM_OutlierCutted=").Data()) << ltmWithOut[ivalue] <<
686 (Char_t*)((names[ivalue] + "_RMS_LTM_OutlierCutted=").Data()) << ltmrmsWithOut[ivalue];
687 }
688 }
689
690 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
691 cstream << "calPads" <<
692 (Char_t*)((names[ivalue] + ".=").Data()) << &vectorArray[ivalue];
693 }
694
695 if (mapFileName) {
696 for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
697 if (isector < 36)
698 cstream << "calPads" <<
699 (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapIROCArray[ivalue];
700 else
701 cstream << "calPads" <<
702 (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapOROCArray[ivalue];
703 }
704 }
705
706 cstream << "calPads" <<
707 "row.=" << &posArray[0] <<
708 "pad.=" << &posArray[1] <<
709 "lx.=" << &posArray[2] <<
710 "ly.=" << &posArray[3] <<
711 "gx.=" << &posArray[4] <<
712 "gy.=" << &posArray[5] <<
713 "rpad.=" << &posArray[6] <<
714 "channel.=" << &posArray[7];
715
716 cstream << "calPads" <<
717 "\n";
718
719 delete[] posArray;
720 delete[] vectorArray;
721 }
722
723
724 delete[] names;
725 if (mapFileName) {
726 delete mapIROCs;
727 delete mapOROCs;
728 delete[] mapIROCArray;
729 delete[] mapOROCArray;
730 delete[] mapNames;
731 }
732}
3ac615eb 733
734
735
736void AliTPCcalibDB::RegisterExB(Int_t index, Float_t bz, Bool_t bdelete){
737 //
738 // Register static ExB correction map
739 // index - registration index - used for visualization
740 // bz - bz field in kGaus
741
0a997b33 742 // Float_t factor = bz/(-5.); // default b filed in Cheb with minus sign
743 Float_t factor = bz/(5.); // default b filed in Cheb with minus sign
744 // was chenged in the Revision ???? (Ruben can you add here number)
3ac615eb 745
4642ac4b 746 AliMagF* bmap = new AliMagF("MapsExB","MapsExB", factor,TMath::Sign(1.f,factor),AliMagF::k5kG);
3ac615eb 747
748 AliTPCExBFirst *exb = new AliTPCExBFirst(bmap,0.88*2.6400e+04,50,50,50);
749 AliTPCExB::SetInstance(exb);
750
751 if (bdelete){
752 delete bmap;
753 }else{
754 AliTPCExB::RegisterField(index,bmap);
755 }
756 if (index>=fgExBArray.GetEntries()) fgExBArray.Expand((index+1)*2+11);
757 fgExBArray.AddAt(exb,index);
758}
759
760
761AliTPCExB* AliTPCcalibDB::GetExB(Float_t bz, Bool_t deleteB) {
762 //
763 // bz filed in KGaus not in tesla
764 // Get ExB correction map
765 // if doesn't exist - create it
766 //
767 Int_t index = TMath::Nint(5+bz);
768 if (index>fgExBArray.GetEntries()) fgExBArray.Expand((index+1)*2+11);
769 if (!fgExBArray.At(index)) AliTPCcalibDB::RegisterExB(index,bz,deleteB);
770 return (AliTPCExB*)fgExBArray.At(index);
771}
772
773
774void AliTPCcalibDB::SetExBField(Float_t bz){
775 //
776 // Set magnetic filed for ExB correction
777 //
778 fExB = GetExB(bz,kFALSE);
779}
bf85fe4d 780
0a997b33 781void AliTPCcalibDB::SetExBField(const AliMagF* bmap){
782 //
783 // Set magnetic field for ExB correction
784 //
785 AliTPCExBFirst *exb = new AliTPCExBFirst(bmap,0.88*2.6400e+04,50,50,50);
786 AliTPCExB::SetInstance(exb);
787 fExB=exb;
788}
789
bf85fe4d 790
791
5e1215d4 792
793
794void AliTPCcalibDB::UpdateRunInformations( Int_t run, Bool_t force){
bf85fe4d 795 //
796 // - > Don't use it for reconstruction - Only for Calibration studies
797 //
1e722a63 798 if (run<0) return;
799 if (fRunList[run]>0 &&force==kFALSE) return;
bf85fe4d 800 AliCDBEntry * entry = 0;
801 if (run>= fRunList.GetSize()){
802 fRunList.Set(run*2+1);
da6c0bc9 803 fGRPArray.Expand(run*2+1);
0231c65f 804 fGRPMaps.Expand(run*2+1);
e2914767 805 fGoofieArray.Expand(run*2+1);
806 fVoltageArray.Expand(run*2+1);
da6c0bc9 807 fTemperatureArray.Expand(run*2+1);
808 fVdriftArray.Expand(run*2+1);
5e1215d4 809 fDriftCorrectionArray.Expand(run*2+1);
a2c3785e 810 fTimeGainSplinesArray.Expand(run*2+1);
bf85fe4d 811 }
1e722a63 812
813 fRunList[run]=1; // sign as used
814
5e1215d4 815 //
bf85fe4d 816 entry = AliCDBManager::Instance()->Get("GRP/GRP/Data",run);
0231c65f 817 if (entry) {
818 AliGRPObject * grpRun = dynamic_cast<AliGRPObject*>(entry->GetObject());
819 if (!grpRun){
820 TMap* map = dynamic_cast<TMap*>(entry->GetObject());
821 if (map){
e2914767 822 //grpRun = new AliGRPObject;
823 //grpRun->ReadValuesFromMap(map);
824 grpRun = MakeGRPObjectFromMap(map);
825
0231c65f 826 fGRPMaps.AddAt(map,run);
827 }
828 }
829 fGRPArray.AddAt(grpRun,run);
830 }
bf85fe4d 831 entry = AliCDBManager::Instance()->Get("TPC/Calib/Goofie",run);
5e1215d4 832 if (entry){
833 fGoofieArray.AddAt(entry->GetObject(),run);
834 }
e2914767 835 //
836 entry = AliCDBManager::Instance()->Get("TPC/Calib/HighVoltage",run);
5e1215d4 837 if (entry) {
838 fVoltageArray.AddAt(entry->GetObject(),run);
839 }
e2914767 840 //
a2c3785e 841 entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeGain",run);
5e1215d4 842 if (entry) {
843 fTimeGainSplinesArray.AddAt(entry->GetObject(),run);
844 }
845 //
846 entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeDrift",run);
847 if (entry) {
848 fDriftCorrectionArray.AddAt(entry->GetObject(),run);
849 }
a2c3785e 850 //
bf85fe4d 851 entry = AliCDBManager::Instance()->Get("TPC/Calib/Temperature",run);
5e1215d4 852 if (entry) {
853 fTemperatureArray.AddAt(entry->GetObject(),run);
854 }
1e722a63 855 //apply fDButil filters
856
857 fDButil->UpdateFromCalibDB();
858 if (fTemperature) fDButil->FilterTemperature(fTemperature);
da6c0bc9 859
bfec3eeb 860 AliDCSSensor * press = GetPressureSensor(run,0);
da6c0bc9 861 AliTPCSensorTempArray * temp = GetTemperatureSensor(run);
1e722a63 862 Bool_t accept=kTRUE;
863 if (temp) {
864 accept = fDButil->FilterTemperature(temp)>0.1;
865 }
866 if (press) {
867 const Double_t kMinP=950.;
868 const Double_t kMaxP=1050.;
869 const Double_t kMaxdP=10.;
870 const Double_t kSigmaCut=4.;
871 fDButil->FilterSensor(press,kMinP,kMaxP,kMaxdP,kSigmaCut);
872 if (press->GetFit()==0) accept=kFALSE;
873 }
874 if (press && temp &&accept){
da6c0bc9 875 AliTPCCalibVdrift * vdrift = new AliTPCCalibVdrift(temp, press,0);
876 fVdriftArray.AddAt(vdrift,run);
877 }
1e722a63 878 fDButil->FilterCE(120., 3., 4.,0);
879 fDButil->FilterTracks(run, 10.,0);
bf85fe4d 880}
881
882
883Float_t AliTPCcalibDB::GetGain(Int_t sector, Int_t row, Int_t pad){
884 //
885 //
886 AliTPCCalPad *calPad = Instance()->fDedxGainFactor;;
887 if (!calPad) return 0;
888 return calPad->GetCalROC(sector)->GetValue(row,pad);
889}
890
7390f655 891AliSplineFit* AliTPCcalibDB::GetVdriftSplineFit(const char* name, Int_t run){
892 //
893 //
894 //
895 TObjArray *arr=GetTimeVdriftSplineRun(run);
896 if (!arr) return 0;
897 return dynamic_cast<AliSplineFit*>(arr->FindObject(name));
898}
899
2cb269df 900AliSplineFit* AliTPCcalibDB::CreateVdriftSplineFit(const char* graphName, Int_t run){
901 //
902 // create spline fit from the drift time graph in TimeDrift
903 //
904 TObjArray *arr=GetTimeVdriftSplineRun(run);
905 if (!arr) return 0;
906 TGraph *graph=dynamic_cast<TGraph*>(arr->FindObject(graphName));
907 if (!graph) return 0;
908 AliSplineFit *fit = new AliSplineFit();
909 fit->SetGraph(graph);
910 fit->SetMinPoints(graph->GetN()+1);
911 fit->InitKnots(graph,2,0,0.001);
912 fit->SplineFit(0);
913 return fit;
914}
8de77f00 915
916AliGRPObject *AliTPCcalibDB::GetGRP(Int_t run){
917 //
918 // Get GRP object for given run
919 //
920 AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>((Instance()->fGRPArray).At(run));
921 if (!grpRun) {
5e1215d4 922 Instance()->UpdateRunInformations(run);
8de77f00 923 grpRun = dynamic_cast<AliGRPObject *>(Instance()->fGRPArray.At(run));
924 if (!grpRun) return 0;
925 }
926 return grpRun;
927}
928
0231c65f 929TMap * AliTPCcalibDB::GetGRPMap(Int_t run){
930 //
931 //
932 //
933 TMap * grpRun = dynamic_cast<TMap *>((Instance()->fGRPMaps).At(run));
934 if (!grpRun) {
5e1215d4 935 Instance()->UpdateRunInformations(run);
0231c65f 936 grpRun = dynamic_cast<TMap *>(Instance()->fGRPMaps.At(run));
937 if (!grpRun) return 0;
938 }
939 return grpRun;
940}
8de77f00 941
942
da6c0bc9 943AliDCSSensor * AliTPCcalibDB::GetPressureSensor(Int_t run, Int_t type){
bf85fe4d 944 //
0231c65f 945 // Get Pressure sensor
bfec3eeb 946 // run = run number
947 // type = 0 - Cavern pressure
948 // 1 - Suface pressure
0231c65f 949 // First try to get if trom map - if existing (Old format of data storing)
bf85fe4d 950 //
bfec3eeb 951
952
0231c65f 953 TMap *map = GetGRPMap(run);
954 if (map){
955 AliDCSSensor * sensor = 0;
956 TObject *osensor=0;
957 if (type==0) osensor = ((*map)("fCavernPressure"));
958 if (type==1) osensor = ((*map)("fP2Pressure"));
959 sensor =dynamic_cast<AliDCSSensor *>(osensor);
960 if (sensor) return sensor;
961 }
962 //
963 // If not map try to get it from the GRPObject
964 //
965 AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.At(run));
bf85fe4d 966 if (!grpRun) {
5e1215d4 967 UpdateRunInformations(run);
efdbb95a 968 grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.At(run));
bf85fe4d 969 if (!grpRun) return 0;
970 }
971 AliDCSSensor * sensor = grpRun->GetCavernAtmosPressure();
da6c0bc9 972 if (type==1) sensor = grpRun->GetSurfaceAtmosPressure();
973 return sensor;
bf85fe4d 974}
975
976AliTPCSensorTempArray * AliTPCcalibDB::GetTemperatureSensor(Int_t run){
977 //
978 // Get temperature sensor array
979 //
980 AliTPCSensorTempArray * tempArray = (AliTPCSensorTempArray *)fTemperatureArray.At(run);
981 if (!tempArray) {
5e1215d4 982 UpdateRunInformations(run);
bf85fe4d 983 tempArray = (AliTPCSensorTempArray *)fTemperatureArray.At(run);
984 }
985 return tempArray;
986}
987
a2c3785e 988
989TObjArray * AliTPCcalibDB::GetTimeGainSplinesRun(Int_t run){
bf85fe4d 990 //
991 // Get temperature sensor array
992 //
a2c3785e 993 TObjArray * gainSplines = (TObjArray *)fTimeGainSplinesArray.At(run);
994 if (!gainSplines) {
5e1215d4 995 UpdateRunInformations(run);
a2c3785e 996 gainSplines = (TObjArray *)fTimeGainSplinesArray.At(run);
bf85fe4d 997 }
a2c3785e 998 return gainSplines;
bf85fe4d 999}
1000
7390f655 1001TObjArray * AliTPCcalibDB::GetTimeVdriftSplineRun(Int_t run){
1002 //
1003 // Get drift spline array
1004 //
1005 TObjArray * driftSplines = (TObjArray *)fDriftCorrectionArray.At(run);
1006 if (!driftSplines) {
1007 UpdateRunInformations(run);
1008 driftSplines = (TObjArray *)fDriftCorrectionArray.At(run);
1009 }
1010 return driftSplines;
1011}
1012
e2914767 1013AliDCSSensorArray * AliTPCcalibDB::GetVoltageSensors(Int_t run){
1014 //
1015 // Get temperature sensor array
1016 //
1017 AliDCSSensorArray * voltageArray = (AliDCSSensorArray *)fVoltageArray.At(run);
1018 if (!voltageArray) {
5e1215d4 1019 UpdateRunInformations(run);
e2914767 1020 voltageArray = (AliDCSSensorArray *)fVoltageArray.At(run);
1021 }
1022 return voltageArray;
1023}
1024
99895a4f 1025AliDCSSensorArray * AliTPCcalibDB::GetGoofieSensors(Int_t run){
1026 //
1027 // Get temperature sensor array
1028 //
1029 AliDCSSensorArray * goofieArray = (AliDCSSensorArray *)fGoofieArray.At(run);
1030 if (!goofieArray) {
5e1215d4 1031 UpdateRunInformations(run);
99895a4f 1032 goofieArray = (AliDCSSensorArray *)fGoofieArray.At(run);
1033 }
1034 return goofieArray;
1035}
1036
1037
1038
da6c0bc9 1039AliTPCCalibVdrift * AliTPCcalibDB::GetVdrift(Int_t run){
1040 //
1041 // Get the interface to the the vdrift
1042 //
1043 AliTPCCalibVdrift * vdrift = (AliTPCCalibVdrift*)fVdriftArray.At(run);
1044 if (!vdrift) {
5e1215d4 1045 UpdateRunInformations(run);
da6c0bc9 1046 vdrift= (AliTPCCalibVdrift*)fVdriftArray.At(run);
1047 }
1048 return vdrift;
1049}
1050
892226be 1051Float_t AliTPCcalibDB::GetCEdriftTime(Int_t run, Int_t sector, Double_t timeStamp, Int_t *entries)
1052{
1053 //
1054 // GetCE drift time information for 'sector'
1055 // sector 72 is the mean drift time of the A-Side
1056 // sector 73 is the mean drift time of the C-Side
1057 // it timestamp==-1 return mean value
1058 //
1059 AliTPCcalibDB::Instance()->SetRun(run);
1060 TGraph *gr=AliTPCcalibDB::Instance()->GetCErocTgraph(sector);
1061 if (!gr||sector<0||sector>73) {
1062 if (entries) *entries=0;
1063 return 0.;
1064 }
1065 Float_t val=0.;
1066 if (timeStamp==-1.){
1067 val=gr->GetMean(2);
1068 }else{
1069 for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1070 Double_t x,y;
1071 gr->GetPoint(ipoint,x,y);
1072 if (x<timeStamp) continue;
1073 val=y;
1074 break;
1075 }
1076 }
1077 return val;
1078}
1079
1080Float_t AliTPCcalibDB::GetCEchargeTime(Int_t run, Int_t sector, Double_t timeStamp, Int_t *entries)
1081{
1082 //
1083 // GetCE mean charge for 'sector'
1084 // it timestamp==-1 return mean value
1085 //
1086 AliTPCcalibDB::Instance()->SetRun(run);
1087 TGraph *gr=AliTPCcalibDB::Instance()->GetCErocQgraph(sector);
1088 if (!gr||sector<0||sector>71) {
1089 if (entries) *entries=0;
1090 return 0.;
1091 }
1092 Float_t val=0.;
1093 if (timeStamp==-1.){
1094 val=gr->GetMean(2);
1095 }else{
1096 for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1097 Double_t x,y;
1098 gr->GetPoint(ipoint,x,y);
1099 if (x<timeStamp) continue;
1100 val=y;
1101 break;
1102 }
1103 }
1104 return val;
1105}
1106
7fff7612 1107Float_t AliTPCcalibDB::GetDCSSensorValue(AliDCSSensorArray *arr, Int_t timeStamp, const char * sensorName, Int_t sigDigits)
1108{
1109 //
1110 // Get Value for a DCS sensor 'sensorName', run 'run' at time 'timeStamp'
1111 //
1112 Float_t val=0;
1113 const TString sensorNameString(sensorName);
1114 AliDCSSensor *sensor = arr->GetSensor(sensorNameString);
1115 if (!sensor) return val;
892226be 1116 //use the dcs graph if possible
1117 TGraph *gr=sensor->GetGraph();
1118 if (gr){
1119 for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1120 Double_t x,y;
1121 gr->GetPoint(ipoint,x,y);
7390f655 1122 Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
892226be 1123 if (time<timeStamp) continue;
1124 val=y;
1125 break;
1126 }
1127 //if val is still 0, test if if the requested time if within 5min of the first/last
1128 //data point. If this is the case return the firs/last entry
1129 //the timestamps might not be syncronised for all calibration types, sometimes a 'pre'
1130 //and 'pos' period is requested. Especially to the HV this is not the case!
1131 //first point
1132 if (val==0 ){
1133 Double_t x,y;
1134 gr->GetPoint(0,x,y);
7390f655 1135 Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
892226be 1136 if ((time-timeStamp)<5*60) val=y;
1137 }
1138 //last point
1139 if (val==0 ){
1140 Double_t x,y;
1141 gr->GetPoint(gr->GetN()-1,x,y);
7390f655 1142 Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
892226be 1143 if ((timeStamp-time)<5*60) val=y;
1144 }
1145 } else {
1146 val=sensor->GetValue(timeStamp);
1147 }
7fff7612 1148 if (sigDigits>=0){
1149 val=(Float_t)TMath::Floor(val * TMath::Power(10., sigDigits) + .5) / TMath::Power(10., sigDigits);
1150 }
1151 return val;
1152}
1153
1154Float_t AliTPCcalibDB::GetDCSSensorMeanValue(AliDCSSensorArray *arr, const char * sensorName, Int_t sigDigits)
1155{
1156 //
1157 // Get mean Value for a DCS sensor 'sensorName' during run 'run'
1158 //
1159 Float_t val=0;
1160 const TString sensorNameString(sensorName);
1161 AliDCSSensor *sensor = arr->GetSensor(sensorNameString);
1162 if (!sensor) return val;
892226be 1163
1164 //use dcs graph if it exists
1165 TGraph *gr=sensor->GetGraph();
1166 if (gr){
1167 val=gr->GetMean(2);
1168 } else {
1169 //if we don't have the dcs graph, try to get some meaningful information
1170 if (!sensor->GetFit()) return val;
1171 Int_t nKnots=sensor->GetFit()->GetKnots();
1172 Double_t tMid=(sensor->GetEndTime()-sensor->GetStartTime())/2.;
1173 for (Int_t iKnot=0;iKnot<nKnots;++iKnot){
1174 if (sensor->GetFit()->GetX()[iKnot]>tMid/3600.) break;
1175 val=(Float_t)sensor->GetFit()->GetY0()[iKnot];
1176 }
7fff7612 1177 }
7fff7612 1178 if (sigDigits>=0){
1179 val/=10;
1180 val=(Float_t)TMath::Floor(val * TMath::Power(10., sigDigits) + .5) / TMath::Power(10., sigDigits);
1181 val*=10;
1182 }
1183 return val;
1184}
bf85fe4d 1185
7fff7612 1186Float_t AliTPCcalibDB::GetChamberHighVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits) {
e2914767 1187 //
1188 // return the chamber HV for given run and time: 0-35 IROC, 36-72 OROC
7fff7612 1189 // if timeStamp==-1 return mean value
1190 //
1191 Float_t val=0;
1192 TString sensorName="";
1193 TTimeStamp stamp(timeStamp);
1194 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1195 if (!voltageArray || (sector<0) || (sector>71)) return val;
1196 Char_t sideName='A';
1197 if ((sector/18)%2==1) sideName='C';
1198 if (sector<36){
1199 //IROC
1200 sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
1201 }else{
1202 //OROC
1203 sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
1204 }
1205 if (timeStamp==-1){
1206 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1207 } else {
1208 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1209 }
1210 return val;
1211}
1212Float_t AliTPCcalibDB::GetSkirtVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1213{
1214 //
1215 // Get the skirt voltage for 'run' at 'timeStamp' and 'sector': 0-35 IROC, 36-72 OROC
1216 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1217 // if timeStamp==-1 return the mean value for the run
1218 //
1219 Float_t val=0;
1220 TString sensorName="";
1221 TTimeStamp stamp(timeStamp);
1222 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1223 if (!voltageArray || (sector<0) || (sector>71)) return val;
1224 Char_t sideName='A';
1225 if ((sector/18)%2==1) sideName='C';
1226 sensorName=Form("TPC_SKIRT_%c_VMEAS",sideName);
1227 if (timeStamp==-1){
1228 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1229 } else {
1230 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1231 }
1232 return val;
1233}
1234
1235Float_t AliTPCcalibDB::GetCoverVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1236{
1237 //
1238 // Get the cover voltage for run 'run' at time 'timeStamp'
1239 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1240 // if timeStamp==-1 return the mean value for the run
e2914767 1241 //
7fff7612 1242 Float_t val=0;
1243 TString sensorName="";
e2914767 1244 TTimeStamp stamp(timeStamp);
1245 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
7fff7612 1246 if (!voltageArray || (sector<0) || (sector>71)) return val;
1247 Char_t sideName='A';
1248 if ((sector/18)%2==1) sideName='C';
1249 if (sector<36){
1250 //IROC
1251 sensorName=Form("TPC_COVER_I_%c_VMEAS",sideName);
1252 }else{
1253 //OROC
1254 sensorName=Form("TPC_COVER_O_%c_VMEAS",sideName);
1255 }
1256 if (timeStamp==-1){
1257 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1258 } else {
1259 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1260 }
1261 return val;
1262}
1263
1264Float_t AliTPCcalibDB::GetGGoffsetVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1265{
1266 //
1267 // Get the GG offset voltage for run 'run' at time 'timeStamp'
1268 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1269 // if timeStamp==-1 return the mean value for the run
1270 //
1271 Float_t val=0;
1272 TString sensorName="";
1273 TTimeStamp stamp(timeStamp);
1274 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1275 if (!voltageArray || (sector<0) || (sector>71)) return val;
1276 Char_t sideName='A';
1277 if ((sector/18)%2==1) sideName='C';
1278 if (sector<36){
1279 //IROC
1280 sensorName=Form("TPC_GATE_I_%c_OFF_VMEAS",sideName);
1281 }else{
1282 //OROC
1283 sensorName=Form("TPC_GATE_O_%c_OFF_VMEAS",sideName);
1284 }
1285 if (timeStamp==-1){
1286 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1287 } else {
1288 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1289 }
1290 return val;
1291}
1292
1293Float_t AliTPCcalibDB::GetGGnegVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1294{
1295 //
1296 // Get the GG offset voltage for run 'run' at time 'timeStamp'
1297 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1298 // if timeStamp==-1 return the mean value for the run
1299 //
1300 Float_t val=0;
1301 TString sensorName="";
1302 TTimeStamp stamp(timeStamp);
1303 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1304 if (!voltageArray || (sector<0) || (sector>71)) return val;
1305 Char_t sideName='A';
1306 if ((sector/18)%2==1) sideName='C';
1307 if (sector<36){
1308 //IROC
1309 sensorName=Form("TPC_GATE_I_%c_NEG_VMEAS",sideName);
1310 }else{
1311 //OROC
1312 sensorName=Form("TPC_GATE_O_%c_NEG_VMEAS",sideName);
1313 }
1314 if (timeStamp==-1){
1315 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1316 } else {
1317 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1318 }
1319 return val;
1320}
1321
1322Float_t AliTPCcalibDB::GetGGposVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1323{
1324 //
1325 // Get the GG offset voltage for run 'run' at time 'timeStamp'
1326 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1327 // if timeStamp==-1 return the mean value for the run
1328 //
1329 Float_t val=0;
1330 TString sensorName="";
1331 TTimeStamp stamp(timeStamp);
1332 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1333 if (!voltageArray || (sector<0) || (sector>71)) return val;
1334 Char_t sideName='A';
1335 if ((sector/18)%2==1) sideName='C';
1336 if (sector<36){
1337 //IROC
1338 sensorName=Form("TPC_GATE_I_%c_POS_VMEAS",sideName);
1339 }else{
1340 //OROC
1341 sensorName=Form("TPC_GATE_O_%c_POS_VMEAS",sideName);
1342 }
1343 if (timeStamp==-1){
1344 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1345 } else {
1346 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1347 }
1348 return val;
e2914767 1349}
bf85fe4d 1350
da6c0bc9 1351Float_t AliTPCcalibDB::GetPressure(Int_t timeStamp, Int_t run, Int_t type){
bf85fe4d 1352 //
1353 // GetPressure for given time stamp and runt
1354 //
1355 TTimeStamp stamp(timeStamp);
da6c0bc9 1356 AliDCSSensor * sensor = Instance()->GetPressureSensor(run,type);
bf85fe4d 1357 if (!sensor) return 0;
bf85fe4d 1358 return sensor->GetValue(stamp);
1359}
1360
5312f439 1361Float_t AliTPCcalibDB::GetL3Current(Int_t run, Int_t statType){
1362 //
1363 // return L3 current
1364 // stat type is: AliGRPObject::Stats: kMean = 0, kTruncMean = 1, kMedian = 2, kSDMean = 3, kSDMedian = 4
1365 //
1366 Float_t current=-1;
1367 AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
1368 if (grp) current=grp->GetL3Current((AliGRPObject::Stats)statType);
1369 return current;
1370}
1371
1372Float_t AliTPCcalibDB::GetBz(Int_t run){
1373 //
e6970ab5 1374 // calculate BZ in T from L3 current
5312f439 1375 //
1376 Float_t bz=-1;
1377 Float_t current=AliTPCcalibDB::GetL3Current(run);
e6970ab5 1378 if (current>-1) bz=5*current/30000.*.1;
5312f439 1379 return bz;
1380}
1381
1382Char_t AliTPCcalibDB::GetL3Polarity(Int_t run) {
1383 //
1384 // get l3 polarity from GRP
1385 //
7390f655 1386 Char_t pol=-100;
1387 AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
1388 if (grp) pol=grp->GetL3Polarity();
1389 return pol;
5312f439 1390}
1391
1392TString AliTPCcalibDB::GetRunType(Int_t run){
1393 //
1394 // return run type from grp
1395 //
7390f655 1396
1397// TString type("UNKNOWN");
1398 AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
1399 if (grp) return grp->GetRunType();
1400 return "UNKNOWN";
5312f439 1401}
1402
7f7847fe 1403Float_t AliTPCcalibDB::GetValueGoofie(Int_t timeStamp, Int_t run, Int_t type){
1404 //
1405 // GetPressure for given time stamp and runt
1406 //
1407 TTimeStamp stamp(timeStamp);
1408 AliDCSSensorArray* goofieArray = AliTPCcalibDB::Instance()->GetGoofieSensors(run);
1409 if (!goofieArray) return 0;
1410 AliDCSSensor *sensor = goofieArray->GetSensor(type);
1411 return sensor->GetValue(stamp);
1412}
1413
1414
1415
1416
1417
1418
f0269955 1419Bool_t AliTPCcalibDB::GetTemperatureFit(Int_t timeStamp, Int_t run, Int_t side,TVectorD& fit){
1420 //
1421 //
1422 //
1423 TTimeStamp tstamp(timeStamp);
64b48395 1424 AliTPCSensorTempArray* tempArray = Instance()->GetTemperatureSensor(run);
f0269955 1425 if (! tempArray) return kFALSE;
1426 AliTPCTempMap * tempMap = new AliTPCTempMap(tempArray);
1427 TLinearFitter * fitter = tempMap->GetLinearFitter(3,side,tstamp);
1428 if (fitter){
1429 fitter->Eval();
1430 fitter->GetParameters(fit);
1431 }
1432 delete fitter;
1433 delete tempMap;
1434 if (!fitter) return kFALSE;
1435 return kTRUE;
1436}
1437
64b48395 1438Float_t AliTPCcalibDB::GetTemperature(Int_t timeStamp, Int_t run, Int_t side){
1439 //
1440 //
1441 //
12e42756 1442 TVectorD vec(5);
64b48395 1443 if (side==0) {
1444 GetTemperatureFit(timeStamp,run,0,vec);
1445 return vec[0];
1446 }
1447 if (side==1){
1448 GetTemperatureFit(timeStamp,run,0,vec);
1449 return vec[0];
1450 }
57dc06f2 1451 return 0;
64b48395 1452}
bf85fe4d 1453
1454
da6c0bc9 1455Double_t AliTPCcalibDB::GetPTRelative(UInt_t timeSec, Int_t run, Int_t side){
1456 //
1457 // Get relative P/T
1458 // time - absolute time
1459 // run - run number
1460 // side - 0 - A side 1-C side
1461 AliTPCCalibVdrift * vdrift = Instance()->GetVdrift(run);
1462 if (!vdrift) return 0;
1463 return vdrift->GetPTRelative(timeSec,side);
1464}
1465
e2914767 1466AliGRPObject * AliTPCcalibDB::MakeGRPObjectFromMap(TMap *map){
1467 //
1468 // Function to covert old GRP run information from TMap to GRPObject
1469 //
1470 // TMap * map = AliTPCcalibDB::GetGRPMap(52406);
1471 if (!map) return 0;
1472 AliDCSSensor * sensor = 0;
1473 TObject *osensor=0;
1474 osensor = ((*map)("fP2Pressure"));
1475 sensor =dynamic_cast<AliDCSSensor *>(osensor);
1476 //
1477 if (!sensor) return 0;
1478 //
1479 AliDCSSensor * sensor2 = new AliDCSSensor(*sensor);
1480 osensor = ((*map)("fCavernPressure"));
1481 TGraph * gr = new TGraph(2);
1482 gr->GetX()[0]= -100000.;
1483 gr->GetX()[1]= 1000000.;
1484 gr->GetY()[0]= atof(osensor->GetName());
1485 gr->GetY()[1]= atof(osensor->GetName());
1486 sensor2->SetGraph(gr);
1487 sensor2->SetFit(0);
1488
1489
1490 AliGRPObject *grpRun = new AliGRPObject;
1491 grpRun->ReadValuesFromMap(map);
1492 grpRun->SetCavernAtmosPressure(sensor2);
1493 grpRun->SetSurfaceAtmosPressure(sensor);
1494 return grpRun;
1495}
1496
5312f439 1497Bool_t AliTPCcalibDB::CreateGUITree(Int_t run, const char* filename)
1498{
1499 //
1500 // Create a gui tree for run number 'run'
1501 //
e2914767 1502
5312f439 1503 if (!AliCDBManager::Instance()->GetDefaultStorage()){
1504 AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
1505 MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
1506 return kFALSE;
1507 }
1508 //db instance
1509 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
1510 // retrieve cal pad objects
1511 db->SetRun(run);
1512 AliTPCPreprocessorOnline prep;
1513 //noise and pedestals
1514 prep.AddComponent(db->GetPedestals());
1515 prep.AddComponent(db->GetPadNoise());
1516 //pulser data
1517 prep.AddComponent(db->GetPulserTmean());
1518 prep.AddComponent(db->GetPulserTrms());
1519 prep.AddComponent(db->GetPulserQmean());
1520 //CE data
1521 prep.AddComponent(db->GetCETmean());
1522 prep.AddComponent(db->GetCETrms());
1523 prep.AddComponent(db->GetCEQmean());
1524 //Altro data
1525 prep.AddComponent(db->GetALTROAcqStart() );
1526 prep.AddComponent(db->GetALTROZsThr() );
1527 prep.AddComponent(db->GetALTROFPED() );
1528 prep.AddComponent(db->GetALTROAcqStop() );
1529 prep.AddComponent(db->GetALTROMasked() );
1530 //
1531 TString file(filename);
1532 if (file.IsNull()) file=Form("guiTreeRun_%d.root",run);
1533 prep.DumpToFile(file.Data());
1534 return kTRUE;
1535}
e2914767 1536
7390f655 1537Bool_t AliTPCcalibDB::CreateRefFile(Int_t run, const char* filename)
1538{
1539 //
1540 // Create a gui tree for run number 'run'
1541 //
1542
1543 if (!AliCDBManager::Instance()->GetDefaultStorage()){
1544 AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
1545 MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
1546 return kFALSE;
1547 }
1548 TString file(filename);
1549 if (file.IsNull()) file=Form("RefCalPads_%d.root",run);
1550 TDirectory *currDir=gDirectory;
1551 //db instance
1552 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
1553 // retrieve cal pad objects
1554 db->SetRun(run);
1555 //open file
1556 TFile f(file.Data(),"recreate");
1557 //noise and pedestals
1558 db->GetPedestals()->Write("Pedestals");
1559 db->GetPadNoise()->Write("PadNoise");
1560 //pulser data
1561 db->GetPulserTmean()->Write("PulserTmean");
1562 db->GetPulserTrms()->Write("PulserTrms");
1563 db->GetPulserQmean()->Write("PulserQmean");
1564 //CE data
1565 db->GetCETmean()->Write("CETmean");
1566 db->GetCETrms()->Write("CETrms");
1567 db->GetCEQmean()->Write("CEQmean");
1568 //Altro data
1569 db->GetALTROAcqStart() ->Write("ALTROAcqStart");
1570 db->GetALTROZsThr() ->Write("ALTROZsThr");
1571 db->GetALTROFPED() ->Write("ALTROFPED");
1572 db->GetALTROAcqStop() ->Write("ALTROAcqStop");
1573 db->GetALTROMasked() ->Write("ALTROMasked");
1574 //
1575 f.Close();
1576 currDir->cd();
1577 return kTRUE;
1578}
17c90083 1579
1580
1581
817766d5 1582Double_t AliTPCcalibDB::GetVDriftCorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
17c90083 1583 //
1584 // Get time dependent drift velocity correction
1585 // multiplication factor vd = vdnom *(1+vdriftcorr)
1586 // Arguments:
1587 // mode determines the algorith how to combine the Laser Track, LaserCE and physics tracks
1588 // timestamp - timestamp
1589 // run - run number
1590 // side - the drift velocity per side (possible for laser and CE)
1591 //
1592 // Notice - Extrapolation outside of calibration range - using constant function
1593 //
817766d5 1594 Double_t result;
1e722a63 1595 // mode 1 automatic mode - according to the distance to the valid calibration
1596 // -
1597 Double_t deltaP=0, driftP=0, wP = 0.;
1598 Double_t deltaLT=0, driftLT=0, wLT = 0.;
1599 Double_t deltaCE=0, driftCE=0, wCE = 0.;
1600 driftP = fDButil->GetVDriftTPC(deltaP,run,timeStamp);
1601 driftCE = fDButil->GetVDriftTPCCE(deltaCE, run,timeStamp,36000,2);
1602 driftLT = fDButil->GetVDriftTPCLaserTracks(deltaLT,run,timeStamp,36000,2);
1603 deltaP = TMath::Abs(deltaP);
1604 deltaLT = TMath::Abs(deltaLT);
1605 deltaCE = TMath::Abs(deltaCE);
1606 if (mode==1) {
1607 const Double_t kEpsilon=0.0000000001;
1608 Double_t meanDist= (deltaP+deltaLT+deltaCE)*0.3;
1609 if (meanDist<1.) return driftLT;
1610 wP = meanDist/(deltaP +0.005*meanDist);
1611 wLT = meanDist/(deltaLT+0.005*meanDist);
1612 wCE = meanDist/(deltaCE+0.001*meanDist);
1613 if (TMath::Abs(driftCE)<kEpsilon) wCE=0; // invalid calibration
1614 result = (driftP*wP+driftLT*wLT+driftCE*wCE)/(wP+wLT+wCE);
43a74775 1615 }
817766d5 1616
43a74775 1617 return result;
17c90083 1618}
1619
817766d5 1620Double_t AliTPCcalibDB::GetTime0CorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
17c90083 1621 //
43a74775 1622 // Get time dependent time 0 (trigger delay in cm) correction
17c90083 1623 // additive correction time0 = time0+ GetTime0CorrectionTime
1624 // Value etracted combining the vdrift correction using laser tracks and CE and the physics track matchin
1625 // Arguments:
1626 // mode determines the algorith how to combine the Laser Track and physics tracks
1627 // timestamp - timestamp
1628 // run - run number
1629 // side - the drift velocity per side (possible for laser and CE)
1630 //
1631 // Notice - Extrapolation outside of calibration range - using constant function
1632 //
817766d5 1633 Double_t result=0;
1e722a63 1634 if (mode==1) result=fDButil->GetTriggerOffsetTPC(run,timeStamp);
817766d5 1635 result *=fParam->GetZLength();
1636
1637 return result;
43a74775 1638
17c90083 1639}
1640
1641
1642
1643
43a74775 1644Double_t AliTPCcalibDB::GetVDriftCorrectionGy(Int_t timeStamp, Int_t run, Int_t side, Int_t /*mode*/){
17c90083 1645 //
1646 // Get global y correction drift velocity correction factor
1647 // additive factor vd = vdnom*(1+GetVDriftCorrectionGy *gy)
1648 // Value etracted combining the vdrift correction using laser tracks and CE
1649 // Arguments:
1650 // mode determines the algorith how to combine the Laser Track, LaserCE
1651 // timestamp - timestamp
1652 // run - run number
1653 // side - the drift velocity gy correction per side (CE and Laser tracks)
1654 //
1655 // Notice - Extrapolation outside of calibration range - using constant function
a8f8b6a1 1656 //
1657 if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
1658 UpdateRunInformations(run,kFALSE);
43a74775 1659 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
4429bfef 1660 if (!array) return 0;
43a74775 1661 TGraphErrors *laserA= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_A");
1662 TGraphErrors *laserC= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_C");
1663
1664 Double_t result=0;
1665 if (laserA && laserC){
1666 result= (laserA->Eval(timeStamp)+laserC->Eval(timeStamp))*0.5;
1667 }
1668 if (laserA && side==0){
1669 result = (laserA->Eval(timeStamp));
1670 }
1671 if (laserC &&side==1){
1672 result = (laserC->Eval(timeStamp));
1673 }
1674 return -result/250.; //normalized before
17c90083 1675}