//-*- Mode: C++ -*-
// $Id$
#ifndef ALIHLTTPCHWCFDATA_H
#define ALIHLTTPCHWCFDATA_H
//* This file is property of and copyright by the ALICE HLT Project *
//* ALICE Experiment at CERN, All rights reserved. *
//* See cxx source for full Copyright notice *
/// @file AliHLTTPCHWCFData.h
/// @author Matthias Richter
/// @date 2011-08-04
/// @brief Decoder methods for the HWCF format
///
#include "AliHLTTPCRootTypes.h"
#include "AliHLTDataTypes.h"
#include "AliHLTLogging.h"
#include "AliHLTErrorGuard.h"
class TArrayC;
/**
* @class AliHLTTPCHWCFData
* The class provides decoding functionality for the output format of the
* TPC HW ClusterFinder
*
* Two formats have been defined in the past and can be detected:
* version 0: 5 32bit words 20 Byte
*
* word 0: header (big endian 32bit unsigned)
* bit 31-30: 0x11 indicates cluster
* bit 29-24: row number in partition
* bit 23-0: Qtot, fixed point number with 6 bits after the point
* word 1: pad (float)
* word 2: time (float)
* word 3: pad variance (float)
* word 4: time variance (float)
*
*
* version 1: 6 32bit words 24 Byte
*
* word 0: header (big endian 32bit unsigned)
* bit 31-30: 0x11 indicates cluster
* bit 29-24: row number in partition
* bit 23-0: Qmax, fixed point number with 6 bits after the point
* word 1: total charge 32bit big endian, fixed point number with 12 bits after the point
* word 2: pad (float)
* word 3: time (float)
* word 4: pad variance (float)
* word 5: time variance (float)
*
*/
class AliHLTTPCHWCFData : public AliHLTLogging {
public:
AliHLTTPCHWCFData(int forceVersion=-1);
virtual ~AliHLTTPCHWCFData();
int Init(const AliHLTUInt8_t* pBuffer, int bufferSize);
int Reset();
Int_t GetNumberOfClusters() const;
Int_t GetPadRow(int i) const;
Float_t GetPad(int i) const;
Float_t GetTime(int i) const;
Float_t GetSigmaY2(int i) const;
Float_t GetSigmaZ2(int i) const;
Int_t GetCharge(int i) const;
Int_t GetQMax(int i) const;
int CheckVersion();
bool CheckAssumption(int format, const AliHLTUInt8_t* pData, int size) const;
// check if index is within bounds
bool CheckBounds(int i) const {
if (fVersion<0) {
ALIHLTERRORGUARD(1, "");
return false;
}
int elementsize=GetElementSize(fVersion);
if (elementsize<0) return false;
return ((i+1)*elementsize+fRCUTrailerSize<=fBufferSize);
}
// get the size of one element
int GetElementSize(int version) const {
switch (version) {
case 0: return sizeof(AliHLTTPCHWClusterV0);
case 1: return sizeof(AliHLTTPCHWClusterV1);
default:
ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
}
return -1;
}
// pointer to RCU trailer
const AliHLTUInt8_t* GetRCUTrailer() const
{
if (fRCUTrailerSize<=0 || fpBuffer==NULL || fBufferSize0) ?sy2 :0.;
}
Float_t GetSigmaZ2() const {
Float_t sz2 = fSigmaZ2 - fTime*fTime;
return (sz2>0) ?sz2 :0.;
}
Int_t GetCharge() const;
Int_t GetQMax() const {return -1;}
};
struct AliHLTTPCHWClusterV1 {
AliHLTUInt32_t fHeader;
AliHLTUInt32_t fCharge;
Float_t fPad;
Float_t fTime;
Float_t fSigmaY2;
Float_t fSigmaZ2;
Int_t GetPadRow() const;
Float_t GetPad() const {return fPad+0.5;}
Float_t GetTime() const {return fTime;}
Float_t GetSigmaY2() const {
Float_t sy2 = fSigmaY2 - fPad*fPad;
return (sy2>0) ?sy2 :0.;
}
Float_t GetSigmaZ2() const {
Float_t sz2 = fSigmaZ2 - fTime*fTime;
return (sz2>0) ?sz2 :0.;
}
Int_t GetCharge() const;
Int_t GetQMax() const;
};
template
class AliHLTTPCHWClusterDecoder {
public:
AliHLTTPCHWClusterDecoder(const T* pClusterArray, int entries);
~AliHLTTPCHWClusterDecoder();
// i'th element, no bounds check for performance reasons
const T& operator[](unsigned i) {
return fpClusterArray[i];
}
Int_t GetPadRow(int i) const {return fpClusterArray[i]->GetPadRow();}
Float_t GetPad(int i) const {return fpClusterArray[i]->GetPad();}
Float_t GetTime(int i) const {return fpClusterArray[i]->GetTime();}
Float_t GetSigmaY2(int i) const {return fpClusterArray[i]->GetSigmaY2();}
Float_t GetSigmaZ2(int i) const {return fpClusterArray[i]->GetSigmaZ2();}
Int_t GetCharge(int i) const {return fpClusterArray[i]->GetCharge();}
Int_t GetQMax(int i) const {return fpClusterArray[i]->GetQMax();}
private:
const T* fpClusterArray; //! array of clusters
int fEntries; //! number of entries
};
class iterator {
public:
iterator()
: fData(NULL), fVersion(-1), fElementSize(0) {}
iterator(const AliHLTUInt8_t* pData, int version, int elementSize)
: fData(pData), fVersion(version), fElementSize(elementSize) {}
iterator(const iterator& i)
: fData(i.fData), fVersion(i.fVersion), fElementSize(i.fElementSize) {}
iterator& operator=(const iterator& i)
{ fData=i.fData; fVersion=i.fVersion; fElementSize=i.fElementSize; return *this;}
~iterator() {fData=NULL;}
bool operator==(const iterator& i) const {return (fData!=NULL) && (fData==i.fData);}
bool operator!=(const iterator& i) const {return (fData!=NULL) && (fData!=i.fData);}
// prefix operators
iterator& operator++() {fData+=fElementSize; return *this;}
iterator& operator--() {fData-=fElementSize; return *this;}
// postfix operators
iterator operator++(int) {iterator i(*this); fData+=fElementSize; return i;}
iterator operator--(int) {iterator i(*this); fData-=fElementSize; return i;}
iterator& operator+=(int step) {fData+=step*fElementSize; return *this;}
Int_t GetPadRow() const {
switch (fVersion) {
case 0: return reinterpret_cast(fData)->GetPadRow();
case 1: return reinterpret_cast(fData)->GetPadRow();
} return -1;
}
Float_t GetPad() const {
switch (fVersion) {
case 0: return reinterpret_cast(fData)->GetPad();
case 1: return reinterpret_cast(fData)->GetPad();
} return -10000.;
}
Float_t GetTime() const {
switch (fVersion) {
case 0: return reinterpret_cast(fData)->GetTime();
case 1: return reinterpret_cast(fData)->GetTime();
} return -10000.;
}
Float_t GetSigmaY2() const {
switch (fVersion) {
case 0: return reinterpret_cast(fData)->GetSigmaY2();
case 1: return reinterpret_cast(fData)->GetSigmaY2();
} return -10000.;
}
Float_t GetSigmaZ2() const {
switch (fVersion) {
case 0: return reinterpret_cast(fData)->GetSigmaZ2();
case 1: return reinterpret_cast(fData)->GetSigmaZ2();
} return -10000.;
}
Int_t GetCharge() const {
switch (fVersion) {
case 0: return reinterpret_cast(fData)->GetCharge();
case 1: return reinterpret_cast(fData)->GetCharge();
} return -1;
}
Int_t GetQMax() const {
switch (fVersion) {
case 0: return reinterpret_cast(fData)->GetQMax();
case 1: return reinterpret_cast(fData)->GetQMax();
} return -1;
}
protected:
private:
const AliHLTUInt8_t* fData; //! data
int fVersion; //! format version
int fElementSize; //! element size
};
// prepare iterator and end marker
iterator& begin() {
fIterator.~iterator();
new (&fIterator) iterator(fpBuffer, fVersion, GetElementSize(fVersion));
fIteratorEnd=fIterator;
fIteratorEnd+=GetNumberOfClusters();
return fIterator;
}
// get loop end marker
iterator& end() {
return fIteratorEnd;
}
// find one single element
iterator& find(int i) {
fIterator.~iterator();
fIteratorEnd.~iterator();
if (i>=GetNumberOfClusters()) return fIterator;
new (&fIterator) iterator(fpBuffer, fVersion, GetElementSize(fVersion));
fIterator+=i;
fIteratorEnd=fIterator;
fIteratorEnd+=1;
return fIterator;
}
static const unsigned fgkAliHLTTPCHWClusterSize;
protected:
private:
AliHLTTPCHWCFData(const AliHLTTPCHWCFData&);
AliHLTTPCHWCFData& operator=(const AliHLTTPCHWCFData&);
// get pointer to i'th element
const AliHLTUInt8_t* Get(int i) const
{
if (!fpBuffer) return NULL;
int elementsize=GetElementSize(fVersion);
if (elementsize<0) return NULL;
return fpBuffer+(i*elementsize);
}
const AliHLTUInt8_t* fpBuffer; //! pointer to data buffer
int fBufferSize; //! size of data buffer
int fVersion; //! format version
int fForcedVersion; //! forced format version
int fRCUTrailerSize; //! size of the RCU trailer in Byte
TArrayC* fpFileBuffer; //! internal buffer for file content
iterator fIterator; //! iterator
iterator fIteratorEnd; //! end iterator
ClassDef(AliHLTTPCHWCFData, 0)
};
#endif