]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONCalibrationData.cxx
3f63f3231aa130f1a8a8f99caee819c2813326ab
[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[80];
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 (patched)
573   {
574     TIter next(hvMap);
575     TObjString* hvChannelName;
576     
577     while ( ( hvChannelName = static_cast<TObjString*>(next()) ) )
578     {
579       TString name(hvChannelName->String());
580       
581       if ( name.Contains("sw") ) continue; // skip switches
582       
583       TPair* hvPair = static_cast<TPair*>(hvMap->FindObject(name.Data()));
584       TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
585       if (!values)
586       {
587         AliErrorClass(Form("Could not get values for alias %s",name.Data()));
588       }
589       else
590       {
591         TString msg;
592         
593         AliDebugClass(1,Form("channel %s",name.Data()));
594         Bool_t ok = PatchHVValues(*values,&msg);
595         
596         if ( messages ) 
597         {
598           messages->Add(new TObjString(Form("%s:%s",hvChannelName->String().Data(),msg.Data())));
599         }
600         
601         if (!ok)
602         {
603           AliErrorClass(Form("PatchHVValue was not successfull ! This is serious ! "
604                              "You'll have to check the logic for channel %s in run %09d",
605                              name.Data(),runNumber));
606         }
607       }
608     }
609     
610   }
611   
612   if ( messages ) 
613   {
614     Int_t a(0),b(0),c(0),d(0),e(0),f(0),g(0),h(0),u(0),z(0);
615     TIter next(messages);
616     TObjString* msg;
617     char hvCase;
618     
619     while ( ( msg = static_cast<TObjString*>(next()) ) )
620     {
621       Int_t i = msg->String().Index("CASE",strlen("CASE"),0,TString::kExact);
622       
623       if ( i >= 0 )
624       {
625         sscanf(msg->String()(i,msg->String().Length()-i).Data(),"CASE:%c",&hvCase);
626       }
627
628       switch (hvCase)
629       {
630         case 'A': ++a; break;
631         case 'B': ++b; break;
632         case 'C': ++c; break;
633         case 'D': ++d; break;
634         case 'E': ++e; break;
635         case 'F': ++f; break;
636         case 'G': ++g; break;
637         case 'H': ++h; break;
638         case 'Z': ++z; break;
639         default: ++u; break;
640       }
641     }
642     
643     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)",
644                                       a,b,c,d,e,f,g,h,z,u)));
645   }
646   
647   return hvMap;
648 }
649
650 //_____________________________________________________________________________
651 TMap*
652 AliMUONCalibrationData::CreateTriggerDCS(Int_t runNumber, Int_t* startOfValidity)
653 {
654   /// Create a new Trigger HV and curent map from the OCDB for a given run
655   return dynamic_cast<TMap*>(CreateObject(runNumber,"MUON/Calib/TriggerDCS",startOfValidity));
656 }
657
658 //_____________________________________________________________________________
659 AliMUONVStore*
660 AliMUONCalibrationData::CreateLocalTriggerBoardMasks(Int_t runNumber, Int_t* startOfValidity)
661 {
662   /// Get the internal store for LocalTriggerBoardMasks from OCDB
663   
664   return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/LocalTriggerBoardMasks",startOfValidity));
665 }
666
667 //_____________________________________________________________________________
668 AliMUONVStore*
669 AliMUONCalibrationData::CreateNeighbours(Int_t runNumber, Int_t* startOfValidity)
670 {
671   /// Create a neighbour store from the OCDB for a given run
672   return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/Neighbours",startOfValidity));
673 }
674
675 //_____________________________________________________________________________
676 TObject*
677 AliMUONCalibrationData::CreateObject(Int_t runNumber, const char* path, Int_t* startOfValidity)
678 {
679   /// Access the CDB for a given path (e.g. MUON/Calib/Pedestals),
680   /// and return the corresponding TObject.
681   
682   AliCodeTimerAutoClass(Form("%09d : %s",runNumber,path),0);
683   
684   AliCDBManager* man = AliCDBManager::Instance();
685   
686   AliCDBEntry* entry =  man->Get(path,runNumber);
687   
688   if (entry)
689   {
690                 if ( startOfValidity ) *startOfValidity = entry->GetId().GetFirstRun();
691                 
692     TObject* object = entry->GetObject();
693     if (!(man->GetCacheFlag()))
694     {
695       entry->SetOwner(kFALSE);
696       delete entry;      
697     }
698     return object;
699   }
700         else
701         {
702                 if ( startOfValidity )  *startOfValidity = AliCDBRunRange::Infinity();
703   }
704         
705   {
706     
707     AliCodeTimerAutoClass(Form("Failed to get %s for run %09d",path,runNumber),1);
708
709   }
710   
711   return 0x0;
712 }
713
714 //_____________________________________________________________________________
715 AliMUONVStore*
716 AliMUONCalibrationData::CreateOccupancyMap(Int_t runNumber, Int_t* startOfValidity)
717 {
718   /// Create a new occupancy map store from the OCDB for a given run
719   return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/OccupancyMap",startOfValidity));
720 }
721
722 //_____________________________________________________________________________
723 AliMUONRejectList*
724 AliMUONCalibrationData::CreateRejectList(Int_t runNumber, Int_t* startOfValidity)
725 {
726   /// Create a new rejectlist store from the OCDB for a given run
727   return dynamic_cast<AliMUONRejectList*>(CreateObject(runNumber,"MUON/Calib/RejectList",startOfValidity));
728 }
729
730 //_____________________________________________________________________________
731 AliMUONVStore*
732 AliMUONCalibrationData::CreatePedestals(Int_t runNumber, Int_t* startOfValidity)
733 {
734   /// Create a new pedestal store from the OCDB for a given run
735   return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/Pedestals",startOfValidity));
736 }
737
738 //_____________________________________________________________________________
739 AliMUONVStore*
740 AliMUONCalibrationData::CreateConfig(Int_t runNumber, Int_t* startOfValidity)
741 {
742   /// Create a new config store from the OCDB for a given run
743   return dynamic_cast<AliMUONVStore*>(CreateObject(runNumber,"MUON/Calib/Config",startOfValidity));
744 }
745
746
747 //_____________________________________________________________________________
748 AliMUONRegionalTriggerConfig*
749 AliMUONCalibrationData::CreateRegionalTriggerConfig(Int_t runNumber, Int_t* startOfValidity)
750 {
751   /// Create the internal store for RegionalTriggerConfig from OCDB
752   
753   return dynamic_cast<AliMUONRegionalTriggerConfig*>(CreateObject(runNumber,"MUON/Calib/RegionalTriggerConfig",startOfValidity));
754 }
755
756 //_____________________________________________________________________________
757 AliMUONTriggerEfficiencyCells* 
758 AliMUONCalibrationData::CreateTriggerEfficiency(Int_t runNumber, Int_t* startOfValidity)
759 {
760   /// Create trigger efficiency object from OCBD
761   
762   return dynamic_cast<AliMUONTriggerEfficiencyCells*>(CreateObject(runNumber,"MUON/Calib/TriggerEfficiency",startOfValidity));
763 }
764
765 //_____________________________________________________________________________
766 AliMUONTriggerLut* 
767 AliMUONCalibrationData::CreateTriggerLut(Int_t runNumber, Int_t* startOfValidity)
768 {
769   /// Create trigger LUT from OCDB
770   
771   return dynamic_cast<AliMUONTriggerLut*>(CreateObject(runNumber,"MUON/Calib/TriggerLut",startOfValidity));
772 }
773
774 //_____________________________________________________________________________
775 AliMUONVStore*
776 AliMUONCalibrationData::Gains() const
777 {
778   /// Create (if needed) and return the internal store for gains.
779   if (fgBypassGains) return fgBypassGains;
780   
781   if (!fGains)
782   {
783     fGains = CreateGains(fRunNumber);
784   }
785   return fGains;
786 }
787  
788 //_____________________________________________________________________________
789 AliMUONVCalibParam*
790 AliMUONCalibrationData::Gains(Int_t detElemId, Int_t manuId) const
791 {
792 /// Return the gains for a given (detElemId, manuId) pair
793 /// Note that, unlike the DeadChannel case, if the result is 0x0, that's an
794 /// error (meaning that we should get gains for all channels).
795
796   AliMUONVStore* gains = Gains();
797   if (!gains)
798   {
799     return 0x0;
800   }
801   
802   return static_cast<AliMUONVCalibParam*>(gains->FindObject(detElemId,manuId));
803 }
804
805 //_____________________________________________________________________________
806 AliMUONGlobalCrateConfig* 
807 AliMUONCalibrationData::GlobalTriggerCrateConfig() const
808 {
809   /// Return the config for the global trigger board.
810   
811   if (!fGlobalTriggerCrateConfig)
812   {
813     fGlobalTriggerCrateConfig = CreateGlobalTriggerCrateConfig(fRunNumber);
814   }
815   return fGlobalTriggerCrateConfig;
816 }
817
818
819 //_____________________________________________________________________________
820 TMap*
821 AliMUONCalibrationData::HV(Bool_t patched) const
822 {
823   /// Return the calibration for a given (detElemId, manuId) pair
824   
825   if (!fHV)
826   {
827     fHV = CreateHV(fRunNumber,0,patched);
828   }
829   return fHV;
830 }
831
832 //_____________________________________________________________________________
833 TMap*
834 AliMUONCalibrationData::TriggerDCS() const
835 {
836   /// Return the calibration for a given (detElemId, manuId) pair
837   
838   if (!fTriggerDCS)
839   {
840     fTriggerDCS = CreateTriggerDCS(fRunNumber);
841   }
842   return fTriggerDCS;
843 }
844
845 //_____________________________________________________________________________
846 AliMUONVStore*
847 AliMUONCalibrationData::Neighbours() const
848 {
849   /// Create (if needed) and return the internal store for neighbours.
850   if (!fNeighbours)
851   {
852     fNeighbours = CreateNeighbours(fRunNumber);
853   }
854   return fNeighbours;
855 }
856
857 //_____________________________________________________________________________
858 AliMUONVCalibParam* 
859 AliMUONCalibrationData::LocalTriggerBoardMasks(Int_t localBoardNumber) const
860 {
861 /// Return the masks for a given trigger local board.
862
863   if (!fLocalTriggerBoardMasks)
864   {
865     fLocalTriggerBoardMasks = CreateLocalTriggerBoardMasks(fRunNumber);
866   }
867
868   if ( fLocalTriggerBoardMasks ) 
869   {
870     AliMUONVCalibParam* ltbm = 
871       static_cast<AliMUONVCalibParam*>(fLocalTriggerBoardMasks->FindObject(localBoardNumber));
872     if (!ltbm)
873     {
874       AliError(Form("Could not get mask for localBoardNumber=%d",localBoardNumber));
875     }
876     return ltbm;  
877   }
878   return 0x0;
879 }
880
881 //_____________________________________________________________________________
882 AliMUONVStore*
883 AliMUONCalibrationData::OccupancyMap() const
884 {
885   /// Get occupancy map
886   if (!fOccupancyMap)
887   {
888     fOccupancyMap = CreateOccupancyMap(fRunNumber);
889   }
890   return fOccupancyMap;
891 }
892
893 //_____________________________________________________________________________
894 AliMUONRejectList*
895 AliMUONCalibrationData::RejectList() const
896 {
897   /// Get reject list
898   if (!fRejectList)
899   {
900     fRejectList = CreateRejectList(fRunNumber);
901   }
902   return fRejectList;
903 }
904
905 //_____________________________________________________________________________
906 void
907 AliMUONCalibrationData::BypassStores(AliMUONVStore* ped, AliMUONVStore* gain)
908 {
909   /// Force the use of those pedestals and gains
910   fgBypassPedestals = ped;
911   fgBypassGains = gain;
912   
913 }
914
915 //_____________________________________________________________________________
916 AliMUONVStore*
917 AliMUONCalibrationData::Pedestals() const
918 {
919   /// Return pedestals
920   
921   if (fgBypassPedestals) return fgBypassPedestals;
922   
923   if (!fPedestals)
924   {
925     fPedestals = CreatePedestals(fRunNumber);
926   }
927   return fPedestals;
928 }
929
930 //_____________________________________________________________________________
931 AliMUONVStore*
932 AliMUONCalibrationData::Config() const
933 {
934   /// Return config
935   
936   if (!fConfig)
937   {
938     fConfig = CreateConfig(fRunNumber);
939   }
940   return fConfig;
941 }
942
943 //_____________________________________________________________________________
944 AliMUONVCalibParam*
945 AliMUONCalibrationData::Pedestals(Int_t detElemId, Int_t manuId) const
946 {
947   /// Return the pedestals for a given (detElemId, manuId) pair.
948   /// A return value of 0x0 is considered an error, meaning we should get
949   /// pedestals for all channels.
950   
951   AliMUONVStore* pedestals = Pedestals();
952   if (!pedestals) 
953   {
954     return 0x0;
955   }
956   
957   return static_cast<AliMUONVCalibParam*>(pedestals->FindObject(detElemId,manuId));
958 }
959
960 //_____________________________________________________________________________
961 void
962 AliMUONCalibrationData::Print(Option_t*) const
963 {
964   /// A very basic dump of our guts.
965
966   cout << "RunNumber " << RunNumber()
967   << " fGains=" << fGains
968   << " fPedestals=" << fPedestals
969   << " fConfig=" << fConfig
970   << " fHV=" << fHV
971   << " fTriggerDCS=" << fTriggerDCS
972   << " fLocalTriggerBoardMasks=" << fLocalTriggerBoardMasks
973   << " fRegionalTriggerConfig=" << fRegionalTriggerConfig
974   << " fGlobalTriggerCrateConfig=" << fGlobalTriggerCrateConfig
975   << " fTriggerLut=" << fTriggerLut
976   << endl;
977 }
978
979
980 //_____________________________________________________________________________
981 AliMUONRegionalTriggerConfig* 
982 AliMUONCalibrationData::RegionalTriggerConfig() const
983 {
984   /// Return the config for the regional trigger board.
985   
986   if (!fRegionalTriggerConfig)
987   {
988     fRegionalTriggerConfig = CreateRegionalTriggerConfig(fRunNumber);
989     }
990   return fRegionalTriggerConfig;
991 }
992
993
994 //_____________________________________________________________________________
995 AliMUONTriggerEfficiencyCells*
996 AliMUONCalibrationData::TriggerEfficiency() const
997 {
998 /// Return the trigger efficiency.
999
1000   if (!fTriggerEfficiency)
1001   {
1002     fTriggerEfficiency = CreateTriggerEfficiency(fRunNumber);
1003   }
1004   return fTriggerEfficiency;
1005 }
1006
1007
1008 //_____________________________________________________________________________
1009 AliMUONTriggerLut*
1010 AliMUONCalibrationData::TriggerLut() const
1011 {
1012 /// Return the trigger look up table.
1013
1014   if (!fTriggerLut)
1015   {
1016     fTriggerLut = CreateTriggerLut(fRunNumber);
1017   }
1018   return fTriggerLut;
1019 }
1020
1021 //_____________________________________________________________________________
1022 void
1023 AliMUONCalibrationData::Reset()
1024 {
1025 /// Reset all data
1026
1027   AliCodeTimerAuto("",0);
1028   
1029   delete fConfig;
1030   fConfig = 0x0;
1031   delete fPedestals;
1032   fPedestals = 0x0;
1033   delete fGains;
1034   fGains = 0x0;
1035   delete fHV;
1036   fHV = 0x0;
1037   delete fTriggerDCS;
1038   fTriggerDCS = 0x0;
1039   delete fLocalTriggerBoardMasks;
1040   fLocalTriggerBoardMasks = 0x0;
1041   delete fRegionalTriggerConfig;
1042   fRegionalTriggerConfig = 0x0;
1043   delete fGlobalTriggerCrateConfig;
1044   fGlobalTriggerCrateConfig = 0x0;
1045   
1046   delete fTriggerLut;
1047   fTriggerLut = 0x0;
1048   delete fTriggerEfficiency;
1049   fTriggerEfficiency = 0x0;
1050   delete fCapacitances;
1051   fCapacitances = 0x0;
1052   delete fNeighbours;
1053   fNeighbours = 0x0;
1054 }
1055
1056 //_____________________________________________________________________________
1057 void
1058 AliMUONCalibrationData::Check(Int_t runNumber)
1059 {
1060   /// Self-check to see if we can read all data for a given run 
1061   /// from the current OCDB...
1062   
1063   if ( ! CreateCapacitances(runNumber) )
1064   {
1065     AliErrorClass("Could not read capacitances");
1066   }
1067   else
1068   {
1069     AliInfoClass("Capacitances read OK");
1070   }
1071
1072   if ( ! CreateGains(runNumber) ) 
1073   {
1074     AliErrorClass("Could not read gains");
1075   }
1076   else
1077   {
1078     AliInfoClass("Gains read OK");
1079   }
1080
1081   if ( ! CreateGlobalTriggerCrateConfig(runNumber) ) 
1082   {
1083     AliErrorClass("Could not read Trigger Crate Config");
1084   }
1085   else
1086   {
1087     AliInfoClass("TriggerBoardMasks read OK");
1088   }
1089
1090   if ( !  CreateHV(runNumber) )
1091   {
1092     AliErrorClass("Could not read HV");
1093   }
1094   else
1095   {
1096     AliInfoClass("HV read OK");
1097   }
1098
1099   if ( !  CreateTriggerDCS(runNumber) )
1100   {
1101     AliErrorClass("Could not read Trigger HV and Currents");
1102   }
1103   else
1104   {
1105     AliInfoClass("Trigger HV and Currents read OK");
1106   }
1107
1108   if ( ! CreateNeighbours(runNumber) )
1109   {
1110     AliErrorClass("Could not read Neighbours");
1111   }
1112   else
1113   {
1114     AliInfoClass("Neighbours read OK");
1115   }
1116
1117   if ( !  CreateLocalTriggerBoardMasks(runNumber) )
1118   {
1119     AliErrorClass("Could not read LocalTriggerBoardMasks");
1120   }
1121   else
1122   {
1123     AliInfoClass("LocalTriggerBoardMasks read OK");
1124   }
1125   
1126   if ( ! CreatePedestals(runNumber) )
1127   {
1128     AliErrorClass("Could not read pedestals");
1129   }
1130   else
1131   {
1132     AliInfoClass("Pedestals read OK");
1133   }
1134
1135   if ( ! CreateConfig(runNumber) )
1136   {
1137     AliErrorClass("Could not read config");
1138   }
1139   else
1140   {
1141     AliInfoClass("Config read OK");
1142   }
1143   
1144   if ( ! CreateRegionalTriggerConfig(runNumber) )
1145   {
1146     AliErrorClass("Could not read RegionalTriggerConfig");
1147   }
1148   else
1149   {
1150     AliInfoClass("RegionalTriggerBoardMasks read OK");
1151   }
1152   
1153   if ( ! CreateTriggerLut(runNumber) )
1154   {
1155     AliErrorClass("Could not read TriggerLut");
1156   }
1157   else
1158   {
1159     AliInfoClass("TriggerLut read OK");
1160   }
1161
1162   if ( ! CreateTriggerEfficiency(runNumber) )
1163   {
1164     AliErrorClass("Could not read TriggerEfficiency");
1165   }
1166   else    
1167   {
1168     AliInfoClass("TriggerEfficiency read OK");
1169   }
1170 }