#include "AliMUONTrackerData.h"
+#include "AliCodeTimer.h"
+#include "AliLog.h"
+#include "AliMUON1DArray.h"
+#include "AliMUON1DMap.h"
+#include "AliMUON2DMap.h"
#include "AliMUONCalibParamND.h"
+#include "AliMUONSparseHisto.h"
#include "AliMUONVStore.h"
#include "AliMpBusPatch.h"
+#include "AliMpConstants.h"
#include "AliMpDDLStore.h"
-#include "AliMpDEManager.h"
#include "AliMpDEIterator.h"
+#include "AliMpDEManager.h"
#include "AliMpDetElement.h"
#include "AliMpHVNamer.h"
-#include "AliCodeTimer.h"
-#include "AliLog.h"
+#include "AliMpManuIterator.h"
#include <Riostream.h>
+#include <TH1.h>
#include <TMath.h>
#include <TObjArray.h>
#include <TObjString.h>
fDimension(dimension*2+fgkExtraDimension),
fNevents(0x0),
fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
+fExternalDimensionNames(new TObjArray(dimension)),
fExternalDimension(dimension),
-fIsRunnable(runnable)
+fIsRunnable(runnable),
+fHistogramming(new Int_t[fExternalDimension]),
+fChannelHistos(0x0)
{
/// ctor
+ memset(fHistogramming,0,sizeof(Int_t)); // histogramming is off by default. Use SetHistogramDimension to turn it on.
+ fExternalDimensionNames->SetOwner(kTRUE);
fDimensionNames->SetOwner(kTRUE);
fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
delete fChamberValues;
delete fPCBValues;
delete fDimensionNames;
+ delete fExternalDimensionNames;
+ delete[] fHistogramming;
+ delete fChannelHistos;
}
//_____________________________________________________________________________
Bool_t
AliMUONTrackerData::Add(const AliMUONVStore& store)
{
- /// We first convert the external store to a temporary internal store
- /// with more dimension (2*store's dimension)
+ /// Add the given external store to our internal store
- AliCodeTimerAuto(GetName())
-
- Int_t ndim(NumberOfDimensions()-fgkExtraDimension-fgkVirtualExtraDimension);
+ AliCodeTimerAuto(GetName());
+
+ ++fNevents;
+ NumberOfEventsChanged();
- AliMUONVStore* istore = store.Create();
+ if (!fChannelValues)
+ {
+ fChannelValues = store.Create();
+ fManuValues = store.Create();
+ fPCBValues = store.Create();
+ fBusPatchValues = new AliMUON1DMap;
+ fDEValues = new AliMUON1DMap;
+ fChamberValues = new AliMUON1DArray;
+ }
TIter next(store.CreateIterator());
AliMUONVCalibParam* external;
- AliCodeTimerStart("from external to internal store");
-
while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
{
- Int_t detElemId = external->ID0();
- Int_t manuId = external->ID1();
+ if ( external->Dimension() != ExternalDimension() )
+ {
+ AliError(Form("Incompatible dimensions %d vs %d",
+ external->Dimension(),ExternalDimension()));
+ return kFALSE;
+ }
- AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+
+ AliMUONVCalibParam* chamber, *de, *busPatch, *pcb, *manu, *channel;
+ AliMpDetElement* mpde;
- AliMUONVCalibParam* internal = static_cast<AliMUONVCalibParam*>
- (istore->FindObject(detElemId,manuId));
+ Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
- if (!internal)
- {
- internal = new AliMUONCalibParamND(ndim,external->Size(),
- detElemId, manuId,
- 0.0);
- istore->Add(internal);
- }
+ Int_t detElemId = mpde->GetId();
+
+ Double_t value[] = { 0.0, 0.0 };
+
+ Int_t nch = mpde->NofChannelsInManu(manuId);
for ( Int_t i = 0; i < external->Size(); ++i )
{
- Bool_t connectPad = de->IsConnectedChannel(manuId,i);
-
- if (!connectPad) continue;
+ Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
+ : mpde->IsConnectedChannel(manuId,i));
+ // note we only use IsConnectedChannel method when really needed, as
+ // it costs (some) CPU time...
- for ( Int_t j = 0; j < external->Dimension(); ++j )
+ if ( existingChannel )
{
- Int_t ix = External2Internal(j);
-
- Double_t vext = external->IsDoublePrecision() ?
- external->ValueAsDouble(i,j) :
- external->ValueAsFloat(i,j);
+ Bool_t validChannel(kFALSE);
- Double_t sumw = internal->ValueAsDouble(i,ix) + vext;
- Double_t sumw2 = internal->ValueAsDouble(i,ix+1) + vext*vext;
+ for ( Int_t j = 0; j < external->Dimension(); ++j )
+ {
+ Double_t vext = external->IsDoublePrecision() ?
+ external->ValueAsDoubleFast(i,j) :
+ external->ValueAsFloatFast(i,j);
+
+ if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
+
+ validChannel = kTRUE;
+
+ Int_t ix = External2Internal(j);
+
+ value[0] = vext;
+ value[1] = vext*vext;
+
+ if ( IsHistogrammed(j) )
+ {
+ FillChannel(detElemId,manuId,i,j,vext);
+ }
+
+ for ( Int_t k = 0; k < 2; ++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]);
+
+ 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]);
+ }
+ }
+ }
- internal->SetValueAsFloat(i,ix,sumw);
- internal->SetValueAsFloat(i,ix+1,sumw2);
+ if ( validChannel )
+ {
+ channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
+ channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
+ manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+ manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
+ busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+ busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
+ de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+ de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
+ chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+ chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
+ if ( pcb )
+ {
+ pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+ pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
+ }
+ }
}
}
}
- AliCodeTimerStop("from external to internal store");
-
- /// and we add this internal store to what we already have
-
- InternalAdd(*istore);
-
- /// delete the temporary internal store.
- AliCodeTimerStart("delete");
- delete istore;
- AliCodeTimerStop("delete");
-
return kTRUE;
}
//_____________________________________________________________________________
AliMUONVCalibParam*
-AliMUONTrackerData::BusPatchParam(Int_t busPatchId) const
+AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
{
/// Return (if it exist), the VCalibParam for a given busPatch
- return fBusPatchValues ? static_cast<AliMUONVCalibParam*>
- (fBusPatchValues->FindObject(busPatchId)) : 0x0;
+
+ AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
+ (fBusPatchValues->FindObject(busPatchId)) : 0x0;
+
+ if (!busPatch && create && fBusPatchValues)
+ {
+ busPatch = CreateBusPatchParam(busPatchId);
+ fBusPatchValues->Add(busPatch);
+ }
+
+ return busPatch;
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam*
+AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
+{
+ /// Create storage for one bus patch
+
+ AliCodeTimerAuto("");
+
+ AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
+
+ if (!bp)
+ {
+ AliError(Form("Got an invalid buspatchId = %d",busPatchId));
+ return 0x0;
+ }
+
+ AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
+
+ // set the number of channels in that buspatch
+
+ Int_t nchannels(0);
+
+ Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
+
+ AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+
+ for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
+ {
+ Int_t manuId = bp->GetManuId(i);
+ nchannels += de->NofChannelsInManu(manuId);
+ }
+
+ busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
+
+ return busPatch;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
AliMUONVCalibParam*
-AliMUONTrackerData::ChamberParam(Int_t chamberId) const
+AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
{
/// Return (if it exist) the VCalibParam for a given chamber
- return fChamberValues ? static_cast<AliMUONVCalibParam*>
+
+ AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
(fChamberValues->FindObject(chamberId)) : 0x0;
+
+ if (!chamber && create && fChamberValues)
+ {
+ chamber = CreateChamberParam(chamberId);
+ fChamberValues->Add(chamber);
+ }
+
+ return chamber;
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam*
+AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
+{
+ /// Create storage for one chamber
+
+ AliCodeTimerAuto("");
+
+ AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
+
+ // set the number of channels in that chamber
+
+ Int_t nchannels(0);
+
+ AliMpDEIterator it;
+
+ it.First(chamberId);
+
+ while ( !it.IsDone() )
+ {
+ AliMpDetElement* det = it.CurrentDE();
+
+ for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
+ {
+ Int_t busPatchId = det->GetBusPatchId(i);
+ AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
+ for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
+ {
+ Int_t manuId = bp->GetManuId(j);
+ nchannels += det->NofChannelsInManu(manuId);
+ }
+ }
+
+ it.Next();
+ }
+
+ chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
+
+ return chamber;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
AliMUONVCalibParam*
-AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId) const
+AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
+ AliMUONVCalibParam* external) const
{
/// Return (if it exist) the VCalibParam for a given manu
- return fChannelValues ? static_cast<AliMUONVCalibParam*>
- (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
+
+ AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
+ (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
+
+ if (!param && external && fChannelValues)
+ {
+ param = CreateDouble(*external);
+ fChannelValues->Add(param);
+ }
+
+ return param;
}
-
//_____________________________________________________________________________
void
AliMUONTrackerData::Clear(Option_t*)
if ( fBusPatchValues) fBusPatchValues->Clear();
if ( fPCBValues ) fPCBValues->Clear();
if ( fDEValues) fDEValues->Clear();
- if ( fChamberValues) fChamberValues->Clear();
+ if ( fChamberValues ) fChamberValues->Clear();
+ if ( fChannelHistos ) fChannelHistos->Clear();
fNevents = 0;
NumberOfEventsChanged();
}
Int_t manuChannel) const
{
/// Return the number of times a given channel had data
- AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>
- (fChannelValues->FindObject(detElemId,manuId));
-
- if ( !param ) return 0.0;
- return param->ValueAsDouble(manuChannel,IndexOfOccupancyDimension());
+ return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
}
//_____________________________________________________________________________
AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param) const
{
/// Create a double version of VCalibParam, for internal use
- AliMUONVCalibParam* c = new AliMUONCalibParamND(param.Dimension()+fgkExtraDimension,
- param.Size(),
- param.ID0(),
- param.ID1(),
- 0.0);
+
+ AliCodeTimerAuto("");
+
+ AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
+ param.Size(),
+ param.ID0(),
+ param.ID1(),
+ 0.0);
for ( Int_t i = 0; i < c->Size(); ++i )
{
//_____________________________________________________________________________
AliMUONVCalibParam*
-AliMUONTrackerData::DetectionElementParam(Int_t detElemId) const
+AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
{
/// Return (if it exist) the VCalibParam for a given detection element
- return fDEValues ? static_cast<AliMUONVCalibParam*>
- (fDEValues->FindObject(detElemId)) : 0x0 ;
+
+ AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
+ (fDEValues->FindObject(detElemId)) : 0x0 ;
+
+ if (!de && create && fDEValues)
+ {
+ de = CreateDetectionElementParam(detElemId);
+ fDEValues->Add(de);
+ }
+
+ return de;
+
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam*
+AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
+{
+ /// Create storage for one detection element
+
+ AliCodeTimerAuto("");
+
+ AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
+
+ AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+ Int_t nchannels(0);
+
+ for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
+ {
+ Int_t busPatchId = det->GetBusPatchId(i);
+ AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
+ for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
+ {
+ Int_t manuId = bp->GetManuId(j);
+ nchannels += det->NofChannelsInManu(manuId);
+ }
+ }
+
+ de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
+
+ return de;
}
//_____________________________________________________________________________
}
//_____________________________________________________________________________
-Bool_t
-AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
+TString
+AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
{
- /// Whether we have data for a given buspatch
- return ( BusPatchParam(busPatchId) != 0 );
+ /// Get the name of a given external dimension
+
+ TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
+ if ( value )
+ {
+ return value->String();
+ }
+ else
+ {
+ return TString("Invalid");
+ }
}
//_____________________________________________________________________________
-Bool_t
-AliMUONTrackerData::HasChamber(Int_t chamberId) const
+void
+AliMUONTrackerData::FillChannel(Int_t detElemId, Int_t manuId, Int_t manuChannel,
+ Int_t dim, Double_t value)
{
- /// Whether we have data for a given chamber
- return ( ChamberParam(chamberId) != 0 );
+ /// Fill histogram of a given channel
+
+ AliMUONSparseHisto* h = GetChannelHisto(detElemId, manuId, manuChannel,dim);
+
+ h->Fill(static_cast<Int_t>(TMath::Nint(value)));
}
//_____________________________________________________________________________
-Bool_t
-AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
+TH1*
+AliMUONTrackerData::CreateChannelHisto(Int_t detElemId, Int_t manuId,
+ Int_t manuChannel, Int_t dim)
{
- /// Whether we have data for a given detection element
- return ( DetectionElementParam(detElemId) != 0 );
+ /// Create histogram of a given channel. Note that in order
+ /// to keep memory footprint as low as possible, you should delete
+ /// the returned pointer as soon as possible...
+
+ if ( HasChannel(detElemId, manuId, manuChannel) && IsHistogrammed(dim) )
+ {
+ AliMUONSparseHisto* sh = GetChannelHisto(detElemId,manuId,manuChannel,dim);
+
+ if ( sh )
+ {
+ TH1* h = new TH1I(Form("DE%04dMANU%04dCH%02d_%d",detElemId,manuId,manuChannel,dim),
+ Form("Data=%s Dim=%s",GetName(),ExternalDimensionName(dim).Data()),
+ 4096,-0.5,4095.5);
+
+ Add(*h,*sh);
+ return h;
+ }
+ }
+ return 0x0;
}
//_____________________________________________________________________________
-Bool_t
-AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
+void
+AliMUONTrackerData::Add(TH1& h, const AliMUONSparseHisto& sh)
{
- /// Whether we have data for a given manu
- return ( ManuParam(detElemId,manuId) != 0 );
+ /// Add sparse histo content to histogram.
+
+ Double_t entries(h.GetEntries());
+
+ for ( Int_t i = 0; i < sh.GetNbins(); ++i )
+ {
+ Int_t x = sh.GetBinContent(i);
+ Int_t adc, count;
+ sh.Decode(x,adc,count);
+ h.Fill(adc,count);
+ entries += count;
+ }
+
+ h.SetEntries(entries);
}
//_____________________________________________________________________________
-Bool_t
-AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
+TH1*
+AliMUONTrackerData::CreateHisto(const char* name, Int_t dim) const
{
- /// Whether we have data for a given pcb
- return ( PCBParam(detElemId,pcbIndex) != 0 );
+ /// Create a single histogram
+
+ return new TH1I(name,Form("Data=%s Dim=%s",GetName(),ExternalDimensionName(dim).Data()),
+ 4096,-0.5,4095.5);
}
//_____________________________________________________________________________
-Bool_t
-AliMUONTrackerData::InternalAdd(const AliMUONVStore& store)
+TH1*
+AliMUONTrackerData::CreateBusPatchHisto(Int_t busPatchId, Int_t dim)
{
- /// Add the given store to our internal store
- /// Store must be of dimension = fDimension-1
+ /// Create histogram of a given bus patch. Note that in order
+ /// to keep memory footprint as low as possible, you should delete
+ /// the returned pointer as soon as possible...
- AliCodeTimerAuto(GetName());
+ TH1* h(0x0);
- AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
-
- ++fNevents;
- NumberOfEventsChanged();
-
- if (!fChannelValues)
+ if ( HasBusPatch(busPatchId) && IsHistogrammed(dim))
{
- fChannelValues = store.Create();
- fManuValues = store.Create();
- fBusPatchValues = store.Create();
- fDEValues = store.Create();
- fChamberValues = store.Create();
- fPCBValues = store.Create();
+ h = CreateHisto(Form("BP%04d_%d",busPatchId,dim),dim);
+ AddBusPatchHisto(*h,busPatchId,dim);
}
- TIter next(store.CreateIterator());
- AliMUONVCalibParam* external;
-
- AliMpHVNamer namer;
-
- while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
+ return h;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONTrackerData::AddBusPatchHisto(TH1& h, Int_t busPatchId, Int_t dim)
+{
+ /// Add data from one bus patch to the histogram
+
+ if ( HasBusPatch(busPatchId ) )
{
- if ( external->Dimension() != fDimension-fgkExtraDimension )
+ AliMpBusPatch* busPatch = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
+ for ( Int_t i = 0; i < busPatch->GetNofManus(); ++i )
{
- AliError(Form("Incompatible dimensions %d vs %d",
- external->Dimension(),fDimension-fgkExtraDimension));
- return kFALSE;
+ Int_t manuId = busPatch->GetManuId(i);
+ AddManuHisto(h,busPatch->GetDEId(),manuId,dim);
}
-
- Int_t detElemId = external->ID0();
-
- AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
-
- Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
-
- Int_t manuId = external->ID1();
-
- AliMpDetElement* mpde = ddlStore->GetDetElement(detElemId);
+ }
+}
- Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
-
- Int_t pcbIndex = -1;
-
- if ( stationType == AliMp::kStation345 )
- {
- pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
- }
- AliMUONVCalibParam* channel = ChannelParam(detElemId,manuId);
- if (!channel)
- {
- channel = CreateDouble(*external);
- fChannelValues->Add(channel);
- }
+//_____________________________________________________________________________
+TH1*
+AliMUONTrackerData::CreateDEHisto(Int_t detElemId, Int_t dim)
+{
+ /// Create histogram of a given detection element. Note that in order
+ /// to keep memory footprint as low as possible, you should delete
+ /// the returned pointer as soon as possible...
+
+ TH1* h(0x0);
+
+ if ( HasDetectionElement(detElemId) && IsHistogrammed(dim) )
+ {
+ h = CreateHisto(Form("DE%04d-%d",detElemId,dim),dim);
+ AddDEHisto(*h,detElemId,dim);
+ }
+
+ return h;
+}
- AliMUONVCalibParam* manu = ManuParam(detElemId,manuId);
- if (!manu)
+//_____________________________________________________________________________
+void
+AliMUONTrackerData::AddDEHisto(TH1& h, Int_t detElemId, Int_t dim)
+{
+ /// Add data from one detection element to the histogram
+
+ if ( HasDetectionElement(detElemId) )
+ {
+ AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+ for ( Int_t i = 0; i < de->GetNofBusPatches(); ++ i )
{
- manu = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
- 1,
- detElemId,
- manuId,
- 0.0);
-
- // set the number of channels in that manu
-
- AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
-
- manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
-
- fManuValues->Add(manu);
+ Int_t busPatchId = de->GetBusPatchId(i);
+ AddBusPatchHisto(h,busPatchId,dim);
}
-
- AliMUONVCalibParam* busPatch = BusPatchParam(busPatchId);
- if (!busPatch)
- {
- AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
-
- if (!bp)
- {
- AliError(Form("Got an invalid buspatchId = %d",busPatchId));
- continue;
- }
-
- busPatch = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
- 1,
- busPatchId,
- 0,
- 0.0);
-
- // set the number of channels in that buspatch
-
- Int_t nchannels(0);
-
- AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
-
- for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
- {
- Int_t manuId = bp->GetManuId(i);
- nchannels += de->NofChannelsInManu(manuId);
- }
+ }
+}
- busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
-
- fBusPatchValues->Add(busPatch);
- }
+//_____________________________________________________________________________
+TH1*
+AliMUONTrackerData::CreateManuHisto(Int_t detElemId, Int_t manuId, Int_t dim)
+{
+ /// Create histogram of a given manu. Note that in order
+ /// to keep memory footprint as low as possible, you should delete
+ /// the returned pointer as soon as possible...
+
+ TH1* h(0x0);
+
+ if ( HasManu(detElemId, manuId) && IsHistogrammed(dim) )
+ {
+ h = CreateHisto(Form("DE%04dMANU%04d_%d",detElemId,manuId,dim),dim);
+ AddManuHisto(*h,detElemId,manuId,dim);
+ }
+
+ return h;
+}
- AliMUONVCalibParam* de = DetectionElementParam(detElemId);
- if (!de)
+//_____________________________________________________________________________
+void
+AliMUONTrackerData::AddManuHisto(TH1& h, Int_t detElemId, Int_t manuId, Int_t dim)
+{
+ /// Add data from a given manu to histogram
+
+ if ( HasManu(detElemId,manuId) )
+ {
+ for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i )
{
- de = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
- 1,
- detElemId,
- 0,
- 0.0);
-
- AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
- Int_t nchannels(0);
-
- for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
+ if ( HasChannel(detElemId,manuId,i) )
{
- Int_t busPatchId = det->GetBusPatchId(i);
- AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
- for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
- {
- Int_t manuId = bp->GetManuId(j);
- nchannels += det->NofChannelsInManu(manuId);
- }
- }
-
- de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
-
- fDEValues->Add(de);
- }
-
- AliMUONVCalibParam* chamber = ChamberParam(chamberId);
- if (!chamber)
- {
- chamber = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
- 1,
- chamberId,
- 0,
- 0.0);
-
- // set the number of channels in that chamber
-
- Int_t nchannels(0);
-
- AliMpDEIterator it;
-
- it.First(chamberId);
-
- while ( !it.IsDone() )
- {
- AliMpDetElement* det = it.CurrentDE();
+ AliMUONSparseHisto* sh = GetChannelHisto(detElemId,manuId,i,dim);
- for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
- {
- Int_t busPatchId = det->GetBusPatchId(i);
- AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
- for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
- {
- Int_t manuId = bp->GetManuId(j);
- nchannels += det->NofChannelsInManu(manuId);
- }
+ if ( sh )
+ {
+ Add(h,*sh);
}
-
- it.Next();
}
-
- chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
-
- fChamberValues->Add(chamber);
}
+ }
+}
- AliMUONVCalibParam* pcb = 0x0;
-
- if ( pcbIndex >= 0 )
+//_____________________________________________________________________________
+TH1*
+AliMUONTrackerData::CreatePCBHisto(Int_t /*detElemId*/, Int_t /*pcbIndex*/, Int_t /*dim*/)
+{
+ /// Create histogram of a given PCB. Note that in order
+ /// to keep memory footprint as low as possible, you should delete
+ /// the returned pointer as soon as possible...
+
+ // TH1* h(0x0);
+//
+// if ( HasPCB(detElemId, pcbIndex) && IsHistogrammed(dim))
+// {
+// h = CreateHisto(Form("DE%04dPCB1d_%d",detElemId,pcbIndex,dim),dim);
+// }
+//
+// return h;
+
+ AliWarning("Not implemented (is it needed ?)");
+ return 0x0;
+}
+
+//_____________________________________________________________________________
+TH1*
+AliMUONTrackerData::CreateChamberHisto(Int_t chamberId, Int_t dim)
+{
+ /// Create histogram of a given chamber. Note that in order
+ /// to keep memory footprint as low as possible, you should delete
+ /// the returned pointer as soon as possible...
+
+ TH1* h(0x0);
+
+ if ( HasChamber(chamberId) && IsHistogrammed(dim))
+ {
+ h = CreateHisto(Form("CHAMBER%02d_%d",chamberId,dim),dim);
+ AliMpDEIterator it;
+ it.First(chamberId);
+ while ( !it.IsDone() )
{
- pcb = PCBParam(detElemId,pcbIndex);
- if (!pcb)
- {
- pcb = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
- namer.NumberOfPCBs(detElemId),
- detElemId,
- pcbIndex,
- 0.0);
- fPCBValues->Add(pcb);
- }
+ Int_t detElemId = it.CurrentDEId();
+ AddDEHisto(*h,detElemId,dim);
+ it.Next();
}
-
- for ( Int_t i = 0; i < external->Size(); ++i )
- {
- Bool_t existingChannel = mpde->IsConnectedChannel(manuId,i);
-
- if ( existingChannel )
- {
- Bool_t validChannel(kFALSE);
-
- for ( Int_t j = 0; j < external->Dimension(); ++j )
- {
- if ( external->ValueAsFloat(i,j) >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
-
- validChannel = kTRUE;
-
- Double_t vext = external->IsDoublePrecision() ?
- external->ValueAsDouble(i,j) :
- external->ValueAsFloat(i,j);
-
- Double_t value = channel->ValueAsDouble(i,j) + vext;
-
- channel->SetValueAsDouble(i,j,value);
-
- manu->SetValueAsDouble(0,j,manu->ValueAsDouble(0,j)+vext);
-
- busPatch->SetValueAsDouble(0,j,busPatch->ValueAsDouble(0,j)+vext);
+ }
+
+ return h;
+}
- de->SetValueAsDouble(0,j,de->ValueAsDouble(0,j)+vext);
+//_____________________________________________________________________________
+AliMUONSparseHisto*
+AliMUONTrackerData::GetChannelHisto(Int_t detElemId, Int_t manuId,
+ Int_t manuChannel, Int_t dim)
+{
+ /// Get histogram of a given channel
+
+ if (!fChannelHistos) fChannelHistos = new AliMUON2DMap(kTRUE);
+
+ TObjArray* dimArray = static_cast<TObjArray*>(fChannelHistos->FindObject(detElemId,manuId));
+ if (!dimArray)
+ {
+ dimArray = new TObjArray(fExternalDimension);
+ dimArray->SetUniqueID( ( manuId << 16 ) | detElemId );
+ fChannelHistos->Add(dimArray);
+ }
+
+ TObjArray* channels = static_cast<TObjArray*>(dimArray->UncheckedAt(dim));
+ if (!channels)
+ {
+ channels = new TObjArray(AliMpConstants::ManuNofChannels());
+ dimArray->AddAt(channels,dim);
+ }
+
+ AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(channels->UncheckedAt(manuChannel));
+ if (!h)
+ {
+ h = new AliMUONSparseHisto;
+ h->SetUniqueID(( manuChannel << 16 ) | dim);
+ channels->AddAt(h,manuChannel);
+ }
+
+ return h;
+
+// below is an alternate implementation, using a 1DMap, which *seems* to be
+// slightly SLOWER.
+//
+// AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fChannelHistos->FindObject(detElemId,manuId));
+// if (!m)
+// {
+// m = new AliMUON1DMap(kFALSE);
+// m->SetUniqueID( ( manuId << 16 ) | detElemId );
+// fChannelHistos->Add(m);
+// }
+//
+// UInt_t uid = ( manuChannel << 16 ) | dim;
+//
+// AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
+// if (!h)
+// {
+// h = new AliMUONSparseHisto;
+//
+// h->SetUniqueID(uid);
+//
+// m->Add(h);
+// }
- chamber->SetValueAsDouble(0,j,chamber->ValueAsDouble(0,j)+vext);
+ return h;
+}
- if ( pcb )
- {
- pcb->SetValueAsDouble(pcbIndex,j,pcb->ValueAsDouble(pcbIndex,j)+vext);
- }
- }
-
- if ( validChannel )
- {
- channel->SetValueAsDouble(i,IndexOfOccupancyDimension(),
- channel->ValueAsDouble(i,IndexOfOccupancyDimension())+1.0);
- manu->SetValueAsDouble(0,IndexOfOccupancyDimension(),
- manu->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);
- busPatch->SetValueAsDouble(0,IndexOfOccupancyDimension(),
- busPatch->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);
- de->SetValueAsDouble(0,IndexOfOccupancyDimension(),
- de->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);
- chamber->SetValueAsDouble(0,IndexOfOccupancyDimension(),
- chamber->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);
- if ( pcb )
- {
- pcb->SetValueAsDouble(pcbIndex,IndexOfOccupancyDimension(),
- pcb->ValueAsDouble(pcbIndex,IndexOfOccupancyDimension())+1.0);
- }
- }
- }
- }
+//_____________________________________________________________________________
+Int_t
+AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
+ AliMUONVCalibParam*& chamber,
+ AliMUONVCalibParam*& de,
+ AliMUONVCalibParam*& busPatch,
+ AliMUONVCalibParam*& pcb,
+ AliMUONVCalibParam*& manu,
+ AliMUONVCalibParam*& channel,
+ AliMpDetElement*& mpde)
+{
+ /// Get containers at all levels
+
+ AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
+
+ Int_t detElemId = external->ID0();
+
+ Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
+
+ Int_t manuId = external->ID1();
+
+ mpde = ddlStore->GetDetElement(detElemId);
+
+ Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
+
+ Int_t pcbIndex = -1;
+
+ AliMp::StationType stationType = mpde->GetStationType();
+
+ if ( stationType == AliMp::kStation345 )
+ {
+ AliMpHVNamer namer;
+ pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
+ }
+
+ channel = ChannelParam(detElemId,manuId,external);
+
+ manu = ManuParam(detElemId,manuId,kTRUE);
+
+ busPatch = BusPatchParam(busPatchId,kTRUE);
+
+ de = DetectionElementParam(detElemId,kTRUE);
+
+ chamber = ChamberParam(chamberId,kTRUE);
+
+ pcb = 0x0;
+
+ if ( pcbIndex >= 0 )
+ {
+ pcb = PCBParam(detElemId,pcbIndex,kTRUE);
}
+
+ return manuId;
+}
- return kTRUE;
+//_____________________________________________________________________________
+Bool_t
+AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
+{
+ /// Whether we have data for a given buspatch
+ return ( BusPatchParam(busPatchId) != 0 );
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONTrackerData::HasChamber(Int_t chamberId) const
+{
+ /// Whether we have data for a given chamber
+ return ( ChamberParam(chamberId) != 0 );
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
+{
+ /// Whether we have data for a given detection element
+ return ( DetectionElementParam(detElemId) != 0 );
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
+{
+ /// Whether we have data for a given manu
+ return ( ManuParam(detElemId,manuId) != 0 );
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
+{
+ /// Whether we have data for a given pcb
+ return ( PCBParam(detElemId,pcbIndex) != 0 );
}
//_____________________________________________________________________________
//_____________________________________________________________________________
AliMUONVCalibParam*
-AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId) const
+AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
{
/// Get the VCalibParam for a given manu
- return fManuValues ? static_cast<AliMUONVCalibParam*>
- (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
+
+ AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
+ (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
+
+ if (!manu && create && fManuValues)
+ {
+ manu = CreateManuParam(detElemId,manuId);
+ fManuValues->Add(manu);
+ }
+
+ return manu;
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam*
+AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
+{
+ /// Create storage for one manu
+
+ AliCodeTimerAuto("");
+
+ AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
+
+ // set the number of channels in that manu
+
+ AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+
+ manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
+
+ return manu;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
AliMUONVCalibParam*
-AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex) const
+AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
{
/// Return (if it exist) the VCalibParam for a given pcb
- return fPCBValues ? static_cast<AliMUONVCalibParam*>
- (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
+
+ AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
+ (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
+
+ if (create && fPCBValues && !pcb)
+ {
+ pcb = CreatePCBParam(detElemId,pcbIndex);
+ fPCBValues->Add(pcb);
+ }
+
+ return pcb;
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam*
+AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
+{
+ /// Create storage for one PCB (station345 only)
+
+ AliCodeTimerAuto("");
+
+ AliMpHVNamer namer;
+
+ AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
+ namer.NumberOfPCBs(detElemId),
+ detElemId,
+ pcbIndex,
+ 0.0);
+ return pcb;
}
//_____________________________________________________________________________
{
cout << " Nevents=" << fNevents << endl;
}
+
+ for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
+ {
+ TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
+ cout << Form("External Dimension %2d Name %s %s",i,
+ ( name ? name->String().Data() : "null"),
+ ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
+ }
for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
{
TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
- cout << Form("Dimension %2d Name %s",i,
+ cout << Form("Internal Dimension %2d Name %s",i,
( name ? name->String().Data() : "null")) << endl;
}
-
- cout << Form("External Dimensions = %d",fExternalDimension) << endl;
-
+
TString sopt(opt);
sopt.ToUpper();
SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
}
+
+ SetExternalDimensionName(index,name);
+}
+
+//_____________________________________________________________________________
+void
+AliMUONTrackerData::SetHistogramDimension(Int_t index, Bool_t value)
+{
+ /// decide to make histos for a given dimension
+ if ( index >= ExternalDimension() )
+ {
+ AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
+ return;
+ }
+
+ fHistogramming[index] = value;
}
//_____________________________________________________________________________
fDimensionNames->AddAt(new TObjString(value),index);
}
+//_____________________________________________________________________________
+void
+AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
+{
+ /// Set the name of a given external dimension
+ if ( index >= fExternalDimension )
+ {
+ AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
+ return;
+ }
+
+ TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
+
+ if ( ovalue )
+ {
+ fExternalDimensionNames->Remove(ovalue);
+ delete ovalue;
+ }
+ fExternalDimensionNames->AddAt(new TObjString(value),index);
+}
+
//_____________________________________________________________________________
Double_t
AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, Int_t dim) const