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