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