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