Fixes for #86059: Install data when ALICE_ROOT does not point to source (Christian)
[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 "AliMUONRejectList.h"
28 #include "AliMUONSparseHisto.h"
29 #include "AliMUONVStore.h"
30 #include "AliMpBusPatch.h"
31 #include "AliMpConstants.h"
32 #include "AliMpCDB.h"
33 #include "AliMpDDLStore.h"
34 #include "AliMpManuStore.h"
35 #include "AliMpDEIterator.h"
36 #include "AliMpDEManager.h"
37 #include "AliMpDetElement.h"
38 #include "AliMpDCSNamer.h"
39 #include "AliMpManuIterator.h"
40 #include "AliMpEncodePair.h"
41 #include "AliMpSegmentation.h"
42 #include <Riostream.h>
43 #include <TClass.h>
44 #include <TMath.h>
45 #include <TObjArray.h>
46 #include <TObjString.h>
47 #include <TString.h>
48 #include <TTimeStamp.h>
49 #include <TVector2.h>
50 #include <cassert>
51 #include <float.h>
52
53 /// \class AliMUONTrackerData
54 ///
55 /// Implementation of AliMUONVTrackerData class
56 ///
57 /// \author Laurent Aphecetche, Subatech
58
59 ///\cond CLASSIMP
60 ClassImp(AliMUONTrackerData)
61 ///\endcond
62
63 const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
64 const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
65
66 //_____________________________________________________________________________
67 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
68                                        Int_t dimension,
69                                        Bool_t issingleevent)
70 : AliMUONVTrackerData(name,title),
71 fIsSingleEvent(issingleevent),
72 fChannelValues(0x0),
73 fManuValues(0x0),
74 fBusPatchValues(0x0),
75 fDEValues(0x0),
76 fChamberValues(0x0),
77 fPCBValues(0x0),
78 fDimension(External2Internal(dimension)+fgkExtraDimension),
79 fNevents(0),
80 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
81 fExternalDimensionNames(new TObjArray(dimension)),
82 fExternalDimension(dimension),
83 fHistogramming(new Int_t[fExternalDimension]),
84 fHistos(0x0),
85 fXmin(0.0),
86 fXmax(0.0),
87 fIsChannelLevelEnabled(kTRUE),
88 fIsManuLevelEnabled(kTRUE),
89 fIsBustPatchLevelEnabled(kTRUE),
90 fIsPCBLevelEnabled(kTRUE),
91 fNofDDLs(0),
92 fNofEventsPerDDL(0x0)
93 {  
94   /// ctor
95   memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
96   fExternalDimensionNames->SetOwner(kTRUE);
97   fDimensionNames->SetOwner(kTRUE);  
98   fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
99   fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
100   fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
101   Clear();
102 }
103
104 //_____________________________________________________________________________
105 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
106                                        const AliMUONVStore& manuValues)
107 : AliMUONVTrackerData(name,title),
108 fIsSingleEvent(kFALSE),
109 fChannelValues(0x0),
110 fManuValues(0x0),
111 fBusPatchValues(0x0),
112 fDEValues(0x0),
113 fChamberValues(0x0),
114 fPCBValues(0x0),
115 fDimension(0),
116 fNevents(0),
117 fDimensionNames(0x0),
118 fExternalDimensionNames(0x0),
119 fExternalDimension(0),
120 fHistogramming(0x0),
121 fHistos(0x0),
122 fXmin(0.0),
123 fXmax(0.0),
124 fIsChannelLevelEnabled(kFALSE),
125 fIsManuLevelEnabled(kTRUE),
126 fIsBustPatchLevelEnabled(kTRUE),
127 fIsPCBLevelEnabled(kTRUE),
128 fNofDDLs(0),
129 fNofEventsPerDDL(0x0)
130 {  
131   /// ctor with pre-computed values at the manu level
132   /// In this case, we force fIsChannelLevelEnabled = kFALSE
133   /// ctor
134   
135   if (manuValues.GetSize()==0)
136   {
137     AliFatal("Cannot create a tracker data from nothing in that case !");
138   }
139   
140   if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
141   {
142     AliError("Cannot work without (full) mapping");
143     return;
144   }
145   
146   TIter next(manuValues.CreateIterator());
147   AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
148   
149   Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
150   
151   fDimension = External2Internal(dimension)+fgkExtraDimension;
152   
153   fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
154   fExternalDimensionNames = new TObjArray(dimension);
155   fExternalDimension = dimension;
156   fHistogramming = new Int_t[fExternalDimension];
157   memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
158
159   fExternalDimensionNames->SetOwner(kTRUE);
160   fDimensionNames->SetOwner(kTRUE);  
161   fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
162   fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
163   fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
164   Clear();
165   TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
166   AssertStores();
167   
168   next.Reset();
169   AliMUONVCalibParam* external;
170   
171   while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
172   {
173     Int_t detElemId, manuId;
174     
175     GetDEManu(*external,detElemId,manuId);
176     
177     AliMUONVCalibParam* chamber(0x0);
178     AliMUONVCalibParam* de(0x0);
179     AliMUONVCalibParam* busPatch(0x0);
180     AliMUONVCalibParam* pcb(0x0);
181     AliMUONVCalibParam* manu(0x0);
182     AliMUONVCalibParam* channel(0x0);
183     AliMpDetElement* mpde(0x0);
184     
185     AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,manuId,0);
186     // as external, but without event count
187     wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
188     wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
189     wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
190     wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
191     
192     Int_t mid = GetParts(wec,chamber,de,busPatch,pcb,manu,channel,mpde);
193
194     if ( manuId != mid ) 
195     {
196       AliError(Form("Something is wrong for DE %5d : manuId = %d vs mid = %d",detElemId,manuId,mid));
197       continue;
198     }
199     
200     if ( manuId < 0 ) 
201     {
202       AliError("Got a < 0 manuId. Should not happen here !");
203       continue;
204     }
205     
206     assert(channel==0x0);
207     
208     Int_t n1 = manu->ValueAsInt(0,IndexOfNumberDimension());
209     Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
210     if  ( n1 != n2 )
211     {
212       AliError(Form("Incoherent number of manu channels for DE %5d MANU %5d : %d vs %d",
213                     detElemId,manuId,n1,n2));
214     }
215     
216     Int_t nevt = external->ValueAsInt(0,4);
217     
218     Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
219
220     Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus(busPatchId);
221
222     if ( nevents[ddl] == 0 ) 
223     {
224       nevents[ddl] = nevt;
225     }
226     else
227     {
228       if ( nevents.At(ddl) != nevt ) 
229       {
230         AliError(Form("Nevt mismatch for DE %5d MANU %5d DDL %d : %d vs %d",
231                       detElemId,manuId,ddl,nevents.At(ddl),nevt));
232         continue;
233       }
234     }
235     
236     for ( Int_t i = 0; i < wec->Dimension()-1; ++i ) 
237     {
238       manu->SetValueAsDouble(0,i,manu->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
239       
240       busPatch->SetValueAsDouble(0,i,busPatch->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
241       
242       de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
243       
244       chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
245     }    
246     delete wec;
247   }  
248   
249   UpdateNumberOfEvents(&nevents);
250
251 }
252
253 //_____________________________________________________________________________
254 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
255                                        const AliMUONVStore& deOrBpValues, Int_t val)
256 : AliMUONVTrackerData(name,title),
257 fIsSingleEvent(kFALSE),
258 fChannelValues(0x0),
259 fManuValues(0x0),
260 fBusPatchValues(0x0),
261 fDEValues(0x0),
262 fChamberValues(0x0),
263 fPCBValues(0x0),
264 fDimension(0),
265 fNevents(0),
266 fDimensionNames(0x0),
267 fExternalDimensionNames(0x0),
268 fExternalDimension(0),
269 fHistogramming(0x0),
270 fHistos(0x0),
271 fXmin(0.0),
272 fXmax(0.0),
273 fIsChannelLevelEnabled(kFALSE),
274 fIsManuLevelEnabled(kFALSE),
275 fIsBustPatchLevelEnabled(kFALSE),
276 fIsPCBLevelEnabled(kFALSE),
277 fNofDDLs(0),
278 fNofEventsPerDDL(0x0)
279 {  
280   /// ctor with values at the detection element OR bus patch level
281   /// In this case, we force fIsChannelLevelEnabled = fIsManuLevelEnabled = kFALSE
282   /// ctor
283   
284   if (deOrBpValues.GetSize()==0)
285   {
286     AliFatal("Cannot create a tracker data from nothing in that case !");
287   }
288   
289   if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
290   {
291     AliError("Cannot work without (full) mapping");
292     return;
293   }
294   
295   if ( val == 1 ) 
296   {
297     BuildFromDEStore(deOrBpValues);
298   }
299   else if ( val == 2 )
300   {
301     BuildFromBPStore(deOrBpValues);
302   }
303   else
304   {
305     AliFatal("Wrong parameter. Must be 1 or 2");
306   }
307   
308   
309 }
310
311 //_____________________________________________________________________________
312 void AliMUONTrackerData::BuildFromDEStore(const AliMUONVStore& deValues)
313 {
314   /// Fill internals from a store of values at the detection element level
315   
316   TIter next(deValues.CreateIterator());
317   AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
318   
319   Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
320   
321   fDimension = External2Internal(dimension)+fgkExtraDimension;
322   
323   fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
324   fExternalDimensionNames = new TObjArray(dimension);
325   fExternalDimension = dimension;
326   fHistogramming = new Int_t[fExternalDimension];
327   memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
328   
329   fExternalDimensionNames->SetOwner(kTRUE);
330   fDimensionNames->SetOwner(kTRUE);  
331   fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
332   fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
333   fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
334   Clear();
335   TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
336   AssertStores();
337   
338   next.Reset();
339   AliMUONVCalibParam* external;
340   
341   while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
342   {
343     Int_t detElemId = external->ID0();
344     
345     AliMpDetElement* mpde = AliMpDDLStore::Instance()->GetDetElement(detElemId,kFALSE);
346     
347     if (!mpde)
348     {
349       AliError(Form("Got an invalid DE (%d) from external store",detElemId));
350       continue;
351     }
352     
353     Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
354     AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
355     AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
356     
357     AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,0,0);
358     // as external, but without event count
359     wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
360     wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
361     wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
362     wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
363     
364     Int_t n1 = de->ValueAsInt(0,IndexOfNumberDimension());
365     Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
366     if  ( n1 != n2 )
367     {
368       AliError(Form("Incoherent number of dimensions for DE%d : %d vs %d",
369                     detElemId,n1,n2));
370       continue;
371     }
372     
373     Int_t nevt = external->ValueAsInt(0,4);
374     
375     Int_t ddl = mpde->GetDdlId();
376     
377     if ( nevents[ddl] == 0 ) 
378     {
379       nevents[ddl] = nevt;
380     }
381     else
382     {
383       if ( nevents.At(ddl) != nevt ) 
384       {
385         AliError(Form("Nevt mismatch for DE %5d  DDL %d : %d vs %d",
386                       detElemId,ddl,nevents.At(ddl),nevt));
387         continue;
388       }
389     }
390     
391     for ( Int_t i = 0; i < wec->Dimension()-1; ++i ) 
392     {
393       de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
394       
395       chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
396     }    
397     delete wec;
398   }  
399   
400   UpdateNumberOfEvents(&nevents);
401 }
402
403 //_____________________________________________________________________________
404 void AliMUONTrackerData::BuildFromBPStore(const AliMUONVStore& bpValues)
405 {
406   /// Fill internals from a store of values at the bus patch level
407   
408   fIsBustPatchLevelEnabled = kTRUE;
409   
410   TIter next(bpValues.CreateIterator());
411   AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
412   
413   Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
414   
415   fDimension = External2Internal(dimension)+fgkExtraDimension;
416   
417   fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
418   fExternalDimensionNames = new TObjArray(dimension);
419   fExternalDimension = dimension;
420   fHistogramming = new Int_t[fExternalDimension];
421   memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
422   
423   fExternalDimensionNames->SetOwner(kTRUE);
424   fDimensionNames->SetOwner(kTRUE);  
425   fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
426   fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
427   fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
428   Clear();
429   TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
430   AssertStores();
431   
432   next.Reset();
433   AliMUONVCalibParam* external;
434   
435   while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
436   {
437     Int_t busPatchId = external->ID0();
438     
439     AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId,kFALSE);
440     
441     if (!mpbp)
442     {
443       AliError(Form("Got an invalid buspatchId (%d) from external store",busPatchId));
444       continue;
445     }
446     
447     Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
448     Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
449     AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
450     AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
451     AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE);
452     
453     AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,busPatchId,0,0);
454     // as external, but without event count
455     wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
456     wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
457     wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
458     wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
459     
460     Int_t n1 = bp->ValueAsInt(0,IndexOfNumberDimension());
461     Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
462     if  ( n1 != n2 )
463     {
464       AliError(Form("Incoherent number of dimensions for BP%d : %d vs %d",
465                     busPatchId,n1,n2));
466       continue;
467     }
468     
469     Int_t nevt = external->ValueAsInt(0,4);
470     
471     Int_t ddl = mpbp->GetDdlId();
472     
473     if ( nevents[ddl] == 0 ) 
474     {
475       nevents[ddl] = nevt;
476     }
477     else
478     {
479       if ( nevents.At(ddl) != nevt ) 
480       {
481         AliError(Form("Nevt mismatch for BP %5d  DDL %d : %d vs %d",
482                       busPatchId,ddl,nevents.At(ddl),nevt));
483         continue;
484       }
485     }
486     
487     for ( Int_t i = 0; i < wec->Dimension()-1; ++i ) 
488     {
489       bp->SetValueAsDouble(0,i,bp->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
490       
491       de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
492       
493       chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
494     }    
495     delete wec;
496   }  
497   
498   UpdateNumberOfEvents(&nevents);  
499 }
500
501 //_____________________________________________________________________________
502 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
503                                        const AliMUONRejectList& rejectList)
504 : AliMUONVTrackerData(name,title),
505 fIsSingleEvent(kFALSE),
506 fChannelValues(0x0),
507 fManuValues(0x0),
508 fBusPatchValues(0x0),
509 fDEValues(0x0),
510 fChamberValues(0x0),
511 fPCBValues(0x0),
512 fDimension(External2Internal(1)+fgkExtraDimension),
513 fNevents(0),
514 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
515 fExternalDimensionNames(new TObjArray(1)),
516 fExternalDimension(1),
517 fHistogramming(new Int_t[fExternalDimension]),
518 fHistos(0x0),
519 fXmin(0.0),
520 fXmax(0.0),
521 fIsChannelLevelEnabled(kTRUE),
522 fIsManuLevelEnabled(kTRUE),
523 fIsBustPatchLevelEnabled(kTRUE),
524 fIsPCBLevelEnabled(kFALSE),
525 fNofDDLs(0),
526 fNofEventsPerDDL(0x0)
527 {  
528   
529    /// ctor with values from the given rejectlist
530     
531   if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
532   {
533     AliError("Cannot work without (full) mapping");
534     return;
535   }
536   
537   memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
538   
539   fExternalDimensionNames->SetOwner(kTRUE);
540   fDimensionNames->SetOwner(kTRUE);  
541   fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
542   fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
543   fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
544   Clear();
545   TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
546   AssertStores();
547   
548   
549   for ( Int_t chamberId = 0; chamberId < AliMpConstants::NofChambers(); ++chamberId ) 
550   {
551 //    AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
552
553     // FIXME : update the chamber value ?
554     
555     AliMpDEIterator deit;
556   
557     deit.First(chamberId);
558
559     while ( !deit.IsDone() ) 
560     {
561       AliMpDetElement* mpde = deit.CurrentDE();
562       
563       Int_t detElemId = mpde->GetId();
564
565       AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
566
567       DispatchValue(*de,0,rejectList.DetectionElementProbability(detElemId),0.0,mpde->NofChannels());
568       
569       for ( Int_t iBusPatch = 0; iBusPatch < mpde->GetNofBusPatches(); ++iBusPatch ) 
570       {
571         Int_t busPatchId = mpde->GetBusPatchId(iBusPatch);
572         
573         AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE);
574
575         AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
576
577         Int_t nch(0);
578         
579         for ( Int_t iManu = 0 ;iManu < mpbp->GetNofManus(); ++iManu )
580         {
581           Int_t manuId = mpbp->GetManuId(iManu);
582           
583           nch += mpde->NofChannelsInManu(manuId);
584           
585           AliMUONVCalibParam* manu = ManuParam(detElemId,manuId,kTRUE);
586           
587           DispatchValue(*manu,0,rejectList.ManuProbability(detElemId,manuId),0.0,mpde->NofChannelsInManu(manuId));
588           
589           AliMUONVCalibParam* c = ChannelParam(detElemId,manuId);
590           
591           if (!c)
592           {
593             c = new AliMUONCalibParamND(Dimension(),
594                                         AliMpConstants::ManuNofChannels(),
595                                         detElemId,
596                                         manuId,
597                                         0.0);
598             fChannelValues->Add(c);
599           }
600           
601           for ( Int_t manuChannel = 0; manuChannel < AliMpConstants::ManuNofChannels(); ++manuChannel )
602           {
603             DispatchValue(*c,manuChannel,rejectList.ChannelProbability(detElemId,manuId,manuChannel),0.0,1);
604           }
605         }
606
607         DispatchValue(*bp,0,rejectList.BusPatchProbability(busPatchId),0.0,nch);
608
609       }
610       
611       deit.Next();
612     }
613  
614   }
615   
616   
617   SetDimensionName(0,"RejectProba");
618
619   UpdateNumberOfEvents(0x0);
620 }
621
622 //_____________________________________________________________________________
623 AliMUONTrackerData::~AliMUONTrackerData()
624 {
625   /// dtor
626   delete fChannelValues;
627   delete fManuValues;
628   delete fBusPatchValues;
629   delete fDEValues;
630   delete fChamberValues;
631   delete fPCBValues;
632   delete fDimensionNames;
633   delete fExternalDimensionNames;
634   delete[] fHistogramming;
635   delete fHistos;
636   delete[] fNofEventsPerDDL;
637 }
638
639 //_____________________________________________________________________________
640 Bool_t
641 AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents)
642 {
643   /// Add the given external store to our internal store
644   return InternalAdd(store,nevents,kFALSE);
645 }
646
647 //_____________________________________________________________________________
648 Bool_t 
649 AliMUONTrackerData::Add(const AliMUONTrackerData& data)
650 {
651   /// Add data to *this
652   // We do this by looping on all VCalibParam stored in the various containers,
653   // and simply adding the values there.
654   // Same thing for the number of events per DDL.
655   // Same thing for sparsehistograms, if we have some.
656
657   // First cross check we have compatible objects.
658   
659   AliCodeTimerAuto("",0);
660   
661   if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled ) 
662   {
663     AliError("Incompatible IsChannelLevelEnabled status");
664     return kFALSE;
665   }
666   
667   if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled ) 
668   {
669     AliError("Incompatible IsManuLevelEnabled status");
670     return kFALSE;
671   }
672   
673   if ( fIsSingleEvent != data.fIsSingleEvent ) 
674   {
675     AliError("Incompatible IsSingleEvent status");
676     return kFALSE;
677   }
678   
679   if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension ) 
680   {
681     AliError("Incompatible dimensions");
682     return kFALSE;
683   }
684
685   if ( fNofDDLs != data.fNofDDLs ) 
686   {
687     AliError("Incompatible number of Ddls");
688     return kFALSE;
689   }
690   
691   if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming ) 
692       || fXmin != data.fXmin || fXmax != data.fXmax ) 
693   {
694     AliError(Form("Incompatible histogramming (%p vs %p) (xmax = %e vs %e ; xmin = %e vs %e)",
695              fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
696     return kFALSE;
697   }
698
699   if ( fHistogramming )
700   {
701     for ( Int_t i = 0; i < fExternalDimension; ++i ) 
702     {
703       if ( fHistogramming[i] != data.fHistogramming[i] )
704       {
705         AliError(Form("Incompatible histogramming for external dimension %d",i));
706         return kFALSE;
707       }
708     }
709   }
710   
711   // OK. Seems we have compatible objects, so we can proceed with the actual
712   // merging...
713   
714   if ( data.fChannelValues ) 
715   {
716     Add2D(*(data.fChannelValues),*fChannelValues);
717   }
718   
719   if ( data.fManuValues ) 
720   {
721     Add2D(*(data.fManuValues),*fManuValues);
722   }
723   
724   if ( data.fPCBValues ) 
725   {
726     Add2D(*(data.fPCBValues),*fPCBValues);
727   }
728   
729   if ( data.fBusPatchValues ) 
730   {
731     Add1D(*(data.fBusPatchValues),*fBusPatchValues);
732   }
733   
734   if ( data.fDEValues ) 
735   {
736     Add1D(*(data.fDEValues),*fDEValues);
737   }
738   
739   if ( data.fChamberValues ) 
740   {
741     Add1D(*(data.fChamberValues),*fChamberValues);
742   }
743
744   for ( Int_t i = 0; i < fNofDDLs; ++i ) 
745   {
746     fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
747   }
748   
749   if ( data.fHistos ) 
750   {
751     TIter nexthisto(data.fHistos->CreateIterator());
752     AliMUONVStore* store;
753     while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
754     {
755       TIter ns(store->CreateIterator());
756       AliMUONSparseHisto* h;
757       while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
758       {
759         AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
760         
761         if (!thisStore)
762         {
763           thisStore = store->Create();
764           thisStore->SetUniqueID(store->GetUniqueID());
765           fHistos->Add(thisStore);
766         }
767         
768         AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
769         
770         if (!mine) 
771         {
772           thisStore->Add(h);
773         }
774         else
775         {
776           mine->Add(*h);
777         }
778       }
779     }
780   }
781   
782   for ( Int_t i = 0 ; i < fNofDDLs; ++i ) 
783   {
784     fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
785   }
786   
787   return kTRUE;
788 }
789
790 //_____________________________________________________________________________
791 void 
792 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
793 {
794   /// Add one 2d store to another
795   
796   TIter next(src.CreateIterator());
797   AliMUONVCalibParam* p;
798   
799   while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
800   {
801     AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
802     
803     if (!a)
804     {
805       dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
806     }
807     else
808     {
809       AddCalibParams(*p,*a);
810     }
811   }
812 }
813
814 //_____________________________________________________________________________
815 void 
816 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
817 {
818   /// Add one 1d store to another
819   
820   TIter next(src.CreateIterator());
821   AliMUONVCalibParam* p;
822   
823   while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
824   {
825     AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
826     
827     if (!a)
828     {
829       dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
830     }
831     else
832     {
833       AddCalibParams(*p,*a);
834     }
835   }
836 }
837
838 //_____________________________________________________________________________
839 void
840 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
841 {
842   /// Add src to dest
843   for ( Int_t i = 0; i < src.Size(); ++i ) 
844   {
845     for ( Int_t j = 0; j < src.Dimension(); ++j )
846     {
847       dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
848     }
849   }
850 }
851
852 //_____________________________________________________________________________
853 Bool_t
854 AliMUONTrackerData::Replace(const AliMUONVStore& store)
855 {
856   /// Replace our values by values from the given external store
857   Bool_t rv = InternalAdd(store,0x0,kTRUE);
858   AliMUONVTrackerData::Replace(store);
859   return rv;
860 }
861
862 //_____________________________________________________________________________
863 Bool_t
864 AliMUONTrackerData::UpdateNumberOfEvents(TArrayI* nevents)
865 {
866   /// Update the number of events
867   
868   if (!fNofDDLs)
869   {
870     fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
871     fNofEventsPerDDL = new Int_t[fNofDDLs];
872     for ( Int_t i = 0; i < fNofDDLs; ++i ) 
873     {
874       fNofEventsPerDDL[i] = 0;
875     }
876   }
877   
878   if (nevents)
879   {
880     if (nevents->GetSize() != fNofDDLs ) 
881     {
882       AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
883                     nevents->GetSize(),fNofDDLs));
884       return kFALSE;
885     }
886     
887     for ( Int_t i = 0 ; i < fNofDDLs; ++i ) 
888     {
889       fNofEventsPerDDL[i] += nevents->At(i);
890       fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
891     }
892   }
893   else
894   {
895     for ( Int_t i = 0 ; i < fNofDDLs; ++i ) 
896     {
897       ++fNofEventsPerDDL[i];
898       fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
899     }
900   }
901   return kTRUE;
902 }
903
904 //_____________________________________________________________________________
905 void
906 AliMUONTrackerData::AssertStores()
907 {
908   /// Insure our stores are allocated
909   
910   if (!fChamberValues)
911   {
912     Int_t numberOfBusPatches(0);
913     Int_t numberOfDEs(0);
914     
915     // get number of bus patches and number of detection element
916     // to initialize fBusPatchValues and fDEValues below
917     
918     if (!AliMpDDLStore::Instance(false))
919     {
920       AliMpCDB::LoadAll();
921     }
922     
923     TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
924     while ( next() ) ++numberOfBusPatches;
925     AliMpDEIterator deIt;
926     deIt.First();
927     while (!deIt.IsDone())
928     {
929       ++numberOfDEs;
930       deIt.Next();
931     }
932     
933     if ( fIsChannelLevelEnabled ) 
934     {
935       fChannelValues = new AliMUON2DMap(kTRUE);
936     }
937     if  ( fIsManuLevelEnabled ) 
938     {
939       fManuValues = new AliMUON2DMap(kTRUE);
940     }
941     if ( fIsPCBLevelEnabled )
942     {
943       fPCBValues = new AliMUON2DMap(kFALSE);
944     }
945     if ( fIsBustPatchLevelEnabled )
946     {
947       fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
948     }
949     fDEValues = new AliMUON1DMap(numberOfDEs);
950     fChamberValues = new AliMUON1DArray;
951   }
952 }
953
954 //_____________________________________________________________________________
955 Bool_t
956 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
957 {
958   /// Add the given external store to our internal store
959   
960   AliCodeTimerAuto(GetName(),0);
961     
962   if ( !replace)
963   {
964     if ( IsSingleEvent() && NumberOfEvents(-1) == 1 ) 
965     {
966       AliError(Form("%s is supposed to be single event only",GetName()));
967       return kFALSE;
968     }  
969   }
970
971   UpdateNumberOfEvents(nevents);
972   
973   AssertStores();
974   
975   TIter next(store.CreateIterator());
976   AliMUONVCalibParam* external;
977   
978   Int_t nk(2);
979   
980   if ( IsSingleEvent() ) nk = 1;
981
982   while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
983   {
984     if ( external->Dimension() != ExternalDimension() )
985     {
986       AliError(Form("Incompatible dimensions %d vs %d",
987                     external->Dimension(),ExternalDimension()));
988       return kFALSE;
989     }
990     
991     AliMUONVCalibParam* chamber(0x0);
992     AliMUONVCalibParam* de(0x0);
993     AliMUONVCalibParam* busPatch(0x0);
994     AliMUONVCalibParam* pcb(0x0);
995     AliMUONVCalibParam* manu(0x0);
996     AliMUONVCalibParam* channel(0x0);
997     AliMpDetElement* mpde(0x0);
998     
999     Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
1000     
1001     if ( manuId < 0 ) continue;
1002     
1003     Int_t detElemId = mpde->GetId();
1004     
1005     Double_t value[] = { 0.0, 0.0 };
1006     
1007     Int_t nch = mpde->NofChannelsInManu(manuId);
1008     
1009     for ( Int_t i = 0; i < external->Size(); ++i ) 
1010     {
1011       Bool_t existingChannel =  ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
1012                                                                            : mpde->IsConnectedChannel(manuId,i));
1013       // note we only use IsConnectedChannel method when really needed, as
1014       // it costs (some) CPU time...
1015       
1016       if ( existingChannel ) 
1017       {
1018         Bool_t validChannel(kFALSE);
1019         
1020         for ( Int_t j = 0; j < external->Dimension(); ++j )
1021         {
1022           Double_t vext = external->IsDoublePrecision() ? 
1023             external->ValueAsDoubleFast(i,j) :
1024             external->ValueAsFloatFast(i,j);
1025           
1026           if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
1027           
1028           validChannel = kTRUE;
1029                     
1030           Int_t ix = External2Internal(j);
1031           
1032           value[0] = vext;
1033           value[1] = vext*vext;
1034           
1035           if ( IsHistogrammed(j) )
1036           {
1037             FillHisto(detElemId,manuId,i,j,vext);
1038           }
1039           
1040           for ( Int_t k = 0; k < nk; ++k ) 
1041           {
1042             Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
1043             
1044                                                 if ( channel ) 
1045                                                 {
1046                                                         channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
1047                                                 }
1048                                                 
1049             if (manu)
1050             {
1051               manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);            
1052             }
1053             
1054             busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1055             
1056             de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1057             
1058             chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1059             
1060             if ( pcb ) 
1061             {
1062               pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1063             }
1064           }
1065         }
1066         
1067         if ( validChannel && !replace )
1068         {
1069                                         if ( channel ) 
1070                                         {
1071                                                 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
1072                                                                                                                                                                         channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
1073                                         }
1074                                         
1075           if (manu)
1076           {
1077             manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1078                                        manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
1079           }
1080           
1081           busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1082                                                          busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
1083           de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1084                                              de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
1085           chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1086                                                        chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0); 
1087           if ( pcb ) 
1088           {
1089             pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1090                                       pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
1091           }
1092         }
1093       }
1094     }
1095   }
1096   
1097   NumberOfEventsChanged();
1098   
1099   return kTRUE;
1100 }
1101
1102 //_____________________________________________________________________________
1103 Double_t 
1104 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
1105 {
1106   /// Return the value of a given buspatch for a given dimension
1107   /// or 0 if not existing
1108   AliMUONVCalibParam* param = BusPatchParam(busPatchId);
1109   return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
1110 }
1111
1112 //_____________________________________________________________________________
1113 AliMUONVCalibParam* 
1114 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
1115 {
1116   /// Return (if it exist), the VCalibParam for a given busPatch
1117   
1118   AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
1119     (fBusPatchValues->FindObject(busPatchId)) : 0x0;
1120   
1121   if (!busPatch && create && fBusPatchValues)
1122   {
1123     busPatch = CreateBusPatchParam(busPatchId);
1124     fBusPatchValues->Add(busPatch);
1125   }
1126   
1127   return busPatch;
1128 }
1129
1130 //_____________________________________________________________________________
1131 AliMUONVCalibParam* 
1132 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
1133 {
1134   /// Create storage for one bus patch
1135   
1136   AliCodeTimerAuto("",0);
1137   
1138   AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1139   
1140   if (!bp)
1141   {
1142     AliError(Form("Got an invalid buspatchId = %d",busPatchId));
1143     return 0x0;
1144   }
1145   
1146   AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
1147   
1148   // set the number of channels in that buspatch
1149   
1150   Int_t nchannels(0);
1151   
1152   Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
1153   
1154   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1155   
1156   for ( Int_t i = 0; i < bp->GetNofManus(); ++i ) 
1157   {
1158     Int_t manuId = bp->GetManuId(i);
1159     nchannels += de->NofChannelsInManu(manuId);
1160   }
1161   
1162   busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1163   
1164   return busPatch;
1165 }
1166
1167 //_____________________________________________________________________________
1168 Double_t 
1169 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
1170 {
1171   /// Return the value fo a given chamber for a given dimension,
1172   /// or zero if not existing
1173   
1174   // FIXME: is the Value() correct wrt to number of events in the case of
1175   // chamber ? Or should we do something custom at the chamber level 
1176   // (as it spans several ddls) ?
1177   
1178   AliMUONVCalibParam* param = ChamberParam(chamberId);
1179   return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
1180 }
1181
1182 //_____________________________________________________________________________
1183 AliMUONVCalibParam* 
1184 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
1185 {
1186   /// Return (if it exist) the VCalibParam for a given chamber
1187   
1188   AliMUONVCalibParam* chamber =  fChamberValues ? static_cast<AliMUONVCalibParam*>
1189   (fChamberValues->FindObject(chamberId)) : 0x0;
1190   
1191   if (!chamber && create && fChamberValues)
1192   {
1193     chamber = CreateChamberParam(chamberId);
1194     fChamberValues->Add(chamber);
1195   }
1196     
1197   return chamber;
1198 }
1199
1200 //_____________________________________________________________________________
1201 AliMUONVCalibParam* 
1202 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
1203 {
1204   /// Create storage for one chamber
1205   
1206   AliCodeTimerAuto("",0);
1207   
1208   AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
1209   
1210   // set the number of channels in that chamber
1211   
1212   Int_t nchannels(0);
1213   
1214   AliMpDEIterator it;
1215   
1216   it.First(chamberId);
1217   
1218   while ( !it.IsDone() )
1219   {        
1220     AliMpDetElement* det = it.CurrentDE();
1221     
1222     for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
1223     {
1224       Int_t busPatchId = det->GetBusPatchId(i);
1225       AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1226       for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
1227       {
1228         Int_t manuId = bp->GetManuId(j);
1229         nchannels += det->NofChannelsInManu(manuId);
1230       }        
1231     }
1232     
1233     it.Next();
1234   }
1235   
1236   chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1237   
1238   return chamber;
1239 }
1240
1241 //_____________________________________________________________________________
1242 Double_t 
1243 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId, 
1244                             Int_t manuChannel, Int_t dim) const
1245 {
1246   /// Return the value for a given channel for a given dimension
1247   
1248   AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
1249   
1250   return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1251 }
1252
1253 //_____________________________________________________________________________
1254 AliMUONVCalibParam* 
1255 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
1256                                  const AliMUONVCalibParam* external) const
1257 {
1258   /// Return (if it exist) the VCalibParam for a given manu
1259   
1260   AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
1261     (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
1262   
1263   if (!param && external && fChannelValues)
1264   {
1265     param = CreateDouble(*external,detElemId,manuId);
1266     fChannelValues->Add(param);
1267   }
1268   
1269   return param;
1270 }
1271
1272 //_____________________________________________________________________________
1273 void 
1274 AliMUONTrackerData::Clear(Option_t*)
1275 {
1276   /// Clear all the values
1277   if ( fChannelValues ) fChannelValues->Clear();
1278   if ( fManuValues ) fManuValues->Clear();
1279   if ( fBusPatchValues) fBusPatchValues->Clear();
1280   if ( fPCBValues ) fPCBValues->Clear();
1281   if ( fDEValues) fDEValues->Clear();
1282   if ( fChamberValues ) fChamberValues->Clear();
1283   if ( fHistos ) fHistos->Clear();
1284   for ( Int_t i = 0; i < fNofDDLs; ++i ) 
1285   {
1286     fNofEventsPerDDL[i] = 0;
1287   }
1288   fNevents = 0;
1289   NumberOfEventsChanged();
1290 }
1291
1292 //_____________________________________________________________________________
1293 Double_t 
1294 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId, 
1295                           Int_t manuChannel) const
1296 {
1297   /// Return the number of times a given channel had data
1298   
1299   return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
1300 }
1301
1302 //_____________________________________________________________________________
1303 AliMUONVCalibParam*
1304 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param, 
1305                                  Int_t detElemId, Int_t manuId) const
1306 {
1307   /// Create a double version of VCalibParam, for internal use
1308   
1309   AliCodeTimerAuto("",0);
1310   
1311   AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
1312                                                   param.Size(),
1313                                                   detElemId,
1314                                                   manuId,
1315                                                   0.0);
1316   
1317   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
1318   
1319   for ( Int_t i = 0; i < c->Size(); ++i ) 
1320   {
1321     Double_t value(0.0);
1322     
1323     if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
1324       
1325     c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
1326   }
1327   
1328   return c;
1329 }
1330
1331 //_____________________________________________________________________________
1332 Double_t 
1333 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
1334 {
1335   /// Return the value for a given detection element for a given dimension
1336   AliMUONVCalibParam* param = DetectionElementParam(detElemId);
1337   return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1338
1339 }
1340
1341 //_____________________________________________________________________________
1342 AliMUONVCalibParam* 
1343 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
1344 {
1345   /// Return (if it exist) the VCalibParam for a given detection element
1346   
1347   AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
1348     (fDEValues->FindObject(detElemId)) : 0x0 ;
1349   
1350   if (!de && create && fDEValues)
1351   {
1352     de = CreateDetectionElementParam(detElemId);
1353     fDEValues->Add(de);
1354   }
1355   
1356   return de;
1357   
1358 }
1359
1360 //_____________________________________________________________________________
1361 AliMUONVCalibParam* 
1362 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
1363 {
1364   /// Create storage for one detection element
1365   
1366   AliCodeTimerAuto("",0);
1367   
1368   AliMUONVCalibParam*  de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
1369   
1370   AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1371   Int_t nchannels(0);
1372   
1373   for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
1374   {
1375     Int_t busPatchId = det->GetBusPatchId(i);
1376     AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1377     for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
1378     {
1379       Int_t manuId = bp->GetManuId(j);
1380       nchannels += det->NofChannelsInManu(manuId);
1381     }        
1382   }
1383   
1384   de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1385   
1386   return de;
1387 }
1388
1389 //_____________________________________________________________________________
1390 Int_t 
1391 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
1392 {
1393   /// Get the "local" ddlid (0..19) of a given buspatch
1394   AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
1395   if (bp)
1396   {
1397     return bp->GetDdlId();
1398   }
1399   return -1;
1400 }
1401
1402 //_____________________________________________________________________________
1403 Int_t 
1404 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
1405 {
1406   /// Get the "local" ddlid (0..19) of a given detection element
1407   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
1408   if (de)
1409   {
1410     return de->GetDdlId();
1411   }
1412   return -1;
1413 }
1414
1415 //_____________________________________________________________________________
1416 Int_t 
1417 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
1418 {
1419   /// Get the "local" ddlid (0..19) of a given chamber
1420   /// This has no real meaning (as there are several ddls per chamber),
1421   /// so we take the ddlid where we got the max number of events
1422   
1423   AliMpDEIterator it;
1424   
1425   it.First(chamberid);
1426   Int_t n(0);
1427   Int_t d(-1);
1428   
1429   while (!it.IsDone())
1430   {
1431     Int_t detElemId = it.CurrentDEId();
1432     Int_t ddlId = DdlIdFromDetElemId(detElemId);
1433     if ( NumberOfEvents(ddlId) > n ) 
1434     {
1435       n = NumberOfEvents(ddlId);
1436       d = ddlId;
1437     }
1438     it.Next();
1439   }
1440   
1441   return d;
1442 }
1443
1444 //_____________________________________________________________________________
1445 TString 
1446 AliMUONTrackerData::DimensionName(Int_t dim) const
1447 {
1448   /// Get the name of a given dimension
1449   TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
1450   if ( value ) 
1451   {
1452     return value->String();
1453   }
1454   else
1455   {
1456     return TString("Invalid");
1457   }  
1458 }
1459
1460 //_____________________________________________________________________________
1461 void 
1462 AliMUONTrackerData::DisableChannelLevel()
1463
1464   /// Disable the storing of data at channel level
1465   
1466   delete fChannelValues;
1467   fChannelValues = 0x0;
1468   fIsChannelLevelEnabled = kFALSE; 
1469 }
1470
1471 //_____________________________________________________________________________
1472 void 
1473 AliMUONTrackerData::DisableManuLevel()
1474
1475   /// Disable the storing of data at manu level (and below)
1476   
1477   DisableChannelLevel();
1478   delete fManuValues;
1479   fManuValues = 0x0;
1480   fIsManuLevelEnabled = kFALSE; 
1481 }
1482
1483 //_____________________________________________________________________________
1484 Int_t 
1485 AliMUONTrackerData::External2Internal(Int_t index) const 
1486 {
1487   /// From external to internal dimension
1488   return IsSingleEvent() ? index : index*2;
1489 }
1490
1491 //_____________________________________________________________________________
1492 TString 
1493 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
1494 {
1495   /// Get the name of a given external dimension
1496   
1497   TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
1498   if ( value ) 
1499   {
1500     return value->String();
1501   }
1502   else
1503   {
1504     return TString("Invalid");
1505   }  
1506 }
1507
1508 //_____________________________________________________________________________
1509 void
1510 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
1511                               Int_t dim, Double_t value)
1512 {
1513   /// Fill histogram of a given channel
1514   
1515   AliMUONSparseHisto* h(0x0);
1516   
1517         if ( fIsChannelLevelEnabled ) 
1518         {
1519                 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
1520   }
1521   else if ( fIsManuLevelEnabled ) 
1522   {
1523     h = GetManuSparseHisto(detElemId,manuId,dim);
1524   }
1525   
1526   AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
1527   
1528   if (h)
1529   {
1530                 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
1531         }
1532 }
1533
1534 //_____________________________________________________________________________
1535 AliMUONSparseHisto*
1536 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, 
1537                                        Int_t dim) const
1538 {
1539   /// Get histogram of a given manu
1540   
1541   if (!fHistos) return 0x0;
1542   
1543   AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1544   if (!m) return 0x0;
1545   
1546   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1547   
1548   return h;
1549 }
1550
1551 //_____________________________________________________________________________
1552 AliMUONSparseHisto*
1553 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
1554 {
1555   /// Get histogram of a given manu. Create it if necessary
1556   
1557   if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1558   
1559   AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1560   if (!m)
1561   {
1562     m = new AliMUON1DArray(NumberOfDimensions());
1563     m->SetUniqueID( ( manuId << 16 ) | detElemId );
1564     fHistos->Add(m);
1565   }
1566     
1567   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1568   if (!h)
1569   {
1570     h = new AliMUONSparseHisto(fXmin,fXmax);
1571     
1572     h->SetUniqueID(dim);
1573     
1574     m->Add(h);
1575   }
1576   
1577    return h;
1578 }
1579
1580 //_____________________________________________________________________________
1581 AliMUONSparseHisto*
1582 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, 
1583                                           Int_t manuChannel, Int_t dim) const
1584 {
1585   /// Get histogram of a given channel
1586   
1587   if (!fHistos) return 0x0;
1588   
1589   AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1590   if (!m) return 0x0;
1591   
1592   UInt_t uid = ( manuChannel << 16 ) | dim;
1593   
1594   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1595   
1596   return h;
1597 }
1598
1599 //_____________________________________________________________________________
1600 AliMUONSparseHisto*
1601 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, 
1602                                           Int_t manuChannel, Int_t dim)
1603 {
1604   /// Get histogram of a given channel. Create it if necessary
1605   
1606   if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1607   
1608   AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1609   if (!m)
1610   {
1611     m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1612     m->SetUniqueID( ( manuId << 16 ) | detElemId );
1613     fHistos->Add(m);
1614   }
1615   
1616   UInt_t uid = ( manuChannel << 16 ) | dim;
1617   
1618   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1619   if (!h)
1620   {
1621     h = new AliMUONSparseHisto(fXmin,fXmax);
1622     
1623     h->SetUniqueID(uid);
1624     
1625     m->Add(h);
1626   }
1627
1628   return h;
1629 }
1630
1631 //_____________________________________________________________________________
1632 void
1633 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1634                               Int_t& detElemId, Int_t& manuId) const
1635 {
1636   /// Tries to get (detElemId,manuId) of param
1637   
1638   // Load mapping manu store
1639   if ( ! AliMpCDB::LoadManuStore() ) {
1640     AliError("Could not access manu store from OCDB !");
1641     return;
1642   }
1643
1644   if ( param.ID1() <= 0 ) 
1645   {
1646     // we (probably) get a manu serial number
1647     Int_t serial = param.ID0();
1648     MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1649     detElemId = AliMp::PairFirst(pair);
1650     manuId = AliMp::PairSecond(pair);
1651     if ( !detElemId ) 
1652     {
1653       AliDebug(1,Form("DE %d manuId %d from serial %d is not correct !",
1654                       detElemId,manuId,serial));
1655     }
1656   }
1657   else
1658   {
1659     // we get a (de,manu) pair
1660     detElemId = param.ID0();
1661     manuId = param.ID1();
1662   }
1663 }
1664
1665
1666 //_____________________________________________________________________________
1667 Int_t
1668 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1669                              AliMUONVCalibParam*& chamber,
1670                              AliMUONVCalibParam*& de,
1671                              AliMUONVCalibParam*& busPatch,
1672                              AliMUONVCalibParam*& pcb,
1673                              AliMUONVCalibParam*& manu,
1674                              AliMUONVCalibParam*& channel,
1675                              AliMpDetElement*& mpde)
1676 {
1677   /// Get containers at all levels
1678  
1679   chamber = de = busPatch = pcb = manu = channel = 0x0;
1680   mpde = 0x0;
1681   
1682   AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1683   
1684   Int_t detElemId;
1685   Int_t manuId;
1686   
1687   GetDEManu(*external,detElemId,manuId);
1688   
1689   mpde = ddlStore->GetDetElement(detElemId,kFALSE);
1690
1691   if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1692   {
1693     return -1;
1694   }
1695   
1696   // explicitely check that de,manu is correct
1697   const AliMpVSegmentation* mpseg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId,kFALSE);
1698   
1699   if (!mpseg)
1700   {
1701     return -1;
1702   }
1703   
1704   Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1705     
1706   Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1707   
1708   if ( busPatchId <= 0 )
1709   {
1710     return -1;
1711   }
1712   
1713   Int_t pcbIndex = -1;
1714   
1715   AliMp::StationType stationType = mpde->GetStationType();
1716   
1717   if ( stationType == AliMp::kStation345 ) 
1718   {
1719     AliMpDCSNamer namer("TRACKER");
1720     pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1721   }
1722   
1723   if ( fIsChannelLevelEnabled ) 
1724   {
1725     channel = ChannelParam(detElemId,manuId,external);
1726   }
1727   
1728   manu = ManuParam(detElemId,manuId,kTRUE);
1729   
1730   busPatch = BusPatchParam(busPatchId,kTRUE);
1731   
1732   de = DetectionElementParam(detElemId,kTRUE);
1733   
1734   chamber = ChamberParam(chamberId,kTRUE);
1735   
1736   pcb = 0x0;
1737   
1738   if ( pcbIndex >= 0 ) 
1739   {
1740     pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1741   }
1742   
1743   return manuId;
1744 }
1745
1746 //_____________________________________________________________________________
1747 Bool_t 
1748 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1749 {
1750   /// Whether we have data for a given buspatch
1751   return ( BusPatchParam(busPatchId) != 0 );
1752 }
1753
1754 //_____________________________________________________________________________
1755 Bool_t 
1756 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1757 {
1758   /// Whether we have data for a given chamber
1759   return ( ChamberParam(chamberId) != 0 );
1760 }
1761
1762 //_____________________________________________________________________________
1763 Bool_t 
1764 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1765 {
1766   /// Whether we have data for a given detection element
1767   return ( DetectionElementParam(detElemId) != 0 );
1768 }
1769
1770 //_____________________________________________________________________________
1771 Bool_t
1772 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1773 {
1774   /// Whether we have data for a given manu
1775   return ( ManuParam(detElemId,manuId) != 0 ); 
1776 }
1777
1778 //_____________________________________________________________________________
1779 Bool_t
1780 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1781 {
1782   /// Whether we have data for a given pcb
1783   return ( PCBParam(detElemId,pcbIndex) != 0 ); 
1784 }
1785
1786 //_____________________________________________________________________________
1787 Double_t 
1788 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1789 {
1790   /// Return the value for a given manu and a given dimension
1791   
1792   AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1793   return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1794 }
1795
1796 //_____________________________________________________________________________
1797 AliMUONVCalibParam* 
1798 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1799 {
1800   /// Get the VCalibParam for a given manu
1801   
1802   AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1803     (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1804   
1805   if (!manu && create && fManuValues)
1806   {
1807     manu = CreateManuParam(detElemId,manuId);
1808     fManuValues->Add(manu);
1809   }
1810   
1811   return manu;
1812 }
1813
1814 //_____________________________________________________________________________
1815 AliMUONVCalibParam* 
1816 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1817 {
1818   /// Create storage for one manu
1819   
1820   AliCodeTimerAuto("",0);
1821   
1822   AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1823   
1824   // set the number of channels in that manu
1825   
1826   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1827   
1828   manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1829   
1830   return manu;
1831 }
1832
1833 //_____________________________________________________________________________
1834 Long64_t
1835 AliMUONTrackerData::Merge(TCollection* list)
1836 {
1837   /// Merge this with a list of AliMUONVTrackerData
1838
1839   if (!list) return 0;
1840   
1841   if ( list->IsEmpty() ) return NumberOfEvents(-1);
1842   
1843   TIter next(list);
1844   const TObject* o(0x0);
1845   
1846   while ( ( o = next() ) )
1847   {
1848     const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1849     if (!data)
1850     {
1851       AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1852                     o->GetName()));
1853     }
1854     else
1855     {
1856       Bool_t ok = Add(*data);
1857       if (!ok)
1858       {
1859         AliError("Got incompatible objects");
1860       }
1861     }
1862   }
1863   
1864   return NumberOfEvents(-1);
1865 }
1866
1867 //_____________________________________________________________________________
1868 Int_t 
1869 AliMUONTrackerData::NumberOfDimensions() const
1870 {
1871   /// Number of dimensions we're dealing with
1872   
1873   return fDimension + fgkVirtualExtraDimension; 
1874 }
1875
1876 //_____________________________________________________________________________
1877 Int_t
1878 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1879 {
1880   /// Get the number of events we've seen for a given DDL, or the max
1881   /// in case ddlNumber<0
1882
1883   Int_t n(0);
1884   
1885   if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1886   {
1887     n = fNofEventsPerDDL[ddlNumber];
1888   }
1889   else
1890   {
1891     // get the max number of events
1892     return fNevents;
1893   }
1894   
1895   return n;
1896 }
1897
1898 //_____________________________________________________________________________
1899 Double_t 
1900 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1901 {
1902   /// Return the value of a given pcb for a given dimension
1903
1904   AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1905   
1906   return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1907 }
1908
1909 //_____________________________________________________________________________
1910 AliMUONVCalibParam* 
1911 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1912 {
1913   /// Return (if it exist) the VCalibParam for a given pcb
1914
1915   AliMUONVCalibParam* pcb =  fPCBValues ? static_cast<AliMUONVCalibParam*>
1916     (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1917   
1918   if (create && fPCBValues && !pcb)
1919   {
1920     pcb = CreatePCBParam(detElemId,pcbIndex);
1921     fPCBValues->Add(pcb);
1922   }
1923   
1924   return pcb;
1925 }
1926
1927 //_____________________________________________________________________________
1928 AliMUONVCalibParam* 
1929 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1930 {
1931   /// Create storage for one PCB (station345 only)
1932   
1933   AliCodeTimerAuto("",0);
1934   
1935   AliMpDCSNamer namer("TRACKER");
1936   
1937   AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1938                                                     namer.NumberOfPCBs(detElemId),
1939                                                     detElemId,
1940                                                     pcbIndex,
1941                                                     0.0);
1942   return pcb;
1943 }
1944
1945 //_____________________________________________________________________________
1946 void 
1947 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1948 {
1949   /// Printout
1950   
1951   TNamed::Print(opt);
1952   
1953   if ( !fIsSingleEvent ) 
1954   {
1955     for ( Int_t i = 0; i < fNofDDLs; ++i ) 
1956     {
1957       cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1958     }
1959   }
1960
1961         if ( !fIsChannelLevelEnabled ) 
1962         {
1963                 cout << "Is not storing data at the channel level" << endl;
1964         }
1965
1966   if ( !fIsManuLevelEnabled ) 
1967         {
1968                 cout << "Is not storing data at the manu level" << endl;
1969         }
1970   
1971   for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i ) 
1972   {
1973     TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1974     cout << Form("External Dimension %2d Name %s %s",i,
1975                  ( name ? name->String().Data() : "null"),
1976                  ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1977   }
1978   
1979   for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i ) 
1980   {
1981     TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1982     cout << Form("Internal Dimension %2d Name %s",i,
1983                  ( name ? name->String().Data() : "null")) << endl;
1984   }
1985     
1986   TString sopt(opt);
1987   sopt.ToUpper();
1988   
1989   if ( sopt.Contains("CHANNEL") )
1990   {
1991     if ( fIsChannelLevelEnabled ) 
1992     {      
1993       if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1994     }
1995     else
1996     {
1997       AliWarning("You requested channel values, but they were not stored !");
1998     }
1999   }
2000
2001   if ( sopt.Contains("MANU") )
2002   {
2003     if ( fIsManuLevelEnabled ) 
2004     {
2005       if ( fManuValues ) fManuValues->Print(wildcard,opt);
2006     }
2007     else
2008     {
2009       AliWarning("You requested manu values, but they were not stored !");
2010     }
2011   }
2012
2013   if ( sopt.Contains("BUSPATCH") && fBusPatchValues ) 
2014   {
2015     fBusPatchValues->Print(wildcard,opt);
2016   }
2017
2018   if ( sopt.Contains("DE") && fDEValues ) 
2019   {
2020     fDEValues->Print(wildcard,opt);
2021   }
2022
2023   if ( sopt.Contains("CHAMBER") && fChamberValues ) 
2024   {
2025     fChamberValues->Print(wildcard,opt);
2026   }
2027   
2028 }
2029
2030 //_____________________________________________________________________________
2031 void
2032 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
2033 {  
2034   /// Set the name of a given dimension
2035
2036   if ( index >= fExternalDimension ) 
2037   {
2038     AliError(Form("%s : dimension %s : Index out of bounds : %d / %d",
2039                   GetName(),
2040                   name,index,fExternalDimension));
2041     return;
2042   }
2043   
2044   Int_t ix = External2Internal(index);
2045   
2046   if ( !IsSingleEvent() ) 
2047   {
2048     const char* prefix[] = { "mean", "sigma" };
2049   
2050     for ( Int_t i = 0; i < 2; ++i ) 
2051     {
2052       Int_t j = ix+i;
2053     
2054       SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
2055     }
2056   }
2057   else
2058   {
2059     SetInternalDimensionName(index,name);
2060   }
2061   
2062   SetExternalDimensionName(index,name);
2063 }
2064
2065 //_____________________________________________________________________________
2066 void 
2067 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
2068 {
2069   /// decide to make histos for a given dimension
2070   if ( index >= ExternalDimension() ) 
2071   {
2072     AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
2073     return;
2074   }
2075   
2076   AliWarning(Form("Will %s make histogram for data %s index %d : that might ressemble a memory leak depending on the input data",
2077                   value ? "":"not", GetName(),index));
2078   fHistogramming[index] = value;
2079   fXmin = xmin;
2080   fXmax = xmax;
2081 }
2082
2083 //_____________________________________________________________________________
2084 void 
2085 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
2086 {
2087   /// Set the name of a given internal dimension
2088   if ( index >= fDimension ) 
2089   {
2090     AliError(Form("Index out of bounds : %d / %d",index,fDimension));
2091     return;
2092   }
2093   
2094   TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
2095     
2096   if ( ovalue ) 
2097   {
2098     fDimensionNames->Remove(ovalue);
2099     delete ovalue;
2100   }
2101   fDimensionNames->AddAt(new TObjString(value),index);
2102 }
2103
2104 //_____________________________________________________________________________
2105 void 
2106 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
2107 {
2108   /// Set the name of a given external dimension
2109   if ( index >= fExternalDimension ) 
2110   {
2111     AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
2112     return;
2113   }
2114   
2115   TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
2116   
2117   if ( ovalue ) 
2118   {
2119     fExternalDimensionNames->Remove(ovalue);
2120     delete ovalue;
2121   }
2122   fExternalDimensionNames->AddAt(new TObjString(value),index);
2123 }
2124
2125 //_____________________________________________________________________________
2126 Double_t 
2127 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, 
2128                           Int_t dim, Int_t ddlId) const
2129 {
2130   /// Compute the value for a given dim, using the internal information we have
2131   /// Basically we're converting sum of weights and sum of squares of weights
2132   /// into means and sigmas, and number of events into occupancy number.
2133
2134   Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
2135   
2136   if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
2137   
2138   Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
2139
2140   if ( dim >= fDimension ) 
2141   {
2142     return occ;
2143   }
2144   
2145   if ( dim == IndexOfOccupancyDimension() ) 
2146   {
2147     if ( ddlId < 0 ) AliError("Got a negative ddl id !");
2148     return occ/n/NumberOfEvents(ddlId);
2149   }
2150   
2151   Double_t value = param.ValueAsDouble(i,dim);
2152   
2153   if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
2154   
2155   if ( TMath::Even(dim) || IsSingleEvent() ) 
2156   {
2157                 Double_t x = value/occ;
2158                 
2159                 return ( TMath::Finite(x) ? x : 0.0 ) ;
2160   }
2161   else
2162   {
2163     Double_t nn = occ;
2164     
2165     if ( nn > 1.0 ) 
2166     {
2167       Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
2168     
2169       return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
2170     }
2171     else
2172     {
2173       return 0.0;
2174     }
2175   }
2176   
2177   AliError("Why am I here ?");
2178   return 0.0;
2179 }
2180
2181 //_____________________________________________________________________________
2182 void 
2183 AliMUONTrackerData::Streamer(TBuffer &R__b)
2184 {
2185   /// Customized streamer                                                    
2186   
2187   if (R__b.IsReading()) {
2188     AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
2189     if ( !fNofDDLs )
2190     {
2191       // backward compatible mode : we set number of events
2192       // per DDL to the total number of events (the only information
2193       // we had before version 7 of that class)
2194       delete[] fNofEventsPerDDL;
2195       fNofDDLs=20;
2196       fNofEventsPerDDL = new Int_t[fNofDDLs];
2197       for ( Int_t i = 0; i < fNofDDLs; ++i ) 
2198       {
2199         fNofEventsPerDDL[i] = fNevents;
2200       }
2201     }
2202   } 
2203   else {
2204     AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
2205   }
2206 }
2207
2208 //_____________________________________________________________________________
2209 Bool_t 
2210 AliMUONTrackerData::ExportAsASCIIOccupancyFile(const char* filename, Int_t runNumber) const
2211 {
2212   /// Export only the occupancy part, in a format compatible with what
2213   /// the online occupancy DA is writing
2214   
2215   if ( ! AliMpDDLStore::Instance(kFALSE) )
2216   {
2217     AliError("Mapping not loaded. Cannot work");
2218     return kFALSE;
2219   }
2220   
2221   if (!fManuValues)
2222   {
2223     AliError("No manu values. Cannot work");
2224     return kFALSE;
2225   }
2226   
2227   ofstream out(filename);
2228   
2229   if (out.bad())
2230   {
2231     AliError(Form("Cannot create file %s",filename));
2232     return kFALSE;
2233   }
2234   
2235   out << "//===========================================================================" << endl;
2236   out << "//  Hit counter exported from $Id$" << endl;
2237   out << "//===========================================================================" << endl;
2238   out << "//" << endl;
2239   out << "//       * Run Number          : " << runNumber << endl;
2240   out << "//       * File Creation Date  : " << TTimeStamp().AsString("l") << endl;
2241   out << "//---------------------------------------------------------------------------" << endl;
2242   out << "//  BP   MANU  SUM_N  NEVENTS" << endl;
2243   out << "//---------------------------------------------------------------------------" << endl;
2244   
2245   TIter next(fManuValues->CreateIterator());
2246   AliMUONVCalibParam* manu;
2247   
2248   while ( ( manu = static_cast<AliMUONVCalibParam*>(next()) ) )
2249   {
2250     Int_t detElemId = manu->ID0();
2251     Int_t manuId = manu->ID1();
2252     Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
2253     Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus( busPatchId);
2254     if ( busPatchId < 0 || ddl < 0 )
2255     {
2256       AliError(Form("Got invalid (DE,manu,bp,ddl)=(%d,%d,%d,%d). Skipping it",detElemId,manuId,busPatchId,ddl));
2257       continue;
2258     }
2259
2260     Int_t nevents = fNofEventsPerDDL[ddl];
2261     
2262     out << Form("%5d %5d %10d %10d",busPatchId,manuId,manu->ValueAsInt(0,IndexOfOccupancyDimension()),nevents) << endl;
2263   }
2264   
2265   out.close();
2266   return kTRUE;
2267 }
2268   
2269 //_____________________________________________________________________________
2270 void AliMUONTrackerData::DispatchValue(AliMUONVCalibParam& param, 
2271                                        Int_t index,
2272                                        Double_t y, 
2273                                        Double_t ey,
2274                                        Int_t nchannels)
2275 {
2276   /// fills the calibparam with a single value
2277   
2278   Double_t sumn = 1000.0; // or any value strictly above 1
2279   Double_t sumw = sumn*y;
2280   Double_t sumw2 = (sumn-1)*ey*ey+sumw*sumw/sumn;
2281   
2282   param.SetValueAsDouble(index,0,sumw);
2283   param.SetValueAsDouble(index,1,sumw2);
2284   param.SetValueAsDouble(index,2,sumn);
2285   param.SetValueAsDouble(index,3,nchannels);
2286   
2287 }