Be sure to load mapping when needed
[u/mrichter/AliRoot.git] / MUON / AliMUONCalibrationData.cxx
CommitLineData
c5bdf179 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// $Id$
17
18#include "AliMUONCalibrationData.h"
19
20#include "AliCDBEntry.h"
21#include "AliCDBManager.h"
4bec0403 22#include "AliCodeTimer.h"
32f1b761 23#include "AliDCSValue.h"
c5bdf179 24#include "AliLog.h"
32f1b761 25#include "AliMpDCSNamer.h"
b37b9546 26#include "AliMpIntPair.h"
32f1b761 27#include "AliMUONGlobalCrateConfig.h"
28#include "AliMUONRegionalTriggerConfig.h"
0045b488 29#include "AliMUONRejectList.h"
e7d7fa47 30#include "AliMUONTriggerEfficiencyCells.h"
31#include "AliMUONTriggerLut.h"
32f1b761 32#include "AliMUONVCalibParam.h"
a0eca509 33#include "AliMUONVStore.h"
34#include "AliMUONVStore.h"
92c23b09 35
4bec0403 36#include <Riostream.h>
37#include <TClass.h>
38#include <TMap.h>
b37b9546 39#include <TMath.h>
c5bdf179 40
3d1463c8 41//-----------------------------------------------------------------------------
5398f946 42/// \class AliMUONCalibrationData
43///
48ed403b 44/// For the moment, this class stores pedestals, gains, hv (for tracker)
45/// and lut, masks and efficiencies (for trigger) that are fetched from the CDB.
e7d7fa47 46///
47/// This class is to be considered as a convenience class.
48/// Its aim is to ease retrieval of calibration data from the
49/// condition database.
50///
51/// It acts as a "facade" to a bunch of underlying
52/// containers/calibration classes.
53///
5398f946 54/// \author Laurent Aphecetche
3d1463c8 55//-----------------------------------------------------------------------------
e7d7fa47 56
5398f946 57/// \cond CLASSIMP
c5bdf179 58ClassImp(AliMUONCalibrationData)
5398f946 59/// \endcond
c5bdf179 60
9ee1d6ff 61AliMUONVStore* AliMUONCalibrationData::fgBypassPedestals(0x0);
62AliMUONVStore* AliMUONCalibrationData::fgBypassGains(0x0);
8f29b706 63
b37b9546 64namespace
65{
66 void MarkForDeletion(Int_t* indices, Int_t first, Int_t last)
67 {
68 for ( Int_t i = first; i <= last; ++i )
69 {
70 indices[i] = 1;
71 }
72 }
73}
74
c5bdf179 75//_____________________________________________________________________________
76AliMUONCalibrationData::AliMUONCalibrationData(Int_t runNumber,
77 Bool_t deferredInitialization)
78: TObject(),
79fIsValid(kTRUE),
80fRunNumber(runNumber),
81fGains(0x0),
c3ce65fd 82fPedestals(0x0),
48ed403b 83fHV(0x0),
49e110ec 84fTriggerDCS(0x0),
e7d7fa47 85fLocalTriggerBoardMasks(0x0),
92c23b09 86fRegionalTriggerConfig(0x0),
87fGlobalTriggerCrateConfig(0x0),
e7d7fa47 88fTriggerLut(0x0),
c1bbaf66 89fTriggerEfficiency(0x0),
d067ba7c 90fCapacitances(0x0),
2b8a1212 91fNeighbours(0x0),
0045b488 92fOccupancyMap(0x0),
6c870207 93fRejectList(0x0),
94fConfig(0x0)
c5bdf179 95{
5398f946 96/// Default ctor.
97
c3ce65fd 98 // If deferredInitialization is false, we read *all* calibrations
99 // at once.
100 // So when using this class to access only one kind of calibrations (e.g.
101 // only pedestals), you should put deferredInitialization to kTRUE, which
102 // will instruct this object to fetch the data only when neeeded.
5398f946 103
c5bdf179 104 if ( deferredInitialization == kFALSE )
105 {
5562688f 106 Gains();
107 Pedestals();
7eafe398 108 OccupancyMap();
0045b488 109 RejectList();
5562688f 110 HV();
49e110ec 111 TriggerDCS();
5562688f 112 LocalTriggerBoardMasks(0);
92c23b09 113 RegionalTriggerConfig();
114 GlobalTriggerCrateConfig();
5562688f 115 TriggerLut();
116 TriggerEfficiency();
117 Capacitances();
118 Neighbours();
6c870207 119 Config();
c5bdf179 120 }
121}
122
e7d7fa47 123//_____________________________________________________________________________
c5bdf179 124AliMUONCalibrationData::~AliMUONCalibrationData()
125{
f436adf2 126 /// Destructor. Note that we're the owner of our pointers if the OCDB cache
127 /// is not set. Otherwise the cache is supposed to take care of them...
128 if (!(AliCDBManager::Instance()->GetCacheFlag())) Reset();
c3ce65fd 129}
c3ce65fd 130
131//_____________________________________________________________________________
5562688f 132AliMUONVStore*
133AliMUONCalibrationData::Capacitances() const
c3ce65fd 134{
5562688f 135 /// Create (if needed) and return the internal store for capacitances.
136
137 if (!fCapacitances)
c3ce65fd 138 {
5562688f 139 fCapacitances = CreateCapacitances(fRunNumber);
c3ce65fd 140 }
5562688f 141 return fCapacitances;
c5bdf179 142}
143
144//_____________________________________________________________________________
5562688f 145AliMUONVStore*
143cd71a 146AliMUONCalibrationData::CreateCapacitances(Int_t runNumber, Int_t* startOfValidity)
c5bdf179 147{
5562688f 148 /// Create capa store from OCDB for a given run
149
143cd71a 150 return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/Capacitances",startOfValidity));
5562688f 151}
5398f946 152
5562688f 153//_____________________________________________________________________________
154AliMUONVStore*
143cd71a 155AliMUONCalibrationData::CreateGains(Int_t runNumber, Int_t* startOfValidity)
5562688f 156{
157 /// Create a new gain store from the OCDB for a given run
143cd71a 158 return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/Gains",startOfValidity));
c5bdf179 159}
160
161//_____________________________________________________________________________
92c23b09 162AliMUONGlobalCrateConfig*
143cd71a 163AliMUONCalibrationData::CreateGlobalTriggerCrateConfig(Int_t runNumber, Int_t* startOfValidity)
c5bdf179 164{
92c23b09 165 /// Create the internal store for GlobalTriggerCrateConfig from OCDB
48ed403b 166
143cd71a 167 return dynamic_cast<AliMUONGlobalCrateConfig*>(CreateObject(runNumber,"MUON/Calib/GlobalTriggerCrateConfig",startOfValidity));
48ed403b 168}
169
92c23b09 170
32f1b761 171//______________________________________________________________________________
b37b9546 172Bool_t AliMUONCalibrationData::CheckHVGroup(TObjArray& values, Int_t first, Int_t last, Double_t& value, Int_t& slope, TString* msg)
32f1b761 173{
b37b9546 174 // Get the HV of the values between first and last indices
175 // return the HV slope (in Volt per second) and a message
176 // Return kFALSE if we must discard the group
177 //
32f1b761 178
b37b9546 179 if (msg) *msg="";
32f1b761 180
b37b9546 181 if ( last < first ) return kFALSE;
182 if ( last - first < 2 ) return kFALSE;
32f1b761 183
b37b9546 184 Double_t a(0.0);
185 Double_t b(0.0);
186
187 Float_t HVSAME(1); // 1 volts
188
189 AliDCSValue* vfirst = static_cast<AliDCSValue*>(values.UncheckedAt(first));
190 AliDCSValue* vlast = static_cast<AliDCSValue*>(values.UncheckedAt(last));
191
192 Int_t deltaHV = TMath::Nint(TMath::Abs(vfirst->GetFloat()-vlast->GetFloat()));
32f1b761 193
b37b9546 194 if ( deltaHV < HVSAME ) return kFALSE;
195
196 for ( Int_t i = first; i <= last; ++i )
197 {
198 AliDCSValue* v = static_cast<AliDCSValue*>(values.UncheckedAt(i));
199
200 Double_t y = v->GetFloat() - vfirst->GetFloat();
201 Double_t x = v->GetTimeStamp() - vfirst->GetTimeStamp();
32f1b761 202
b37b9546 203 a += x*y;
204 b += x*x;
205 }
32f1b761 206
b37b9546 207 value = a/b;
208 slope = value > 0 ? 1 : -1;
209 value = TMath::Abs(value);
32f1b761 210
b37b9546 211 UInt_t deltaTime = vlast->GetTimeStamp() - vfirst->GetTimeStamp();
32f1b761 212
b37b9546 213 if (msg)
32f1b761 214 {
b37b9546 215 if (slope>0) (*msg) = Form("RU%d[%d:%d](%d)",TMath::Nint(value),first,last,deltaTime);
216 if (slope<0) (*msg) = Form("RD%d[%d:%d](%d)",TMath::Nint(value),first,last,deltaTime);
32f1b761 217
b37b9546 218 if ( TMath::Nint(value) == 0 )
32f1b761 219 {
b37b9546 220 // this is to protect for the few cases
221 // (see e.g. MchHvLvLeft/Chamber00Left/Quad2Sect0.actual.vMon in run 134497)
222 // where we can have *lots* of values (2483 in this example) but that
223 // are more or less constant...
224 //
225 // or simply to remove small ramps
226 //
227 slope = 0;
228 value = (vfirst->GetFloat()+vlast->GetFloat())/2.0;
229 *msg = Form("FLUCT%d[%d:%d]",TMath::Nint(value),first,last);
32f1b761 230 }
231 }
232
b37b9546 233 return kTRUE;
234}
235
236//______________________________________________________________________________
237Bool_t AliMUONCalibrationData::PatchHVValues(TObjArray& values,
238 TString* msg)
239{
240 /// We do here a little bit of massaging of the HV values, if needed.
241 ///
242 /// The main point is to "gather" values that are within a given small amount
243 /// of time (typically 60 seconds) and infer a slope from those values
244 /// slope > 0 means it is a ramp-up, slope < 0 that's a ramp-down
245 ///
246 /// This is to avoid both the "ramp-down-before-end-of-run" and the
247 /// "ramp-up-after-start-of-run" syndroms...
248 ///
249 /// Return kFALSE is the kind of HV (trouble) case we have here
250 /// has not been identified...
251 ///
252
253 UInt_t DELTATIME(60); // in seconds
254 Int_t IENDRU(60); // in seconds
255
256 // Start by finding groups of values which are not separated (each) by more than
257 // deltaTime
258
259 Bool_t gather(kFALSE);
260 Int_t ifirst(0);
261 Int_t ilast(0);
262 TObjArray groups;
263 groups.SetOwner(kTRUE);
264
265 for ( Int_t i = values.GetLast(); i > 0; --i )
32f1b761 266 {
b37b9546 267 AliDCSValue* vi = static_cast<AliDCSValue*>(values.UncheckedAt(i));
268 AliDCSValue* vj = static_cast<AliDCSValue*>(values.UncheckedAt(i-1));
269
270 if ( vi->GetTimeStamp() - vj->GetTimeStamp() < DELTATIME )
32f1b761 271 {
b37b9546 272 if ( !gather )
273 {
274 gather = kTRUE;
275 ifirst = i;
276 }
277 ilast=i;
32f1b761 278 }
b37b9546 279 else
32f1b761 280 {
b37b9546 281 if ( gather )
282 {
283 ilast=i;
284
285 groups.Add(new AliMpIntPair(ilast,ifirst));
286 }
287 gather = kFALSE;
32f1b761 288 }
32f1b761 289 }
290
b37b9546 291 if (gather)
32f1b761 292 {
b37b9546 293 groups.Add(new AliMpIntPair(0,ifirst));
32f1b761 294 }
b37b9546 295
296 TIter nextGroup(&groups,kIterBackward);
297 AliMpIntPair* p;
298 TString internalMsg;
299 Int_t ngroups(0);
300
301 Int_t nRU(0);
302 Int_t nRD(0);
303 Int_t nStartRU(0);
304 Int_t nEndAndShortRU(0);
305 Int_t nEndRD(0);
306 Int_t nTripRD(0);
307 Int_t nFluct(0);
32f1b761 308
b37b9546 309 while ( ( p = static_cast<AliMpIntPair*>(nextGroup()) ) )
32f1b761 310 {
b37b9546 311 Double_t value;
312 Int_t slope;
32f1b761 313
b37b9546 314 TString groupMsg;
315
316 AliDebugClass(1,Form("group %d:%d",p->GetFirst(),p->GetSecond()));
317
318 Bool_t ok = CheckHVGroup(values,p->GetFirst(),p->GetSecond(),value,slope,&groupMsg);
319
320 if (!ok) continue;
321
322 ++ngroups;
323
324 if ( slope > 0 )
325 {
326 if ( p->GetFirst() == 0 )
327 {
328 // start with a ramp-up
329 ++nStartRU;
330 }
331 else if ( p->GetSecond() == values.GetLast() && TMath::Nint(value) < IENDRU )
332 {
333 ++nEndAndShortRU;
334 }
335 else
336 {
337 // ramp-up in the middle of nowhere...
338 ++nRU;
339 }
340 }
341 else if ( slope < 0 )
32f1b761 342 {
b37b9546 343 if ( p->GetSecond() == values.GetLast() )
344 {
345 // end with a ramp-down
346 ++nEndRD;
347 }
348 else
349 {
350 // ramp-down in the middle of nowhere
351 ++nRD;
352 }
353
354 AliDCSValue* d = static_cast<AliDCSValue*>(values.At(p->GetSecond()));
355
356 if ( d->GetFloat() < AliMpDCSNamer::TrackerHVOFF() )
357 {
358 ++nTripRD;
359 }
32f1b761 360 }
b37b9546 361 else
32f1b761 362 {
b37b9546 363 ++nFluct;
32f1b761 364 }
b37b9546 365
366 internalMsg += groupMsg;
367 internalMsg += " ";
32f1b761 368 }
369
b37b9546 370 /*
371
372 Once we have "decoded" the groups we try to find out which of
373 the following cases we're facing :
374
375 case A = -------- = OK(1)
376
377 case B = ----
378 \
379 \ = OK, once we have removed the ramp-down (2)
380
381 case C = -----
382 /
383 / = OK, once we have removed the ramp-up (3)
384
385 case D = -----
386 / \
387 / \ = OK, once we have removed the ramp-down (2) and the ramp-up (3)
388
389 case E = ----
390 \
391 \____ = TRIP = BAD (here the ramp-down slope should be bigger than in case C)
392
393 case F = ----
394 \ ----- = BAD (trip + ramp-up at end of run)
395 \____/
396
397 case G = fluctuations (within a range defined in CheckHVGroup...)
398
399 case H =
400 /
401 / = ramp-up right at the end-of-run = OK (4)
402 ------
403
404 (1) OK means the group is identified correctly, still the value can be below ready...
405 (2) ramp-down values will be removed if the ramp is indeed the last values in the serie
406 i.e. it's really an end-of-run problem (otherwise it's not case B)
407 (3) ramp-up values will be removed if the ramp is indeed the first values in the serie
408 i.e. it's really a start-of-run problem (otherwise it's not case C)
409 (4) OK if short enough...
410
411 Any other case is unknown and we'll :
412 a) return kFALSE
413 b) assume the channel is OFF.
414
415
416 */
417
418 AliDebugClass(1,Form("msg=%s ngroupds=%d",internalMsg.Data(),ngroups));
419 AliDebugClass(1,Form("nRU %d nRD %d nStartRU %d nEndRD %d nTripRD %d nFluct %d",
420 nRU,nRD,nStartRU,nEndRD,nTripRD,nFluct));
421
422 TString hvCase("OTHER");
423 int dummy(0),a(-1),b(-1);
8763322f 424 char r[81];
b37b9546 425 Int_t nvalues = values.GetSize();
426 Int_t* indices = new Int_t[nvalues];
427 memset(indices,0,nvalues*sizeof(Int_t));
428
429 AliDCSValue* vfirst = static_cast<AliDCSValue*>(values.UncheckedAt(0));
430 AliDCSValue* vlast = static_cast<AliDCSValue*>(values.UncheckedAt(values.GetLast()));
431
432 UInt_t meanTimeStamp = ( vfirst->GetTimeStamp() + vlast->GetTimeStamp() ) / 2;
433
434 if ( ngroups == 0 )
32f1b761 435 {
b37b9546 436 hvCase = "A";
437 }
438 else if ( nTripRD > 0 )
439 {
440 if ( nRU > 0 && nRD > 0 )
32f1b761 441 {
b37b9546 442 hvCase = "F";
32f1b761 443 }
444 else
445 {
b37b9546 446 hvCase = "E";
32f1b761 447 }
b37b9546 448 internalMsg += "TRIP ";
449 MarkForDeletion(indices,0,values.GetLast());
450 values.Add(new AliDCSValue(static_cast<Float_t>(0),meanTimeStamp));
451 }
452 else if ( nStartRU > 0 && nRU == 0 && nRD == 0 && nEndRD == 0 )
453 {
454 hvCase = "C";
455 sscanf(internalMsg.Data(),"RU%10d[%10d:%10d]%80s",&dummy,&a,&b,r);
456 MarkForDeletion(indices,a,b);
457 }
458 else if ( nStartRU > 0 && nEndRD > 0 && nRD == 0 && nRU == 0 )
459 {
460 hvCase = "D";
461 sscanf(internalMsg.Data(),"RU%10d[%10d:%10d]%80s",&dummy,&a,&b,r);
462 MarkForDeletion(indices,a,b-1);
463 Int_t i = internalMsg.Index("RD",strlen("RD"),0,TString::kExact);
464 sscanf(internalMsg(i,internalMsg.Length()-i).Data(),
465 "RD%10d[%10d:%10d]%80s",&dummy,&a,&b,r);
466 MarkForDeletion(indices,a+1,b);
467 }
468 else if ( nEndRD > 0 && nStartRU == 0 && nRU == 0 && nRD == 0 )
469 {
470 hvCase = "B";
471 Int_t i = internalMsg.Index("RD",strlen("RD"),0,TString::kExact);
472 sscanf(internalMsg(i,internalMsg.Length()-i).Data(),
473 "RD%10d[%10d:%10d]%80s",&dummy,&a,&b,r);
474 MarkForDeletion(indices,a,b);
475 }
476 else if ( nFluct > 0 )
477 {
478 hvCase = "G";
479 TObjArray* af = internalMsg.Tokenize(" ");
480 TIter next(af);
481 TObjString* str;
482 while ( ( str = static_cast<TObjString*>(next()) ) )
483 {
484 TString s(str->String());
485 if ( s.BeginsWith("FLUCT") )
486 {
487 sscanf(s.Data(),"FLUCT%d[%d:%d]",&dummy,&a,&b);
488 MarkForDeletion(indices,a,b);
489 }
490 }
491 delete af;
492 }
493 else if ( nEndAndShortRU > 0 && nStartRU == 0 && nRU == 0 && nRD == 0 && nEndRD == 0 )
494 {
495 hvCase = "H";
496 sscanf(internalMsg.Data(),"RU%10d[%10d:%10d]%80s",&dummy,&a,&b,r);
497 MarkForDeletion(indices,a,b);
498 }
499 else
500 {
501 // last chance...
502 // here we know it's not a trip, so let's assume everything is OK
503 // if first and last value are in the same ballpark
504
505 const Double_t HVFLUCT(20); // volts
506
507 if ( TMath::Abs(vfirst->GetFloat() - vlast->GetFloat()) < HVFLUCT )
508 {
509 hvCase = "Z";
510 }
511 MarkForDeletion(indices,1,nvalues-1);
32f1b761 512 }
513
b37b9546 514 for ( Int_t i = 0; i < nvalues; ++i )
32f1b761 515 {
b37b9546 516 if ( indices[i] )
517 {
518 values.RemoveAt(i);
519 }
520 }
32f1b761 521
b37b9546 522 values.Compress();
523
524 delete[] indices;
525
526 if ( !values.GetEntries() )
527 {
528 AliErrorClass(Form("No value left after patch... Check that !!! initial # of values=%d msg=%s",
529 nvalues,internalMsg.Data()));
530 hvCase = "OTHER";
531 }
532
533 // take the max of the remaining values
534 TIter nextA(&values);
535 AliDCSValue* val;
536 Float_t maxval(-9999);
537
538 while ( ( val = static_cast<AliDCSValue*>(nextA()) ) )
539 {
540 if ( val->GetFloat() > maxval )
541 {
542 maxval = val->GetFloat();
543 }
544 }
545
546 values.Clear();
547
548 values.Add(new AliDCSValue(maxval,meanTimeStamp));
549
550 // once the case is inferred, add a "CASE:%10d",hvCase.Data()
551 // to the msg
552 // so we can them sum up for all channels and get a summary per run...
553
554 internalMsg += Form("CASE:%s",hvCase.Data());
555
556 if (msg) *msg = internalMsg.Data();
557
558 return hvCase=="OTHER" ? kFALSE : kTRUE;
32f1b761 559}
92c23b09 560
48ed403b 561//_____________________________________________________________________________
5562688f 562TMap*
b37b9546 563AliMUONCalibrationData::CreateHV(Int_t runNumber,
564 Int_t* startOfValidity,
565 Bool_t patched,
566 TList* messages)
c1bbaf66 567{
5562688f 568 /// Create a new HV map from the OCDB for a given run
32f1b761 569 TMap* hvMap = dynamic_cast<TMap*>(CreateObject(runNumber,"MUON/Calib/HV",startOfValidity));
b37b9546 570
8763322f 571 if (!hvMap) return 0x0;
572
32f1b761 573 if (patched)
574 {
575 TIter next(hvMap);
576 TObjString* hvChannelName;
577
578 while ( ( hvChannelName = static_cast<TObjString*>(next()) ) )
579 {
580 TString name(hvChannelName->String());
581
582 if ( name.Contains("sw") ) continue; // skip switches
583
584 TPair* hvPair = static_cast<TPair*>(hvMap->FindObject(name.Data()));
585 TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
586 if (!values)
587 {
588 AliErrorClass(Form("Could not get values for alias %s",name.Data()));
589 }
590 else
591 {
b37b9546 592 TString msg;
593
594 AliDebugClass(1,Form("channel %s",name.Data()));
595 Bool_t ok = PatchHVValues(*values,&msg);
596
597 if ( messages )
598 {
599 messages->Add(new TObjString(Form("%s:%s",hvChannelName->String().Data(),msg.Data())));
600 }
32f1b761 601
b37b9546 602 if (!ok)
32f1b761 603 {
b37b9546 604 AliErrorClass(Form("PatchHVValue was not successfull ! This is serious ! "
605 "You'll have to check the logic for channel %s in run %09d",
606 name.Data(),runNumber));
32f1b761 607 }
608 }
609 }
610
611 }
b37b9546 612
613 if ( messages )
614 {
615 Int_t a(0),b(0),c(0),d(0),e(0),f(0),g(0),h(0),u(0),z(0);
616 TIter next(messages);
617 TObjString* msg;
618 char hvCase;
619
620 while ( ( msg = static_cast<TObjString*>(next()) ) )
621 {
622 Int_t i = msg->String().Index("CASE",strlen("CASE"),0,TString::kExact);
623
624 if ( i >= 0 )
625 {
8763322f 626 sscanf(msg->String()(i,msg->String().Length()-i).Data(),"CASE:%10c",&hvCase);
b37b9546 627 }
628
629 switch (hvCase)
630 {
631 case 'A': ++a; break;
632 case 'B': ++b; break;
633 case 'C': ++c; break;
634 case 'D': ++d; break;
635 case 'E': ++e; break;
636 case 'F': ++f; break;
637 case 'G': ++g; break;
638 case 'H': ++h; break;
639 case 'Z': ++z; break;
640 default: ++u; break;
641 }
642 }
643
644 messages->Add(new TObjString(Form("SUMMARY : # of cases A(%3d) B(%3d) C(%3d) D(%3d) E(%3d) F(%3d) G(%3d) H(%3d) Z(%3d) OTHER(%3d)",
645 a,b,c,d,e,f,g,h,z,u)));
646 }
647
32f1b761 648 return hvMap;
c1bbaf66 649}
650
651//_____________________________________________________________________________
49e110ec 652TMap*
653AliMUONCalibrationData::CreateTriggerDCS(Int_t runNumber, Int_t* startOfValidity)
654{
655 /// Create a new Trigger HV and curent map from the OCDB for a given run
656 return dynamic_cast<TMap*>(CreateObject(runNumber,"MUON/Calib/TriggerDCS",startOfValidity));
657}
658
659//_____________________________________________________________________________
a0eca509 660AliMUONVStore*
143cd71a 661AliMUONCalibrationData::CreateLocalTriggerBoardMasks(Int_t runNumber, Int_t* startOfValidity)
d067ba7c 662{
5562688f 663 /// Get the internal store for LocalTriggerBoardMasks from OCDB
664
143cd71a 665 return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/LocalTriggerBoardMasks",startOfValidity));
d067ba7c 666}
667
668//_____________________________________________________________________________
a0eca509 669AliMUONVStore*
143cd71a 670AliMUONCalibrationData::CreateNeighbours(Int_t runNumber, Int_t* startOfValidity)
48ed403b 671{
5562688f 672 /// Create a neighbour store from the OCDB for a given run
143cd71a 673 return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/Neighbours",startOfValidity));
c5bdf179 674}
675
676//_____________________________________________________________________________
5562688f 677TObject*
143cd71a 678AliMUONCalibrationData::CreateObject(Int_t runNumber, const char* path, Int_t* startOfValidity)
d067ba7c 679{
5562688f 680 /// Access the CDB for a given path (e.g. MUON/Calib/Pedestals),
681 /// and return the corresponding TObject.
d067ba7c 682
b37b9546 683 AliCodeTimerAutoClass(Form("%09d : %s",runNumber,path),0);
4bec0403 684
5562688f 685 AliCDBManager* man = AliCDBManager::Instance();
686
465302eb 687 AliCDBEntry* entry = man->Get(path,runNumber);
5562688f 688
5562688f 689 if (entry)
d067ba7c 690 {
143cd71a 691 if ( startOfValidity ) *startOfValidity = entry->GetId().GetFirstRun();
692
4bec0403 693 TObject* object = entry->GetObject();
82586209 694 if (!(man->GetCacheFlag()))
695 {
696 entry->SetOwner(kFALSE);
697 delete entry;
698 }
4bec0403 699 return object;
700 }
143cd71a 701 else
702 {
703 if ( startOfValidity ) *startOfValidity = AliCDBRunRange::Infinity();
704 }
705
0045b488 706 {
707
b37b9546 708 AliCodeTimerAutoClass(Form("Failed to get %s for run %09d",path,runNumber),1);
0045b488 709
710 }
711
5562688f 712 return 0x0;
d067ba7c 713}
714
715//_____________________________________________________________________________
a0eca509 716AliMUONVStore*
7eafe398 717AliMUONCalibrationData::CreateOccupancyMap(Int_t runNumber, Int_t* startOfValidity)
2b8a1212 718{
7eafe398 719 /// Create a new occupancy map store from the OCDB for a given run
720 return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/OccupancyMap",startOfValidity));
2b8a1212 721}
722
723//_____________________________________________________________________________
0045b488 724AliMUONRejectList*
725AliMUONCalibrationData::CreateRejectList(Int_t runNumber, Int_t* startOfValidity)
726{
727 /// Create a new rejectlist store from the OCDB for a given run
728 return dynamic_cast<AliMUONRejectList*>(CreateObject(runNumber,"MUON/Calib/RejectList",startOfValidity));
729}
730
731//_____________________________________________________________________________
2b8a1212 732AliMUONVStore*
143cd71a 733AliMUONCalibrationData::CreatePedestals(Int_t runNumber, Int_t* startOfValidity)
c1bbaf66 734{
5562688f 735 /// Create a new pedestal store from the OCDB for a given run
143cd71a 736 return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/Pedestals",startOfValidity));
c1bbaf66 737}
738
6c870207 739//_____________________________________________________________________________
740AliMUONVStore*
741AliMUONCalibrationData::CreateConfig(Int_t runNumber, Int_t* startOfValidity)
742{
743 /// Create a new config store from the OCDB for a given run
744 return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/Config",startOfValidity));
745}
746
92c23b09 747
c1bbaf66 748//_____________________________________________________________________________
92c23b09 749AliMUONRegionalTriggerConfig*
143cd71a 750AliMUONCalibrationData::CreateRegionalTriggerConfig(Int_t runNumber, Int_t* startOfValidity)
5562688f 751{
92c23b09 752 /// Create the internal store for RegionalTriggerConfig from OCDB
5562688f 753
143cd71a 754 return dynamic_cast<AliMUONRegionalTriggerConfig*>(CreateObject(runNumber,"MUON/Calib/RegionalTriggerConfig",startOfValidity));
5562688f 755}
756
757//_____________________________________________________________________________
758AliMUONTriggerEfficiencyCells*
143cd71a 759AliMUONCalibrationData::CreateTriggerEfficiency(Int_t runNumber, Int_t* startOfValidity)
c5bdf179 760{
5562688f 761 /// Create trigger efficiency object from OCBD
762
143cd71a 763 return dynamic_cast<AliMUONTriggerEfficiencyCells*>(CreateObject(runNumber,"MUON/Calib/TriggerEfficiency",startOfValidity));
5562688f 764}
5398f946 765
5562688f 766//_____________________________________________________________________________
767AliMUONTriggerLut*
143cd71a 768AliMUONCalibrationData::CreateTriggerLut(Int_t runNumber, Int_t* startOfValidity)
5562688f 769{
770 /// Create trigger LUT from OCDB
771
143cd71a 772 return dynamic_cast<AliMUONTriggerLut*>(CreateObject(runNumber,"MUON/Calib/TriggerLut",startOfValidity));
5562688f 773}
774
775//_____________________________________________________________________________
776AliMUONVStore*
777AliMUONCalibrationData::Gains() const
778{
779 /// Create (if needed) and return the internal store for gains.
9ee1d6ff 780 if (fgBypassGains) return fgBypassGains;
8f29b706 781
c5bdf179 782 if (!fGains)
783 {
5562688f 784 fGains = CreateGains(fRunNumber);
c5bdf179 785 }
786 return fGains;
787}
b37b9546 788
c5bdf179 789//_____________________________________________________________________________
5562688f 790AliMUONVCalibParam*
791AliMUONCalibrationData::Gains(Int_t detElemId, Int_t manuId) const
e7d7fa47 792{
5562688f 793/// Return the gains for a given (detElemId, manuId) pair
794/// Note that, unlike the DeadChannel case, if the result is 0x0, that's an
795/// error (meaning that we should get gains for all channels).
5398f946 796
5562688f 797 AliMUONVStore* gains = Gains();
798 if (!gains)
799 {
800 return 0x0;
801 }
802
803 return static_cast<AliMUONVCalibParam*>(gains->FindObject(detElemId,manuId));
e7d7fa47 804}
805
806//_____________________________________________________________________________
92c23b09 807AliMUONGlobalCrateConfig*
808AliMUONCalibrationData::GlobalTriggerCrateConfig() const
e7d7fa47 809{
92c23b09 810 /// Return the config for the global trigger board.
5562688f 811
92c23b09 812 if (!fGlobalTriggerCrateConfig)
e7d7fa47 813 {
92c23b09 814 fGlobalTriggerCrateConfig = CreateGlobalTriggerCrateConfig(fRunNumber);
e7d7fa47 815 }
92c23b09 816 return fGlobalTriggerCrateConfig;
e7d7fa47 817}
818
92c23b09 819
e7d7fa47 820//_____________________________________________________________________________
5562688f 821TMap*
32f1b761 822AliMUONCalibrationData::HV(Bool_t patched) const
e7d7fa47 823{
5562688f 824 /// Return the calibration for a given (detElemId, manuId) pair
48ed403b 825
5562688f 826 if (!fHV)
e7d7fa47 827 {
32f1b761 828 fHV = CreateHV(fRunNumber,0,patched);
e7d7fa47 829 }
5562688f 830 return fHV;
e7d7fa47 831}
832
833//_____________________________________________________________________________
49e110ec 834TMap*
835AliMUONCalibrationData::TriggerDCS() const
836{
837 /// Return the calibration for a given (detElemId, manuId) pair
838
839 if (!fTriggerDCS)
840 {
841 fTriggerDCS = CreateTriggerDCS(fRunNumber);
842 }
843 return fTriggerDCS;
844}
845
846//_____________________________________________________________________________
a0eca509 847AliMUONVStore*
5562688f 848AliMUONCalibrationData::Neighbours() const
e7d7fa47 849{
5562688f 850 /// Create (if needed) and return the internal store for neighbours.
851 if (!fNeighbours)
852 {
853 fNeighbours = CreateNeighbours(fRunNumber);
854 }
855 return fNeighbours;
856}
857
858//_____________________________________________________________________________
859AliMUONVCalibParam*
860AliMUONCalibrationData::LocalTriggerBoardMasks(Int_t localBoardNumber) const
861{
862/// Return the masks for a given trigger local board.
5398f946 863
e7d7fa47 864 if (!fLocalTriggerBoardMasks)
865 {
5562688f 866 fLocalTriggerBoardMasks = CreateLocalTriggerBoardMasks(fRunNumber);
867 }
868
869 if ( fLocalTriggerBoardMasks )
870 {
871 AliMUONVCalibParam* ltbm =
872 static_cast<AliMUONVCalibParam*>(fLocalTriggerBoardMasks->FindObject(localBoardNumber));
873 if (!ltbm)
e7d7fa47 874 {
5562688f 875 AliError(Form("Could not get mask for localBoardNumber=%d",localBoardNumber));
e7d7fa47 876 }
5562688f 877 return ltbm;
e7d7fa47 878 }
5562688f 879 return 0x0;
e7d7fa47 880}
881
882//_____________________________________________________________________________
a0eca509 883AliMUONVStore*
7eafe398 884AliMUONCalibrationData::OccupancyMap() const
2b8a1212 885{
7eafe398 886 /// Get occupancy map
887 if (!fOccupancyMap)
2b8a1212 888 {
7eafe398 889 fOccupancyMap = CreateOccupancyMap(fRunNumber);
2b8a1212 890 }
7eafe398 891 return fOccupancyMap;
2b8a1212 892}
893
894//_____________________________________________________________________________
0045b488 895AliMUONRejectList*
896AliMUONCalibrationData::RejectList() const
897{
898 /// Get reject list
899 if (!fRejectList)
900 {
901 fRejectList = CreateRejectList(fRunNumber);
902 }
903 return fRejectList;
904}
905
906//_____________________________________________________________________________
8f29b706 907void
908AliMUONCalibrationData::BypassStores(AliMUONVStore* ped, AliMUONVStore* gain)
909{
910 /// Force the use of those pedestals and gains
9ee1d6ff 911 fgBypassPedestals = ped;
912 fgBypassGains = gain;
8f29b706 913
914}
915
916//_____________________________________________________________________________
2b8a1212 917AliMUONVStore*
5562688f 918AliMUONCalibrationData::Pedestals() const
c5bdf179 919{
5562688f 920 /// Return pedestals
8f29b706 921
9ee1d6ff 922 if (fgBypassPedestals) return fgBypassPedestals;
8f29b706 923
c5bdf179 924 if (!fPedestals)
925 {
5562688f 926 fPedestals = CreatePedestals(fRunNumber);
c5bdf179 927 }
928 return fPedestals;
929}
930
931//_____________________________________________________________________________
6c870207 932AliMUONVStore*
933AliMUONCalibrationData::Config() const
934{
935 /// Return config
936
937 if (!fConfig)
938 {
939 fConfig = CreateConfig(fRunNumber);
940 }
941 return fConfig;
942}
943
944//_____________________________________________________________________________
5562688f 945AliMUONVCalibParam*
946AliMUONCalibrationData::Pedestals(Int_t detElemId, Int_t manuId) const
947{
948 /// Return the pedestals for a given (detElemId, manuId) pair.
949 /// A return value of 0x0 is considered an error, meaning we should get
950 /// pedestals for all channels.
951
952 AliMUONVStore* pedestals = Pedestals();
953 if (!pedestals)
954 {
955 return 0x0;
956 }
957
958 return static_cast<AliMUONVCalibParam*>(pedestals->FindObject(detElemId,manuId));
959}
960
961//_____________________________________________________________________________
c5bdf179 962void
963AliMUONCalibrationData::Print(Option_t*) const
964{
5562688f 965 /// A very basic dump of our guts.
5398f946 966
c5bdf179 967 cout << "RunNumber " << RunNumber()
e7d7fa47 968 << " fGains=" << fGains
969 << " fPedestals=" << fPedestals
6c870207 970 << " fConfig=" << fConfig
48ed403b 971 << " fHV=" << fHV
49e110ec 972 << " fTriggerDCS=" << fTriggerDCS
e7d7fa47 973 << " fLocalTriggerBoardMasks=" << fLocalTriggerBoardMasks
92c23b09 974 << " fRegionalTriggerConfig=" << fRegionalTriggerConfig
975 << " fGlobalTriggerCrateConfig=" << fGlobalTriggerCrateConfig
e7d7fa47 976 << " fTriggerLut=" << fTriggerLut
c5bdf179 977 << endl;
978}
979
92c23b09 980
48ed403b 981//_____________________________________________________________________________
92c23b09 982AliMUONRegionalTriggerConfig*
983AliMUONCalibrationData::RegionalTriggerConfig() const
e7d7fa47 984{
92c23b09 985 /// Return the config for the regional trigger board.
48ed403b 986
92c23b09 987 if (!fRegionalTriggerConfig)
e7d7fa47 988 {
92c23b09 989 fRegionalTriggerConfig = CreateRegionalTriggerConfig(fRunNumber);
e7d7fa47 990 }
92c23b09 991 return fRegionalTriggerConfig;
e7d7fa47 992}
993
92c23b09 994
e7d7fa47 995//_____________________________________________________________________________
996AliMUONTriggerEfficiencyCells*
997AliMUONCalibrationData::TriggerEfficiency() const
998{
5398f946 999/// Return the trigger efficiency.
1000
e7d7fa47 1001 if (!fTriggerEfficiency)
1002 {
5562688f 1003 fTriggerEfficiency = CreateTriggerEfficiency(fRunNumber);
e7d7fa47 1004 }
1005 return fTriggerEfficiency;
1006}
1007
5562688f 1008
e7d7fa47 1009//_____________________________________________________________________________
1010AliMUONTriggerLut*
1011AliMUONCalibrationData::TriggerLut() const
1012{
5398f946 1013/// Return the trigger look up table.
1014
e7d7fa47 1015 if (!fTriggerLut)
1016 {
5562688f 1017 fTriggerLut = CreateTriggerLut(fRunNumber);
e7d7fa47 1018 }
1019 return fTriggerLut;
1020}
1021
c1bbaf66 1022//_____________________________________________________________________________
1023void
1024AliMUONCalibrationData::Reset()
1025{
1026/// Reset all data
1027
82586209 1028 AliCodeTimerAuto("",0);
1029
6c870207 1030 delete fConfig;
1031 fConfig = 0x0;
c1bbaf66 1032 delete fPedestals;
1033 fPedestals = 0x0;
1034 delete fGains;
1035 fGains = 0x0;
1036 delete fHV;
1037 fHV = 0x0;
49e110ec 1038 delete fTriggerDCS;
1039 fTriggerDCS = 0x0;
c1bbaf66 1040 delete fLocalTriggerBoardMasks;
1041 fLocalTriggerBoardMasks = 0x0;
92c23b09 1042 delete fRegionalTriggerConfig;
1043 fRegionalTriggerConfig = 0x0;
1044 delete fGlobalTriggerCrateConfig;
1045 fGlobalTriggerCrateConfig = 0x0;
1046
c1bbaf66 1047 delete fTriggerLut;
1048 fTriggerLut = 0x0;
1049 delete fTriggerEfficiency;
1050 fTriggerEfficiency = 0x0;
1051 delete fCapacitances;
1052 fCapacitances = 0x0;
d067ba7c 1053 delete fNeighbours;
1054 fNeighbours = 0x0;
c1bbaf66 1055}
1056
630711ed 1057//_____________________________________________________________________________
1058void
1059AliMUONCalibrationData::Check(Int_t runNumber)
1060{
1061 /// Self-check to see if we can read all data for a given run
1062 /// from the current OCDB...
1063
1064 if ( ! CreateCapacitances(runNumber) )
1065 {
1066 AliErrorClass("Could not read capacitances");
1067 }
1068 else
1069 {
1070 AliInfoClass("Capacitances read OK");
1071 }
1072
1073 if ( ! CreateGains(runNumber) )
1074 {
1075 AliErrorClass("Could not read gains");
1076 }
1077 else
1078 {
1079 AliInfoClass("Gains read OK");
1080 }
1081
1082 if ( ! CreateGlobalTriggerCrateConfig(runNumber) )
1083 {
1084 AliErrorClass("Could not read Trigger Crate Config");
1085 }
1086 else
1087 {
1088 AliInfoClass("TriggerBoardMasks read OK");
1089 }
1090
1091 if ( ! CreateHV(runNumber) )
1092 {
1093 AliErrorClass("Could not read HV");
1094 }
1095 else
1096 {
1097 AliInfoClass("HV read OK");
49e110ec 1098 }
1099
1100 if ( ! CreateTriggerDCS(runNumber) )
1101 {
1102 AliErrorClass("Could not read Trigger HV and Currents");
1103 }
1104 else
1105 {
1106 AliInfoClass("Trigger HV and Currents read OK");
630711ed 1107 }
1108
1109 if ( ! CreateNeighbours(runNumber) )
1110 {
1111 AliErrorClass("Could not read Neighbours");
1112 }
1113 else
1114 {
1115 AliInfoClass("Neighbours read OK");
1116 }
1117
1118 if ( ! CreateLocalTriggerBoardMasks(runNumber) )
1119 {
1120 AliErrorClass("Could not read LocalTriggerBoardMasks");
1121 }
1122 else
1123 {
1124 AliInfoClass("LocalTriggerBoardMasks read OK");
1125 }
1126
1127 if ( ! CreatePedestals(runNumber) )
1128 {
1129 AliErrorClass("Could not read pedestals");
1130 }
1131 else
1132 {
1133 AliInfoClass("Pedestals read OK");
1134 }
6c870207 1135
1136 if ( ! CreateConfig(runNumber) )
1137 {
1138 AliErrorClass("Could not read config");
1139 }
1140 else
1141 {
1142 AliInfoClass("Config read OK");
1143 }
630711ed 1144
1145 if ( ! CreateRegionalTriggerConfig(runNumber) )
1146 {
1147 AliErrorClass("Could not read RegionalTriggerConfig");
1148 }
1149 else
1150 {
1151 AliInfoClass("RegionalTriggerBoardMasks read OK");
1152 }
1153
1154 if ( ! CreateTriggerLut(runNumber) )
1155 {
1156 AliErrorClass("Could not read TriggerLut");
1157 }
1158 else
1159 {
1160 AliInfoClass("TriggerLut read OK");
1161 }
1162
1163 if ( ! CreateTriggerEfficiency(runNumber) )
1164 {
1165 AliErrorClass("Could not read TriggerEfficiency");
1166 }
1167 else
1168 {
1169 AliInfoClass("TriggerEfficiency read OK");
1170 }
1171}