]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/Base/AliTPCcalibDB.cxx
ATO-78 - edge handling (mirroring out of range pads) set as an option
[u/mrichter/AliRoot.git] / TPC / Base / 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
829455ad 29// Reconstruction - AliTPCclusterer::Digits2Clusters(AliRawReader* rawReader)
8cd9634d 30//
1ac191a6 31// 1.) pad by pad calibration - AliTPCCalPad
f5344549 32//
1ac191a6 33// a.) fPadGainFactor
34// Simulation: AliTPCDigitizer::ExecFast - Multiply by gain
829455ad 35// Reconstruction : AliTPCclusterer::Digits2Clusters - Divide by gain
f5344549 36//
1ac191a6 37// b.) fPadNoise -
38// Simulation: AliTPCDigitizer::ExecFast
829455ad 39// Reconstruction: AliTPCclusterer::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
829455ad 43// Reconstruction: Used in AliTPCclusterer::Digits2Clusters(AliRawReader* rawReader)
f5344549 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
829455ad 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 -
829455ad 63// AliTPCclusterer::AddCluster
64// AliTPCtracker::Transform
8cd9634d 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>
949d8707 85#include <AliCDBId.h>
c5bbaa2c 86#include <AliLog.h>
3ac615eb 87#include <AliMagF.h>
7fff7612 88#include <AliSplineFit.h>
f14d21a1 89#include <AliCTPTimeParams.h>
c5bbaa2c 90
9a836cc2 91#include "TGraphErrors.h"
c5bbaa2c 92#include "AliTPCcalibDB.h"
949d8707 93#include "AliTPCdataQA.h"
817766d5 94#include "AliTPCcalibDButil.h"
d6834f5f 95#include "AliTPCAltroMapping.h"
418bbcaf 96#include "AliTPCExB.h"
c5bbaa2c 97
98#include "AliTPCCalROC.h"
99#include "AliTPCCalPad.h"
54472e4f 100#include "AliTPCSensorTempArray.h"
bf85fe4d 101#include "AliGRPObject.h"
418bbcaf 102#include "AliTPCTransform.h"
f6b5fa33 103#include "AliTPCmapper.h"
d6834f5f 104
418bbcaf 105class AliCDBStorage;
106class AliTPCCalDet;
86df2b3a 107//
108//
109
86df2b3a 110#include "TFile.h"
111#include "TKey.h"
43a74775 112#include "TGraphErrors.h"
86df2b3a 113
114#include "TObjArray.h"
115#include "TObjString.h"
116#include "TString.h"
7390f655 117#include "TDirectory.h"
f6b5fa33 118#include "TArrayI.h"
86df2b3a 119#include "AliTPCCalPad.h"
0fe7645c 120#include "AliTPCCalibPulser.h"
86df2b3a 121#include "AliTPCCalibPedestal.h"
122#include "AliTPCCalibCE.h"
3ac615eb 123#include "AliTPCExBFirst.h"
bf85fe4d 124#include "AliTPCTempMap.h"
da6c0bc9 125#include "AliTPCCalibVdrift.h"
6e7d7dc4 126#include "AliTPCCalibRaw.h"
43a74775 127#include "AliTPCParam.h"
cf5b0aa0 128#include "AliTPCCorrection.h"
3f3549a3 129#include "AliTPCComposedCorrection.h"
5312f439 130#include "AliTPCPreprocessorOnline.h"
661f340b 131#include "AliTimeStamp.h"
132#include "AliTriggerRunScalers.h"
133#include "AliTriggerScalers.h"
134#include "AliTriggerScalersRecord.h"
c5bbaa2c 135
136ClassImp(AliTPCcalibDB)
137
138AliTPCcalibDB* AliTPCcalibDB::fgInstance = 0;
139Bool_t AliTPCcalibDB::fgTerminated = kFALSE;
3ac615eb 140TObjArray AliTPCcalibDB::fgExBArray; // array of ExB corrections
c5bbaa2c 141
142
143//_ singleton implementation __________________________________________________
144AliTPCcalibDB* AliTPCcalibDB::Instance()
145{
146 //
147 // Singleton implementation
8de4c8a6 148 // Returns an instance of this class, it is created if necessary
c5bbaa2c 149 //
150
151 if (fgTerminated != kFALSE)
152 return 0;
153
154 if (fgInstance == 0)
155 fgInstance = new AliTPCcalibDB();
156
157 return fgInstance;
158}
159
160void 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//_____________________________________________________________________________
e4dce695 178AliTPCcalibDB::AliTPCcalibDB():
9389f9a4 179 TObject(),
e4dce695 180 fRun(-1),
f5344549 181 fTransform(0),
481f877b 182 fExB(0),
e4dce695 183 fPadGainFactor(0),
8de4c8a6 184 fActiveChannelMap(0),
9f6e9f81 185 fDedxGainFactor(0),
e4dce695 186 fPadTime0(0),
2293155b 187 fDistortionMap(0),
cf5b0aa0 188 fComposedCorrection(0),
0b736a46 189 fComposedCorrectionArray(0),
e4dce695 190 fPadNoise(0),
191 fPedestals(0),
6e7d7dc4 192 fCalibRaw(0),
949d8707 193 fDataQA(0),
5312f439 194 fALTROConfigData(0),
4bef51b7 195 fIonTailArray(0),
5312f439 196 fPulserData(0),
197 fCEData(0),
661f340b 198 fHVsensors(),
199 fGrRunState(0x0),
e4dce695 200 fTemperature(0),
d6834f5f 201 fMapping(0),
96305e49 202 fParam(0),
a2c3785e 203 fClusterParam(0),
0736ecae 204 fRecoParamList(0),
a2c3785e 205 fTimeGainSplines(0),
6b5e0bab 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
3f3549a3 215 fBHasAlignmentOCDB(kFALSE), // Flag - has the alignment on the composed correction ?
f14d21a1 216 fDButil(0),
88a69e6f 217 fCTPTimeParams(0),
218 fMode(-1)
c5bbaa2c 219{
220 //
221 // constructor
222 //
54472e4f 223 //
534fd34a 224 fgInstance=this;
661f340b 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 }
c5bbaa2c 231 Update(); // temporary
2b4c6ff5 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
c5bbaa2c 240}
241
9389f9a4 242AliTPCcalibDB::AliTPCcalibDB(const AliTPCcalibDB& ):
243 TObject(),
244 fRun(-1),
245 fTransform(0),
246 fExB(0),
247 fPadGainFactor(0),
8de4c8a6 248 fActiveChannelMap(0),
9f6e9f81 249 fDedxGainFactor(0),
9389f9a4 250 fPadTime0(0),
2293155b 251 fDistortionMap(0),
cf5b0aa0 252 fComposedCorrection(0),
0b736a46 253 fComposedCorrectionArray(0),
9389f9a4 254 fPadNoise(0),
255 fPedestals(0),
6e7d7dc4 256 fCalibRaw(0),
949d8707 257 fDataQA(0),
5312f439 258 fALTROConfigData(0),
4bef51b7 259 fIonTailArray(0),
5312f439 260 fPulserData(0),
261 fCEData(0),
661f340b 262 fHVsensors(),
263 fGrRunState(0x0),
9389f9a4 264 fTemperature(0),
265 fMapping(0),
9389f9a4 266 fParam(0),
bf85fe4d 267 fClusterParam(0),
0736ecae 268 fRecoParamList(0),
a2c3785e 269 fTimeGainSplines(0),
6b5e0bab 270 fTimeGainSplinesArray(1),
bf85fe4d 271 fGRPArray(0), //! array of GRPs - per run - JUST for calibration studies
0231c65f 272 fGRPMaps(0), //! array of GRPs - per run - JUST for calibration studies
bf85fe4d 273 fGoofieArray(0), //! array of GOOFIE values -per run - Just for calibration studies
e2914767 274 fVoltageArray(0),
bf85fe4d 275 fTemperatureArray(0), //! array of temperature sensors - per run - Just for calibration studies
da6c0bc9 276 fVdriftArray(0), //! array of v drift interfaces
5647625c 277 fDriftCorrectionArray(0), //! array of v drift corrections
1e722a63 278 fRunList(0), //! run list - indicates try to get the run param
3f3549a3 279 fBHasAlignmentOCDB(kFALSE), // Flag - has the alignment on the composed correction ?
f14d21a1 280 fDButil(0),
88a69e6f 281 fCTPTimeParams(0),
282 fMode(-1)
9389f9a4 283{
284 //
285 // Copy constructor invalid -- singleton implementation
286 //
661f340b 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 }
2b4c6ff5 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
9389f9a4 302}
303
304AliTPCcalibDB& 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
c5bbaa2c 315//_____________________________________________________________________________
316AliTPCcalibDB::~AliTPCcalibDB()
317{
318 //
319 // destructor
320 //
a0f26671 321 //delete fIonTailArray;
8de4c8a6 322 delete fActiveChannelMap;
661f340b 323 delete fGrRunState;
b1e5634c 324 fgInstance = 0;
c5bbaa2c 325}
b1e5634c 326
8b63d99c 327AliTPCCalPad* AliTPCcalibDB::GetDistortionMap(Int_t i) const {
328 //
329 // get distortion map - due E field distortions
330 //
331 return (fDistortionMap) ? (AliTPCCalPad*)fDistortionMap->At(i):0;
332}
c5bbaa2c 333
0736ecae 334AliTPCRecoParam* AliTPCcalibDB::GetRecoParam(Int_t i) const {
335 return (fRecoParamList) ? (AliTPCRecoParam*)fRecoParamList->At(i):0;
336}
337
c5bbaa2c 338//_____________________________________________________________________________
339AliCDBEntry* AliTPCcalibDB::GetCDBEntry(const char* cdbPath)
340{
341 //
342 // Retrieves an entry with path <cdbPath> from the CDB.
343 //
344 char chinfo[1000];
345
68751c2c 346 AliCDBEntry* entry = AliCDBManager::Instance()->Get(cdbPath, fRun);
c5bbaa2c 347 if (!entry)
348 {
4aa37f93 349 snprintf(chinfo,1000,"AliTPCcalibDB: Failed to get entry:\t%s ", cdbPath);
c5bbaa2c 350 AliError(chinfo);
351 return 0;
352 }
353 return entry;
354}
355
356
357//_____________________________________________________________________________
358void AliTPCcalibDB::SetRun(Long64_t run)
359{
360 //
361 // Sets current run number. Calibration data is read from the corresponding file.
362 //
363 if (fRun == run)
364 return;
a2c3785e 365 fRun = run;
c5bbaa2c 366 Update();
367}
368
369
370
371void AliTPCcalibDB::Update(){
92fb7d95 372 //
373 // cache the OCDB entries for simulation, reconstruction, calibration
374 //
375 //
a8f8b6a1 376 AliCDBEntry * entry=0;
68751c2c 377 Bool_t cdbCache = AliCDBManager::Instance()->GetCacheFlag(); // save cache status
378 AliCDBManager::Instance()->SetCacheFlag(kTRUE); // activate CDB cache
1e722a63 379 fDButil = new AliTPCcalibDButil;
c5bbaa2c 380 //
8e6dc09b 381 fRun = AliCDBManager::Instance()->GetRun();
5647625c 382
c5bbaa2c 383 entry = GetCDBEntry("TPC/Calib/PadGainFactor");
384 if (entry){
68751c2c 385 //if (fPadGainFactor) delete fPadGainFactor;
c5bbaa2c 386 entry->SetOwner(kTRUE);
387 fPadGainFactor = (AliTPCCalPad*)entry->GetObject();
2293155b 388 }else{
13242232 389 AliFatal("TPC - Missing calibration entry TPC/Calib/PadGainFactor");
c5bbaa2c 390 }
391 //
3af3fbc4 392 entry = GetCDBEntry("TPC/Calib/TimeGain");
393 if (entry){
394 //if (fTimeGainSplines) delete fTimeGainSplines;
395 entry->SetOwner(kTRUE);
396 fTimeGainSplines = (TObjArray*)entry->GetObject();
2293155b 397 }else{
13242232 398 AliFatal("TPC - Missing calibration entry TPC/Calib/Timegain");
3af3fbc4 399 }
400 //
9f6e9f81 401 entry = GetCDBEntry("TPC/Calib/GainFactorDedx");
402 if (entry){
403 entry->SetOwner(kTRUE);
404 fDedxGainFactor = (AliTPCCalPad*)entry->GetObject();
2293155b 405 }else{
13242232 406 AliFatal("TPC - Missing calibration entry TPC/Calib/gainFactordEdx");
9f6e9f81 407 }
408 //
c5bbaa2c 409 entry = GetCDBEntry("TPC/Calib/PadTime0");
410 if (entry){
68751c2c 411 //if (fPadTime0) delete fPadTime0;
c5bbaa2c 412 entry->SetOwner(kTRUE);
413 fPadTime0 = (AliTPCCalPad*)entry->GetObject();
2293155b 414 }else{
13242232 415 AliFatal("TPC - Missing calibration entry");
c5bbaa2c 416 }
2293155b 417
8b63d99c 418 entry = GetCDBEntry("TPC/Calib/Distortion");
2293155b 419 if (entry){
420 //if (fPadTime0) delete fPadTime0;
421 entry->SetOwner(kTRUE);
8b63d99c 422 fDistortionMap =dynamic_cast<TObjArray*>(entry->GetObject());
2293155b 423 }else{
424 //AliFatal("TPC - Missing calibration entry")
425 }
426
427
c5bbaa2c 428 //
c5bbaa2c 429 //
430 entry = GetCDBEntry("TPC/Calib/PadNoise");
431 if (entry){
68751c2c 432 //if (fPadNoise) delete fPadNoise;
c5bbaa2c 433 entry->SetOwner(kTRUE);
434 fPadNoise = (AliTPCCalPad*)entry->GetObject();
2293155b 435 }else{
13242232 436 AliFatal("TPC - Missing calibration entry");
c5bbaa2c 437 }
8477f500 438
439 entry = GetCDBEntry("TPC/Calib/Pedestals");
440 if (entry){
441 //if (fPedestals) delete fPedestals;
442 entry->SetOwner(kTRUE);
443 fPedestals = (AliTPCCalPad*)entry->GetObject();
444 }
445
54472e4f 446 entry = GetCDBEntry("TPC/Calib/Temperature");
447 if (entry){
448 //if (fTemperature) delete fTemperature;
449 entry->SetOwner(kTRUE);
450 fTemperature = (AliTPCSensorTempArray*)entry->GetObject();
451 }
452
8477f500 453 entry = GetCDBEntry("TPC/Calib/Parameters");
454 if (entry){
54472e4f 455 //if (fPadNoise) delete fPadNoise;
8477f500 456 entry->SetOwner(kTRUE);
2baa7fb5 457 fParam = (AliTPCParam*)(entry->GetObject());
2293155b 458 }else{
13242232 459 AliFatal("TPC - Missing calibration entry TPC/Calib/Parameters");
8477f500 460 }
461
96305e49 462 entry = GetCDBEntry("TPC/Calib/ClusterParam");
463 if (entry){
96305e49 464 entry->SetOwner(kTRUE);
2baa7fb5 465 fClusterParam = (AliTPCClusterParam*)(entry->GetObject());
2293155b 466 }else{
13242232 467 AliFatal("TPC - Missing calibration entry");
96305e49 468 }
469
0736ecae 470 entry = GetCDBEntry("TPC/Calib/RecoParam");
471 if (entry){
c8558d35 472 //PH entry->SetOwner(kTRUE);
0736ecae 473 fRecoParamList = dynamic_cast<TObjArray*>(entry->GetObject());
474
475 }else{
476 AliFatal("TPC - Missing calibration entry TPC/Calib/RecoParam");
477 }
478
479
5312f439 480 //ALTRO configuration data
481 entry = GetCDBEntry("TPC/Calib/AltroConfig");
482 if (entry){
483 entry->SetOwner(kTRUE);
484 fALTROConfigData=(TObjArray*)(entry->GetObject());
2293155b 485 }else{
13242232 486 AliFatal("TPC - Missing calibration entry");
5312f439 487 }
488
489 //Calibration Pulser data
490 entry = GetCDBEntry("TPC/Calib/Pulser");
491 if (entry){
492 entry->SetOwner(kTRUE);
493 fPulserData=(TObjArray*)(entry->GetObject());
494 }
495
9a836cc2 496 //Calibration ION tail data
832977ba 497 entry = GetCDBEntry("TPC/Calib/IonTail");
498 if (entry){
a0f26671 499 //delete fIonTailArray; fIonTailArray=NULL;
832977ba 500 entry->SetOwner(kTRUE);
501 fIonTailArray=(TObjArray*)(entry->GetObject());
f3869d7b 502 fIonTailArray->SetOwner(); //own the keys
832977ba 503 }
504
5312f439 505 //CE data
506 entry = GetCDBEntry("TPC/Calib/CE");
507 if (entry){
508 entry->SetOwner(kTRUE);
509 fCEData=(TObjArray*)(entry->GetObject());
510 }
6e7d7dc4 511 //RAW calibration data
56ce896d 512 // entry = GetCDBEntry("TPC/Calib/Raw");
8de4c8a6 513
d6834f5f 514 entry = GetCDBEntry("TPC/Calib/Mapping");
515 if (entry){
516 //if (fPadNoise) delete fPadNoise;
517 entry->SetOwner(kTRUE);
518 TObjArray * array = dynamic_cast<TObjArray*>(entry->GetObject());
519 if (array && array->GetEntriesFast()==6){
520 fMapping = new AliTPCAltroMapping*[6];
521 for (Int_t i=0; i<6; i++){
5312f439 522 fMapping[i] = dynamic_cast<AliTPCAltroMapping*>(array->At(i));
d6834f5f 523 }
524 }
525 }
526
2293155b 527 //CTP calibration data
f14d21a1 528 entry = GetCDBEntry("GRP/CTP/CTPtiming");
529 if (entry){
4a880881 530 //entry->SetOwner(kTRUE);
f14d21a1 531 fCTPTimeParams=dynamic_cast<AliCTPTimeParams*>(entry->GetObject());
2293155b 532 }else{
13242232 533 AliError("TPC - Missing calibration entry");
2293155b 534 }
be67055b 535 //TPC space point correction data
536 entry = GetCDBEntry("TPC/Calib/Correction");
537 if (entry){
538 //entry->SetOwner(kTRUE);
539 fComposedCorrection=dynamic_cast<AliTPCCorrection*>(entry->GetObject());
0b736a46 540 if (fComposedCorrection) fComposedCorrection->Init();
541 fComposedCorrectionArray=dynamic_cast<TObjArray*>(entry->GetObject());
542 if (fComposedCorrectionArray){
543 for (Int_t i=0; i<fComposedCorrectionArray->GetEntries(); i++){
3f3549a3 544 AliTPCComposedCorrection* composedCorrection= dynamic_cast<AliTPCComposedCorrection*>(fComposedCorrectionArray->At(i));
545 if (composedCorrection) {
546 composedCorrection->Init();
547 if (composedCorrection->GetCorrections()){
548 if (composedCorrection->GetCorrections()->FindObject("FitAlignTPC")){
549 fBHasAlignmentOCDB=kTRUE;
550 }
551 }
552 }
0b736a46 553 }
3f3549a3 554 }
be67055b 555 }else{
13242232 556 AliError("TPC - Missing calibration entry- TPC/Calib/Correction");
88a69e6f 557 }
558 //RCU trigger config mode
559 fMode=GetRCUTriggerConfig();
3ac615eb 560 //
f5344549 561 if (!fTransform) {
562 fTransform=new AliTPCTransform();
bfec3eeb 563 fTransform->SetCurrentRun(AliCDBManager::Instance()->GetRun());
f5344549 564 }
8477f500 565
661f340b 566 // Chamber HV data
567 // needs to be called before InitDeadMap
568 UpdateChamberHighVoltageData();
569
ba63ff39 570 // Create Dead Channel Map
571 InitDeadMap();
572
c5bbaa2c 573 //
68751c2c 574 AliCDBManager::Instance()->SetCacheFlag(cdbCache); // reset original CDB cache
c5bbaa2c 575}
e4dce695 576
56ce896d 577void AliTPCcalibDB::UpdateNonRec(){
578 //
579 // Update/Load the parameters which are important for QA studies
580 // and not used yet for the reconstruction
581 //
582 //RAW calibration data
583 AliCDBEntry * entry=0;
584 entry = GetCDBEntry("TPC/Calib/Raw");
585 if (entry){
586 entry->SetOwner(kTRUE);
41a5d739 587 TObjArray *arr=dynamic_cast<TObjArray*>(entry->GetObject());
56ce896d 588 if (arr) fCalibRaw=(AliTPCCalibRaw*)arr->At(0);
41a5d739 589 else fCalibRaw = (AliTPCCalibRaw*)(entry->GetObject());
56ce896d 590 }
591 //QA calibration data
592 entry = GetCDBEntry("TPC/Calib/QA");
593 if (entry){
594 entry->SetOwner(kTRUE);
595 fDataQA=dynamic_cast<AliTPCdataQA*>(entry->GetObject());
596 }
2293155b 597 // High voltage
2b4c6ff5 598 if (fRun>=0 && !fVoltageArray.GetValue(Form("%i",fRun))){
14301155 599 entry = AliCDBManager::Instance()->Get("TPC/Calib/HighVoltage",fRun);
600 if (entry) {
2b4c6ff5 601 fVoltageArray.Add(new TObjString(Form("%i",fRun)),entry->GetObject());
14301155 602 }
2293155b 603 }
604
56ce896d 605}
606
d4559772 607Bool_t AliTPCcalibDB::GetTailcancelationGraphs(Int_t sector, TGraphErrors ** graphRes, Float_t * indexAmpGraphs){
9a836cc2 608
609//
610// Read OCDB entry object of Iontail (TObjArray of TGraphErrors of TRFs)
611// Naming of the TRF objects is: "gr_<chamber_type>_<voltage>_<laser_track_angle>_<distance_to_COG>" --> "gr_iroc_1240_1_1"
612//
613
614 Int_t run = fTransform->GetCurrentRunNumber();
615 SetRun(run);
f3869d7b 616 Float_t rocVoltage = GetChamberHighVoltage(run,sector, -1); // Get the voltage from OCDB with a getter (old function)
9a836cc2 617// Float_t rocVoltage=GetChamberHighVoltageMedian(sector); // Get the voltage from OCDB, new function from Jens
618
619 Int_t nominalVoltage = (sector<36) ? 1240 : 1470 ; // nominal voltage of 2012 when the TRF functions were produced
d4559772 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
9a836cc2 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());
f3869d7b 644 if (!objname.Contains(rocType)) continue;
645
9a836cc2 646 TObjArray *objArr = objname.Tokenize("_");
647
648 // select the roc type (IROC or OROC) and the trackAngle
f3869d7b 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 }
9a836cc2 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++) {
f3869d7b 662 if (diffVoltage >= TMath::Abs(rocVoltage-voltages[k]) && voltages[k]!=0)
9a836cc2 663 {
664 diffVoltage = TMath::Abs(rocVoltage-voltages[k]);
665 ampIndex = k;
666 }
667 }
668 tempVoltage = voltages[ampIndex]; // use closest voltage to current voltage
9a836cc2 669 if (run<140000) tempVoltage = nominalVoltage; // for 2010 data
9a836cc2 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());
f3869d7b 678 if (!objname.Contains(rocType)) continue; //choose ROC type
679
9a836cc2 680 TObjArray *objArr1 = objname.Tokenize("_");
681
682 // TRF eleminations
f3869d7b 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());
a62f3bf7 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 ?
f3869d7b 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);
9a836cc2 698
f3869d7b 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);
9a836cc2 703 }
86df2b3a 704
f3869d7b 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++;
9a836cc2 713 }
9a836cc2 714 delete objArr1;
715 }
d4559772 716 return kTRUE;
9a836cc2 717}
86df2b3a 718
719void AliTPCcalibDB::CreateObjectList(const Char_t *filename, TObjArray *calibObjects)
720{
418bbcaf 721//
722// Create calibration objects and read contents from OCDB
723//
86df2b3a 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;
2c632057 743 while ( (sObjLine = (TObjString*)nextLine()) ){
86df2b3a 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));
09d5920f 750 delete arrNextCol;
751
86df2b3a 752 if ( !sObjType || ! sObjFileName ) continue;
753 TString sType(sObjType->GetString());
754 TString sFileName(sObjFileName->GetString());
661f340b 755// printf("%s\t%s\n",sType.Data(),sFileName.Data());
86df2b3a 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") {
0fe7645c 779 AliTPCCalibPulser *sig = (AliTPCCalibPulser*)fIn->Get("AliTPCCalibPulser");
86df2b3a 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 }
09d5920f 810 delete arrFileLine;
86df2b3a 811}
812
ba63ff39 813Int_t AliTPCcalibDB::InitDeadMap() {
814 // Initialize DeadChannel Map
815 // Source of information:
661f340b 816 // - HV (see UpdateChamberHighVoltageData())
ba63ff39 817 // - Altro disabled channels. Noisy channels.
818 // - DDL list
86df2b3a 819
8de4c8a6 820 // check necessary information
661f340b 821 const Int_t run=GetRun();
8de4c8a6 822 if (run<0){
823 AliError("run not set in CDB manager. Cannot create active channel map");
824 return 0;
825 }
661f340b 826 AliDCSSensorArray* voltageArray = GetVoltageSensors(run);
8de4c8a6 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
8de4c8a6 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
661f340b 855 if (!fActiveChannelMap) fActiveChannelMap=new AliTPCCalPad("ActiveChannelMap","ActiveChannelMap");
856
8de4c8a6 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
661f340b 869 // see UpdateChamberHighVoltageData()
870 if (!fChamberHVStatus[iROC]){
8de4c8a6 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;
ba63ff39 892}
86df2b3a 893
894void AliTPCcalibDB::MakeTree(const char * fileName, TObjArray * array, const char * mapFileName, AliTPCCalPad* outlierPad, Float_t ltmFraction) {
895 //
896 // Write a tree with all available information
418bbcaf 897 // if mapFileName is specified, the Map information are also written to the tree
86df2b3a 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++) {
418bbcaf 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);
86df2b3a 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}
3ac615eb 1101
f14d21a1 1102Int_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
1121Bool_t AliTPCcalibDB::IsTrgL0()
1122{
1123 //
1124 // return if the FEE readout was triggered on L0
1125 //
88a69e6f 1126 if (fMode<0) return kFALSE;
1127 return (fMode==1);
f14d21a1 1128}
3ac615eb 1129
f14d21a1 1130Bool_t AliTPCcalibDB::IsTrgL1()
1131{
1132 //
1133 // return if the FEE readout was triggered on L1
1134 //
88a69e6f 1135 if (fMode<0) return kFALSE;
1136 return (fMode==0);
f14d21a1 1137}
3ac615eb 1138
1139void 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
0a997b33 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)
3ac615eb 1148
4642ac4b 1149 AliMagF* bmap = new AliMagF("MapsExB","MapsExB", factor,TMath::Sign(1.f,factor),AliMagF::k5kG);
3ac615eb 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
1164AliTPCExB* 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
1177void AliTPCcalibDB::SetExBField(Float_t bz){
1178 //
1179 // Set magnetic filed for ExB correction
1180 //
1181 fExB = GetExB(bz,kFALSE);
1182}
bf85fe4d 1183
0a997b33 1184void 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
bf85fe4d 1193
1194
5e1215d4 1195void AliTPCcalibDB::UpdateRunInformations( Int_t run, Bool_t force){
bf85fe4d 1196 //
1197 // - > Don't use it for reconstruction - Only for Calibration studies
1198 //
b96c3aef 1199 if (run<=0) return;
2b4c6ff5 1200 TObjString runstr(Form("%i",run));
14301155 1201 fRun=run;
bf85fe4d 1202 AliCDBEntry * entry = 0;
cc65e4f5 1203 if (run>= fRunList.fN){
bf85fe4d 1204 fRunList.Set(run*2+1);
cc65e4f5 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
d32e8676 1210 if (!fTimeGainSplines) fTimeGainSplines = new TObjArray(run*2+1);
cc65e4f5 1211 fTimeGainSplines->Expand(run*2+1); // Array of AliSplineFits: at 0 MIP position in
bf85fe4d 1212 }
cc65e4f5 1213 if (fRunList[run]>0 &&force==kFALSE) return;
1e722a63 1214
1215 fRunList[run]=1; // sign as used
1216
5e1215d4 1217 //
bf85fe4d 1218 entry = AliCDBManager::Instance()->Get("GRP/GRP/Data",run);
0231c65f 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){
e2914767 1224 //grpRun = new AliGRPObject;
1225 //grpRun->ReadValuesFromMap(map);
1226 grpRun = MakeGRPObjectFromMap(map);
1227
2b4c6ff5 1228 fGRPMaps.Add(new TObjString(runstr),map);
0231c65f 1229 }
1230 }
2b4c6ff5 1231 fGRPArray.Add(new TObjString(runstr),grpRun);
0231c65f 1232 }
bf85fe4d 1233 entry = AliCDBManager::Instance()->Get("TPC/Calib/Goofie",run);
5e1215d4 1234 if (entry){
2b4c6ff5 1235 fGoofieArray.Add(new TObjString(runstr),entry->GetObject());
5e1215d4 1236 }
e2914767 1237 //
2293155b 1238
e2914767 1239 //
a2c3785e 1240 entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeGain",run);
5e1215d4 1241 if (entry) {
2b4c6ff5 1242 fTimeGainSplinesArray.Add(new TObjString(runstr),entry->GetObject());
2293155b 1243 }else{
13242232 1244 AliFatal("TPC - Missing calibration entry TimeGain");
5e1215d4 1245 }
1246 //
1247 entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeDrift",run);
1248 if (entry) {
3f3549a3 1249 TObjArray * timeArray = (TObjArray*)entry->GetObject();
2b4c6ff5 1250 fDriftCorrectionArray.Add(new TObjString(runstr),entry->GetObject());
3f3549a3 1251 AliTPCCorrection * correctionTime = (AliTPCCorrection *)timeArray->FindObject("FitCorrectionTime");
1252 if (correctionTime && fComposedCorrectionArray){
1253 correctionTime->Init();
a8ef8a9c 1254 if (fComposedCorrectionArray->GetEntriesFast()<4) fComposedCorrectionArray->Expand(40);
3f3549a3 1255 fComposedCorrectionArray->AddAt(correctionTime,4); //add time dependent correction to the list of available corrections
1256 }
2293155b 1257 }else{
13242232 1258 AliFatal("TPC - Missing calibration entry TimeDrift");
5e1215d4 1259 }
a2c3785e 1260 //
bf85fe4d 1261 entry = AliCDBManager::Instance()->Get("TPC/Calib/Temperature",run);
5e1215d4 1262 if (entry) {
2b4c6ff5 1263 fTemperatureArray.Add(new TObjString(runstr),entry->GetObject());
5e1215d4 1264 }
8de4c8a6 1265
1266 // High voltage
1267 entry = AliCDBManager::Instance()->Get("TPC/Calib/HighVoltage",run);
2b4c6ff5 1268 if (!fVoltageArray.GetValue(runstr.GetName()) && entry) {
1269 fVoltageArray.Add(new TObjString(runstr),entry->GetObject());
8de4c8a6 1270 }
1271
1e722a63 1272 //apply fDButil filters
1273
1274 fDButil->UpdateFromCalibDB();
1275 if (fTemperature) fDButil->FilterTemperature(fTemperature);
da6c0bc9 1276
bfec3eeb 1277 AliDCSSensor * press = GetPressureSensor(run,0);
da6c0bc9 1278 AliTPCSensorTempArray * temp = GetTemperatureSensor(run);
1e722a63 1279 Bool_t accept=kTRUE;
1280 if (temp) {
1281 accept = fDButil->FilterTemperature(temp)>0.1;
1282 }
1283 if (press) {
7506b1e9 1284 const Double_t kMinP=900.;
1e722a63 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 }
5647625c 1291
1e722a63 1292 if (press && temp &&accept){
da6c0bc9 1293 AliTPCCalibVdrift * vdrift = new AliTPCCalibVdrift(temp, press,0);
2b4c6ff5 1294 fVdriftArray.Add(new TObjString(runstr),vdrift);
da6c0bc9 1295 }
5647625c 1296
1e722a63 1297 fDButil->FilterCE(120., 3., 4.,0);
1298 fDButil->FilterTracks(run, 10.,0);
5647625c 1299
bf85fe4d 1300}
1301
1302
1303Float_t AliTPCcalibDB::GetGain(Int_t sector, Int_t row, Int_t pad){
1304 //
92fb7d95 1305 // Get Gain factor for given pad
bf85fe4d 1306 //
1307 AliTPCCalPad *calPad = Instance()->fDedxGainFactor;;
1308 if (!calPad) return 0;
1309 return calPad->GetCalROC(sector)->GetValue(row,pad);
1310}
1311
7390f655 1312AliSplineFit* AliTPCcalibDB::GetVdriftSplineFit(const char* name, Int_t run){
1313 //
92fb7d95 1314 // GetDrift velocity spline fit
7390f655 1315 //
1316 TObjArray *arr=GetTimeVdriftSplineRun(run);
1317 if (!arr) return 0;
1318 return dynamic_cast<AliSplineFit*>(arr->FindObject(name));
1319}
1320
2cb269df 1321AliSplineFit* 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}
8de77f00 1336
1337AliGRPObject *AliTPCcalibDB::GetGRP(Int_t run){
1338 //
1339 // Get GRP object for given run
1340 //
2b4c6ff5 1341 AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>((Instance()->fGRPArray).GetValue(Form("%i",run)));
8de77f00 1342 if (!grpRun) {
5e1215d4 1343 Instance()->UpdateRunInformations(run);
2b4c6ff5 1344 grpRun = dynamic_cast<AliGRPObject *>(Instance()->fGRPArray.GetValue(Form("%i",run)));
8de77f00 1345 if (!grpRun) return 0;
1346 }
1347 return grpRun;
1348}
1349
0231c65f 1350TMap * AliTPCcalibDB::GetGRPMap(Int_t run){
1351 //
92fb7d95 1352 // Get GRP map for given run
0231c65f 1353 //
2b4c6ff5 1354 TMap * grpRun = dynamic_cast<TMap *>((Instance()->fGRPMaps).GetValue(Form("%i",run)));
0231c65f 1355 if (!grpRun) {
5e1215d4 1356 Instance()->UpdateRunInformations(run);
2b4c6ff5 1357 grpRun = dynamic_cast<TMap *>(Instance()->fGRPMaps.GetValue(Form("%i",run)));
0231c65f 1358 if (!grpRun) return 0;
1359 }
1360 return grpRun;
1361}
8de77f00 1362
1363
da6c0bc9 1364AliDCSSensor * AliTPCcalibDB::GetPressureSensor(Int_t run, Int_t type){
bf85fe4d 1365 //
0231c65f 1366 // Get Pressure sensor
bfec3eeb 1367 // run = run number
1368 // type = 0 - Cavern pressure
1369 // 1 - Suface pressure
0231c65f 1370 // First try to get if trom map - if existing (Old format of data storing)
bf85fe4d 1371 //
bfec3eeb 1372
1373
0231c65f 1374 TMap *map = GetGRPMap(run);
1375 if (map){
1376 AliDCSSensor * sensor = 0;
1377 TObject *osensor=0;
2cd3a697 1378 if (type==0) osensor = ((*map)("fCavernPressure"));
0231c65f 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 //
2b4c6ff5 1386 AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.GetValue(Form("%i",run)));
bf85fe4d 1387 if (!grpRun) {
5e1215d4 1388 UpdateRunInformations(run);
2b4c6ff5 1389 grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.GetValue(Form("%i",run)));
bf85fe4d 1390 if (!grpRun) return 0;
1391 }
2cd3a697 1392 AliDCSSensor * sensor = grpRun->GetCavernAtmosPressure();
da6c0bc9 1393 if (type==1) sensor = grpRun->GetSurfaceAtmosPressure();
1394 return sensor;
bf85fe4d 1395}
1396
1397AliTPCSensorTempArray * AliTPCcalibDB::GetTemperatureSensor(Int_t run){
1398 //
1399 // Get temperature sensor array
1400 //
2b4c6ff5 1401 AliTPCSensorTempArray * tempArray = (AliTPCSensorTempArray *)fTemperatureArray.GetValue(Form("%i",run));
bf85fe4d 1402 if (!tempArray) {
5e1215d4 1403 UpdateRunInformations(run);
2b4c6ff5 1404 tempArray = (AliTPCSensorTempArray *)fTemperatureArray.GetValue(Form("%i",run));
bf85fe4d 1405 }
1406 return tempArray;
1407}
1408
a2c3785e 1409
1410TObjArray * AliTPCcalibDB::GetTimeGainSplinesRun(Int_t run){
bf85fe4d 1411 //
1412 // Get temperature sensor array
1413 //
2b4c6ff5 1414 TObjArray * gainSplines = (TObjArray *)fTimeGainSplinesArray.GetValue(Form("%i",run));
a2c3785e 1415 if (!gainSplines) {
5e1215d4 1416 UpdateRunInformations(run);
2b4c6ff5 1417 gainSplines = (TObjArray *)fTimeGainSplinesArray.GetValue(Form("%i",run));
bf85fe4d 1418 }
a2c3785e 1419 return gainSplines;
bf85fe4d 1420}
1421
7390f655 1422TObjArray * AliTPCcalibDB::GetTimeVdriftSplineRun(Int_t run){
1423 //
1424 // Get drift spline array
1425 //
2b4c6ff5 1426 TObjArray * driftSplines = (TObjArray *)fDriftCorrectionArray.GetValue(Form("%i",run));
7390f655 1427 if (!driftSplines) {
1428 UpdateRunInformations(run);
2b4c6ff5 1429 driftSplines = (TObjArray *)fDriftCorrectionArray.GetValue(Form("%i",run));
7390f655 1430 }
1431 return driftSplines;
1432}
1433
e2914767 1434AliDCSSensorArray * AliTPCcalibDB::GetVoltageSensors(Int_t run){
1435 //
1436 // Get temperature sensor array
1437 //
2b4c6ff5 1438 AliDCSSensorArray * voltageArray = (AliDCSSensorArray *)fVoltageArray.GetValue(Form("%i",run));
e2914767 1439 if (!voltageArray) {
5e1215d4 1440 UpdateRunInformations(run);
2b4c6ff5 1441 voltageArray = (AliDCSSensorArray *)fVoltageArray.GetValue(Form("%i",run));
e2914767 1442 }
1443 return voltageArray;
1444}
1445
99895a4f 1446AliDCSSensorArray * AliTPCcalibDB::GetGoofieSensors(Int_t run){
1447 //
1448 // Get temperature sensor array
1449 //
2b4c6ff5 1450 AliDCSSensorArray * goofieArray = (AliDCSSensorArray *)fGoofieArray.GetValue(Form("%i",run));
99895a4f 1451 if (!goofieArray) {
5e1215d4 1452 UpdateRunInformations(run);
2b4c6ff5 1453 goofieArray = (AliDCSSensorArray *)fGoofieArray.GetValue(Form("%i",run));
99895a4f 1454 }
1455 return goofieArray;
1456}
1457
1458
1459
da6c0bc9 1460AliTPCCalibVdrift * AliTPCcalibDB::GetVdrift(Int_t run){
1461 //
1462 // Get the interface to the the vdrift
1463 //
2b4c6ff5 1464 AliTPCCalibVdrift * vdrift = (AliTPCCalibVdrift*)fVdriftArray.GetValue(Form("%i",run));
da6c0bc9 1465 if (!vdrift) {
5e1215d4 1466 UpdateRunInformations(run);
2b4c6ff5 1467 vdrift= (AliTPCCalibVdrift*)fVdriftArray.GetValue(Form("%i",run));
da6c0bc9 1468 }
1469 return vdrift;
1470}
1471
892226be 1472Float_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
1501Float_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
7fff7612 1528Float_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;
892226be 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);
7390f655 1543 Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
892226be 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);
2c949bb2 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;
892226be 1559 }
1560 //last point
1561 if (val==0 ){
1562 Double_t x,y;
1563 gr->GetPoint(gr->GetN()-1,x,y);
2c949bb2 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;
892226be 1567 }
1568 } else {
1569 val=sensor->GetValue(timeStamp);
1570 }
7fff7612 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
1577Float_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;
892226be 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 }
7fff7612 1600 }
7fff7612 1601 if (sigDigits>=0){
60721370 1602 // val/=10;
7fff7612 1603 val=(Float_t)TMath::Floor(val * TMath::Power(10., sigDigits) + .5) / TMath::Power(10., sigDigits);
60721370 1604 // val*=10;
7fff7612 1605 }
1606 return val;
1607}
bf85fe4d 1608
661f340b 1609Bool_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
1629void 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;
6282b748 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();
661f340b 1649
5a585aa4 1650 //
1651 // In case we use a generated GRP we cannot make use of the start time and end time information
1652 // therefore we cannot calculate proper HV information and will skip this
1653 //
1654 if (startTimeGRP==0 && stopTimeGRP==0) {
1655 AliWarning("Using a generated GRP with 'GetTimeStart()' and 'GetTimeEnd()' == 0. Cannot calculate HV information.");
1656 return;
1657 }
1658
661f340b 1659 //
1660 // check active state by analysing the scalers
1661 //
1662 // initialise graph with active running
1663 AliCDBEntry *entry = GetCDBEntry("GRP/CTP/Scalers");
a3c96d3f 1664 if (!entry) return;
11981cb2 1665 // entry->SetOwner(kTRUE);
661f340b 1666 AliTriggerRunScalers *sca = (AliTriggerRunScalers*)entry->GetObject();
1667 Int_t nchannels = sca->GetNumClasses(); // number of scaler channels (i.e. trigger classes)
1668 Int_t npoints = sca->GetScalersRecords()->GetEntries(); // number of samples
1669
1670 delete fGrRunState;
1671 fGrRunState=new TGraph;
1672 fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(startTimeGRP)-.001,0);
1673 fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(startTimeGRP),1);
1674 ULong64_t lastSum=0;
1675 Double_t timeLast=0.;
1676 Bool_t active=kTRUE;
1677 for (int i=0; i<npoints; i++) {
1678 AliTriggerScalersRecord *rec = (AliTriggerScalersRecord *) sca->GetScalersRecord(i);
1679 Double_t time = ((AliTimeStamp*) rec->GetTimeStamp())->GetSeconds();
1680 ULong64_t sum=0;
1681 for (int j=0; j<nchannels; j++) sum += ((AliTriggerScalers*) rec->GetTriggerScalers()->At(j))->GetL2CA();
1682 if (TMath::Abs(time-timeLast)<.001 && sum==lastSum ) continue;
1683 if (active && sum==lastSum){
1684 fGrRunState->SetPoint(fGrRunState->GetN(),timeLast-.01,1);
1685 fGrRunState->SetPoint(fGrRunState->GetN(),timeLast,0);
1686 active=kFALSE;
1687 } else if (!active && sum>lastSum ){
1688 fGrRunState->SetPoint(fGrRunState->GetN(),timeLast-.01,0);
1689 fGrRunState->SetPoint(fGrRunState->GetN(),timeLast,1);
1690 active=kTRUE;
1691 }
1692 lastSum=sum;
1693 timeLast=time;
1694 }
1695 fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(stopTimeGRP),active);
1696 fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(stopTimeGRP)+.001,0);
1697
1698
1699
1700 // reset all values
1701 for (Int_t iROC=0;iROC<72;++iROC) {
1702 fChamberHVmedian[iROC] = -1;
1703 fChamberHVgoodFraction[iROC] = 0.;
1704 fCurrentNominalVoltage[iROC] = -999.;
1705 fChamberHVStatus[iROC] = kFALSE;
1706 }
1707
1708 AliDCSSensorArray* voltageArray = GetVoltageSensors(run);
1709 if (!voltageArray) {
1710 AliError("Voltage Array missing. Cannot calculate HV information!");
1711 return;
1712 }
1713
1714 // max HV diffs before a chamber is masked
1715 const Float_t maxVdiff = fParam->GetMaxVoltageDeviation();
1716 const Float_t maxDipVoltage = fParam->GetMaxDipVoltage();
1717 const Float_t maxFracHVbad = fParam->GetMaxFractionHVbad();
1718
1719 const Int_t samplingPeriod=1;
1720
1721 // array with sampled voltages
1722 const Int_t maxSamples=(stopTimeGRP-startTimeGRP)/samplingPeriod + 10*samplingPeriod;
1723 Float_t *vSampled = new Float_t[maxSamples];
1724
1725 // deviation of the median from the nominal voltage
1726 Double_t chamberMedianDeviation[72]={0.};
1727
1728 for (Int_t iROC=0; iROC<72; ++iROC){
1729 chamberMedianDeviation[iROC]=0.;
1730 TString sensorName="";
1731 Char_t sideName='A';
1732 if ((iROC/18)%2==1) sideName='C';
1733 if (iROC<36) sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,iROC%18);
1734 else sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,iROC%18);
1735
1736 AliDCSSensor *sensor = voltageArray->GetSensor(sensorName);
1737
1738 fHVsensors[iROC]=sensor;
1739 if (!sensor) continue;
1740
1741 Int_t nPointsSampled=0;
1742
1743 TGraph *gr=sensor->GetGraph();
1744 if ( gr && gr->GetN()>1 ){
1745 //1. sample voltage over time
1746 // get a robust median
1747 // buffer sampled voltages
1748
1749 // current sampling time
1750 Int_t time=startTimeGRP;
1751
1752 // input graph sampling point
1753 const Int_t nGraph=gr->GetN();
1754 Int_t pointGraph=0;
1755
1756 //initialise graph information
1757 Int_t timeGraph=TMath::Nint(gr->GetX()[pointGraph+1]*3600+sensor->GetStartTime());
1758 Double_t sampledHV=gr->GetY()[pointGraph++];
1759
1760 while (time<stopTimeGRP){
1761 while (timeGraph<=time && pointGraph+1<nGraph){
1762 timeGraph=TMath::Nint(gr->GetX()[pointGraph+1]*3600+sensor->GetStartTime());
1763 sampledHV=gr->GetY()[pointGraph++];
1764 }
1765 time+=samplingPeriod;
1766 if (!IsDataTakingActive(time-samplingPeriod)) continue;
1767 vSampled[nPointsSampled++]=sampledHV;
1768 }
1769
1770 if (nPointsSampled<1) continue;
1771
1772 fChamberHVmedian[iROC]=TMath::Median(nPointsSampled,vSampled);
1773 chamberMedianDeviation[iROC]=fChamberHVmedian[iROC]-fParam->GetNominalVoltage(iROC);
1774
1775 //2. calculate good HV fraction
1776 Int_t ngood=0;
1777 for (Int_t ipoint=0; ipoint<nPointsSampled; ++ipoint) {
1778 if (TMath::Abs(vSampled[ipoint]-fChamberHVmedian[iROC])<maxDipVoltage) ++ngood;
1779 }
1780
1781 fChamberHVgoodFraction[iROC]=Float_t(ngood)/Float_t(nPointsSampled);
e81b123b 1782 } else if (!gr && !sensor->GetFit() ){
1783 // This is an exception handling.
1784 // It was observed that for some rund in the 2010 data taking no HV info is available
1785 // for some sectors. However they were active. So take care about this
1786 fChamberHVmedian[iROC] = fParam->GetNominalVoltage(iROC);
1787 fChamberHVgoodFraction[iROC] = 1.;
1788 AliWarning(Form("ROC %d detected without HV Splines and HV graph. Will set median HV to nominal voltage",iROC));
661f340b 1789 } else {
1790 AliError(Form("No Graph or too few points found for HV sensor of ROC %d",iROC));
1791 }
1792 }
1793
1794 delete [] vSampled;
1795 vSampled=0x0;
1796
1797 // get median deviation from all chambers (detect e.g. -50V)
1798 const Double_t medianIROC=TMath::Median( 36, chamberMedianDeviation );
1799 const Double_t medianOROC=TMath::Median( 36, chamberMedianDeviation+36 );
1800
1801 // Define current default voltages
1802 for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
1803 const Float_t averageDeviation=(iROC<36)?medianIROC:medianOROC;
1804 fCurrentNominalVoltage[iROC]=fParam->GetNominalVoltage(iROC)+averageDeviation;
1805 }
1806
1807 //
1808 // Check HV status
1809 //
1810 for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
1811 fChamberHVStatus[iROC]=kTRUE;
1812
1813 //a. Deviation of median from current nominal voltage
1814 // allow larger than nominal voltages
1815 if (fCurrentNominalVoltage[iROC]-fChamberHVmedian[iROC] > maxVdiff) fChamberHVStatus[iROC]=kFALSE;
1816
1817 //b. Fraction of bad hv values
1818 if ( 1-fChamberHVgoodFraction[iROC] > maxFracHVbad ) fChamberHVStatus[iROC]=kFALSE;
1819 }
1820}
1821
2073b7a5 1822Float_t AliTPCcalibDB::GetChamberHighVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits, Bool_t current) {
e2914767 1823 //
1824 // return the chamber HV for given run and time: 0-35 IROC, 36-72 OROC
7fff7612 1825 // if timeStamp==-1 return mean value
1826 //
1827 Float_t val=0;
1828 TString sensorName="";
1829 TTimeStamp stamp(timeStamp);
1830 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1831 if (!voltageArray || (sector<0) || (sector>71)) return val;
1832 Char_t sideName='A';
1833 if ((sector/18)%2==1) sideName='C';
1834 if (sector<36){
1835 //IROC
1836 sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
1837 }else{
1838 //OROC
1839 sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
1840 }
2073b7a5 1841 if (current){
1842 if (sector<36){
1843 //IROC
1844 sensorName=Form("TPC_ANODE_I_%c%02d_IMEAS",sideName,sector%18);
8de4c8a6 1845 }else{
2073b7a5 1846 //OROC
1847 sensorName=Form("TPC_ANODE_O_%c%02d_0_IMEAS",sideName,sector%18);
1848 }
8de4c8a6 1849
2073b7a5 1850 }
7fff7612 1851 if (timeStamp==-1){
1852 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1853 } else {
1854 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1855 }
1856 return val;
1857}
1858Float_t AliTPCcalibDB::GetSkirtVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1859{
1860 //
1861 // Get the skirt voltage for 'run' at 'timeStamp' and 'sector': 0-35 IROC, 36-72 OROC
1862 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1863 // if timeStamp==-1 return the mean value for the run
1864 //
1865 Float_t val=0;
1866 TString sensorName="";
1867 TTimeStamp stamp(timeStamp);
1868 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1869 if (!voltageArray || (sector<0) || (sector>71)) return val;
1870 Char_t sideName='A';
1871 if ((sector/18)%2==1) sideName='C';
1872 sensorName=Form("TPC_SKIRT_%c_VMEAS",sideName);
1873 if (timeStamp==-1){
1874 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1875 } else {
1876 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1877 }
1878 return val;
1879}
1880
1881Float_t AliTPCcalibDB::GetCoverVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1882{
1883 //
1884 // Get the cover voltage for run 'run' at time 'timeStamp'
1885 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1886 // if timeStamp==-1 return the mean value for the run
e2914767 1887 //
7fff7612 1888 Float_t val=0;
1889 TString sensorName="";
e2914767 1890 TTimeStamp stamp(timeStamp);
1891 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
7fff7612 1892 if (!voltageArray || (sector<0) || (sector>71)) return val;
1893 Char_t sideName='A';
1894 if ((sector/18)%2==1) sideName='C';
1895 if (sector<36){
1896 //IROC
1897 sensorName=Form("TPC_COVER_I_%c_VMEAS",sideName);
1898 }else{
1899 //OROC
1900 sensorName=Form("TPC_COVER_O_%c_VMEAS",sideName);
1901 }
1902 if (timeStamp==-1){
1903 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1904 } else {
1905 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1906 }
1907 return val;
1908}
1909
1910Float_t AliTPCcalibDB::GetGGoffsetVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1911{
1912 //
1913 // Get the GG offset voltage for run 'run' at time 'timeStamp'
1914 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1915 // if timeStamp==-1 return the mean value for the run
1916 //
1917 Float_t val=0;
1918 TString sensorName="";
1919 TTimeStamp stamp(timeStamp);
1920 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1921 if (!voltageArray || (sector<0) || (sector>71)) return val;
1922 Char_t sideName='A';
1923 if ((sector/18)%2==1) sideName='C';
1924 if (sector<36){
1925 //IROC
1926 sensorName=Form("TPC_GATE_I_%c_OFF_VMEAS",sideName);
1927 }else{
1928 //OROC
1929 sensorName=Form("TPC_GATE_O_%c_OFF_VMEAS",sideName);
1930 }
1931 if (timeStamp==-1){
1932 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1933 } else {
1934 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1935 }
1936 return val;
1937}
1938
1939Float_t AliTPCcalibDB::GetGGnegVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1940{
1941 //
1942 // Get the GG offset voltage for run 'run' at time 'timeStamp'
1943 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1944 // if timeStamp==-1 return the mean value for the run
1945 //
1946 Float_t val=0;
1947 TString sensorName="";
1948 TTimeStamp stamp(timeStamp);
1949 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1950 if (!voltageArray || (sector<0) || (sector>71)) return val;
1951 Char_t sideName='A';
1952 if ((sector/18)%2==1) sideName='C';
1953 if (sector<36){
1954 //IROC
1955 sensorName=Form("TPC_GATE_I_%c_NEG_VMEAS",sideName);
1956 }else{
1957 //OROC
1958 sensorName=Form("TPC_GATE_O_%c_NEG_VMEAS",sideName);
1959 }
1960 if (timeStamp==-1){
1961 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1962 } else {
1963 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1964 }
1965 return val;
1966}
1967
1968Float_t AliTPCcalibDB::GetGGposVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1969{
1970 //
1971 // Get the GG offset voltage for run 'run' at time 'timeStamp'
1972 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1973 // if timeStamp==-1 return the mean value for the run
1974 //
1975 Float_t val=0;
1976 TString sensorName="";
1977 TTimeStamp stamp(timeStamp);
1978 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1979 if (!voltageArray || (sector<0) || (sector>71)) return val;
1980 Char_t sideName='A';
1981 if ((sector/18)%2==1) sideName='C';
1982 if (sector<36){
1983 //IROC
1984 sensorName=Form("TPC_GATE_I_%c_POS_VMEAS",sideName);
1985 }else{
1986 //OROC
1987 sensorName=Form("TPC_GATE_O_%c_POS_VMEAS",sideName);
1988 }
1989 if (timeStamp==-1){
1990 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1991 } else {
1992 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1993 }
1994 return val;
e2914767 1995}
bf85fe4d 1996
da6c0bc9 1997Float_t AliTPCcalibDB::GetPressure(Int_t timeStamp, Int_t run, Int_t type){
bf85fe4d 1998 //
1999 // GetPressure for given time stamp and runt
2000 //
2001 TTimeStamp stamp(timeStamp);
da6c0bc9 2002 AliDCSSensor * sensor = Instance()->GetPressureSensor(run,type);
bf85fe4d 2003 if (!sensor) return 0;
bf85fe4d 2004 return sensor->GetValue(stamp);
2005}
2006
5312f439 2007Float_t AliTPCcalibDB::GetL3Current(Int_t run, Int_t statType){
2008 //
2009 // return L3 current
2010 // stat type is: AliGRPObject::Stats: kMean = 0, kTruncMean = 1, kMedian = 2, kSDMean = 3, kSDMedian = 4
2011 //
2012 Float_t current=-1;
2013 AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2014 if (grp) current=grp->GetL3Current((AliGRPObject::Stats)statType);
2015 return current;
2016}
2017
2018Float_t AliTPCcalibDB::GetBz(Int_t run){
2019 //
e6970ab5 2020 // calculate BZ in T from L3 current
5312f439 2021 //
2022 Float_t bz=-1;
2023 Float_t current=AliTPCcalibDB::GetL3Current(run);
e6970ab5 2024 if (current>-1) bz=5*current/30000.*.1;
5312f439 2025 return bz;
2026}
2027
2028Char_t AliTPCcalibDB::GetL3Polarity(Int_t run) {
2029 //
2030 // get l3 polarity from GRP
2031 //
7390f655 2032 Char_t pol=-100;
2033 AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2034 if (grp) pol=grp->GetL3Polarity();
2035 return pol;
5312f439 2036}
2037
2038TString AliTPCcalibDB::GetRunType(Int_t run){
2039 //
2040 // return run type from grp
2041 //
7390f655 2042
2043// TString type("UNKNOWN");
2044 AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
2045 if (grp) return grp->GetRunType();
2046 return "UNKNOWN";
5312f439 2047}
2048
7f7847fe 2049Float_t AliTPCcalibDB::GetValueGoofie(Int_t timeStamp, Int_t run, Int_t type){
2050 //
2051 // GetPressure for given time stamp and runt
2052 //
2053 TTimeStamp stamp(timeStamp);
2054 AliDCSSensorArray* goofieArray = AliTPCcalibDB::Instance()->GetGoofieSensors(run);
2055 if (!goofieArray) return 0;
2056 AliDCSSensor *sensor = goofieArray->GetSensor(type);
2057 return sensor->GetValue(stamp);
2058}
2059
2060
2061
2062
2063
2064
f0269955 2065Bool_t AliTPCcalibDB::GetTemperatureFit(Int_t timeStamp, Int_t run, Int_t side,TVectorD& fit){
2066 //
92fb7d95 2067 // GetTmeparature fit at parameter for given time stamp
f0269955 2068 //
2069 TTimeStamp tstamp(timeStamp);
64b48395 2070 AliTPCSensorTempArray* tempArray = Instance()->GetTemperatureSensor(run);
f0269955 2071 if (! tempArray) return kFALSE;
2072 AliTPCTempMap * tempMap = new AliTPCTempMap(tempArray);
2073 TLinearFitter * fitter = tempMap->GetLinearFitter(3,side,tstamp);
2074 if (fitter){
2075 fitter->Eval();
2076 fitter->GetParameters(fit);
2077 }
2078 delete fitter;
2079 delete tempMap;
2080 if (!fitter) return kFALSE;
2081 return kTRUE;
2082}
2083
64b48395 2084Float_t AliTPCcalibDB::GetTemperature(Int_t timeStamp, Int_t run, Int_t side){
2085 //
92fb7d95 2086 // Get mean temperature
2087 //
12e42756 2088 TVectorD vec(5);
64b48395 2089 if (side==0) {
2090 GetTemperatureFit(timeStamp,run,0,vec);
2091 return vec[0];
2092 }
2093 if (side==1){
2094 GetTemperatureFit(timeStamp,run,0,vec);
2095 return vec[0];
2096 }
57dc06f2 2097 return 0;
64b48395 2098}
bf85fe4d 2099
2100
da6c0bc9 2101Double_t AliTPCcalibDB::GetPTRelative(UInt_t timeSec, Int_t run, Int_t side){
2102 //
2103 // Get relative P/T
2104 // time - absolute time
2105 // run - run number
2106 // side - 0 - A side 1-C side
2107 AliTPCCalibVdrift * vdrift = Instance()->GetVdrift(run);
2108 if (!vdrift) return 0;
2109 return vdrift->GetPTRelative(timeSec,side);
2110}
2111
e2914767 2112AliGRPObject * AliTPCcalibDB::MakeGRPObjectFromMap(TMap *map){
2113 //
2114 // Function to covert old GRP run information from TMap to GRPObject
2115 //
2116 // TMap * map = AliTPCcalibDB::GetGRPMap(52406);
2117 if (!map) return 0;
2118 AliDCSSensor * sensor = 0;
2119 TObject *osensor=0;
2120 osensor = ((*map)("fP2Pressure"));
2121 sensor =dynamic_cast<AliDCSSensor *>(osensor);
2122 //
2123 if (!sensor) return 0;
2124 //
2125 AliDCSSensor * sensor2 = new AliDCSSensor(*sensor);
2cd3a697 2126 osensor = ((*map)("fCavernPressure"));
e2914767 2127 TGraph * gr = new TGraph(2);
2128 gr->GetX()[0]= -100000.;
2129 gr->GetX()[1]= 1000000.;
2130 gr->GetY()[0]= atof(osensor->GetName());
2131 gr->GetY()[1]= atof(osensor->GetName());
2132 sensor2->SetGraph(gr);
2133 sensor2->SetFit(0);
2134
2135
2136 AliGRPObject *grpRun = new AliGRPObject;
2137 grpRun->ReadValuesFromMap(map);
2138 grpRun->SetCavernAtmosPressure(sensor2);
2cd3a697 2139 grpRun->SetCavernAtmosPressure(sensor2);
e2914767 2140 grpRun->SetSurfaceAtmosPressure(sensor);
2141 return grpRun;
2142}
2143
5312f439 2144Bool_t AliTPCcalibDB::CreateGUITree(Int_t run, const char* filename)
2145{
2146 //
2147 // Create a gui tree for run number 'run'
2148 //
e2914767 2149
5312f439 2150 if (!AliCDBManager::Instance()->GetDefaultStorage()){
2151 AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
2152 MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
2153 return kFALSE;
2154 }
2155 //db instance
2156 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
2157 // retrieve cal pad objects
2158 db->SetRun(run);
949d8707 2159 db->CreateGUITree(filename);
7fe54a9b 2160 return kTRUE;
949d8707 2161}
2162
2163Bool_t AliTPCcalibDB::CreateGUITree(const char* filename){
2164 //
2165 //
2166 //
2167 if (!AliCDBManager::Instance()->GetDefaultStorage()){
2168 AliError("Default Storage not set. Cannot create calibration Tree!");
2169 return kFALSE;
2170 }
56ce896d 2171 UpdateNonRec(); // load all infromation now
2172
5312f439 2173 AliTPCPreprocessorOnline prep;
b06ad5b4 2174 if (GetActiveChannelMap()) prep.AddComponent(new AliTPCCalPad(*GetActiveChannelMap()));
2175
2176 // gain map
2177 if (GetDedxGainFactor()) prep.AddComponent(new AliTPCCalPad(*GetDedxGainFactor()));
5312f439 2178 //noise and pedestals
949d8707 2179 if (GetPedestals()) prep.AddComponent(new AliTPCCalPad(*(GetPedestals())));
2180 if (GetPadNoise() ) prep.AddComponent(new AliTPCCalPad(*(GetPadNoise())));
5312f439 2181 //pulser data
949d8707 2182 if (GetPulserTmean()) prep.AddComponent(new AliTPCCalPad(*(GetPulserTmean())));
2183 if (GetPulserTrms() ) prep.AddComponent(new AliTPCCalPad(*(GetPulserTrms())));
2184 if (GetPulserQmean()) prep.AddComponent(new AliTPCCalPad(*(GetPulserQmean())));
5312f439 2185 //CE data
949d8707 2186 if (GetCETmean()) prep.AddComponent(new AliTPCCalPad(*(GetCETmean())));
2187 if (GetCETrms() ) prep.AddComponent(new AliTPCCalPad(*(GetCETrms())));
2188 if (GetCEQmean()) prep.AddComponent(new AliTPCCalPad(*(GetCEQmean())));
5312f439 2189 //Altro data
949d8707 2190 if (GetALTROAcqStart() ) prep.AddComponent(new AliTPCCalPad(*(GetALTROAcqStart() )));
2191 if (GetALTROZsThr() ) prep.AddComponent(new AliTPCCalPad(*(GetALTROZsThr() )));
2192 if (GetALTROFPED() ) prep.AddComponent(new AliTPCCalPad(*(GetALTROFPED() )));
2193 if (GetALTROAcqStop() ) prep.AddComponent(new AliTPCCalPad(*(GetALTROAcqStop() )));
2194 if (GetALTROMasked() ) prep.AddComponent(new AliTPCCalPad(*(GetALTROMasked() )));
2195 //QA
2196 AliTPCdataQA *dataQA=GetDataQA();
2197 if (dataQA) {
2198 if (dataQA->GetNLocalMaxima())
2199 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNLocalMaxima())));
2200 if (dataQA->GetMaxCharge())
2201 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMaxCharge())));
2202 if (dataQA->GetMeanCharge())
2203 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMeanCharge())));
2204 if (dataQA->GetNoThreshold())
2205 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNoThreshold())));
2206 if (dataQA->GetNTimeBins())
2207 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNTimeBins())));
2208 if (dataQA->GetNPads())
2209 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNPads())));
2210 if (dataQA->GetTimePosition())
2211 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetTimePosition())));
2212 }
2213
5312f439 2214 //
2215 TString file(filename);
2b4c6ff5 2216 if (file.IsNull()) file=Form("guiTreeRun_%i.root",fRun);
5312f439 2217 prep.DumpToFile(file.Data());
2218 return kTRUE;
2219}
e2914767 2220
7390f655 2221Bool_t AliTPCcalibDB::CreateRefFile(Int_t run, const char* filename)
2222{
2223 //
2224 // Create a gui tree for run number 'run'
2225 //
2226
2227 if (!AliCDBManager::Instance()->GetDefaultStorage()){
2228 AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
2229 MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
2230 return kFALSE;
2231 }
2232 TString file(filename);
2233 if (file.IsNull()) file=Form("RefCalPads_%d.root",run);
2234 TDirectory *currDir=gDirectory;
2235 //db instance
2236 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
2237 // retrieve cal pad objects
2238 db->SetRun(run);
2239 //open file
2240 TFile f(file.Data(),"recreate");
2241 //noise and pedestals
2242 db->GetPedestals()->Write("Pedestals");
2243 db->GetPadNoise()->Write("PadNoise");
2244 //pulser data
2245 db->GetPulserTmean()->Write("PulserTmean");
2246 db->GetPulserTrms()->Write("PulserTrms");
2247 db->GetPulserQmean()->Write("PulserQmean");
2248 //CE data
2249 db->GetCETmean()->Write("CETmean");
2250 db->GetCETrms()->Write("CETrms");
2251 db->GetCEQmean()->Write("CEQmean");
2252 //Altro data
2253 db->GetALTROAcqStart() ->Write("ALTROAcqStart");
2254 db->GetALTROZsThr() ->Write("ALTROZsThr");
2255 db->GetALTROFPED() ->Write("ALTROFPED");
2256 db->GetALTROAcqStop() ->Write("ALTROAcqStop");
2257 db->GetALTROMasked() ->Write("ALTROMasked");
2258 //
2259 f.Close();
2260 currDir->cd();
2261 return kTRUE;
2262}
17c90083 2263
2264
2265
817766d5 2266Double_t AliTPCcalibDB::GetVDriftCorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
17c90083 2267 //
2268 // Get time dependent drift velocity correction
2269 // multiplication factor vd = vdnom *(1+vdriftcorr)
2270 // Arguments:
2271 // mode determines the algorith how to combine the Laser Track, LaserCE and physics tracks
2272 // timestamp - timestamp
2273 // run - run number
2274 // side - the drift velocity per side (possible for laser and CE)
2275 //
2276 // Notice - Extrapolation outside of calibration range - using constant function
2277 //
b7c5eb40 2278 Double_t result=0;
1e722a63 2279 // mode 1 automatic mode - according to the distance to the valid calibration
2280 // -
cc65e4f5 2281 Double_t deltaP=0, driftP=0, wP = 0.;
2282 Double_t deltaITS=0,driftITS=0, wITS= 0.;
2283 Double_t deltaLT=0, driftLT=0, wLT = 0.;
2284 Double_t deltaCE=0, driftCE=0, wCE = 0.;
1e722a63 2285 driftP = fDButil->GetVDriftTPC(deltaP,run,timeStamp);
cc65e4f5 2286 driftITS= fDButil->GetVDriftTPCITS(deltaITS,run,timeStamp);
1e722a63 2287 driftCE = fDButil->GetVDriftTPCCE(deltaCE, run,timeStamp,36000,2);
2288 driftLT = fDButil->GetVDriftTPCLaserTracks(deltaLT,run,timeStamp,36000,2);
cc65e4f5 2289 deltaITS = TMath::Abs(deltaITS);
1e722a63 2290 deltaP = TMath::Abs(deltaP);
2291 deltaLT = TMath::Abs(deltaLT);
2292 deltaCE = TMath::Abs(deltaCE);
2293 if (mode==1) {
cc65e4f5 2294 const Double_t kEpsilon=0.00000000001;
2295 const Double_t kdeltaT=360.; // 10 minutes
a52d8b6f 2296 if(TMath::Abs(deltaITS) < 12*kdeltaT) {
5647625c 2297 result = driftITS;
2298 } else {
cc65e4f5 2299 wITS = 64.*kdeltaT/(deltaITS +kdeltaT);
2300 wLT = 16.*kdeltaT/(deltaLT +kdeltaT);
2301 wP = 0. *kdeltaT/(deltaP +kdeltaT);
2302 wCE = 1. *kdeltaT/(deltaCE +kdeltaT);
2303 //
2304 //
2305 if (TMath::Abs(driftP)<kEpsilon) wP=0; // invalid calibration
2306 if (TMath::Abs(driftITS)<kEpsilon)wITS=0; // invalid calibration
2307 if (TMath::Abs(driftLT)<kEpsilon) wLT=0; // invalid calibration
1e722a63 2308 if (TMath::Abs(driftCE)<kEpsilon) wCE=0; // invalid calibration
cc65e4f5 2309 if (wP+wITS+wLT+wCE<kEpsilon) return 0;
2310 result = (driftP*wP+driftITS*wITS+driftLT*wLT+driftCE*wCE)/(wP+wITS+wLT+wCE);
5647625c 2311 }
2312
2313
43a74775 2314 }
817766d5 2315
43a74775 2316 return result;
17c90083 2317}
2318
817766d5 2319Double_t AliTPCcalibDB::GetTime0CorrectionTime(Int_t timeStamp, Int_t run, Int_t /*side*/, Int_t mode){
17c90083 2320 //
43a74775 2321 // Get time dependent time 0 (trigger delay in cm) correction
17c90083 2322 // additive correction time0 = time0+ GetTime0CorrectionTime
2323 // Value etracted combining the vdrift correction using laser tracks and CE and the physics track matchin
2324 // Arguments:
2325 // mode determines the algorith how to combine the Laser Track and physics tracks
2326 // timestamp - timestamp
2327 // run - run number
2328 // side - the drift velocity per side (possible for laser and CE)
2329 //
2330 // Notice - Extrapolation outside of calibration range - using constant function
2331 //
817766d5 2332 Double_t result=0;
cc65e4f5 2333 if (mode==2) {
2334 // TPC-TPC mode
2335 result=fDButil->GetTriggerOffsetTPC(run,timeStamp);
2336 result *=fParam->GetZLength();
2337 }
2338 if (mode==1){
2339 // TPC-ITS mode
2340 Double_t dist=0;
86c39d37 2341 result= -fDButil->GetTime0TPCITS(dist, run, timeStamp)*fParam->GetDriftV()/1000000.;
cc65e4f5 2342 }
817766d5 2343 return result;
43a74775 2344
17c90083 2345}
2346
2347
2348
2349
43a74775 2350Double_t AliTPCcalibDB::GetVDriftCorrectionGy(Int_t timeStamp, Int_t run, Int_t side, Int_t /*mode*/){
17c90083 2351 //
2352 // Get global y correction drift velocity correction factor
2353 // additive factor vd = vdnom*(1+GetVDriftCorrectionGy *gy)
5647625c 2354 // Value etracted combining the vdrift correction using laser tracks and CE or TPC-ITS
17c90083 2355 // Arguments:
5647625c 2356 // mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
17c90083 2357 // timestamp - timestamp
2358 // run - run number
2359 // side - the drift velocity gy correction per side (CE and Laser tracks)
2360 //
2361 // Notice - Extrapolation outside of calibration range - using constant function
a8f8b6a1 2362 //
2363 if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
2364 UpdateRunInformations(run,kFALSE);
43a74775 2365 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
4429bfef 2366 if (!array) return 0;
5647625c 2367 Double_t result=0;
2368
2369 // use TPC-ITS if present
2370 TGraphErrors *gr= (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_VDGY");
3760239f 2371 if (!gr) gr = (TGraphErrors*)array->FindObject("ALIGN_TOFB_TPC_VDGY");
5647625c 2372 if(gr) {
0fc78dbd 2373 result = AliTPCcalibDButil::EvalGraphConst(gr,timeStamp);
5647625c 2374
2375 // transform from [(cm/mus)/ m] to [1/cm]
2376 result /= (fParam->GetDriftV()/1000000.);
2377 result /= 100.;
2378
2379 //printf("result %e \n", result);
2380 return result;
2381 }
2382
2383 // use laser if ITS-TPC not present
43a74775 2384 TGraphErrors *laserA= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_A");
2385 TGraphErrors *laserC= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_C");
2386
43a74775 2387 if (laserA && laserC){
2388 result= (laserA->Eval(timeStamp)+laserC->Eval(timeStamp))*0.5;
2389 }
2390 if (laserA && side==0){
2391 result = (laserA->Eval(timeStamp));
2392 }
2393 if (laserC &&side==1){
2394 result = (laserC->Eval(timeStamp));
2395 }
5647625c 2396 //printf("laser result %e \n", -result/250.);
2397
43a74775 2398 return -result/250.; //normalized before
17c90083 2399}
949d8707 2400
e185e9d8 2401
2402Double_t AliTPCcalibDB::GetVDriftCorrectionDeltaZ(Int_t /*timeStamp*/, Int_t run, Int_t /*side*/, Int_t /*mode*/){
2403 //
2404 // Get deltaZ run/by/run correction - as fitted together with drift velocity
2405 // Value extracted form the TPC-ITS, mean value is used
2406
2407 // Arguments:
2408 // mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
00e32b66 2409 // timestamp - not used
e185e9d8 2410 // run - run number
00e32b66 2411 // side - common for boith sides
e185e9d8 2412 //
2413 if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
2414 UpdateRunInformations(run,kFALSE);
2415 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2416 if (!array) return 0;
2417 Double_t result=0;
2418
2419 // use TPC-ITS if present
2420 TGraphErrors *gr= (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_DELTAZ");
2421 if(gr) {
2422 result = TMath::Mean(gr->GetN(), gr->GetY());
2423 }
2424 return result;
2425}
2426
2427
2428
2429
72b94ffb 2430AliTPCCalPad* AliTPCcalibDB::MakeDeadMap(Double_t notInMap, const char* nameMappingFile) {
f6b5fa33 2431//
2432// Read list of active DDLs from OCDB entry
2433// Generate and return AliTPCCalPad containing 1 for all pads in active DDLs,
2434// 0 for all pads in non-active DDLs.
72b94ffb 2435// For DDLs with missing status information (no DCS input point to Shuttle),
2436// the value of the AliTPCCalPad entry is determined by the parameter
2437// notInMap (default value 1)
f6b5fa33 2438//
2439 char chinfo[1000];
2440
2441 TFile *fileMapping = new TFile(nameMappingFile, "read");
2442 AliTPCmapper *mapping = (AliTPCmapper*) fileMapping->Get("tpcMapping");
2443 if (!mapping) {
4aa37f93 2444 snprintf(chinfo,1000,"Failed to get mapping object from %s. ...\n", nameMappingFile);
f6b5fa33 2445 AliError (chinfo);
2446 return 0;
2447 }
2448
2449 AliTPCCalPad *deadMap = new AliTPCCalPad("deadMap","deadMap");
2450 if (!deadMap) {
2451 AliError("Failed to allocate dead map AliTPCCalPad");
2452 return 0;
2453 }
2454
2455 /// get list of active DDLs from OCDB entry
2456 Int_t idDDL=0;
2457 if (!fALTROConfigData ) {
2458 AliError("No ALTRO config OCDB entry available");
2459 return 0;
2460 }
2461 TMap *activeDDL = (TMap*)fALTROConfigData->FindObject("DDLArray");
2462 TObjString *ddlArray=0;
2463 if (activeDDL) {
2464 ddlArray = (TObjString*)activeDDL->GetValue("DDLArray");
2465 if (!ddlArray) {
2466 AliError("Empty list of active DDLs in OCDB entry");
2467 return 0;
2468 }
2469 } else {
2470 AliError("List of active DDLs not available in OCDB entry");
2471 return 0;
2472 }
2473 TString arrDDL=ddlArray->GetString();
2474 Int_t offset = mapping->GetTpcDdlOffset();
2475 Double_t active;
2476 for (Int_t i=0; i<mapping->GetNumDdl(); i++) {
2477 idDDL= i+offset;
d150d64f 2478 if (idDDL<0) continue;
f6b5fa33 2479 Int_t patch = mapping->GetPatchFromEquipmentID(idDDL);
9f98a33d 2480 if (patch<0) continue;
f6b5fa33 2481 Int_t roc=mapping->GetRocFromEquipmentID(idDDL);
55d90f9a 2482 if (roc<0) continue;
f6b5fa33 2483 AliTPCCalROC *calRoc=deadMap->GetCalROC(roc);
2484 if (calRoc) {
2485 for ( Int_t branch = 0; branch < 2; branch++ ) {
2486 for ( Int_t fec = 0; fec < mapping->GetNfec(patch, branch); fec++ ) {
2487 for ( Int_t altro = 0; altro < 8; altro++ ) {
2488 for ( Int_t channel = 0; channel < 16; channel++ ) {
2489 Int_t hwadd = mapping->CodeHWAddress(branch, fec, altro, channel);
2490 Int_t row = mapping->GetPadRow(patch, hwadd); // row in a ROC (IROC or OROC)
2491// Int_t globalrow = mapping.GetGlobalPadRow(patch, hwadd); // row in full sector (IROC plus OROC)
2492 Int_t pad = mapping->GetPad(patch, hwadd);
72b94ffb 2493 if (!TString(arrDDL[i]).IsDigit()) {
2494 active = notInMap;
2495 } else {
2496 active=TString(arrDDL[i]).Atof();
2497 }
f6b5fa33 2498 calRoc->SetValue(row,pad,active);
2499 } // end channel for loop
2500 } // end altro for loop
2501 } // end fec for loop
2502 } // end branch for loop
2503 } // valid calROC
2504 } // end loop on active DDLs
2505 return deadMap;
2506}
f14d21a1 2507
2508
0b736a46 2509
2510AliTPCCorrection * AliTPCcalibDB::GetTPCComposedCorrection(Float_t field) const{
2511 //
2512 // GetComposed correction for given field setting
3f3549a3 2513 // If not specific correction for field used return correction for all field
2514 // - Complication needed to gaurantee OCDB back compatibility
2515 // - Not neeeded for the new space point correction
0b736a46 2516 if (!fComposedCorrectionArray) return 0;
3f3549a3 2517 if (field>0.1 && fComposedCorrectionArray->At(1)) {
2518 return (AliTPCCorrection *)fComposedCorrectionArray->At(1);
2519 }
2520 if (field<-0.1 &&fComposedCorrectionArray->At(2)) {
2521 return (AliTPCCorrection *)fComposedCorrectionArray->At(2);
2522 }
0b736a46 2523 return (AliTPCCorrection *)fComposedCorrectionArray->At(0);
2524
2525}
2526
3f3549a3 2527
2528AliTPCCorrection * AliTPCcalibDB::GetTPCComposedCorrectionDelta() const{
2529 //
2530 // GetComposedCorrection delta
2531 // Delta is time dependent - taken form the CalibTime OCDB entry
2532 //
2533 if (!fComposedCorrectionArray) return 0;
a8ef8a9c 2534 if (fRun<0) return 0;
2b4c6ff5 2535 if (fDriftCorrectionArray.GetValue(Form("%i",fRun))==0) return 0;
012c4694 2536 if (fComposedCorrectionArray->GetEntriesFast()<=4) {
2537 fComposedCorrectionArray->Expand(5);
2b4c6ff5 2538 TObjArray * timeArray =(TObjArray*)(fDriftCorrectionArray.GetValue(Form("%i",fRun)));
a8ef8a9c 2539 AliTPCCorrection * correctionTime = (AliTPCCorrection *)timeArray->FindObject("FitCorrectionTime");
2540 if (correctionTime){
2541 correctionTime->Init();
2542 fComposedCorrectionArray->AddAt(correctionTime,4); //add time dependent c
2543 }
2544 }
3f3549a3 2545 return (AliTPCCorrection *)fComposedCorrectionArray->At(4); //
2546}
2547
00e32b66 2548Double_t AliTPCcalibDB::GetGainCorrectionHVandPT(Int_t timeStamp, Int_t run, Int_t sector, Int_t deltaCache, Int_t mode){
e185e9d8 2549 //
2550 // Correction for changes of gain caused by change of the HV and by relative change of the gas density
2551 // Function is slow some kind of caching needed
2552 // Cache implemented using the static TVectorD
2553 //
2554 // Input paremeters:
2555 // deltaCache - maximal time differnce above which the cache is recaclulated
00e32b66 2556 // mode - mode==0 by default return combined correction
2557 // actual HV and Pt correction has to be present in the run calibration otherwise it is ignored.
9198ac8a 2558 // (retrun value differnt than 1 only in case calibration present in the OCDB entry CalibTimeGain
00e32b66 2559 // mode==1 return combined correction ( important for calibration pass)
9198ac8a 2560 // (in case thereis no calibration in CalibTimeGain, default value from the AliTPCParam (Parameters) is used
2561 // this mode is used in the CPass0
00e32b66 2562 // mode==2 return HV correction
2563 // mode==3 return P/T correction
2564 // Usage in the simulation/reconstruction
2565 // MC: Qcorr = Qorig*GetGainCorrectionHVandPT ( in AliTPC.cxx )
2566 // Rec: dEdx = dEdx/GetGainCorrectionHVandPT ( in aliTPCseed.cxx )
2567 //
3d674021 2568 static Float_t gGainCorrection[72];
2569 static Float_t gGainCorrectionPT[72];
2570 static Float_t gGainCorrectionHV[72];
9198ac8a 2571 static Int_t gTimeStamp=-99999999;
00e32b66 2572 static Bool_t hasTimeDependent=kFALSE;
e185e9d8 2573 if ( TMath::Abs(timeStamp-gTimeStamp)> deltaCache){
2574 //
2575 TGraphErrors * graphGHV = 0;
2576 TGraphErrors * graphGPT = 0;
2577 TObjArray *timeGainSplines = GetTimeGainSplinesRun(run);
00e32b66 2578 if (timeGainSplines){
2579 graphGHV = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesHV");
2580 graphGPT = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesPT");
2581 if (graphGHV) hasTimeDependent=kTRUE;
2582 }
e185e9d8 2583 if (!graphGHV) graphGHV = fParam->GetGainSlopesHV();
2584 if (!graphGPT) graphGPT = fParam->GetGainSlopesPT();
2585 //
2586 for (Int_t isec=0; isec<72; isec++){
2587 Double_t deltaHV= GetChamberHighVoltage(run,isec, timeStamp) - fParam->GetNominalVoltage(isec);
2588 Double_t deltaGHV=0;
2589 Double_t deltaGPT=0;
2590 if (graphGHV) deltaGHV = graphGHV->GetY()[isec]*deltaHV;
2591 if (graphGPT) deltaGPT = graphGPT->GetY()[isec]*GetPTRelative(timeStamp,run,0);
00e32b66 2592 gGainCorrection[isec]=(1.+deltaGHV)*(1.+deltaGPT);
3d674021 2593 gGainCorrectionPT[isec]=1+deltaGPT;
2594 gGainCorrectionHV[isec]=1+deltaGHV;
e185e9d8 2595 }
2596 gTimeStamp=timeStamp;
2597 }
00e32b66 2598 if (mode==0){
2599 if (hasTimeDependent) return gGainCorrection[sector];
3d674021 2600 if (!hasTimeDependent) return 1;
00e32b66 2601 }
2602 if (mode==1) return gGainCorrection[sector];
2603 if (mode==2) return gGainCorrectionPT[sector];
2604 if (mode==3) return gGainCorrectionHV[sector];
3d674021 2605 return 1;
e185e9d8 2606}