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