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 if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled )
661 AliError("Incompatible IsChannelLevelEnabled status");
665 if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled )
667 AliError("Incompatible IsManuLevelEnabled status");
671 if ( fIsSingleEvent != data.fIsSingleEvent )
673 AliError("Incompatible IsSingleEvent status");
677 if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension )
679 AliError("Incompatible dimensions");
683 if ( fNofDDLs != data.fNofDDLs )
685 AliError("Incompatible number of Ddls");
689 if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming )
690 || fXmin != data.fXmin || fXmax != data.fXmax )
692 AliError(Form("Incompatible histogramming (%p vs %p) (xmax = %e vs %e ; xmin = %e vs %e)",
693 fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
697 if ( fHistogramming )
699 for ( Int_t i = 0; i < fExternalDimension; ++i )
701 if ( fHistogramming[i] != data.fHistogramming[i] )
703 AliError(Form("Incompatible histogramming for external dimension %d",i));
709 // OK. Seems we have compatible objects, so we can proceed with the actual
712 if ( data.fChannelValues )
714 Add2D(*(data.fChannelValues),*fChannelValues);
717 if ( data.fManuValues )
719 Add2D(*(data.fManuValues),*fManuValues);
722 if ( data.fPCBValues )
724 Add2D(*(data.fPCBValues),*fPCBValues);
727 if ( data.fBusPatchValues )
729 Add1D(*(data.fBusPatchValues),*fBusPatchValues);
732 if ( data.fDEValues )
734 Add1D(*(data.fDEValues),*fDEValues);
737 if ( data.fChamberValues )
739 Add1D(*(data.fChamberValues),*fChamberValues);
742 for ( Int_t i = 0; i < fNofDDLs; ++i )
744 fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
749 TIter nexthisto(data.fHistos->CreateIterator());
750 AliMUONVStore* store;
751 while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
753 TIter ns(store->CreateIterator());
754 AliMUONSparseHisto* h;
755 while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
757 AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
761 thisStore = store->Create();
762 thisStore->SetUniqueID(store->GetUniqueID());
763 fHistos->Add(thisStore);
766 AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
780 fNevents = TMath::Max(fNevents,data.fNevents);
785 //_____________________________________________________________________________
787 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
789 /// Add one 2d store to another
791 TIter next(src.CreateIterator());
792 AliMUONVCalibParam* p;
794 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
796 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
800 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
804 AddCalibParams(*p,*a);
809 //_____________________________________________________________________________
811 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
813 /// Add one 1d store to another
815 TIter next(src.CreateIterator());
816 AliMUONVCalibParam* p;
818 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
820 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
824 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
828 AddCalibParams(*p,*a);
833 //_____________________________________________________________________________
835 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
838 for ( Int_t i = 0; i < src.Size(); ++i )
840 for ( Int_t j = 0; j < src.Dimension(); ++j )
842 dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
847 //_____________________________________________________________________________
849 AliMUONTrackerData::Replace(const AliMUONVStore& store)
851 /// Replace our values by values from the given external store
852 Bool_t rv = InternalAdd(store,0x0,kTRUE);
853 AliMUONVTrackerData::Replace(store);
857 //_____________________________________________________________________________
859 AliMUONTrackerData::UpdateNumberOfEvents(TArrayI* nevents)
861 /// Update the number of events
865 fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
866 fNofEventsPerDDL = new Int_t[fNofDDLs];
867 for ( Int_t i = 0; i < fNofDDLs; ++i )
869 fNofEventsPerDDL[i] = 0;
875 if (nevents->GetSize() != fNofDDLs )
877 AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
878 nevents->GetSize(),fNofDDLs));
882 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
884 fNofEventsPerDDL[i] += nevents->At(i);
885 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
890 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
892 ++fNofEventsPerDDL[i];
893 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
899 //_____________________________________________________________________________
901 AliMUONTrackerData::AssertStores()
903 /// Insure our stores are allocated
907 Int_t numberOfBusPatches(0);
908 Int_t numberOfDEs(0);
910 // get number of bus patches and number of detection element
911 // to initialize fBusPatchValues and fDEValues below
913 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
914 while ( next() ) ++numberOfBusPatches;
915 AliMpDEIterator deIt;
917 while (!deIt.IsDone())
923 if ( fIsChannelLevelEnabled )
925 fChannelValues = new AliMUON2DMap(kTRUE);
927 if ( fIsManuLevelEnabled )
929 fManuValues = new AliMUON2DMap(kTRUE);
931 if ( fIsPCBLevelEnabled )
933 fPCBValues = new AliMUON2DMap(kFALSE);
935 if ( fIsBustPatchLevelEnabled )
937 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
939 fDEValues = new AliMUON1DMap(numberOfDEs);
940 fChamberValues = new AliMUON1DArray;
944 //_____________________________________________________________________________
946 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
948 /// Add the given external store to our internal store
950 AliCodeTimerAuto(GetName(),0);
954 if ( IsSingleEvent() && NumberOfEvents(-1) == 1 )
956 AliError(Form("%s is supposed to be single event only",GetName()));
961 UpdateNumberOfEvents(nevents);
965 TIter next(store.CreateIterator());
966 AliMUONVCalibParam* external;
970 if ( IsSingleEvent() ) nk = 1;
972 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
974 if ( external->Dimension() != ExternalDimension() )
976 AliError(Form("Incompatible dimensions %d vs %d",
977 external->Dimension(),ExternalDimension()));
981 AliMUONVCalibParam* chamber(0x0);
982 AliMUONVCalibParam* de(0x0);
983 AliMUONVCalibParam* busPatch(0x0);
984 AliMUONVCalibParam* pcb(0x0);
985 AliMUONVCalibParam* manu(0x0);
986 AliMUONVCalibParam* channel(0x0);
987 AliMpDetElement* mpde(0x0);
989 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
991 if ( manuId < 0 ) continue;
993 Int_t detElemId = mpde->GetId();
995 Double_t value[] = { 0.0, 0.0 };
997 Int_t nch = mpde->NofChannelsInManu(manuId);
999 for ( Int_t i = 0; i < external->Size(); ++i )
1001 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
1002 : mpde->IsConnectedChannel(manuId,i));
1003 // note we only use IsConnectedChannel method when really needed, as
1004 // it costs (some) CPU time...
1006 if ( existingChannel )
1008 Bool_t validChannel(kFALSE);
1010 for ( Int_t j = 0; j < external->Dimension(); ++j )
1012 Double_t vext = external->IsDoublePrecision() ?
1013 external->ValueAsDoubleFast(i,j) :
1014 external->ValueAsFloatFast(i,j);
1016 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
1018 validChannel = kTRUE;
1020 Int_t ix = External2Internal(j);
1023 value[1] = vext*vext;
1025 if ( IsHistogrammed(j) )
1027 FillHisto(detElemId,manuId,i,j,vext);
1030 for ( Int_t k = 0; k < nk; ++k )
1032 Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
1036 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
1041 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1044 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1046 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1048 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1052 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1057 if ( validChannel && !replace )
1061 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
1062 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
1067 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1068 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1071 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1072 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1073 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1074 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1075 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1076 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1079 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1080 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1087 NumberOfEventsChanged();
1092 //_____________________________________________________________________________
1094 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
1096 /// Return the value of a given buspatch for a given dimension
1097 /// or 0 if not existing
1098 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
1099 return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
1102 //_____________________________________________________________________________
1104 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
1106 /// Return (if it exist), the VCalibParam for a given busPatch
1108 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
1109 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
1111 if (!busPatch && create && fBusPatchValues)
1113 busPatch = CreateBusPatchParam(busPatchId);
1114 fBusPatchValues->Add(busPatch);
1120 //_____________________________________________________________________________
1122 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
1124 /// Create storage for one bus patch
1126 AliCodeTimerAuto("",0);
1128 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1132 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
1136 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
1138 // set the number of channels in that buspatch
1142 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
1144 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1146 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
1148 Int_t manuId = bp->GetManuId(i);
1149 nchannels += de->NofChannelsInManu(manuId);
1152 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1157 //_____________________________________________________________________________
1159 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
1161 /// Return the value fo a given chamber for a given dimension,
1162 /// or zero if not existing
1164 // FIXME: is the Value() correct wrt to number of events in the case of
1165 // chamber ? Or should we do something custom at the chamber level
1166 // (as it spans several ddls) ?
1168 AliMUONVCalibParam* param = ChamberParam(chamberId);
1169 return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
1172 //_____________________________________________________________________________
1174 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
1176 /// Return (if it exist) the VCalibParam for a given chamber
1178 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
1179 (fChamberValues->FindObject(chamberId)) : 0x0;
1181 if (!chamber && create && fChamberValues)
1183 chamber = CreateChamberParam(chamberId);
1184 fChamberValues->Add(chamber);
1190 //_____________________________________________________________________________
1192 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
1194 /// Create storage for one chamber
1196 AliCodeTimerAuto("",0);
1198 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
1200 // set the number of channels in that chamber
1206 it.First(chamberId);
1208 while ( !it.IsDone() )
1210 AliMpDetElement* det = it.CurrentDE();
1212 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1214 Int_t busPatchId = det->GetBusPatchId(i);
1215 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1216 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1218 Int_t manuId = bp->GetManuId(j);
1219 nchannels += det->NofChannelsInManu(manuId);
1226 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1231 //_____________________________________________________________________________
1233 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
1234 Int_t manuChannel, Int_t dim) const
1236 /// Return the value for a given channel for a given dimension
1238 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
1240 return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1243 //_____________________________________________________________________________
1245 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
1246 const AliMUONVCalibParam* external) const
1248 /// Return (if it exist) the VCalibParam for a given manu
1250 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
1251 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
1253 if (!param && external && fChannelValues)
1255 param = CreateDouble(*external,detElemId,manuId);
1256 fChannelValues->Add(param);
1262 //_____________________________________________________________________________
1264 AliMUONTrackerData::Clear(Option_t*)
1266 /// Clear all the values
1267 if ( fChannelValues ) fChannelValues->Clear();
1268 if ( fManuValues ) fManuValues->Clear();
1269 if ( fBusPatchValues) fBusPatchValues->Clear();
1270 if ( fPCBValues ) fPCBValues->Clear();
1271 if ( fDEValues) fDEValues->Clear();
1272 if ( fChamberValues ) fChamberValues->Clear();
1273 if ( fHistos ) fHistos->Clear();
1274 for ( Int_t i = 0; i < fNofDDLs; ++i )
1276 fNofEventsPerDDL[i] = 0;
1279 NumberOfEventsChanged();
1282 //_____________________________________________________________________________
1284 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
1285 Int_t manuChannel) const
1287 /// Return the number of times a given channel had data
1289 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
1292 //_____________________________________________________________________________
1294 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
1295 Int_t detElemId, Int_t manuId) const
1297 /// Create a double version of VCalibParam, for internal use
1299 AliCodeTimerAuto("",0);
1301 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
1307 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
1309 for ( Int_t i = 0; i < c->Size(); ++i )
1311 Double_t value(0.0);
1313 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
1315 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
1321 //_____________________________________________________________________________
1323 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
1325 /// Return the value for a given detection element for a given dimension
1326 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
1327 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1331 //_____________________________________________________________________________
1333 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
1335 /// Return (if it exist) the VCalibParam for a given detection element
1337 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
1338 (fDEValues->FindObject(detElemId)) : 0x0 ;
1340 if (!de && create && fDEValues)
1342 de = CreateDetectionElementParam(detElemId);
1350 //_____________________________________________________________________________
1352 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
1354 /// Create storage for one detection element
1356 AliCodeTimerAuto("",0);
1358 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
1360 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1363 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1365 Int_t busPatchId = det->GetBusPatchId(i);
1366 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1367 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1369 Int_t manuId = bp->GetManuId(j);
1370 nchannels += det->NofChannelsInManu(manuId);
1374 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1379 //_____________________________________________________________________________
1381 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
1383 /// Get the "local" ddlid (0..19) of a given buspatch
1384 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
1387 return bp->GetDdlId();
1392 //_____________________________________________________________________________
1394 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
1396 /// Get the "local" ddlid (0..19) of a given detection element
1397 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
1400 return de->GetDdlId();
1405 //_____________________________________________________________________________
1407 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
1409 /// Get the "local" ddlid (0..19) of a given chamber
1410 /// This has no real meaning (as there are several ddls per chamber),
1411 /// so we take the ddlid where we got the max number of events
1415 it.First(chamberid);
1419 while (!it.IsDone())
1421 Int_t detElemId = it.CurrentDEId();
1422 Int_t ddlId = DdlIdFromDetElemId(detElemId);
1423 if ( NumberOfEvents(ddlId) > n )
1425 n = NumberOfEvents(ddlId);
1434 //_____________________________________________________________________________
1436 AliMUONTrackerData::DimensionName(Int_t dim) const
1438 /// Get the name of a given dimension
1439 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
1442 return value->String();
1446 return TString("Invalid");
1450 //_____________________________________________________________________________
1452 AliMUONTrackerData::DisableChannelLevel()
1454 /// Disable the storing of data at channel level
1456 delete fChannelValues;
1457 fChannelValues = 0x0;
1458 fIsChannelLevelEnabled = kFALSE;
1461 //_____________________________________________________________________________
1463 AliMUONTrackerData::DisableManuLevel()
1465 /// Disable the storing of data at manu level (and below)
1467 DisableChannelLevel();
1470 fIsManuLevelEnabled = kFALSE;
1473 //_____________________________________________________________________________
1475 AliMUONTrackerData::External2Internal(Int_t index) const
1477 /// From external to internal dimension
1478 return IsSingleEvent() ? index : index*2;
1481 //_____________________________________________________________________________
1483 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
1485 /// Get the name of a given external dimension
1487 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
1490 return value->String();
1494 return TString("Invalid");
1498 //_____________________________________________________________________________
1500 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
1501 Int_t dim, Double_t value)
1503 /// Fill histogram of a given channel
1505 AliMUONSparseHisto* h(0x0);
1507 if ( fIsChannelLevelEnabled )
1509 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
1511 else if ( fIsManuLevelEnabled )
1513 h = GetManuSparseHisto(detElemId,manuId,dim);
1516 AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
1520 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
1524 //_____________________________________________________________________________
1526 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId,
1529 /// Get histogram of a given manu
1531 if (!fHistos) return 0x0;
1533 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1536 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1541 //_____________________________________________________________________________
1543 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
1545 /// Get histogram of a given manu. Create it if necessary
1547 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1549 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1552 m = new AliMUON1DArray(NumberOfDimensions());
1553 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1557 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1560 h = new AliMUONSparseHisto(fXmin,fXmax);
1562 h->SetUniqueID(dim);
1570 //_____________________________________________________________________________
1572 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1573 Int_t manuChannel, Int_t dim) const
1575 /// Get histogram of a given channel
1577 if (!fHistos) return 0x0;
1579 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1582 UInt_t uid = ( manuChannel << 16 ) | dim;
1584 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1589 //_____________________________________________________________________________
1591 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1592 Int_t manuChannel, Int_t dim)
1594 /// Get histogram of a given channel. Create it if necessary
1596 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1598 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1601 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1602 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1606 UInt_t uid = ( manuChannel << 16 ) | dim;
1608 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1611 h = new AliMUONSparseHisto(fXmin,fXmax);
1613 h->SetUniqueID(uid);
1621 //_____________________________________________________________________________
1623 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1624 Int_t& detElemId, Int_t& manuId) const
1626 /// Tries to get (detElemId,manuId) of param
1628 // Load mapping manu store
1629 if ( ! AliMpCDB::LoadManuStore() ) {
1630 AliError("Could not access manu store from OCDB !");
1634 if ( param.ID1() <= 0 )
1636 // we (probably) get a manu serial number
1637 Int_t serial = param.ID0();
1638 MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1639 detElemId = AliMp::PairFirst(pair);
1640 manuId = AliMp::PairSecond(pair);
1643 AliDebug(1,Form("DE %d manuId %d from serial %d is not correct !",
1644 detElemId,manuId,serial));
1649 // we get a (de,manu) pair
1650 detElemId = param.ID0();
1651 manuId = param.ID1();
1656 //_____________________________________________________________________________
1658 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1659 AliMUONVCalibParam*& chamber,
1660 AliMUONVCalibParam*& de,
1661 AliMUONVCalibParam*& busPatch,
1662 AliMUONVCalibParam*& pcb,
1663 AliMUONVCalibParam*& manu,
1664 AliMUONVCalibParam*& channel,
1665 AliMpDetElement*& mpde)
1667 /// Get containers at all levels
1669 chamber = de = busPatch = pcb = manu = channel = 0x0;
1672 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1677 GetDEManu(*external,detElemId,manuId);
1679 mpde = ddlStore->GetDetElement(detElemId,kFALSE);
1681 if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1686 // explicitely check that de,manu is correct
1687 const AliMpVSegmentation* mpseg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId,kFALSE);
1694 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1696 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1698 if ( busPatchId <= 0 )
1703 Int_t pcbIndex = -1;
1705 AliMp::StationType stationType = mpde->GetStationType();
1707 if ( stationType == AliMp::kStation345 )
1709 AliMpDCSNamer namer("TRACKER");
1710 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1713 if ( fIsChannelLevelEnabled )
1715 channel = ChannelParam(detElemId,manuId,external);
1718 manu = ManuParam(detElemId,manuId,kTRUE);
1720 busPatch = BusPatchParam(busPatchId,kTRUE);
1722 de = DetectionElementParam(detElemId,kTRUE);
1724 chamber = ChamberParam(chamberId,kTRUE);
1728 if ( pcbIndex >= 0 )
1730 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1736 //_____________________________________________________________________________
1738 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1740 /// Whether we have data for a given buspatch
1741 return ( BusPatchParam(busPatchId) != 0 );
1744 //_____________________________________________________________________________
1746 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1748 /// Whether we have data for a given chamber
1749 return ( ChamberParam(chamberId) != 0 );
1752 //_____________________________________________________________________________
1754 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1756 /// Whether we have data for a given detection element
1757 return ( DetectionElementParam(detElemId) != 0 );
1760 //_____________________________________________________________________________
1762 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1764 /// Whether we have data for a given manu
1765 return ( ManuParam(detElemId,manuId) != 0 );
1768 //_____________________________________________________________________________
1770 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1772 /// Whether we have data for a given pcb
1773 return ( PCBParam(detElemId,pcbIndex) != 0 );
1776 //_____________________________________________________________________________
1778 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1780 /// Return the value for a given manu and a given dimension
1782 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1783 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1786 //_____________________________________________________________________________
1788 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1790 /// Get the VCalibParam for a given manu
1792 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1793 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1795 if (!manu && create && fManuValues)
1797 manu = CreateManuParam(detElemId,manuId);
1798 fManuValues->Add(manu);
1804 //_____________________________________________________________________________
1806 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1808 /// Create storage for one manu
1810 AliCodeTimerAuto("",0);
1812 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1814 // set the number of channels in that manu
1816 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1818 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1823 //_____________________________________________________________________________
1825 AliMUONTrackerData::Merge(TCollection* list)
1827 /// Merge this with a list of AliMUONVTrackerData
1829 if (!list) return 0;
1831 if ( list->IsEmpty() ) return NumberOfEvents(-1);
1834 const TObject* o(0x0);
1836 while ( ( o = next() ) )
1838 const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1841 AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1846 Bool_t ok = Add(*data);
1849 AliError("Got incompatible objects");
1854 return NumberOfEvents(-1);
1857 //_____________________________________________________________________________
1859 AliMUONTrackerData::NumberOfDimensions() const
1861 /// Number of dimensions we're dealing with
1863 return fDimension + fgkVirtualExtraDimension;
1866 //_____________________________________________________________________________
1868 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1870 /// Get the number of events we've seen for a given DDL, or the max
1871 /// in case ddlNumber<0
1875 if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1877 n = fNofEventsPerDDL[ddlNumber];
1881 // get the max number of events
1888 //_____________________________________________________________________________
1890 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1892 /// Return the value of a given pcb for a given dimension
1894 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1896 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1899 //_____________________________________________________________________________
1901 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1903 /// Return (if it exist) the VCalibParam for a given pcb
1905 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
1906 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1908 if (create && fPCBValues && !pcb)
1910 pcb = CreatePCBParam(detElemId,pcbIndex);
1911 fPCBValues->Add(pcb);
1917 //_____________________________________________________________________________
1919 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1921 /// Create storage for one PCB (station345 only)
1923 AliCodeTimerAuto("",0);
1925 AliMpDCSNamer namer("TRACKER");
1927 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1928 namer.NumberOfPCBs(detElemId),
1935 //_____________________________________________________________________________
1937 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1943 if ( !fIsSingleEvent )
1945 for ( Int_t i = 0; i < fNofDDLs; ++i )
1947 cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1951 if ( !fIsChannelLevelEnabled )
1953 cout << "Is not storing data at the channel level" << endl;
1956 if ( !fIsManuLevelEnabled )
1958 cout << "Is not storing data at the manu level" << endl;
1961 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
1963 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1964 cout << Form("External Dimension %2d Name %s %s",i,
1965 ( name ? name->String().Data() : "null"),
1966 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1969 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
1971 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1972 cout << Form("Internal Dimension %2d Name %s",i,
1973 ( name ? name->String().Data() : "null")) << endl;
1979 if ( sopt.Contains("CHANNEL") )
1981 if ( fIsChannelLevelEnabled )
1983 if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1987 AliWarning("You requested channel values, but they were not stored !");
1991 if ( sopt.Contains("MANU") )
1993 if ( fIsManuLevelEnabled )
1995 if ( fManuValues ) fManuValues->Print(wildcard,opt);
1999 AliWarning("You requested manu values, but they were not stored !");
2003 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
2005 fBusPatchValues->Print(wildcard,opt);
2008 if ( sopt.Contains("DE") && fDEValues )
2010 fDEValues->Print(wildcard,opt);
2013 if ( sopt.Contains("CHAMBER") && fChamberValues )
2015 fChamberValues->Print(wildcard,opt);
2020 //_____________________________________________________________________________
2022 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
2024 /// Set the name of a given dimension
2026 if ( index >= fExternalDimension )
2028 AliError(Form("%s : dimension %s : Index out of bounds : %d / %d",
2030 name,index,fExternalDimension));
2034 Int_t ix = External2Internal(index);
2036 if ( !IsSingleEvent() )
2038 const char* prefix[] = { "mean", "sigma" };
2040 for ( Int_t i = 0; i < 2; ++i )
2044 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
2049 SetInternalDimensionName(index,name);
2052 SetExternalDimensionName(index,name);
2055 //_____________________________________________________________________________
2057 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
2059 /// decide to make histos for a given dimension
2060 if ( index >= ExternalDimension() )
2062 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
2066 AliWarning(Form("Will %s make histogram for data %s index %d : that might ressemble a memory leak depending on the input data",
2067 value ? "":"not", GetName(),index));
2068 fHistogramming[index] = value;
2073 //_____________________________________________________________________________
2075 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
2077 /// Set the name of a given internal dimension
2078 if ( index >= fDimension )
2080 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
2084 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
2088 fDimensionNames->Remove(ovalue);
2091 fDimensionNames->AddAt(new TObjString(value),index);
2094 //_____________________________________________________________________________
2096 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
2098 /// Set the name of a given external dimension
2099 if ( index >= fExternalDimension )
2101 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
2105 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
2109 fExternalDimensionNames->Remove(ovalue);
2112 fExternalDimensionNames->AddAt(new TObjString(value),index);
2115 //_____________________________________________________________________________
2117 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i,
2118 Int_t dim, Int_t ddlId) const
2120 /// Compute the value for a given dim, using the internal information we have
2121 /// Basically we're converting sum of weights and sum of squares of weights
2122 /// into means and sigmas, and number of events into occupancy number.
2124 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
2126 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
2128 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
2130 if ( dim >= fDimension )
2135 if ( dim == IndexOfOccupancyDimension() )
2137 if ( ddlId < 0 ) AliError("Got a negative ddl id !");
2138 return occ/n/NumberOfEvents(ddlId);
2141 Double_t value = param.ValueAsDouble(i,dim);
2143 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
2145 if ( TMath::Even(dim) || IsSingleEvent() )
2147 Double_t x = value/occ;
2149 return ( TMath::Finite(x) ? x : 0.0 ) ;
2157 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
2159 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
2167 AliError("Why am I here ?");
2171 //_____________________________________________________________________________
2173 AliMUONTrackerData::Streamer(TBuffer &R__b)
2175 /// Customized streamer
2177 if (R__b.IsReading()) {
2178 AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
2181 // backward compatible mode : we set number of events
2182 // per DDL to the total number of events (the only information
2183 // we had before version 7 of that class)
2184 delete[] fNofEventsPerDDL;
2186 fNofEventsPerDDL = new Int_t[fNofDDLs];
2187 for ( Int_t i = 0; i < fNofDDLs; ++i )
2189 fNofEventsPerDDL[i] = fNevents;
2194 AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
2198 //_____________________________________________________________________________
2200 AliMUONTrackerData::ExportAsASCIIOccupancyFile(const char* filename, Int_t runNumber) const
2202 /// Export only the occupancy part, in a format compatible with what
2203 /// the online occupancy DA is writing
2205 if ( ! AliMpDDLStore::Instance(kFALSE) )
2207 AliError("Mapping not loaded. Cannot work");
2213 AliError("No manu values. Cannot work");
2217 ofstream out(filename);
2221 AliError(Form("Cannot create file %s",filename));
2225 out << "//===========================================================================" << endl;
2226 out << "// Hit counter exported from $Id$" << endl;
2227 out << "//===========================================================================" << endl;
2228 out << "//" << endl;
2229 out << "// * Run Number : " << runNumber << endl;
2230 out << "// * File Creation Date : " << TTimeStamp().AsString("l") << endl;
2231 out << "//---------------------------------------------------------------------------" << endl;
2232 out << "// BP MANU SUM_N NEVENTS" << endl;
2233 out << "//---------------------------------------------------------------------------" << endl;
2235 TIter next(fManuValues->CreateIterator());
2236 AliMUONVCalibParam* manu;
2238 while ( ( manu = static_cast<AliMUONVCalibParam*>(next()) ) )
2240 Int_t detElemId = manu->ID0();
2241 Int_t manuId = manu->ID1();
2242 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
2243 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus( busPatchId);
2244 if ( busPatchId < 0 || ddl < 0 )
2246 AliError(Form("Got invalid (DE,manu,bp,ddl)=(%d,%d,%d,%d). Skipping it",detElemId,manuId,busPatchId,ddl));
2250 Int_t nevents = fNofEventsPerDDL[ddl];
2252 out << Form("%5d %5d %10d %10d",busPatchId,manuId,manu->ValueAsInt(0,IndexOfOccupancyDimension()),nevents) << endl;
2259 //_____________________________________________________________________________
2260 void AliMUONTrackerData::DispatchValue(AliMUONVCalibParam& param,
2266 /// fills the calibparam with a single value
2268 Double_t sumn = 1000.0; // or any value strictly above 1
2269 Double_t sumw = sumn*y;
2270 Double_t sumw2 = (sumn-1)*ey*ey+sumw*sumw/sumn;
2272 param.SetValueAsDouble(index,0,sumw);
2273 param.SetValueAsDouble(index,1,sumw2);
2274 param.SetValueAsDouble(index,2,sumn);
2275 param.SetValueAsDouble(index,3,nchannels);