]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONTrackerData.cxx
Removing an AliInfo
[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 "AliLog.h"
22 #include "AliMUON1DArray.h"
23 #include "AliMUON1DMap.h"
24 #include "AliMUON2DMap.h"
25 #include "AliMUONCalibParamND.h"
26 #include "AliMUONSparseHisto.h"
27 #include "AliMUONVStore.h"
28 #include "AliMpBusPatch.h"
29 #include "AliMpConstants.h"
30 #include "AliMpDDLStore.h"
31 #include "AliMpDEIterator.h"
32 #include "AliMpDEManager.h"
33 #include "AliMpDetElement.h"
34 #include "AliMpHVNamer.h"
35 #include "AliMpManuIterator.h"
36 #include <Riostream.h>
37 #include <TMath.h>
38 #include <TObjArray.h>
39 #include <TObjString.h>
40 #include <TString.h>
41 #include <TVector2.h>
42 #include <float.h>
43
44 /// \class AliMUONTrackerData
45 ///
46 /// Implementation of AliMUONVTrackerData class
47 ///
48 /// \author Laurent Aphecetche, Subatech
49
50 ///\cond CLASSIMP
51 ClassImp(AliMUONTrackerData)
52 ///\endcond
53
54 const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
55 const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
56
57 //_____________________________________________________________________________
58 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
59                                        Int_t dimension,
60                                        Bool_t issingleevent)
61 : AliMUONVTrackerData(name,title),
62 fIsSingleEvent(issingleevent),
63 fChannelValues(0x0),
64 fManuValues(0x0),
65 fBusPatchValues(0x0),
66 fDEValues(0x0),
67 fChamberValues(0x0),
68 fPCBValues(0x0),
69 fDimension(External2Internal(dimension)+fgkExtraDimension),
70 fNevents(0x0),
71 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
72 fExternalDimensionNames(new TObjArray(dimension)),
73 fExternalDimension(dimension),
74 fHistogramming(new Int_t[fExternalDimension]),
75 fChannelHistos(0x0),
76 fXmin(0.0),
77 fXmax(0.0)
78 {  
79   /// ctor
80   memset(fHistogramming,0,sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
81   fExternalDimensionNames->SetOwner(kTRUE);
82   fDimensionNames->SetOwner(kTRUE);  
83   fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
84   fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
85   fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
86   Clear();
87 }
88
89 //_____________________________________________________________________________
90 AliMUONTrackerData::~AliMUONTrackerData()
91 {
92   /// dtor
93   delete fChannelValues;
94   delete fManuValues;
95   delete fBusPatchValues;
96   delete fDEValues;
97   delete fChamberValues;
98   delete fPCBValues;
99   delete fDimensionNames;
100   delete fExternalDimensionNames;
101   delete[] fHistogramming;
102   delete fChannelHistos;
103 }
104
105 //_____________________________________________________________________________
106 Bool_t
107 AliMUONTrackerData::Add(const AliMUONVStore& store)
108 {
109   /// Add the given external store to our internal store
110   return InternalAdd(store,kFALSE);
111 }
112
113 //_____________________________________________________________________________
114 Bool_t
115 AliMUONTrackerData::Replace(const AliMUONVStore& store)
116 {
117   /// Replace our values by values from the given external store
118   Bool_t rv = InternalAdd(store,kTRUE);
119   AliMUONVTrackerData::Replace(store);
120   return rv;
121 }
122
123 //_____________________________________________________________________________
124 Bool_t
125 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, Bool_t replace)
126 {
127   /// Add the given external store to our internal store
128   
129   AliCodeTimerAuto(GetName());
130     
131   if ( !replace)
132   {
133     if ( IsSingleEvent() && fNevents == 1 ) 
134     {
135       AliError(Form("%s is supposed to be single event only",GetName()));
136       return kFALSE;
137     }  
138     ++fNevents;  
139     NumberOfEventsChanged();
140   }
141   
142   if (!fChannelValues)
143   {
144     Int_t numberOfBusPatches(0);
145     Int_t numberOfDEs(0);
146     
147     // get number of bus patches and number of detection element
148     // to initialize fBusPatchValues and fDEValues below
149     
150     TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
151     while ( next() ) ++numberOfBusPatches;
152     AliMpDEIterator deIt;
153     deIt.First();
154     while (!deIt.IsDone())
155     {
156       ++numberOfDEs;
157       deIt.Next();
158     }
159     
160     fChannelValues = new AliMUON2DMap(kTRUE);
161     fManuValues = new AliMUON2DMap(kTRUE);
162     fPCBValues = new AliMUON2DMap(kFALSE);
163     fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
164     fDEValues = new AliMUON1DMap(numberOfDEs);
165     fChamberValues = new AliMUON1DArray;
166   }
167   
168   TIter next(store.CreateIterator());
169   AliMUONVCalibParam* external;
170   
171   Int_t nk(2);
172   
173   if ( IsSingleEvent() ) nk = 1;
174
175   while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
176   {
177     if ( external->Dimension() != ExternalDimension() )
178     {
179       AliError(Form("Incompatible dimensions %d vs %d",
180                     external->Dimension(),ExternalDimension()));
181       return kFALSE;
182     }
183     
184
185     AliMUONVCalibParam* chamber, *de, *busPatch, *pcb, *manu, *channel;
186     AliMpDetElement* mpde;
187     
188     Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
189     
190     if ( manuId < 0 ) continue;
191     
192     Int_t detElemId = mpde->GetId();
193     
194     Double_t value[] = { 0.0, 0.0 };
195     
196     Int_t nch = mpde->NofChannelsInManu(manuId);
197     
198     for ( Int_t i = 0; i < external->Size(); ++i ) 
199     {
200       Bool_t existingChannel =  ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
201                                                                            : mpde->IsConnectedChannel(manuId,i));
202       // note we only use IsConnectedChannel method when really needed, as
203       // it costs (some) CPU time...
204       
205       if ( existingChannel ) 
206       {
207         Bool_t validChannel(kFALSE);
208         
209         for ( Int_t j = 0; j < external->Dimension(); ++j )
210         {
211           Double_t vext = external->IsDoublePrecision() ? 
212             external->ValueAsDoubleFast(i,j) :
213             external->ValueAsFloatFast(i,j);
214           
215           if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
216           
217           validChannel = kTRUE;
218                     
219           Int_t ix = External2Internal(j);
220           
221           value[0] = vext;
222           value[1] = vext*vext;
223           
224           if ( IsHistogrammed(j) )
225           {
226             FillChannel(detElemId,manuId,i,j,vext);
227           }
228           
229           for ( Int_t k = 0; k < nk; ++k ) 
230           {
231             Double_t e = replace ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
232             
233             channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
234               
235             manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);            
236             
237             busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
238             
239             de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
240             
241             chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
242             
243             if ( pcb ) 
244             {
245               pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
246             }
247           }
248         }
249         
250         if ( validChannel && !replace )
251         {
252           channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
253                                         channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
254           manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
255                                                  manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
256           busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
257                                                          busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
258           de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
259                                              de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
260           chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
261                                                        chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0); 
262           if ( pcb ) 
263           {
264             pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
265                                       pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
266           }
267         }
268       }
269     }
270   }
271   
272   return kTRUE;
273 }
274
275 //_____________________________________________________________________________
276 Double_t 
277 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
278 {
279   /// Return the value of a given buspatch for a given dimension
280   /// or 0 if not existing
281   AliMUONVCalibParam* param = BusPatchParam(busPatchId);
282   return param ? Value(*param,0,dim) : 0.0;
283 }
284
285 //_____________________________________________________________________________
286 AliMUONVCalibParam* 
287 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
288 {
289   /// Return (if it exist), the VCalibParam for a given busPatch
290   
291   AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
292     (fBusPatchValues->FindObject(busPatchId)) : 0x0;
293   
294   if (!busPatch && create && fBusPatchValues)
295   {
296     busPatch = CreateBusPatchParam(busPatchId);
297     fBusPatchValues->Add(busPatch);
298   }
299   
300   return busPatch;
301 }
302
303 //_____________________________________________________________________________
304 AliMUONVCalibParam* 
305 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
306 {
307   /// Create storage for one bus patch
308   
309   AliCodeTimerAuto("");
310   
311   AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
312   
313   if (!bp)
314   {
315     AliError(Form("Got an invalid buspatchId = %d",busPatchId));
316     return 0x0;
317   }
318   
319   AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
320   
321   // set the number of channels in that buspatch
322   
323   Int_t nchannels(0);
324   
325   Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
326   
327   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
328   
329   for ( Int_t i = 0; i < bp->GetNofManus(); ++i ) 
330   {
331     Int_t manuId = bp->GetManuId(i);
332     nchannels += de->NofChannelsInManu(manuId);
333   }
334   
335   busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
336   
337   return busPatch;
338 }
339
340 //_____________________________________________________________________________
341 Double_t 
342 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
343 {
344   /// Return the value fo a given chamber for a given dimension,
345   /// or zero if not existing
346   AliMUONVCalibParam* param = ChamberParam(chamberId);
347   return param ? Value(*param,0,dim) : 0.0;
348 }
349
350 //_____________________________________________________________________________
351 AliMUONVCalibParam* 
352 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
353 {
354   /// Return (if it exist) the VCalibParam for a given chamber
355   
356   AliMUONVCalibParam* chamber =  fChamberValues ? static_cast<AliMUONVCalibParam*>
357   (fChamberValues->FindObject(chamberId)) : 0x0;
358   
359   if (!chamber && create && fChamberValues)
360   {
361     chamber = CreateChamberParam(chamberId);
362     fChamberValues->Add(chamber);
363   }
364     
365   return chamber;
366 }
367
368 //_____________________________________________________________________________
369 AliMUONVCalibParam* 
370 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
371 {
372   /// Create storage for one chamber
373   
374   AliCodeTimerAuto("");
375   
376   AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
377   
378   // set the number of channels in that chamber
379   
380   Int_t nchannels(0);
381   
382   AliMpDEIterator it;
383   
384   it.First(chamberId);
385   
386   while ( !it.IsDone() )
387   {        
388     AliMpDetElement* det = it.CurrentDE();
389     
390     for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
391     {
392       Int_t busPatchId = det->GetBusPatchId(i);
393       AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
394       for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
395       {
396         Int_t manuId = bp->GetManuId(j);
397         nchannels += det->NofChannelsInManu(manuId);
398       }        
399     }
400     
401     it.Next();
402   }
403   
404   chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
405   
406   return chamber;
407 }
408
409 //_____________________________________________________________________________
410 Double_t 
411 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId, 
412                             Int_t manuChannel, Int_t dim) const
413 {
414   /// Return the value for a given channel for a given dimension
415   
416   AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
417   
418   return param ? Value(*param,manuChannel,dim) : 0.0;
419 }
420
421 //_____________________________________________________________________________
422 AliMUONVCalibParam* 
423 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
424                                  AliMUONVCalibParam* external) const
425 {
426   /// Return (if it exist) the VCalibParam for a given manu
427   
428   AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
429     (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
430   
431   if (!param && external && fChannelValues)
432   {
433     param = CreateDouble(*external,detElemId,manuId);
434     fChannelValues->Add(param);
435   }
436   
437   return param;
438 }
439
440 //_____________________________________________________________________________
441 void 
442 AliMUONTrackerData::Clear(Option_t*)
443 {
444   /// Clear all the values
445   if ( fChannelValues ) fChannelValues->Clear();
446   if ( fManuValues ) fManuValues->Clear();
447   if ( fBusPatchValues) fBusPatchValues->Clear();
448   if ( fPCBValues ) fPCBValues->Clear();
449   if ( fDEValues) fDEValues->Clear();
450   if ( fChamberValues ) fChamberValues->Clear();
451   if ( fChannelHistos ) fChannelHistos->Clear();
452   fNevents = 0;
453   NumberOfEventsChanged();
454 }
455
456 //_____________________________________________________________________________
457 Double_t 
458 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId, 
459                           Int_t manuChannel) const
460 {
461   /// Return the number of times a given channel had data
462   
463   return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
464 }
465
466 //_____________________________________________________________________________
467 AliMUONVCalibParam*
468 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param, 
469                                  Int_t detElemId, Int_t manuId) const
470 {
471   /// Create a double version of VCalibParam, for internal use
472   
473   AliCodeTimerAuto("");
474   
475   AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
476                                                   param.Size(),
477                                                   detElemId,
478                                                   manuId,
479                                                   0.0);
480   
481   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
482   
483   for ( Int_t i = 0; i < c->Size(); ++i ) 
484   {
485     Double_t value(0.0);
486     
487     if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
488       
489     c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
490   }
491   
492   return c;
493 }
494
495 //_____________________________________________________________________________
496 Double_t 
497 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
498 {
499   /// Return the value for a given detection element for a given dimension
500   AliMUONVCalibParam* param = DetectionElementParam(detElemId);
501   return param ? Value(*param,0,dim) : 0.0;
502
503 }
504
505 //_____________________________________________________________________________
506 AliMUONVCalibParam* 
507 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
508 {
509   /// Return (if it exist) the VCalibParam for a given detection element
510   
511   AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
512     (fDEValues->FindObject(detElemId)) : 0x0 ;
513   
514   if (!de && create && fDEValues)
515   {
516     de = CreateDetectionElementParam(detElemId);
517     fDEValues->Add(de);
518   }
519   
520   return de;
521   
522 }
523
524 //_____________________________________________________________________________
525 AliMUONVCalibParam* 
526 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
527 {
528   /// Create storage for one detection element
529   
530   AliCodeTimerAuto("");
531   
532   AliMUONVCalibParam*  de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
533   
534   AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
535   Int_t nchannels(0);
536   
537   for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
538   {
539     Int_t busPatchId = det->GetBusPatchId(i);
540     AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
541     for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
542     {
543       Int_t manuId = bp->GetManuId(j);
544       nchannels += det->NofChannelsInManu(manuId);
545     }        
546   }
547   
548   de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
549   
550   return de;
551 }
552
553 //_____________________________________________________________________________
554 TString 
555 AliMUONTrackerData::DimensionName(Int_t dim) const
556 {
557   /// Get the name of a given dimension
558   TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
559   if ( value ) 
560   {
561     return value->String();
562   }
563   else
564   {
565     return TString("Invalid");
566   }  
567 }
568
569 //_____________________________________________________________________________
570 Int_t 
571 AliMUONTrackerData::External2Internal(Int_t index) const 
572 {
573   /// From external to internal dimension
574   return IsSingleEvent() ? index : index*2;
575 }
576
577 //_____________________________________________________________________________
578 TString 
579 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
580 {
581   /// Get the name of a given external dimension
582   
583   TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
584   if ( value ) 
585   {
586     return value->String();
587   }
588   else
589   {
590     return TString("Invalid");
591   }  
592 }
593
594 //_____________________________________________________________________________
595 void
596 AliMUONTrackerData::FillChannel(Int_t detElemId, Int_t manuId, Int_t manuChannel,
597                                 Int_t dim, Double_t value)
598 {
599   /// Fill histogram of a given channel
600   
601   AliMUONSparseHisto* h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
602  
603   h->Fill(static_cast<Int_t>(TMath::Nint(value)));
604 }
605
606 //_____________________________________________________________________________
607 AliMUONSparseHisto*
608 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, 
609                                           Int_t manuChannel, Int_t dim) const
610 {
611   /// Get histogram of a given channel
612   
613   if (!fChannelHistos) return 0x0;
614   
615   AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fChannelHistos->FindObject(detElemId,manuId));
616   if (!m) return 0x0;
617   
618   UInt_t uid = ( manuChannel << 16 ) | dim;
619   
620   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
621   
622   return h;
623 }
624
625 //_____________________________________________________________________________
626 AliMUONSparseHisto*
627 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, 
628                                           Int_t manuChannel, Int_t dim)
629 {
630   /// Get histogram of a given channel. Create it if necessary
631   
632   if (!fChannelHistos) fChannelHistos = new AliMUON2DMap(kTRUE);
633   
634   AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fChannelHistos->FindObject(detElemId,manuId));
635   if (!m)
636   {
637     m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
638     m->SetUniqueID( ( manuId << 16 ) | detElemId );
639     fChannelHistos->Add(m);
640   }
641   
642   UInt_t uid = ( manuChannel << 16 ) | dim;
643   
644   AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
645   if (!h)
646   {
647     h = new AliMUONSparseHisto(fXmin,fXmax);
648     
649     h->SetUniqueID(uid);
650     
651     m->Add(h);
652   }
653
654   return h;
655 }
656
657 //_____________________________________________________________________________
658 Int_t
659 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
660                              AliMUONVCalibParam*& chamber,
661                              AliMUONVCalibParam*& de,
662                              AliMUONVCalibParam*& busPatch,
663                              AliMUONVCalibParam*& pcb,
664                              AliMUONVCalibParam*& manu,
665                              AliMUONVCalibParam*& channel,
666                              AliMpDetElement*& mpde)
667 {
668   /// Get containers at all levels
669  
670   AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
671   
672   Int_t detElemId;
673   Int_t manuId;
674   
675   if ( external->ID1() <= 0 ) 
676   {
677     // we get a manu serial number
678     Int_t serial = external->ID0();
679     AliMpIntPair pair = ddlStore->GetDetElemIdManu(serial);
680     detElemId = pair.GetFirst();
681     manuId = pair.GetSecond();
682     if ( !detElemId ) 
683     {
684       AliError(Form("DE %d manuId %d from serial %d is not correct !",
685                     detElemId,manuId,serial));
686       return -1;
687     }
688   }
689   else
690   {
691     // we get a (de,manu) pair
692     detElemId = external->ID0();
693     manuId = external->ID1();
694   }
695
696   mpde = ddlStore->GetDetElement(detElemId);
697
698   Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
699     
700   Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
701   
702   Int_t pcbIndex = -1;
703   
704   AliMp::StationType stationType = mpde->GetStationType();
705   
706   if ( stationType == AliMp::kStation345 ) 
707   {
708     AliMpHVNamer namer;
709     pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
710   }
711   
712   channel = ChannelParam(detElemId,manuId,external);
713   
714   manu = ManuParam(detElemId,manuId,kTRUE);
715   
716   busPatch = BusPatchParam(busPatchId,kTRUE);
717   
718   de = DetectionElementParam(detElemId,kTRUE);
719   
720   chamber = ChamberParam(chamberId,kTRUE);
721   
722   pcb = 0x0;
723   
724   if ( pcbIndex >= 0 ) 
725   {
726     pcb = PCBParam(detElemId,pcbIndex,kTRUE);
727   }
728   
729   return manuId;
730 }
731
732 //_____________________________________________________________________________
733 Bool_t 
734 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
735 {
736   /// Whether we have data for a given buspatch
737   return ( BusPatchParam(busPatchId) != 0 );
738 }
739
740 //_____________________________________________________________________________
741 Bool_t 
742 AliMUONTrackerData::HasChamber(Int_t chamberId) const
743 {
744   /// Whether we have data for a given chamber
745   return ( ChamberParam(chamberId) != 0 );
746 }
747
748 //_____________________________________________________________________________
749 Bool_t 
750 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
751 {
752   /// Whether we have data for a given detection element
753   return ( DetectionElementParam(detElemId) != 0 );
754 }
755
756 //_____________________________________________________________________________
757 Bool_t
758 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
759 {
760   /// Whether we have data for a given manu
761   return ( ManuParam(detElemId,manuId) != 0 ); 
762 }
763
764 //_____________________________________________________________________________
765 Bool_t
766 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
767 {
768   /// Whether we have data for a given pcb
769   return ( PCBParam(detElemId,pcbIndex) != 0 ); 
770 }
771
772 //_____________________________________________________________________________
773 Double_t 
774 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
775 {
776   /// Return the value for a given manu and a given dimension
777   
778   AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
779   return param ? Value(*param,0,dim) : 0.0;
780 }
781
782 //_____________________________________________________________________________
783 AliMUONVCalibParam* 
784 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
785 {
786   /// Get the VCalibParam for a given manu
787   
788   AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
789     (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
790   
791   if (!manu && create && fManuValues)
792   {
793     manu = CreateManuParam(detElemId,manuId);
794     fManuValues->Add(manu);
795   }
796   
797   return manu;
798 }
799
800 //_____________________________________________________________________________
801 AliMUONVCalibParam* 
802 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
803 {
804   /// Create storage for one manu
805   
806   AliCodeTimerAuto("");
807   
808   AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
809   
810   // set the number of channels in that manu
811   
812   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
813   
814   manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
815   
816   return manu;
817 }
818
819 //_____________________________________________________________________________
820 Long64_t
821 AliMUONTrackerData::Merge(TCollection*)
822 {
823   /// Merge all tracker data objects from li into a single one.
824   
825   AliError("Not implemented yet");
826   
827   return 0;
828 }
829
830 //_____________________________________________________________________________
831 Int_t 
832 AliMUONTrackerData::NumberOfDimensions() const
833 {
834   /// Number of dimensions we're dealing with
835   
836   return fDimension + fgkVirtualExtraDimension; 
837 }
838
839 //_____________________________________________________________________________
840 Double_t 
841 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
842 {
843   /// Return the value of a given pcb for a given dimension
844
845   AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
846   
847   return param ? Value(*param,0,dim) : 0.0;
848 }
849
850 //_____________________________________________________________________________
851 AliMUONVCalibParam* 
852 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
853 {
854   /// Return (if it exist) the VCalibParam for a given pcb
855
856   AliMUONVCalibParam* pcb =  fPCBValues ? static_cast<AliMUONVCalibParam*>
857     (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
858   
859   if (create && fPCBValues && !pcb)
860   {
861     pcb = CreatePCBParam(detElemId,pcbIndex);
862     fPCBValues->Add(pcb);
863   }
864   
865   return pcb;
866 }
867
868 //_____________________________________________________________________________
869 AliMUONVCalibParam* 
870 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
871 {
872   /// Create storage for one PCB (station345 only)
873   
874   AliCodeTimerAuto("");
875   
876   AliMpHVNamer namer;
877   
878   AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
879                                                     namer.NumberOfPCBs(detElemId),
880                                                     detElemId,
881                                                     pcbIndex,
882                                                     0.0);
883   return pcb;
884 }
885
886 //_____________________________________________________________________________
887 void 
888 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
889 {
890   /// Printout
891   
892   TNamed::Print(opt);
893   
894   if ( !fIsSingleEvent ) 
895   {
896     cout << " Nevents=" << fNevents << endl;
897   }
898
899   for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i ) 
900   {
901     TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
902     cout << Form("External Dimension %2d Name %s %s",i,
903                  ( name ? name->String().Data() : "null"),
904                  ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
905   }
906   
907   for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i ) 
908   {
909     TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
910     cout << Form("Internal Dimension %2d Name %s",i,
911                  ( name ? name->String().Data() : "null")) << endl;
912   }
913     
914   TString sopt(opt);
915   sopt.ToUpper();
916   
917   if ( sopt.Contains("CHANNEL") && fChannelValues ) 
918   {
919     fChannelValues->Print(wildcard,opt);
920   }
921
922   if ( sopt.Contains("MANU") && fManuValues ) 
923   {
924     fManuValues->Print(wildcard,opt);
925   }
926
927   if ( sopt.Contains("BUSPATCH") && fBusPatchValues ) 
928   {
929     fBusPatchValues->Print(wildcard,opt);
930   }
931
932   if ( sopt.Contains("DE") && fDEValues ) 
933   {
934     fDEValues->Print(wildcard,opt);
935   }
936
937   if ( sopt.Contains("CHAMBER") && fChamberValues ) 
938   {
939     fChamberValues->Print(wildcard,opt);
940   }
941   
942 }
943
944 //_____________________________________________________________________________
945 void
946 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
947 {  
948   /// Set the name of a given dimension
949
950   if ( index >= fExternalDimension ) 
951   {
952     AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
953     return;
954   }
955   
956   Int_t ix = External2Internal(index);
957   
958   if ( !IsSingleEvent() ) 
959   {
960     const char* prefix[] = { "mean", "sigma" };
961   
962     for ( Int_t i = 0; i < 2; ++i ) 
963     {
964       Int_t j = ix+i;
965     
966       SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
967     }
968   }
969   else
970   {
971     SetInternalDimensionName(index,name);
972   }
973   
974   SetExternalDimensionName(index,name);
975 }
976
977 //_____________________________________________________________________________
978 void 
979 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
980 {
981   /// decide to make histos for a given dimension
982   if ( index >= ExternalDimension() ) 
983   {
984     AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
985     return;
986   }
987   
988   fHistogramming[index] = value;
989   fXmin = xmin;
990   fXmax = xmax;
991 }
992
993 //_____________________________________________________________________________
994 void 
995 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
996 {
997   /// Set the name of a given internal dimension
998   if ( index >= fDimension ) 
999   {
1000     AliError(Form("Index out of bounds : %d / %d",index,fDimension));
1001     return;
1002   }
1003   
1004   TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
1005     
1006   if ( ovalue ) 
1007   {
1008     fDimensionNames->Remove(ovalue);
1009     delete ovalue;
1010   }
1011   fDimensionNames->AddAt(new TObjString(value),index);
1012 }
1013
1014 //_____________________________________________________________________________
1015 void 
1016 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
1017 {
1018   /// Set the name of a given external dimension
1019   if ( index >= fExternalDimension ) 
1020   {
1021     AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1022     return;
1023   }
1024   
1025   TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
1026   
1027   if ( ovalue ) 
1028   {
1029     fExternalDimensionNames->Remove(ovalue);
1030     delete ovalue;
1031   }
1032   fExternalDimensionNames->AddAt(new TObjString(value),index);
1033 }
1034
1035 //_____________________________________________________________________________
1036 Double_t 
1037 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, Int_t dim) const
1038 {
1039   /// Compute the value for a given dim, using the internal information we have
1040   /// Basically we're converting sum of weights and sum of squares of weights
1041   /// into means and sigmas, and number of events into occupancy number.
1042
1043   Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
1044   
1045   if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
1046   
1047   Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
1048
1049   if ( dim >= fDimension ) 
1050   {
1051     return occ;
1052   }
1053   
1054   if ( dim == IndexOfOccupancyDimension() ) return occ/n/NumberOfEvents();
1055   
1056   Double_t value = param.ValueAsDouble(i,dim);
1057   
1058   if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
1059   
1060   if ( TMath::Even(dim) || IsSingleEvent() ) 
1061   {
1062     return value/occ;
1063   }
1064   else
1065   {
1066     Double_t nn = occ;
1067     
1068     if ( nn > 1.0 ) 
1069     {
1070       Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
1071     
1072       return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
1073     }
1074     else
1075     {
1076       return 0.0;
1077     }
1078   }
1079   
1080   AliError("Why am I here ?");
1081   return 0.0;
1082 }
1083