1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 #include "AliMUONTrackerData.h"
20 #include "AliCodeTimer.h"
23 #include "AliMUON1DArray.h"
24 #include "AliMUON1DMap.h"
25 #include "AliMUON2DMap.h"
26 #include "AliMUONCalibParamND.h"
27 #include "AliMUONRejectList.h"
28 #include "AliMUONSparseHisto.h"
29 #include "AliMUONVStore.h"
30 #include "AliMpBusPatch.h"
31 #include "AliMpConstants.h"
33 #include "AliMpDDLStore.h"
34 #include "AliMpManuStore.h"
35 #include "AliMpDEIterator.h"
36 #include "AliMpDEManager.h"
37 #include "AliMpDetElement.h"
38 #include "AliMpDCSNamer.h"
39 #include "AliMpManuIterator.h"
40 #include "AliMpEncodePair.h"
41 #include "AliMpSegmentation.h"
42 #include <Riostream.h>
45 #include <TObjArray.h>
46 #include <TObjString.h>
48 #include <TTimeStamp.h>
53 /// \class AliMUONTrackerData
55 /// Implementation of AliMUONVTrackerData class
57 /// \author Laurent Aphecetche, Subatech
60 ClassImp(AliMUONTrackerData)
63 const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
64 const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
66 //_____________________________________________________________________________
67 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
70 : AliMUONVTrackerData(name,title),
71 fIsSingleEvent(issingleevent),
78 fDimension(External2Internal(dimension)+fgkExtraDimension),
80 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
81 fExternalDimensionNames(new TObjArray(dimension)),
82 fExternalDimension(dimension),
83 fHistogramming(new Int_t[fExternalDimension]),
87 fIsChannelLevelEnabled(kTRUE),
88 fIsManuLevelEnabled(kTRUE),
89 fIsBustPatchLevelEnabled(kTRUE),
90 fIsPCBLevelEnabled(kTRUE),
95 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
96 fExternalDimensionNames->SetOwner(kTRUE);
97 fDimensionNames->SetOwner(kTRUE);
98 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
99 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
100 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
104 //_____________________________________________________________________________
105 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
106 const AliMUONVStore& manuValues)
107 : AliMUONVTrackerData(name,title),
108 fIsSingleEvent(kFALSE),
111 fBusPatchValues(0x0),
117 fDimensionNames(0x0),
118 fExternalDimensionNames(0x0),
119 fExternalDimension(0),
124 fIsChannelLevelEnabled(kFALSE),
125 fIsManuLevelEnabled(kTRUE),
126 fIsBustPatchLevelEnabled(kTRUE),
127 fIsPCBLevelEnabled(kTRUE),
129 fNofEventsPerDDL(0x0)
131 /// ctor with pre-computed values at the manu level
132 /// In this case, we force fIsChannelLevelEnabled = kFALSE
135 if (manuValues.GetSize()==0)
137 AliFatal("Cannot create a tracker data from nothing in that case !");
140 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
142 AliError("Cannot work without (full) mapping");
146 TIter next(manuValues.CreateIterator());
147 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
149 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
151 fDimension = External2Internal(dimension)+fgkExtraDimension;
153 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
154 fExternalDimensionNames = new TObjArray(dimension);
155 fExternalDimension = dimension;
156 fHistogramming = new Int_t[fExternalDimension];
157 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
159 fExternalDimensionNames->SetOwner(kTRUE);
160 fDimensionNames->SetOwner(kTRUE);
161 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
162 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
163 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
165 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
169 AliMUONVCalibParam* external;
171 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
173 Int_t detElemId, manuId;
175 GetDEManu(*external,detElemId,manuId);
177 AliMUONVCalibParam* chamber(0x0);
178 AliMUONVCalibParam* de(0x0);
179 AliMUONVCalibParam* busPatch(0x0);
180 AliMUONVCalibParam* pcb(0x0);
181 AliMUONVCalibParam* manu(0x0);
182 AliMUONVCalibParam* channel(0x0);
183 AliMpDetElement* mpde(0x0);
185 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,manuId,0);
186 // as external, but without event count
187 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
188 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
189 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
190 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
192 Int_t mid = GetParts(wec,chamber,de,busPatch,pcb,manu,channel,mpde);
196 AliError(Form("Something is wrong for DE %5d : manuId = %d vs mid = %d",detElemId,manuId,mid));
202 AliError("Got a < 0 manuId. Should not happen here !");
206 assert(channel==0x0);
208 Int_t n1 = manu->ValueAsInt(0,IndexOfNumberDimension());
209 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
212 AliError(Form("Incoherent number of manu channels for DE %5d MANU %5d : %d vs %d",
213 detElemId,manuId,n1,n2));
216 Int_t nevt = external->ValueAsInt(0,4);
218 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
220 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus(busPatchId);
222 if ( nevents[ddl] == 0 )
228 if ( nevents.At(ddl) != nevt )
230 AliError(Form("Nevt mismatch for DE %5d MANU %5d DDL %d : %d vs %d",
231 detElemId,manuId,ddl,nevents.At(ddl),nevt));
236 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
238 manu->SetValueAsDouble(0,i,manu->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
240 busPatch->SetValueAsDouble(0,i,busPatch->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
242 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
244 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
249 UpdateNumberOfEvents(&nevents);
253 //_____________________________________________________________________________
254 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
255 const AliMUONVStore& deOrBpValues, Int_t val)
256 : AliMUONVTrackerData(name,title),
257 fIsSingleEvent(kFALSE),
260 fBusPatchValues(0x0),
266 fDimensionNames(0x0),
267 fExternalDimensionNames(0x0),
268 fExternalDimension(0),
273 fIsChannelLevelEnabled(kFALSE),
274 fIsManuLevelEnabled(kFALSE),
275 fIsBustPatchLevelEnabled(kFALSE),
276 fIsPCBLevelEnabled(kFALSE),
278 fNofEventsPerDDL(0x0)
280 /// ctor with values at the detection element OR bus patch level
281 /// In this case, we force fIsChannelLevelEnabled = fIsManuLevelEnabled = kFALSE
284 if (deOrBpValues.GetSize()==0)
286 AliFatal("Cannot create a tracker data from nothing in that case !");
289 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
291 AliError("Cannot work without (full) mapping");
297 BuildFromDEStore(deOrBpValues);
301 BuildFromBPStore(deOrBpValues);
305 AliFatal("Wrong parameter. Must be 1 or 2");
311 //_____________________________________________________________________________
312 void AliMUONTrackerData::BuildFromDEStore(const AliMUONVStore& deValues)
314 /// Fill internals from a store of values at the detection element level
316 TIter next(deValues.CreateIterator());
317 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
319 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
321 fDimension = External2Internal(dimension)+fgkExtraDimension;
323 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
324 fExternalDimensionNames = new TObjArray(dimension);
325 fExternalDimension = dimension;
326 fHistogramming = new Int_t[fExternalDimension];
327 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
329 fExternalDimensionNames->SetOwner(kTRUE);
330 fDimensionNames->SetOwner(kTRUE);
331 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
332 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
333 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
335 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
339 AliMUONVCalibParam* external;
341 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
343 Int_t detElemId = external->ID0();
345 AliMpDetElement* mpde = AliMpDDLStore::Instance()->GetDetElement(detElemId,kFALSE);
349 AliError(Form("Got an invalid DE (%d) from external store",detElemId));
353 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
354 AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
355 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
357 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,0,0);
358 // as external, but without event count
359 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
360 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
361 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
362 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
364 Int_t n1 = de->ValueAsInt(0,IndexOfNumberDimension());
365 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
368 AliError(Form("Incoherent number of dimensions for DE%d : %d vs %d",
373 Int_t nevt = external->ValueAsInt(0,4);
375 Int_t ddl = mpde->GetDdlId();
377 if ( nevents[ddl] == 0 )
383 if ( nevents.At(ddl) != nevt )
385 AliError(Form("Nevt mismatch for DE %5d DDL %d : %d vs %d",
386 detElemId,ddl,nevents.At(ddl),nevt));
391 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
393 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
395 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
400 UpdateNumberOfEvents(&nevents);
403 //_____________________________________________________________________________
404 void AliMUONTrackerData::BuildFromBPStore(const AliMUONVStore& bpValues)
406 /// Fill internals from a store of values at the bus patch level
408 fIsBustPatchLevelEnabled = kTRUE;
410 TIter next(bpValues.CreateIterator());
411 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
413 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
415 fDimension = External2Internal(dimension)+fgkExtraDimension;
417 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
418 fExternalDimensionNames = new TObjArray(dimension);
419 fExternalDimension = dimension;
420 fHistogramming = new Int_t[fExternalDimension];
421 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
423 fExternalDimensionNames->SetOwner(kTRUE);
424 fDimensionNames->SetOwner(kTRUE);
425 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
426 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
427 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
429 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
433 AliMUONVCalibParam* external;
435 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
437 Int_t busPatchId = external->ID0();
439 AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId,kFALSE);
443 AliError(Form("Got an invalid buspatchId (%d) from external store",busPatchId));
447 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
448 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
449 AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
450 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
451 AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE);
453 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,busPatchId,0,0);
454 // as external, but without event count
455 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
456 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
457 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
458 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
460 Int_t n1 = bp->ValueAsInt(0,IndexOfNumberDimension());
461 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
464 AliError(Form("Incoherent number of dimensions for BP%d : %d vs %d",
469 Int_t nevt = external->ValueAsInt(0,4);
471 Int_t ddl = mpbp->GetDdlId();
473 if ( nevents[ddl] == 0 )
479 if ( nevents.At(ddl) != nevt )
481 AliError(Form("Nevt mismatch for BP %5d DDL %d : %d vs %d",
482 busPatchId,ddl,nevents.At(ddl),nevt));
487 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
489 bp->SetValueAsDouble(0,i,bp->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
491 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
493 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
498 UpdateNumberOfEvents(&nevents);
501 //_____________________________________________________________________________
502 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
503 const AliMUONRejectList& rejectList)
504 : AliMUONVTrackerData(name,title),
505 fIsSingleEvent(kFALSE),
508 fBusPatchValues(0x0),
512 fDimension(External2Internal(1)+fgkExtraDimension),
514 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
515 fExternalDimensionNames(new TObjArray(1)),
516 fExternalDimension(1),
517 fHistogramming(new Int_t[fExternalDimension]),
521 fIsChannelLevelEnabled(kTRUE),
522 fIsManuLevelEnabled(kTRUE),
523 fIsBustPatchLevelEnabled(kTRUE),
524 fIsPCBLevelEnabled(kFALSE),
526 fNofEventsPerDDL(0x0)
529 /// ctor with values from the given rejectlist
531 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
533 AliError("Cannot work without (full) mapping");
537 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
539 fExternalDimensionNames->SetOwner(kTRUE);
540 fDimensionNames->SetOwner(kTRUE);
541 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
542 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
543 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
545 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
549 for ( Int_t chamberId = 0; chamberId < AliMpConstants::NofChambers(); ++chamberId )
551 // AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
553 // FIXME : update the chamber value ?
555 AliMpDEIterator deit;
557 deit.First(chamberId);
559 while ( !deit.IsDone() )
561 AliMpDetElement* mpde = deit.CurrentDE();
563 Int_t detElemId = mpde->GetId();
565 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
567 DispatchValue(*de,0,rejectList.DetectionElementProbability(detElemId),0.0,mpde->NofChannels());
569 for ( Int_t iBusPatch = 0; iBusPatch < mpde->GetNofBusPatches(); ++iBusPatch )
571 Int_t busPatchId = mpde->GetBusPatchId(iBusPatch);
573 AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE);
575 AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
579 for ( Int_t iManu = 0 ;iManu < mpbp->GetNofManus(); ++iManu )
581 Int_t manuId = mpbp->GetManuId(iManu);
583 nch += mpde->NofChannelsInManu(manuId);
585 AliMUONVCalibParam* manu = ManuParam(detElemId,manuId,kTRUE);
587 DispatchValue(*manu,0,rejectList.ManuProbability(detElemId,manuId),0.0,mpde->NofChannelsInManu(manuId));
589 AliMUONVCalibParam* c = ChannelParam(detElemId,manuId);
593 c = new AliMUONCalibParamND(Dimension(),
594 AliMpConstants::ManuNofChannels(),
598 fChannelValues->Add(c);
601 for ( Int_t manuChannel = 0; manuChannel < AliMpConstants::ManuNofChannels(); ++manuChannel )
603 DispatchValue(*c,manuChannel,rejectList.ChannelProbability(detElemId,manuId,manuChannel),0.0,1);
607 DispatchValue(*bp,0,rejectList.BusPatchProbability(busPatchId),0.0,nch);
617 SetDimensionName(0,"RejectProba");
619 UpdateNumberOfEvents(0x0);
622 //_____________________________________________________________________________
623 AliMUONTrackerData::~AliMUONTrackerData()
626 delete fChannelValues;
628 delete fBusPatchValues;
630 delete fChamberValues;
632 delete fDimensionNames;
633 delete fExternalDimensionNames;
634 delete[] fHistogramming;
636 delete[] fNofEventsPerDDL;
639 //_____________________________________________________________________________
641 AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents)
643 /// Add the given external store to our internal store
644 return InternalAdd(store,nevents,kFALSE);
647 //_____________________________________________________________________________
649 AliMUONTrackerData::Add(const AliMUONTrackerData& data)
651 /// Add data to *this
652 // We do this by looping on all VCalibParam stored in the various containers,
653 // and simply adding the values there.
654 // Same thing for the number of events per DDL.
655 // Same thing for sparsehistograms, if we have some.
657 // First cross check we have compatible objects.
659 AliCodeTimerAuto("",0);
661 if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled )
663 AliError("Incompatible IsChannelLevelEnabled status");
667 if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled )
669 AliError("Incompatible IsManuLevelEnabled status");
673 if ( fIsSingleEvent != data.fIsSingleEvent )
675 AliError("Incompatible IsSingleEvent status");
679 if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension )
681 AliError("Incompatible dimensions");
685 if ( fNofDDLs != data.fNofDDLs )
687 AliError("Incompatible number of Ddls");
691 if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming )
692 || fXmin != data.fXmin || fXmax != data.fXmax )
694 AliError(Form("Incompatible histogramming (%p vs %p) (xmax = %e vs %e ; xmin = %e vs %e)",
695 fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
699 if ( fHistogramming )
701 for ( Int_t i = 0; i < fExternalDimension; ++i )
703 if ( fHistogramming[i] != data.fHistogramming[i] )
705 AliError(Form("Incompatible histogramming for external dimension %d",i));
711 // OK. Seems we have compatible objects, so we can proceed with the actual
714 if ( data.fChannelValues )
716 Add2D(*(data.fChannelValues),*fChannelValues);
719 if ( data.fManuValues )
721 Add2D(*(data.fManuValues),*fManuValues);
724 if ( data.fPCBValues )
726 Add2D(*(data.fPCBValues),*fPCBValues);
729 if ( data.fBusPatchValues )
731 Add1D(*(data.fBusPatchValues),*fBusPatchValues);
734 if ( data.fDEValues )
736 Add1D(*(data.fDEValues),*fDEValues);
739 if ( data.fChamberValues )
741 Add1D(*(data.fChamberValues),*fChamberValues);
744 for ( Int_t i = 0; i < fNofDDLs; ++i )
746 fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
751 TIter nexthisto(data.fHistos->CreateIterator());
752 AliMUONVStore* store;
753 while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
755 TIter ns(store->CreateIterator());
756 AliMUONSparseHisto* h;
757 while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
759 AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
763 thisStore = store->Create();
764 thisStore->SetUniqueID(store->GetUniqueID());
765 fHistos->Add(thisStore);
768 AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
782 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
784 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
790 //_____________________________________________________________________________
792 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
794 /// Add one 2d store to another
796 TIter next(src.CreateIterator());
797 AliMUONVCalibParam* p;
799 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
801 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
805 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
809 AddCalibParams(*p,*a);
814 //_____________________________________________________________________________
816 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
818 /// Add one 1d store to another
820 TIter next(src.CreateIterator());
821 AliMUONVCalibParam* p;
823 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
825 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
829 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
833 AddCalibParams(*p,*a);
838 //_____________________________________________________________________________
840 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
843 for ( Int_t i = 0; i < src.Size(); ++i )
845 for ( Int_t j = 0; j < src.Dimension(); ++j )
847 dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
852 //_____________________________________________________________________________
854 AliMUONTrackerData::Replace(const AliMUONVStore& store)
856 /// Replace our values by values from the given external store
857 Bool_t rv = InternalAdd(store,0x0,kTRUE);
858 AliMUONVTrackerData::Replace(store);
862 //_____________________________________________________________________________
864 AliMUONTrackerData::UpdateNumberOfEvents(TArrayI* nevents)
866 /// Update the number of events
870 fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
871 fNofEventsPerDDL = new Int_t[fNofDDLs];
872 for ( Int_t i = 0; i < fNofDDLs; ++i )
874 fNofEventsPerDDL[i] = 0;
880 if (nevents->GetSize() != fNofDDLs )
882 AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
883 nevents->GetSize(),fNofDDLs));
887 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
889 fNofEventsPerDDL[i] += nevents->At(i);
890 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
895 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
897 ++fNofEventsPerDDL[i];
898 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
904 //_____________________________________________________________________________
906 AliMUONTrackerData::AssertStores()
908 /// Insure our stores are allocated
912 Int_t numberOfBusPatches(0);
913 Int_t numberOfDEs(0);
915 // get number of bus patches and number of detection element
916 // to initialize fBusPatchValues and fDEValues below
918 if (!AliMpDDLStore::Instance(false))
923 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
924 while ( next() ) ++numberOfBusPatches;
925 AliMpDEIterator deIt;
927 while (!deIt.IsDone())
933 if ( fIsChannelLevelEnabled )
935 fChannelValues = new AliMUON2DMap(kTRUE);
937 if ( fIsManuLevelEnabled )
939 fManuValues = new AliMUON2DMap(kTRUE);
941 if ( fIsPCBLevelEnabled )
943 fPCBValues = new AliMUON2DMap(kFALSE);
945 if ( fIsBustPatchLevelEnabled )
947 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
949 fDEValues = new AliMUON1DMap(numberOfDEs);
950 fChamberValues = new AliMUON1DArray;
954 //_____________________________________________________________________________
956 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
958 /// Add the given external store to our internal store
960 AliCodeTimerAuto(GetName(),0);
964 if ( IsSingleEvent() && NumberOfEvents(-1) == 1 )
966 AliError(Form("%s is supposed to be single event only",GetName()));
971 UpdateNumberOfEvents(nevents);
975 TIter next(store.CreateIterator());
976 AliMUONVCalibParam* external;
980 if ( IsSingleEvent() ) nk = 1;
982 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
984 if ( external->Dimension() != ExternalDimension() )
986 AliError(Form("Incompatible dimensions %d vs %d",
987 external->Dimension(),ExternalDimension()));
991 AliMUONVCalibParam* chamber(0x0);
992 AliMUONVCalibParam* de(0x0);
993 AliMUONVCalibParam* busPatch(0x0);
994 AliMUONVCalibParam* pcb(0x0);
995 AliMUONVCalibParam* manu(0x0);
996 AliMUONVCalibParam* channel(0x0);
997 AliMpDetElement* mpde(0x0);
999 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
1001 if ( manuId < 0 ) continue;
1003 Int_t detElemId = mpde->GetId();
1005 Double_t value[] = { 0.0, 0.0 };
1007 Int_t nch = mpde->NofChannelsInManu(manuId);
1009 for ( Int_t i = 0; i < external->Size(); ++i )
1011 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
1012 : mpde->IsConnectedChannel(manuId,i));
1013 // note we only use IsConnectedChannel method when really needed, as
1014 // it costs (some) CPU time...
1016 if ( existingChannel )
1018 Bool_t validChannel(kFALSE);
1020 for ( Int_t j = 0; j < external->Dimension(); ++j )
1022 Double_t vext = external->IsDoublePrecision() ?
1023 external->ValueAsDoubleFast(i,j) :
1024 external->ValueAsFloatFast(i,j);
1026 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
1028 validChannel = kTRUE;
1030 Int_t ix = External2Internal(j);
1033 value[1] = vext*vext;
1035 if ( IsHistogrammed(j) )
1037 FillHisto(detElemId,manuId,i,j,vext);
1040 for ( Int_t k = 0; k < nk; ++k )
1042 Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
1046 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
1051 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1054 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1056 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1058 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1062 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1067 if ( validChannel && !replace )
1071 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
1072 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
1077 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1078 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1081 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1082 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1083 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1084 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1085 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1086 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1089 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1090 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1097 NumberOfEventsChanged();
1102 //_____________________________________________________________________________
1104 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
1106 /// Return the value of a given buspatch for a given dimension
1107 /// or 0 if not existing
1108 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
1109 return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
1112 //_____________________________________________________________________________
1114 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
1116 /// Return (if it exist), the VCalibParam for a given busPatch
1118 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
1119 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
1121 if (!busPatch && create && fBusPatchValues)
1123 busPatch = CreateBusPatchParam(busPatchId);
1124 fBusPatchValues->Add(busPatch);
1130 //_____________________________________________________________________________
1132 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
1134 /// Create storage for one bus patch
1136 AliCodeTimerAuto("",0);
1138 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1142 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
1146 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
1148 // set the number of channels in that buspatch
1152 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
1154 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1156 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
1158 Int_t manuId = bp->GetManuId(i);
1159 nchannels += de->NofChannelsInManu(manuId);
1162 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1167 //_____________________________________________________________________________
1169 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
1171 /// Return the value fo a given chamber for a given dimension,
1172 /// or zero if not existing
1174 // FIXME: is the Value() correct wrt to number of events in the case of
1175 // chamber ? Or should we do something custom at the chamber level
1176 // (as it spans several ddls) ?
1178 AliMUONVCalibParam* param = ChamberParam(chamberId);
1179 return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
1182 //_____________________________________________________________________________
1184 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
1186 /// Return (if it exist) the VCalibParam for a given chamber
1188 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
1189 (fChamberValues->FindObject(chamberId)) : 0x0;
1191 if (!chamber && create && fChamberValues)
1193 chamber = CreateChamberParam(chamberId);
1194 fChamberValues->Add(chamber);
1200 //_____________________________________________________________________________
1202 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
1204 /// Create storage for one chamber
1206 AliCodeTimerAuto("",0);
1208 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
1210 // set the number of channels in that chamber
1216 it.First(chamberId);
1218 while ( !it.IsDone() )
1220 AliMpDetElement* det = it.CurrentDE();
1222 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1224 Int_t busPatchId = det->GetBusPatchId(i);
1225 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1226 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1228 Int_t manuId = bp->GetManuId(j);
1229 nchannels += det->NofChannelsInManu(manuId);
1236 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1241 //_____________________________________________________________________________
1243 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
1244 Int_t manuChannel, Int_t dim) const
1246 /// Return the value for a given channel for a given dimension
1248 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
1250 return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1253 //_____________________________________________________________________________
1255 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
1256 const AliMUONVCalibParam* external) const
1258 /// Return (if it exist) the VCalibParam for a given manu
1260 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
1261 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
1263 if (!param && external && fChannelValues)
1265 param = CreateDouble(*external,detElemId,manuId);
1266 fChannelValues->Add(param);
1272 //_____________________________________________________________________________
1274 AliMUONTrackerData::Clear(Option_t*)
1276 /// Clear all the values
1277 if ( fChannelValues ) fChannelValues->Clear();
1278 if ( fManuValues ) fManuValues->Clear();
1279 if ( fBusPatchValues) fBusPatchValues->Clear();
1280 if ( fPCBValues ) fPCBValues->Clear();
1281 if ( fDEValues) fDEValues->Clear();
1282 if ( fChamberValues ) fChamberValues->Clear();
1283 if ( fHistos ) fHistos->Clear();
1284 for ( Int_t i = 0; i < fNofDDLs; ++i )
1286 fNofEventsPerDDL[i] = 0;
1289 NumberOfEventsChanged();
1292 //_____________________________________________________________________________
1294 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
1295 Int_t manuChannel) const
1297 /// Return the number of times a given channel had data
1299 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
1302 //_____________________________________________________________________________
1304 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
1305 Int_t detElemId, Int_t manuId) const
1307 /// Create a double version of VCalibParam, for internal use
1309 AliCodeTimerAuto("",0);
1311 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
1317 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
1319 for ( Int_t i = 0; i < c->Size(); ++i )
1321 Double_t value(0.0);
1323 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
1325 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
1331 //_____________________________________________________________________________
1333 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
1335 /// Return the value for a given detection element for a given dimension
1336 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
1337 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1341 //_____________________________________________________________________________
1343 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
1345 /// Return (if it exist) the VCalibParam for a given detection element
1347 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
1348 (fDEValues->FindObject(detElemId)) : 0x0 ;
1350 if (!de && create && fDEValues)
1352 de = CreateDetectionElementParam(detElemId);
1360 //_____________________________________________________________________________
1362 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
1364 /// Create storage for one detection element
1366 AliCodeTimerAuto("",0);
1368 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
1370 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1373 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1375 Int_t busPatchId = det->GetBusPatchId(i);
1376 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1377 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1379 Int_t manuId = bp->GetManuId(j);
1380 nchannels += det->NofChannelsInManu(manuId);
1384 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1389 //_____________________________________________________________________________
1391 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
1393 /// Get the "local" ddlid (0..19) of a given buspatch
1394 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
1397 return bp->GetDdlId();
1402 //_____________________________________________________________________________
1404 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
1406 /// Get the "local" ddlid (0..19) of a given detection element
1407 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
1410 return de->GetDdlId();
1415 //_____________________________________________________________________________
1417 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
1419 /// Get the "local" ddlid (0..19) of a given chamber
1420 /// This has no real meaning (as there are several ddls per chamber),
1421 /// so we take the ddlid where we got the max number of events
1425 it.First(chamberid);
1429 while (!it.IsDone())
1431 Int_t detElemId = it.CurrentDEId();
1432 Int_t ddlId = DdlIdFromDetElemId(detElemId);
1433 if ( NumberOfEvents(ddlId) > n )
1435 n = NumberOfEvents(ddlId);
1444 //_____________________________________________________________________________
1446 AliMUONTrackerData::DimensionName(Int_t dim) const
1448 /// Get the name of a given dimension
1449 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
1452 return value->String();
1456 return TString("Invalid");
1460 //_____________________________________________________________________________
1462 AliMUONTrackerData::DisableChannelLevel()
1464 /// Disable the storing of data at channel level
1466 delete fChannelValues;
1467 fChannelValues = 0x0;
1468 fIsChannelLevelEnabled = kFALSE;
1471 //_____________________________________________________________________________
1473 AliMUONTrackerData::DisableManuLevel()
1475 /// Disable the storing of data at manu level (and below)
1477 DisableChannelLevel();
1480 fIsManuLevelEnabled = kFALSE;
1483 //_____________________________________________________________________________
1485 AliMUONTrackerData::External2Internal(Int_t index) const
1487 /// From external to internal dimension
1488 return IsSingleEvent() ? index : index*2;
1491 //_____________________________________________________________________________
1493 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
1495 /// Get the name of a given external dimension
1497 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
1500 return value->String();
1504 return TString("Invalid");
1508 //_____________________________________________________________________________
1510 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
1511 Int_t dim, Double_t value)
1513 /// Fill histogram of a given channel
1515 AliMUONSparseHisto* h(0x0);
1517 if ( fIsChannelLevelEnabled )
1519 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
1521 else if ( fIsManuLevelEnabled )
1523 h = GetManuSparseHisto(detElemId,manuId,dim);
1526 AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
1530 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
1534 //_____________________________________________________________________________
1536 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId,
1539 /// Get histogram of a given manu
1541 if (!fHistos) return 0x0;
1543 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1546 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1551 //_____________________________________________________________________________
1553 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
1555 /// Get histogram of a given manu. Create it if necessary
1557 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1559 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1562 m = new AliMUON1DArray(NumberOfDimensions());
1563 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1567 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1570 h = new AliMUONSparseHisto(fXmin,fXmax);
1572 h->SetUniqueID(dim);
1580 //_____________________________________________________________________________
1582 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1583 Int_t manuChannel, Int_t dim) const
1585 /// Get histogram of a given channel
1587 if (!fHistos) return 0x0;
1589 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1592 UInt_t uid = ( manuChannel << 16 ) | dim;
1594 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1599 //_____________________________________________________________________________
1601 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1602 Int_t manuChannel, Int_t dim)
1604 /// Get histogram of a given channel. Create it if necessary
1606 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1608 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1611 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1612 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1616 UInt_t uid = ( manuChannel << 16 ) | dim;
1618 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1621 h = new AliMUONSparseHisto(fXmin,fXmax);
1623 h->SetUniqueID(uid);
1631 //_____________________________________________________________________________
1633 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1634 Int_t& detElemId, Int_t& manuId) const
1636 /// Tries to get (detElemId,manuId) of param
1638 // Load mapping manu store
1639 if ( ! AliMpCDB::LoadManuStore() ) {
1640 AliError("Could not access manu store from OCDB !");
1644 if ( param.ID1() <= 0 )
1646 // we (probably) get a manu serial number
1647 Int_t serial = param.ID0();
1648 MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1649 detElemId = AliMp::PairFirst(pair);
1650 manuId = AliMp::PairSecond(pair);
1653 AliDebug(1,Form("DE %d manuId %d from serial %d is not correct !",
1654 detElemId,manuId,serial));
1659 // we get a (de,manu) pair
1660 detElemId = param.ID0();
1661 manuId = param.ID1();
1666 //_____________________________________________________________________________
1668 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1669 AliMUONVCalibParam*& chamber,
1670 AliMUONVCalibParam*& de,
1671 AliMUONVCalibParam*& busPatch,
1672 AliMUONVCalibParam*& pcb,
1673 AliMUONVCalibParam*& manu,
1674 AliMUONVCalibParam*& channel,
1675 AliMpDetElement*& mpde)
1677 /// Get containers at all levels
1679 chamber = de = busPatch = pcb = manu = channel = 0x0;
1682 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1687 GetDEManu(*external,detElemId,manuId);
1689 mpde = ddlStore->GetDetElement(detElemId,kFALSE);
1691 if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1696 // explicitely check that de,manu is correct
1697 const AliMpVSegmentation* mpseg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId,kFALSE);
1704 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1706 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1708 if ( busPatchId <= 0 )
1713 Int_t pcbIndex = -1;
1715 AliMp::StationType stationType = mpde->GetStationType();
1717 if ( stationType == AliMp::kStation345 )
1719 AliMpDCSNamer namer("TRACKER");
1720 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1723 if ( fIsChannelLevelEnabled )
1725 channel = ChannelParam(detElemId,manuId,external);
1728 manu = ManuParam(detElemId,manuId,kTRUE);
1730 busPatch = BusPatchParam(busPatchId,kTRUE);
1732 de = DetectionElementParam(detElemId,kTRUE);
1734 chamber = ChamberParam(chamberId,kTRUE);
1738 if ( pcbIndex >= 0 )
1740 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1746 //_____________________________________________________________________________
1748 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1750 /// Whether we have data for a given buspatch
1751 return ( BusPatchParam(busPatchId) != 0 );
1754 //_____________________________________________________________________________
1756 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1758 /// Whether we have data for a given chamber
1759 return ( ChamberParam(chamberId) != 0 );
1762 //_____________________________________________________________________________
1764 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1766 /// Whether we have data for a given detection element
1767 return ( DetectionElementParam(detElemId) != 0 );
1770 //_____________________________________________________________________________
1772 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1774 /// Whether we have data for a given manu
1775 return ( ManuParam(detElemId,manuId) != 0 );
1778 //_____________________________________________________________________________
1780 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1782 /// Whether we have data for a given pcb
1783 return ( PCBParam(detElemId,pcbIndex) != 0 );
1786 //_____________________________________________________________________________
1788 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1790 /// Return the value for a given manu and a given dimension
1792 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1793 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1796 //_____________________________________________________________________________
1798 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1800 /// Get the VCalibParam for a given manu
1802 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1803 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1805 if (!manu && create && fManuValues)
1807 manu = CreateManuParam(detElemId,manuId);
1808 fManuValues->Add(manu);
1814 //_____________________________________________________________________________
1816 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1818 /// Create storage for one manu
1820 AliCodeTimerAuto("",0);
1822 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1824 // set the number of channels in that manu
1826 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1828 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1833 //_____________________________________________________________________________
1835 AliMUONTrackerData::Merge(TCollection* list)
1837 /// Merge this with a list of AliMUONVTrackerData
1839 if (!list) return 0;
1841 if ( list->IsEmpty() ) return NumberOfEvents(-1);
1844 const TObject* o(0x0);
1846 while ( ( o = next() ) )
1848 const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1851 AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1856 Bool_t ok = Add(*data);
1859 AliError("Got incompatible objects");
1864 return NumberOfEvents(-1);
1867 //_____________________________________________________________________________
1869 AliMUONTrackerData::NumberOfDimensions() const
1871 /// Number of dimensions we're dealing with
1873 return fDimension + fgkVirtualExtraDimension;
1876 //_____________________________________________________________________________
1878 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1880 /// Get the number of events we've seen for a given DDL, or the max
1881 /// in case ddlNumber<0
1885 if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1887 n = fNofEventsPerDDL[ddlNumber];
1891 // get the max number of events
1898 //_____________________________________________________________________________
1900 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1902 /// Return the value of a given pcb for a given dimension
1904 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1906 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1909 //_____________________________________________________________________________
1911 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1913 /// Return (if it exist) the VCalibParam for a given pcb
1915 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
1916 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1918 if (create && fPCBValues && !pcb)
1920 pcb = CreatePCBParam(detElemId,pcbIndex);
1921 fPCBValues->Add(pcb);
1927 //_____________________________________________________________________________
1929 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1931 /// Create storage for one PCB (station345 only)
1933 AliCodeTimerAuto("",0);
1935 AliMpDCSNamer namer("TRACKER");
1937 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1938 namer.NumberOfPCBs(detElemId),
1945 //_____________________________________________________________________________
1947 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1953 if ( !fIsSingleEvent )
1955 for ( Int_t i = 0; i < fNofDDLs; ++i )
1957 cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1961 if ( !fIsChannelLevelEnabled )
1963 cout << "Is not storing data at the channel level" << endl;
1966 if ( !fIsManuLevelEnabled )
1968 cout << "Is not storing data at the manu level" << endl;
1971 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
1973 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1974 cout << Form("External Dimension %2d Name %s %s",i,
1975 ( name ? name->String().Data() : "null"),
1976 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1979 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
1981 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1982 cout << Form("Internal Dimension %2d Name %s",i,
1983 ( name ? name->String().Data() : "null")) << endl;
1989 if ( sopt.Contains("CHANNEL") )
1991 if ( fIsChannelLevelEnabled )
1993 if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1997 AliWarning("You requested channel values, but they were not stored !");
2001 if ( sopt.Contains("MANU") )
2003 if ( fIsManuLevelEnabled )
2005 if ( fManuValues ) fManuValues->Print(wildcard,opt);
2009 AliWarning("You requested manu values, but they were not stored !");
2013 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
2015 fBusPatchValues->Print(wildcard,opt);
2018 if ( sopt.Contains("DE") && fDEValues )
2020 fDEValues->Print(wildcard,opt);
2023 if ( sopt.Contains("CHAMBER") && fChamberValues )
2025 fChamberValues->Print(wildcard,opt);
2030 //_____________________________________________________________________________
2032 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
2034 /// Set the name of a given dimension
2036 if ( index >= fExternalDimension )
2038 AliError(Form("%s : dimension %s : Index out of bounds : %d / %d",
2040 name,index,fExternalDimension));
2044 Int_t ix = External2Internal(index);
2046 if ( !IsSingleEvent() )
2048 const char* prefix[] = { "mean", "sigma" };
2050 for ( Int_t i = 0; i < 2; ++i )
2054 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
2059 SetInternalDimensionName(index,name);
2062 SetExternalDimensionName(index,name);
2065 //_____________________________________________________________________________
2067 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
2069 /// decide to make histos for a given dimension
2070 if ( index >= ExternalDimension() )
2072 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
2076 AliWarning(Form("Will %s make histogram for data %s index %d : that might ressemble a memory leak depending on the input data",
2077 value ? "":"not", GetName(),index));
2078 fHistogramming[index] = value;
2083 //_____________________________________________________________________________
2085 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
2087 /// Set the name of a given internal dimension
2088 if ( index >= fDimension )
2090 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
2094 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
2098 fDimensionNames->Remove(ovalue);
2101 fDimensionNames->AddAt(new TObjString(value),index);
2104 //_____________________________________________________________________________
2106 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
2108 /// Set the name of a given external dimension
2109 if ( index >= fExternalDimension )
2111 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
2115 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
2119 fExternalDimensionNames->Remove(ovalue);
2122 fExternalDimensionNames->AddAt(new TObjString(value),index);
2125 //_____________________________________________________________________________
2127 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i,
2128 Int_t dim, Int_t ddlId) const
2130 /// Compute the value for a given dim, using the internal information we have
2131 /// Basically we're converting sum of weights and sum of squares of weights
2132 /// into means and sigmas, and number of events into occupancy number.
2134 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
2136 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
2138 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
2140 if ( dim >= fDimension )
2145 if ( dim == IndexOfOccupancyDimension() )
2147 if ( ddlId < 0 ) AliError("Got a negative ddl id !");
2148 return occ/n/NumberOfEvents(ddlId);
2151 Double_t value = param.ValueAsDouble(i,dim);
2153 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
2155 if ( TMath::Even(dim) || IsSingleEvent() )
2157 Double_t x = value/occ;
2159 return ( TMath::Finite(x) ? x : 0.0 ) ;
2167 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
2169 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
2177 AliError("Why am I here ?");
2181 //_____________________________________________________________________________
2183 AliMUONTrackerData::Streamer(TBuffer &R__b)
2185 /// Customized streamer
2187 if (R__b.IsReading()) {
2188 AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
2191 // backward compatible mode : we set number of events
2192 // per DDL to the total number of events (the only information
2193 // we had before version 7 of that class)
2194 delete[] fNofEventsPerDDL;
2196 fNofEventsPerDDL = new Int_t[fNofDDLs];
2197 for ( Int_t i = 0; i < fNofDDLs; ++i )
2199 fNofEventsPerDDL[i] = fNevents;
2204 AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
2208 //_____________________________________________________________________________
2210 AliMUONTrackerData::ExportAsASCIIOccupancyFile(const char* filename, Int_t runNumber) const
2212 /// Export only the occupancy part, in a format compatible with what
2213 /// the online occupancy DA is writing
2215 if ( ! AliMpDDLStore::Instance(kFALSE) )
2217 AliError("Mapping not loaded. Cannot work");
2223 AliError("No manu values. Cannot work");
2227 ofstream out(filename);
2231 AliError(Form("Cannot create file %s",filename));
2235 out << "//===========================================================================" << endl;
2236 out << "// Hit counter exported from $Id$" << endl;
2237 out << "//===========================================================================" << endl;
2238 out << "//" << endl;
2239 out << "// * Run Number : " << runNumber << endl;
2240 out << "// * File Creation Date : " << TTimeStamp().AsString("l") << endl;
2241 out << "//---------------------------------------------------------------------------" << endl;
2242 out << "// BP MANU SUM_N NEVENTS" << endl;
2243 out << "//---------------------------------------------------------------------------" << endl;
2245 TIter next(fManuValues->CreateIterator());
2246 AliMUONVCalibParam* manu;
2248 while ( ( manu = static_cast<AliMUONVCalibParam*>(next()) ) )
2250 Int_t detElemId = manu->ID0();
2251 Int_t manuId = manu->ID1();
2252 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
2253 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus( busPatchId);
2254 if ( busPatchId < 0 || ddl < 0 )
2256 AliError(Form("Got invalid (DE,manu,bp,ddl)=(%d,%d,%d,%d). Skipping it",detElemId,manuId,busPatchId,ddl));
2260 Int_t nevents = fNofEventsPerDDL[ddl];
2262 out << Form("%5d %5d %10d %10d",busPatchId,manuId,manu->ValueAsInt(0,IndexOfOccupancyDimension()),nevents) << endl;
2269 //_____________________________________________________________________________
2270 void AliMUONTrackerData::DispatchValue(AliMUONVCalibParam& param,
2276 /// fills the calibparam with a single value
2278 Double_t sumn = 1000.0; // or any value strictly above 1
2279 Double_t sumw = sumn*y;
2280 Double_t sumw2 = (sumn-1)*ey*ey+sumw*sumw/sumn;
2282 param.SetValueAsDouble(index,0,sumw);
2283 param.SetValueAsDouble(index,1,sumw2);
2284 param.SetValueAsDouble(index,2,sumn);
2285 param.SetValueAsDouble(index,3,nchannels);