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