]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONTrackerData.cxx
-- modified cut analysis for Pb-Pb
[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   if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled ) 
660   {
661     AliError("Incompatible IsChannelLevelEnabled status");
662     return kFALSE;
663   }
664   
665   if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled ) 
666   {
667     AliError("Incompatible IsManuLevelEnabled status");
668     return kFALSE;
669   }
670   
671   if ( fIsSingleEvent != data.fIsSingleEvent ) 
672   {
673     AliError("Incompatible IsSingleEvent status");
674     return kFALSE;
675   }
676   
677   if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension ) 
678   {
679     AliError("Incompatible dimensions");
680     return kFALSE;
681   }
682
683   if ( fNofDDLs != data.fNofDDLs ) 
684   {
685     AliError("Incompatible number of Ddls");
686     return kFALSE;
687   }
688   
689   if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming ) 
690       || fXmin != data.fXmin || fXmax != data.fXmax ) 
691   {
692     AliError(Form("Incompatible histogramming (%p vs %p) (xmax = %e vs %e ; xmin = %e vs %e)",
693              fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
694     return kFALSE;
695   }
696
697   if ( fHistogramming )
698   {
699     for ( Int_t i = 0; i < fExternalDimension; ++i ) 
700     {
701       if ( fHistogramming[i] != data.fHistogramming[i] )
702       {
703         AliError(Form("Incompatible histogramming for external dimension %d",i));
704         return kFALSE;
705       }
706     }
707   }
708   
709   // OK. Seems we have compatible objects, so we can proceed with the actual
710   // merging...
711   
712   if ( data.fChannelValues ) 
713   {
714     Add2D(*(data.fChannelValues),*fChannelValues);
715   }
716   
717   if ( data.fManuValues ) 
718   {
719     Add2D(*(data.fManuValues),*fManuValues);
720   }
721   
722   if ( data.fPCBValues ) 
723   {
724     Add2D(*(data.fPCBValues),*fPCBValues);
725   }
726   
727   if ( data.fBusPatchValues ) 
728   {
729     Add1D(*(data.fBusPatchValues),*fBusPatchValues);
730   }
731   
732   if ( data.fDEValues ) 
733   {
734     Add1D(*(data.fDEValues),*fDEValues);
735   }
736   
737   if ( data.fChamberValues ) 
738   {
739     Add1D(*(data.fChamberValues),*fChamberValues);
740   }
741
742   for ( Int_t i = 0; i < fNofDDLs; ++i ) 
743   {
744     fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
745   }
746   
747   if ( data.fHistos ) 
748   {
749     TIter nexthisto(data.fHistos->CreateIterator());
750     AliMUONVStore* store;
751     while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
752     {
753       TIter ns(store->CreateIterator());
754       AliMUONSparseHisto* h;
755       while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
756       {
757         AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
758         
759         if (!thisStore)
760         {
761           thisStore = store->Create();
762           thisStore->SetUniqueID(store->GetUniqueID());
763           fHistos->Add(thisStore);
764         }
765         
766         AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
767         
768         if (!mine) 
769         {
770           thisStore->Add(h);
771         }
772         else
773         {
774           mine->Add(*h);
775         }
776       }
777     }
778   }
779   
780   fNevents =  TMath::Max(fNevents,data.fNevents);
781   
782   return kTRUE;
783 }
784
785 //_____________________________________________________________________________
786 void 
787 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
788 {
789   /// Add one 2d store to another
790   
791   TIter next(src.CreateIterator());
792   AliMUONVCalibParam* p;
793   
794   while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
795   {
796     AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
797     
798     if (!a)
799     {
800       dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
801     }
802     else
803     {
804       AddCalibParams(*p,*a);
805     }
806   }
807 }
808
809 //_____________________________________________________________________________
810 void 
811 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
812 {
813   /// Add one 1d store to another
814   
815   TIter next(src.CreateIterator());
816   AliMUONVCalibParam* p;
817   
818   while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
819   {
820     AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
821     
822     if (!a)
823     {
824       dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
825     }
826     else
827     {
828       AddCalibParams(*p,*a);
829     }
830   }
831 }
832
833 //_____________________________________________________________________________
834 void
835 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
836 {
837   /// Add src to dest
838   for ( Int_t i = 0; i < src.Size(); ++i ) 
839   {
840     for ( Int_t j = 0; j < src.Dimension(); ++j )
841     {
842       dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
843     }
844   }
845 }
846
847 //_____________________________________________________________________________
848 Bool_t
849 AliMUONTrackerData::Replace(const AliMUONVStore& store)
850 {
851   /// Replace our values by values from the given external store
852   Bool_t rv = InternalAdd(store,0x0,kTRUE);
853   AliMUONVTrackerData::Replace(store);
854   return rv;
855 }
856
857 //_____________________________________________________________________________
858 Bool_t
859 AliMUONTrackerData::UpdateNumberOfEvents(TArrayI* nevents)
860 {
861   /// Update the number of events
862   
863   if (!fNofDDLs)
864   {
865     fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
866     fNofEventsPerDDL = new Int_t[fNofDDLs];
867     for ( Int_t i = 0; i < fNofDDLs; ++i ) 
868     {
869       fNofEventsPerDDL[i] = 0;
870     }
871   }
872   
873   if (nevents)
874   {
875     if (nevents->GetSize() != fNofDDLs ) 
876     {
877       AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
878                     nevents->GetSize(),fNofDDLs));
879       return kFALSE;
880     }
881     
882     for ( Int_t i = 0 ; i < fNofDDLs; ++i ) 
883     {
884       fNofEventsPerDDL[i] += nevents->At(i);
885       fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
886     }
887   }
888   else
889   {
890     for ( Int_t i = 0 ; i < fNofDDLs; ++i ) 
891     {
892       ++fNofEventsPerDDL[i];
893       fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
894     }
895   }
896   return kTRUE;
897 }
898
899 //_____________________________________________________________________________
900 void
901 AliMUONTrackerData::AssertStores()
902 {
903   /// Insure our stores are allocated
904   
905   if (!fChamberValues)
906   {
907     Int_t numberOfBusPatches(0);
908     Int_t numberOfDEs(0);
909     
910     // get number of bus patches and number of detection element
911     // to initialize fBusPatchValues and fDEValues below
912     
913     TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
914     while ( next() ) ++numberOfBusPatches;
915     AliMpDEIterator deIt;
916     deIt.First();
917     while (!deIt.IsDone())
918     {
919       ++numberOfDEs;
920       deIt.Next();
921     }
922     
923     if ( fIsChannelLevelEnabled ) 
924     {
925       fChannelValues = new AliMUON2DMap(kTRUE);
926     }
927     if  ( fIsManuLevelEnabled ) 
928     {
929       fManuValues = new AliMUON2DMap(kTRUE);
930     }
931     if ( fIsPCBLevelEnabled )
932     {
933       fPCBValues = new AliMUON2DMap(kFALSE);
934     }
935     if ( fIsBustPatchLevelEnabled )
936     {
937       fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
938     }
939     fDEValues = new AliMUON1DMap(numberOfDEs);
940     fChamberValues = new AliMUON1DArray;
941   }
942 }
943
944 //_____________________________________________________________________________
945 Bool_t
946 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
947 {
948   /// Add the given external store to our internal store
949   
950   AliCodeTimerAuto(GetName(),0);
951     
952   if ( !replace)
953   {
954     if ( IsSingleEvent() && NumberOfEvents(-1) == 1 ) 
955     {
956       AliError(Form("%s is supposed to be single event only",GetName()));
957       return kFALSE;
958     }  
959   }
960
961   UpdateNumberOfEvents(nevents);
962   
963   AssertStores();
964   
965   TIter next(store.CreateIterator());
966   AliMUONVCalibParam* external;
967   
968   Int_t nk(2);
969   
970   if ( IsSingleEvent() ) nk = 1;
971
972   while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
973   {
974     if ( external->Dimension() != ExternalDimension() )
975     {
976       AliError(Form("Incompatible dimensions %d vs %d",
977                     external->Dimension(),ExternalDimension()));
978       return kFALSE;
979     }
980     
981     AliMUONVCalibParam* chamber(0x0);
982     AliMUONVCalibParam* de(0x0);
983     AliMUONVCalibParam* busPatch(0x0);
984     AliMUONVCalibParam* pcb(0x0);
985     AliMUONVCalibParam* manu(0x0);
986     AliMUONVCalibParam* channel(0x0);
987     AliMpDetElement* mpde(0x0);
988     
989     Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
990     
991     if ( manuId < 0 ) continue;
992     
993     Int_t detElemId = mpde->GetId();
994     
995     Double_t value[] = { 0.0, 0.0 };
996     
997     Int_t nch = mpde->NofChannelsInManu(manuId);
998     
999     for ( Int_t i = 0; i < external->Size(); ++i ) 
1000     {
1001       Bool_t existingChannel =  ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
1002                                                                            : mpde->IsConnectedChannel(manuId,i));
1003       // note we only use IsConnectedChannel method when really needed, as
1004       // it costs (some) CPU time...
1005       
1006       if ( existingChannel ) 
1007       {
1008         Bool_t validChannel(kFALSE);
1009         
1010         for ( Int_t j = 0; j < external->Dimension(); ++j )
1011         {
1012           Double_t vext = external->IsDoublePrecision() ? 
1013             external->ValueAsDoubleFast(i,j) :
1014             external->ValueAsFloatFast(i,j);
1015           
1016           if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
1017           
1018           validChannel = kTRUE;
1019                     
1020           Int_t ix = External2Internal(j);
1021           
1022           value[0] = vext;
1023           value[1] = vext*vext;
1024           
1025           if ( IsHistogrammed(j) )
1026           {
1027             FillHisto(detElemId,manuId,i,j,vext);
1028           }
1029           
1030           for ( Int_t k = 0; k < nk; ++k ) 
1031           {
1032             Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
1033             
1034                                                 if ( channel ) 
1035                                                 {
1036                                                         channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
1037                                                 }
1038                                                 
1039             if (manu)
1040             {
1041               manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);            
1042             }
1043             
1044             busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1045             
1046             de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1047             
1048             chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1049             
1050             if ( pcb ) 
1051             {
1052               pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1053             }
1054           }
1055         }
1056         
1057         if ( validChannel && !replace )
1058         {
1059                                         if ( channel ) 
1060                                         {
1061                                                 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
1062                                                                                                                                                                         channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
1063                                         }
1064                                         
1065           if (manu)
1066           {
1067             manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1068                                        manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
1069           }
1070           
1071           busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1072                                                          busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
1073           de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1074                                              de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
1075           chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1076                                                        chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0); 
1077           if ( pcb ) 
1078           {
1079             pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1080                                       pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
1081           }
1082         }
1083       }
1084     }
1085   }
1086   
1087   NumberOfEventsChanged();
1088   
1089   return kTRUE;
1090 }
1091
1092 //_____________________________________________________________________________
1093 Double_t 
1094 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
1095 {
1096   /// Return the value of a given buspatch for a given dimension
1097   /// or 0 if not existing
1098   AliMUONVCalibParam* param = BusPatchParam(busPatchId);
1099   return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
1100 }
1101
1102 //_____________________________________________________________________________
1103 AliMUONVCalibParam* 
1104 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
1105 {
1106   /// Return (if it exist), the VCalibParam for a given busPatch
1107   
1108   AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
1109     (fBusPatchValues->FindObject(busPatchId)) : 0x0;
1110   
1111   if (!busPatch && create && fBusPatchValues)
1112   {
1113     busPatch = CreateBusPatchParam(busPatchId);
1114     fBusPatchValues->Add(busPatch);
1115   }
1116   
1117   return busPatch;
1118 }
1119
1120 //_____________________________________________________________________________
1121 AliMUONVCalibParam* 
1122 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
1123 {
1124   /// Create storage for one bus patch
1125   
1126   AliCodeTimerAuto("",0);
1127   
1128   AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1129   
1130   if (!bp)
1131   {
1132     AliError(Form("Got an invalid buspatchId = %d",busPatchId));
1133     return 0x0;
1134   }
1135   
1136   AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
1137   
1138   // set the number of channels in that buspatch
1139   
1140   Int_t nchannels(0);
1141   
1142   Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
1143   
1144   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1145   
1146   for ( Int_t i = 0; i < bp->GetNofManus(); ++i ) 
1147   {
1148     Int_t manuId = bp->GetManuId(i);
1149     nchannels += de->NofChannelsInManu(manuId);
1150   }
1151   
1152   busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1153   
1154   return busPatch;
1155 }
1156
1157 //_____________________________________________________________________________
1158 Double_t 
1159 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
1160 {
1161   /// Return the value fo a given chamber for a given dimension,
1162   /// or zero if not existing
1163   
1164   // FIXME: is the Value() correct wrt to number of events in the case of
1165   // chamber ? Or should we do something custom at the chamber level 
1166   // (as it spans several ddls) ?
1167   
1168   AliMUONVCalibParam* param = ChamberParam(chamberId);
1169   return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
1170 }
1171
1172 //_____________________________________________________________________________
1173 AliMUONVCalibParam* 
1174 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
1175 {
1176   /// Return (if it exist) the VCalibParam for a given chamber
1177   
1178   AliMUONVCalibParam* chamber =  fChamberValues ? static_cast<AliMUONVCalibParam*>
1179   (fChamberValues->FindObject(chamberId)) : 0x0;
1180   
1181   if (!chamber && create && fChamberValues)
1182   {
1183     chamber = CreateChamberParam(chamberId);
1184     fChamberValues->Add(chamber);
1185   }
1186     
1187   return chamber;
1188 }
1189
1190 //_____________________________________________________________________________
1191 AliMUONVCalibParam* 
1192 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
1193 {
1194   /// Create storage for one chamber
1195   
1196   AliCodeTimerAuto("",0);
1197   
1198   AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
1199   
1200   // set the number of channels in that chamber
1201   
1202   Int_t nchannels(0);
1203   
1204   AliMpDEIterator it;
1205   
1206   it.First(chamberId);
1207   
1208   while ( !it.IsDone() )
1209   {        
1210     AliMpDetElement* det = it.CurrentDE();
1211     
1212     for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
1213     {
1214       Int_t busPatchId = det->GetBusPatchId(i);
1215       AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1216       for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
1217       {
1218         Int_t manuId = bp->GetManuId(j);
1219         nchannels += det->NofChannelsInManu(manuId);
1220       }        
1221     }
1222     
1223     it.Next();
1224   }
1225   
1226   chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1227   
1228   return chamber;
1229 }
1230
1231 //_____________________________________________________________________________
1232 Double_t 
1233 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId, 
1234                             Int_t manuChannel, Int_t dim) const
1235 {
1236   /// Return the value for a given channel for a given dimension
1237   
1238   AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
1239   
1240   return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1241 }
1242
1243 //_____________________________________________________________________________
1244 AliMUONVCalibParam* 
1245 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
1246                                  const AliMUONVCalibParam* external) const
1247 {
1248   /// Return (if it exist) the VCalibParam for a given manu
1249   
1250   AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
1251     (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
1252   
1253   if (!param && external && fChannelValues)
1254   {
1255     param = CreateDouble(*external,detElemId,manuId);
1256     fChannelValues->Add(param);
1257   }
1258   
1259   return param;
1260 }
1261
1262 //_____________________________________________________________________________
1263 void 
1264 AliMUONTrackerData::Clear(Option_t*)
1265 {
1266   /// Clear all the values
1267   if ( fChannelValues ) fChannelValues->Clear();
1268   if ( fManuValues ) fManuValues->Clear();
1269   if ( fBusPatchValues) fBusPatchValues->Clear();
1270   if ( fPCBValues ) fPCBValues->Clear();
1271   if ( fDEValues) fDEValues->Clear();
1272   if ( fChamberValues ) fChamberValues->Clear();
1273   if ( fHistos ) fHistos->Clear();
1274   for ( Int_t i = 0; i < fNofDDLs; ++i ) 
1275   {
1276     fNofEventsPerDDL[i] = 0;
1277   }
1278   fNevents = 0;
1279   NumberOfEventsChanged();
1280 }
1281
1282 //_____________________________________________________________________________
1283 Double_t 
1284 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId, 
1285                           Int_t manuChannel) const
1286 {
1287   /// Return the number of times a given channel had data
1288   
1289   return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
1290 }
1291
1292 //_____________________________________________________________________________
1293 AliMUONVCalibParam*
1294 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param, 
1295                                  Int_t detElemId, Int_t manuId) const
1296 {
1297   /// Create a double version of VCalibParam, for internal use
1298   
1299   AliCodeTimerAuto("",0);
1300   
1301   AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
1302                                                   param.Size(),
1303                                                   detElemId,
1304                                                   manuId,
1305                                                   0.0);
1306   
1307   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
1308   
1309   for ( Int_t i = 0; i < c->Size(); ++i ) 
1310   {
1311     Double_t value(0.0);
1312     
1313     if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
1314       
1315     c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
1316   }
1317   
1318   return c;
1319 }
1320
1321 //_____________________________________________________________________________
1322 Double_t 
1323 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
1324 {
1325   /// Return the value for a given detection element for a given dimension
1326   AliMUONVCalibParam* param = DetectionElementParam(detElemId);
1327   return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1328
1329 }
1330
1331 //_____________________________________________________________________________
1332 AliMUONVCalibParam* 
1333 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
1334 {
1335   /// Return (if it exist) the VCalibParam for a given detection element
1336   
1337   AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
1338     (fDEValues->FindObject(detElemId)) : 0x0 ;
1339   
1340   if (!de && create && fDEValues)
1341   {
1342     de = CreateDetectionElementParam(detElemId);
1343     fDEValues->Add(de);
1344   }
1345   
1346   return de;
1347   
1348 }
1349
1350 //_____________________________________________________________________________
1351 AliMUONVCalibParam* 
1352 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
1353 {
1354   /// Create storage for one detection element
1355   
1356   AliCodeTimerAuto("",0);
1357   
1358   AliMUONVCalibParam*  de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
1359   
1360   AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1361   Int_t nchannels(0);
1362   
1363   for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
1364   {
1365     Int_t busPatchId = det->GetBusPatchId(i);
1366     AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1367     for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
1368     {
1369       Int_t manuId = bp->GetManuId(j);
1370       nchannels += det->NofChannelsInManu(manuId);
1371     }        
1372   }
1373   
1374   de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1375   
1376   return de;
1377 }
1378
1379 //_____________________________________________________________________________
1380 Int_t 
1381 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
1382 {
1383   /// Get the "local" ddlid (0..19) of a given buspatch
1384   AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
1385   if (bp)
1386   {
1387     return bp->GetDdlId();
1388   }
1389   return -1;
1390 }
1391
1392 //_____________________________________________________________________________
1393 Int_t 
1394 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
1395 {
1396   /// Get the "local" ddlid (0..19) of a given detection element
1397   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
1398   if (de)
1399   {
1400     return de->GetDdlId();
1401   }
1402   return -1;
1403 }
1404
1405 //_____________________________________________________________________________
1406 Int_t 
1407 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
1408 {
1409   /// Get the "local" ddlid (0..19) of a given chamber
1410   /// This has no real meaning (as there are several ddls per chamber),
1411   /// so we take the ddlid where we got the max number of events
1412   
1413   AliMpDEIterator it;
1414   
1415   it.First(chamberid);
1416   Int_t n(0);
1417   Int_t d(-1);
1418   
1419   while (!it.IsDone())
1420   {
1421     Int_t detElemId = it.CurrentDEId();
1422     Int_t ddlId = DdlIdFromDetElemId(detElemId);
1423     if ( NumberOfEvents(ddlId) > n ) 
1424     {
1425       n = NumberOfEvents(ddlId);
1426       d = ddlId;
1427     }
1428     it.Next();
1429   }
1430   
1431   return d;
1432 }
1433
1434 //_____________________________________________________________________________
1435 TString 
1436 AliMUONTrackerData::DimensionName(Int_t dim) const
1437 {
1438   /// Get the name of a given dimension
1439   TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
1440   if ( value ) 
1441   {
1442     return value->String();
1443   }
1444   else
1445   {
1446     return TString("Invalid");
1447   }  
1448 }
1449
1450 //_____________________________________________________________________________
1451 void 
1452 AliMUONTrackerData::DisableChannelLevel()
1453
1454   /// Disable the storing of data at channel level
1455   
1456   delete fChannelValues;
1457   fChannelValues = 0x0;
1458   fIsChannelLevelEnabled = kFALSE; 
1459 }
1460
1461 //_____________________________________________________________________________
1462 void 
1463 AliMUONTrackerData::DisableManuLevel()
1464
1465   /// Disable the storing of data at manu level (and below)
1466   
1467   DisableChannelLevel();
1468   delete fManuValues;
1469   fManuValues = 0x0;
1470   fIsManuLevelEnabled = kFALSE; 
1471 }
1472
1473 //_____________________________________________________________________________
1474 Int_t 
1475 AliMUONTrackerData::External2Internal(Int_t index) const 
1476 {
1477   /// From external to internal dimension
1478   return IsSingleEvent() ? index : index*2;
1479 }
1480
1481 //_____________________________________________________________________________
1482 TString 
1483 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
1484 {
1485   /// Get the name of a given external dimension
1486   
1487   TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
1488   if ( value ) 
1489   {
1490     return value->String();
1491   }
1492   else
1493   {
1494     return TString("Invalid");
1495   }  
1496 }
1497
1498 //_____________________________________________________________________________
1499 void
1500 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
1501                               Int_t dim, Double_t value)
1502 {
1503   /// Fill histogram of a given channel
1504   
1505   AliMUONSparseHisto* h(0x0);
1506   
1507         if ( fIsChannelLevelEnabled ) 
1508         {
1509                 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
1510   }
1511   else if ( fIsManuLevelEnabled ) 
1512   {
1513     h = GetManuSparseHisto(detElemId,manuId,dim);
1514   }
1515   
1516   AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
1517   
1518   if (h)
1519   {
1520                 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
1521         }
1522 }
1523
1524 //_____________________________________________________________________________
1525 AliMUONSparseHisto*
1526 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, 
1527                                        Int_t dim) const
1528 {
1529   /// Get histogram of a given manu
1530   
1531   if (!fHistos) return 0x0;
1532   
1533   AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1534   if (!m) return 0x0;
1535   
1536   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1537   
1538   return h;
1539 }
1540
1541 //_____________________________________________________________________________
1542 AliMUONSparseHisto*
1543 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
1544 {
1545   /// Get histogram of a given manu. Create it if necessary
1546   
1547   if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1548   
1549   AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1550   if (!m)
1551   {
1552     m = new AliMUON1DArray(NumberOfDimensions());
1553     m->SetUniqueID( ( manuId << 16 ) | detElemId );
1554     fHistos->Add(m);
1555   }
1556     
1557   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1558   if (!h)
1559   {
1560     h = new AliMUONSparseHisto(fXmin,fXmax);
1561     
1562     h->SetUniqueID(dim);
1563     
1564     m->Add(h);
1565   }
1566   
1567    return h;
1568 }
1569
1570 //_____________________________________________________________________________
1571 AliMUONSparseHisto*
1572 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, 
1573                                           Int_t manuChannel, Int_t dim) const
1574 {
1575   /// Get histogram of a given channel
1576   
1577   if (!fHistos) return 0x0;
1578   
1579   AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1580   if (!m) return 0x0;
1581   
1582   UInt_t uid = ( manuChannel << 16 ) | dim;
1583   
1584   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1585   
1586   return h;
1587 }
1588
1589 //_____________________________________________________________________________
1590 AliMUONSparseHisto*
1591 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, 
1592                                           Int_t manuChannel, Int_t dim)
1593 {
1594   /// Get histogram of a given channel. Create it if necessary
1595   
1596   if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1597   
1598   AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1599   if (!m)
1600   {
1601     m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1602     m->SetUniqueID( ( manuId << 16 ) | detElemId );
1603     fHistos->Add(m);
1604   }
1605   
1606   UInt_t uid = ( manuChannel << 16 ) | dim;
1607   
1608   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1609   if (!h)
1610   {
1611     h = new AliMUONSparseHisto(fXmin,fXmax);
1612     
1613     h->SetUniqueID(uid);
1614     
1615     m->Add(h);
1616   }
1617
1618   return h;
1619 }
1620
1621 //_____________________________________________________________________________
1622 void
1623 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1624                               Int_t& detElemId, Int_t& manuId) const
1625 {
1626   /// Tries to get (detElemId,manuId) of param
1627   
1628   // Load mapping manu store
1629   if ( ! AliMpCDB::LoadManuStore() ) {
1630     AliError("Could not access manu store from OCDB !");
1631     return;
1632   }
1633
1634   if ( param.ID1() <= 0 ) 
1635   {
1636     // we (probably) get a manu serial number
1637     Int_t serial = param.ID0();
1638     MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1639     detElemId = AliMp::PairFirst(pair);
1640     manuId = AliMp::PairSecond(pair);
1641     if ( !detElemId ) 
1642     {
1643       AliDebug(1,Form("DE %d manuId %d from serial %d is not correct !",
1644                       detElemId,manuId,serial));
1645     }
1646   }
1647   else
1648   {
1649     // we get a (de,manu) pair
1650     detElemId = param.ID0();
1651     manuId = param.ID1();
1652   }
1653 }
1654
1655
1656 //_____________________________________________________________________________
1657 Int_t
1658 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1659                              AliMUONVCalibParam*& chamber,
1660                              AliMUONVCalibParam*& de,
1661                              AliMUONVCalibParam*& busPatch,
1662                              AliMUONVCalibParam*& pcb,
1663                              AliMUONVCalibParam*& manu,
1664                              AliMUONVCalibParam*& channel,
1665                              AliMpDetElement*& mpde)
1666 {
1667   /// Get containers at all levels
1668  
1669   chamber = de = busPatch = pcb = manu = channel = 0x0;
1670   mpde = 0x0;
1671   
1672   AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1673   
1674   Int_t detElemId;
1675   Int_t manuId;
1676   
1677   GetDEManu(*external,detElemId,manuId);
1678   
1679   mpde = ddlStore->GetDetElement(detElemId,kFALSE);
1680
1681   if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1682   {
1683     return -1;
1684   }
1685   
1686   // explicitely check that de,manu is correct
1687   const AliMpVSegmentation* mpseg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId,kFALSE);
1688   
1689   if (!mpseg)
1690   {
1691     return -1;
1692   }
1693   
1694   Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1695     
1696   Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1697   
1698   if ( busPatchId <= 0 )
1699   {
1700     return -1;
1701   }
1702   
1703   Int_t pcbIndex = -1;
1704   
1705   AliMp::StationType stationType = mpde->GetStationType();
1706   
1707   if ( stationType == AliMp::kStation345 ) 
1708   {
1709     AliMpDCSNamer namer("TRACKER");
1710     pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1711   }
1712   
1713   if ( fIsChannelLevelEnabled ) 
1714   {
1715     channel = ChannelParam(detElemId,manuId,external);
1716   }
1717   
1718   manu = ManuParam(detElemId,manuId,kTRUE);
1719   
1720   busPatch = BusPatchParam(busPatchId,kTRUE);
1721   
1722   de = DetectionElementParam(detElemId,kTRUE);
1723   
1724   chamber = ChamberParam(chamberId,kTRUE);
1725   
1726   pcb = 0x0;
1727   
1728   if ( pcbIndex >= 0 ) 
1729   {
1730     pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1731   }
1732   
1733   return manuId;
1734 }
1735
1736 //_____________________________________________________________________________
1737 Bool_t 
1738 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1739 {
1740   /// Whether we have data for a given buspatch
1741   return ( BusPatchParam(busPatchId) != 0 );
1742 }
1743
1744 //_____________________________________________________________________________
1745 Bool_t 
1746 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1747 {
1748   /// Whether we have data for a given chamber
1749   return ( ChamberParam(chamberId) != 0 );
1750 }
1751
1752 //_____________________________________________________________________________
1753 Bool_t 
1754 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1755 {
1756   /// Whether we have data for a given detection element
1757   return ( DetectionElementParam(detElemId) != 0 );
1758 }
1759
1760 //_____________________________________________________________________________
1761 Bool_t
1762 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1763 {
1764   /// Whether we have data for a given manu
1765   return ( ManuParam(detElemId,manuId) != 0 ); 
1766 }
1767
1768 //_____________________________________________________________________________
1769 Bool_t
1770 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1771 {
1772   /// Whether we have data for a given pcb
1773   return ( PCBParam(detElemId,pcbIndex) != 0 ); 
1774 }
1775
1776 //_____________________________________________________________________________
1777 Double_t 
1778 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1779 {
1780   /// Return the value for a given manu and a given dimension
1781   
1782   AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1783   return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1784 }
1785
1786 //_____________________________________________________________________________
1787 AliMUONVCalibParam* 
1788 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1789 {
1790   /// Get the VCalibParam for a given manu
1791   
1792   AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1793     (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1794   
1795   if (!manu && create && fManuValues)
1796   {
1797     manu = CreateManuParam(detElemId,manuId);
1798     fManuValues->Add(manu);
1799   }
1800   
1801   return manu;
1802 }
1803
1804 //_____________________________________________________________________________
1805 AliMUONVCalibParam* 
1806 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1807 {
1808   /// Create storage for one manu
1809   
1810   AliCodeTimerAuto("",0);
1811   
1812   AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1813   
1814   // set the number of channels in that manu
1815   
1816   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1817   
1818   manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1819   
1820   return manu;
1821 }
1822
1823 //_____________________________________________________________________________
1824 Long64_t
1825 AliMUONTrackerData::Merge(TCollection* list)
1826 {
1827   /// Merge this with a list of AliMUONVTrackerData
1828
1829   if (!list) return 0;
1830   
1831   if ( list->IsEmpty() ) return NumberOfEvents(-1);
1832   
1833   TIter next(list);
1834   const TObject* o(0x0);
1835   
1836   while ( ( o = next() ) )
1837   {
1838     const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1839     if (!data)
1840     {
1841       AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1842                     o->GetName()));
1843     }
1844     else
1845     {
1846       Bool_t ok = Add(*data);
1847       if (!ok)
1848       {
1849         AliError("Got incompatible objects");
1850       }
1851     }
1852   }
1853   
1854   return NumberOfEvents(-1);
1855 }
1856
1857 //_____________________________________________________________________________
1858 Int_t 
1859 AliMUONTrackerData::NumberOfDimensions() const
1860 {
1861   /// Number of dimensions we're dealing with
1862   
1863   return fDimension + fgkVirtualExtraDimension; 
1864 }
1865
1866 //_____________________________________________________________________________
1867 Int_t
1868 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1869 {
1870   /// Get the number of events we've seen for a given DDL, or the max
1871   /// in case ddlNumber<0
1872
1873   Int_t n(0);
1874   
1875   if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1876   {
1877     n = fNofEventsPerDDL[ddlNumber];
1878   }
1879   else
1880   {
1881     // get the max number of events
1882     return fNevents;
1883   }
1884   
1885   return n;
1886 }
1887
1888 //_____________________________________________________________________________
1889 Double_t 
1890 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1891 {
1892   /// Return the value of a given pcb for a given dimension
1893
1894   AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1895   
1896   return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1897 }
1898
1899 //_____________________________________________________________________________
1900 AliMUONVCalibParam* 
1901 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1902 {
1903   /// Return (if it exist) the VCalibParam for a given pcb
1904
1905   AliMUONVCalibParam* pcb =  fPCBValues ? static_cast<AliMUONVCalibParam*>
1906     (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1907   
1908   if (create && fPCBValues && !pcb)
1909   {
1910     pcb = CreatePCBParam(detElemId,pcbIndex);
1911     fPCBValues->Add(pcb);
1912   }
1913   
1914   return pcb;
1915 }
1916
1917 //_____________________________________________________________________________
1918 AliMUONVCalibParam* 
1919 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1920 {
1921   /// Create storage for one PCB (station345 only)
1922   
1923   AliCodeTimerAuto("",0);
1924   
1925   AliMpDCSNamer namer("TRACKER");
1926   
1927   AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1928                                                     namer.NumberOfPCBs(detElemId),
1929                                                     detElemId,
1930                                                     pcbIndex,
1931                                                     0.0);
1932   return pcb;
1933 }
1934
1935 //_____________________________________________________________________________
1936 void 
1937 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1938 {
1939   /// Printout
1940   
1941   TNamed::Print(opt);
1942   
1943   if ( !fIsSingleEvent ) 
1944   {
1945     for ( Int_t i = 0; i < fNofDDLs; ++i ) 
1946     {
1947       cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1948     }
1949   }
1950
1951         if ( !fIsChannelLevelEnabled ) 
1952         {
1953                 cout << "Is not storing data at the channel level" << endl;
1954         }
1955
1956   if ( !fIsManuLevelEnabled ) 
1957         {
1958                 cout << "Is not storing data at the manu level" << endl;
1959         }
1960   
1961   for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i ) 
1962   {
1963     TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1964     cout << Form("External Dimension %2d Name %s %s",i,
1965                  ( name ? name->String().Data() : "null"),
1966                  ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1967   }
1968   
1969   for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i ) 
1970   {
1971     TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1972     cout << Form("Internal Dimension %2d Name %s",i,
1973                  ( name ? name->String().Data() : "null")) << endl;
1974   }
1975     
1976   TString sopt(opt);
1977   sopt.ToUpper();
1978   
1979   if ( sopt.Contains("CHANNEL") )
1980   {
1981     if ( fIsChannelLevelEnabled ) 
1982     {      
1983       if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1984     }
1985     else
1986     {
1987       AliWarning("You requested channel values, but they were not stored !");
1988     }
1989   }
1990
1991   if ( sopt.Contains("MANU") )
1992   {
1993     if ( fIsManuLevelEnabled ) 
1994     {
1995       if ( fManuValues ) fManuValues->Print(wildcard,opt);
1996     }
1997     else
1998     {
1999       AliWarning("You requested manu values, but they were not stored !");
2000     }
2001   }
2002
2003   if ( sopt.Contains("BUSPATCH") && fBusPatchValues ) 
2004   {
2005     fBusPatchValues->Print(wildcard,opt);
2006   }
2007
2008   if ( sopt.Contains("DE") && fDEValues ) 
2009   {
2010     fDEValues->Print(wildcard,opt);
2011   }
2012
2013   if ( sopt.Contains("CHAMBER") && fChamberValues ) 
2014   {
2015     fChamberValues->Print(wildcard,opt);
2016   }
2017   
2018 }
2019
2020 //_____________________________________________________________________________
2021 void
2022 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
2023 {  
2024   /// Set the name of a given dimension
2025
2026   if ( index >= fExternalDimension ) 
2027   {
2028     AliError(Form("%s : dimension %s : Index out of bounds : %d / %d",
2029                   GetName(),
2030                   name,index,fExternalDimension));
2031     return;
2032   }
2033   
2034   Int_t ix = External2Internal(index);
2035   
2036   if ( !IsSingleEvent() ) 
2037   {
2038     const char* prefix[] = { "mean", "sigma" };
2039   
2040     for ( Int_t i = 0; i < 2; ++i ) 
2041     {
2042       Int_t j = ix+i;
2043     
2044       SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
2045     }
2046   }
2047   else
2048   {
2049     SetInternalDimensionName(index,name);
2050   }
2051   
2052   SetExternalDimensionName(index,name);
2053 }
2054
2055 //_____________________________________________________________________________
2056 void 
2057 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
2058 {
2059   /// decide to make histos for a given dimension
2060   if ( index >= ExternalDimension() ) 
2061   {
2062     AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
2063     return;
2064   }
2065   
2066   AliWarning(Form("Will %s make histogram for data %s index %d : that might ressemble a memory leak depending on the input data",
2067                   value ? "":"not", GetName(),index));
2068   fHistogramming[index] = value;
2069   fXmin = xmin;
2070   fXmax = xmax;
2071 }
2072
2073 //_____________________________________________________________________________
2074 void 
2075 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
2076 {
2077   /// Set the name of a given internal dimension
2078   if ( index >= fDimension ) 
2079   {
2080     AliError(Form("Index out of bounds : %d / %d",index,fDimension));
2081     return;
2082   }
2083   
2084   TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
2085     
2086   if ( ovalue ) 
2087   {
2088     fDimensionNames->Remove(ovalue);
2089     delete ovalue;
2090   }
2091   fDimensionNames->AddAt(new TObjString(value),index);
2092 }
2093
2094 //_____________________________________________________________________________
2095 void 
2096 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
2097 {
2098   /// Set the name of a given external dimension
2099   if ( index >= fExternalDimension ) 
2100   {
2101     AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
2102     return;
2103   }
2104   
2105   TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
2106   
2107   if ( ovalue ) 
2108   {
2109     fExternalDimensionNames->Remove(ovalue);
2110     delete ovalue;
2111   }
2112   fExternalDimensionNames->AddAt(new TObjString(value),index);
2113 }
2114
2115 //_____________________________________________________________________________
2116 Double_t 
2117 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, 
2118                           Int_t dim, Int_t ddlId) const
2119 {
2120   /// Compute the value for a given dim, using the internal information we have
2121   /// Basically we're converting sum of weights and sum of squares of weights
2122   /// into means and sigmas, and number of events into occupancy number.
2123
2124   Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
2125   
2126   if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
2127   
2128   Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
2129
2130   if ( dim >= fDimension ) 
2131   {
2132     return occ;
2133   }
2134   
2135   if ( dim == IndexOfOccupancyDimension() ) 
2136   {
2137     if ( ddlId < 0 ) AliError("Got a negative ddl id !");
2138     return occ/n/NumberOfEvents(ddlId);
2139   }
2140   
2141   Double_t value = param.ValueAsDouble(i,dim);
2142   
2143   if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
2144   
2145   if ( TMath::Even(dim) || IsSingleEvent() ) 
2146   {
2147                 Double_t x = value/occ;
2148                 
2149                 return ( TMath::Finite(x) ? x : 0.0 ) ;
2150   }
2151   else
2152   {
2153     Double_t nn = occ;
2154     
2155     if ( nn > 1.0 ) 
2156     {
2157       Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
2158     
2159       return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
2160     }
2161     else
2162     {
2163       return 0.0;
2164     }
2165   }
2166   
2167   AliError("Why am I here ?");
2168   return 0.0;
2169 }
2170
2171 //_____________________________________________________________________________
2172 void 
2173 AliMUONTrackerData::Streamer(TBuffer &R__b)
2174 {
2175   /// Customized streamer                                                    
2176   
2177   if (R__b.IsReading()) {
2178     AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
2179     if ( !fNofDDLs )
2180     {
2181       // backward compatible mode : we set number of events
2182       // per DDL to the total number of events (the only information
2183       // we had before version 7 of that class)
2184       delete[] fNofEventsPerDDL;
2185       fNofDDLs=20;
2186       fNofEventsPerDDL = new Int_t[fNofDDLs];
2187       for ( Int_t i = 0; i < fNofDDLs; ++i ) 
2188       {
2189         fNofEventsPerDDL[i] = fNevents;
2190       }
2191     }
2192   } 
2193   else {
2194     AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
2195   }
2196 }
2197
2198 //_____________________________________________________________________________
2199 Bool_t 
2200 AliMUONTrackerData::ExportAsASCIIOccupancyFile(const char* filename, Int_t runNumber) const
2201 {
2202   /// Export only the occupancy part, in a format compatible with what
2203   /// the online occupancy DA is writing
2204   
2205   if ( ! AliMpDDLStore::Instance(kFALSE) )
2206   {
2207     AliError("Mapping not loaded. Cannot work");
2208     return kFALSE;
2209   }
2210   
2211   if (!fManuValues)
2212   {
2213     AliError("No manu values. Cannot work");
2214     return kFALSE;
2215   }
2216   
2217   ofstream out(filename);
2218   
2219   if (out.bad())
2220   {
2221     AliError(Form("Cannot create file %s",filename));
2222     return kFALSE;
2223   }
2224   
2225   out << "//===========================================================================" << endl;
2226   out << "//  Hit counter exported from $Id$" << endl;
2227   out << "//===========================================================================" << endl;
2228   out << "//" << endl;
2229   out << "//       * Run Number          : " << runNumber << endl;
2230   out << "//       * File Creation Date  : " << TTimeStamp().AsString("l") << endl;
2231   out << "//---------------------------------------------------------------------------" << endl;
2232   out << "//  BP   MANU  SUM_N  NEVENTS" << endl;
2233   out << "//---------------------------------------------------------------------------" << endl;
2234   
2235   TIter next(fManuValues->CreateIterator());
2236   AliMUONVCalibParam* manu;
2237   
2238   while ( ( manu = static_cast<AliMUONVCalibParam*>(next()) ) )
2239   {
2240     Int_t detElemId = manu->ID0();
2241     Int_t manuId = manu->ID1();
2242     Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
2243     Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus( busPatchId);
2244     if ( busPatchId < 0 || ddl < 0 )
2245     {
2246       AliError(Form("Got invalid (DE,manu,bp,ddl)=(%d,%d,%d,%d). Skipping it",detElemId,manuId,busPatchId,ddl));
2247       continue;
2248     }
2249
2250     Int_t nevents = fNofEventsPerDDL[ddl];
2251     
2252     out << Form("%5d %5d %10d %10d",busPatchId,manuId,manu->ValueAsInt(0,IndexOfOccupancyDimension()),nevents) << endl;
2253   }
2254   
2255   out.close();
2256   return kTRUE;
2257 }
2258   
2259 //_____________________________________________________________________________
2260 void AliMUONTrackerData::DispatchValue(AliMUONVCalibParam& param, 
2261                                        Int_t index,
2262                                        Double_t y, 
2263                                        Double_t ey,
2264                                        Int_t nchannels)
2265 {
2266   /// fills the calibparam with a single value
2267   
2268   Double_t sumn = 1000.0; // or any value strictly above 1
2269   Double_t sumw = sumn*y;
2270   Double_t sumw2 = (sumn-1)*ey*ey+sumw*sumw/sumn;
2271   
2272   param.SetValueAsDouble(index,0,sumw);
2273   param.SetValueAsDouble(index,1,sumw2);
2274   param.SetValueAsDouble(index,2,sumn);
2275   param.SetValueAsDouble(index,3,nchannels);
2276   
2277 }