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