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