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