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& deOrBpValues, 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 OR bus patch level
282 /// In this case, we force fIsChannelLevelEnabled = fIsManuLevelEnabled = kFALSE
285 if (deOrBpValues.GetSize()==0)
287 AliFatal("Cannot create a tracker data from nothing in that case !");
290 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
292 AliError("Cannot work without (full) mapping");
298 BuildFromDEStore(deOrBpValues);
302 BuildFromBPStore(deOrBpValues);
306 AliFatal("Wrong parameter. Must be 1 or 2");
312 //_____________________________________________________________________________
313 void AliMUONTrackerData::BuildFromDEStore(const AliMUONVStore& deValues)
315 /// Fill internals from a store of values at the detection element level
317 TIter next(deValues.CreateIterator());
318 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
320 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
322 fDimension = External2Internal(dimension)+fgkExtraDimension;
324 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
325 fExternalDimensionNames = new TObjArray(dimension);
326 fExternalDimension = dimension;
327 fHistogramming = new Int_t[fExternalDimension];
328 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
330 fExternalDimensionNames->SetOwner(kTRUE);
331 fDimensionNames->SetOwner(kTRUE);
332 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
333 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
334 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
336 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
340 AliMUONVCalibParam* external;
342 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
344 Int_t detElemId = external->ID0();
346 AliMpDetElement* mpde = AliMpDDLStore::Instance()->GetDetElement(detElemId,kFALSE);
350 AliError(Form("Got an invalid DE (%d) from external store",detElemId));
354 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
355 AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
356 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
358 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,0,0);
359 // as external, but without event count
360 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
361 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
362 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
363 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
365 Int_t n1 = de->ValueAsInt(0,IndexOfNumberDimension());
366 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
369 AliError(Form("Incoherent number of dimensions for DE%d : %d vs %d",
374 Int_t nevt = external->ValueAsInt(0,4);
376 Int_t ddl = mpde->GetDdlId();
378 if ( nevents[ddl] == 0 )
384 if ( nevents.At(ddl) != nevt )
386 AliError(Form("Nevt mismatch for DE %5d DDL %d : %d vs %d",
387 detElemId,ddl,nevents.At(ddl),nevt));
392 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
394 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
396 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
401 UpdateNumberOfEvents(&nevents);
404 //_____________________________________________________________________________
405 void AliMUONTrackerData::BuildFromBPStore(const AliMUONVStore& bpValues)
407 /// Fill internals from a store of values at the bus patch level
409 fIsBustPatchLevelEnabled = kTRUE;
411 TIter next(bpValues.CreateIterator());
412 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
414 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
416 fDimension = External2Internal(dimension)+fgkExtraDimension;
418 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
419 fExternalDimensionNames = new TObjArray(dimension);
420 fExternalDimension = dimension;
421 fHistogramming = new Int_t[fExternalDimension];
422 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
424 fExternalDimensionNames->SetOwner(kTRUE);
425 fDimensionNames->SetOwner(kTRUE);
426 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
427 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
428 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
430 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
434 AliMUONVCalibParam* external;
436 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
438 Int_t busPatchId = external->ID0();
440 AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId,kFALSE);
444 AliError(Form("Got an invalid buspatchId (%d) from external store",busPatchId));
448 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
449 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
450 AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
451 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
452 AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE);
454 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,busPatchId,0,0);
455 // as external, but without event count
456 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
457 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
458 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
459 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
461 Int_t n1 = bp->ValueAsInt(0,IndexOfNumberDimension());
462 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
465 AliError(Form("Incoherent number of dimensions for BP%d : %d vs %d",
470 Int_t nevt = external->ValueAsInt(0,4);
472 Int_t ddl = mpbp->GetDdlId();
474 if ( nevents[ddl] == 0 )
480 if ( nevents.At(ddl) != nevt )
482 AliError(Form("Nevt mismatch for BP %5d DDL %d : %d vs %d",
483 busPatchId,ddl,nevents.At(ddl),nevt));
488 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
490 bp->SetValueAsDouble(0,i,bp->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
492 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
494 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
499 UpdateNumberOfEvents(&nevents);
502 //_____________________________________________________________________________
503 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
504 const AliMUONRejectList& rejectList)
505 : AliMUONVTrackerData(name,title),
506 fIsSingleEvent(kFALSE),
509 fBusPatchValues(0x0),
513 fDimension(External2Internal(1)+fgkExtraDimension),
515 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
516 fExternalDimensionNames(new TObjArray(1)),
517 fExternalDimension(1),
518 fHistogramming(new Int_t[fExternalDimension]),
522 fIsChannelLevelEnabled(kTRUE),
523 fIsManuLevelEnabled(kTRUE),
524 fIsBustPatchLevelEnabled(kTRUE),
525 fIsPCBLevelEnabled(kFALSE),
527 fNofEventsPerDDL(0x0)
530 /// ctor with values from the given rejectlist
532 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
534 AliError("Cannot work without (full) mapping");
538 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
540 fExternalDimensionNames->SetOwner(kTRUE);
541 fDimensionNames->SetOwner(kTRUE);
542 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
543 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
544 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
546 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
550 for ( Int_t chamberId = 0; chamberId < AliMUONConstants::NCh(); ++chamberId )
552 // AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
554 // FIXME : update the chamber value ?
556 AliMpDEIterator deit;
558 deit.First(chamberId);
560 while ( !deit.IsDone() )
562 AliMpDetElement* mpde = deit.CurrentDE();
564 Int_t detElemId = mpde->GetId();
566 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
568 DispatchValue(*de,0,rejectList.DetectionElementProbability(detElemId),0.0,mpde->NofChannels());
570 for ( Int_t iBusPatch = 0; iBusPatch < mpde->GetNofBusPatches(); ++iBusPatch )
572 Int_t busPatchId = mpde->GetBusPatchId(iBusPatch);
574 AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE);
576 AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
580 for ( Int_t iManu = 0 ;iManu < mpbp->GetNofManus(); ++iManu )
582 Int_t manuId = mpbp->GetManuId(iManu);
584 nch += mpde->NofChannelsInManu(manuId);
586 AliMUONVCalibParam* manu = ManuParam(detElemId,manuId,kTRUE);
588 DispatchValue(*manu,0,rejectList.ManuProbability(detElemId,manuId),0.0,mpde->NofChannelsInManu(manuId));
590 AliMUONVCalibParam* c = ChannelParam(detElemId,manuId);
594 c = new AliMUONCalibParamND(Dimension(),
595 AliMpConstants::ManuNofChannels(),
599 fChannelValues->Add(c);
602 for ( Int_t manuChannel = 0; manuChannel < AliMpConstants::ManuNofChannels(); ++manuChannel )
604 DispatchValue(*c,manuChannel,rejectList.ChannelProbability(detElemId,manuId,manuChannel),0.0,1);
608 DispatchValue(*bp,0,rejectList.BusPatchProbability(busPatchId),0.0,nch);
618 SetDimensionName(0,"RejectProba");
620 UpdateNumberOfEvents(0x0);
623 //_____________________________________________________________________________
624 AliMUONTrackerData::~AliMUONTrackerData()
627 delete fChannelValues;
629 delete fBusPatchValues;
631 delete fChamberValues;
633 delete fDimensionNames;
634 delete fExternalDimensionNames;
635 delete[] fHistogramming;
637 delete[] fNofEventsPerDDL;
640 //_____________________________________________________________________________
642 AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents)
644 /// Add the given external store to our internal store
645 return InternalAdd(store,nevents,kFALSE);
648 //_____________________________________________________________________________
650 AliMUONTrackerData::Add(const AliMUONTrackerData& data)
652 /// Add data to *this
653 // We do this by looping on all VCalibParam stored in the various containers,
654 // and simply adding the values there.
655 // Same thing for the number of events per DDL.
656 // Same thing for sparsehistograms, if we have some.
658 // First cross check we have compatible objects.
660 if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled )
662 AliError("Incompatible IsChannelLevelEnabled status");
666 if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled )
668 AliError("Incompatible IsManuLevelEnabled status");
672 if ( fIsSingleEvent != data.fIsSingleEvent )
674 AliError("Incompatible IsSingleEvent status");
678 if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension )
680 AliError("Incompatible dimensions");
684 if ( fNofDDLs != data.fNofDDLs )
686 AliError("Incompatible number of Ddls");
690 if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming )
691 || fXmin != data.fXmin || fXmax != data.fXmax )
693 AliError(Form("Incompatible histogramming (%p vs %p) (xmax = %e vs %e ; xmin = %e vs %e)",
694 fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
698 if ( fHistogramming )
700 for ( Int_t i = 0; i < fExternalDimension; ++i )
702 if ( fHistogramming[i] != data.fHistogramming[i] )
704 AliError(Form("Incompatible histogramming for external dimension %d",i));
710 // OK. Seems we have compatible objects, so we can proceed with the actual
713 if ( data.fChannelValues )
715 Add2D(*(data.fChannelValues),*fChannelValues);
718 if ( data.fManuValues )
720 Add2D(*(data.fManuValues),*fManuValues);
723 if ( data.fPCBValues )
725 Add2D(*(data.fPCBValues),*fPCBValues);
728 if ( data.fBusPatchValues )
730 Add1D(*(data.fBusPatchValues),*fBusPatchValues);
733 if ( data.fDEValues )
735 Add1D(*(data.fDEValues),*fDEValues);
738 if ( data.fChamberValues )
740 Add1D(*(data.fChamberValues),*fChamberValues);
743 for ( Int_t i = 0; i < fNofDDLs; ++i )
745 fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
750 TIter nexthisto(data.fHistos->CreateIterator());
751 AliMUONVStore* store;
752 while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
754 TIter ns(store->CreateIterator());
755 AliMUONSparseHisto* h;
756 while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
758 AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
762 thisStore = store->Create();
763 thisStore->SetUniqueID(store->GetUniqueID());
764 fHistos->Add(thisStore);
767 AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
781 fNevents = TMath::Max(fNevents,data.fNevents);
786 //_____________________________________________________________________________
788 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
790 /// Add one 2d store to another
792 TIter next(src.CreateIterator());
793 AliMUONVCalibParam* p;
795 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
797 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
801 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
805 AddCalibParams(*p,*a);
810 //_____________________________________________________________________________
812 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
814 /// Add one 1d store to another
816 TIter next(src.CreateIterator());
817 AliMUONVCalibParam* p;
819 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
821 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
825 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
829 AddCalibParams(*p,*a);
834 //_____________________________________________________________________________
836 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
839 for ( Int_t i = 0; i < src.Size(); ++i )
841 for ( Int_t j = 0; j < src.Dimension(); ++j )
843 dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
848 //_____________________________________________________________________________
850 AliMUONTrackerData::Replace(const AliMUONVStore& store)
852 /// Replace our values by values from the given external store
853 Bool_t rv = InternalAdd(store,0x0,kTRUE);
854 AliMUONVTrackerData::Replace(store);
858 //_____________________________________________________________________________
860 AliMUONTrackerData::UpdateNumberOfEvents(TArrayI* nevents)
862 /// Update the number of events
866 fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
867 fNofEventsPerDDL = new Int_t[fNofDDLs];
868 for ( Int_t i = 0; i < fNofDDLs; ++i )
870 fNofEventsPerDDL[i] = 0;
876 if (nevents->GetSize() != fNofDDLs )
878 AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
879 nevents->GetSize(),fNofDDLs));
883 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
885 fNofEventsPerDDL[i] += nevents->At(i);
886 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
891 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
893 ++fNofEventsPerDDL[i];
894 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
900 //_____________________________________________________________________________
902 AliMUONTrackerData::AssertStores()
904 /// Insure our stores are allocated
908 Int_t numberOfBusPatches(0);
909 Int_t numberOfDEs(0);
911 // get number of bus patches and number of detection element
912 // to initialize fBusPatchValues and fDEValues below
914 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
915 while ( next() ) ++numberOfBusPatches;
916 AliMpDEIterator deIt;
918 while (!deIt.IsDone())
924 if ( fIsChannelLevelEnabled )
926 fChannelValues = new AliMUON2DMap(kTRUE);
928 if ( fIsManuLevelEnabled )
930 fManuValues = new AliMUON2DMap(kTRUE);
932 if ( fIsPCBLevelEnabled )
934 fPCBValues = new AliMUON2DMap(kFALSE);
936 if ( fIsBustPatchLevelEnabled )
938 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
940 fDEValues = new AliMUON1DMap(numberOfDEs);
941 fChamberValues = new AliMUON1DArray;
945 //_____________________________________________________________________________
947 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
949 /// Add the given external store to our internal store
951 AliCodeTimerAuto(GetName(),0);
955 if ( IsSingleEvent() && NumberOfEvents(-1) == 1 )
957 AliError(Form("%s is supposed to be single event only",GetName()));
962 UpdateNumberOfEvents(nevents);
966 TIter next(store.CreateIterator());
967 AliMUONVCalibParam* external;
971 if ( IsSingleEvent() ) nk = 1;
973 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
975 if ( external->Dimension() != ExternalDimension() )
977 AliError(Form("Incompatible dimensions %d vs %d",
978 external->Dimension(),ExternalDimension()));
982 AliMUONVCalibParam* chamber(0x0);
983 AliMUONVCalibParam* de(0x0);
984 AliMUONVCalibParam* busPatch(0x0);
985 AliMUONVCalibParam* pcb(0x0);
986 AliMUONVCalibParam* manu(0x0);
987 AliMUONVCalibParam* channel(0x0);
988 AliMpDetElement* mpde(0x0);
990 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
992 if ( manuId < 0 ) continue;
994 Int_t detElemId = mpde->GetId();
996 Double_t value[] = { 0.0, 0.0 };
998 Int_t nch = mpde->NofChannelsInManu(manuId);
1000 for ( Int_t i = 0; i < external->Size(); ++i )
1002 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
1003 : mpde->IsConnectedChannel(manuId,i));
1004 // note we only use IsConnectedChannel method when really needed, as
1005 // it costs (some) CPU time...
1007 if ( existingChannel )
1009 Bool_t validChannel(kFALSE);
1011 for ( Int_t j = 0; j < external->Dimension(); ++j )
1013 Double_t vext = external->IsDoublePrecision() ?
1014 external->ValueAsDoubleFast(i,j) :
1015 external->ValueAsFloatFast(i,j);
1017 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
1019 validChannel = kTRUE;
1021 Int_t ix = External2Internal(j);
1024 value[1] = vext*vext;
1026 if ( IsHistogrammed(j) )
1028 FillHisto(detElemId,manuId,i,j,vext);
1031 for ( Int_t k = 0; k < nk; ++k )
1033 Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
1037 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
1042 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1045 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1047 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1049 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1053 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
1058 if ( validChannel && !replace )
1062 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
1063 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
1068 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1069 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1072 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1073 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1074 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1075 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1076 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1077 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1080 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
1081 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
1088 NumberOfEventsChanged();
1093 //_____________________________________________________________________________
1095 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
1097 /// Return the value of a given buspatch for a given dimension
1098 /// or 0 if not existing
1099 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
1100 return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
1103 //_____________________________________________________________________________
1105 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
1107 /// Return (if it exist), the VCalibParam for a given busPatch
1109 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
1110 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
1112 if (!busPatch && create && fBusPatchValues)
1114 busPatch = CreateBusPatchParam(busPatchId);
1115 fBusPatchValues->Add(busPatch);
1121 //_____________________________________________________________________________
1123 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
1125 /// Create storage for one bus patch
1127 AliCodeTimerAuto("",0);
1129 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1133 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
1137 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
1139 // set the number of channels in that buspatch
1143 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
1145 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1147 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
1149 Int_t manuId = bp->GetManuId(i);
1150 nchannels += de->NofChannelsInManu(manuId);
1153 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1158 //_____________________________________________________________________________
1160 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
1162 /// Return the value fo a given chamber for a given dimension,
1163 /// or zero if not existing
1165 // FIXME: is the Value() correct wrt to number of events in the case of
1166 // chamber ? Or should we do something custom at the chamber level
1167 // (as it spans several ddls) ?
1169 AliMUONVCalibParam* param = ChamberParam(chamberId);
1170 return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
1173 //_____________________________________________________________________________
1175 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
1177 /// Return (if it exist) the VCalibParam for a given chamber
1179 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
1180 (fChamberValues->FindObject(chamberId)) : 0x0;
1182 if (!chamber && create && fChamberValues)
1184 chamber = CreateChamberParam(chamberId);
1185 fChamberValues->Add(chamber);
1191 //_____________________________________________________________________________
1193 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
1195 /// Create storage for one chamber
1197 AliCodeTimerAuto("",0);
1199 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
1201 // set the number of channels in that chamber
1207 it.First(chamberId);
1209 while ( !it.IsDone() )
1211 AliMpDetElement* det = it.CurrentDE();
1213 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1215 Int_t busPatchId = det->GetBusPatchId(i);
1216 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1217 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1219 Int_t manuId = bp->GetManuId(j);
1220 nchannels += det->NofChannelsInManu(manuId);
1227 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1232 //_____________________________________________________________________________
1234 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
1235 Int_t manuChannel, Int_t dim) const
1237 /// Return the value for a given channel for a given dimension
1239 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
1241 return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1244 //_____________________________________________________________________________
1246 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
1247 const AliMUONVCalibParam* external) const
1249 /// Return (if it exist) the VCalibParam for a given manu
1251 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
1252 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
1254 if (!param && external && fChannelValues)
1256 param = CreateDouble(*external,detElemId,manuId);
1257 fChannelValues->Add(param);
1263 //_____________________________________________________________________________
1265 AliMUONTrackerData::Clear(Option_t*)
1267 /// Clear all the values
1268 if ( fChannelValues ) fChannelValues->Clear();
1269 if ( fManuValues ) fManuValues->Clear();
1270 if ( fBusPatchValues) fBusPatchValues->Clear();
1271 if ( fPCBValues ) fPCBValues->Clear();
1272 if ( fDEValues) fDEValues->Clear();
1273 if ( fChamberValues ) fChamberValues->Clear();
1274 if ( fHistos ) fHistos->Clear();
1275 for ( Int_t i = 0; i < fNofDDLs; ++i )
1277 fNofEventsPerDDL[i] = 0;
1280 NumberOfEventsChanged();
1283 //_____________________________________________________________________________
1285 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
1286 Int_t manuChannel) const
1288 /// Return the number of times a given channel had data
1290 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
1293 //_____________________________________________________________________________
1295 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
1296 Int_t detElemId, Int_t manuId) const
1298 /// Create a double version of VCalibParam, for internal use
1300 AliCodeTimerAuto("",0);
1302 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
1308 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
1310 for ( Int_t i = 0; i < c->Size(); ++i )
1312 Double_t value(0.0);
1314 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
1316 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
1322 //_____________________________________________________________________________
1324 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
1326 /// Return the value for a given detection element for a given dimension
1327 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
1328 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1332 //_____________________________________________________________________________
1334 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
1336 /// Return (if it exist) the VCalibParam for a given detection element
1338 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
1339 (fDEValues->FindObject(detElemId)) : 0x0 ;
1341 if (!de && create && fDEValues)
1343 de = CreateDetectionElementParam(detElemId);
1351 //_____________________________________________________________________________
1353 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
1355 /// Create storage for one detection element
1357 AliCodeTimerAuto("",0);
1359 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
1361 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1364 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1366 Int_t busPatchId = det->GetBusPatchId(i);
1367 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1368 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1370 Int_t manuId = bp->GetManuId(j);
1371 nchannels += det->NofChannelsInManu(manuId);
1375 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1380 //_____________________________________________________________________________
1382 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
1384 /// Get the "local" ddlid (0..19) of a given buspatch
1385 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
1388 return bp->GetDdlId();
1393 //_____________________________________________________________________________
1395 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
1397 /// Get the "local" ddlid (0..19) of a given detection element
1398 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
1401 return de->GetDdlId();
1406 //_____________________________________________________________________________
1408 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
1410 /// Get the "local" ddlid (0..19) of a given chamber
1411 /// This has no real meaning (as there are several ddls per chamber),
1412 /// so we take the ddlid where we got the max number of events
1416 it.First(chamberid);
1420 while (!it.IsDone())
1422 Int_t detElemId = it.CurrentDEId();
1423 Int_t ddlId = DdlIdFromDetElemId(detElemId);
1424 if ( NumberOfEvents(ddlId) > n )
1426 n = NumberOfEvents(ddlId);
1435 //_____________________________________________________________________________
1437 AliMUONTrackerData::DimensionName(Int_t dim) const
1439 /// Get the name of a given dimension
1440 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
1443 return value->String();
1447 return TString("Invalid");
1451 //_____________________________________________________________________________
1453 AliMUONTrackerData::DisableChannelLevel()
1455 /// Disable the storing of data at channel level
1457 delete fChannelValues;
1458 fChannelValues = 0x0;
1459 fIsChannelLevelEnabled = kFALSE;
1462 //_____________________________________________________________________________
1464 AliMUONTrackerData::DisableManuLevel()
1466 /// Disable the storing of data at manu level (and below)
1468 DisableChannelLevel();
1471 fIsManuLevelEnabled = kFALSE;
1474 //_____________________________________________________________________________
1476 AliMUONTrackerData::External2Internal(Int_t index) const
1478 /// From external to internal dimension
1479 return IsSingleEvent() ? index : index*2;
1482 //_____________________________________________________________________________
1484 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
1486 /// Get the name of a given external dimension
1488 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
1491 return value->String();
1495 return TString("Invalid");
1499 //_____________________________________________________________________________
1501 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
1502 Int_t dim, Double_t value)
1504 /// Fill histogram of a given channel
1506 AliMUONSparseHisto* h(0x0);
1508 if ( fIsChannelLevelEnabled )
1510 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
1512 else if ( fIsManuLevelEnabled )
1514 h = GetManuSparseHisto(detElemId,manuId,dim);
1517 AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
1521 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
1525 //_____________________________________________________________________________
1527 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId,
1530 /// Get histogram of a given manu
1532 if (!fHistos) return 0x0;
1534 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1537 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1542 //_____________________________________________________________________________
1544 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
1546 /// Get histogram of a given manu. Create it if necessary
1548 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1550 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1553 m = new AliMUON1DArray(NumberOfDimensions());
1554 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1558 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1561 h = new AliMUONSparseHisto(fXmin,fXmax);
1563 h->SetUniqueID(dim);
1571 //_____________________________________________________________________________
1573 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1574 Int_t manuChannel, Int_t dim) const
1576 /// Get histogram of a given channel
1578 if (!fHistos) return 0x0;
1580 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1583 UInt_t uid = ( manuChannel << 16 ) | dim;
1585 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1590 //_____________________________________________________________________________
1592 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1593 Int_t manuChannel, Int_t dim)
1595 /// Get histogram of a given channel. Create it if necessary
1597 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1599 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1602 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1603 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1607 UInt_t uid = ( manuChannel << 16 ) | dim;
1609 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1612 h = new AliMUONSparseHisto(fXmin,fXmax);
1614 h->SetUniqueID(uid);
1622 //_____________________________________________________________________________
1624 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1625 Int_t& detElemId, Int_t& manuId) const
1627 /// Tries to get (detElemId,manuId) of param
1629 // Load mapping manu store
1630 if ( ! AliMpCDB::LoadManuStore() ) {
1631 AliError("Could not access manu store from OCDB !");
1635 if ( param.ID1() <= 0 )
1637 // we (probably) get a manu serial number
1638 Int_t serial = param.ID0();
1639 MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1640 detElemId = AliMp::PairFirst(pair);
1641 manuId = AliMp::PairSecond(pair);
1644 AliDebug(1,Form("DE %d manuId %d from serial %d is not correct !",
1645 detElemId,manuId,serial));
1650 // we get a (de,manu) pair
1651 detElemId = param.ID0();
1652 manuId = param.ID1();
1657 //_____________________________________________________________________________
1659 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1660 AliMUONVCalibParam*& chamber,
1661 AliMUONVCalibParam*& de,
1662 AliMUONVCalibParam*& busPatch,
1663 AliMUONVCalibParam*& pcb,
1664 AliMUONVCalibParam*& manu,
1665 AliMUONVCalibParam*& channel,
1666 AliMpDetElement*& mpde)
1668 /// Get containers at all levels
1670 chamber = de = busPatch = pcb = manu = channel = 0x0;
1673 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1678 GetDEManu(*external,detElemId,manuId);
1680 mpde = ddlStore->GetDetElement(detElemId,kFALSE);
1682 if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1687 // explicitely check that de,manu is correct
1688 const AliMpVSegmentation* mpseg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId,kFALSE);
1695 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1697 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1699 if ( busPatchId <= 0 )
1704 Int_t pcbIndex = -1;
1706 AliMp::StationType stationType = mpde->GetStationType();
1708 if ( stationType == AliMp::kStation345 )
1710 AliMpDCSNamer namer("TRACKER");
1711 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1714 if ( fIsChannelLevelEnabled )
1716 channel = ChannelParam(detElemId,manuId,external);
1719 manu = ManuParam(detElemId,manuId,kTRUE);
1721 busPatch = BusPatchParam(busPatchId,kTRUE);
1723 de = DetectionElementParam(detElemId,kTRUE);
1725 chamber = ChamberParam(chamberId,kTRUE);
1729 if ( pcbIndex >= 0 )
1731 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1737 //_____________________________________________________________________________
1739 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1741 /// Whether we have data for a given buspatch
1742 return ( BusPatchParam(busPatchId) != 0 );
1745 //_____________________________________________________________________________
1747 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1749 /// Whether we have data for a given chamber
1750 return ( ChamberParam(chamberId) != 0 );
1753 //_____________________________________________________________________________
1755 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1757 /// Whether we have data for a given detection element
1758 return ( DetectionElementParam(detElemId) != 0 );
1761 //_____________________________________________________________________________
1763 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1765 /// Whether we have data for a given manu
1766 return ( ManuParam(detElemId,manuId) != 0 );
1769 //_____________________________________________________________________________
1771 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1773 /// Whether we have data for a given pcb
1774 return ( PCBParam(detElemId,pcbIndex) != 0 );
1777 //_____________________________________________________________________________
1779 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1781 /// Return the value for a given manu and a given dimension
1783 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1784 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1787 //_____________________________________________________________________________
1789 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1791 /// Get the VCalibParam for a given manu
1793 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1794 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1796 if (!manu && create && fManuValues)
1798 manu = CreateManuParam(detElemId,manuId);
1799 fManuValues->Add(manu);
1805 //_____________________________________________________________________________
1807 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1809 /// Create storage for one manu
1811 AliCodeTimerAuto("",0);
1813 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1815 // set the number of channels in that manu
1817 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1819 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1824 //_____________________________________________________________________________
1826 AliMUONTrackerData::Merge(TCollection* list)
1828 /// Merge this with a list of AliMUONVTrackerData
1830 if (!list) return 0;
1832 if ( list->IsEmpty() ) return NumberOfEvents(-1);
1835 const TObject* o(0x0);
1837 while ( ( o = next() ) )
1839 const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1842 AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1847 Bool_t ok = Add(*data);
1850 AliError("Got incompatible objects");
1855 return NumberOfEvents(-1);
1858 //_____________________________________________________________________________
1860 AliMUONTrackerData::NumberOfDimensions() const
1862 /// Number of dimensions we're dealing with
1864 return fDimension + fgkVirtualExtraDimension;
1867 //_____________________________________________________________________________
1869 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1871 /// Get the number of events we've seen for a given DDL, or the max
1872 /// in case ddlNumber<0
1876 if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1878 n = fNofEventsPerDDL[ddlNumber];
1882 // get the max number of events
1889 //_____________________________________________________________________________
1891 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1893 /// Return the value of a given pcb for a given dimension
1895 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1897 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1900 //_____________________________________________________________________________
1902 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1904 /// Return (if it exist) the VCalibParam for a given pcb
1906 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
1907 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1909 if (create && fPCBValues && !pcb)
1911 pcb = CreatePCBParam(detElemId,pcbIndex);
1912 fPCBValues->Add(pcb);
1918 //_____________________________________________________________________________
1920 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1922 /// Create storage for one PCB (station345 only)
1924 AliCodeTimerAuto("",0);
1926 AliMpDCSNamer namer("TRACKER");
1928 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1929 namer.NumberOfPCBs(detElemId),
1936 //_____________________________________________________________________________
1938 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1944 if ( !fIsSingleEvent )
1946 for ( Int_t i = 0; i < fNofDDLs; ++i )
1948 cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1952 if ( !fIsChannelLevelEnabled )
1954 cout << "Is not storing data at the channel level" << endl;
1957 if ( !fIsManuLevelEnabled )
1959 cout << "Is not storing data at the manu level" << endl;
1962 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
1964 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1965 cout << Form("External Dimension %2d Name %s %s",i,
1966 ( name ? name->String().Data() : "null"),
1967 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1970 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
1972 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1973 cout << Form("Internal Dimension %2d Name %s",i,
1974 ( name ? name->String().Data() : "null")) << endl;
1980 if ( sopt.Contains("CHANNEL") )
1982 if ( fIsChannelLevelEnabled )
1984 if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1988 AliWarning("You requested channel values, but they were not stored !");
1992 if ( sopt.Contains("MANU") )
1994 if ( fIsManuLevelEnabled )
1996 if ( fManuValues ) fManuValues->Print(wildcard,opt);
2000 AliWarning("You requested manu values, but they were not stored !");
2004 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
2006 fBusPatchValues->Print(wildcard,opt);
2009 if ( sopt.Contains("DE") && fDEValues )
2011 fDEValues->Print(wildcard,opt);
2014 if ( sopt.Contains("CHAMBER") && fChamberValues )
2016 fChamberValues->Print(wildcard,opt);
2021 //_____________________________________________________________________________
2023 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
2025 /// Set the name of a given dimension
2027 if ( index >= fExternalDimension )
2029 AliError(Form("%s : dimension %s : Index out of bounds : %d / %d",
2031 name,index,fExternalDimension));
2035 Int_t ix = External2Internal(index);
2037 if ( !IsSingleEvent() )
2039 const char* prefix[] = { "mean", "sigma" };
2041 for ( Int_t i = 0; i < 2; ++i )
2045 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
2050 SetInternalDimensionName(index,name);
2053 SetExternalDimensionName(index,name);
2056 //_____________________________________________________________________________
2058 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
2060 /// decide to make histos for a given dimension
2061 if ( index >= ExternalDimension() )
2063 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
2067 AliWarning(Form("Will %s make histogram for data %s index %d : that might ressemble a memory leak depending on the input data",
2068 value ? "":"not", GetName(),index));
2069 fHistogramming[index] = value;
2074 //_____________________________________________________________________________
2076 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
2078 /// Set the name of a given internal dimension
2079 if ( index >= fDimension )
2081 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
2085 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
2089 fDimensionNames->Remove(ovalue);
2092 fDimensionNames->AddAt(new TObjString(value),index);
2095 //_____________________________________________________________________________
2097 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
2099 /// Set the name of a given external dimension
2100 if ( index >= fExternalDimension )
2102 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
2106 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
2110 fExternalDimensionNames->Remove(ovalue);
2113 fExternalDimensionNames->AddAt(new TObjString(value),index);
2116 //_____________________________________________________________________________
2118 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i,
2119 Int_t dim, Int_t ddlId) const
2121 /// Compute the value for a given dim, using the internal information we have
2122 /// Basically we're converting sum of weights and sum of squares of weights
2123 /// into means and sigmas, and number of events into occupancy number.
2125 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
2127 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
2129 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
2131 if ( dim >= fDimension )
2136 if ( dim == IndexOfOccupancyDimension() )
2138 if ( ddlId < 0 ) AliError("Got a negative ddl id !");
2139 return occ/n/NumberOfEvents(ddlId);
2142 Double_t value = param.ValueAsDouble(i,dim);
2144 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
2146 if ( TMath::Even(dim) || IsSingleEvent() )
2148 Double_t x = value/occ;
2150 return ( TMath::Finite(x) ? x : 0.0 ) ;
2158 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
2160 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
2168 AliError("Why am I here ?");
2172 //_____________________________________________________________________________
2174 AliMUONTrackerData::Streamer(TBuffer &R__b)
2176 /// Customized streamer
2178 if (R__b.IsReading()) {
2179 AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
2182 // backward compatible mode : we set number of events
2183 // per DDL to the total number of events (the only information
2184 // we had before version 7 of that class)
2185 delete[] fNofEventsPerDDL;
2187 fNofEventsPerDDL = new Int_t[fNofDDLs];
2188 for ( Int_t i = 0; i < fNofDDLs; ++i )
2190 fNofEventsPerDDL[i] = fNevents;
2195 AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
2199 //_____________________________________________________________________________
2201 AliMUONTrackerData::ExportAsASCIIOccupancyFile(const char* filename, Int_t runNumber) const
2203 /// Export only the occupancy part, in a format compatible with what
2204 /// the online occupancy DA is writing
2206 if ( ! AliMpDDLStore::Instance(kFALSE) )
2208 AliError("Mapping not loaded. Cannot work");
2214 AliError("No manu values. Cannot work");
2218 ofstream out(filename);
2222 AliError(Form("Cannot create file %s",filename));
2226 out << "//===========================================================================" << endl;
2227 out << "// Hit counter exported from $Id$" << endl;
2228 out << "//===========================================================================" << endl;
2229 out << "//" << endl;
2230 out << "// * Run Number : " << runNumber << endl;
2231 out << "// * File Creation Date : " << TTimeStamp().AsString("l") << endl;
2232 out << "//---------------------------------------------------------------------------" << endl;
2233 out << "// BP MANU SUM_N NEVENTS" << endl;
2234 out << "//---------------------------------------------------------------------------" << endl;
2236 TIter next(fManuValues->CreateIterator());
2237 AliMUONVCalibParam* manu;
2239 while ( ( manu = static_cast<AliMUONVCalibParam*>(next()) ) )
2241 Int_t detElemId = manu->ID0();
2242 Int_t manuId = manu->ID1();
2243 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
2244 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus( busPatchId);
2245 if ( busPatchId < 0 || ddl < 0 )
2247 AliError(Form("Got invalid (DE,manu,bp,ddl)=(%d,%d,%d,%d). Skipping it",detElemId,manuId,busPatchId,ddl));
2251 Int_t nevents = fNofEventsPerDDL[ddl];
2253 out << Form("%5d %5d %10d %10d",busPatchId,manuId,manu->ValueAsInt(0,IndexOfOccupancyDimension()),nevents) << endl;
2260 //_____________________________________________________________________________
2261 void AliMUONTrackerData::DispatchValue(AliMUONVCalibParam& param,
2267 /// fills the calibparam with a single value
2269 Double_t sumn = 1000.0; // or any value strictly above 1
2270 Double_t sumw = sumn*y;
2271 Double_t sumw2 = (sumn-1)*ey*ey+sumw*sumw/sumn;
2273 param.SetValueAsDouble(index,0,sumw);
2274 param.SetValueAsDouble(index,1,sumw2);
2275 param.SetValueAsDouble(index,2,sumn);
2276 param.SetValueAsDouble(index,3,nchannels);