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