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