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