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
62 ClassImp(AliMUONTrackerData)
65 const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
66 const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
68 //_____________________________________________________________________________
69 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
72 : AliMUONVTrackerData(name,title),
73 fIsSingleEvent(issingleevent),
80 fDimension(External2Internal(dimension)+fgkExtraDimension),
82 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
83 fExternalDimensionNames(new TObjArray(dimension)),
84 fExternalDimension(dimension),
85 fHistogramming(new Int_t[fExternalDimension]),
89 fIsChannelLevelEnabled(kTRUE),
90 fIsManuLevelEnabled(kTRUE),
91 fIsBustPatchLevelEnabled(kTRUE),
92 fIsPCBLevelEnabled(kTRUE),
97 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
98 fExternalDimensionNames->SetOwner(kTRUE);
99 fDimensionNames->SetOwner(kTRUE);
100 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
101 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
102 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
106 //_____________________________________________________________________________
107 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
108 const AliMUONVStore& manuValues)
109 : AliMUONVTrackerData(name,title),
110 fIsSingleEvent(kFALSE),
113 fBusPatchValues(0x0),
119 fDimensionNames(0x0),
120 fExternalDimensionNames(0x0),
121 fExternalDimension(0),
126 fIsChannelLevelEnabled(kFALSE),
127 fIsManuLevelEnabled(kTRUE),
128 fIsBustPatchLevelEnabled(kTRUE),
129 fIsPCBLevelEnabled(kTRUE),
131 fNofEventsPerDDL(0x0)
133 /// ctor with pre-computed values at the manu level
134 /// In this case, we force fIsChannelLevelEnabled = kFALSE
137 if (manuValues.GetSize()==0)
139 AliFatal("Cannot create a tracker data from nothing in that case !");
142 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
144 AliError("Cannot work without (full) mapping");
148 TIter next(manuValues.CreateIterator());
149 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
151 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
153 fDimension = External2Internal(dimension)+fgkExtraDimension;
155 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
156 fExternalDimensionNames = new TObjArray(dimension);
157 fExternalDimension = dimension;
158 fHistogramming = new Int_t[fExternalDimension];
159 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
161 fExternalDimensionNames->SetOwner(kTRUE);
162 fDimensionNames->SetOwner(kTRUE);
163 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
164 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
165 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
167 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
171 AliMUONVCalibParam* external;
173 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
175 Int_t detElemId, manuId;
177 GetDEManu(*external,detElemId,manuId);
179 AliMUONVCalibParam* chamber(0x0);
180 AliMUONVCalibParam* de(0x0);
181 AliMUONVCalibParam* busPatch(0x0);
182 AliMUONVCalibParam* pcb(0x0);
183 AliMUONVCalibParam* manu(0x0);
184 AliMUONVCalibParam* channel(0x0);
185 AliMpDetElement* mpde(0x0);
187 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,manuId,0);
188 // as external, but without event count
189 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
190 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
191 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
192 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
194 Int_t mid = GetParts(wec,chamber,de,busPatch,pcb,manu,channel,mpde);
198 AliError(Form("Something is wrong for DE %5d : manuId = %d vs mid = %d",detElemId,manuId,mid));
204 AliError("Got a < 0 manuId. Should not happen here !");
208 assert(channel==0x0);
210 Int_t n1 = manu->ValueAsInt(0,IndexOfNumberDimension());
211 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
214 AliError(Form("Incoherent number of manu channels for DE %5d MANU %5d : %d vs %d",
215 detElemId,manuId,n1,n2));
218 Int_t nevt = external->ValueAsInt(0,4);
220 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
222 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus(busPatchId);
224 if ( nevents[ddl] == 0 )
230 if ( nevents.At(ddl) != nevt )
232 AliError(Form("Nevt mismatch for DE %5d MANU %5d DDL %d : %d vs %d",
233 detElemId,manuId,ddl,nevents.At(ddl),nevt));
238 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
240 manu->SetValueAsDouble(0,i,manu->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
242 busPatch->SetValueAsDouble(0,i,busPatch->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
244 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
246 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
251 UpdateNumberOfEvents(&nevents);
255 //_____________________________________________________________________________
256 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
257 const AliMUONVStore& deOrBpValues, Int_t val)
258 : AliMUONVTrackerData(name,title),
259 fIsSingleEvent(kFALSE),
262 fBusPatchValues(0x0),
268 fDimensionNames(0x0),
269 fExternalDimensionNames(0x0),
270 fExternalDimension(0),
275 fIsChannelLevelEnabled(kFALSE),
276 fIsManuLevelEnabled(kFALSE),
277 fIsBustPatchLevelEnabled(kFALSE),
278 fIsPCBLevelEnabled(kFALSE),
280 fNofEventsPerDDL(0x0)
282 /// ctor with values at the detection element OR bus patch level
283 /// In this case, we force fIsChannelLevelEnabled = fIsManuLevelEnabled = kFALSE
286 if (deOrBpValues.GetSize()==0)
288 AliFatal("Cannot create a tracker data from nothing in that case !");
291 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
293 AliError("Cannot work without (full) mapping");
299 BuildFromDEStore(deOrBpValues);
303 BuildFromBPStore(deOrBpValues);
307 AliFatal("Wrong parameter. Must be 1 or 2");
313 //_____________________________________________________________________________
314 void AliMUONTrackerData::BuildFromDEStore(const AliMUONVStore& deValues)
316 /// Fill internals from a store of values at the detection element level
318 TIter next(deValues.CreateIterator());
319 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
321 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
323 fDimension = External2Internal(dimension)+fgkExtraDimension;
325 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
326 fExternalDimensionNames = new TObjArray(dimension);
327 fExternalDimension = dimension;
328 fHistogramming = new Int_t[fExternalDimension];
329 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
331 fExternalDimensionNames->SetOwner(kTRUE);
332 fDimensionNames->SetOwner(kTRUE);
333 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
334 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
335 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
337 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
341 AliMUONVCalibParam* external;
343 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
345 Int_t detElemId = external->ID0();
347 AliMpDetElement* mpde = AliMpDDLStore::Instance()->GetDetElement(detElemId,kFALSE);
351 AliError(Form("Got an invalid DE (%d) from external store",detElemId));
355 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
356 AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
357 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
359 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,0,0);
360 // as external, but without event count
361 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
362 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
363 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
364 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
366 Int_t n1 = de->ValueAsInt(0,IndexOfNumberDimension());
367 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
370 AliError(Form("Incoherent number of dimensions for DE%d : %d vs %d",
375 Int_t nevt = external->ValueAsInt(0,4);
377 Int_t ddl = mpde->GetDdlId();
379 if ( nevents[ddl] == 0 )
385 if ( nevents.At(ddl) != nevt )
387 AliError(Form("Nevt mismatch for DE %5d DDL %d : %d vs %d",
388 detElemId,ddl,nevents.At(ddl),nevt));
393 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
395 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
397 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
402 UpdateNumberOfEvents(&nevents);
405 //_____________________________________________________________________________
406 void AliMUONTrackerData::BuildFromBPStore(const AliMUONVStore& bpValues)
408 /// Fill internals from a store of values at the bus patch level
410 fIsBustPatchLevelEnabled = kTRUE;
412 TIter next(bpValues.CreateIterator());
413 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
415 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
417 fDimension = External2Internal(dimension)+fgkExtraDimension;
419 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
420 fExternalDimensionNames = new TObjArray(dimension);
421 fExternalDimension = dimension;
422 fHistogramming = new Int_t[fExternalDimension];
423 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
425 fExternalDimensionNames->SetOwner(kTRUE);
426 fDimensionNames->SetOwner(kTRUE);
427 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
428 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
429 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
431 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
435 AliMUONVCalibParam* external;
437 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
439 Int_t busPatchId = external->ID0();
441 AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId,kFALSE);
445 AliError(Form("Got an invalid buspatchId (%d) from external store",busPatchId));
449 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
450 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
451 AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
452 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
453 AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE);
455 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,busPatchId,0,0);
456 // as external, but without event count
457 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
458 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
459 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
460 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
462 Int_t n1 = bp->ValueAsInt(0,IndexOfNumberDimension());
463 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
466 AliError(Form("Incoherent number of dimensions for BP%d : %d vs %d",
471 Int_t nevt = external->ValueAsInt(0,4);
473 Int_t ddl = mpbp->GetDdlId();
475 if ( nevents[ddl] == 0 )
481 if ( nevents.At(ddl) != nevt )
483 AliError(Form("Nevt mismatch for BP %5d DDL %d : %d vs %d",
484 busPatchId,ddl,nevents.At(ddl),nevt));
489 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
491 bp->SetValueAsDouble(0,i,bp->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
493 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
495 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
500 UpdateNumberOfEvents(&nevents);
503 //_____________________________________________________________________________
504 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
505 const AliMUONRejectList& rejectList)
506 : AliMUONVTrackerData(name,title),
507 fIsSingleEvent(kFALSE),
510 fBusPatchValues(0x0),
514 fDimension(External2Internal(1)+fgkExtraDimension),
516 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
517 fExternalDimensionNames(new TObjArray(1)),
518 fExternalDimension(1),
519 fHistogramming(new Int_t[fExternalDimension]),
523 fIsChannelLevelEnabled(kTRUE),
524 fIsManuLevelEnabled(kTRUE),
525 fIsBustPatchLevelEnabled(kTRUE),
526 fIsPCBLevelEnabled(kFALSE),
528 fNofEventsPerDDL(0x0)
531 /// ctor with values from the given rejectlist
533 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
535 AliError("Cannot work without (full) mapping");
539 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
541 fExternalDimensionNames->SetOwner(kTRUE);
542 fDimensionNames->SetOwner(kTRUE);
543 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
544 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
545 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
547 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
551 for ( Int_t chamberId = 0; chamberId < AliMpConstants::NofChambers(); ++chamberId )
553 // AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
555 // FIXME : update the chamber value ?
557 AliMpDEIterator deit;
559 deit.First(chamberId);
561 while ( !deit.IsDone() )
563 AliMpDetElement* mpde = deit.CurrentDE();
565 Int_t detElemId = mpde->GetId();
567 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
569 DispatchValue(*de,0,rejectList.DetectionElementProbability(detElemId),0.0,mpde->NofChannels());
571 for ( Int_t iBusPatch = 0; iBusPatch < mpde->GetNofBusPatches(); ++iBusPatch )
573 Int_t busPatchId = mpde->GetBusPatchId(iBusPatch);
575 AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE);
577 AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
581 for ( Int_t iManu = 0 ;iManu < mpbp->GetNofManus(); ++iManu )
583 Int_t manuId = mpbp->GetManuId(iManu);
585 nch += mpde->NofChannelsInManu(manuId);
587 AliMUONVCalibParam* manu = ManuParam(detElemId,manuId,kTRUE);
589 DispatchValue(*manu,0,rejectList.ManuProbability(detElemId,manuId),0.0,mpde->NofChannelsInManu(manuId));
591 AliMUONVCalibParam* c = ChannelParam(detElemId,manuId);
595 c = new AliMUONCalibParamND(Dimension(),
596 AliMpConstants::ManuNofChannels(),
600 fChannelValues->Add(c);
603 for ( Int_t manuChannel = 0; manuChannel < AliMpConstants::ManuNofChannels(); ++manuChannel )
605 DispatchValue(*c,manuChannel,rejectList.ChannelProbability(detElemId,manuId,manuChannel),0.0,1);
609 DispatchValue(*bp,0,rejectList.BusPatchProbability(busPatchId),0.0,nch);
619 SetDimensionName(0,"RejectProba");
621 UpdateNumberOfEvents(0x0);
624 //_____________________________________________________________________________
625 AliMUONTrackerData::~AliMUONTrackerData()
628 delete fChannelValues;
630 delete fBusPatchValues;
632 delete fChamberValues;
634 delete fDimensionNames;
635 delete fExternalDimensionNames;
636 delete[] fHistogramming;
638 delete[] fNofEventsPerDDL;
641 //_____________________________________________________________________________
643 AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents)
645 /// Add the given external store to our internal store
646 return InternalAdd(store,nevents,kFALSE);
649 //_____________________________________________________________________________
651 AliMUONTrackerData::Add(const AliMUONTrackerData& data)
653 /// Add data to *this
654 // We do this by looping on all VCalibParam stored in the various containers,
655 // and simply adding the values there.
656 // Same thing for the number of events per DDL.
657 // Same thing for sparsehistograms, if we have some.
659 // First cross check we have compatible objects.
661 AliCodeTimerAuto("",0);
663 if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled )
665 AliError("Incompatible IsChannelLevelEnabled status");
669 if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled )
671 AliError("Incompatible IsManuLevelEnabled status");
675 if ( fIsSingleEvent != data.fIsSingleEvent )
677 AliError("Incompatible IsSingleEvent status");
681 if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension )
683 AliError("Incompatible dimensions");
687 if ( fNofDDLs != data.fNofDDLs )
689 AliError("Incompatible number of Ddls");
693 if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming )
694 || fXmin != data.fXmin || fXmax != data.fXmax )
696 AliError(Form("Incompatible histogramming (%p vs %p) (xmax = %e vs %e ; xmin = %e vs %e)",
697 fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
701 if ( fHistogramming )
703 for ( Int_t i = 0; i < fExternalDimension; ++i )
705 if ( fHistogramming[i] != data.fHistogramming[i] )
707 AliError(Form("Incompatible histogramming for external dimension %d",i));
713 // OK. Seems we have compatible objects, so we can proceed with the actual
716 if ( data.fChannelValues )
718 Add2D(*(data.fChannelValues),*fChannelValues);
721 if ( data.fManuValues )
723 Add2D(*(data.fManuValues),*fManuValues);
726 if ( data.fPCBValues )
728 Add2D(*(data.fPCBValues),*fPCBValues);
731 if ( data.fBusPatchValues )
733 Add1D(*(data.fBusPatchValues),*fBusPatchValues);
736 if ( data.fDEValues )
738 Add1D(*(data.fDEValues),*fDEValues);
741 if ( data.fChamberValues )
743 Add1D(*(data.fChamberValues),*fChamberValues);
746 for ( Int_t i = 0; i < fNofDDLs; ++i )
748 fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
753 TIter nexthisto(data.fHistos->CreateIterator());
754 AliMUONVStore* store;
755 while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
757 TIter ns(store->CreateIterator());
758 AliMUONSparseHisto* h;
759 while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
761 AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
765 thisStore = store->Create();
766 thisStore->SetUniqueID(store->GetUniqueID());
767 fHistos->Add(thisStore);
770 AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
784 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
786 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
792 //_____________________________________________________________________________
794 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
796 /// Add one 2d store to another
798 TIter next(src.CreateIterator());
799 AliMUONVCalibParam* p;
801 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
803 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
807 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
811 AddCalibParams(*p,*a);
816 //_____________________________________________________________________________
818 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
820 /// Add one 1d store to another
822 TIter next(src.CreateIterator());
823 AliMUONVCalibParam* p;
825 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
827 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
831 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
835 AddCalibParams(*p,*a);
840 //_____________________________________________________________________________
842 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
845 for ( Int_t i = 0; i < src.Size(); ++i )
847 for ( Int_t j = 0; j < src.Dimension(); ++j )
849 dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
854 //_____________________________________________________________________________
856 AliMUONTrackerData::Replace(const AliMUONVStore& store)
858 /// Replace our values by values from the given external store
859 Bool_t rv = InternalAdd(store,0x0,kTRUE);
860 AliMUONVTrackerData::Replace(store);
864 //_____________________________________________________________________________
866 AliMUONTrackerData::UpdateNumberOfEvents(TArrayI* nevents)
868 /// Update the number of events
872 fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
873 fNofEventsPerDDL = new Int_t[fNofDDLs];
874 for ( Int_t i = 0; i < fNofDDLs; ++i )
876 fNofEventsPerDDL[i] = 0;
882 if (nevents->GetSize() != fNofDDLs )
884 AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
885 nevents->GetSize(),fNofDDLs));
889 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
891 fNofEventsPerDDL[i] += nevents->At(i);
892 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
897 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
899 ++fNofEventsPerDDL[i];
900 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
906 //_____________________________________________________________________________
908 AliMUONTrackerData::AssertStores()
910 /// Insure our stores are allocated
914 Int_t numberOfBusPatches(0);
915 Int_t numberOfDEs(0);
917 // get number of bus patches and number of detection element
918 // to initialize fBusPatchValues and fDEValues below
920 if (!AliMpDDLStore::Instance(false))
925 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
926 while ( next() ) ++numberOfBusPatches;
927 AliMpDEIterator deIt;
929 while (!deIt.IsDone())
935 if ( fIsChannelLevelEnabled )
937 fChannelValues = new AliMUON2DMap(kTRUE);
939 if ( fIsManuLevelEnabled )
941 fManuValues = new AliMUON2DMap(kTRUE);
943 if ( fIsPCBLevelEnabled )
945 fPCBValues = new AliMUON2DMap(kFALSE);
947 if ( fIsBustPatchLevelEnabled )
949 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
951 fDEValues = new AliMUON1DMap(numberOfDEs);
952 fChamberValues = new AliMUON1DArray;
956 //_____________________________________________________________________________
958 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
960 /// Add the given external store to our internal store
962 AliCodeTimerAuto(GetName(),0);
966 if ( IsSingleEvent() && NumberOfEvents(-1) == 1 )
968 AliError(Form("%s is supposed to be single event only",GetName()));
973 UpdateNumberOfEvents(nevents);
977 TIter next(store.CreateIterator());
978 AliMUONVCalibParam* external;
982 if ( IsSingleEvent() ) nk = 1;
984 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
986 if ( external->Dimension() != ExternalDimension() )
988 AliError(Form("Incompatible dimensions %d vs %d",
989 external->Dimension(),ExternalDimension()));
993 AliMUONVCalibParam* chamber(0x0);
994 AliMUONVCalibParam* de(0x0);
995 AliMUONVCalibParam* busPatch(0x0);
996 AliMUONVCalibParam* pcb(0x0);
997 AliMUONVCalibParam* manu(0x0);
998 AliMUONVCalibParam* channel(0x0);
999 AliMpDetElement* mpde(0x0);
1001 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
1003 if ( manuId < 0 ) continue;
1005 Int_t detElemId = mpde->GetId();
1007 Double_t value[] = { 0.0, 0.0 };
1009 Int_t nch = mpde->NofChannelsInManu(manuId);
1011 for ( Int_t i = 0; i < external->Size(); ++i )
1013 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
1014 : mpde->IsConnectedChannel(manuId,i));
1015 // note we only use IsConnectedChannel method when really needed, as
1016 // it costs (some) CPU time...
1018 if ( existingChannel )
1020 Bool_t validChannel(kFALSE);
1022 for ( Int_t j = 0; j < external->Dimension(); ++j )
1024 Double_t vext = external->IsDoublePrecision() ?
1025 external->ValueAsDoubleFast(i,j) :
1026 external->ValueAsFloatFast(i,j);
1028 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
1030 validChannel = kTRUE;
1032 Int_t ix = External2Internal(j);
1035 value[1] = vext*vext;
1037 if ( IsHistogrammed(j) )
1039 FillHisto(detElemId,manuId,i,j,vext);
1042 for ( Int_t k = 0; k < nk; ++k )
1044 Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
1048 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
1053 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1056 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1058 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1060 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1064 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1069 if ( validChannel && !replace )
1073 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
1074 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
1079 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1080 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1083 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1084 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1085 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1086 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1087 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1088 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1091 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1092 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1099 NumberOfEventsChanged();
1104 //_____________________________________________________________________________
1106 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
1108 /// Return the value of a given buspatch for a given dimension
1109 /// or 0 if not existing
1110 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
1111 return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
1114 //_____________________________________________________________________________
1116 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
1118 /// Return (if it exist), the VCalibParam for a given busPatch
1120 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
1121 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
1123 if (!busPatch && create && fBusPatchValues)
1125 busPatch = CreateBusPatchParam(busPatchId);
1126 fBusPatchValues->Add(busPatch);
1132 //_____________________________________________________________________________
1134 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
1136 /// Create storage for one bus patch
1138 AliCodeTimerAuto("",0);
1140 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1144 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
1148 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
1150 // set the number of channels in that buspatch
1154 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
1156 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1158 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
1160 Int_t manuId = bp->GetManuId(i);
1161 nchannels += de->NofChannelsInManu(manuId);
1164 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1169 //_____________________________________________________________________________
1171 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
1173 /// Return the value fo a given chamber for a given dimension,
1174 /// or zero if not existing
1176 // FIXME: is the Value() correct wrt to number of events in the case of
1177 // chamber ? Or should we do something custom at the chamber level
1178 // (as it spans several ddls) ?
1180 AliMUONVCalibParam* param = ChamberParam(chamberId);
1181 return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
1184 //_____________________________________________________________________________
1186 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
1188 /// Return (if it exist) the VCalibParam for a given chamber
1190 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
1191 (fChamberValues->FindObject(chamberId)) : 0x0;
1193 if (!chamber && create && fChamberValues)
1195 chamber = CreateChamberParam(chamberId);
1196 fChamberValues->Add(chamber);
1202 //_____________________________________________________________________________
1204 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
1206 /// Create storage for one chamber
1208 AliCodeTimerAuto("",0);
1210 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
1212 // set the number of channels in that chamber
1218 it.First(chamberId);
1220 while ( !it.IsDone() )
1222 AliMpDetElement* det = it.CurrentDE();
1224 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1226 Int_t busPatchId = det->GetBusPatchId(i);
1227 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1228 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1230 Int_t manuId = bp->GetManuId(j);
1231 nchannels += det->NofChannelsInManu(manuId);
1238 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1243 //_____________________________________________________________________________
1245 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
1246 Int_t manuChannel, Int_t dim) const
1248 /// Return the value for a given channel for a given dimension
1250 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
1252 return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1255 //_____________________________________________________________________________
1257 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
1258 const AliMUONVCalibParam* external) const
1260 /// Return (if it exist) the VCalibParam for a given manu
1262 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
1263 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
1265 if (!param && external && fChannelValues)
1267 param = CreateDouble(*external,detElemId,manuId);
1268 fChannelValues->Add(param);
1274 //_____________________________________________________________________________
1276 AliMUONTrackerData::Clear(Option_t*)
1278 /// Clear all the values
1279 if ( fChannelValues ) fChannelValues->Clear();
1280 if ( fManuValues ) fManuValues->Clear();
1281 if ( fBusPatchValues) fBusPatchValues->Clear();
1282 if ( fPCBValues ) fPCBValues->Clear();
1283 if ( fDEValues) fDEValues->Clear();
1284 if ( fChamberValues ) fChamberValues->Clear();
1285 if ( fHistos ) fHistos->Clear();
1286 for ( Int_t i = 0; i < fNofDDLs; ++i )
1288 fNofEventsPerDDL[i] = 0;
1291 NumberOfEventsChanged();
1294 //_____________________________________________________________________________
1296 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
1297 Int_t manuChannel) const
1299 /// Return the number of times a given channel had data
1301 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
1304 //_____________________________________________________________________________
1306 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
1307 Int_t detElemId, Int_t manuId) const
1309 /// Create a double version of VCalibParam, for internal use
1311 AliCodeTimerAuto("",0);
1313 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
1319 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
1321 for ( Int_t i = 0; i < c->Size(); ++i )
1323 Double_t value(0.0);
1325 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
1327 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
1333 //_____________________________________________________________________________
1335 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
1337 /// Return the value for a given detection element for a given dimension
1338 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
1339 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1343 //_____________________________________________________________________________
1345 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
1347 /// Return (if it exist) the VCalibParam for a given detection element
1349 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
1350 (fDEValues->FindObject(detElemId)) : 0x0 ;
1352 if (!de && create && fDEValues)
1354 de = CreateDetectionElementParam(detElemId);
1362 //_____________________________________________________________________________
1364 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
1366 /// Create storage for one detection element
1368 AliCodeTimerAuto("",0);
1370 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
1372 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1375 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1377 Int_t busPatchId = det->GetBusPatchId(i);
1378 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1379 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1381 Int_t manuId = bp->GetManuId(j);
1382 nchannels += det->NofChannelsInManu(manuId);
1386 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1391 //_____________________________________________________________________________
1393 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
1395 /// Get the "local" ddlid (0..19) of a given buspatch
1396 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
1399 return bp->GetDdlId();
1404 //_____________________________________________________________________________
1406 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
1408 /// Get the "local" ddlid (0..19) of a given detection element
1409 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
1412 return de->GetDdlId();
1417 //_____________________________________________________________________________
1419 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
1421 /// Get the "local" ddlid (0..19) of a given chamber
1422 /// This has no real meaning (as there are several ddls per chamber),
1423 /// so we take the ddlid where we got the max number of events
1427 it.First(chamberid);
1431 while (!it.IsDone())
1433 Int_t detElemId = it.CurrentDEId();
1434 Int_t ddlId = DdlIdFromDetElemId(detElemId);
1435 if ( NumberOfEvents(ddlId) > n )
1437 n = NumberOfEvents(ddlId);
1446 //_____________________________________________________________________________
1448 AliMUONTrackerData::DimensionName(Int_t dim) const
1450 /// Get the name of a given dimension
1451 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
1454 return value->String();
1458 return TString("Invalid");
1462 //_____________________________________________________________________________
1464 AliMUONTrackerData::DisableChannelLevel()
1466 /// Disable the storing of data at channel level
1468 delete fChannelValues;
1469 fChannelValues = 0x0;
1470 fIsChannelLevelEnabled = kFALSE;
1473 //_____________________________________________________________________________
1475 AliMUONTrackerData::DisableManuLevel()
1477 /// Disable the storing of data at manu level (and below)
1479 DisableChannelLevel();
1482 fIsManuLevelEnabled = kFALSE;
1485 //_____________________________________________________________________________
1487 AliMUONTrackerData::External2Internal(Int_t index) const
1489 /// From external to internal dimension
1490 return IsSingleEvent() ? index : index*2;
1493 //_____________________________________________________________________________
1495 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
1497 /// Get the name of a given external dimension
1499 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
1502 return value->String();
1506 return TString("Invalid");
1510 //_____________________________________________________________________________
1512 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
1513 Int_t dim, Double_t value)
1515 /// Fill histogram of a given channel
1517 AliMUONSparseHisto* h(0x0);
1519 if ( fIsChannelLevelEnabled )
1521 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
1523 else if ( fIsManuLevelEnabled )
1525 h = GetManuSparseHisto(detElemId,manuId,dim);
1528 AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
1532 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
1536 //_____________________________________________________________________________
1538 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId,
1541 /// Get histogram of a given manu
1543 if (!fHistos) return 0x0;
1545 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1548 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1553 //_____________________________________________________________________________
1555 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
1557 /// Get histogram of a given manu. Create it if necessary
1559 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1561 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1564 m = new AliMUON1DArray(NumberOfDimensions());
1565 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1569 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1572 h = new AliMUONSparseHisto(fXmin,fXmax);
1574 h->SetUniqueID(dim);
1582 //_____________________________________________________________________________
1584 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1585 Int_t manuChannel, Int_t dim) const
1587 /// Get histogram of a given channel
1589 if (!fHistos) return 0x0;
1591 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1594 UInt_t uid = ( manuChannel << 16 ) | dim;
1596 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1601 //_____________________________________________________________________________
1603 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1604 Int_t manuChannel, Int_t dim)
1606 /// Get histogram of a given channel. Create it if necessary
1608 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1610 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1613 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1614 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1618 UInt_t uid = ( manuChannel << 16 ) | dim;
1620 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1623 h = new AliMUONSparseHisto(fXmin,fXmax);
1625 h->SetUniqueID(uid);
1633 //_____________________________________________________________________________
1635 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1636 Int_t& detElemId, Int_t& manuId) const
1638 /// Tries to get (detElemId,manuId) of param
1640 // Load mapping manu store
1641 if ( ! AliMpCDB::LoadManuStore() ) {
1642 AliError("Could not access manu store from OCDB !");
1646 if ( param.ID1() <= 0 )
1648 // we (probably) get a manu serial number
1649 Int_t serial = param.ID0();
1650 MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1651 detElemId = AliMp::PairFirst(pair);
1652 manuId = AliMp::PairSecond(pair);
1655 AliDebug(1,Form("DE %d manuId %d from serial %d is not correct !",
1656 detElemId,manuId,serial));
1661 // we get a (de,manu) pair
1662 detElemId = param.ID0();
1663 manuId = param.ID1();
1668 //_____________________________________________________________________________
1670 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1671 AliMUONVCalibParam*& chamber,
1672 AliMUONVCalibParam*& de,
1673 AliMUONVCalibParam*& busPatch,
1674 AliMUONVCalibParam*& pcb,
1675 AliMUONVCalibParam*& manu,
1676 AliMUONVCalibParam*& channel,
1677 AliMpDetElement*& mpde)
1679 /// Get containers at all levels
1681 chamber = de = busPatch = pcb = manu = channel = 0x0;
1684 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1689 GetDEManu(*external,detElemId,manuId);
1691 mpde = ddlStore->GetDetElement(detElemId,kFALSE);
1693 if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1698 // explicitely check that de,manu is correct
1699 const AliMpVSegmentation* mpseg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId,kFALSE);
1706 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1708 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1710 if ( busPatchId <= 0 )
1715 Int_t pcbIndex = -1;
1717 AliMp::StationType stationType = mpde->GetStationType();
1719 if ( stationType == AliMp::kStation345 )
1721 AliMpDCSNamer namer("TRACKER");
1722 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1725 if ( fIsChannelLevelEnabled )
1727 channel = ChannelParam(detElemId,manuId,external);
1730 manu = ManuParam(detElemId,manuId,kTRUE);
1732 busPatch = BusPatchParam(busPatchId,kTRUE);
1734 de = DetectionElementParam(detElemId,kTRUE);
1736 chamber = ChamberParam(chamberId,kTRUE);
1740 if ( pcbIndex >= 0 )
1742 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1748 //_____________________________________________________________________________
1750 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1752 /// Whether we have data for a given buspatch
1753 return ( BusPatchParam(busPatchId) != 0 );
1756 //_____________________________________________________________________________
1758 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1760 /// Whether we have data for a given chamber
1761 return ( ChamberParam(chamberId) != 0 );
1764 //_____________________________________________________________________________
1766 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1768 /// Whether we have data for a given detection element
1769 return ( DetectionElementParam(detElemId) != 0 );
1772 //_____________________________________________________________________________
1774 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1776 /// Whether we have data for a given manu
1777 return ( ManuParam(detElemId,manuId) != 0 );
1780 //_____________________________________________________________________________
1782 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1784 /// Whether we have data for a given pcb
1785 return ( PCBParam(detElemId,pcbIndex) != 0 );
1788 //_____________________________________________________________________________
1790 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1792 /// Return the value for a given manu and a given dimension
1794 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1795 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1798 //_____________________________________________________________________________
1800 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1802 /// Get the VCalibParam for a given manu
1804 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1805 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1807 if (!manu && create && fManuValues)
1809 manu = CreateManuParam(detElemId,manuId);
1810 fManuValues->Add(manu);
1816 //_____________________________________________________________________________
1818 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1820 /// Create storage for one manu
1822 AliCodeTimerAuto("",0);
1824 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1826 // set the number of channels in that manu
1828 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1830 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1835 //_____________________________________________________________________________
1837 AliMUONTrackerData::Merge(TCollection* list)
1839 /// Merge this with a list of AliMUONVTrackerData
1841 if (!list) return 0;
1843 if ( list->IsEmpty() ) return NumberOfEvents(-1);
1846 const TObject* o(0x0);
1848 while ( ( o = next() ) )
1850 const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1853 AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1858 Bool_t ok = Add(*data);
1861 AliError("Got incompatible objects");
1866 return NumberOfEvents(-1);
1869 //_____________________________________________________________________________
1871 AliMUONTrackerData::NumberOfDimensions() const
1873 /// Number of dimensions we're dealing with
1875 return fDimension + fgkVirtualExtraDimension;
1878 //_____________________________________________________________________________
1880 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1882 /// Get the number of events we've seen for a given DDL, or the max
1883 /// in case ddlNumber<0
1887 if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1889 n = fNofEventsPerDDL[ddlNumber];
1893 // get the max number of events
1900 //_____________________________________________________________________________
1902 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1904 /// Return the value of a given pcb for a given dimension
1906 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1908 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1911 //_____________________________________________________________________________
1913 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1915 /// Return (if it exist) the VCalibParam for a given pcb
1917 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
1918 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1920 if (create && fPCBValues && !pcb)
1922 pcb = CreatePCBParam(detElemId,pcbIndex);
1923 fPCBValues->Add(pcb);
1929 //_____________________________________________________________________________
1931 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1933 /// Create storage for one PCB (station345 only)
1935 AliCodeTimerAuto("",0);
1937 AliMpDCSNamer namer("TRACKER");
1939 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1940 namer.NumberOfPCBs(detElemId),
1947 //_____________________________________________________________________________
1949 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1955 if ( !fIsSingleEvent )
1957 for ( Int_t i = 0; i < fNofDDLs; ++i )
1959 cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1963 if ( !fIsChannelLevelEnabled )
1965 cout << "Is not storing data at the channel level" << endl;
1968 if ( !fIsManuLevelEnabled )
1970 cout << "Is not storing data at the manu level" << endl;
1973 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
1975 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1976 cout << Form("External Dimension %2d Name %s %s",i,
1977 ( name ? name->String().Data() : "null"),
1978 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1981 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
1983 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1984 cout << Form("Internal Dimension %2d Name %s",i,
1985 ( name ? name->String().Data() : "null")) << endl;
1991 if ( sopt.Contains("CHANNEL") )
1993 if ( fIsChannelLevelEnabled )
1995 if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1999 AliWarning("You requested channel values, but they were not stored !");
2003 if ( sopt.Contains("MANU") )
2005 if ( fIsManuLevelEnabled )
2007 if ( fManuValues ) fManuValues->Print(wildcard,opt);
2011 AliWarning("You requested manu values, but they were not stored !");
2015 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
2017 fBusPatchValues->Print(wildcard,opt);
2020 if ( sopt.Contains("DE") && fDEValues )
2022 fDEValues->Print(wildcard,opt);
2025 if ( sopt.Contains("CHAMBER") && fChamberValues )
2027 fChamberValues->Print(wildcard,opt);
2032 //_____________________________________________________________________________
2034 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
2036 /// Set the name of a given dimension
2038 if ( index >= fExternalDimension )
2040 AliError(Form("%s : dimension %s : Index out of bounds : %d / %d",
2042 name,index,fExternalDimension));
2046 Int_t ix = External2Internal(index);
2048 if ( !IsSingleEvent() )
2050 const char* prefix[] = { "mean", "sigma" };
2052 for ( Int_t i = 0; i < 2; ++i )
2056 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
2061 SetInternalDimensionName(index,name);
2064 SetExternalDimensionName(index,name);
2067 //_____________________________________________________________________________
2069 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
2071 /// decide to make histos for a given dimension
2072 if ( index >= ExternalDimension() )
2074 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
2078 AliWarning(Form("Will %s make histogram for data %s index %d : that might ressemble a memory leak depending on the input data",
2079 value ? "":"not", GetName(),index));
2080 fHistogramming[index] = value;
2085 //_____________________________________________________________________________
2087 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
2089 /// Set the name of a given internal dimension
2090 if ( index >= fDimension )
2092 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
2096 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
2100 fDimensionNames->Remove(ovalue);
2103 fDimensionNames->AddAt(new TObjString(value),index);
2106 //_____________________________________________________________________________
2108 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
2110 /// Set the name of a given external dimension
2111 if ( index >= fExternalDimension )
2113 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
2117 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
2121 fExternalDimensionNames->Remove(ovalue);
2124 fExternalDimensionNames->AddAt(new TObjString(value),index);
2127 //_____________________________________________________________________________
2129 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i,
2130 Int_t dim, Int_t ddlId) const
2132 /// Compute the value for a given dim, using the internal information we have
2133 /// Basically we're converting sum of weights and sum of squares of weights
2134 /// into means and sigmas, and number of events into occupancy number.
2136 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
2138 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
2140 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
2142 if ( dim >= fDimension )
2147 if ( dim == IndexOfOccupancyDimension() )
2149 if ( ddlId < 0 ) AliError("Got a negative ddl id !");
2150 return occ/n/NumberOfEvents(ddlId);
2153 Double_t value = param.ValueAsDouble(i,dim);
2155 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
2157 if ( TMath::Even(dim) || IsSingleEvent() )
2159 Double_t x = value/occ;
2161 return ( TMath::Finite(x) ? x : 0.0 ) ;
2169 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
2171 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
2179 AliError("Why am I here ?");
2183 //_____________________________________________________________________________
2185 AliMUONTrackerData::Streamer(TBuffer &R__b)
2187 /// Customized streamer
2189 if (R__b.IsReading()) {
2190 AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
2193 // backward compatible mode : we set number of events
2194 // per DDL to the total number of events (the only information
2195 // we had before version 7 of that class)
2196 delete[] fNofEventsPerDDL;
2198 fNofEventsPerDDL = new Int_t[fNofDDLs];
2199 for ( Int_t i = 0; i < fNofDDLs; ++i )
2201 fNofEventsPerDDL[i] = fNevents;
2206 AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
2210 //_____________________________________________________________________________
2212 AliMUONTrackerData::ExportAsASCIIOccupancyFile(const char* filename, Int_t runNumber) const
2214 /// Export only the occupancy part, in a format compatible with what
2215 /// the online occupancy DA is writing
2217 if ( ! AliMpDDLStore::Instance(kFALSE) )
2219 AliError("Mapping not loaded. Cannot work");
2225 AliError("No manu values. Cannot work");
2229 ofstream out(filename);
2233 AliError(Form("Cannot create file %s",filename));
2237 out << "//===========================================================================" << endl;
2238 out << "// Hit counter exported from $Id$" << endl;
2239 out << "//===========================================================================" << endl;
2240 out << "//" << endl;
2241 out << "// * Run Number : " << runNumber << endl;
2242 out << "// * File Creation Date : " << TTimeStamp().AsString("l") << endl;
2243 out << "//---------------------------------------------------------------------------" << endl;
2244 out << "// BP MANU SUM_N NEVENTS" << endl;
2245 out << "//---------------------------------------------------------------------------" << endl;
2247 TIter next(fManuValues->CreateIterator());
2248 AliMUONVCalibParam* manu;
2250 while ( ( manu = static_cast<AliMUONVCalibParam*>(next()) ) )
2252 Int_t detElemId = manu->ID0();
2253 Int_t manuId = manu->ID1();
2254 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
2255 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus( busPatchId);
2256 if ( busPatchId < 0 || ddl < 0 )
2258 AliError(Form("Got invalid (DE,manu,bp,ddl)=(%d,%d,%d,%d). Skipping it",detElemId,manuId,busPatchId,ddl));
2262 Int_t nevents = fNofEventsPerDDL[ddl];
2264 out << Form("%5d %5d %10d %10d",busPatchId,manuId,manu->ValueAsInt(0,IndexOfOccupancyDimension()),nevents) << endl;
2271 //_____________________________________________________________________________
2272 void AliMUONTrackerData::DispatchValue(AliMUONVCalibParam& param,
2278 /// fills the calibparam with a single value
2280 Double_t sumn = 1000.0; // or any value strictly above 1
2281 Double_t sumw = sumn*y;
2282 Double_t sumw2 = (sumn-1)*ey*ey+sumw*sumw/sumn;
2284 param.SetValueAsDouble(index,0,sumw);
2285 param.SetValueAsDouble(index,1,sumw2);
2286 param.SetValueAsDouble(index,2,sumn);
2287 param.SetValueAsDouble(index,3,nchannels);