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