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