X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;ds=sidebyside;f=MUON%2FAliMUONTrackerData.cxx;h=f377a5ac421d881c0554e6435610c2719f071e05;hb=106d1ca13052eee4d44bb6635c85164feb3f72a8;hp=c6bbc293c0123006ef004b98dce2f4918198ce74;hpb=7b6684fee09cb8cac37b3ed96dd6218fcce96da3;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONTrackerData.cxx b/MUON/AliMUONTrackerData.cxx index c6bbc293c01..f377a5ac421 100644 --- a/MUON/AliMUONTrackerData.cxx +++ b/MUON/AliMUONTrackerData.cxx @@ -18,27 +18,37 @@ #include "AliMUONTrackerData.h" #include "AliCodeTimer.h" +#include "AliDAQ.h" #include "AliLog.h" #include "AliMUON1DArray.h" #include "AliMUON1DMap.h" #include "AliMUON2DMap.h" #include "AliMUONCalibParamND.h" +#include "AliMUONConstants.h" +#include "AliMUONRejectList.h" #include "AliMUONSparseHisto.h" #include "AliMUONVStore.h" #include "AliMpBusPatch.h" #include "AliMpConstants.h" +#include "AliMpCDB.h" #include "AliMpDDLStore.h" +#include "AliMpManuStore.h" #include "AliMpDEIterator.h" #include "AliMpDEManager.h" #include "AliMpDetElement.h" -#include "AliMpHVNamer.h" +#include "AliMpDCSNamer.h" #include "AliMpManuIterator.h" +#include "AliMpEncodePair.h" +#include "AliMpSegmentation.h" #include +#include #include #include #include #include +#include #include +#include #include /// \class AliMUONTrackerData @@ -57,27 +67,33 @@ const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1; //_____________________________________________________________________________ AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title, Int_t dimension, - Bool_t runnable) + Bool_t issingleevent) : AliMUONVTrackerData(name,title), +fIsSingleEvent(issingleevent), fChannelValues(0x0), fManuValues(0x0), fBusPatchValues(0x0), fDEValues(0x0), fChamberValues(0x0), fPCBValues(0x0), -fDimension(dimension*2+fgkExtraDimension), -fNevents(0x0), +fDimension(External2Internal(dimension)+fgkExtraDimension), +fNevents(0), fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)), fExternalDimensionNames(new TObjArray(dimension)), fExternalDimension(dimension), -fIsRunnable(runnable), fHistogramming(new Int_t[fExternalDimension]), -fChannelHistos(0x0), +fHistos(0x0), fXmin(0.0), -fXmax(0.0) +fXmax(0.0), +fIsChannelLevelEnabled(kTRUE), +fIsManuLevelEnabled(kTRUE), +fIsBustPatchLevelEnabled(kTRUE), +fIsPCBLevelEnabled(kTRUE), +fNofDDLs(0), +fNofEventsPerDDL(0x0) { /// ctor - memset(fHistogramming,0,sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on. + memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on. fExternalDimensionNames->SetOwner(kTRUE); fDimensionNames->SetOwner(kTRUE); fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension()); @@ -86,6 +102,411 @@ fXmax(0.0) Clear(); } +//_____________________________________________________________________________ +AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title, + const AliMUONVStore& manuValues) +: AliMUONVTrackerData(name,title), +fIsSingleEvent(kFALSE), +fChannelValues(0x0), +fManuValues(0x0), +fBusPatchValues(0x0), +fDEValues(0x0), +fChamberValues(0x0), +fPCBValues(0x0), +fDimension(0), +fNevents(0), +fDimensionNames(0x0), +fExternalDimensionNames(0x0), +fExternalDimension(0), +fHistogramming(0x0), +fHistos(0x0), +fXmin(0.0), +fXmax(0.0), +fIsChannelLevelEnabled(kFALSE), +fIsManuLevelEnabled(kTRUE), +fIsBustPatchLevelEnabled(kTRUE), +fIsPCBLevelEnabled(kTRUE), +fNofDDLs(0), +fNofEventsPerDDL(0x0) +{ + /// ctor with pre-computed values at the manu level + /// In this case, we force fIsChannelLevelEnabled = kFALSE + /// ctor + + if (manuValues.GetSize()==0) + { + AliFatal("Cannot create a tracker data from nothing in that case !"); + } + + if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) ) + { + AliError("Cannot work without (full) mapping"); + return; + } + + TIter next(manuValues.CreateIterator()); + AliMUONVCalibParam* m = static_cast(next()); + + Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2; + + fDimension = External2Internal(dimension)+fgkExtraDimension; + + fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension); + fExternalDimensionNames = new TObjArray(dimension); + fExternalDimension = dimension; + fHistogramming = new Int_t[fExternalDimension]; + memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on. + + fExternalDimensionNames->SetOwner(kTRUE); + fDimensionNames->SetOwner(kTRUE); + fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension()); + fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension()); + fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension); + Clear(); + TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK")); + AssertStores(); + + next.Reset(); + AliMUONVCalibParam* external; + + while ( ( external = static_cast(next()) ) ) + { + Int_t detElemId, manuId; + + GetDEManu(*external,detElemId,manuId); + + AliMUONVCalibParam* chamber(0x0); + AliMUONVCalibParam* de(0x0); + AliMUONVCalibParam* busPatch(0x0); + AliMUONVCalibParam* pcb(0x0); + AliMUONVCalibParam* manu(0x0); + AliMUONVCalibParam* channel(0x0); + AliMpDetElement* mpde(0x0); + + AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,manuId,0); + // as external, but without event count + wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0)); + wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1)); + wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2)); + wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3)); + + Int_t mid = GetParts(wec,chamber,de,busPatch,pcb,manu,channel,mpde); + + if ( manuId != mid ) + { + AliError(Form("Something is wrong for DE %5d : manuId = %d vs mid = %d",detElemId,manuId,mid)); + continue; + } + + if ( manuId < 0 ) + { + AliError("Got a < 0 manuId. Should not happen here !"); + continue; + } + + assert(channel==0x0); + + Int_t n1 = manu->ValueAsInt(0,IndexOfNumberDimension()); + Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension()); + if ( n1 != n2 ) + { + AliError(Form("Incoherent number of manu channels for DE %5d MANU %5d : %d vs %d", + detElemId,manuId,n1,n2)); + } + + Int_t nevt = external->ValueAsInt(0,4); + + Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId); + + Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus(busPatchId); + + if ( nevents[ddl] == 0 ) + { + nevents[ddl] = nevt; + } + else + { + if ( nevents.At(ddl) != nevt ) + { + AliError(Form("Nevt mismatch for DE %5d MANU %5d DDL %d : %d vs %d", + detElemId,manuId,ddl,nevents.At(ddl),nevt)); + continue; + } + } + + for ( Int_t i = 0; i < wec->Dimension()-1; ++i ) + { + manu->SetValueAsDouble(0,i,manu->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i)); + + busPatch->SetValueAsDouble(0,i,busPatch->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i)); + + de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i)); + + chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i)); + } + delete wec; + } + + UpdateNumberOfEvents(&nevents); + +} + +//_____________________________________________________________________________ +AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title, + const AliMUONVStore& deValues, Int_t val) +: AliMUONVTrackerData(name,title), +fIsSingleEvent(kFALSE), +fChannelValues(0x0), +fManuValues(0x0), +fBusPatchValues(0x0), +fDEValues(0x0), +fChamberValues(0x0), +fPCBValues(0x0), +fDimension(0), +fNevents(0), +fDimensionNames(0x0), +fExternalDimensionNames(0x0), +fExternalDimension(0), +fHistogramming(0x0), +fHistos(0x0), +fXmin(0.0), +fXmax(0.0), +fIsChannelLevelEnabled(kFALSE), +fIsManuLevelEnabled(kFALSE), +fIsBustPatchLevelEnabled(kFALSE), +fIsPCBLevelEnabled(kFALSE), +fNofDDLs(0), +fNofEventsPerDDL(0x0) +{ + /// ctor with values at the detection element level + /// In this case, we force fIsChannelLevelEnabled = fIsManuLevelEnabled = kFALSE + /// ctor + + if (deValues.GetSize()==0) + { + AliFatal("Cannot create a tracker data from nothing in that case !"); + } + + if ( val != 1 ) + { + AliFatal("Wrong parameter. For DE, must be 1"); + } + + if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) ) + { + AliError("Cannot work without (full) mapping"); + return; + } + + TIter next(deValues.CreateIterator()); + AliMUONVCalibParam* m = static_cast(next()); + + Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2; + + fDimension = External2Internal(dimension)+fgkExtraDimension; + + fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension); + fExternalDimensionNames = new TObjArray(dimension); + fExternalDimension = dimension; + fHistogramming = new Int_t[fExternalDimension]; + memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on. + + fExternalDimensionNames->SetOwner(kTRUE); + fDimensionNames->SetOwner(kTRUE); + fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension()); + fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension()); + fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension); + Clear(); + TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK")); + AssertStores(); + + next.Reset(); + AliMUONVCalibParam* external; + + while ( ( external = static_cast(next()) ) ) + { + Int_t detElemId = external->ID0(); + + AliMpDetElement* mpde = AliMpDDLStore::Instance()->GetDetElement(detElemId,kFALSE); + + if (!mpde) + { + AliError(Form("Got an invalid DE (%d) from external store",detElemId)); + continue; + } + + Int_t chamberId = AliMpDEManager::GetChamberId(detElemId); + AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE); + AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE); + + AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,0,0); + // as external, but without event count + wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0)); + wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1)); + wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2)); + wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3)); + + Int_t n1 = de->ValueAsInt(0,IndexOfNumberDimension()); + Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension()); + if ( n1 != n2 ) + { + AliError(Form("Incoherent number of dimensions for DE%d : %d vs %d", + detElemId,n1,n2)); + continue; + } + + Int_t nevt = external->ValueAsInt(0,4); + + Int_t ddl = mpde->GetDdlId(); + + if ( nevents[ddl] == 0 ) + { + nevents[ddl] = nevt; + } + else + { + if ( nevents.At(ddl) != nevt ) + { + AliError(Form("Nevt mismatch for DE %5d DDL %d : %d vs %d", + detElemId,ddl,nevents.At(ddl),nevt)); + continue; + } + } + + for ( Int_t i = 0; i < wec->Dimension()-1; ++i ) + { + de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i)); + + chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i)); + } + delete wec; + } + + UpdateNumberOfEvents(&nevents); + +} + +//_____________________________________________________________________________ +AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title, + const AliMUONRejectList& rejectList) +: AliMUONVTrackerData(name,title), +fIsSingleEvent(kFALSE), +fChannelValues(0x0), +fManuValues(0x0), +fBusPatchValues(0x0), +fDEValues(0x0), +fChamberValues(0x0), +fPCBValues(0x0), +fDimension(External2Internal(1)+fgkExtraDimension), +fNevents(0), +fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)), +fExternalDimensionNames(new TObjArray(1)), +fExternalDimension(1), +fHistogramming(new Int_t[fExternalDimension]), +fHistos(0x0), +fXmin(0.0), +fXmax(0.0), +fIsChannelLevelEnabled(kTRUE), +fIsManuLevelEnabled(kTRUE), +fIsBustPatchLevelEnabled(kTRUE), +fIsPCBLevelEnabled(kFALSE), +fNofDDLs(0), +fNofEventsPerDDL(0x0) +{ + + /// ctor with values from the given rejectlist + + if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) ) + { + AliError("Cannot work without (full) mapping"); + return; + } + + memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on. + + fExternalDimensionNames->SetOwner(kTRUE); + fDimensionNames->SetOwner(kTRUE); + fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension()); + fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension()); + fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension); + Clear(); + TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK")); + AssertStores(); + + + for ( Int_t chamberId = 0; chamberId < AliMUONConstants::NCh(); ++chamberId ) + { + AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE); + + // FIXME : update the chamber value ! + + AliMpDEIterator deit; + + deit.First(chamberId); + + while ( !deit.IsDone() ) + { + AliMpDetElement* mpde = deit.CurrentDE(); + + Int_t detElemId = mpde->GetId(); + + AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE); + + DispatchValue(*de,0,rejectList.DetectionElementProbability(detElemId),0.0,mpde->NofChannels()); + + for ( Int_t iBusPatch = 0; iBusPatch < mpde->GetNofBusPatches(); ++iBusPatch ) + { + Int_t busPatchId = mpde->GetBusPatchId(iBusPatch); + + AliMUONVCalibParam* bp = BusPatchParam(busPatchId,kTRUE); + + AliMpBusPatch* mpbp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId); + + Int_t nch(0); + + for ( Int_t iManu = 0 ;iManu < mpbp->GetNofManus(); ++iManu ) + { + Int_t manuId = mpbp->GetManuId(iManu); + + nch += mpde->NofChannelsInManu(manuId); + + AliMUONVCalibParam* manu = ManuParam(detElemId,manuId,kTRUE); + + DispatchValue(*manu,0,rejectList.ManuProbability(detElemId,manuId),0.0,mpde->NofChannelsInManu(manuId)); + + AliMUONVCalibParam* c = ChannelParam(detElemId,manuId); + + if (!c) + { + c = new AliMUONCalibParamND(Dimension(), + AliMpConstants::ManuNofChannels(), + detElemId, + manuId, + 0.0); + fChannelValues->Add(c); + } + + for ( Int_t manuChannel = 0; manuChannel < AliMpConstants::ManuNofChannels(); ++manuChannel ) + { + DispatchValue(*c,manuChannel,rejectList.ChannelProbability(detElemId,manuId,manuChannel),0.0,1); + } + } + + DispatchValue(*bp,0,rejectList.BusPatchProbability(busPatchId),0.0,nch); + + } + + deit.Next(); + } + + } + + + SetDimensionName(0,"RejectProba"); + + UpdateNumberOfEvents(0x0); +} + //_____________________________________________________________________________ AliMUONTrackerData::~AliMUONTrackerData() { @@ -99,33 +520,343 @@ AliMUONTrackerData::~AliMUONTrackerData() delete fDimensionNames; delete fExternalDimensionNames; delete[] fHistogramming; - delete fChannelHistos; + delete fHistos; + delete[] fNofEventsPerDDL; +} + +//_____________________________________________________________________________ +Bool_t +AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents) +{ + /// Add the given external store to our internal store + return InternalAdd(store,nevents,kFALSE); +} + +//_____________________________________________________________________________ +Bool_t +AliMUONTrackerData::Add(const AliMUONTrackerData& data) +{ + /// Add data to *this + // We do this by looping on all VCalibParam stored in the various containers, + // and simply adding the values there. + // Same thing for the number of events per DDL. + // Same thing for sparsehistograms, if we have some. + + // First cross check we have compatible objects. + + if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled ) + { + AliError("Incompatible IsChannelLevelEnabled status"); + return kFALSE; + } + + if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled ) + { + AliError("Incompatible IsManuLevelEnabled status"); + return kFALSE; + } + + if ( fIsSingleEvent != data.fIsSingleEvent ) + { + AliError("Incompatible IsSingleEvent status"); + return kFALSE; + } + + if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension ) + { + AliError("Incompatible dimensions"); + return kFALSE; + } + + if ( fNofDDLs != data.fNofDDLs ) + { + AliError("Incompatible number of Ddls"); + return kFALSE; + } + + if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming ) + || fXmin != data.fXmin || fXmax != data.fXmax ) + { + AliError(Form("Incompatible histogramming (%p vs %p) (xmax = %e vs %e ; xmin = %e vs %e)", + fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin)); + return kFALSE; + } + + if ( fHistogramming ) + { + for ( Int_t i = 0; i < fExternalDimension; ++i ) + { + if ( fHistogramming[i] != data.fHistogramming[i] ) + { + AliError(Form("Incompatible histogramming for external dimension %d",i)); + return kFALSE; + } + } + } + + // OK. Seems we have compatible objects, so we can proceed with the actual + // merging... + + if ( data.fChannelValues ) + { + Add2D(*(data.fChannelValues),*fChannelValues); + } + + if ( data.fManuValues ) + { + Add2D(*(data.fManuValues),*fManuValues); + } + + if ( data.fPCBValues ) + { + Add2D(*(data.fPCBValues),*fPCBValues); + } + + if ( data.fBusPatchValues ) + { + Add1D(*(data.fBusPatchValues),*fBusPatchValues); + } + + if ( data.fDEValues ) + { + Add1D(*(data.fDEValues),*fDEValues); + } + + if ( data.fChamberValues ) + { + Add1D(*(data.fChamberValues),*fChamberValues); + } + + for ( Int_t i = 0; i < fNofDDLs; ++i ) + { + fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i]; + } + + if ( data.fHistos ) + { + TIter nexthisto(data.fHistos->CreateIterator()); + AliMUONVStore* store; + while ( ( store = static_cast(nexthisto()) ) ) + { + TIter ns(store->CreateIterator()); + AliMUONSparseHisto* h; + while ( ( h = static_cast(ns()) ) ) + { + AliMUONVStore* thisStore = static_cast(fHistos->FindObject(store->GetUniqueID())); + + if (!thisStore) + { + thisStore = store->Create(); + thisStore->SetUniqueID(store->GetUniqueID()); + fHistos->Add(thisStore); + } + + AliMUONSparseHisto* mine = static_cast(thisStore->FindObject(h->GetUniqueID())); + + if (!mine) + { + thisStore->Add(h); + } + else + { + mine->Add(*h); + } + } + } + } + + fNevents = TMath::Max(fNevents,data.fNevents); + + return kTRUE; +} + +//_____________________________________________________________________________ +void +AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const +{ + /// Add one 2d store to another + + TIter next(src.CreateIterator()); + AliMUONVCalibParam* p; + + while ( ( p = static_cast(next()) ) ) + { + AliMUONVCalibParam* a = static_cast(dest.FindObject(p->ID0(),p->ID1())); + + if (!a) + { + dest.Add(static_cast(p->Clone())); + } + else + { + AddCalibParams(*p,*a); + } + } +} + +//_____________________________________________________________________________ +void +AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const +{ + /// Add one 1d store to another + + TIter next(src.CreateIterator()); + AliMUONVCalibParam* p; + + while ( ( p = static_cast(next()) ) ) + { + AliMUONVCalibParam* a = static_cast(dest.FindObject(p->GetUniqueID())); + + if (!a) + { + dest.Add(static_cast(p->Clone())); + } + else + { + AddCalibParams(*p,*a); + } + } +} + +//_____________________________________________________________________________ +void +AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const +{ + /// Add src to dest + for ( Int_t i = 0; i < src.Size(); ++i ) + { + for ( Int_t j = 0; j < src.Dimension(); ++j ) + { + dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j)); + } + } +} + +//_____________________________________________________________________________ +Bool_t +AliMUONTrackerData::Replace(const AliMUONVStore& store) +{ + /// Replace our values by values from the given external store + Bool_t rv = InternalAdd(store,0x0,kTRUE); + AliMUONVTrackerData::Replace(store); + return rv; +} + +//_____________________________________________________________________________ +Bool_t +AliMUONTrackerData::UpdateNumberOfEvents(TArrayI* nevents) +{ + /// Update the number of events + + if (!fNofDDLs) + { + fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK"); + fNofEventsPerDDL = new Int_t[fNofDDLs]; + for ( Int_t i = 0; i < fNofDDLs; ++i ) + { + fNofEventsPerDDL[i] = 0; + } + } + + if (nevents) + { + if (nevents->GetSize() != fNofDDLs ) + { + AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d", + nevents->GetSize(),fNofDDLs)); + return kFALSE; + } + + for ( Int_t i = 0 ; i < fNofDDLs; ++i ) + { + fNofEventsPerDDL[i] += nevents->At(i); + fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]); + } + } + else + { + for ( Int_t i = 0 ; i < fNofDDLs; ++i ) + { + ++fNofEventsPerDDL[i]; + fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]); + } + } + return kTRUE; +} + +//_____________________________________________________________________________ +void +AliMUONTrackerData::AssertStores() +{ + /// Insure our stores are allocated + + if (!fChamberValues) + { + Int_t numberOfBusPatches(0); + Int_t numberOfDEs(0); + + // get number of bus patches and number of detection element + // to initialize fBusPatchValues and fDEValues below + + TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator()); + while ( next() ) ++numberOfBusPatches; + AliMpDEIterator deIt; + deIt.First(); + while (!deIt.IsDone()) + { + ++numberOfDEs; + deIt.Next(); + } + + if ( fIsChannelLevelEnabled ) + { + fChannelValues = new AliMUON2DMap(kTRUE); + } + if ( fIsManuLevelEnabled ) + { + fManuValues = new AliMUON2DMap(kTRUE); + } + if ( fIsPCBLevelEnabled ) + { + fPCBValues = new AliMUON2DMap(kFALSE); + } + if ( fIsBustPatchLevelEnabled ) + { + fBusPatchValues = new AliMUON1DMap(numberOfBusPatches); + } + fDEValues = new AliMUON1DMap(numberOfDEs); + fChamberValues = new AliMUON1DArray; + } } //_____________________________________________________________________________ Bool_t -AliMUONTrackerData::Add(const AliMUONVStore& store, Int_t numberOfEvents) +AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace) { /// Add the given external store to our internal store - AliCodeTimerAuto(GetName()); + AliCodeTimerAuto(GetName(),0); - fNevents += numberOfEvents; - NumberOfEventsChanged(); - - if (!fChannelValues) + if ( !replace) { - fChannelValues = new AliMUON2DMap(kTRUE); - fManuValues = new AliMUON2DMap(kTRUE); - fPCBValues = new AliMUON2DMap(kFALSE); - fBusPatchValues = new AliMUON1DMap; - fDEValues = new AliMUON1DMap; - fChamberValues = new AliMUON1DArray; + if ( IsSingleEvent() && NumberOfEvents(-1) == 1 ) + { + AliError(Form("%s is supposed to be single event only",GetName())); + return kFALSE; + } } + + UpdateNumberOfEvents(nevents); + + AssertStores(); TIter next(store.CreateIterator()); AliMUONVCalibParam* external; + Int_t nk(2); + + if ( IsSingleEvent() ) nk = 1; + while ( ( external = static_cast(next()) ) ) { if ( external->Dimension() != ExternalDimension() ) @@ -135,9 +866,13 @@ AliMUONTrackerData::Add(const AliMUONVStore& store, Int_t numberOfEvents) return kFALSE; } - - AliMUONVCalibParam* chamber, *de, *busPatch, *pcb, *manu, *channel; - AliMpDetElement* mpde; + AliMUONVCalibParam* chamber(0x0); + AliMUONVCalibParam* de(0x0); + AliMUONVCalibParam* busPatch(0x0); + AliMUONVCalibParam* pcb(0x0); + AliMUONVCalibParam* manu(0x0); + AliMUONVCalibParam* channel(0x0); + AliMpDetElement* mpde(0x0); Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde); @@ -177,34 +912,50 @@ AliMUONTrackerData::Add(const AliMUONVStore& store, Int_t numberOfEvents) if ( IsHistogrammed(j) ) { - FillChannel(detElemId,manuId,i,j,vext); + FillHisto(detElemId,manuId,i,j,vext); } - for ( Int_t k = 0; k < 2; ++k ) + for ( Int_t k = 0; k < nk; ++k ) { - channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)+value[k]); - - manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)+value[k]); + Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0; + + if ( channel ) + { + channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]); + } + + if (manu) + { + manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]); + } + + busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]); + + de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]); + + chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]); - busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)+value[k]); - - de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)+value[k]); - - chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)+value[k]); - if ( pcb ) { - pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)+value[k]); + pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]); } } } - if ( validChannel ) + if ( validChannel && !replace ) { - channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(), - channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0); - manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(), - manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0); + if ( channel ) + { + channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(), + channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0); + } + + if (manu) + { + manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(), + manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0); + } + busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(), busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0); de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(), @@ -221,6 +972,8 @@ AliMUONTrackerData::Add(const AliMUONVStore& store, Int_t numberOfEvents) } } + NumberOfEventsChanged(); + return kTRUE; } @@ -231,7 +984,7 @@ AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const /// Return the value of a given buspatch for a given dimension /// or 0 if not existing AliMUONVCalibParam* param = BusPatchParam(busPatchId); - return param ? Value(*param,0,dim) : 0.0; + return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0; } //_____________________________________________________________________________ @@ -258,7 +1011,7 @@ AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const { /// Create storage for one bus patch - AliCodeTimerAuto(""); + AliCodeTimerAuto("",0); AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId); @@ -295,8 +1048,13 @@ AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const { /// Return the value fo a given chamber for a given dimension, /// or zero if not existing + + // FIXME: is the Value() correct wrt to number of events in the case of + // chamber ? Or should we do something custom at the chamber level + // (as it spans several ddls) ? + AliMUONVCalibParam* param = ChamberParam(chamberId); - return param ? Value(*param,0,dim) : 0.0; + return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0; } //_____________________________________________________________________________ @@ -323,7 +1081,7 @@ AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const { /// Create storage for one chamber - AliCodeTimerAuto(""); + AliCodeTimerAuto("",0); AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0); @@ -367,13 +1125,13 @@ AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId, AliMUONVCalibParam* param = ChannelParam(detElemId,manuId); - return param ? Value(*param,manuChannel,dim) : 0.0; + return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0; } //_____________________________________________________________________________ AliMUONVCalibParam* AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId, - AliMUONVCalibParam* external) const + const AliMUONVCalibParam* external) const { /// Return (if it exist) the VCalibParam for a given manu @@ -400,7 +1158,11 @@ AliMUONTrackerData::Clear(Option_t*) if ( fPCBValues ) fPCBValues->Clear(); if ( fDEValues) fDEValues->Clear(); if ( fChamberValues ) fChamberValues->Clear(); - if ( fChannelHistos ) fChannelHistos->Clear(); + if ( fHistos ) fHistos->Clear(); + for ( Int_t i = 0; i < fNofDDLs; ++i ) + { + fNofEventsPerDDL[i] = 0; + } fNevents = 0; NumberOfEventsChanged(); } @@ -422,7 +1184,7 @@ AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param, { /// Create a double version of VCalibParam, for internal use - AliCodeTimerAuto(""); + AliCodeTimerAuto("",0); AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(), param.Size(), @@ -450,7 +1212,7 @@ AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const { /// Return the value for a given detection element for a given dimension AliMUONVCalibParam* param = DetectionElementParam(detElemId); - return param ? Value(*param,0,dim) : 0.0; + return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0; } @@ -479,7 +1241,7 @@ AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const { /// Create storage for one detection element - AliCodeTimerAuto(""); + AliCodeTimerAuto("",0); AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0); @@ -502,6 +1264,61 @@ AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const return de; } +//_____________________________________________________________________________ +Int_t +AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const +{ + /// Get the "local" ddlid (0..19) of a given buspatch + AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid); + if (bp) + { + return bp->GetDdlId(); + } + return -1; +} + +//_____________________________________________________________________________ +Int_t +AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const +{ + /// Get the "local" ddlid (0..19) of a given detection element + AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid); + if (de) + { + return de->GetDdlId(); + } + return -1; +} + +//_____________________________________________________________________________ +Int_t +AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const +{ + /// Get the "local" ddlid (0..19) of a given chamber + /// This has no real meaning (as there are several ddls per chamber), + /// so we take the ddlid where we got the max number of events + + AliMpDEIterator it; + + it.First(chamberid); + Int_t n(0); + Int_t d(-1); + + while (!it.IsDone()) + { + Int_t detElemId = it.CurrentDEId(); + Int_t ddlId = DdlIdFromDetElemId(detElemId); + if ( NumberOfEvents(ddlId) > n ) + { + n = NumberOfEvents(ddlId); + d = ddlId; + } + it.Next(); + } + + return d; +} + //_____________________________________________________________________________ TString AliMUONTrackerData::DimensionName(Int_t dim) const @@ -518,6 +1335,37 @@ AliMUONTrackerData::DimensionName(Int_t dim) const } } +//_____________________________________________________________________________ +void +AliMUONTrackerData::DisableChannelLevel() +{ + /// Disable the storing of data at channel level + + delete fChannelValues; + fChannelValues = 0x0; + fIsChannelLevelEnabled = kFALSE; +} + +//_____________________________________________________________________________ +void +AliMUONTrackerData::DisableManuLevel() +{ + /// Disable the storing of data at manu level (and below) + + DisableChannelLevel(); + delete fManuValues; + fManuValues = 0x0; + fIsManuLevelEnabled = kFALSE; +} + +//_____________________________________________________________________________ +Int_t +AliMUONTrackerData::External2Internal(Int_t index) const +{ + /// From external to internal dimension + return IsSingleEvent() ? index : index*2; +} + //_____________________________________________________________________________ TString AliMUONTrackerData::ExternalDimensionName(Int_t dim) const @@ -537,14 +1385,74 @@ AliMUONTrackerData::ExternalDimensionName(Int_t dim) const //_____________________________________________________________________________ void -AliMUONTrackerData::FillChannel(Int_t detElemId, Int_t manuId, Int_t manuChannel, - Int_t dim, Double_t value) +AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel, + Int_t dim, Double_t value) { /// Fill histogram of a given channel - AliMUONSparseHisto* h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim); - - h->Fill(static_cast(TMath::Nint(value))); + AliMUONSparseHisto* h(0x0); + + if ( fIsChannelLevelEnabled ) + { + h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim); + } + else if ( fIsManuLevelEnabled ) + { + h = GetManuSparseHisto(detElemId,manuId,dim); + } + + AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h)); + + if (h) + { + h->Fill(static_cast(TMath::Nint(value))); + } +} + +//_____________________________________________________________________________ +AliMUONSparseHisto* +AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, + Int_t dim) const +{ + /// Get histogram of a given manu + + if (!fHistos) return 0x0; + + AliMUON1DArray* m = static_cast(fHistos->FindObject(detElemId,manuId)); + if (!m) return 0x0; + + AliMUONSparseHisto* h = static_cast(m->FindObject(dim)); + + return h; +} + +//_____________________________________________________________________________ +AliMUONSparseHisto* +AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim) +{ + /// Get histogram of a given manu. Create it if necessary + + if (!fHistos) fHistos = new AliMUON2DMap(kTRUE); + + AliMUON1DArray* m = static_cast(fHistos->FindObject(detElemId,manuId)); + if (!m) + { + m = new AliMUON1DArray(NumberOfDimensions()); + m->SetUniqueID( ( manuId << 16 ) | detElemId ); + fHistos->Add(m); + } + + AliMUONSparseHisto* h = static_cast(m->FindObject(dim)); + if (!h) + { + h = new AliMUONSparseHisto(fXmin,fXmax); + + h->SetUniqueID(dim); + + m->Add(h); + } + + return h; } //_____________________________________________________________________________ @@ -554,9 +1462,9 @@ AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, { /// Get histogram of a given channel - if (!fChannelHistos) return 0x0; + if (!fHistos) return 0x0; - AliMUON1DMap* m = static_cast(fChannelHistos->FindObject(detElemId,manuId)); + AliMUON1DMap* m = static_cast(fHistos->FindObject(detElemId,manuId)); if (!m) return 0x0; UInt_t uid = ( manuChannel << 16 ) | dim; @@ -573,14 +1481,14 @@ AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, { /// Get histogram of a given channel. Create it if necessary - if (!fChannelHistos) fChannelHistos = new AliMUON2DMap(kTRUE); + if (!fHistos) fHistos = new AliMUON2DMap(kTRUE); - AliMUON1DMap* m = static_cast(fChannelHistos->FindObject(detElemId,manuId)); + AliMUON1DMap* m = static_cast(fHistos->FindObject(detElemId,manuId)); if (!m) { m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim m->SetUniqueID( ( manuId << 16 ) | detElemId ); - fChannelHistos->Add(m); + fHistos->Add(m); } UInt_t uid = ( manuChannel << 16 ) | dim; @@ -598,6 +1506,41 @@ AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId, return h; } +//_____________________________________________________________________________ +void +AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param, + Int_t& detElemId, Int_t& manuId) const +{ + /// Tries to get (detElemId,manuId) of param + + // Load mapping manu store + if ( ! AliMpCDB::LoadManuStore() ) { + AliError("Could not access manu store from OCDB !"); + return; + } + + if ( param.ID1() <= 0 ) + { + // we (probably) get a manu serial number + Int_t serial = param.ID0(); + MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial); + detElemId = AliMp::PairFirst(pair); + manuId = AliMp::PairSecond(pair); + if ( !detElemId ) + { + AliDebug(1,Form("DE %d manuId %d from serial %d is not correct !", + detElemId,manuId,serial)); + } + } + else + { + // we get a (de,manu) pair + detElemId = param.ID0(); + manuId = param.ID1(); + } +} + + //_____________________________________________________________________________ Int_t AliMUONTrackerData::GetParts(AliMUONVCalibParam* external, @@ -611,49 +1554,54 @@ AliMUONTrackerData::GetParts(AliMUONVCalibParam* external, { /// Get containers at all levels + chamber = de = busPatch = pcb = manu = channel = 0x0; + mpde = 0x0; + AliMpDDLStore* ddlStore = AliMpDDLStore::Instance(); Int_t detElemId; Int_t manuId; - if ( external->ID1() <= 0 ) + GetDEManu(*external,detElemId,manuId); + + mpde = ddlStore->GetDetElement(detElemId,kFALSE); + + if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus { - // we get a manu serial number - Int_t serial = external->ID0(); - AliMpIntPair pair = ddlStore->GetDetElemIdManu(serial); - detElemId = pair.GetFirst(); - manuId = pair.GetSecond(); - if ( !detElemId ) - { - AliError(Form("DE %d manuId %d from serial %d is not correct !", - detElemId,manuId,serial)); - return -1; - } + return -1; } - else + + // explicitely check that de,manu is correct + const AliMpVSegmentation* mpseg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId,kFALSE); + + if (!mpseg) { - // we get a (de,manu) pair - detElemId = external->ID0(); - manuId = external->ID1(); + return -1; } - - mpde = ddlStore->GetDetElement(detElemId); - + Int_t chamberId = AliMpDEManager::GetChamberId(detElemId); Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId); + if ( busPatchId <= 0 ) + { + return -1; + } + Int_t pcbIndex = -1; AliMp::StationType stationType = mpde->GetStationType(); if ( stationType == AliMp::kStation345 ) { - AliMpHVNamer namer; + AliMpDCSNamer namer("TRACKER"); pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId); } - channel = ChannelParam(detElemId,manuId,external); + if ( fIsChannelLevelEnabled ) + { + channel = ChannelParam(detElemId,manuId,external); + } manu = ManuParam(detElemId,manuId,kTRUE); @@ -720,7 +1668,7 @@ AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const /// Return the value for a given manu and a given dimension AliMUONVCalibParam* param = ManuParam(detElemId,manuId); - return param ? Value(*param,0,dim) : 0.0; + return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0; } //_____________________________________________________________________________ @@ -747,7 +1695,7 @@ AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const { /// Create storage for one manu - AliCodeTimerAuto(""); + AliCodeTimerAuto("",0); AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0); @@ -762,13 +1710,36 @@ AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const //_____________________________________________________________________________ Long64_t -AliMUONTrackerData::Merge(TCollection* li) +AliMUONTrackerData::Merge(TCollection* list) { - /// Merge all tracker data objects from li into a single one. + /// Merge this with a list of AliMUONVTrackerData + + if (!list) return 0; + + if ( list->IsEmpty() ) return NumberOfEvents(-1); + + TIter next(list); + const TObject* o(0x0); - AliError("Not implemented yet"); + while ( ( o = next() ) ) + { + const AliMUONTrackerData* data = dynamic_cast(o); + if (!data) + { + AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it", + o->GetName())); + } + else + { + Bool_t ok = Add(*data); + if (!ok) + { + AliError("Got incompatible objects"); + } + } + } - return 0; + return NumberOfEvents(-1); } //_____________________________________________________________________________ @@ -780,6 +1751,28 @@ AliMUONTrackerData::NumberOfDimensions() const return fDimension + fgkVirtualExtraDimension; } +//_____________________________________________________________________________ +Int_t +AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const +{ + /// Get the number of events we've seen for a given DDL, or the max + /// in case ddlNumber<0 + + Int_t n(0); + + if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs ) + { + n = fNofEventsPerDDL[ddlNumber]; + } + else + { + // get the max number of events + return fNevents; + } + + return n; +} + //_____________________________________________________________________________ Double_t AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const @@ -788,7 +1781,7 @@ AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex); - return param ? Value(*param,pcbIndex,dim) : 0.0; + return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0; } //_____________________________________________________________________________ @@ -815,9 +1808,9 @@ AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const { /// Create storage for one PCB (station345 only) - AliCodeTimerAuto(""); + AliCodeTimerAuto("",0); - AliMpHVNamer namer; + AliMpDCSNamer namer("TRACKER"); AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(), namer.NumberOfPCBs(detElemId), @@ -835,11 +1828,24 @@ AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const TNamed::Print(opt); - if ( fIsRunnable ) + if ( !fIsSingleEvent ) { - cout << " Nevents=" << fNevents << endl; + for ( Int_t i = 0; i < fNofDDLs; ++i ) + { + cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl; + } } + if ( !fIsChannelLevelEnabled ) + { + cout << "Is not storing data at the channel level" << endl; + } + + if ( !fIsManuLevelEnabled ) + { + cout << "Is not storing data at the manu level" << endl; + } + for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i ) { TObjString* name = static_cast(fExternalDimensionNames->At(i)); @@ -858,14 +1864,28 @@ AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const TString sopt(opt); sopt.ToUpper(); - if ( sopt.Contains("CHANNEL") && fChannelValues ) + if ( sopt.Contains("CHANNEL") ) { - fChannelValues->Print(wildcard,opt); + if ( fIsChannelLevelEnabled ) + { + if ( fChannelValues ) fChannelValues->Print(wildcard,opt); + } + else + { + AliWarning("You requested channel values, but they were not stored !"); + } } - if ( sopt.Contains("MANU") && fManuValues ) + if ( sopt.Contains("MANU") ) { - fManuValues->Print(wildcard,opt); + if ( fIsManuLevelEnabled ) + { + if ( fManuValues ) fManuValues->Print(wildcard,opt); + } + else + { + AliWarning("You requested manu values, but they were not stored !"); + } } if ( sopt.Contains("BUSPATCH") && fBusPatchValues ) @@ -893,19 +1913,28 @@ AliMUONTrackerData::SetDimensionName(Int_t index, const char* name) if ( index >= fExternalDimension ) { - AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension)); + AliError(Form("%s : dimension %s : Index out of bounds : %d / %d", + GetName(), + name,index,fExternalDimension)); return; } Int_t ix = External2Internal(index); - const char* prefix[] = { "mean", "sigma" }; - - for ( Int_t i = 0; i < 2; ++i ) + if ( !IsSingleEvent() ) { - Int_t j = ix+i; + const char* prefix[] = { "mean", "sigma" }; + + for ( Int_t i = 0; i < 2; ++i ) + { + Int_t j = ix+i; - SetInternalDimensionName(j,Form("%s of %s",prefix[i],name)); + SetInternalDimensionName(j,Form("%s of %s",prefix[i],name)); + } + } + else + { + SetInternalDimensionName(index,name); } SetExternalDimensionName(index,name); @@ -922,6 +1951,8 @@ AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_ return; } + AliWarning(Form("Will %s make histogram for data %s index %d : that might ressemble a memory leak depending on the input data", + value ? "":"not", GetName(),index)); fHistogramming[index] = value; fXmin = xmin; fXmax = xmax; @@ -971,7 +2002,8 @@ AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value) //_____________________________________________________________________________ Double_t -AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, Int_t dim) const +AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, + Int_t dim, Int_t ddlId) const { /// Compute the value for a given dim, using the internal information we have /// Basically we're converting sum of weights and sum of squares of weights @@ -988,26 +2020,146 @@ AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, Int_t dim) c return occ; } - if ( dim == IndexOfOccupancyDimension() ) return occ/n/NumberOfEvents(); + if ( dim == IndexOfOccupancyDimension() ) + { + if ( ddlId < 0 ) AliError("Got a negative ddl id !"); + return occ/n/NumberOfEvents(ddlId); + } Double_t value = param.ValueAsDouble(i,dim); if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue(); - if ( TMath::Even(dim) ) + if ( TMath::Even(dim) || IsSingleEvent() ) { - return value/occ; + Double_t x = value/occ; + + return ( TMath::Finite(x) ? x : 0.0 ) ; } else { - Double_t n = occ; + Double_t nn = occ; - Double_t mean = param.ValueAsDouble(i,dim-1)/n; + if ( nn > 1.0 ) + { + Double_t mean = param.ValueAsDouble(i,dim-1)/nn; - return TMath::Sqrt(TMath::Abs((value-n*mean*mean)/(n-1.0))); + return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0))); + } + else + { + return 0.0; + } } AliError("Why am I here ?"); return 0.0; } +//_____________________________________________________________________________ +void +AliMUONTrackerData::Streamer(TBuffer &R__b) +{ + /// Customized streamer + + if (R__b.IsReading()) { + AliMUONTrackerData::Class()->ReadBuffer(R__b, this); + if ( !fNofDDLs ) + { + // backward compatible mode : we set number of events + // per DDL to the total number of events (the only information + // we had before version 7 of that class) + delete[] fNofEventsPerDDL; + fNofDDLs=20; + fNofEventsPerDDL = new Int_t[fNofDDLs]; + for ( Int_t i = 0; i < fNofDDLs; ++i ) + { + fNofEventsPerDDL[i] = fNevents; + } + } + } + else { + AliMUONTrackerData::Class()->WriteBuffer(R__b, this); + } +} + +//_____________________________________________________________________________ +Bool_t +AliMUONTrackerData::ExportAsASCIIOccupancyFile(const char* filename, Int_t runNumber) const +{ + /// Export only the occupancy part, in a format compatible with what + /// the online occupancy DA is writing + + if ( ! AliMpDDLStore::Instance(kFALSE) ) + { + AliError("Mapping not loaded. Cannot work"); + return kFALSE; + } + + if (!fManuValues) + { + AliError("No manu values. Cannot work"); + return kFALSE; + } + + ofstream out(filename); + + if (out.bad()) + { + AliError(Form("Cannot create file %s",filename)); + return kFALSE; + } + + out << "//===========================================================================" << endl; + out << "// Hit counter exported from $Id$" << endl; + out << "//===========================================================================" << endl; + out << "//" << endl; + out << "// * Run Number : " << runNumber << endl; + out << "// * File Creation Date : " << TTimeStamp().AsString("l") << endl; + out << "//---------------------------------------------------------------------------" << endl; + out << "// BP MANU SUM_N NEVENTS" << endl; + out << "//---------------------------------------------------------------------------" << endl; + + TIter next(fManuValues->CreateIterator()); + AliMUONVCalibParam* manu; + + while ( ( manu = static_cast(next()) ) ) + { + Int_t detElemId = manu->ID0(); + Int_t manuId = manu->ID1(); + Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId); + Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus( busPatchId); + if ( busPatchId < 0 || ddl < 0 ) + { + AliError(Form("Got invalid (DE,manu,bp,ddl)=(%d,%d,%d,%d). Skipping it",detElemId,manuId,busPatchId,ddl)); + continue; + } + + Int_t nevents = fNofEventsPerDDL[ddl]; + + out << Form("%5d %5d %10d %10d",busPatchId,manuId,manu->ValueAsInt(0,IndexOfOccupancyDimension()),nevents) << endl; + } + + out.close(); + return kTRUE; +} + +//_____________________________________________________________________________ +void AliMUONTrackerData::DispatchValue(AliMUONVCalibParam& param, + Int_t index, + Double_t y, + Double_t ey, + Int_t nchannels) +{ + /// fills the calibparam with a single value + + Double_t sumn = 1000.0; // or any value strictly above 1 + Double_t sumw = sumn*y; + Double_t sumw2 = (sumn-1)*ey*ey+sumw*sumw/sumn; + + param.SetValueAsDouble(index,0,sumw); + param.SetValueAsDouble(index,1,sumw2); + param.SetValueAsDouble(index,2,sumn); + param.SetValueAsDouble(index,3,nchannels); + +} \ No newline at end of file