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