From: richterm Date: Wed, 21 Mar 2012 13:29:30 +0000 (+0000) Subject: using binary cluster format for unpacking of compressed HLT TPC clusters instead... X-Git-Url: http://git.uio.no/git/?a=commitdiff_plain;h=de2b57021b6236180ccad08e0cef4c7d64279f6f;p=u%2Fmrichter%2FAliRoot.git using binary cluster format for unpacking of compressed HLT TPC clusters instead of multiple TClonesArrays of AliTPCclusterMI, for PbPb data this saves about 200 MB if the file contains events with 3M clusters --- diff --git a/HLT/TPCLib/AliHLTTPCClusterAccessHLTOUT.cxx b/HLT/TPCLib/AliHLTTPCClusterAccessHLTOUT.cxx index ad13c37faf6..60b50e2c7ba 100644 --- a/HLT/TPCLib/AliHLTTPCClusterAccessHLTOUT.cxx +++ b/HLT/TPCLib/AliHLTTPCClusterAccessHLTOUT.cxx @@ -37,6 +37,8 @@ #include "AliHLTSystem.h" #include "AliHLTPluginBase.h" #include "AliTPCclusterMI.h" +#include "AliTPCClustersRow.h" +#include "AliTPCParam.h" #include "TClonesArray.h" #include #include @@ -53,6 +55,7 @@ AliHLTTPCClusterAccessHLTOUT::AliHLTTPCClusterAccessHLTOUT() , fClusters(NULL) , fCurrentSector(-1) , fpDecoder(NULL) + , fTPCParam(NULL) { // see header file for class documentation // or @@ -74,6 +77,13 @@ AliHLTTPCClusterAccessHLTOUT::~AliHLTTPCClusterAccessHLTOUT() delete fpDecoder; fpDecoder=NULL; } + if (fTPCParam) { + // FIXME: a copy of the TPCParam object is not possible because there is + // no appropriate copy constructor or assignment operator, using as + // external pointer + //delete fTPCParam; + fTPCParam=NULL; + } } void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method, const char *params, Int_t *error) @@ -112,6 +122,36 @@ TObject* AliHLTTPCClusterAccessHLTOUT::FindObject(const char *name) const return TObject::FindObject(name); } +void AliHLTTPCClusterAccessHLTOUT::Copy(TObject &object) const +{ + /// inherited from TObject: supports writing of data to AliTPCClustersRow + AliTPCClustersRow* rowcl=dynamic_cast(&object); + if (rowcl) { + int index=rowcl->GetID(); + if (!fTPCParam) { + AliFatal("TPCParam object not initialized, use 'Copy()' funtion to initialize"); + return; + } + int sector=-1; + int row=-1; + if (!fTPCParam->AdjustSectorRow(index, sector, row)) { + AliFatal(Form("failed to get sector and row for index %d", index)); + return; + } + fClusters->FillSectorArray(rowcl->GetArray(), sector, row); + return; + } + AliTPCParam* tpcparam=dynamic_cast(&object); + if (tpcparam) { + // FIXME: can nor make a copy of the TPCparam object because + // there is no appropriate copy constructor or assignment operator + const_cast(this)->fTPCParam=tpcparam; + return; + } + return TObject::Copy(object); +} + + void AliHLTTPCClusterAccessHLTOUT::Clear(Option_t * option) { /// inherited from TObject: cleanup @@ -157,20 +197,20 @@ int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params) } if (!fClusters) { - fClusters=new AliTPCclusterMIContainer; + fClusters=new AliRawClusterContainer; } if (!fClusters) return -ENOMEM; if (fCurrentSector>=0) { // cluster container already filled fCurrentSector=sector; - TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector); - if (!pArray) { - AliError(Form("can not get cluster array for sector %d", sector)); - return -ENOBUFS; - } - if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) for sector %d", pArray->GetEntriesFast() ,sector)); - return pArray->GetEntriesFast(); +// TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector); +// if (!pArray) { +// AliError(Form("can not get cluster array for sector %d", sector)); +// return -ENOBUFS; +// } +// if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) for sector %d", pArray->GetEntriesFast() ,sector)); + return 0; //pArray->GetEntriesFast(); } // fill the cluster container @@ -343,140 +383,214 @@ int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params) pSystem->ReleaseHLTOUT(pHLTOUT); if (iResult<0) return iResult; - if (fVerbosity>0) { - int nConvertedClusters=0; - for (int s=0; s<72; s++) { - TObjArray* pArray=fClusters->GetSectorArray(s); - if (!pArray) continue; - nConvertedClusters+=pArray->GetEntriesFast(); - } - AliInfo(Form("extracted HLT clusters: %d, converted HLT clusters: %d", nExtractedClusters, nConvertedClusters)); - } +// if (fVerbosity>0) { +// int nConvertedClusters=0; +// for (int s=0; s<72; s++) { +// TObjArray* pArray=fClusters->GetSectorArray(s); +// if (!pArray) continue; +// nConvertedClusters+=pArray->GetEntriesFast(); +// } +// AliInfo(Form("extracted HLT clusters: %d, converted HLT clusters: %d", nExtractedClusters, nConvertedClusters)); +// } fCurrentSector=sector; - TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector); - if (!pArray) { - AliError(Form("can not get cluster array for sector %d", sector)); - return -ENOBUFS; - } - if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) for sector %d", pArray->GetEntriesFast() ,sector)); - return pArray->GetEntriesFast(); +// TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector); +// if (!pArray) { +// AliError(Form("can not get cluster array for sector %d", sector)); +// return -ENOBUFS; +// } +// if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) for sector %d", pArray->GetEntriesFast() ,sector)); + return 0; //pArray->GetEntriesFast(); } -AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::AliTPCclusterMIContainer() - : fClusterArrays() - , fRemainingClusterIds() - , fTrackModelClusterIds() - , fCurrentClusterIds(NULL) - , fClusterMCData() +AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::AliRawClusterContainer() + : fClusterVectors() + , fClusterMaps() + , fSectorArray(new TClonesArray(AliTPCclusterMI::Class())) , fIterator() { /// constructor + AliHLTTPCRawClusterVector* first=new AliHLTTPCRawClusterVector; + if (first) { + first->reserve(500000); + fClusterVectors.push_back(first); + } for (int i=0; i<72; i++) { - fClusterArrays.push_back(new TClonesArray("AliTPCclusterMI")); + fClusterMaps.push_back(new AliRawClusterEntryVector); } } -AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::~AliTPCclusterMIContainer() +AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::~AliRawClusterContainer() { /// dectructor - for (vector::iterator i=fClusterArrays.begin(); i!=fClusterArrays.end(); i++) { - if (*i) { - (*i)->Clear(); - delete *i; + { + for (vector::iterator i=fClusterVectors.begin(); i!=fClusterVectors.end(); i++) { + if (*i) { + delete *i; + } } } + { + for (vector::iterator i=fClusterMaps.begin(); i!=fClusterMaps.end(); i++) { + if (*i) { + delete *i; + } + } + } + if (fSectorArray) { + fSectorArray->Clear(); + delete fSectorArray; + fSectorArray=NULL; + } } -AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::BeginRemainingClusterBlock(int /*count*/, AliHLTUInt32_t specification) +AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::BeginRemainingClusterBlock(int count, AliHLTUInt32_t specification) { /// iterator of remaining clusters block of specification - AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(specification); + + // reserve space in the array of all clusters + // reserve space in the map of the partition + unsigned index=AliHLTTPCDefinitions::GetMinSliceNr(specification); AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(specification); - unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition; - if (index=2) index+=36; + if (indexsize()+count>fClusterMaps[index]->capacity()) { + fClusterMaps[index]->reserve(fClusterMaps[index]->size()+count); + } + fIterator=iterator(this); return fIterator; } -AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::BeginTrackModelClusterBlock(int /*count*/) +AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::BeginTrackModelClusterBlock(int /*count*/) { /// iterator of track model clusters - if (fTrackModelClusterIds.fIds && fTrackModelClusterIds.fSize>0) - fCurrentClusterIds=&fTrackModelClusterIds; - else - fCurrentClusterIds=NULL; fIterator=iterator(this); return fIterator; } -AliTPCclusterMI* AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::NextCluster(int slice, int partition) +AliHLTTPCClusterAccessHLTOUT::AliRawClusterEntry* AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::NextCluster(int slice, int partition) { /// load next cluster from array of the sepcific sector unsigned sector=partition<2?slice:slice+36; - if (fClusterArrays.size()<=sector || - fClusterArrays[sector]==NULL) { + if (fClusterMaps.size()<=sector || + fClusterMaps[sector]==NULL) { AliErrorClass(Form("no cluster array available for sector %d", sector)); return NULL; } - TClonesArray& array=*(fClusterArrays[sector]); - int count=array.GetEntriesFast(); - return new (array[count]) AliTPCclusterMI; + if (fClusterVectors.size()==0) { + AliFatalClass("memory allocation of first cluster array failed"); + return NULL; + } + AliHLTTPCRawClusterVector* pClusters=NULL; + for (vector::iterator i=fClusterVectors.begin(); i!=fClusterVectors.end(); i++) { + if (*i && (*i)->size()<(*i)->capacity()) { + pClusters=*i; + break; + } + } + if (!pClusters) { + pClusters=new AliHLTTPCRawClusterVector; + if (!pClusters) { + AliFatalClass("memory allocation of next cluster array failed"); + return NULL; + } + pClusters->reserve(500000); + fClusterVectors.push_back(pClusters); + } + + AliHLTTPCRawCluster dummy; + pClusters->push_back(dummy); + AliRawClusterEntry entry(&(pClusters->back())); + AliRawClusterEntryVector& map=*(fClusterMaps[sector]); + map.push_back(entry); + return &map.back(); } -void AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::Clear(Option_t* /*option*/) +void AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::Clear(Option_t* /*option*/) { /// internal cleanup { - for (vector::iterator i=fClusterArrays.begin(); i!=fClusterArrays.end(); i++) - if (*i) (*i)->Clear(); - } - { - for (vector::iterator i=fRemainingClusterIds.begin(); i!=fRemainingClusterIds.end(); i++) - {i->fIds=NULL; i->fSize=0;} + for (vector::iterator i=fClusterVectors.begin(); i!=fClusterVectors.end(); i++) { + if (*i) (*i)->clear(); + } } - fTrackModelClusterIds.fIds=NULL; fTrackModelClusterIds.fSize=0; - fCurrentClusterIds=NULL; { - for (vector::iterator i=fClusterMCData.begin(); i!=fClusterMCData.end(); i++) - *i=NULL; + for (vector::iterator i=fClusterMaps.begin(); i!=fClusterMaps.end(); i++) + if (*i) (*i)->clear(); } + if (fSectorArray) fSectorArray->Clear(); } -TObjArray* AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::GetSectorArray(unsigned sector) const +TObjArray* AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::GetSectorArray(unsigned sector) const { /// get the cluster array for a sector - if (fClusterArrays.size()<=sector) return NULL; - return fClusterArrays[sector]; + if (fClusterMaps.size()<=sector) return NULL; + if (fSectorArray && + FillSectorArray(fSectorArray, sector)<0) { + fSectorArray->Clear(); + } + return fSectorArray; } -void AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::Print(Option_t *option) const +int AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::FillSectorArray(TClonesArray* pSectorArray, unsigned sector, int row) const +{ + /// fill the cluster array for a sector and specific row if specified + if (!pSectorArray) return -EINVAL; + if (fClusterMaps.size()<=sector) return -ERANGE; + pSectorArray->Clear(); + + AliRawClusterEntryVector& map=*fClusterMaps[sector]; + for (unsigned i=0; i=0 && map[i].fCluster->GetPadRow()!=row) continue; + AliTPCclusterMI* pCluster=new ((*pSectorArray)[i]) AliTPCclusterMI; + if (!pCluster) break; + + pCluster->SetRow(map[i].fCluster->GetPadRow()); + pCluster->SetPad(map[i].fCluster->GetPad()); + pCluster->SetTimeBin(map[i].fCluster->GetTime()); + pCluster->SetSigmaY2(map[i].fCluster->GetSigmaY2()); + pCluster->SetSigmaZ2(map[i].fCluster->GetSigmaZ2()); + pCluster->SetQ(map[i].fCluster->GetCharge()); + pCluster->SetMax(map[i].fCluster->GetQMax()); + + if (map[i].fMC) { + for (int k=0; k<3; k++) { + // TODO: sort the labels according to the weight in order to assign the most likely mc label + // to the first component + pCluster->SetLabel(map[i].fMC->fClusterID[k].fMCID, k); + } + } + } + + return 0; +} + +void AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::Print(Option_t *option) const { /// inherited from TObject - cout << "AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer" << endl; + cout << "AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer" << endl; ios::fmtflags coutflags=cout.flags(); // backup cout status flags bool bAll=false; if ((bAll=(strcmp(option, "full")==0)) || strcmp(option, "short")==0) { - for (unsigned iArray=0; iArrayGetEntriesFast() << endl; + for (unsigned iArray=0; iArrayGetEntriesFast(); iCluster++) { - if (!pArray->At(iCluster)) continue; - AliTPCclusterMI* pCluster=dynamic_cast(pArray->At(iCluster)); - if (!pCluster) break; + for (unsigned iCluster=0; iCluster +class AliTPCParam; class AliTPCClustersRow; +class AliTPCclusterMI; class AliHLTOUT; class TClonesArray; class AliHLTTPCDataCompressionDecoder; -typedef std::map AliHLTTPCClusterMCDataList; - /** * @class AliHLTTPCClusterAccessHLTOUT * Generator for TPC cluster array from HLT TPC clusters in the HLTOUT @@ -97,6 +97,9 @@ class AliHLTTPCClusterAccessHLTOUT : public TObject /// inherited from TObject: return the cluster array if name id "clusterarray" virtual TObject *FindObject(const char *name) const; + /// inherited from TObject: supports writing of data to AliTPCClustersRow + virtual void Copy(TObject &object) const; + /// inherited from TObject: cleanup virtual void Clear(Option_t * option =""); @@ -106,16 +109,33 @@ class AliHLTTPCClusterAccessHLTOUT : public TObject /// process the cluster data block of various formats from HLTOUT int ProcessClusters(const char* params); + /// helper struct to store cluster pointers in a map together with MC info + struct AliRawClusterEntry { + AliRawClusterEntry() : fCluster(NULL), fMC(NULL) {} + AliRawClusterEntry(AliHLTTPCRawCluster* pCluster) : fCluster(pCluster), fMC(NULL) {} + AliRawClusterEntry(const AliRawClusterEntry& other) : fCluster(other.fCluster), fMC(other.fMC) {} + AliRawClusterEntry& operator=(const AliRawClusterEntry& other) { + if (&other==this) return *this; + fCluster=other.fCluster; fMC=other.fMC; + return *this; + } + AliHLTTPCRawCluster* fCluster; //! pointer to cluster in the array of all clusters + const AliHLTTPCClusterMCLabel* fMC; //! pointer to corresponding MC data in HLTOUT block + }; + + typedef vector AliHLTTPCRawClusterVector; + typedef vector AliRawClusterEntryVector; + /** - * @class AliTPCclusterMIContainer + * @class AliRawClusterContainer * Cluster read interface for offline. * The class implements the interface to be used in the decoding * of compressed TPC data. */ - class AliTPCclusterMIContainer { + class AliRawClusterContainer { public: - AliTPCclusterMIContainer(); - virtual ~AliTPCclusterMIContainer(); + AliRawClusterContainer(); + virtual ~AliRawClusterContainer(); struct AliClusterIdBlock { AliClusterIdBlock() : fIds(NULL), fSize(0) {} @@ -125,25 +145,24 @@ class AliHLTTPCClusterAccessHLTOUT : public TObject class iterator { public: - iterator() : fClusterNo(-1), fData(NULL), fCluster(NULL), fRowOffset(0) {} - iterator(AliTPCclusterMIContainer* pData) : fClusterNo(-1), fData(pData), fCluster(NULL), fRowOffset(0) {} - iterator(const iterator& other) : fClusterNo(other.fClusterNo), fData(other.fData), fCluster(other.fCluster), fRowOffset(other.fRowOffset) {} + iterator() : fClusterNo(-1), fData(NULL), fEntry(NULL), fRowOffset(0) {} + iterator(AliRawClusterContainer* pData) : fClusterNo(-1), fData(pData), fEntry(NULL), fRowOffset(0) {} + iterator(const iterator& other) : fClusterNo(other.fClusterNo), fData(other.fData), fEntry(other.fEntry), fRowOffset(other.fRowOffset) {} iterator& operator=(const iterator& other) { if (this==&other) return *this; - fClusterNo=other.fClusterNo; fData=other.fData; fCluster=other.fCluster; fRowOffset=other.fRowOffset; return *this; + fClusterNo=other.fClusterNo; fData=other.fData; fEntry=other.fEntry; fRowOffset=other.fRowOffset; return *this; } ~iterator() {} - void SetPadRow(int row) {if (fCluster) fCluster->SetRow(row-fRowOffset);} - void SetPad(float pad) {if (fCluster) fCluster->SetPad(pad);} - void SetTime(float time) {if (fCluster) fCluster->SetTimeBin(time);} - void SetSigmaY2(float sigmaY2) {if (fCluster) fCluster->SetSigmaY2(sigmaY2);} - void SetSigmaZ2(float sigmaZ2) {if (fCluster) fCluster->SetSigmaZ2(sigmaZ2);} - void SetCharge(unsigned charge) {if (fCluster) fCluster->SetQ(charge);} - void SetQMax(unsigned qmax) {if (fCluster) fCluster->SetMax(qmax);} + void SetPadRow(int row) {if (fEntry && fEntry->fCluster) fEntry->fCluster->SetPadRow(row-fRowOffset);} + void SetPad(float pad) {if (fEntry && fEntry->fCluster) fEntry->fCluster->SetPad(pad);} + void SetTime(float time) {if (fEntry && fEntry->fCluster) fEntry->fCluster->SetTime(time);} + void SetSigmaY2(float sigmaY2) {if (fEntry && fEntry->fCluster) fEntry->fCluster->SetSigmaY2(sigmaY2);} + void SetSigmaZ2(float sigmaZ2) {if (fEntry && fEntry->fCluster) fEntry->fCluster->SetSigmaZ2(sigmaZ2);} + void SetCharge(unsigned charge) {if (fEntry && fEntry->fCluster) fEntry->fCluster->SetCharge(charge);} + void SetQMax(unsigned qmax) {if (fEntry && fEntry->fCluster) fEntry->fCluster->SetQMax(qmax);} void SetMC(const AliHLTTPCClusterMCLabel* pMC) { - if (!fCluster || !pMC) return; - for (int k=0; k<3; k++) fCluster->SetLabel(pMC->fClusterID[k].fMCID, k); + if (fEntry) fEntry->fMC=pMC; } // switch to next cluster @@ -151,8 +170,8 @@ class AliHLTTPCClusterAccessHLTOUT : public TObject private: int fClusterNo; //! cluster no in the current block - AliTPCclusterMIContainer* fData; //! pointer to actual data - AliTPCclusterMI* fCluster; //! pointer to current cluster + AliRawClusterContainer* fData; //! pointer to actual data + AliRawClusterEntry* fEntry; //! pointer to current cluster int fRowOffset; //! row offset for current partition }; @@ -165,22 +184,24 @@ class AliHLTTPCClusterAccessHLTOUT : public TObject virtual void Clear(Option_t * option=""); /// get the cluster array for a sector TObjArray* GetSectorArray(unsigned sector) const; + /// fill the cluster array for a sector and specific row if specified + int FillSectorArray(TClonesArray* pSectorArray, unsigned sector, int row=-1) const; /// print info virtual void Print(Option_t *option=NULL) const; protected: /// load next cluster from array of the sepcific sector - AliTPCclusterMI* NextCluster(int slice, int partition); + AliRawClusterEntry* NextCluster(int slice, int partition); private: - AliTPCclusterMIContainer(const AliTPCclusterMIContainer&); - AliTPCclusterMIContainer& operator=(const AliTPCclusterMIContainer&); - - vector fClusterArrays; //! cluster arrays per sector (offline notation 0-71) - vector fRemainingClusterIds; //! clusters ids for remaining cluster ids - AliClusterIdBlock fTrackModelClusterIds; //! cluster ids for track model clusters - AliClusterIdBlock* fCurrentClusterIds; //! id block currently active in the iteration - vector fClusterMCData; //! references to MC data blocks + /// copy constructor prohibited + AliRawClusterContainer(const AliRawClusterContainer&); + /// assignment operator prohibited + AliRawClusterContainer& operator=(const AliRawClusterContainer&); + + vector fClusterVectors; //! instances of cluster arrays + vector fClusterMaps; //! cluster pointer vectors per sector (offline notation 0-71) + TClonesArray* fSectorArray; //! current sector array of clusters provided to caller iterator fIterator; //! }; @@ -198,9 +219,10 @@ class AliHLTTPCClusterAccessHLTOUT : public TObject }; int fVerbosity; //! verbosity level - AliTPCclusterMIContainer* fClusters; //! cluster container + AliRawClusterContainer* fClusters; //! cluster container int fCurrentSector; //! current sector AliHLTTPCDataCompressionDecoder* fpDecoder; //! decoder instance + AliTPCParam* fTPCParam; //! pointer to TPC param ClassDef(AliHLTTPCClusterAccessHLTOUT, 0) };