]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONTrackerData.cxx
New time interval for DCS DPs retrieval
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerData.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 "AliMUONTrackerData.h"
19
20 #include "AliCodeTimer.h"
21 #include "AliDAQ.h"
22 #include "AliLog.h"
23 #include "AliMUON1DArray.h"
24 #include "AliMUON1DMap.h"
25 #include "AliMUON2DMap.h"
26 #include "AliMUONCalibParamND.h"
27 #include "AliMUONSparseHisto.h"
28 #include "AliMUONVStore.h"
29 #include "AliMpBusPatch.h"
30 #include "AliMpConstants.h"
31 #include "AliMpCDB.h"
32 #include "AliMpDDLStore.h"
33 #include "AliMpManuStore.h"
34 #include "AliMpDEIterator.h"
35 #include "AliMpDEManager.h"
36 #include "AliMpDetElement.h"
37 #include "AliMpHVNamer.h"
38 #include "AliMpManuIterator.h"
39 #include <Riostream.h>
40 #include <TClass.h>
41 #include <TMath.h>
42 #include <TObjArray.h>
43 #include <TObjString.h>
44 #include <TString.h>
45 #include <TVector2.h>
46 #include <float.h>
47
48 /// \class AliMUONTrackerData
49 ///
50 /// Implementation of AliMUONVTrackerData class
51 ///
52 /// \author Laurent Aphecetche, Subatech
53
54 ///\cond CLASSIMP
55 ClassImp(AliMUONTrackerData)
56 ///\endcond
57
58 const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
59 const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
60
61 //_____________________________________________________________________________
62 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
63                                        Int_t dimension,
64                                        Bool_t issingleevent)
65 : AliMUONVTrackerData(name,title),
66 fIsSingleEvent(issingleevent),
67 fChannelValues(0x0),
68 fManuValues(0x0),
69 fBusPatchValues(0x0),
70 fDEValues(0x0),
71 fChamberValues(0x0),
72 fPCBValues(0x0),
73 fDimension(External2Internal(dimension)+fgkExtraDimension),
74 fNevents(0),
75 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
76 fExternalDimensionNames(new TObjArray(dimension)),
77 fExternalDimension(dimension),
78 fHistogramming(new Int_t[fExternalDimension]),
79 fHistos(0x0),
80 fXmin(0.0),
81 fXmax(0.0),
82 fIsChannelLevelEnabled(kTRUE),
83 fIsManuLevelEnabled(kTRUE),
84 fNofDDLs(0),
85 fNofEventsPerDDL(0x0)
86 {  
87   /// ctor
88   memset(fHistogramming,0,sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
89   fExternalDimensionNames->SetOwner(kTRUE);
90   fDimensionNames->SetOwner(kTRUE);  
91   fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
92   fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
93   fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
94   Clear();
95 }
96
97 //_____________________________________________________________________________
98 AliMUONTrackerData::~AliMUONTrackerData()
99 {
100   /// dtor
101   delete fChannelValues;
102   delete fManuValues;
103   delete fBusPatchValues;
104   delete fDEValues;
105   delete fChamberValues;
106   delete fPCBValues;
107   delete fDimensionNames;
108   delete fExternalDimensionNames;
109   delete[] fHistogramming;
110   delete fHistos;
111   delete[] fNofEventsPerDDL;
112 }
113
114 //_____________________________________________________________________________
115 Bool_t
116 AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents)
117 {
118   /// Add the given external store to our internal store
119   return InternalAdd(store,nevents,kFALSE);
120 }
121
122 //_____________________________________________________________________________
123 Bool_t 
124 AliMUONTrackerData::Add(const AliMUONTrackerData& data)
125 {
126   /// Add data to *this
127   // We do this by looping on all VCalibParam stored in the various containers,
128   // and simply adding the values there.
129   // Same thing for the number of events per DDL.
130   // Same thing for sparsehistograms, if we have some.
131
132   // First cross check we have compatible objects.
133   
134   if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled ) 
135   {
136     AliError("Incompatible IsChannelLevelEnabled status");
137     return kFALSE;
138   }
139   
140   if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled ) 
141   {
142     AliError("Incompatible IsManuLevelEnabled status");
143     return kFALSE;
144   }
145   
146   if ( fIsSingleEvent != data.fIsSingleEvent ) 
147   {
148     AliError("Incompatible IsSingleEvent status");
149     return kFALSE;
150   }
151   
152   if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension ) 
153   {
154     AliError("Incompatible dimensions");
155     return kFALSE;
156   }
157
158   if ( fNofDDLs != data.fNofDDLs ) 
159   {
160     AliError("Incompatible number of Ddls");
161     return kFALSE;
162   }
163   
164   if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming ) 
165       || fXmin != data.fXmin || fXmax != data.fXmax ) 
166   {
167     AliError(Form("Incompatible histogramming (%x vs %x) (xmax = %e vs %e ; xmin = %e vs %e)",
168              fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
169     return kFALSE;
170   }
171
172   if ( fHistogramming )
173   {
174     for ( Int_t i = 0; i < fExternalDimension; ++i ) 
175     {
176       if ( fHistogramming[i] != data.fHistogramming[i] )
177       {
178         AliError(Form("Incompatible histogramming for external dimension %d",i));
179         return kFALSE;
180       }
181     }
182   }
183   
184   // OK. Seems we have compatible objects, so we can proceed with the actual
185   // merging...
186   
187   if ( data.fChannelValues ) 
188   {
189     Add2D(*(data.fChannelValues),*fChannelValues);
190   }
191   
192   if ( data.fManuValues ) 
193   {
194     Add2D(*(data.fManuValues),*fManuValues);
195   }
196   
197   if ( data.fPCBValues ) 
198   {
199     Add2D(*(data.fPCBValues),*fPCBValues);
200   }
201   
202   if ( data.fBusPatchValues ) 
203   {
204     Add1D(*(data.fBusPatchValues),*fBusPatchValues);
205   }
206   
207   if ( data.fDEValues ) 
208   {
209     Add1D(*(data.fDEValues),*fDEValues);
210   }
211   
212   if ( data.fChamberValues ) 
213   {
214     Add1D(*(data.fChamberValues),*fChamberValues);
215   }
216
217   for ( Int_t i = 0; i < fNofDDLs; ++i ) 
218   {
219     fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
220   }
221   
222   if ( data.fHistos ) 
223   {
224     TIter nexthisto(data.fHistos->CreateIterator());
225     AliMUONVStore* store;
226     while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
227     {
228       TIter ns(store->CreateIterator());
229       AliMUONSparseHisto* h;
230       while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
231       {
232         AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
233         
234         if (!thisStore)
235         {
236           thisStore = store->Create();
237           thisStore->SetUniqueID(store->GetUniqueID());
238           fHistos->Add(thisStore);
239         }
240         
241         AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
242         
243         if (!mine) 
244         {
245           thisStore->Add(h);
246         }
247         else
248         {
249           mine->Add(*h);
250         }
251       }
252     }
253   }
254   
255   return kTRUE;
256 }
257
258 //_____________________________________________________________________________
259 void 
260 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
261 {
262   /// Add one 2d store to another
263   
264   TIter next(src.CreateIterator());
265   AliMUONVCalibParam* p;
266   
267   while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
268   {
269     AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
270     
271     if (!a)
272     {
273       dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
274     }
275     else
276     {
277       AddCalibParams(*p,*a);
278     }
279   }
280 }
281
282 //_____________________________________________________________________________
283 void 
284 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
285 {
286   /// Add one 1d store to another
287   
288   TIter next(src.CreateIterator());
289   AliMUONVCalibParam* p;
290   
291   while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
292   {
293     AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
294     
295     if (!a)
296     {
297       dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
298     }
299     else
300     {
301       AddCalibParams(*p,*a);
302     }
303   }
304 }
305
306 //_____________________________________________________________________________
307 void
308 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
309 {
310   /// Add src to dest
311   for ( Int_t i = 0; i < src.Size(); ++i ) 
312   {
313     for ( Int_t j = 0; j < src.Dimension(); ++j )
314     {
315       dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
316     }
317   }
318 }
319
320 //_____________________________________________________________________________
321 Bool_t
322 AliMUONTrackerData::Replace(const AliMUONVStore& store)
323 {
324   /// Replace our values by values from the given external store
325   Bool_t rv = InternalAdd(store,0x0,kTRUE);
326   AliMUONVTrackerData::Replace(store);
327   return rv;
328 }
329
330 //_____________________________________________________________________________
331 Bool_t
332 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
333 {
334   /// Add the given external store to our internal store
335   
336   AliCodeTimerAuto(GetName());
337     
338   if ( !replace)
339   {
340     if ( IsSingleEvent() && NumberOfEvents(-1) == 1 ) 
341     {
342       AliError(Form("%s is supposed to be single event only",GetName()));
343       return kFALSE;
344     }  
345     NumberOfEventsChanged();
346   }
347
348   if (!fNofDDLs)
349   {
350     fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
351     fNofEventsPerDDL = new Int_t[fNofDDLs];
352     for ( Int_t i = 0; i < fNofDDLs; ++i ) 
353     {
354       fNofEventsPerDDL[i] = 0;
355     }
356   }
357     
358   if (nevents)
359   {
360     if (nevents->GetSize() != fNofDDLs ) 
361     {
362       AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
363                     nevents->GetSize(),fNofDDLs));
364       return kFALSE;
365     }
366     
367     for ( Int_t i = 0 ; i < fNofDDLs; ++i ) 
368     {
369       fNofEventsPerDDL[i] += nevents->At(i);
370       fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
371     }
372   }
373   else
374   {
375     for ( Int_t i = 0 ; i < fNofDDLs; ++i ) 
376     {
377       ++fNofEventsPerDDL[i];
378       fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
379     }
380   }
381   
382   if (!fChamberValues)
383   {
384     Int_t numberOfBusPatches(0);
385     Int_t numberOfDEs(0);
386     
387     // get number of bus patches and number of detection element
388     // to initialize fBusPatchValues and fDEValues below
389     
390     TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
391     while ( next() ) ++numberOfBusPatches;
392     AliMpDEIterator deIt;
393     deIt.First();
394     while (!deIt.IsDone())
395     {
396       ++numberOfDEs;
397       deIt.Next();
398     }
399     
400                 if ( fIsChannelLevelEnabled ) 
401                 {
402                         fChannelValues = new AliMUON2DMap(kTRUE);
403                 }
404     if  ( fIsManuLevelEnabled ) 
405     {
406       fManuValues = new AliMUON2DMap(kTRUE);
407     }
408     fPCBValues = new AliMUON2DMap(kFALSE);
409     fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
410     fDEValues = new AliMUON1DMap(numberOfDEs);
411     fChamberValues = new AliMUON1DArray;
412   }
413   
414   TIter next(store.CreateIterator());
415   AliMUONVCalibParam* external;
416   
417   Int_t nk(2);
418   
419   if ( IsSingleEvent() ) nk = 1;
420
421   while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
422   {
423     if ( external->Dimension() != ExternalDimension() )
424     {
425       AliError(Form("Incompatible dimensions %d vs %d",
426                     external->Dimension(),ExternalDimension()));
427       return kFALSE;
428     }
429     
430
431     AliMUONVCalibParam* chamber, *de, *busPatch, *pcb, *manu, *channel;
432     AliMpDetElement* mpde;
433     
434     Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
435     
436     if ( manuId < 0 ) continue;
437     
438     Int_t detElemId = mpde->GetId();
439     
440     Double_t value[] = { 0.0, 0.0 };
441     
442     Int_t nch = mpde->NofChannelsInManu(manuId);
443     
444     for ( Int_t i = 0; i < external->Size(); ++i ) 
445     {
446       Bool_t existingChannel =  ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
447                                                                            : mpde->IsConnectedChannel(manuId,i));
448       // note we only use IsConnectedChannel method when really needed, as
449       // it costs (some) CPU time...
450       
451       if ( existingChannel ) 
452       {
453         Bool_t validChannel(kFALSE);
454         
455         for ( Int_t j = 0; j < external->Dimension(); ++j )
456         {
457           Double_t vext = external->IsDoublePrecision() ? 
458             external->ValueAsDoubleFast(i,j) :
459             external->ValueAsFloatFast(i,j);
460           
461           if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
462           
463           validChannel = kTRUE;
464                     
465           Int_t ix = External2Internal(j);
466           
467           value[0] = vext;
468           value[1] = vext*vext;
469           
470           if ( IsHistogrammed(j) )
471           {
472             FillHisto(detElemId,manuId,i,j,vext);
473           }
474           
475           for ( Int_t k = 0; k < nk; ++k ) 
476           {
477             Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
478             
479                                                 if ( channel ) 
480                                                 {
481                                                         channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
482                                                 }
483                                                 
484             if (manu)
485             {
486               manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);            
487             }
488             
489             busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
490             
491             de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
492             
493             chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
494             
495             if ( pcb ) 
496             {
497               pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
498             }
499           }
500         }
501         
502         if ( validChannel && !replace )
503         {
504                                         if ( channel ) 
505                                         {
506                                                 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
507                                                                                                                                                                         channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
508                                         }
509                                         
510           if (manu)
511           {
512             manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
513                                        manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
514           }
515           
516           busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
517                                                          busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
518           de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
519                                              de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
520           chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
521                                                        chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0); 
522           if ( pcb ) 
523           {
524             pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
525                                       pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
526           }
527         }
528       }
529     }
530   }
531   
532   return kTRUE;
533 }
534
535 //_____________________________________________________________________________
536 Double_t 
537 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
538 {
539   /// Return the value of a given buspatch for a given dimension
540   /// or 0 if not existing
541   AliMUONVCalibParam* param = BusPatchParam(busPatchId);
542   return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
543 }
544
545 //_____________________________________________________________________________
546 AliMUONVCalibParam* 
547 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
548 {
549   /// Return (if it exist), the VCalibParam for a given busPatch
550   
551   AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
552     (fBusPatchValues->FindObject(busPatchId)) : 0x0;
553   
554   if (!busPatch && create && fBusPatchValues)
555   {
556     busPatch = CreateBusPatchParam(busPatchId);
557     fBusPatchValues->Add(busPatch);
558   }
559   
560   return busPatch;
561 }
562
563 //_____________________________________________________________________________
564 AliMUONVCalibParam* 
565 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
566 {
567   /// Create storage for one bus patch
568   
569   AliCodeTimerAuto("");
570   
571   AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
572   
573   if (!bp)
574   {
575     AliError(Form("Got an invalid buspatchId = %d",busPatchId));
576     return 0x0;
577   }
578   
579   AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
580   
581   // set the number of channels in that buspatch
582   
583   Int_t nchannels(0);
584   
585   Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
586   
587   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
588   
589   for ( Int_t i = 0; i < bp->GetNofManus(); ++i ) 
590   {
591     Int_t manuId = bp->GetManuId(i);
592     nchannels += de->NofChannelsInManu(manuId);
593   }
594   
595   busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
596   
597   return busPatch;
598 }
599
600 //_____________________________________________________________________________
601 Double_t 
602 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
603 {
604   /// Return the value fo a given chamber for a given dimension,
605   /// or zero if not existing
606   
607   // FIXME: is the Value() correct wrt to number of events in the case of
608   // chamber ? Or should we do something custom at the chamber level 
609   // (as it spans several ddls) ?
610   
611   AliMUONVCalibParam* param = ChamberParam(chamberId);
612   return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
613 }
614
615 //_____________________________________________________________________________
616 AliMUONVCalibParam* 
617 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
618 {
619   /// Return (if it exist) the VCalibParam for a given chamber
620   
621   AliMUONVCalibParam* chamber =  fChamberValues ? static_cast<AliMUONVCalibParam*>
622   (fChamberValues->FindObject(chamberId)) : 0x0;
623   
624   if (!chamber && create && fChamberValues)
625   {
626     chamber = CreateChamberParam(chamberId);
627     fChamberValues->Add(chamber);
628   }
629     
630   return chamber;
631 }
632
633 //_____________________________________________________________________________
634 AliMUONVCalibParam* 
635 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
636 {
637   /// Create storage for one chamber
638   
639   AliCodeTimerAuto("");
640   
641   AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
642   
643   // set the number of channels in that chamber
644   
645   Int_t nchannels(0);
646   
647   AliMpDEIterator it;
648   
649   it.First(chamberId);
650   
651   while ( !it.IsDone() )
652   {        
653     AliMpDetElement* det = it.CurrentDE();
654     
655     for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
656     {
657       Int_t busPatchId = det->GetBusPatchId(i);
658       AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
659       for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
660       {
661         Int_t manuId = bp->GetManuId(j);
662         nchannels += det->NofChannelsInManu(manuId);
663       }        
664     }
665     
666     it.Next();
667   }
668   
669   chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
670   
671   return chamber;
672 }
673
674 //_____________________________________________________________________________
675 Double_t 
676 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId, 
677                             Int_t manuChannel, Int_t dim) const
678 {
679   /// Return the value for a given channel for a given dimension
680   
681   AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
682   
683   return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
684 }
685
686 //_____________________________________________________________________________
687 AliMUONVCalibParam* 
688 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
689                                  AliMUONVCalibParam* external) const
690 {
691   /// Return (if it exist) the VCalibParam for a given manu
692   
693   AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
694     (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
695   
696   if (!param && external && fChannelValues)
697   {
698     param = CreateDouble(*external,detElemId,manuId);
699     fChannelValues->Add(param);
700   }
701   
702   return param;
703 }
704
705 //_____________________________________________________________________________
706 void 
707 AliMUONTrackerData::Clear(Option_t*)
708 {
709   /// Clear all the values
710   if ( fChannelValues ) fChannelValues->Clear();
711   if ( fManuValues ) fManuValues->Clear();
712   if ( fBusPatchValues) fBusPatchValues->Clear();
713   if ( fPCBValues ) fPCBValues->Clear();
714   if ( fDEValues) fDEValues->Clear();
715   if ( fChamberValues ) fChamberValues->Clear();
716   if ( fHistos ) fHistos->Clear();
717   for ( Int_t i = 0; i < fNofDDLs; ++i ) 
718   {
719     fNofEventsPerDDL[i] = 0;
720   }
721   NumberOfEventsChanged();
722 }
723
724 //_____________________________________________________________________________
725 Double_t 
726 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId, 
727                           Int_t manuChannel) const
728 {
729   /// Return the number of times a given channel had data
730   
731   return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
732 }
733
734 //_____________________________________________________________________________
735 AliMUONVCalibParam*
736 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param, 
737                                  Int_t detElemId, Int_t manuId) const
738 {
739   /// Create a double version of VCalibParam, for internal use
740   
741   AliCodeTimerAuto("");
742   
743   AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
744                                                   param.Size(),
745                                                   detElemId,
746                                                   manuId,
747                                                   0.0);
748   
749   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
750   
751   for ( Int_t i = 0; i < c->Size(); ++i ) 
752   {
753     Double_t value(0.0);
754     
755     if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
756       
757     c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
758   }
759   
760   return c;
761 }
762
763 //_____________________________________________________________________________
764 Double_t 
765 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
766 {
767   /// Return the value for a given detection element for a given dimension
768   AliMUONVCalibParam* param = DetectionElementParam(detElemId);
769   return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
770
771 }
772
773 //_____________________________________________________________________________
774 AliMUONVCalibParam* 
775 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
776 {
777   /// Return (if it exist) the VCalibParam for a given detection element
778   
779   AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
780     (fDEValues->FindObject(detElemId)) : 0x0 ;
781   
782   if (!de && create && fDEValues)
783   {
784     de = CreateDetectionElementParam(detElemId);
785     fDEValues->Add(de);
786   }
787   
788   return de;
789   
790 }
791
792 //_____________________________________________________________________________
793 AliMUONVCalibParam* 
794 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
795 {
796   /// Create storage for one detection element
797   
798   AliCodeTimerAuto("");
799   
800   AliMUONVCalibParam*  de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
801   
802   AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
803   Int_t nchannels(0);
804   
805   for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
806   {
807     Int_t busPatchId = det->GetBusPatchId(i);
808     AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
809     for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
810     {
811       Int_t manuId = bp->GetManuId(j);
812       nchannels += det->NofChannelsInManu(manuId);
813     }        
814   }
815   
816   de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
817   
818   return de;
819 }
820
821 //_____________________________________________________________________________
822 Int_t 
823 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
824 {
825   /// Get the "local" ddlid (0..19) of a given buspatch
826   AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
827   if (bp)
828   {
829     return bp->GetDdlId();
830   }
831   return -1;
832 }
833
834 //_____________________________________________________________________________
835 Int_t 
836 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
837 {
838   /// Get the "local" ddlid (0..19) of a given detection element
839   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
840   if (de)
841   {
842     return de->GetDdlId();
843   }
844   return -1;
845 }
846
847 //_____________________________________________________________________________
848 Int_t 
849 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
850 {
851   /// Get the "local" ddlid (0..19) of a given chamber
852   /// This has no real meaning (as there are several ddls per chamber),
853   /// so we take the ddlid where we got the max number of events
854   
855   AliMpDEIterator it;
856   
857   it.First(chamberid);
858   Int_t n(0);
859   Int_t d(-1);
860   
861   while (!it.IsDone())
862   {
863     Int_t detElemId = it.CurrentDEId();
864     Int_t ddlId = DdlIdFromDetElemId(detElemId);
865     if ( NumberOfEvents(ddlId) > n ) 
866     {
867       n = NumberOfEvents(ddlId);
868       d = ddlId;
869     }
870     it.Next();
871   }
872   
873   return d;
874 }
875
876 //_____________________________________________________________________________
877 TString 
878 AliMUONTrackerData::DimensionName(Int_t dim) const
879 {
880   /// Get the name of a given dimension
881   TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
882   if ( value ) 
883   {
884     return value->String();
885   }
886   else
887   {
888     return TString("Invalid");
889   }  
890 }
891
892 //_____________________________________________________________________________
893 void 
894 AliMUONTrackerData::DisableChannelLevel()
895
896   /// Disable the storing of data at channel level
897   
898   delete fChannelValues;
899   fChannelValues = 0x0;
900   fIsChannelLevelEnabled = kFALSE; 
901 }
902
903 //_____________________________________________________________________________
904 void 
905 AliMUONTrackerData::DisableManuLevel()
906
907   /// Disable the storing of data at manu level (and below)
908   
909   DisableChannelLevel();
910   delete fManuValues;
911   fManuValues = 0x0;
912   fIsManuLevelEnabled = kFALSE; 
913 }
914
915 //_____________________________________________________________________________
916 Int_t 
917 AliMUONTrackerData::External2Internal(Int_t index) const 
918 {
919   /// From external to internal dimension
920   return IsSingleEvent() ? index : index*2;
921 }
922
923 //_____________________________________________________________________________
924 TString 
925 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
926 {
927   /// Get the name of a given external dimension
928   
929   TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
930   if ( value ) 
931   {
932     return value->String();
933   }
934   else
935   {
936     return TString("Invalid");
937   }  
938 }
939
940 //_____________________________________________________________________________
941 void
942 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
943                               Int_t dim, Double_t value)
944 {
945   /// Fill histogram of a given channel
946   
947   AliMUONSparseHisto* h(0x0);
948   
949         if ( fIsChannelLevelEnabled ) 
950         {
951                 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
952   }
953   else if ( fIsManuLevelEnabled ) 
954   {
955     h = GetManuSparseHisto(detElemId,manuId,dim);
956   }
957   
958   AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
959   
960   if (h)
961   {
962                 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
963         }
964 }
965
966 //_____________________________________________________________________________
967 AliMUONSparseHisto*
968 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, 
969                                        Int_t dim) const
970 {
971   /// Get histogram of a given manu
972   
973   if (!fHistos) return 0x0;
974   
975   AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
976   if (!m) return 0x0;
977   
978   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
979   
980   return h;
981 }
982
983 //_____________________________________________________________________________
984 AliMUONSparseHisto*
985 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
986 {
987   /// Get histogram of a given manu. Create it if necessary
988   
989   if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
990   
991   AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
992   if (!m)
993   {
994     m = new AliMUON1DArray(NumberOfDimensions());
995     m->SetUniqueID( ( manuId << 16 ) | detElemId );
996     fHistos->Add(m);
997   }
998     
999   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1000   if (!h)
1001   {
1002     h = new AliMUONSparseHisto(fXmin,fXmax);
1003     
1004     h->SetUniqueID(dim);
1005     
1006     m->Add(h);
1007   }
1008   
1009    return h;
1010 }
1011
1012 //_____________________________________________________________________________
1013 AliMUONSparseHisto*
1014 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, 
1015                                           Int_t manuChannel, Int_t dim) const
1016 {
1017   /// Get histogram of a given channel
1018   
1019   if (!fHistos) return 0x0;
1020   
1021   AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1022   if (!m) return 0x0;
1023   
1024   UInt_t uid = ( manuChannel << 16 ) | dim;
1025   
1026   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1027   
1028   return h;
1029 }
1030
1031 //_____________________________________________________________________________
1032 AliMUONSparseHisto*
1033 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, 
1034                                           Int_t manuChannel, Int_t dim)
1035 {
1036   /// Get histogram of a given channel. Create it if necessary
1037   
1038   if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1039   
1040   AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1041   if (!m)
1042   {
1043     m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1044     m->SetUniqueID( ( manuId << 16 ) | detElemId );
1045     fHistos->Add(m);
1046   }
1047   
1048   UInt_t uid = ( manuChannel << 16 ) | dim;
1049   
1050   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1051   if (!h)
1052   {
1053     h = new AliMUONSparseHisto(fXmin,fXmax);
1054     
1055     h->SetUniqueID(uid);
1056     
1057     m->Add(h);
1058   }
1059
1060   return h;
1061 }
1062
1063 //_____________________________________________________________________________
1064 void
1065 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1066                               Int_t& detElemId, Int_t& manuId) const
1067 {
1068   /// Tries to get (detElemId,manuId) of param
1069   
1070   // Load mapping manu store
1071   if ( ! AliMpCDB::LoadManuStore() ) {
1072     AliError("Could not access manu store from OCDB !");
1073     return;
1074   }
1075
1076   if ( param.ID1() <= 0 ) 
1077   {
1078     // we (probably) get a manu serial number
1079     Int_t serial = param.ID0();
1080     AliMpIntPair pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1081     detElemId = pair.GetFirst();
1082     manuId = pair.GetSecond();
1083     if ( !detElemId ) 
1084     {
1085       AliError(Form("DE %d manuId %d from serial %d is not correct !",
1086                     detElemId,manuId,serial));
1087     }
1088   }
1089   else
1090   {
1091     // we get a (de,manu) pair
1092     detElemId = param.ID0();
1093     manuId = param.ID1();
1094   }
1095 }
1096
1097
1098 //_____________________________________________________________________________
1099 Int_t
1100 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1101                              AliMUONVCalibParam*& chamber,
1102                              AliMUONVCalibParam*& de,
1103                              AliMUONVCalibParam*& busPatch,
1104                              AliMUONVCalibParam*& pcb,
1105                              AliMUONVCalibParam*& manu,
1106                              AliMUONVCalibParam*& channel,
1107                              AliMpDetElement*& mpde)
1108 {
1109   /// Get containers at all levels
1110  
1111   AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1112   
1113   Int_t detElemId;
1114   Int_t manuId;
1115   
1116   GetDEManu(*external,detElemId,manuId);
1117   
1118   mpde = ddlStore->GetDetElement(detElemId);
1119
1120   Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1121     
1122   Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1123   
1124   Int_t pcbIndex = -1;
1125   
1126   AliMp::StationType stationType = mpde->GetStationType();
1127   
1128   if ( stationType == AliMp::kStation345 ) 
1129   {
1130     AliMpHVNamer namer;
1131     pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1132   }
1133   
1134   channel = ChannelParam(detElemId,manuId,external);
1135   
1136   manu = ManuParam(detElemId,manuId,kTRUE);
1137   
1138   busPatch = BusPatchParam(busPatchId,kTRUE);
1139   
1140   de = DetectionElementParam(detElemId,kTRUE);
1141   
1142   chamber = ChamberParam(chamberId,kTRUE);
1143   
1144   pcb = 0x0;
1145   
1146   if ( pcbIndex >= 0 ) 
1147   {
1148     pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1149   }
1150   
1151   return manuId;
1152 }
1153
1154 //_____________________________________________________________________________
1155 Bool_t 
1156 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1157 {
1158   /// Whether we have data for a given buspatch
1159   return ( BusPatchParam(busPatchId) != 0 );
1160 }
1161
1162 //_____________________________________________________________________________
1163 Bool_t 
1164 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1165 {
1166   /// Whether we have data for a given chamber
1167   return ( ChamberParam(chamberId) != 0 );
1168 }
1169
1170 //_____________________________________________________________________________
1171 Bool_t 
1172 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1173 {
1174   /// Whether we have data for a given detection element
1175   return ( DetectionElementParam(detElemId) != 0 );
1176 }
1177
1178 //_____________________________________________________________________________
1179 Bool_t
1180 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1181 {
1182   /// Whether we have data for a given manu
1183   return ( ManuParam(detElemId,manuId) != 0 ); 
1184 }
1185
1186 //_____________________________________________________________________________
1187 Bool_t
1188 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1189 {
1190   /// Whether we have data for a given pcb
1191   return ( PCBParam(detElemId,pcbIndex) != 0 ); 
1192 }
1193
1194 //_____________________________________________________________________________
1195 Double_t 
1196 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1197 {
1198   /// Return the value for a given manu and a given dimension
1199   
1200   AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1201   return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1202 }
1203
1204 //_____________________________________________________________________________
1205 AliMUONVCalibParam* 
1206 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1207 {
1208   /// Get the VCalibParam for a given manu
1209   
1210   AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1211     (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1212   
1213   if (!manu && create && fManuValues)
1214   {
1215     manu = CreateManuParam(detElemId,manuId);
1216     fManuValues->Add(manu);
1217   }
1218   
1219   return manu;
1220 }
1221
1222 //_____________________________________________________________________________
1223 AliMUONVCalibParam* 
1224 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1225 {
1226   /// Create storage for one manu
1227   
1228   AliCodeTimerAuto("");
1229   
1230   AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1231   
1232   // set the number of channels in that manu
1233   
1234   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1235   
1236   manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1237   
1238   return manu;
1239 }
1240
1241 //_____________________________________________________________________________
1242 Long64_t
1243 AliMUONTrackerData::Merge(TCollection* list)
1244 {
1245   /// Merge this with a list of AliMUONVTrackerData
1246
1247   if (!list) return 0;
1248   
1249   if ( list->IsEmpty() ) return NumberOfEvents(-1);
1250   
1251   TIter next(list);
1252   const TObject* o(0x0);
1253   
1254   while ( ( o = next() ) )
1255   {
1256     const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1257     if (!o)
1258     {
1259       AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1260                     o->GetName()));
1261     }
1262     else
1263     {
1264       Bool_t ok = Add(*data);
1265       if (!ok)
1266       {
1267         AliError("Got incompatible objects");
1268       }
1269     }
1270   }
1271   
1272   return NumberOfEvents(-1);
1273 }
1274
1275 //_____________________________________________________________________________
1276 Int_t 
1277 AliMUONTrackerData::NumberOfDimensions() const
1278 {
1279   /// Number of dimensions we're dealing with
1280   
1281   return fDimension + fgkVirtualExtraDimension; 
1282 }
1283
1284 //_____________________________________________________________________________
1285 Int_t
1286 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1287 {
1288   /// Get the number of events we've seen for a given DDL, or the max
1289   /// in case ddlNumber<0
1290
1291   Int_t n(0);
1292   
1293   if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1294   {
1295     n = fNofEventsPerDDL[ddlNumber];
1296   }
1297   else
1298   {
1299     // get the max number of events
1300     return fNevents;
1301   }
1302   
1303   return n;
1304 }
1305
1306 //_____________________________________________________________________________
1307 Double_t 
1308 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1309 {
1310   /// Return the value of a given pcb for a given dimension
1311
1312   AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1313   
1314   return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1315 }
1316
1317 //_____________________________________________________________________________
1318 AliMUONVCalibParam* 
1319 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1320 {
1321   /// Return (if it exist) the VCalibParam for a given pcb
1322
1323   AliMUONVCalibParam* pcb =  fPCBValues ? static_cast<AliMUONVCalibParam*>
1324     (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1325   
1326   if (create && fPCBValues && !pcb)
1327   {
1328     pcb = CreatePCBParam(detElemId,pcbIndex);
1329     fPCBValues->Add(pcb);
1330   }
1331   
1332   return pcb;
1333 }
1334
1335 //_____________________________________________________________________________
1336 AliMUONVCalibParam* 
1337 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1338 {
1339   /// Create storage for one PCB (station345 only)
1340   
1341   AliCodeTimerAuto("");
1342   
1343   AliMpHVNamer namer;
1344   
1345   AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1346                                                     namer.NumberOfPCBs(detElemId),
1347                                                     detElemId,
1348                                                     pcbIndex,
1349                                                     0.0);
1350   return pcb;
1351 }
1352
1353 //_____________________________________________________________________________
1354 void 
1355 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1356 {
1357   /// Printout
1358   
1359   TNamed::Print(opt);
1360   
1361   if ( !fIsSingleEvent ) 
1362   {
1363     for ( Int_t i = 0; i < fNofDDLs; ++i ) 
1364     {
1365       cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1366     }
1367   }
1368
1369         if ( !fIsChannelLevelEnabled ) 
1370         {
1371                 cout << "Is not storing data at the channel level" << endl;
1372         }
1373
1374   if ( !fIsManuLevelEnabled ) 
1375         {
1376                 cout << "Is not storing data at the manu level" << endl;
1377         }
1378   
1379   for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i ) 
1380   {
1381     TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1382     cout << Form("External Dimension %2d Name %s %s",i,
1383                  ( name ? name->String().Data() : "null"),
1384                  ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1385   }
1386   
1387   for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i ) 
1388   {
1389     TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1390     cout << Form("Internal Dimension %2d Name %s",i,
1391                  ( name ? name->String().Data() : "null")) << endl;
1392   }
1393     
1394   TString sopt(opt);
1395   sopt.ToUpper();
1396   
1397   if ( sopt.Contains("CHANNEL") )
1398   {
1399     if ( fIsChannelLevelEnabled ) 
1400     {      
1401       if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1402     }
1403     else
1404     {
1405       AliWarning("You requested channel values, but they were not stored !");
1406     }
1407   }
1408
1409   if ( sopt.Contains("MANU") )
1410   {
1411     if ( fIsManuLevelEnabled ) 
1412     {
1413       if ( fManuValues ) fManuValues->Print(wildcard,opt);
1414     }
1415     else
1416     {
1417       AliWarning("You requested manu values, but they were not stored !");
1418     }
1419   }
1420
1421   if ( sopt.Contains("BUSPATCH") && fBusPatchValues ) 
1422   {
1423     fBusPatchValues->Print(wildcard,opt);
1424   }
1425
1426   if ( sopt.Contains("DE") && fDEValues ) 
1427   {
1428     fDEValues->Print(wildcard,opt);
1429   }
1430
1431   if ( sopt.Contains("CHAMBER") && fChamberValues ) 
1432   {
1433     fChamberValues->Print(wildcard,opt);
1434   }
1435   
1436 }
1437
1438 //_____________________________________________________________________________
1439 void
1440 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
1441 {  
1442   /// Set the name of a given dimension
1443
1444   if ( index >= fExternalDimension ) 
1445   {
1446     AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1447     return;
1448   }
1449   
1450   Int_t ix = External2Internal(index);
1451   
1452   if ( !IsSingleEvent() ) 
1453   {
1454     const char* prefix[] = { "mean", "sigma" };
1455   
1456     for ( Int_t i = 0; i < 2; ++i ) 
1457     {
1458       Int_t j = ix+i;
1459     
1460       SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
1461     }
1462   }
1463   else
1464   {
1465     SetInternalDimensionName(index,name);
1466   }
1467   
1468   SetExternalDimensionName(index,name);
1469 }
1470
1471 //_____________________________________________________________________________
1472 void 
1473 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
1474 {
1475   /// decide to make histos for a given dimension
1476   if ( index >= ExternalDimension() ) 
1477   {
1478     AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
1479     return;
1480   }
1481   
1482   fHistogramming[index] = value;
1483   fXmin = xmin;
1484   fXmax = xmax;
1485 }
1486
1487 //_____________________________________________________________________________
1488 void 
1489 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
1490 {
1491   /// Set the name of a given internal dimension
1492   if ( index >= fDimension ) 
1493   {
1494     AliError(Form("Index out of bounds : %d / %d",index,fDimension));
1495     return;
1496   }
1497   
1498   TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
1499     
1500   if ( ovalue ) 
1501   {
1502     fDimensionNames->Remove(ovalue);
1503     delete ovalue;
1504   }
1505   fDimensionNames->AddAt(new TObjString(value),index);
1506 }
1507
1508 //_____________________________________________________________________________
1509 void 
1510 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
1511 {
1512   /// Set the name of a given external dimension
1513   if ( index >= fExternalDimension ) 
1514   {
1515     AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1516     return;
1517   }
1518   
1519   TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
1520   
1521   if ( ovalue ) 
1522   {
1523     fExternalDimensionNames->Remove(ovalue);
1524     delete ovalue;
1525   }
1526   fExternalDimensionNames->AddAt(new TObjString(value),index);
1527 }
1528
1529 //_____________________________________________________________________________
1530 Double_t 
1531 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, 
1532                           Int_t dim, Int_t ddlId) const
1533 {
1534   /// Compute the value for a given dim, using the internal information we have
1535   /// Basically we're converting sum of weights and sum of squares of weights
1536   /// into means and sigmas, and number of events into occupancy number.
1537
1538   Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
1539   
1540   if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
1541   
1542   Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
1543
1544   if ( dim >= fDimension ) 
1545   {
1546     return occ;
1547   }
1548   
1549   if ( dim == IndexOfOccupancyDimension() ) 
1550   {
1551     if ( ddlId < 0 ) AliError("Got a negative ddl id !");
1552     return occ/n/NumberOfEvents(ddlId);
1553   }
1554   
1555   Double_t value = param.ValueAsDouble(i,dim);
1556   
1557   if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
1558   
1559   if ( TMath::Even(dim) || IsSingleEvent() ) 
1560   {
1561                 Double_t x = value/occ;
1562                 
1563                 return ( TMath::Finite(x) ? x : 0.0 ) ;
1564   }
1565   else
1566   {
1567     Double_t nn = occ;
1568     
1569     if ( nn > 1.0 ) 
1570     {
1571       Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
1572     
1573       return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
1574     }
1575     else
1576     {
1577       return 0.0;
1578     }
1579   }
1580   
1581   AliError("Why am I here ?");
1582   return 0.0;
1583 }
1584
1585 //_____________________________________________________________________________
1586 void 
1587 AliMUONTrackerData::Streamer(TBuffer &R__b)
1588 {
1589   /// Customized streamer                                                    
1590   
1591   if (R__b.IsReading()) {
1592     AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
1593     if ( !fNofDDLs )
1594     {
1595       // backward compatible mode : we set number of events
1596       // per DDL to the total number of events (the only information
1597       // we had before version 7 of that class)
1598       delete[] fNofEventsPerDDL;
1599       fNofDDLs=20;
1600       fNofEventsPerDDL = new Int_t[fNofDDLs];
1601       for ( Int_t i = 0; i < fNofDDLs; ++i ) 
1602       {
1603         fNofEventsPerDDL[i] = fNevents;
1604       }
1605     }
1606   } 
1607   else {
1608     AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
1609   }
1610 }
1611
1612