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