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