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