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