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