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 "AliMUONSparseHisto.h"
28 #include "AliMUONVStore.h"
29 #include "AliMpBusPatch.h"
30 #include "AliMpConstants.h"
32 #include "AliMpDDLStore.h"
33 #include "AliMpManuStore.h"
34 #include "AliMpDEIterator.h"
35 #include "AliMpDEManager.h"
36 #include "AliMpDetElement.h"
37 #include "AliMpDCSNamer.h"
38 #include "AliMpManuIterator.h"
39 #include "AliMpEncodePair.h"
40 #include <Riostream.h>
43 #include <TObjArray.h>
44 #include <TObjString.h>
49 /// \class AliMUONTrackerData
51 /// Implementation of AliMUONVTrackerData class
53 /// \author Laurent Aphecetche, Subatech
56 ClassImp(AliMUONTrackerData)
59 const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
60 const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
62 //_____________________________________________________________________________
63 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
66 : AliMUONVTrackerData(name,title),
67 fIsSingleEvent(issingleevent),
74 fDimension(External2Internal(dimension)+fgkExtraDimension),
76 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
77 fExternalDimensionNames(new TObjArray(dimension)),
78 fExternalDimension(dimension),
79 fHistogramming(new Int_t[fExternalDimension]),
83 fIsChannelLevelEnabled(kTRUE),
84 fIsManuLevelEnabled(kTRUE),
89 memset(fHistogramming,0,sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
90 fExternalDimensionNames->SetOwner(kTRUE);
91 fDimensionNames->SetOwner(kTRUE);
92 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
93 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
94 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
98 //_____________________________________________________________________________
99 AliMUONTrackerData::~AliMUONTrackerData()
102 delete fChannelValues;
104 delete fBusPatchValues;
106 delete fChamberValues;
108 delete fDimensionNames;
109 delete fExternalDimensionNames;
110 delete[] fHistogramming;
112 delete[] fNofEventsPerDDL;
115 //_____________________________________________________________________________
117 AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents)
119 /// Add the given external store to our internal store
120 return InternalAdd(store,nevents,kFALSE);
123 //_____________________________________________________________________________
125 AliMUONTrackerData::Add(const AliMUONTrackerData& data)
127 /// Add data to *this
128 // We do this by looping on all VCalibParam stored in the various containers,
129 // and simply adding the values there.
130 // Same thing for the number of events per DDL.
131 // Same thing for sparsehistograms, if we have some.
133 // First cross check we have compatible objects.
135 if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled )
137 AliError("Incompatible IsChannelLevelEnabled status");
141 if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled )
143 AliError("Incompatible IsManuLevelEnabled status");
147 if ( fIsSingleEvent != data.fIsSingleEvent )
149 AliError("Incompatible IsSingleEvent status");
153 if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension )
155 AliError("Incompatible dimensions");
159 if ( fNofDDLs != data.fNofDDLs )
161 AliError("Incompatible number of Ddls");
165 if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming )
166 || fXmin != data.fXmin || fXmax != data.fXmax )
168 AliError(Form("Incompatible histogramming (%x vs %x) (xmax = %e vs %e ; xmin = %e vs %e)",
169 fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
173 if ( fHistogramming )
175 for ( Int_t i = 0; i < fExternalDimension; ++i )
177 if ( fHistogramming[i] != data.fHistogramming[i] )
179 AliError(Form("Incompatible histogramming for external dimension %d",i));
185 // OK. Seems we have compatible objects, so we can proceed with the actual
188 if ( data.fChannelValues )
190 Add2D(*(data.fChannelValues),*fChannelValues);
193 if ( data.fManuValues )
195 Add2D(*(data.fManuValues),*fManuValues);
198 if ( data.fPCBValues )
200 Add2D(*(data.fPCBValues),*fPCBValues);
203 if ( data.fBusPatchValues )
205 Add1D(*(data.fBusPatchValues),*fBusPatchValues);
208 if ( data.fDEValues )
210 Add1D(*(data.fDEValues),*fDEValues);
213 if ( data.fChamberValues )
215 Add1D(*(data.fChamberValues),*fChamberValues);
218 for ( Int_t i = 0; i < fNofDDLs; ++i )
220 fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
225 TIter nexthisto(data.fHistos->CreateIterator());
226 AliMUONVStore* store;
227 while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
229 TIter ns(store->CreateIterator());
230 AliMUONSparseHisto* h;
231 while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
233 AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
237 thisStore = store->Create();
238 thisStore->SetUniqueID(store->GetUniqueID());
239 fHistos->Add(thisStore);
242 AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
259 //_____________________________________________________________________________
261 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
263 /// Add one 2d store to another
265 TIter next(src.CreateIterator());
266 AliMUONVCalibParam* p;
268 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
270 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
274 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
278 AddCalibParams(*p,*a);
283 //_____________________________________________________________________________
285 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
287 /// Add one 1d store to another
289 TIter next(src.CreateIterator());
290 AliMUONVCalibParam* p;
292 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
294 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
298 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
302 AddCalibParams(*p,*a);
307 //_____________________________________________________________________________
309 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
312 for ( Int_t i = 0; i < src.Size(); ++i )
314 for ( Int_t j = 0; j < src.Dimension(); ++j )
316 dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
321 //_____________________________________________________________________________
323 AliMUONTrackerData::Replace(const AliMUONVStore& store)
325 /// Replace our values by values from the given external store
326 Bool_t rv = InternalAdd(store,0x0,kTRUE);
327 AliMUONVTrackerData::Replace(store);
331 //_____________________________________________________________________________
333 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
335 /// Add the given external store to our internal store
337 AliCodeTimerAuto(GetName());
341 if ( IsSingleEvent() && NumberOfEvents(-1) == 1 )
343 AliError(Form("%s is supposed to be single event only",GetName()));
350 fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
351 fNofEventsPerDDL = new Int_t[fNofDDLs];
352 for ( Int_t i = 0; i < fNofDDLs; ++i )
354 fNofEventsPerDDL[i] = 0;
360 if (nevents->GetSize() != fNofDDLs )
362 AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
363 nevents->GetSize(),fNofDDLs));
367 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
369 fNofEventsPerDDL[i] += nevents->At(i);
370 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
375 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
377 ++fNofEventsPerDDL[i];
378 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
384 Int_t numberOfBusPatches(0);
385 Int_t numberOfDEs(0);
387 // get number of bus patches and number of detection element
388 // to initialize fBusPatchValues and fDEValues below
390 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
391 while ( next() ) ++numberOfBusPatches;
392 AliMpDEIterator deIt;
394 while (!deIt.IsDone())
400 if ( fIsChannelLevelEnabled )
402 fChannelValues = new AliMUON2DMap(kTRUE);
404 if ( fIsManuLevelEnabled )
406 fManuValues = new AliMUON2DMap(kTRUE);
408 fPCBValues = new AliMUON2DMap(kFALSE);
409 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
410 fDEValues = new AliMUON1DMap(numberOfDEs);
411 fChamberValues = new AliMUON1DArray;
414 TIter next(store.CreateIterator());
415 AliMUONVCalibParam* external;
419 if ( IsSingleEvent() ) nk = 1;
421 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
423 if ( external->Dimension() != ExternalDimension() )
425 AliError(Form("Incompatible dimensions %d vs %d",
426 external->Dimension(),ExternalDimension()));
431 AliMUONVCalibParam* chamber, *de, *busPatch, *pcb, *manu, *channel;
432 AliMpDetElement* mpde;
434 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
436 if ( manuId < 0 ) continue;
438 Int_t detElemId = mpde->GetId();
440 Double_t value[] = { 0.0, 0.0 };
442 Int_t nch = mpde->NofChannelsInManu(manuId);
444 for ( Int_t i = 0; i < external->Size(); ++i )
446 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
447 : mpde->IsConnectedChannel(manuId,i));
448 // note we only use IsConnectedChannel method when really needed, as
449 // it costs (some) CPU time...
451 if ( existingChannel )
453 Bool_t validChannel(kFALSE);
455 for ( Int_t j = 0; j < external->Dimension(); ++j )
457 Double_t vext = external->IsDoublePrecision() ?
458 external->ValueAsDoubleFast(i,j) :
459 external->ValueAsFloatFast(i,j);
461 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
463 validChannel = kTRUE;
465 Int_t ix = External2Internal(j);
468 value[1] = vext*vext;
470 if ( IsHistogrammed(j) )
472 FillHisto(detElemId,manuId,i,j,vext);
475 for ( Int_t k = 0; k < nk; ++k )
477 Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
481 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
486 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);
489 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
491 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
493 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
497 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
502 if ( validChannel && !replace )
506 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
507 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
512 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
513 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
516 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
517 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
518 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
519 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
520 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
521 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
524 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
525 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
532 NumberOfEventsChanged();
537 //_____________________________________________________________________________
539 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
541 /// Return the value of a given buspatch for a given dimension
542 /// or 0 if not existing
543 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
544 return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
547 //_____________________________________________________________________________
549 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
551 /// Return (if it exist), the VCalibParam for a given busPatch
553 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
554 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
556 if (!busPatch && create && fBusPatchValues)
558 busPatch = CreateBusPatchParam(busPatchId);
559 fBusPatchValues->Add(busPatch);
565 //_____________________________________________________________________________
567 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
569 /// Create storage for one bus patch
571 AliCodeTimerAuto("");
573 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
577 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
581 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
583 // set the number of channels in that buspatch
587 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
589 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
591 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
593 Int_t manuId = bp->GetManuId(i);
594 nchannels += de->NofChannelsInManu(manuId);
597 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
602 //_____________________________________________________________________________
604 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
606 /// Return the value fo a given chamber for a given dimension,
607 /// or zero if not existing
609 // FIXME: is the Value() correct wrt to number of events in the case of
610 // chamber ? Or should we do something custom at the chamber level
611 // (as it spans several ddls) ?
613 AliMUONVCalibParam* param = ChamberParam(chamberId);
614 return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
617 //_____________________________________________________________________________
619 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
621 /// Return (if it exist) the VCalibParam for a given chamber
623 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
624 (fChamberValues->FindObject(chamberId)) : 0x0;
626 if (!chamber && create && fChamberValues)
628 chamber = CreateChamberParam(chamberId);
629 fChamberValues->Add(chamber);
635 //_____________________________________________________________________________
637 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
639 /// Create storage for one chamber
641 AliCodeTimerAuto("");
643 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
645 // set the number of channels in that chamber
653 while ( !it.IsDone() )
655 AliMpDetElement* det = it.CurrentDE();
657 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
659 Int_t busPatchId = det->GetBusPatchId(i);
660 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
661 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
663 Int_t manuId = bp->GetManuId(j);
664 nchannels += det->NofChannelsInManu(manuId);
671 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
676 //_____________________________________________________________________________
678 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
679 Int_t manuChannel, Int_t dim) const
681 /// Return the value for a given channel for a given dimension
683 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
685 return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
688 //_____________________________________________________________________________
690 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
691 AliMUONVCalibParam* external) const
693 /// Return (if it exist) the VCalibParam for a given manu
695 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
696 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
698 if (!param && external && fChannelValues)
700 param = CreateDouble(*external,detElemId,manuId);
701 fChannelValues->Add(param);
707 //_____________________________________________________________________________
709 AliMUONTrackerData::Clear(Option_t*)
711 /// Clear all the values
712 if ( fChannelValues ) fChannelValues->Clear();
713 if ( fManuValues ) fManuValues->Clear();
714 if ( fBusPatchValues) fBusPatchValues->Clear();
715 if ( fPCBValues ) fPCBValues->Clear();
716 if ( fDEValues) fDEValues->Clear();
717 if ( fChamberValues ) fChamberValues->Clear();
718 if ( fHistos ) fHistos->Clear();
719 for ( Int_t i = 0; i < fNofDDLs; ++i )
721 fNofEventsPerDDL[i] = 0;
723 NumberOfEventsChanged();
726 //_____________________________________________________________________________
728 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
729 Int_t manuChannel) const
731 /// Return the number of times a given channel had data
733 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
736 //_____________________________________________________________________________
738 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
739 Int_t detElemId, Int_t manuId) const
741 /// Create a double version of VCalibParam, for internal use
743 AliCodeTimerAuto("");
745 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
751 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
753 for ( Int_t i = 0; i < c->Size(); ++i )
757 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
759 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
765 //_____________________________________________________________________________
767 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
769 /// Return the value for a given detection element for a given dimension
770 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
771 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
775 //_____________________________________________________________________________
777 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
779 /// Return (if it exist) the VCalibParam for a given detection element
781 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
782 (fDEValues->FindObject(detElemId)) : 0x0 ;
784 if (!de && create && fDEValues)
786 de = CreateDetectionElementParam(detElemId);
794 //_____________________________________________________________________________
796 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
798 /// Create storage for one detection element
800 AliCodeTimerAuto("");
802 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
804 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
807 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
809 Int_t busPatchId = det->GetBusPatchId(i);
810 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
811 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
813 Int_t manuId = bp->GetManuId(j);
814 nchannels += det->NofChannelsInManu(manuId);
818 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
823 //_____________________________________________________________________________
825 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
827 /// Get the "local" ddlid (0..19) of a given buspatch
828 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
831 return bp->GetDdlId();
836 //_____________________________________________________________________________
838 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
840 /// Get the "local" ddlid (0..19) of a given detection element
841 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
844 return de->GetDdlId();
849 //_____________________________________________________________________________
851 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
853 /// Get the "local" ddlid (0..19) of a given chamber
854 /// This has no real meaning (as there are several ddls per chamber),
855 /// so we take the ddlid where we got the max number of events
865 Int_t detElemId = it.CurrentDEId();
866 Int_t ddlId = DdlIdFromDetElemId(detElemId);
867 if ( NumberOfEvents(ddlId) > n )
869 n = NumberOfEvents(ddlId);
878 //_____________________________________________________________________________
880 AliMUONTrackerData::DimensionName(Int_t dim) const
882 /// Get the name of a given dimension
883 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
886 return value->String();
890 return TString("Invalid");
894 //_____________________________________________________________________________
896 AliMUONTrackerData::DisableChannelLevel()
898 /// Disable the storing of data at channel level
900 delete fChannelValues;
901 fChannelValues = 0x0;
902 fIsChannelLevelEnabled = kFALSE;
905 //_____________________________________________________________________________
907 AliMUONTrackerData::DisableManuLevel()
909 /// Disable the storing of data at manu level (and below)
911 DisableChannelLevel();
914 fIsManuLevelEnabled = kFALSE;
917 //_____________________________________________________________________________
919 AliMUONTrackerData::External2Internal(Int_t index) const
921 /// From external to internal dimension
922 return IsSingleEvent() ? index : index*2;
925 //_____________________________________________________________________________
927 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
929 /// Get the name of a given external dimension
931 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
934 return value->String();
938 return TString("Invalid");
942 //_____________________________________________________________________________
944 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
945 Int_t dim, Double_t value)
947 /// Fill histogram of a given channel
949 AliMUONSparseHisto* h(0x0);
951 if ( fIsChannelLevelEnabled )
953 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
955 else if ( fIsManuLevelEnabled )
957 h = GetManuSparseHisto(detElemId,manuId,dim);
960 AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
964 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
968 //_____________________________________________________________________________
970 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId,
973 /// Get histogram of a given manu
975 if (!fHistos) return 0x0;
977 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
980 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
985 //_____________________________________________________________________________
987 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
989 /// Get histogram of a given manu. Create it if necessary
991 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
993 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
996 m = new AliMUON1DArray(NumberOfDimensions());
997 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1001 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1004 h = new AliMUONSparseHisto(fXmin,fXmax);
1006 h->SetUniqueID(dim);
1014 //_____________________________________________________________________________
1016 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1017 Int_t manuChannel, Int_t dim) const
1019 /// Get histogram of a given channel
1021 if (!fHistos) return 0x0;
1023 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1026 UInt_t uid = ( manuChannel << 16 ) | dim;
1028 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1033 //_____________________________________________________________________________
1035 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1036 Int_t manuChannel, Int_t dim)
1038 /// Get histogram of a given channel. Create it if necessary
1040 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1042 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1045 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1046 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1050 UInt_t uid = ( manuChannel << 16 ) | dim;
1052 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1055 h = new AliMUONSparseHisto(fXmin,fXmax);
1057 h->SetUniqueID(uid);
1065 //_____________________________________________________________________________
1067 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1068 Int_t& detElemId, Int_t& manuId) const
1070 /// Tries to get (detElemId,manuId) of param
1072 // Load mapping manu store
1073 if ( ! AliMpCDB::LoadManuStore() ) {
1074 AliError("Could not access manu store from OCDB !");
1078 if ( param.ID1() <= 0 )
1080 // we (probably) get a manu serial number
1081 Int_t serial = param.ID0();
1082 MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1083 detElemId = AliMp::PairFirst(pair);
1084 manuId = AliMp::PairSecond(pair);
1087 AliError(Form("DE %d manuId %d from serial %d is not correct !",
1088 detElemId,manuId,serial));
1093 // we get a (de,manu) pair
1094 detElemId = param.ID0();
1095 manuId = param.ID1();
1100 //_____________________________________________________________________________
1102 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1103 AliMUONVCalibParam*& chamber,
1104 AliMUONVCalibParam*& de,
1105 AliMUONVCalibParam*& busPatch,
1106 AliMUONVCalibParam*& pcb,
1107 AliMUONVCalibParam*& manu,
1108 AliMUONVCalibParam*& channel,
1109 AliMpDetElement*& mpde)
1111 /// Get containers at all levels
1113 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1118 GetDEManu(*external,detElemId,manuId);
1120 mpde = ddlStore->GetDetElement(detElemId);
1122 if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1127 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1129 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1131 Int_t pcbIndex = -1;
1133 AliMp::StationType stationType = mpde->GetStationType();
1135 if ( stationType == AliMp::kStation345 )
1137 AliMpDCSNamer namer("TRACKER");
1138 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1141 channel = ChannelParam(detElemId,manuId,external);
1143 manu = ManuParam(detElemId,manuId,kTRUE);
1145 busPatch = BusPatchParam(busPatchId,kTRUE);
1147 de = DetectionElementParam(detElemId,kTRUE);
1149 chamber = ChamberParam(chamberId,kTRUE);
1153 if ( pcbIndex >= 0 )
1155 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1161 //_____________________________________________________________________________
1163 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1165 /// Whether we have data for a given buspatch
1166 return ( BusPatchParam(busPatchId) != 0 );
1169 //_____________________________________________________________________________
1171 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1173 /// Whether we have data for a given chamber
1174 return ( ChamberParam(chamberId) != 0 );
1177 //_____________________________________________________________________________
1179 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1181 /// Whether we have data for a given detection element
1182 return ( DetectionElementParam(detElemId) != 0 );
1185 //_____________________________________________________________________________
1187 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1189 /// Whether we have data for a given manu
1190 return ( ManuParam(detElemId,manuId) != 0 );
1193 //_____________________________________________________________________________
1195 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1197 /// Whether we have data for a given pcb
1198 return ( PCBParam(detElemId,pcbIndex) != 0 );
1201 //_____________________________________________________________________________
1203 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1205 /// Return the value for a given manu and a given dimension
1207 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1208 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1211 //_____________________________________________________________________________
1213 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1215 /// Get the VCalibParam for a given manu
1217 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1218 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1220 if (!manu && create && fManuValues)
1222 manu = CreateManuParam(detElemId,manuId);
1223 fManuValues->Add(manu);
1229 //_____________________________________________________________________________
1231 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1233 /// Create storage for one manu
1235 AliCodeTimerAuto("");
1237 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1239 // set the number of channels in that manu
1241 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1243 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1248 //_____________________________________________________________________________
1250 AliMUONTrackerData::Merge(TCollection* list)
1252 /// Merge this with a list of AliMUONVTrackerData
1254 if (!list) return 0;
1256 if ( list->IsEmpty() ) return NumberOfEvents(-1);
1259 const TObject* o(0x0);
1261 while ( ( o = next() ) )
1263 const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1266 AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1271 Bool_t ok = Add(*data);
1274 AliError("Got incompatible objects");
1279 return NumberOfEvents(-1);
1282 //_____________________________________________________________________________
1284 AliMUONTrackerData::NumberOfDimensions() const
1286 /// Number of dimensions we're dealing with
1288 return fDimension + fgkVirtualExtraDimension;
1291 //_____________________________________________________________________________
1293 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1295 /// Get the number of events we've seen for a given DDL, or the max
1296 /// in case ddlNumber<0
1300 if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1302 n = fNofEventsPerDDL[ddlNumber];
1306 // get the max number of events
1313 //_____________________________________________________________________________
1315 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1317 /// Return the value of a given pcb for a given dimension
1319 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1321 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1324 //_____________________________________________________________________________
1326 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1328 /// Return (if it exist) the VCalibParam for a given pcb
1330 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
1331 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1333 if (create && fPCBValues && !pcb)
1335 pcb = CreatePCBParam(detElemId,pcbIndex);
1336 fPCBValues->Add(pcb);
1342 //_____________________________________________________________________________
1344 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1346 /// Create storage for one PCB (station345 only)
1348 AliCodeTimerAuto("");
1350 AliMpDCSNamer namer("TRACKER");
1352 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1353 namer.NumberOfPCBs(detElemId),
1360 //_____________________________________________________________________________
1362 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1368 if ( !fIsSingleEvent )
1370 for ( Int_t i = 0; i < fNofDDLs; ++i )
1372 cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1376 if ( !fIsChannelLevelEnabled )
1378 cout << "Is not storing data at the channel level" << endl;
1381 if ( !fIsManuLevelEnabled )
1383 cout << "Is not storing data at the manu level" << endl;
1386 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
1388 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1389 cout << Form("External Dimension %2d Name %s %s",i,
1390 ( name ? name->String().Data() : "null"),
1391 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1394 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
1396 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1397 cout << Form("Internal Dimension %2d Name %s",i,
1398 ( name ? name->String().Data() : "null")) << endl;
1404 if ( sopt.Contains("CHANNEL") )
1406 if ( fIsChannelLevelEnabled )
1408 if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1412 AliWarning("You requested channel values, but they were not stored !");
1416 if ( sopt.Contains("MANU") )
1418 if ( fIsManuLevelEnabled )
1420 if ( fManuValues ) fManuValues->Print(wildcard,opt);
1424 AliWarning("You requested manu values, but they were not stored !");
1428 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
1430 fBusPatchValues->Print(wildcard,opt);
1433 if ( sopt.Contains("DE") && fDEValues )
1435 fDEValues->Print(wildcard,opt);
1438 if ( sopt.Contains("CHAMBER") && fChamberValues )
1440 fChamberValues->Print(wildcard,opt);
1445 //_____________________________________________________________________________
1447 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
1449 /// Set the name of a given dimension
1451 if ( index >= fExternalDimension )
1453 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1457 Int_t ix = External2Internal(index);
1459 if ( !IsSingleEvent() )
1461 const char* prefix[] = { "mean", "sigma" };
1463 for ( Int_t i = 0; i < 2; ++i )
1467 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
1472 SetInternalDimensionName(index,name);
1475 SetExternalDimensionName(index,name);
1478 //_____________________________________________________________________________
1480 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
1482 /// decide to make histos for a given dimension
1483 if ( index >= ExternalDimension() )
1485 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
1489 fHistogramming[index] = value;
1494 //_____________________________________________________________________________
1496 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
1498 /// Set the name of a given internal dimension
1499 if ( index >= fDimension )
1501 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
1505 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
1509 fDimensionNames->Remove(ovalue);
1512 fDimensionNames->AddAt(new TObjString(value),index);
1515 //_____________________________________________________________________________
1517 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
1519 /// Set the name of a given external dimension
1520 if ( index >= fExternalDimension )
1522 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1526 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
1530 fExternalDimensionNames->Remove(ovalue);
1533 fExternalDimensionNames->AddAt(new TObjString(value),index);
1536 //_____________________________________________________________________________
1538 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i,
1539 Int_t dim, Int_t ddlId) const
1541 /// Compute the value for a given dim, using the internal information we have
1542 /// Basically we're converting sum of weights and sum of squares of weights
1543 /// into means and sigmas, and number of events into occupancy number.
1545 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
1547 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
1549 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
1551 if ( dim >= fDimension )
1556 if ( dim == IndexOfOccupancyDimension() )
1558 if ( ddlId < 0 ) AliError("Got a negative ddl id !");
1559 return occ/n/NumberOfEvents(ddlId);
1562 Double_t value = param.ValueAsDouble(i,dim);
1564 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
1566 if ( TMath::Even(dim) || IsSingleEvent() )
1568 Double_t x = value/occ;
1570 return ( TMath::Finite(x) ? x : 0.0 ) ;
1578 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
1580 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
1588 AliError("Why am I here ?");
1592 //_____________________________________________________________________________
1594 AliMUONTrackerData::Streamer(TBuffer &R__b)
1596 /// Customized streamer
1598 if (R__b.IsReading()) {
1599 AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
1602 // backward compatible mode : we set number of events
1603 // per DDL to the total number of events (the only information
1604 // we had before version 7 of that class)
1605 delete[] fNofEventsPerDDL;
1607 fNofEventsPerDDL = new Int_t[fNofDDLs];
1608 for ( Int_t i = 0; i < fNofDDLs; ++i )
1610 fNofEventsPerDDL[i] = fNevents;
1615 AliMUONTrackerData::Class()->WriteBuffer(R__b, this);