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 "AliMUONConstants.h"
28 #include "AliMUONRejectList.h"
29 #include "AliMUONSparseHisto.h"
30 #include "AliMUONVStore.h"
31 #include "AliMpBusPatch.h"
32 #include "AliMpConstants.h"
34 #include "AliMpDDLStore.h"
35 #include "AliMpManuStore.h"
36 #include "AliMpDEIterator.h"
37 #include "AliMpDEManager.h"
38 #include "AliMpDetElement.h"
39 #include "AliMpDCSNamer.h"
40 #include "AliMpManuIterator.h"
41 #include "AliMpEncodePair.h"
42 #include "AliMpSegmentation.h"
43 #include <Riostream.h>
46 #include <TObjArray.h>
47 #include <TObjString.h>
49 #include <TTimeStamp.h>
54 /// \class AliMUONTrackerData
56 /// Implementation of AliMUONVTrackerData class
58 /// \author Laurent Aphecetche, Subatech
61 ClassImp(AliMUONTrackerData)
64 const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
65 const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
67 //_____________________________________________________________________________
68 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
71 : AliMUONVTrackerData(name,title),
72 fIsSingleEvent(issingleevent),
79 fDimension(External2Internal(dimension)+fgkExtraDimension),
81 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
82 fExternalDimensionNames(new TObjArray(dimension)),
83 fExternalDimension(dimension),
84 fHistogramming(new Int_t[fExternalDimension]),
88 fIsChannelLevelEnabled(kTRUE),
89 fIsManuLevelEnabled(kTRUE),
90 fIsBustPatchLevelEnabled(kTRUE),
91 fIsPCBLevelEnabled(kTRUE),
96 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
97 fExternalDimensionNames->SetOwner(kTRUE);
98 fDimensionNames->SetOwner(kTRUE);
99 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
100 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
101 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
105 //_____________________________________________________________________________
106 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
107 const AliMUONVStore& manuValues)
108 : AliMUONVTrackerData(name,title),
109 fIsSingleEvent(kFALSE),
112 fBusPatchValues(0x0),
118 fDimensionNames(0x0),
119 fExternalDimensionNames(0x0),
120 fExternalDimension(0),
125 fIsChannelLevelEnabled(kFALSE),
126 fIsManuLevelEnabled(kTRUE),
127 fIsBustPatchLevelEnabled(kTRUE),
128 fIsPCBLevelEnabled(kTRUE),
130 fNofEventsPerDDL(0x0)
132 /// ctor with pre-computed values at the manu level
133 /// In this case, we force fIsChannelLevelEnabled = kFALSE
136 if (manuValues.GetSize()==0)
138 AliFatal("Cannot create a tracker data from nothing in that case !");
141 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
143 AliError("Cannot work without (full) mapping");
147 TIter next(manuValues.CreateIterator());
148 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
150 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
152 fDimension = External2Internal(dimension)+fgkExtraDimension;
154 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
155 fExternalDimensionNames = new TObjArray(dimension);
156 fExternalDimension = dimension;
157 fHistogramming = new Int_t[fExternalDimension];
158 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
160 fExternalDimensionNames->SetOwner(kTRUE);
161 fDimensionNames->SetOwner(kTRUE);
162 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
163 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
164 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
166 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
170 AliMUONVCalibParam* external;
172 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
174 Int_t detElemId, manuId;
176 GetDEManu(*external,detElemId,manuId);
178 AliMUONVCalibParam* chamber(0x0);
179 AliMUONVCalibParam* de(0x0);
180 AliMUONVCalibParam* busPatch(0x0);
181 AliMUONVCalibParam* pcb(0x0);
182 AliMUONVCalibParam* manu(0x0);
183 AliMUONVCalibParam* channel(0x0);
184 AliMpDetElement* mpde(0x0);
186 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,manuId,0);
187 // as external, but without event count
188 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
189 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
190 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
191 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
193 Int_t mid = GetParts(wec,chamber,de,busPatch,pcb,manu,channel,mpde);
197 AliError(Form("Something is wrong for DE %5d : manuId = %d vs mid = %d",detElemId,manuId,mid));
203 AliError("Got a < 0 manuId. Should not happen here !");
207 assert(channel==0x0);
209 Int_t n1 = manu->ValueAsInt(0,IndexOfNumberDimension());
210 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
213 AliError(Form("Incoherent number of manu channels for DE %5d MANU %5d : %d vs %d",
214 detElemId,manuId,n1,n2));
217 Int_t nevt = external->ValueAsInt(0,4);
219 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
221 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus(busPatchId);
223 if ( nevents[ddl] == 0 )
229 if ( nevents.At(ddl) != nevt )
231 AliError(Form("Nevt mismatch for DE %5d MANU %5d DDL %d : %d vs %d",
232 detElemId,manuId,ddl,nevents.At(ddl),nevt));
237 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
239 manu->SetValueAsDouble(0,i,manu->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
241 busPatch->SetValueAsDouble(0,i,busPatch->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
243 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
245 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
250 UpdateNumberOfEvents(&nevents);
254 //_____________________________________________________________________________
255 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
256 const AliMUONVStore& deValues, Int_t val)
257 : AliMUONVTrackerData(name,title),
258 fIsSingleEvent(kFALSE),
261 fBusPatchValues(0x0),
267 fDimensionNames(0x0),
268 fExternalDimensionNames(0x0),
269 fExternalDimension(0),
274 fIsChannelLevelEnabled(kFALSE),
275 fIsManuLevelEnabled(kFALSE),
276 fIsBustPatchLevelEnabled(kFALSE),
277 fIsPCBLevelEnabled(kFALSE),
279 fNofEventsPerDDL(0x0)
281 /// ctor with values at the detection element level
282 /// In this case, we force fIsChannelLevelEnabled = fIsManuLevelEnabled = kFALSE
285 if (deValues.GetSize()==0)
287 AliFatal("Cannot create a tracker data from nothing in that case !");
292 AliFatal("Wrong parameter. For DE, must be 1");
295 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
297 AliError("Cannot work without (full) mapping");
301 TIter next(deValues.CreateIterator());
302 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
304 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
306 fDimension = External2Internal(dimension)+fgkExtraDimension;
308 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
309 fExternalDimensionNames = new TObjArray(dimension);
310 fExternalDimension = dimension;
311 fHistogramming = new Int_t[fExternalDimension];
312 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
314 fExternalDimensionNames->SetOwner(kTRUE);
315 fDimensionNames->SetOwner(kTRUE);
316 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
317 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
318 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
320 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
324 AliMUONVCalibParam* external;
326 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
328 Int_t detElemId = external->ID0();
330 AliMpDetElement* mpde = AliMpDDLStore::Instance()->GetDetElement(detElemId,kFALSE);
334 AliError(Form("Got an invalid DE (%d) from external store",detElemId));
338 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
339 AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
340 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
342 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,0,0);
343 // as external, but without event count
344 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
345 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
346 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
347 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
349 Int_t n1 = de->ValueAsInt(0,IndexOfNumberDimension());
350 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
353 AliError(Form("Incoherent number of dimensions for DE%d : %d vs %d",
358 Int_t nevt = external->ValueAsInt(0,4);
360 Int_t ddl = mpde->GetDdlId();
362 if ( nevents[ddl] == 0 )
368 if ( nevents.At(ddl) != nevt )
370 AliError(Form("Nevt mismatch for DE %5d DDL %d : %d vs %d",
371 detElemId,ddl,nevents.At(ddl),nevt));
376 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
378 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
380 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
385 UpdateNumberOfEvents(&nevents);
389 //_____________________________________________________________________________
390 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
391 const AliMUONRejectList& rejectList)
392 : AliMUONVTrackerData(name,title),
393 fIsSingleEvent(kFALSE),
396 fBusPatchValues(0x0),
400 fDimension(External2Internal(1)+fgkExtraDimension),
402 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
403 fExternalDimensionNames(new TObjArray(1)),
404 fExternalDimension(1),
405 fHistogramming(new Int_t[fExternalDimension]),
409 fIsChannelLevelEnabled(kTRUE),
410 fIsManuLevelEnabled(kTRUE),
411 fIsBustPatchLevelEnabled(kTRUE),
412 fIsPCBLevelEnabled(kFALSE),
414 fNofEventsPerDDL(0x0)
417 /// ctor with values from the given rejectlist
419 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
421 AliError("Cannot work without (full) mapping");
425 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
427 fExternalDimensionNames->SetOwner(kTRUE);
428 fDimensionNames->SetOwner(kTRUE);
429 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
430 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
431 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
433 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
437 for ( Int_t chamberId = 0; chamberId < AliMUONConstants::NCh(); ++chamberId )
439 // AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
441 // FIXME : update the chamber value ?
443 AliMpDEIterator deit;
445 deit.First(chamberId);
447 while ( !deit.IsDone() )
449 AliMpDetElement* mpde = deit.CurrentDE();
451 Int_t detElemId = mpde->GetId();
453 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
455 DispatchValue(*de,0,rejectList.DetectionElementProbability(detElemId),0.0,mpde->NofChannels());
457 for ( Int_t iBusPatch = 0; iBusPatch < mpde->GetNofBusPatches(); ++iBusPatch )
459 Int_t busPatchId = mpde->GetBusPatchId(iBusPatch);
461 AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE);
463 AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
467 for ( Int_t iManu = 0 ;iManu < mpbp->GetNofManus(); ++iManu )
469 Int_t manuId = mpbp->GetManuId(iManu);
471 nch += mpde->NofChannelsInManu(manuId);
473 AliMUONVCalibParam* manu = ManuParam(detElemId,manuId,kTRUE);
475 DispatchValue(*manu,0,rejectList.ManuProbability(detElemId,manuId),0.0,mpde->NofChannelsInManu(manuId));
477 AliMUONVCalibParam* c = ChannelParam(detElemId,manuId);
481 c = new AliMUONCalibParamND(Dimension(),
482 AliMpConstants::ManuNofChannels(),
486 fChannelValues->Add(c);
489 for ( Int_t manuChannel = 0; manuChannel < AliMpConstants::ManuNofChannels(); ++manuChannel )
491 DispatchValue(*c,manuChannel,rejectList.ChannelProbability(detElemId,manuId,manuChannel),0.0,1);
495 DispatchValue(*bp,0,rejectList.BusPatchProbability(busPatchId),0.0,nch);
505 SetDimensionName(0,"RejectProba");
507 UpdateNumberOfEvents(0x0);
510 //_____________________________________________________________________________
511 AliMUONTrackerData::~AliMUONTrackerData()
514 delete fChannelValues;
516 delete fBusPatchValues;
518 delete fChamberValues;
520 delete fDimensionNames;
521 delete fExternalDimensionNames;
522 delete[] fHistogramming;
524 delete[] fNofEventsPerDDL;
527 //_____________________________________________________________________________
529 AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents)
531 /// Add the given external store to our internal store
532 return InternalAdd(store,nevents,kFALSE);
535 //_____________________________________________________________________________
537 AliMUONTrackerData::Add(const AliMUONTrackerData& data)
539 /// Add data to *this
540 // We do this by looping on all VCalibParam stored in the various containers,
541 // and simply adding the values there.
542 // Same thing for the number of events per DDL.
543 // Same thing for sparsehistograms, if we have some.
545 // First cross check we have compatible objects.
547 if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled )
549 AliError("Incompatible IsChannelLevelEnabled status");
553 if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled )
555 AliError("Incompatible IsManuLevelEnabled status");
559 if ( fIsSingleEvent != data.fIsSingleEvent )
561 AliError("Incompatible IsSingleEvent status");
565 if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension )
567 AliError("Incompatible dimensions");
571 if ( fNofDDLs != data.fNofDDLs )
573 AliError("Incompatible number of Ddls");
577 if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming )
578 || fXmin != data.fXmin || fXmax != data.fXmax )
580 AliError(Form("Incompatible histogramming (%p vs %p) (xmax = %e vs %e ; xmin = %e vs %e)",
581 fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
585 if ( fHistogramming )
587 for ( Int_t i = 0; i < fExternalDimension; ++i )
589 if ( fHistogramming[i] != data.fHistogramming[i] )
591 AliError(Form("Incompatible histogramming for external dimension %d",i));
597 // OK. Seems we have compatible objects, so we can proceed with the actual
600 if ( data.fChannelValues )
602 Add2D(*(data.fChannelValues),*fChannelValues);
605 if ( data.fManuValues )
607 Add2D(*(data.fManuValues),*fManuValues);
610 if ( data.fPCBValues )
612 Add2D(*(data.fPCBValues),*fPCBValues);
615 if ( data.fBusPatchValues )
617 Add1D(*(data.fBusPatchValues),*fBusPatchValues);
620 if ( data.fDEValues )
622 Add1D(*(data.fDEValues),*fDEValues);
625 if ( data.fChamberValues )
627 Add1D(*(data.fChamberValues),*fChamberValues);
630 for ( Int_t i = 0; i < fNofDDLs; ++i )
632 fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
637 TIter nexthisto(data.fHistos->CreateIterator());
638 AliMUONVStore* store;
639 while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
641 TIter ns(store->CreateIterator());
642 AliMUONSparseHisto* h;
643 while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
645 AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
649 thisStore = store->Create();
650 thisStore->SetUniqueID(store->GetUniqueID());
651 fHistos->Add(thisStore);
654 AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
668 fNevents = TMath::Max(fNevents,data.fNevents);
673 //_____________________________________________________________________________
675 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
677 /// Add one 2d store to another
679 TIter next(src.CreateIterator());
680 AliMUONVCalibParam* p;
682 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
684 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
688 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
692 AddCalibParams(*p,*a);
697 //_____________________________________________________________________________
699 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
701 /// Add one 1d store to another
703 TIter next(src.CreateIterator());
704 AliMUONVCalibParam* p;
706 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
708 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
712 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
716 AddCalibParams(*p,*a);
721 //_____________________________________________________________________________
723 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
726 for ( Int_t i = 0; i < src.Size(); ++i )
728 for ( Int_t j = 0; j < src.Dimension(); ++j )
730 dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
735 //_____________________________________________________________________________
737 AliMUONTrackerData::Replace(const AliMUONVStore& store)
739 /// Replace our values by values from the given external store
740 Bool_t rv = InternalAdd(store,0x0,kTRUE);
741 AliMUONVTrackerData::Replace(store);
745 //_____________________________________________________________________________
747 AliMUONTrackerData::UpdateNumberOfEvents(TArrayI* nevents)
749 /// Update the number of events
753 fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
754 fNofEventsPerDDL = new Int_t[fNofDDLs];
755 for ( Int_t i = 0; i < fNofDDLs; ++i )
757 fNofEventsPerDDL[i] = 0;
763 if (nevents->GetSize() != fNofDDLs )
765 AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
766 nevents->GetSize(),fNofDDLs));
770 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
772 fNofEventsPerDDL[i] += nevents->At(i);
773 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
778 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
780 ++fNofEventsPerDDL[i];
781 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
787 //_____________________________________________________________________________
789 AliMUONTrackerData::AssertStores()
791 /// Insure our stores are allocated
795 Int_t numberOfBusPatches(0);
796 Int_t numberOfDEs(0);
798 // get number of bus patches and number of detection element
799 // to initialize fBusPatchValues and fDEValues below
801 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
802 while ( next() ) ++numberOfBusPatches;
803 AliMpDEIterator deIt;
805 while (!deIt.IsDone())
811 if ( fIsChannelLevelEnabled )
813 fChannelValues = new AliMUON2DMap(kTRUE);
815 if ( fIsManuLevelEnabled )
817 fManuValues = new AliMUON2DMap(kTRUE);
819 if ( fIsPCBLevelEnabled )
821 fPCBValues = new AliMUON2DMap(kFALSE);
823 if ( fIsBustPatchLevelEnabled )
825 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
827 fDEValues = new AliMUON1DMap(numberOfDEs);
828 fChamberValues = new AliMUON1DArray;
832 //_____________________________________________________________________________
834 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
836 /// Add the given external store to our internal store
838 AliCodeTimerAuto(GetName(),0);
842 if ( IsSingleEvent() && NumberOfEvents(-1) == 1 )
844 AliError(Form("%s is supposed to be single event only",GetName()));
849 UpdateNumberOfEvents(nevents);
853 TIter next(store.CreateIterator());
854 AliMUONVCalibParam* external;
858 if ( IsSingleEvent() ) nk = 1;
860 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
862 if ( external->Dimension() != ExternalDimension() )
864 AliError(Form("Incompatible dimensions %d vs %d",
865 external->Dimension(),ExternalDimension()));
869 AliMUONVCalibParam* chamber(0x0);
870 AliMUONVCalibParam* de(0x0);
871 AliMUONVCalibParam* busPatch(0x0);
872 AliMUONVCalibParam* pcb(0x0);
873 AliMUONVCalibParam* manu(0x0);
874 AliMUONVCalibParam* channel(0x0);
875 AliMpDetElement* mpde(0x0);
877 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
879 if ( manuId < 0 ) continue;
881 Int_t detElemId = mpde->GetId();
883 Double_t value[] = { 0.0, 0.0 };
885 Int_t nch = mpde->NofChannelsInManu(manuId);
887 for ( Int_t i = 0; i < external->Size(); ++i )
889 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
890 : mpde->IsConnectedChannel(manuId,i));
891 // note we only use IsConnectedChannel method when really needed, as
892 // it costs (some) CPU time...
894 if ( existingChannel )
896 Bool_t validChannel(kFALSE);
898 for ( Int_t j = 0; j < external->Dimension(); ++j )
900 Double_t vext = external->IsDoublePrecision() ?
901 external->ValueAsDoubleFast(i,j) :
902 external->ValueAsFloatFast(i,j);
904 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
906 validChannel = kTRUE;
908 Int_t ix = External2Internal(j);
911 value[1] = vext*vext;
913 if ( IsHistogrammed(j) )
915 FillHisto(detElemId,manuId,i,j,vext);
918 for ( Int_t k = 0; k < nk; ++k )
920 Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
924 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
929 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);
932 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
934 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
936 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
940 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
945 if ( validChannel && !replace )
949 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
950 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
955 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
956 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
959 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
960 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
961 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
962 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
963 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
964 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
967 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
968 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
975 NumberOfEventsChanged();
980 //_____________________________________________________________________________
982 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
984 /// Return the value of a given buspatch for a given dimension
985 /// or 0 if not existing
986 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
987 return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
990 //_____________________________________________________________________________
992 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
994 /// Return (if it exist), the VCalibParam for a given busPatch
996 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
997 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
999 if (!busPatch && create && fBusPatchValues)
1001 busPatch = CreateBusPatchParam(busPatchId);
1002 fBusPatchValues->Add(busPatch);
1008 //_____________________________________________________________________________
1010 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
1012 /// Create storage for one bus patch
1014 AliCodeTimerAuto("",0);
1016 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1020 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
1024 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
1026 // set the number of channels in that buspatch
1030 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
1032 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1034 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
1036 Int_t manuId = bp->GetManuId(i);
1037 nchannels += de->NofChannelsInManu(manuId);
1040 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1045 //_____________________________________________________________________________
1047 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
1049 /// Return the value fo a given chamber for a given dimension,
1050 /// or zero if not existing
1052 // FIXME: is the Value() correct wrt to number of events in the case of
1053 // chamber ? Or should we do something custom at the chamber level
1054 // (as it spans several ddls) ?
1056 AliMUONVCalibParam* param = ChamberParam(chamberId);
1057 return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
1060 //_____________________________________________________________________________
1062 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
1064 /// Return (if it exist) the VCalibParam for a given chamber
1066 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
1067 (fChamberValues->FindObject(chamberId)) : 0x0;
1069 if (!chamber && create && fChamberValues)
1071 chamber = CreateChamberParam(chamberId);
1072 fChamberValues->Add(chamber);
1078 //_____________________________________________________________________________
1080 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
1082 /// Create storage for one chamber
1084 AliCodeTimerAuto("",0);
1086 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
1088 // set the number of channels in that chamber
1094 it.First(chamberId);
1096 while ( !it.IsDone() )
1098 AliMpDetElement* det = it.CurrentDE();
1100 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1102 Int_t busPatchId = det->GetBusPatchId(i);
1103 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1104 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1106 Int_t manuId = bp->GetManuId(j);
1107 nchannels += det->NofChannelsInManu(manuId);
1114 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1119 //_____________________________________________________________________________
1121 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
1122 Int_t manuChannel, Int_t dim) const
1124 /// Return the value for a given channel for a given dimension
1126 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
1128 return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1131 //_____________________________________________________________________________
1133 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
1134 const AliMUONVCalibParam* external) const
1136 /// Return (if it exist) the VCalibParam for a given manu
1138 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
1139 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
1141 if (!param && external && fChannelValues)
1143 param = CreateDouble(*external,detElemId,manuId);
1144 fChannelValues->Add(param);
1150 //_____________________________________________________________________________
1152 AliMUONTrackerData::Clear(Option_t*)
1154 /// Clear all the values
1155 if ( fChannelValues ) fChannelValues->Clear();
1156 if ( fManuValues ) fManuValues->Clear();
1157 if ( fBusPatchValues) fBusPatchValues->Clear();
1158 if ( fPCBValues ) fPCBValues->Clear();
1159 if ( fDEValues) fDEValues->Clear();
1160 if ( fChamberValues ) fChamberValues->Clear();
1161 if ( fHistos ) fHistos->Clear();
1162 for ( Int_t i = 0; i < fNofDDLs; ++i )
1164 fNofEventsPerDDL[i] = 0;
1167 NumberOfEventsChanged();
1170 //_____________________________________________________________________________
1172 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
1173 Int_t manuChannel) const
1175 /// Return the number of times a given channel had data
1177 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
1180 //_____________________________________________________________________________
1182 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
1183 Int_t detElemId, Int_t manuId) const
1185 /// Create a double version of VCalibParam, for internal use
1187 AliCodeTimerAuto("",0);
1189 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
1195 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
1197 for ( Int_t i = 0; i < c->Size(); ++i )
1199 Double_t value(0.0);
1201 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
1203 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
1209 //_____________________________________________________________________________
1211 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
1213 /// Return the value for a given detection element for a given dimension
1214 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
1215 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1219 //_____________________________________________________________________________
1221 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
1223 /// Return (if it exist) the VCalibParam for a given detection element
1225 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
1226 (fDEValues->FindObject(detElemId)) : 0x0 ;
1228 if (!de && create && fDEValues)
1230 de = CreateDetectionElementParam(detElemId);
1238 //_____________________________________________________________________________
1240 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
1242 /// Create storage for one detection element
1244 AliCodeTimerAuto("",0);
1246 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
1248 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1251 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1253 Int_t busPatchId = det->GetBusPatchId(i);
1254 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1255 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1257 Int_t manuId = bp->GetManuId(j);
1258 nchannels += det->NofChannelsInManu(manuId);
1262 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1267 //_____________________________________________________________________________
1269 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
1271 /// Get the "local" ddlid (0..19) of a given buspatch
1272 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
1275 return bp->GetDdlId();
1280 //_____________________________________________________________________________
1282 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
1284 /// Get the "local" ddlid (0..19) of a given detection element
1285 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
1288 return de->GetDdlId();
1293 //_____________________________________________________________________________
1295 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
1297 /// Get the "local" ddlid (0..19) of a given chamber
1298 /// This has no real meaning (as there are several ddls per chamber),
1299 /// so we take the ddlid where we got the max number of events
1303 it.First(chamberid);
1307 while (!it.IsDone())
1309 Int_t detElemId = it.CurrentDEId();
1310 Int_t ddlId = DdlIdFromDetElemId(detElemId);
1311 if ( NumberOfEvents(ddlId) > n )
1313 n = NumberOfEvents(ddlId);
1322 //_____________________________________________________________________________
1324 AliMUONTrackerData::DimensionName(Int_t dim) const
1326 /// Get the name of a given dimension
1327 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
1330 return value->String();
1334 return TString("Invalid");
1338 //_____________________________________________________________________________
1340 AliMUONTrackerData::DisableChannelLevel()
1342 /// Disable the storing of data at channel level
1344 delete fChannelValues;
1345 fChannelValues = 0x0;
1346 fIsChannelLevelEnabled = kFALSE;
1349 //_____________________________________________________________________________
1351 AliMUONTrackerData::DisableManuLevel()
1353 /// Disable the storing of data at manu level (and below)
1355 DisableChannelLevel();
1358 fIsManuLevelEnabled = kFALSE;
1361 //_____________________________________________________________________________
1363 AliMUONTrackerData::External2Internal(Int_t index) const
1365 /// From external to internal dimension
1366 return IsSingleEvent() ? index : index*2;
1369 //_____________________________________________________________________________
1371 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
1373 /// Get the name of a given external dimension
1375 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
1378 return value->String();
1382 return TString("Invalid");
1386 //_____________________________________________________________________________
1388 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
1389 Int_t dim, Double_t value)
1391 /// Fill histogram of a given channel
1393 AliMUONSparseHisto* h(0x0);
1395 if ( fIsChannelLevelEnabled )
1397 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
1399 else if ( fIsManuLevelEnabled )
1401 h = GetManuSparseHisto(detElemId,manuId,dim);
1404 AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
1408 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
1412 //_____________________________________________________________________________
1414 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId,
1417 /// Get histogram of a given manu
1419 if (!fHistos) return 0x0;
1421 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1424 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1429 //_____________________________________________________________________________
1431 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
1433 /// Get histogram of a given manu. Create it if necessary
1435 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1437 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1440 m = new AliMUON1DArray(NumberOfDimensions());
1441 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1445 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1448 h = new AliMUONSparseHisto(fXmin,fXmax);
1450 h->SetUniqueID(dim);
1458 //_____________________________________________________________________________
1460 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1461 Int_t manuChannel, Int_t dim) const
1463 /// Get histogram of a given channel
1465 if (!fHistos) return 0x0;
1467 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1470 UInt_t uid = ( manuChannel << 16 ) | dim;
1472 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1477 //_____________________________________________________________________________
1479 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1480 Int_t manuChannel, Int_t dim)
1482 /// Get histogram of a given channel. Create it if necessary
1484 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1486 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1489 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1490 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1494 UInt_t uid = ( manuChannel << 16 ) | dim;
1496 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1499 h = new AliMUONSparseHisto(fXmin,fXmax);
1501 h->SetUniqueID(uid);
1509 //_____________________________________________________________________________
1511 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1512 Int_t& detElemId, Int_t& manuId) const
1514 /// Tries to get (detElemId,manuId) of param
1516 // Load mapping manu store
1517 if ( ! AliMpCDB::LoadManuStore() ) {
1518 AliError("Could not access manu store from OCDB !");
1522 if ( param.ID1() <= 0 )
1524 // we (probably) get a manu serial number
1525 Int_t serial = param.ID0();
1526 MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1527 detElemId = AliMp::PairFirst(pair);
1528 manuId = AliMp::PairSecond(pair);
1531 AliDebug(1,Form("DE %d manuId %d from serial %d is not correct !",
1532 detElemId,manuId,serial));
1537 // we get a (de,manu) pair
1538 detElemId = param.ID0();
1539 manuId = param.ID1();
1544 //_____________________________________________________________________________
1546 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1547 AliMUONVCalibParam*& chamber,
1548 AliMUONVCalibParam*& de,
1549 AliMUONVCalibParam*& busPatch,
1550 AliMUONVCalibParam*& pcb,
1551 AliMUONVCalibParam*& manu,
1552 AliMUONVCalibParam*& channel,
1553 AliMpDetElement*& mpde)
1555 /// Get containers at all levels
1557 chamber = de = busPatch = pcb = manu = channel = 0x0;
1560 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1565 GetDEManu(*external,detElemId,manuId);
1567 mpde = ddlStore->GetDetElement(detElemId,kFALSE);
1569 if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1574 // explicitely check that de,manu is correct
1575 const AliMpVSegmentation* mpseg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId,kFALSE);
1582 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1584 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1586 if ( busPatchId <= 0 )
1591 Int_t pcbIndex = -1;
1593 AliMp::StationType stationType = mpde->GetStationType();
1595 if ( stationType == AliMp::kStation345 )
1597 AliMpDCSNamer namer("TRACKER");
1598 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1601 if ( fIsChannelLevelEnabled )
1603 channel = ChannelParam(detElemId,manuId,external);
1606 manu = ManuParam(detElemId,manuId,kTRUE);
1608 busPatch = BusPatchParam(busPatchId,kTRUE);
1610 de = DetectionElementParam(detElemId,kTRUE);
1612 chamber = ChamberParam(chamberId,kTRUE);
1616 if ( pcbIndex >= 0 )
1618 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1624 //_____________________________________________________________________________
1626 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1628 /// Whether we have data for a given buspatch
1629 return ( BusPatchParam(busPatchId) != 0 );
1632 //_____________________________________________________________________________
1634 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1636 /// Whether we have data for a given chamber
1637 return ( ChamberParam(chamberId) != 0 );
1640 //_____________________________________________________________________________
1642 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1644 /// Whether we have data for a given detection element
1645 return ( DetectionElementParam(detElemId) != 0 );
1648 //_____________________________________________________________________________
1650 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1652 /// Whether we have data for a given manu
1653 return ( ManuParam(detElemId,manuId) != 0 );
1656 //_____________________________________________________________________________
1658 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1660 /// Whether we have data for a given pcb
1661 return ( PCBParam(detElemId,pcbIndex) != 0 );
1664 //_____________________________________________________________________________
1666 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1668 /// Return the value for a given manu and a given dimension
1670 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1671 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1674 //_____________________________________________________________________________
1676 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1678 /// Get the VCalibParam for a given manu
1680 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1681 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1683 if (!manu && create && fManuValues)
1685 manu = CreateManuParam(detElemId,manuId);
1686 fManuValues->Add(manu);
1692 //_____________________________________________________________________________
1694 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1696 /// Create storage for one manu
1698 AliCodeTimerAuto("",0);
1700 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1702 // set the number of channels in that manu
1704 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1706 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1711 //_____________________________________________________________________________
1713 AliMUONTrackerData::Merge(TCollection* list)
1715 /// Merge this with a list of AliMUONVTrackerData
1717 if (!list) return 0;
1719 if ( list->IsEmpty() ) return NumberOfEvents(-1);
1722 const TObject* o(0x0);
1724 while ( ( o = next() ) )
1726 const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1729 AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1734 Bool_t ok = Add(*data);
1737 AliError("Got incompatible objects");
1742 return NumberOfEvents(-1);
1745 //_____________________________________________________________________________
1747 AliMUONTrackerData::NumberOfDimensions() const
1749 /// Number of dimensions we're dealing with
1751 return fDimension + fgkVirtualExtraDimension;
1754 //_____________________________________________________________________________
1756 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1758 /// Get the number of events we've seen for a given DDL, or the max
1759 /// in case ddlNumber<0
1763 if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1765 n = fNofEventsPerDDL[ddlNumber];
1769 // get the max number of events
1776 //_____________________________________________________________________________
1778 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1780 /// Return the value of a given pcb for a given dimension
1782 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1784 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1787 //_____________________________________________________________________________
1789 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1791 /// Return (if it exist) the VCalibParam for a given pcb
1793 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
1794 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1796 if (create && fPCBValues && !pcb)
1798 pcb = CreatePCBParam(detElemId,pcbIndex);
1799 fPCBValues->Add(pcb);
1805 //_____________________________________________________________________________
1807 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1809 /// Create storage for one PCB (station345 only)
1811 AliCodeTimerAuto("",0);
1813 AliMpDCSNamer namer("TRACKER");
1815 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1816 namer.NumberOfPCBs(detElemId),
1823 //_____________________________________________________________________________
1825 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1831 if ( !fIsSingleEvent )
1833 for ( Int_t i = 0; i < fNofDDLs; ++i )
1835 cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1839 if ( !fIsChannelLevelEnabled )
1841 cout << "Is not storing data at the channel level" << endl;
1844 if ( !fIsManuLevelEnabled )
1846 cout << "Is not storing data at the manu level" << endl;
1849 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
1851 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1852 cout << Form("External Dimension %2d Name %s %s",i,
1853 ( name ? name->String().Data() : "null"),
1854 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1857 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
1859 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1860 cout << Form("Internal Dimension %2d Name %s",i,
1861 ( name ? name->String().Data() : "null")) << endl;
1867 if ( sopt.Contains("CHANNEL") )
1869 if ( fIsChannelLevelEnabled )
1871 if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1875 AliWarning("You requested channel values, but they were not stored !");
1879 if ( sopt.Contains("MANU") )
1881 if ( fIsManuLevelEnabled )
1883 if ( fManuValues ) fManuValues->Print(wildcard,opt);
1887 AliWarning("You requested manu values, but they were not stored !");
1891 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
1893 fBusPatchValues->Print(wildcard,opt);
1896 if ( sopt.Contains("DE") && fDEValues )
1898 fDEValues->Print(wildcard,opt);
1901 if ( sopt.Contains("CHAMBER") && fChamberValues )
1903 fChamberValues->Print(wildcard,opt);
1908 //_____________________________________________________________________________
1910 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
1912 /// Set the name of a given dimension
1914 if ( index >= fExternalDimension )
1916 AliError(Form("%s : dimension %s : Index out of bounds : %d / %d",
1918 name,index,fExternalDimension));
1922 Int_t ix = External2Internal(index);
1924 if ( !IsSingleEvent() )
1926 const char* prefix[] = { "mean", "sigma" };
1928 for ( Int_t i = 0; i < 2; ++i )
1932 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
1937 SetInternalDimensionName(index,name);
1940 SetExternalDimensionName(index,name);
1943 //_____________________________________________________________________________
1945 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
1947 /// decide to make histos for a given dimension
1948 if ( index >= ExternalDimension() )
1950 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
1954 AliWarning(Form("Will %s make histogram for data %s index %d : that might ressemble a memory leak depending on the input data",
1955 value ? "":"not", GetName(),index));
1956 fHistogramming[index] = value;
1961 //_____________________________________________________________________________
1963 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
1965 /// Set the name of a given internal dimension
1966 if ( index >= fDimension )
1968 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
1972 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
1976 fDimensionNames->Remove(ovalue);
1979 fDimensionNames->AddAt(new TObjString(value),index);
1982 //_____________________________________________________________________________
1984 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
1986 /// Set the name of a given external dimension
1987 if ( index >= fExternalDimension )
1989 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1993 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
1997 fExternalDimensionNames->Remove(ovalue);
2000 fExternalDimensionNames->AddAt(new TObjString(value),index);
2003 //_____________________________________________________________________________
2005 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i,
2006 Int_t dim, Int_t ddlId) const
2008 /// Compute the value for a given dim, using the internal information we have
2009 /// Basically we're converting sum of weights and sum of squares of weights
2010 /// into means and sigmas, and number of events into occupancy number.
2012 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
2014 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
2016 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
2018 if ( dim >= fDimension )
2023 if ( dim == IndexOfOccupancyDimension() )
2025 if ( ddlId < 0 ) AliError("Got a negative ddl id !");
2026 return occ/n/NumberOfEvents(ddlId);
2029 Double_t value = param.ValueAsDouble(i,dim);
2031 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
2033 if ( TMath::Even(dim) || IsSingleEvent() )
2035 Double_t x = value/occ;
2037 return ( TMath::Finite(x) ? x : 0.0 ) ;
2045 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
2047 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
2055 AliError("Why am I here ?");
2059 //_____________________________________________________________________________
2061 AliMUONTrackerData::Streamer(TBuffer &R__b)
2063 /// Customized streamer
2065 if (R__b.IsReading()) {
2066 AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
2069 // backward compatible mode : we set number of events
2070 // per DDL to the total number of events (the only information
2071 // we had before version 7 of that class)
2072 delete[] fNofEventsPerDDL;
2074 fNofEventsPerDDL = new Int_t[fNofDDLs];
2075 for ( Int_t i = 0; i < fNofDDLs; ++i )
2077 fNofEventsPerDDL[i] = fNevents;
2082 AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
2086 //_____________________________________________________________________________
2088 AliMUONTrackerData::ExportAsASCIIOccupancyFile(const char* filename, Int_t runNumber) const
2090 /// Export only the occupancy part, in a format compatible with what
2091 /// the online occupancy DA is writing
2093 if ( ! AliMpDDLStore::Instance(kFALSE) )
2095 AliError("Mapping not loaded. Cannot work");
2101 AliError("No manu values. Cannot work");
2105 ofstream out(filename);
2109 AliError(Form("Cannot create file %s",filename));
2113 out << "//===========================================================================" << endl;
2114 out << "// Hit counter exported from $Id$" << endl;
2115 out << "//===========================================================================" << endl;
2116 out << "//" << endl;
2117 out << "// * Run Number : " << runNumber << endl;
2118 out << "// * File Creation Date : " << TTimeStamp().AsString("l") << endl;
2119 out << "//---------------------------------------------------------------------------" << endl;
2120 out << "// BP MANU SUM_N NEVENTS" << endl;
2121 out << "//---------------------------------------------------------------------------" << endl;
2123 TIter next(fManuValues->CreateIterator());
2124 AliMUONVCalibParam* manu;
2126 while ( ( manu = static_cast<AliMUONVCalibParam*>(next()) ) )
2128 Int_t detElemId = manu->ID0();
2129 Int_t manuId = manu->ID1();
2130 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
2131 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus( busPatchId);
2132 if ( busPatchId < 0 || ddl < 0 )
2134 AliError(Form("Got invalid (DE,manu,bp,ddl)=(%d,%d,%d,%d). Skipping it",detElemId,manuId,busPatchId,ddl));
2138 Int_t nevents = fNofEventsPerDDL[ddl];
2140 out << Form("%5d %5d %10d %10d",busPatchId,manuId,manu->ValueAsInt(0,IndexOfOccupancyDimension()),nevents) << endl;
2147 //_____________________________________________________________________________
2148 void AliMUONTrackerData::DispatchValue(AliMUONVCalibParam& param,
2154 /// fills the calibparam with a single value
2156 Double_t sumn = 1000.0; // or any value strictly above 1
2157 Double_t sumw = sumn*y;
2158 Double_t sumw2 = (sumn-1)*ey*ey+sumw*sumw/sumn;
2160 param.SetValueAsDouble(index,0,sumw);
2161 param.SetValueAsDouble(index,1,sumw2);
2162 param.SetValueAsDouble(index,2,sumn);
2163 param.SetValueAsDouble(index,3,nchannels);