TOF residual information update: added also rhoXphi residuals (i.e. residuals in...
[u/mrichter/AliRoot.git] / TPC / 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
29// Reconstruction - AliTPCclustererMI::Digits2Clusters(AliRawReader* rawReader)
30//
1ac191a6 31// 1.) pad by pad calibration - AliTPCCalPad
f5344549 32//
1ac191a6 33// a.) fPadGainFactor
34// Simulation: AliTPCDigitizer::ExecFast - Multiply by gain
35// Reconstruction : AliTPCclustererMI::Digits2Clusters - Divide by gain
f5344549 36//
1ac191a6 37// b.) fPadNoise -
38// Simulation: AliTPCDigitizer::ExecFast
39// Reconstruction: AliTPCclustererMI::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
43// Reconstruction: Used in AliTPCclustererMI::Digits2Clusters(AliRawReader* rawReader)
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
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 -
63// AliTPCclustererMI::AddCluster
64// AliTPCtrackerMI::Transform
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>
85#include <AliLog.h>
3ac615eb 86#include <AliMagF.h>
7fff7612 87#include <AliSplineFit.h>
c5bbaa2c 88
89#include "AliTPCcalibDB.h"
d6834f5f 90#include "AliTPCAltroMapping.h"
418bbcaf 91#include "AliTPCExB.h"
c5bbaa2c 92
93#include "AliTPCCalROC.h"
94#include "AliTPCCalPad.h"
54472e4f 95#include "AliTPCSensorTempArray.h"
bf85fe4d 96#include "AliGRPObject.h"
418bbcaf 97#include "AliTPCTransform.h"
d6834f5f 98
418bbcaf 99class AliCDBStorage;
100class AliTPCCalDet;
86df2b3a 101//
102//
103
86df2b3a 104#include "TFile.h"
105#include "TKey.h"
43a74775 106#include "TGraphErrors.h"
86df2b3a 107
108#include "TObjArray.h"
109#include "TObjString.h"
110#include "TString.h"
7390f655 111#include "TDirectory.h"
86df2b3a 112#include "AliTPCCalPad.h"
0fe7645c 113#include "AliTPCCalibPulser.h"
86df2b3a 114#include "AliTPCCalibPedestal.h"
115#include "AliTPCCalibCE.h"
3ac615eb 116#include "AliTPCExBFirst.h"
bf85fe4d 117#include "AliTPCTempMap.h"
da6c0bc9 118#include "AliTPCCalibVdrift.h"
6e7d7dc4 119#include "AliTPCCalibRaw.h"
43a74775 120#include "AliTPCParam.h"
86df2b3a 121
5312f439 122#include "AliTPCPreprocessorOnline.h"
86df2b3a 123
c5bbaa2c 124
125ClassImp(AliTPCcalibDB)
126
127AliTPCcalibDB* AliTPCcalibDB::fgInstance = 0;
128Bool_t AliTPCcalibDB::fgTerminated = kFALSE;
3ac615eb 129TObjArray AliTPCcalibDB::fgExBArray; // array of ExB corrections
c5bbaa2c 130
131
132//_ singleton implementation __________________________________________________
133AliTPCcalibDB* AliTPCcalibDB::Instance()
134{
135 //
136 // Singleton implementation
137 // Returns an instance of this class, it is created if neccessary
138 //
139
140 if (fgTerminated != kFALSE)
141 return 0;
142
143 if (fgInstance == 0)
144 fgInstance = new AliTPCcalibDB();
145
146 return fgInstance;
147}
148
149void AliTPCcalibDB::Terminate()
150{
151 //
152 // Singleton implementation
153 // Deletes the instance of this class and sets the terminated flag, instances cannot be requested anymore
154 // This function can be called several times.
155 //
156
157 fgTerminated = kTRUE;
158
159 if (fgInstance != 0)
160 {
161 delete fgInstance;
162 fgInstance = 0;
163 }
164}
165
166//_____________________________________________________________________________
e4dce695 167AliTPCcalibDB::AliTPCcalibDB():
9389f9a4 168 TObject(),
e4dce695 169 fRun(-1),
f5344549 170 fTransform(0),
481f877b 171 fExB(0),
e4dce695 172 fPadGainFactor(0),
9f6e9f81 173 fDedxGainFactor(0),
e4dce695 174 fPadTime0(0),
e4dce695 175 fPadNoise(0),
176 fPedestals(0),
6e7d7dc4 177 fCalibRaw(0),
5312f439 178 fALTROConfigData(0),
179 fPulserData(0),
180 fCEData(0),
e4dce695 181 fTemperature(0),
d6834f5f 182 fMapping(0),
96305e49 183 fParam(0),
a2c3785e 184 fClusterParam(0),
185 fTimeGainSplines(0),
186 fTimeGainSplinesArray(100000),
da6c0bc9 187 fGRPArray(100000), //! array of GRPs - per run - JUST for calibration studies
0231c65f 188 fGRPMaps(100000), //! array of GRPs - per run - JUST for calibration studies
da6c0bc9 189 fGoofieArray(100000), //! array of GOOFIE values -per run - Just for calibration studies
e2914767 190 fVoltageArray(100000),
da6c0bc9 191 fTemperatureArray(100000), //! array of temperature sensors - per run - Just for calibration studies
192 fVdriftArray(100000), //! array of v drift interfaces
5e1215d4 193 fDriftCorrectionArray(100000), //! array of drift correction
bf85fe4d 194 fRunList(100000) //! run list - indicates try to get the run param
195
c5bbaa2c 196{
197 //
198 // constructor
199 //
54472e4f 200 //
c5bbaa2c 201 Update(); // temporary
202}
203
9389f9a4 204AliTPCcalibDB::AliTPCcalibDB(const AliTPCcalibDB& ):
205 TObject(),
206 fRun(-1),
207 fTransform(0),
208 fExB(0),
209 fPadGainFactor(0),
9f6e9f81 210 fDedxGainFactor(0),
9389f9a4 211 fPadTime0(0),
212 fPadNoise(0),
213 fPedestals(0),
6e7d7dc4 214 fCalibRaw(0),
5312f439 215 fALTROConfigData(0),
216 fPulserData(0),
217 fCEData(0),
9389f9a4 218 fTemperature(0),
219 fMapping(0),
9389f9a4 220 fParam(0),
bf85fe4d 221 fClusterParam(0),
a2c3785e 222 fTimeGainSplines(0),
223 fTimeGainSplinesArray(100000),
bf85fe4d 224 fGRPArray(0), //! array of GRPs - per run - JUST for calibration studies
0231c65f 225 fGRPMaps(0), //! array of GRPs - per run - JUST for calibration studies
bf85fe4d 226 fGoofieArray(0), //! array of GOOFIE values -per run - Just for calibration studies
e2914767 227 fVoltageArray(0),
bf85fe4d 228 fTemperatureArray(0), //! array of temperature sensors - per run - Just for calibration studies
da6c0bc9 229 fVdriftArray(0), //! array of v drift interfaces
5e1215d4 230 fDriftCorrectionArray(0), //! array of v drift interfaces
bf85fe4d 231 fRunList(0) //! run list - indicates try to get the run param
9389f9a4 232{
233 //
234 // Copy constructor invalid -- singleton implementation
235 //
236 Error("copy constructor","invalid -- singleton implementation");
237}
238
239AliTPCcalibDB& AliTPCcalibDB::operator= (const AliTPCcalibDB& )
240{
241//
242// Singleton implementation - no assignment operator
243//
244 Error("operator =", "assignment operator not implemented");
245 return *this;
246}
247
248
249
c5bbaa2c 250//_____________________________________________________________________________
251AliTPCcalibDB::~AliTPCcalibDB()
252{
253 //
254 // destructor
255 //
68751c2c 256
257 // don't delete anything, CDB cache is active!
258 //if (fPadGainFactor) delete fPadGainFactor;
259 //if (fPadTime0) delete fPadTime0;
68751c2c 260 //if (fPadNoise) delete fPadNoise;
c5bbaa2c 261}
262
263
264//_____________________________________________________________________________
265AliCDBEntry* AliTPCcalibDB::GetCDBEntry(const char* cdbPath)
266{
267 //
268 // Retrieves an entry with path <cdbPath> from the CDB.
269 //
270 char chinfo[1000];
271
68751c2c 272 AliCDBEntry* entry = AliCDBManager::Instance()->Get(cdbPath, fRun);
c5bbaa2c 273 if (!entry)
274 {
275 sprintf(chinfo,"AliTPCcalibDB: Failed to get entry:\t%s ", cdbPath);
276 AliError(chinfo);
277 return 0;
278 }
279 return entry;
280}
281
282
283//_____________________________________________________________________________
284void AliTPCcalibDB::SetRun(Long64_t run)
285{
286 //
287 // Sets current run number. Calibration data is read from the corresponding file.
288 //
289 if (fRun == run)
290 return;
a2c3785e 291 fRun = run;
c5bbaa2c 292 Update();
293}
294
295
296
297void AliTPCcalibDB::Update(){
a2c3785e 298 //
a8f8b6a1 299 AliCDBEntry * entry=0;
68751c2c 300 Bool_t cdbCache = AliCDBManager::Instance()->GetCacheFlag(); // save cache status
301 AliCDBManager::Instance()->SetCacheFlag(kTRUE); // activate CDB cache
302
c5bbaa2c 303 //
304 entry = GetCDBEntry("TPC/Calib/PadGainFactor");
305 if (entry){
68751c2c 306 //if (fPadGainFactor) delete fPadGainFactor;
c5bbaa2c 307 entry->SetOwner(kTRUE);
308 fPadGainFactor = (AliTPCCalPad*)entry->GetObject();
309 }
310 //
3af3fbc4 311 entry = GetCDBEntry("TPC/Calib/TimeGain");
312 if (entry){
313 //if (fTimeGainSplines) delete fTimeGainSplines;
314 entry->SetOwner(kTRUE);
315 fTimeGainSplines = (TObjArray*)entry->GetObject();
316 }
317 //
9f6e9f81 318 entry = GetCDBEntry("TPC/Calib/GainFactorDedx");
319 if (entry){
320 entry->SetOwner(kTRUE);
321 fDedxGainFactor = (AliTPCCalPad*)entry->GetObject();
322 }
323 //
c5bbaa2c 324 entry = GetCDBEntry("TPC/Calib/PadTime0");
325 if (entry){
68751c2c 326 //if (fPadTime0) delete fPadTime0;
c5bbaa2c 327 entry->SetOwner(kTRUE);
328 fPadTime0 = (AliTPCCalPad*)entry->GetObject();
329 }
330 //
c5bbaa2c 331 //
332 entry = GetCDBEntry("TPC/Calib/PadNoise");
333 if (entry){
68751c2c 334 //if (fPadNoise) delete fPadNoise;
c5bbaa2c 335 entry->SetOwner(kTRUE);
336 fPadNoise = (AliTPCCalPad*)entry->GetObject();
337 }
8477f500 338
339 entry = GetCDBEntry("TPC/Calib/Pedestals");
340 if (entry){
341 //if (fPedestals) delete fPedestals;
342 entry->SetOwner(kTRUE);
343 fPedestals = (AliTPCCalPad*)entry->GetObject();
344 }
345
54472e4f 346 entry = GetCDBEntry("TPC/Calib/Temperature");
347 if (entry){
348 //if (fTemperature) delete fTemperature;
349 entry->SetOwner(kTRUE);
350 fTemperature = (AliTPCSensorTempArray*)entry->GetObject();
351 }
352
8477f500 353 entry = GetCDBEntry("TPC/Calib/Parameters");
354 if (entry){
54472e4f 355 //if (fPadNoise) delete fPadNoise;
8477f500 356 entry->SetOwner(kTRUE);
a778f7e3 357 fParam = (AliTPCParam*)(entry->GetObject()->Clone());
8477f500 358 }
359
96305e49 360 entry = GetCDBEntry("TPC/Calib/ClusterParam");
361 if (entry){
96305e49 362 entry->SetOwner(kTRUE);
363 fClusterParam = (AliTPCClusterParam*)(entry->GetObject()->Clone());
364 }
365
5312f439 366 //ALTRO configuration data
367 entry = GetCDBEntry("TPC/Calib/AltroConfig");
368 if (entry){
369 entry->SetOwner(kTRUE);
370 fALTROConfigData=(TObjArray*)(entry->GetObject());
371 }
372
373 //Calibration Pulser data
374 entry = GetCDBEntry("TPC/Calib/Pulser");
375 if (entry){
376 entry->SetOwner(kTRUE);
377 fPulserData=(TObjArray*)(entry->GetObject());
378 }
379
380 //CE data
381 entry = GetCDBEntry("TPC/Calib/CE");
382 if (entry){
383 entry->SetOwner(kTRUE);
384 fCEData=(TObjArray*)(entry->GetObject());
385 }
6e7d7dc4 386 //RAW calibration data
387 entry = GetCDBEntry("TPC/Calib/Raw");
388 if (entry){
389 entry->SetOwner(kTRUE);
390 TObjArray *arr=(TObjArray*)(entry->GetObject());
391 if (arr) fCalibRaw=(AliTPCCalibRaw*)arr->At(0);
392 }
5312f439 393
d6834f5f 394 entry = GetCDBEntry("TPC/Calib/Mapping");
395 if (entry){
396 //if (fPadNoise) delete fPadNoise;
397 entry->SetOwner(kTRUE);
398 TObjArray * array = dynamic_cast<TObjArray*>(entry->GetObject());
399 if (array && array->GetEntriesFast()==6){
400 fMapping = new AliTPCAltroMapping*[6];
401 for (Int_t i=0; i<6; i++){
5312f439 402 fMapping[i] = dynamic_cast<AliTPCAltroMapping*>(array->At(i));
d6834f5f 403 }
404 }
405 }
406
407
408
3ac615eb 409 //entry = GetCDBEntry("TPC/Calib/ExB");
410 //if (entry) {
411 // entry->SetOwner(kTRUE);
412 // fExB=dynamic_cast<AliTPCExB*>(entry->GetObject()->Clone());
413 //}
414 //
3a3318d5 415 // ExB - calculate during initialization - in simulation /reconstruction
416 // - not invoked here anymore
417 //fExB = GetExB(-5,kTRUE);
f4d5fd21 418 //
f5344549 419 if (!fTransform) {
420 fTransform=new AliTPCTransform();
bfec3eeb 421 fTransform->SetCurrentRun(AliCDBManager::Instance()->GetRun());
f5344549 422 }
8477f500 423
c5bbaa2c 424 //
68751c2c 425 AliCDBManager::Instance()->SetCacheFlag(cdbCache); // reset original CDB cache
c5bbaa2c 426}
e4dce695 427
86df2b3a 428
429
430void AliTPCcalibDB::CreateObjectList(const Char_t *filename, TObjArray *calibObjects)
431{
418bbcaf 432//
433// Create calibration objects and read contents from OCDB
434//
86df2b3a 435 if ( calibObjects == 0x0 ) return;
436 ifstream in;
437 in.open(filename);
438 if ( !in.is_open() ){
439 fprintf(stderr,"Error: cannot open list file '%s'", filename);
440 return;
441 }
442
443 AliTPCCalPad *calPad=0x0;
444
445 TString sFile;
446 sFile.ReadFile(in);
447 in.close();
448
449 TObjArray *arrFileLine = sFile.Tokenize("\n");
450
451 TIter nextLine(arrFileLine);
452
453 TObjString *sObjLine=0x0;
2c632057 454 while ( (sObjLine = (TObjString*)nextLine()) ){
86df2b3a 455 TString sLine(sObjLine->GetString());
456
457 TObjArray *arrNextCol = sLine.Tokenize("\t");
458
459 TObjString *sObjType = (TObjString*)(arrNextCol->At(0));
460 TObjString *sObjFileName = (TObjString*)(arrNextCol->At(1));
461
462 if ( !sObjType || ! sObjFileName ) continue;
463 TString sType(sObjType->GetString());
464 TString sFileName(sObjFileName->GetString());
465 printf("%s\t%s\n",sType.Data(),sFileName.Data());
466
467 TFile *fIn = TFile::Open(sFileName);
468 if ( !fIn ){
469 fprintf(stderr,"File not found: '%s'", sFileName.Data());
470 continue;
471 }
472
473 if ( sType == "CE" ){
474 AliTPCCalibCE *ce = (AliTPCCalibCE*)fIn->Get("AliTPCCalibCE");
475
476 calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadT0());
477 calPad->SetNameTitle("CETmean","CETmean");
478 calibObjects->Add(calPad);
479
480 calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadQ());
481 calPad->SetNameTitle("CEQmean","CEQmean");
482 calibObjects->Add(calPad);
483
484 calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadRMS());
485 calPad->SetNameTitle("CETrms","CETrms");
486 calibObjects->Add(calPad);
487
488 } else if ( sType == "Pulser") {
0fe7645c 489 AliTPCCalibPulser *sig = (AliTPCCalibPulser*)fIn->Get("AliTPCCalibPulser");
86df2b3a 490
491 calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadT0());
492 calPad->SetNameTitle("PulserTmean","PulserTmean");
493 calibObjects->Add(calPad);
494
495 calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadQ());
496 calPad->SetNameTitle("PulserQmean","PulserQmean");
497 calibObjects->Add(calPad);
498
499 calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadRMS());
500 calPad->SetNameTitle("PulserTrms","PulserTrms");
501 calibObjects->Add(calPad);
502
503 } else if ( sType == "Pedestals") {
504 AliTPCCalibPedestal *ped = (AliTPCCalibPedestal*)fIn->Get("AliTPCCalibPedestal");
505
506 calPad = new AliTPCCalPad((TObjArray*)ped->GetCalPadPedestal());
507 calPad->SetNameTitle("Pedestals","Pedestals");
508 calibObjects->Add(calPad);
509
510 calPad = new AliTPCCalPad((TObjArray*)ped->GetCalPadRMS());
511 calPad->SetNameTitle("Noise","Noise");
512 calibObjects->Add(calPad);
513
514 } else {
515 fprintf(stderr,"Undefined Type: '%s'",sType.Data());
516
517 }
518 delete fIn;
519 }
520}
521
522
523
524void AliTPCcalibDB::MakeTree(const char * fileName, TObjArray * array, const char * mapFileName, AliTPCCalPad* outlierPad, Float_t ltmFraction) {
525 //
526 // Write a tree with all available information
418bbcaf 527 // if mapFileName is specified, the Map information are also written to the tree
86df2b3a 528 // pads specified in outlierPad are not used for calculating statistics
529 // - the same function as AliTPCCalPad::MakeTree -
530 //
531 AliTPCROC* tpcROCinstance = AliTPCROC::Instance();
532
533 TObjArray* mapIROCs = 0;
534 TObjArray* mapOROCs = 0;
535 TVectorF *mapIROCArray = 0;
536 TVectorF *mapOROCArray = 0;
537 Int_t mapEntries = 0;
538 TString* mapNames = 0;
539
540 if (mapFileName) {
541 TFile mapFile(mapFileName, "read");
542
543 TList* listOfROCs = mapFile.GetListOfKeys();
544 mapEntries = listOfROCs->GetEntries()/2;
545 mapIROCs = new TObjArray(mapEntries*2);
546 mapOROCs = new TObjArray(mapEntries*2);
547 mapIROCArray = new TVectorF[mapEntries];
548 mapOROCArray = new TVectorF[mapEntries];
549
550 mapNames = new TString[mapEntries];
551 for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
418bbcaf 552 TString nameROC(((TKey*)(listOfROCs->At(ivalue*2)))->GetName());
553 nameROC.Remove(nameROC.Length()-4, 4);
554 mapIROCs->AddAt((AliTPCCalROC*)mapFile.Get((nameROC + "IROC").Data()), ivalue);
555 mapOROCs->AddAt((AliTPCCalROC*)mapFile.Get((nameROC + "OROC").Data()), ivalue);
556 mapNames[ivalue].Append(nameROC);
86df2b3a 557 }
558
559 for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
560 mapIROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(0));
561 mapOROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(36));
562
563 for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(0); ichannel++)
564 (mapIROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapIROCs->At(ivalue)))->GetValue(ichannel);
565 for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(36); ichannel++)
566 (mapOROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapOROCs->At(ivalue)))->GetValue(ichannel);
567 }
568
569 } // if (mapFileName)
570
571 TTreeSRedirector cstream(fileName);
572 Int_t arrayEntries = array->GetEntries();
573
574 TString* names = new TString[arrayEntries];
575 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
576 names[ivalue].Append(((AliTPCCalPad*)array->At(ivalue))->GetName());
577
578 for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++) {
579 //
580 // get statistic for given sector
581 //
582 TVectorF median(arrayEntries);
583 TVectorF mean(arrayEntries);
584 TVectorF rms(arrayEntries);
585 TVectorF ltm(arrayEntries);
586 TVectorF ltmrms(arrayEntries);
587 TVectorF medianWithOut(arrayEntries);
588 TVectorF meanWithOut(arrayEntries);
589 TVectorF rmsWithOut(arrayEntries);
590 TVectorF ltmWithOut(arrayEntries);
591 TVectorF ltmrmsWithOut(arrayEntries);
592
593 TVectorF *vectorArray = new TVectorF[arrayEntries];
594 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
595 vectorArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
596
597 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
598 AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
599 AliTPCCalROC* calROC = calPad->GetCalROC(isector);
600 AliTPCCalROC* outlierROC = 0;
601 if (outlierPad) outlierROC = outlierPad->GetCalROC(isector);
602 if (calROC) {
603 median[ivalue] = calROC->GetMedian();
604 mean[ivalue] = calROC->GetMean();
605 rms[ivalue] = calROC->GetRMS();
606 Double_t ltmrmsValue = 0;
607 ltm[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction);
608 ltmrms[ivalue] = ltmrmsValue;
609 if (outlierROC) {
610 medianWithOut[ivalue] = calROC->GetMedian(outlierROC);
611 meanWithOut[ivalue] = calROC->GetMean(outlierROC);
612 rmsWithOut[ivalue] = calROC->GetRMS(outlierROC);
613 ltmrmsValue = 0;
614 ltmWithOut[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction, outlierROC);
615 ltmrmsWithOut[ivalue] = ltmrmsValue;
616 }
617 }
618 else {
619 median[ivalue] = 0.;
620 mean[ivalue] = 0.;
621 rms[ivalue] = 0.;
622 ltm[ivalue] = 0.;
623 ltmrms[ivalue] = 0.;
624 medianWithOut[ivalue] = 0.;
625 meanWithOut[ivalue] = 0.;
626 rmsWithOut[ivalue] = 0.;
627 ltmWithOut[ivalue] = 0.;
628 ltmrmsWithOut[ivalue] = 0.;
629 }
630 }
631
632 //
633 // fill vectors of variable per pad
634 //
635 TVectorF *posArray = new TVectorF[8];
636 for (Int_t ivalue = 0; ivalue < 8; ivalue++)
637 posArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
638
639 Float_t posG[3] = {0};
640 Float_t posL[3] = {0};
641 Int_t ichannel = 0;
642 for (UInt_t irow = 0; irow < tpcROCinstance->GetNRows(isector); irow++) {
643 for (UInt_t ipad = 0; ipad < tpcROCinstance->GetNPads(isector, irow); ipad++) {
644 tpcROCinstance->GetPositionLocal(isector, irow, ipad, posL);
645 tpcROCinstance->GetPositionGlobal(isector, irow, ipad, posG);
646 posArray[0][ichannel] = irow;
647 posArray[1][ichannel] = ipad;
648 posArray[2][ichannel] = posL[0];
649 posArray[3][ichannel] = posL[1];
650 posArray[4][ichannel] = posG[0];
651 posArray[5][ichannel] = posG[1];
652 posArray[6][ichannel] = (Int_t)(ipad - (Double_t)(tpcROCinstance->GetNPads(isector, irow))/2);
653 posArray[7][ichannel] = ichannel;
654
655 // loop over array containing AliTPCCalPads
656 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
657 AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
658 AliTPCCalROC* calROC = calPad->GetCalROC(isector);
659 if (calROC)
660 (vectorArray[ivalue])[ichannel] = calROC->GetValue(irow, ipad);
661 else
662 (vectorArray[ivalue])[ichannel] = 0;
663 }
664 ichannel++;
665 }
666 }
667
668 cstream << "calPads" <<
669 "sector=" << isector;
670
671 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
672 cstream << "calPads" <<
673 (Char_t*)((names[ivalue] + "_Median=").Data()) << median[ivalue] <<
674 (Char_t*)((names[ivalue] + "_Mean=").Data()) << mean[ivalue] <<
675 (Char_t*)((names[ivalue] + "_RMS=").Data()) << rms[ivalue] <<
676 (Char_t*)((names[ivalue] + "_LTM=").Data()) << ltm[ivalue] <<
677 (Char_t*)((names[ivalue] + "_RMS_LTM=").Data()) << ltmrms[ivalue];
678 if (outlierPad) {
679 cstream << "calPads" <<
680 (Char_t*)((names[ivalue] + "_Median_OutlierCutted=").Data()) << medianWithOut[ivalue] <<
681 (Char_t*)((names[ivalue] + "_Mean_OutlierCutted=").Data()) << meanWithOut[ivalue] <<
682 (Char_t*)((names[ivalue] + "_RMS_OutlierCutted=").Data()) << rmsWithOut[ivalue] <<
683 (Char_t*)((names[ivalue] + "_LTM_OutlierCutted=").Data()) << ltmWithOut[ivalue] <<
684 (Char_t*)((names[ivalue] + "_RMS_LTM_OutlierCutted=").Data()) << ltmrmsWithOut[ivalue];
685 }
686 }
687
688 for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
689 cstream << "calPads" <<
690 (Char_t*)((names[ivalue] + ".=").Data()) << &vectorArray[ivalue];
691 }
692
693 if (mapFileName) {
694 for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
695 if (isector < 36)
696 cstream << "calPads" <<
697 (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapIROCArray[ivalue];
698 else
699 cstream << "calPads" <<
700 (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapOROCArray[ivalue];
701 }
702 }
703
704 cstream << "calPads" <<
705 "row.=" << &posArray[0] <<
706 "pad.=" << &posArray[1] <<
707 "lx.=" << &posArray[2] <<
708 "ly.=" << &posArray[3] <<
709 "gx.=" << &posArray[4] <<
710 "gy.=" << &posArray[5] <<
711 "rpad.=" << &posArray[6] <<
712 "channel.=" << &posArray[7];
713
714 cstream << "calPads" <<
715 "\n";
716
717 delete[] posArray;
718 delete[] vectorArray;
719 }
720
721
722 delete[] names;
723 if (mapFileName) {
724 delete mapIROCs;
725 delete mapOROCs;
726 delete[] mapIROCArray;
727 delete[] mapOROCArray;
728 delete[] mapNames;
729 }
730}
3ac615eb 731
732
733
734void AliTPCcalibDB::RegisterExB(Int_t index, Float_t bz, Bool_t bdelete){
735 //
736 // Register static ExB correction map
737 // index - registration index - used for visualization
738 // bz - bz field in kGaus
739
0a997b33 740 // Float_t factor = bz/(-5.); // default b filed in Cheb with minus sign
741 Float_t factor = bz/(5.); // default b filed in Cheb with minus sign
742 // was chenged in the Revision ???? (Ruben can you add here number)
3ac615eb 743
4642ac4b 744 AliMagF* bmap = new AliMagF("MapsExB","MapsExB", factor,TMath::Sign(1.f,factor),AliMagF::k5kG);
3ac615eb 745
746 AliTPCExBFirst *exb = new AliTPCExBFirst(bmap,0.88*2.6400e+04,50,50,50);
747 AliTPCExB::SetInstance(exb);
748
749 if (bdelete){
750 delete bmap;
751 }else{
752 AliTPCExB::RegisterField(index,bmap);
753 }
754 if (index>=fgExBArray.GetEntries()) fgExBArray.Expand((index+1)*2+11);
755 fgExBArray.AddAt(exb,index);
756}
757
758
759AliTPCExB* AliTPCcalibDB::GetExB(Float_t bz, Bool_t deleteB) {
760 //
761 // bz filed in KGaus not in tesla
762 // Get ExB correction map
763 // if doesn't exist - create it
764 //
765 Int_t index = TMath::Nint(5+bz);
766 if (index>fgExBArray.GetEntries()) fgExBArray.Expand((index+1)*2+11);
767 if (!fgExBArray.At(index)) AliTPCcalibDB::RegisterExB(index,bz,deleteB);
768 return (AliTPCExB*)fgExBArray.At(index);
769}
770
771
772void AliTPCcalibDB::SetExBField(Float_t bz){
773 //
774 // Set magnetic filed for ExB correction
775 //
776 fExB = GetExB(bz,kFALSE);
777}
bf85fe4d 778
0a997b33 779void AliTPCcalibDB::SetExBField(const AliMagF* bmap){
780 //
781 // Set magnetic field for ExB correction
782 //
783 AliTPCExBFirst *exb = new AliTPCExBFirst(bmap,0.88*2.6400e+04,50,50,50);
784 AliTPCExB::SetInstance(exb);
785 fExB=exb;
786}
787
bf85fe4d 788
789
5e1215d4 790
791
792void AliTPCcalibDB::UpdateRunInformations( Int_t run, Bool_t force){
bf85fe4d 793 //
794 // - > Don't use it for reconstruction - Only for Calibration studies
795 //
796 AliCDBEntry * entry = 0;
797 if (run>= fRunList.GetSize()){
798 fRunList.Set(run*2+1);
da6c0bc9 799 fGRPArray.Expand(run*2+1);
0231c65f 800 fGRPMaps.Expand(run*2+1);
e2914767 801 fGoofieArray.Expand(run*2+1);
802 fVoltageArray.Expand(run*2+1);
da6c0bc9 803 fTemperatureArray.Expand(run*2+1);
804 fVdriftArray.Expand(run*2+1);
5e1215d4 805 fDriftCorrectionArray.Expand(run*2+1);
a2c3785e 806 fTimeGainSplinesArray.Expand(run*2+1);
bf85fe4d 807 }
5e1215d4 808 if (fRunList[run]>0 &&force==kFALSE) return;
809 //
bf85fe4d 810 entry = AliCDBManager::Instance()->Get("GRP/GRP/Data",run);
0231c65f 811 if (entry) {
812 AliGRPObject * grpRun = dynamic_cast<AliGRPObject*>(entry->GetObject());
813 if (!grpRun){
814 TMap* map = dynamic_cast<TMap*>(entry->GetObject());
815 if (map){
e2914767 816 //grpRun = new AliGRPObject;
817 //grpRun->ReadValuesFromMap(map);
818 grpRun = MakeGRPObjectFromMap(map);
819
0231c65f 820 fGRPMaps.AddAt(map,run);
821 }
822 }
823 fGRPArray.AddAt(grpRun,run);
824 }
bf85fe4d 825 entry = AliCDBManager::Instance()->Get("TPC/Calib/Goofie",run);
5e1215d4 826 if (entry){
827 fGoofieArray.AddAt(entry->GetObject(),run);
828 }
e2914767 829 //
830 entry = AliCDBManager::Instance()->Get("TPC/Calib/HighVoltage",run);
5e1215d4 831 if (entry) {
832 fVoltageArray.AddAt(entry->GetObject(),run);
833 }
e2914767 834 //
a2c3785e 835 entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeGain",run);
5e1215d4 836 if (entry) {
837 fTimeGainSplinesArray.AddAt(entry->GetObject(),run);
838 }
839 //
840 entry = AliCDBManager::Instance()->Get("TPC/Calib/TimeDrift",run);
841 if (entry) {
842 fDriftCorrectionArray.AddAt(entry->GetObject(),run);
843 }
a2c3785e 844 //
bf85fe4d 845 entry = AliCDBManager::Instance()->Get("TPC/Calib/Temperature",run);
5e1215d4 846 if (entry) {
847 fTemperatureArray.AddAt(entry->GetObject(),run);
848 }
bf85fe4d 849 fRunList[run]=1; // sign as used
da6c0bc9 850
bfec3eeb 851 AliDCSSensor * press = GetPressureSensor(run,0);
da6c0bc9 852 AliTPCSensorTempArray * temp = GetTemperatureSensor(run);
853 if (press && temp){
854 AliTPCCalibVdrift * vdrift = new AliTPCCalibVdrift(temp, press,0);
855 fVdriftArray.AddAt(vdrift,run);
856 }
bf85fe4d 857}
858
859
860Float_t AliTPCcalibDB::GetGain(Int_t sector, Int_t row, Int_t pad){
861 //
862 //
863 AliTPCCalPad *calPad = Instance()->fDedxGainFactor;;
864 if (!calPad) return 0;
865 return calPad->GetCalROC(sector)->GetValue(row,pad);
866}
867
7390f655 868AliSplineFit* AliTPCcalibDB::GetVdriftSplineFit(const char* name, Int_t run){
869 //
870 //
871 //
872 TObjArray *arr=GetTimeVdriftSplineRun(run);
873 if (!arr) return 0;
874 return dynamic_cast<AliSplineFit*>(arr->FindObject(name));
875}
876
2cb269df 877AliSplineFit* AliTPCcalibDB::CreateVdriftSplineFit(const char* graphName, Int_t run){
878 //
879 // create spline fit from the drift time graph in TimeDrift
880 //
881 TObjArray *arr=GetTimeVdriftSplineRun(run);
882 if (!arr) return 0;
883 TGraph *graph=dynamic_cast<TGraph*>(arr->FindObject(graphName));
884 if (!graph) return 0;
885 AliSplineFit *fit = new AliSplineFit();
886 fit->SetGraph(graph);
887 fit->SetMinPoints(graph->GetN()+1);
888 fit->InitKnots(graph,2,0,0.001);
889 fit->SplineFit(0);
890 return fit;
891}
8de77f00 892
893AliGRPObject *AliTPCcalibDB::GetGRP(Int_t run){
894 //
895 // Get GRP object for given run
896 //
897 AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>((Instance()->fGRPArray).At(run));
898 if (!grpRun) {
5e1215d4 899 Instance()->UpdateRunInformations(run);
8de77f00 900 grpRun = dynamic_cast<AliGRPObject *>(Instance()->fGRPArray.At(run));
901 if (!grpRun) return 0;
902 }
903 return grpRun;
904}
905
0231c65f 906TMap * AliTPCcalibDB::GetGRPMap(Int_t run){
907 //
908 //
909 //
910 TMap * grpRun = dynamic_cast<TMap *>((Instance()->fGRPMaps).At(run));
911 if (!grpRun) {
5e1215d4 912 Instance()->UpdateRunInformations(run);
0231c65f 913 grpRun = dynamic_cast<TMap *>(Instance()->fGRPMaps.At(run));
914 if (!grpRun) return 0;
915 }
916 return grpRun;
917}
8de77f00 918
919
da6c0bc9 920AliDCSSensor * AliTPCcalibDB::GetPressureSensor(Int_t run, Int_t type){
bf85fe4d 921 //
0231c65f 922 // Get Pressure sensor
bfec3eeb 923 // run = run number
924 // type = 0 - Cavern pressure
925 // 1 - Suface pressure
0231c65f 926 // First try to get if trom map - if existing (Old format of data storing)
bf85fe4d 927 //
bfec3eeb 928
929
0231c65f 930 TMap *map = GetGRPMap(run);
931 if (map){
932 AliDCSSensor * sensor = 0;
933 TObject *osensor=0;
934 if (type==0) osensor = ((*map)("fCavernPressure"));
935 if (type==1) osensor = ((*map)("fP2Pressure"));
936 sensor =dynamic_cast<AliDCSSensor *>(osensor);
937 if (sensor) return sensor;
938 }
939 //
940 // If not map try to get it from the GRPObject
941 //
942 AliGRPObject * grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.At(run));
bf85fe4d 943 if (!grpRun) {
5e1215d4 944 UpdateRunInformations(run);
efdbb95a 945 grpRun = dynamic_cast<AliGRPObject *>(fGRPArray.At(run));
bf85fe4d 946 if (!grpRun) return 0;
947 }
948 AliDCSSensor * sensor = grpRun->GetCavernAtmosPressure();
da6c0bc9 949 if (type==1) sensor = grpRun->GetSurfaceAtmosPressure();
950 return sensor;
bf85fe4d 951}
952
953AliTPCSensorTempArray * AliTPCcalibDB::GetTemperatureSensor(Int_t run){
954 //
955 // Get temperature sensor array
956 //
957 AliTPCSensorTempArray * tempArray = (AliTPCSensorTempArray *)fTemperatureArray.At(run);
958 if (!tempArray) {
5e1215d4 959 UpdateRunInformations(run);
bf85fe4d 960 tempArray = (AliTPCSensorTempArray *)fTemperatureArray.At(run);
961 }
962 return tempArray;
963}
964
a2c3785e 965
966TObjArray * AliTPCcalibDB::GetTimeGainSplinesRun(Int_t run){
bf85fe4d 967 //
968 // Get temperature sensor array
969 //
a2c3785e 970 TObjArray * gainSplines = (TObjArray *)fTimeGainSplinesArray.At(run);
971 if (!gainSplines) {
5e1215d4 972 UpdateRunInformations(run);
a2c3785e 973 gainSplines = (TObjArray *)fTimeGainSplinesArray.At(run);
bf85fe4d 974 }
a2c3785e 975 return gainSplines;
bf85fe4d 976}
977
7390f655 978TObjArray * AliTPCcalibDB::GetTimeVdriftSplineRun(Int_t run){
979 //
980 // Get drift spline array
981 //
982 TObjArray * driftSplines = (TObjArray *)fDriftCorrectionArray.At(run);
983 if (!driftSplines) {
984 UpdateRunInformations(run);
985 driftSplines = (TObjArray *)fDriftCorrectionArray.At(run);
986 }
987 return driftSplines;
988}
989
e2914767 990AliDCSSensorArray * AliTPCcalibDB::GetVoltageSensors(Int_t run){
991 //
992 // Get temperature sensor array
993 //
994 AliDCSSensorArray * voltageArray = (AliDCSSensorArray *)fVoltageArray.At(run);
995 if (!voltageArray) {
5e1215d4 996 UpdateRunInformations(run);
e2914767 997 voltageArray = (AliDCSSensorArray *)fVoltageArray.At(run);
998 }
999 return voltageArray;
1000}
1001
99895a4f 1002AliDCSSensorArray * AliTPCcalibDB::GetGoofieSensors(Int_t run){
1003 //
1004 // Get temperature sensor array
1005 //
1006 AliDCSSensorArray * goofieArray = (AliDCSSensorArray *)fGoofieArray.At(run);
1007 if (!goofieArray) {
5e1215d4 1008 UpdateRunInformations(run);
99895a4f 1009 goofieArray = (AliDCSSensorArray *)fGoofieArray.At(run);
1010 }
1011 return goofieArray;
1012}
1013
1014
1015
da6c0bc9 1016AliTPCCalibVdrift * AliTPCcalibDB::GetVdrift(Int_t run){
1017 //
1018 // Get the interface to the the vdrift
1019 //
1020 AliTPCCalibVdrift * vdrift = (AliTPCCalibVdrift*)fVdriftArray.At(run);
1021 if (!vdrift) {
5e1215d4 1022 UpdateRunInformations(run);
da6c0bc9 1023 vdrift= (AliTPCCalibVdrift*)fVdriftArray.At(run);
1024 }
1025 return vdrift;
1026}
1027
892226be 1028Float_t AliTPCcalibDB::GetCEdriftTime(Int_t run, Int_t sector, Double_t timeStamp, Int_t *entries)
1029{
1030 //
1031 // GetCE drift time information for 'sector'
1032 // sector 72 is the mean drift time of the A-Side
1033 // sector 73 is the mean drift time of the C-Side
1034 // it timestamp==-1 return mean value
1035 //
1036 AliTPCcalibDB::Instance()->SetRun(run);
1037 TGraph *gr=AliTPCcalibDB::Instance()->GetCErocTgraph(sector);
1038 if (!gr||sector<0||sector>73) {
1039 if (entries) *entries=0;
1040 return 0.;
1041 }
1042 Float_t val=0.;
1043 if (timeStamp==-1.){
1044 val=gr->GetMean(2);
1045 }else{
1046 for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1047 Double_t x,y;
1048 gr->GetPoint(ipoint,x,y);
1049 if (x<timeStamp) continue;
1050 val=y;
1051 break;
1052 }
1053 }
1054 return val;
1055}
1056
1057Float_t AliTPCcalibDB::GetCEchargeTime(Int_t run, Int_t sector, Double_t timeStamp, Int_t *entries)
1058{
1059 //
1060 // GetCE mean charge for 'sector'
1061 // it timestamp==-1 return mean value
1062 //
1063 AliTPCcalibDB::Instance()->SetRun(run);
1064 TGraph *gr=AliTPCcalibDB::Instance()->GetCErocQgraph(sector);
1065 if (!gr||sector<0||sector>71) {
1066 if (entries) *entries=0;
1067 return 0.;
1068 }
1069 Float_t val=0.;
1070 if (timeStamp==-1.){
1071 val=gr->GetMean(2);
1072 }else{
1073 for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1074 Double_t x,y;
1075 gr->GetPoint(ipoint,x,y);
1076 if (x<timeStamp) continue;
1077 val=y;
1078 break;
1079 }
1080 }
1081 return val;
1082}
1083
7fff7612 1084Float_t AliTPCcalibDB::GetDCSSensorValue(AliDCSSensorArray *arr, Int_t timeStamp, const char * sensorName, Int_t sigDigits)
1085{
1086 //
1087 // Get Value for a DCS sensor 'sensorName', run 'run' at time 'timeStamp'
1088 //
1089 Float_t val=0;
1090 const TString sensorNameString(sensorName);
1091 AliDCSSensor *sensor = arr->GetSensor(sensorNameString);
1092 if (!sensor) return val;
892226be 1093 //use the dcs graph if possible
1094 TGraph *gr=sensor->GetGraph();
1095 if (gr){
1096 for (Int_t ipoint=0;ipoint<gr->GetN();++ipoint){
1097 Double_t x,y;
1098 gr->GetPoint(ipoint,x,y);
7390f655 1099 Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
892226be 1100 if (time<timeStamp) continue;
1101 val=y;
1102 break;
1103 }
1104 //if val is still 0, test if if the requested time if within 5min of the first/last
1105 //data point. If this is the case return the firs/last entry
1106 //the timestamps might not be syncronised for all calibration types, sometimes a 'pre'
1107 //and 'pos' period is requested. Especially to the HV this is not the case!
1108 //first point
1109 if (val==0 ){
1110 Double_t x,y;
1111 gr->GetPoint(0,x,y);
7390f655 1112 Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
892226be 1113 if ((time-timeStamp)<5*60) val=y;
1114 }
1115 //last point
1116 if (val==0 ){
1117 Double_t x,y;
1118 gr->GetPoint(gr->GetN()-1,x,y);
7390f655 1119 Int_t time=TMath::Nint(sensor->GetStartTime()+x*3600); //time in graph is hours
892226be 1120 if ((timeStamp-time)<5*60) val=y;
1121 }
1122 } else {
1123 val=sensor->GetValue(timeStamp);
1124 }
7fff7612 1125 if (sigDigits>=0){
1126 val=(Float_t)TMath::Floor(val * TMath::Power(10., sigDigits) + .5) / TMath::Power(10., sigDigits);
1127 }
1128 return val;
1129}
1130
1131Float_t AliTPCcalibDB::GetDCSSensorMeanValue(AliDCSSensorArray *arr, const char * sensorName, Int_t sigDigits)
1132{
1133 //
1134 // Get mean Value for a DCS sensor 'sensorName' during run 'run'
1135 //
1136 Float_t val=0;
1137 const TString sensorNameString(sensorName);
1138 AliDCSSensor *sensor = arr->GetSensor(sensorNameString);
1139 if (!sensor) return val;
892226be 1140
1141 //use dcs graph if it exists
1142 TGraph *gr=sensor->GetGraph();
1143 if (gr){
1144 val=gr->GetMean(2);
1145 } else {
1146 //if we don't have the dcs graph, try to get some meaningful information
1147 if (!sensor->GetFit()) return val;
1148 Int_t nKnots=sensor->GetFit()->GetKnots();
1149 Double_t tMid=(sensor->GetEndTime()-sensor->GetStartTime())/2.;
1150 for (Int_t iKnot=0;iKnot<nKnots;++iKnot){
1151 if (sensor->GetFit()->GetX()[iKnot]>tMid/3600.) break;
1152 val=(Float_t)sensor->GetFit()->GetY0()[iKnot];
1153 }
7fff7612 1154 }
7fff7612 1155 if (sigDigits>=0){
1156 val/=10;
1157 val=(Float_t)TMath::Floor(val * TMath::Power(10., sigDigits) + .5) / TMath::Power(10., sigDigits);
1158 val*=10;
1159 }
1160 return val;
1161}
bf85fe4d 1162
7fff7612 1163Float_t AliTPCcalibDB::GetChamberHighVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits) {
e2914767 1164 //
1165 // return the chamber HV for given run and time: 0-35 IROC, 36-72 OROC
7fff7612 1166 // if timeStamp==-1 return mean value
1167 //
1168 Float_t val=0;
1169 TString sensorName="";
1170 TTimeStamp stamp(timeStamp);
1171 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1172 if (!voltageArray || (sector<0) || (sector>71)) return val;
1173 Char_t sideName='A';
1174 if ((sector/18)%2==1) sideName='C';
1175 if (sector<36){
1176 //IROC
1177 sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
1178 }else{
1179 //OROC
1180 sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
1181 }
1182 if (timeStamp==-1){
1183 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1184 } else {
1185 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1186 }
1187 return val;
1188}
1189Float_t AliTPCcalibDB::GetSkirtVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1190{
1191 //
1192 // Get the skirt voltage for 'run' at 'timeStamp' and 'sector': 0-35 IROC, 36-72 OROC
1193 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1194 // if timeStamp==-1 return the mean value for the run
1195 //
1196 Float_t val=0;
1197 TString sensorName="";
1198 TTimeStamp stamp(timeStamp);
1199 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1200 if (!voltageArray || (sector<0) || (sector>71)) return val;
1201 Char_t sideName='A';
1202 if ((sector/18)%2==1) sideName='C';
1203 sensorName=Form("TPC_SKIRT_%c_VMEAS",sideName);
1204 if (timeStamp==-1){
1205 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1206 } else {
1207 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1208 }
1209 return val;
1210}
1211
1212Float_t AliTPCcalibDB::GetCoverVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1213{
1214 //
1215 // Get the cover voltage for run 'run' at time 'timeStamp'
1216 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1217 // if timeStamp==-1 return the mean value for the run
e2914767 1218 //
7fff7612 1219 Float_t val=0;
1220 TString sensorName="";
e2914767 1221 TTimeStamp stamp(timeStamp);
1222 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
7fff7612 1223 if (!voltageArray || (sector<0) || (sector>71)) return val;
1224 Char_t sideName='A';
1225 if ((sector/18)%2==1) sideName='C';
1226 if (sector<36){
1227 //IROC
1228 sensorName=Form("TPC_COVER_I_%c_VMEAS",sideName);
1229 }else{
1230 //OROC
1231 sensorName=Form("TPC_COVER_O_%c_VMEAS",sideName);
1232 }
1233 if (timeStamp==-1){
1234 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1235 } else {
1236 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1237 }
1238 return val;
1239}
1240
1241Float_t AliTPCcalibDB::GetGGoffsetVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1242{
1243 //
1244 // Get the GG offset voltage for run 'run' at time 'timeStamp'
1245 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1246 // if timeStamp==-1 return the mean value for the run
1247 //
1248 Float_t val=0;
1249 TString sensorName="";
1250 TTimeStamp stamp(timeStamp);
1251 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1252 if (!voltageArray || (sector<0) || (sector>71)) return val;
1253 Char_t sideName='A';
1254 if ((sector/18)%2==1) sideName='C';
1255 if (sector<36){
1256 //IROC
1257 sensorName=Form("TPC_GATE_I_%c_OFF_VMEAS",sideName);
1258 }else{
1259 //OROC
1260 sensorName=Form("TPC_GATE_O_%c_OFF_VMEAS",sideName);
1261 }
1262 if (timeStamp==-1){
1263 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1264 } else {
1265 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1266 }
1267 return val;
1268}
1269
1270Float_t AliTPCcalibDB::GetGGnegVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1271{
1272 //
1273 // Get the GG offset voltage for run 'run' at time 'timeStamp'
1274 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1275 // if timeStamp==-1 return the mean value for the run
1276 //
1277 Float_t val=0;
1278 TString sensorName="";
1279 TTimeStamp stamp(timeStamp);
1280 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1281 if (!voltageArray || (sector<0) || (sector>71)) return val;
1282 Char_t sideName='A';
1283 if ((sector/18)%2==1) sideName='C';
1284 if (sector<36){
1285 //IROC
1286 sensorName=Form("TPC_GATE_I_%c_NEG_VMEAS",sideName);
1287 }else{
1288 //OROC
1289 sensorName=Form("TPC_GATE_O_%c_NEG_VMEAS",sideName);
1290 }
1291 if (timeStamp==-1){
1292 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1293 } else {
1294 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1295 }
1296 return val;
1297}
1298
1299Float_t AliTPCcalibDB::GetGGposVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits)
1300{
1301 //
1302 // Get the GG offset voltage for run 'run' at time 'timeStamp'
1303 // type corresponds to the following: 0 - IROC A-Side; 1 - IROC C-Side; 2 - OROC A-Side; 3 - OROC C-Side
1304 // if timeStamp==-1 return the mean value for the run
1305 //
1306 Float_t val=0;
1307 TString sensorName="";
1308 TTimeStamp stamp(timeStamp);
1309 AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
1310 if (!voltageArray || (sector<0) || (sector>71)) return val;
1311 Char_t sideName='A';
1312 if ((sector/18)%2==1) sideName='C';
1313 if (sector<36){
1314 //IROC
1315 sensorName=Form("TPC_GATE_I_%c_POS_VMEAS",sideName);
1316 }else{
1317 //OROC
1318 sensorName=Form("TPC_GATE_O_%c_POS_VMEAS",sideName);
1319 }
1320 if (timeStamp==-1){
1321 val=AliTPCcalibDB::GetDCSSensorMeanValue(voltageArray, sensorName.Data(),sigDigits);
1322 } else {
1323 val=AliTPCcalibDB::GetDCSSensorValue(voltageArray, timeStamp, sensorName.Data(),sigDigits);
1324 }
1325 return val;
e2914767 1326}
bf85fe4d 1327
da6c0bc9 1328Float_t AliTPCcalibDB::GetPressure(Int_t timeStamp, Int_t run, Int_t type){
bf85fe4d 1329 //
1330 // GetPressure for given time stamp and runt
1331 //
1332 TTimeStamp stamp(timeStamp);
da6c0bc9 1333 AliDCSSensor * sensor = Instance()->GetPressureSensor(run,type);
bf85fe4d 1334 if (!sensor) return 0;
bf85fe4d 1335 return sensor->GetValue(stamp);
1336}
1337
5312f439 1338Float_t AliTPCcalibDB::GetL3Current(Int_t run, Int_t statType){
1339 //
1340 // return L3 current
1341 // stat type is: AliGRPObject::Stats: kMean = 0, kTruncMean = 1, kMedian = 2, kSDMean = 3, kSDMedian = 4
1342 //
1343 Float_t current=-1;
1344 AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
1345 if (grp) current=grp->GetL3Current((AliGRPObject::Stats)statType);
1346 return current;
1347}
1348
1349Float_t AliTPCcalibDB::GetBz(Int_t run){
1350 //
e6970ab5 1351 // calculate BZ in T from L3 current
5312f439 1352 //
1353 Float_t bz=-1;
1354 Float_t current=AliTPCcalibDB::GetL3Current(run);
e6970ab5 1355 if (current>-1) bz=5*current/30000.*.1;
5312f439 1356 return bz;
1357}
1358
1359Char_t AliTPCcalibDB::GetL3Polarity(Int_t run) {
1360 //
1361 // get l3 polarity from GRP
1362 //
7390f655 1363 Char_t pol=-100;
1364 AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
1365 if (grp) pol=grp->GetL3Polarity();
1366 return pol;
5312f439 1367}
1368
1369TString AliTPCcalibDB::GetRunType(Int_t run){
1370 //
1371 // return run type from grp
1372 //
7390f655 1373
1374// TString type("UNKNOWN");
1375 AliGRPObject *grp=AliTPCcalibDB::GetGRP(run);
1376 if (grp) return grp->GetRunType();
1377 return "UNKNOWN";
5312f439 1378}
1379
7f7847fe 1380Float_t AliTPCcalibDB::GetValueGoofie(Int_t timeStamp, Int_t run, Int_t type){
1381 //
1382 // GetPressure for given time stamp and runt
1383 //
1384 TTimeStamp stamp(timeStamp);
1385 AliDCSSensorArray* goofieArray = AliTPCcalibDB::Instance()->GetGoofieSensors(run);
1386 if (!goofieArray) return 0;
1387 AliDCSSensor *sensor = goofieArray->GetSensor(type);
1388 return sensor->GetValue(stamp);
1389}
1390
1391
1392
1393
1394
1395
f0269955 1396Bool_t AliTPCcalibDB::GetTemperatureFit(Int_t timeStamp, Int_t run, Int_t side,TVectorD& fit){
1397 //
1398 //
1399 //
1400 TTimeStamp tstamp(timeStamp);
64b48395 1401 AliTPCSensorTempArray* tempArray = Instance()->GetTemperatureSensor(run);
f0269955 1402 if (! tempArray) return kFALSE;
1403 AliTPCTempMap * tempMap = new AliTPCTempMap(tempArray);
1404 TLinearFitter * fitter = tempMap->GetLinearFitter(3,side,tstamp);
1405 if (fitter){
1406 fitter->Eval();
1407 fitter->GetParameters(fit);
1408 }
1409 delete fitter;
1410 delete tempMap;
1411 if (!fitter) return kFALSE;
1412 return kTRUE;
1413}
1414
64b48395 1415Float_t AliTPCcalibDB::GetTemperature(Int_t timeStamp, Int_t run, Int_t side){
1416 //
1417 //
1418 //
12e42756 1419 TVectorD vec(5);
64b48395 1420 if (side==0) {
1421 GetTemperatureFit(timeStamp,run,0,vec);
1422 return vec[0];
1423 }
1424 if (side==1){
1425 GetTemperatureFit(timeStamp,run,0,vec);
1426 return vec[0];
1427 }
57dc06f2 1428 return 0;
64b48395 1429}
bf85fe4d 1430
1431
da6c0bc9 1432Double_t AliTPCcalibDB::GetPTRelative(UInt_t timeSec, Int_t run, Int_t side){
1433 //
1434 // Get relative P/T
1435 // time - absolute time
1436 // run - run number
1437 // side - 0 - A side 1-C side
1438 AliTPCCalibVdrift * vdrift = Instance()->GetVdrift(run);
1439 if (!vdrift) return 0;
1440 return vdrift->GetPTRelative(timeSec,side);
1441}
1442
e2914767 1443AliGRPObject * AliTPCcalibDB::MakeGRPObjectFromMap(TMap *map){
1444 //
1445 // Function to covert old GRP run information from TMap to GRPObject
1446 //
1447 // TMap * map = AliTPCcalibDB::GetGRPMap(52406);
1448 if (!map) return 0;
1449 AliDCSSensor * sensor = 0;
1450 TObject *osensor=0;
1451 osensor = ((*map)("fP2Pressure"));
1452 sensor =dynamic_cast<AliDCSSensor *>(osensor);
1453 //
1454 if (!sensor) return 0;
1455 //
1456 AliDCSSensor * sensor2 = new AliDCSSensor(*sensor);
1457 osensor = ((*map)("fCavernPressure"));
1458 TGraph * gr = new TGraph(2);
1459 gr->GetX()[0]= -100000.;
1460 gr->GetX()[1]= 1000000.;
1461 gr->GetY()[0]= atof(osensor->GetName());
1462 gr->GetY()[1]= atof(osensor->GetName());
1463 sensor2->SetGraph(gr);
1464 sensor2->SetFit(0);
1465
1466
1467 AliGRPObject *grpRun = new AliGRPObject;
1468 grpRun->ReadValuesFromMap(map);
1469 grpRun->SetCavernAtmosPressure(sensor2);
1470 grpRun->SetSurfaceAtmosPressure(sensor);
1471 return grpRun;
1472}
1473
5312f439 1474Bool_t AliTPCcalibDB::CreateGUITree(Int_t run, const char* filename)
1475{
1476 //
1477 // Create a gui tree for run number 'run'
1478 //
e2914767 1479
5312f439 1480 if (!AliCDBManager::Instance()->GetDefaultStorage()){
1481 AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
1482 MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
1483 return kFALSE;
1484 }
1485 //db instance
1486 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
1487 // retrieve cal pad objects
1488 db->SetRun(run);
1489 AliTPCPreprocessorOnline prep;
1490 //noise and pedestals
1491 prep.AddComponent(db->GetPedestals());
1492 prep.AddComponent(db->GetPadNoise());
1493 //pulser data
1494 prep.AddComponent(db->GetPulserTmean());
1495 prep.AddComponent(db->GetPulserTrms());
1496 prep.AddComponent(db->GetPulserQmean());
1497 //CE data
1498 prep.AddComponent(db->GetCETmean());
1499 prep.AddComponent(db->GetCETrms());
1500 prep.AddComponent(db->GetCEQmean());
1501 //Altro data
1502 prep.AddComponent(db->GetALTROAcqStart() );
1503 prep.AddComponent(db->GetALTROZsThr() );
1504 prep.AddComponent(db->GetALTROFPED() );
1505 prep.AddComponent(db->GetALTROAcqStop() );
1506 prep.AddComponent(db->GetALTROMasked() );
1507 //
1508 TString file(filename);
1509 if (file.IsNull()) file=Form("guiTreeRun_%d.root",run);
1510 prep.DumpToFile(file.Data());
1511 return kTRUE;
1512}
e2914767 1513
7390f655 1514Bool_t AliTPCcalibDB::CreateRefFile(Int_t run, const char* filename)
1515{
1516 //
1517 // Create a gui tree for run number 'run'
1518 //
1519
1520 if (!AliCDBManager::Instance()->GetDefaultStorage()){
1521 AliLog::Message(AliLog::kError, "Default Storage not set. Cannot create Calibration Tree!",
1522 MODULENAME(), "AliTPCcalibDB", FUNCTIONNAME(), __FILE__, __LINE__);
1523 return kFALSE;
1524 }
1525 TString file(filename);
1526 if (file.IsNull()) file=Form("RefCalPads_%d.root",run);
1527 TDirectory *currDir=gDirectory;
1528 //db instance
1529 AliTPCcalibDB *db=AliTPCcalibDB::Instance();
1530 // retrieve cal pad objects
1531 db->SetRun(run);
1532 //open file
1533 TFile f(file.Data(),"recreate");
1534 //noise and pedestals
1535 db->GetPedestals()->Write("Pedestals");
1536 db->GetPadNoise()->Write("PadNoise");
1537 //pulser data
1538 db->GetPulserTmean()->Write("PulserTmean");
1539 db->GetPulserTrms()->Write("PulserTrms");
1540 db->GetPulserQmean()->Write("PulserQmean");
1541 //CE data
1542 db->GetCETmean()->Write("CETmean");
1543 db->GetCETrms()->Write("CETrms");
1544 db->GetCEQmean()->Write("CEQmean");
1545 //Altro data
1546 db->GetALTROAcqStart() ->Write("ALTROAcqStart");
1547 db->GetALTROZsThr() ->Write("ALTROZsThr");
1548 db->GetALTROFPED() ->Write("ALTROFPED");
1549 db->GetALTROAcqStop() ->Write("ALTROAcqStop");
1550 db->GetALTROMasked() ->Write("ALTROMasked");
1551 //
1552 f.Close();
1553 currDir->cd();
1554 return kTRUE;
1555}
17c90083 1556
1557
1558
43a74775 1559Double_t AliTPCcalibDB::GetVDriftCorrectionTime(Int_t timeStamp, Int_t run, Int_t side, Int_t /*mode*/){
17c90083 1560 //
1561 // Get time dependent drift velocity correction
1562 // multiplication factor vd = vdnom *(1+vdriftcorr)
1563 // Arguments:
1564 // mode determines the algorith how to combine the Laser Track, LaserCE and physics tracks
1565 // timestamp - timestamp
1566 // run - run number
1567 // side - the drift velocity per side (possible for laser and CE)
1568 //
1569 // Notice - Extrapolation outside of calibration range - using constant function
1570 //
a8f8b6a1 1571 if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
1572 UpdateRunInformations(run,kFALSE);
43a74775 1573 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
4429bfef 1574 if (!array) return 0;
43a74775 1575 TGraphErrors *laserA= (TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1576 TGraphErrors *laserC= (TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
1577
1578 Double_t result=0;
1579 if (laserA && laserC){
1580 result= (laserA->Eval(timeStamp)+laserC->Eval(timeStamp))*0.5;
1581 }
1582 if (laserA && side==0){
1583 result = (laserA->Eval(timeStamp));
1584 }
1585 if (laserC &&side==1){
1586 result = (laserC->Eval(timeStamp));
1587 }
1588 return result;
17c90083 1589}
1590
43a74775 1591Double_t AliTPCcalibDB::GetTime0CorrectionTime(Int_t timeStamp, Int_t run, Int_t side, Int_t /*mode*/){
17c90083 1592 //
43a74775 1593 // Get time dependent time 0 (trigger delay in cm) correction
17c90083 1594 // additive correction time0 = time0+ GetTime0CorrectionTime
1595 // Value etracted combining the vdrift correction using laser tracks and CE and the physics track matchin
1596 // Arguments:
1597 // mode determines the algorith how to combine the Laser Track and physics tracks
1598 // timestamp - timestamp
1599 // run - run number
1600 // side - the drift velocity per side (possible for laser and CE)
1601 //
1602 // Notice - Extrapolation outside of calibration range - using constant function
1603 //
a8f8b6a1 1604 if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
1605 UpdateRunInformations(run,kFALSE);
43a74775 1606 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
4429bfef 1607 if (!array) return 0;
43a74775 1608 TGraphErrors *laserA= (TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1609 TGraphErrors *laserC= (TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
1610
1611 Double_t lresult=0;
1612 if (laserA && laserC){
1613 lresult= (laserA->Eval(timeStamp)+laserC->Eval(timeStamp))*0.5;
1614 }
1615 if (laserA && side==0){
1616 lresult = (laserA->Eval(timeStamp));
1617 }
1618 if (laserC &&side==1){
1619 lresult = (laserC->Eval(timeStamp));
1620 }
1621 TGraphErrors *cosmic =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1622 if (cosmic){
1623 Double_t cresult =cosmic->Eval(timeStamp);
27c3bb85 1624 Double_t result =(cresult-lresult)*fParam->GetZLength();
43a74775 1625 return result;
1626 }
17c90083 1627 return 0;
43a74775 1628
17c90083 1629}
1630
1631
1632
1633
43a74775 1634Double_t AliTPCcalibDB::GetVDriftCorrectionGy(Int_t timeStamp, Int_t run, Int_t side, Int_t /*mode*/){
17c90083 1635 //
1636 // Get global y correction drift velocity correction factor
1637 // additive factor vd = vdnom*(1+GetVDriftCorrectionGy *gy)
1638 // Value etracted combining the vdrift correction using laser tracks and CE
1639 // Arguments:
1640 // mode determines the algorith how to combine the Laser Track, LaserCE
1641 // timestamp - timestamp
1642 // run - run number
1643 // side - the drift velocity gy correction per side (CE and Laser tracks)
1644 //
1645 // Notice - Extrapolation outside of calibration range - using constant function
a8f8b6a1 1646 //
1647 if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
1648 UpdateRunInformations(run,kFALSE);
43a74775 1649 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
4429bfef 1650 if (!array) return 0;
43a74775 1651 TGraphErrors *laserA= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_A");
1652 TGraphErrors *laserC= (TGraphErrors*)array->FindObject("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_C");
1653
1654 Double_t result=0;
1655 if (laserA && laserC){
1656 result= (laserA->Eval(timeStamp)+laserC->Eval(timeStamp))*0.5;
1657 }
1658 if (laserA && side==0){
1659 result = (laserA->Eval(timeStamp));
1660 }
1661 if (laserC &&side==1){
1662 result = (laserC->Eval(timeStamp));
1663 }
1664 return -result/250.; //normalized before
17c90083 1665}