#include "AliHLTComponent.h"
#include "AliHLTTemplates.h"
#include "AliHLTDataDeflater.h"
-#include "AliRawDataHeader.h"
+#include "AliHLTCDHWrapper.h"
#include "AliLog.h"
#include "TMath.h"
#include <memory>
, fBlocks()
, fSingleBlock()
, fMode(mode)
+ , fWrittenClusterIds(NULL)
{
// see header file for class documentation
// or
// refer to README to build package
// or
// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
- if (fMode==1) {
+ if (fMode&kModeSingle) {
fSingleBlock.SetDecoder(new AliHLTTPCHWCFData);
fSingleBlock.SetGrid(AllocateIndexGrid());
}
, fBlocks()
, fSingleBlock()
, fMode(c.fMode)
+ , fWrittenClusterIds(NULL)
{
/// copy constructor
}
AliHLTSpacePointContainer::operator=(c);
fClusters=c.fClusters;
fMode=c.fMode;
+ fWrittenClusterIds=NULL;
return *this;
}
Clear();
if (fSingleBlock.GetDecoder()) delete fSingleBlock.GetDecoder();
if (fSingleBlock.GetGrid()) delete fSingleBlock.GetGrid();
+ if (fWrittenClusterIds) delete fWrittenClusterIds;
}
int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockData* pDesc)
return 0;
}
if (!pDesc->fPtr) return -ENODATA;
- if (pDesc->fSize<=sizeof(AliRawDataHeader)) return 0;
+ AliHLTCDHWrapper header(pDesc->fPtr);
+ if (pDesc->fSize<=header.GetHeaderSize()) return 0;
AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
AliHLTUInt8_t part = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
AliHLTUInt32_t decoderIndex=AliHLTTPCSpacePointData::GetID(slice, part, 0);
AliHLTUInt32_t *buffer=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
- // skip the first 8 32-bit CDH words
- buffer += 8;
- UInt_t bufferSize32 = ((Int_t)pDesc->fSize - sizeof(AliRawDataHeader) )/sizeof(AliHLTUInt32_t);
+ // skip the first 8 or 10 CDH words
+ buffer += header.GetHeaderSize()/sizeof(AliHLTUInt32_t);
+ UInt_t bufferSize32 = ((Int_t)pDesc->fSize - header.GetHeaderSize() )/sizeof(AliHLTUInt32_t);
AliHLTTPCHWCFData* pDecoder=NULL;
AliHLTSpacePointPropertyGrid* pGrid=NULL;
- if (fMode==1) {
+ if (fMode&kModeSingle) {
pDecoder=fSingleBlock.GetDecoder();
pGrid=fSingleBlock.GetGrid();
} else {
}
if (pDecoder->Init(reinterpret_cast<AliHLTUInt8_t*>(buffer), bufferSize32*sizeof(AliHLTUInt32_t))<0 ||
- (pDecoder->CheckVersion()<0 && (int)bufferSize32>pDecoder->GetRCUTrailerSize())) {
+ (pDecoder->CheckVersion()<0 && (int)(bufferSize32*sizeof(AliHLTUInt32_t))>pDecoder->GetRCUTrailerSize())) {
HLTError("data block of type %s corrupted: can not decode format",
AliHLTComponent::DataType2Text(pDesc->fDataType).c_str());
return -EBADMSG;
}
- if (fMode==1 && !pGrid) {
+ if (fMode&kModeSingle && !pGrid) {
pGrid=AllocateIndexGrid();
if (!pGrid) {
delete pDecoder;
}
}
- if (fMode==0) { // register immediately
+ if (fMode&kModeCreateMap) { // register immediately
UInt_t nofClusters=pDecoder->GetNumberOfClusters();
for (UInt_t i=0; i<nofClusters; i++) {
return iResult;
}
- if (fMode==1) {
+ if (fMode&kModeSingle) {
fSingleBlock.SetDecoder(pDecoder);
fSingleBlock.SetGrid(pGrid);
fSingleBlock.SetId(decoderIndex);
// allocate index grid, one single point to define the dimensions
// max 33 padrows, step 1 padrow
- // max 139 pads, step 8 pads
- // max 1024 time bins, step 10 timebins
- return new AliHLTSpacePointPropertyGrid(33, 1.0, 140, 8, 1024, 10);
+ // max 140 pads, step 2x max delta pad
+ // max 1024 time bins, step 2x max delta time
+ return new AliHLTSpacePointPropertyGrid(33, 1.0,
+ 140, 2*AliHLTTPCDefinitions::GetMaxClusterDeltaPad(),
+ 1024, 2*AliHLTTPCDefinitions::GetMaxClusterDeltaTime()
+ );
}
int AliHLTTPCHWCFSpacePointContainer::PopulateAccessGrid(AliHLTSpacePointPropertyGrid* pGrid, AliHLTUInt32_t mask) const
return cl->second.Decoder()->GetCharge(index);
}
+float AliHLTTPCHWCFSpacePointContainer::GetQMax(AliHLTUInt32_t clusterID) const
+{
+ // get charge
+ std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
+ if (cl==fClusters.end() ||
+ cl->second.Decoder()==NULL) return 0.0;
+ int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
+ return cl->second.Decoder()->GetQMax(index);
+}
+
float AliHLTTPCHWCFSpacePointContainer::GetPhi(AliHLTUInt32_t clusterID) const
{
// get charge
cl!=fClusters.end(); cl++) {
str << " 0x" << hex << setw(8) << setfill('0') << cl->first << dec << cl->second << endl;
}
- out << str;
+ out << str.str();
}
AliHLTSpacePointContainer* AliHLTTPCHWCFSpacePointContainer::SelectByMask(AliHLTUInt32_t mask, bool /*bAlloc*/) const
const char* option) const
{
/// write blocks to HLT component output
- if (fMode==0) return WriteUnsorted(outputPtr, size, offset, outputBlocks, pDeflater, option);
return WriteSorted(outputPtr, size, offset, outputBlocks, pDeflater, option);
}
-int AliHLTTPCHWCFSpacePointContainer::WriteUnsorted(AliHLTUInt8_t* outputPtr,
- AliHLTUInt32_t size,
- AliHLTUInt32_t offset,
- AliHLTComponentBlockDataList&
- outputBlocks,
- AliHLTDataDeflater* pDeflater,
- const char* /*option*/) const
-{
- /// write blocks to HLT component output
- if (!outputPtr) return -EINVAL;
- int iResult=0;
- AliHLTUInt32_t capacity=size;
- size=0;
-
- for (int slice=0; slice<AliHLTTPCTransform::GetNSlice() && iResult>=0; slice++) {
- for (int part=0; part<AliHLTTPCTransform::GetNPatches() && iResult>=0; part++) {
- AliHLTUInt32_t mask=AliHLTTPCSpacePointData::GetID(slice,part,0);
- // FIXME: make GetClusterIDs a const function and handle the cast there
- const vector<AliHLTUInt32_t>* collection=const_cast<AliHLTTPCHWCFSpacePointContainer*>(this)->GetClusterIDs(mask);
- if (!collection || collection->size()==0) continue;
- if (size+sizeof(AliHLTTPCRawClusterData)+collection->size()*sizeof(AliHLTTPCRawCluster)>capacity) {
- ALIHLTERRORGUARD(1,"too little space to write cluster output block");
- iResult=-ENOSPC;
- break;
- }
- AliHLTTPCRawClusterData* blockout=reinterpret_cast<AliHLTTPCRawClusterData*>(outputPtr+size);
- blockout->fVersion=0;
- blockout->fCount=0;
-
- if (pDeflater) {
- pDeflater->Clear();
- pDeflater->InitBitDataOutput(reinterpret_cast<AliHLTUInt8_t*>(blockout->fClusters), capacity-size-sizeof(AliHLTTPCRawClusterData));
- blockout->fVersion=pDeflater->GetDeflaterVersion();
- }
-
- unsigned lastPadRow=0;
- vector<AliHLTUInt32_t>::const_iterator clusterID=collection->begin();
- if (clusterID!=collection->end()) {
- std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(*clusterID);
- for (; clusterID!=collection->end(); clusterID++, (cl!=fClusters.end())?cl++:cl) {
- if (cl!=fClusters.end() && cl->first!=*clusterID) cl=fClusters.find(*clusterID);
- if (cl==fClusters.end() || cl->second.Decoder()==NULL) continue;
- int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
- int padrow=cl->second.Decoder()->GetPadRow(index);
- if (padrow<0) {
- // something wrong here, padrow is stored in the cluster header
- // word which has bit pattern 0x3 in bits bit 30 and 31 which was
- // not recognized
- ALIHLTERRORGUARD(1, "can not read cluster header word");
- break;
- }
-
- // FIXME: the HW ClusterFinder returns only the sum
- // sum(q_i*pad_i*pad_i)/sum(q_i)
- // where the mean needs to be subtracted, not yet in the decoder
- // but should be implemented there
- float pad =cl->second.Decoder()->GetPad(index);
- float time =cl->second.Decoder()->GetTime(index);
- float sigmaY2=cl->second.Decoder()->GetSigmaY2(index);
- float sigmaZ2=cl->second.Decoder()->GetSigmaZ2(index);
- sigmaY2-=pad*pad;
- sigmaZ2-=time*time;
-
- if (!pDeflater) {
- AliHLTTPCRawCluster& c=blockout->fClusters[blockout->fCount];
- padrow+=AliHLTTPCTransform::GetFirstRow(part);
- c.SetPadRow(padrow);
- c.SetCharge(cl->second.Decoder()->GetCharge(index));
- c.SetPad(pad);
- c.SetTime(time);
- c.SetSigmaY2(sigmaY2);
- c.SetSigmaZ2(sigmaZ2);
- c.SetQMax(cl->second.Decoder()->GetQMax(index));
- } else {
- AliHLTUInt64_t padrow64=cl->second.Decoder()->GetPadRow(index);
- // enable if padrows are ordered
- if (padrow64>=lastPadRow) {
- // padrow64-=lastPadRow;
- // lastPadRow+=padrow64;
- } else {
- // AliFatal("padrows not ordered");
- }
-
- AliHLTUInt64_t pad64
- =(AliHLTUInt64_t)round(pad*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kPad].fScale);
- AliHLTUInt64_t time64
- =(AliHLTUInt64_t)round(time*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kTime].fScale);
- AliHLTUInt64_t sigmaY264
- =(AliHLTUInt64_t)round(sigmaY2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaY2].fScale);
- AliHLTUInt64_t sigmaZ264
- =(AliHLTUInt64_t)round(sigmaZ2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaZ2].fScale);
- pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPadRow , padrow64);
- pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPad , pad64);
- pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kTime , time64);
- pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaY2, sigmaY264);
- pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaZ2, sigmaZ264);
- pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kCharge , cl->second.Decoder()->GetCharge(index));
- pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kQMax , cl->second.Decoder()->GetQMax(index));
- }
- blockout->fCount++;
- }
- }
- AliHLTComponent_BlockData bd;
- AliHLTComponent::FillBlockData(bd);
- bd.fOffset = size+offset;
- if (!pDeflater) {
- bd.fSize = sizeof(AliHLTTPCRawClusterData)+blockout->fCount*sizeof(AliHLTTPCRawCluster);
- } else {
- pDeflater->Pad8Bits();
- bd.fSize = sizeof(AliHLTTPCRawClusterData)+pDeflater->GetBitDataOutputSizeBytes();
- pDeflater->CloseBitDataOutput();
- }
- bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, part, part);
- bd.fDataType = AliHLTTPCDefinitions::fgkRawClustersDataType;
- outputBlocks.push_back(bd);
-
- size += bd.fSize;
- }
- }
-
- if (iResult<0) return iResult;
- return size;
-}
-
int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
AliHLTUInt32_t size,
AliHLTUInt32_t offset,
/// write blocks to HLT component output
int iResult=0;
- if (fMode==1) {
+ if (fMode&kModeSingle) {
iResult=WriteSorted(outputPtr, size, offset, fSingleBlock.GetDecoder(), fSingleBlock.GetGrid(), fSingleBlock.GetId(), outputBlocks, pDeflater, option);
} else {
iResult=-ENOENT;
AliHLTComponentBlockDataList&
outputBlocks,
AliHLTDataDeflater* pDeflater,
- const char* /*option*/) const
+ const char* option) const
{
/// write blocks to HLT component output
if (!outputPtr || !pDecoder || !pGrid) return -EINVAL;
if (pDecoder->GetNumberOfClusters()==0) return 0;
+ if (option) {
+ // this is only for sending mc labels in simulation and testing
+ // no impact to real running
+ if (!fWrittenClusterIds && strcmp(option, "write-cluster-ids")==0) {
+ const_cast<AliHLTTPCHWCFSpacePointContainer*>(this)->fWrittenClusterIds=new vector<AliHLTUInt32_t>;
+ }
+ }
int iResult=0;
AliHLTUInt32_t capacity=size;
size=0;
int slice=AliHLTTPCSpacePointData::GetSlice(mask);
int part=AliHLTTPCSpacePointData::GetPatch(mask);
+ // Note: the offset parameter is only for the block descriptors, output pointer and size
+ // consider already the offset
AliHLTTPCRawClusterData* blockout=reinterpret_cast<AliHLTTPCRawClusterData*>(outputPtr+size);
blockout->fVersion=0;
blockout->fCount=0;
pDeflater->Clear();
pDeflater->InitBitDataOutput(reinterpret_cast<AliHLTUInt8_t*>(blockout->fClusters), capacity-size-sizeof(AliHLTTPCRawClusterData));
blockout->fVersion=pDeflater->GetDeflaterVersion();
+ if (fMode&kModeDifferentialPadTime) blockout->fVersion+=2;
}
unsigned lastPadRow=0;
+ AliHLTUInt64_t lastPad64=0;
+ AliHLTUInt64_t lastTime64=0;
AliHLTSpacePointPropertyGrid::iterator clusterID=pGrid->begin();
if (clusterID!=pGrid->end()) {
for (; clusterID!=pGrid->end(); clusterID++) {
+ if (clusterID.Data().fTrackId>-1) {
+ // this is an assigned cluster, skip
+ // TODO: introduce selectors into AliHLTIndexGrid::begin to loop
+ // consistently over entries, e.g. this check has to be done also
+ // in the forwarding of MC labels in
+ // AliHLTTPCDataCompressionComponent::ForwardMCLabels
+ continue;
+ }
if ((unsigned)slice!=AliHLTTPCSpacePointData::GetSlice(clusterID.Data().fId) ||
(unsigned)part!=AliHLTTPCSpacePointData::GetPatch(clusterID.Data().fId)) {
HLTError("cluster index 0x%08x out of slice %d partition %d", clusterID.Data().fId, slice, part);
int index=AliHLTTPCSpacePointData::GetNumber(clusterID.Data().fId);
const AliHLTTPCHWCFData::iterator& input=pDecoder->find(index);
if (!(input!=pDecoder->end())) continue;
+ if (fWrittenClusterIds) fWrittenClusterIds->push_back(clusterID.Data().fId);
int padrow=input.GetPadRow();
if (padrow<0) {
// something wrong here, padrow is stored in the cluster header
break;
}
- // FIXME: the HW ClusterFinder returns only the sum
- // sum(q_i*pad_i*pad_i)/sum(q_i)
- // where the mean needs to be subtracted, not yet in the decoder
- // but should be implemented there
float pad =input.GetPad();
float time =input.GetTime();
float sigmaY2=input.GetSigmaY2();
float sigmaZ2=input.GetSigmaZ2();
- sigmaY2-=pad*pad;
- sigmaZ2-=time*time;
-
if (!pDeflater) {
AliHLTTPCRawCluster& c=blockout->fClusters[blockout->fCount];
padrow+=AliHLTTPCTransform::GetFirstRow(part);
AliFatal("padrows not ordered");
}
+ AliHLTUInt32_t padType=0;
+ AliHLTUInt32_t signdPad=0;
AliHLTUInt64_t pad64=0;
+ if ((fMode&kModeDifferentialPadTime)!=0 && sigmaY2<.00001) {
+ // single pad cluster
+ // use twice the pad position to take account for the 0.5 offset
+ // added in the AliHLTTPCHWCFData decoder in accordance with the
+ // offline definition. Using the factor 2, this offset is not
+ // cut off by rounding
+ pad64=(AliHLTUInt64_t)round(2*pad);
+ padType=1;
+ } else {
if (!isnan(pad)) pad64=(AliHLTUInt64_t)round(pad*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kPad].fScale);
+ }
+ if (fMode&kModeDifferentialPadTime && padType==0) {
+ AliHLTUInt64_t dpad64=0;
+ if (pad64<lastPad64) {
+ dpad64=lastPad64-pad64;
+ signdPad=1;
+ } else {
+ dpad64=pad64-lastPad64;
+ signdPad=0;
+ }
+ lastPad64=pad64;
+ pad64=dpad64;
+ }
+ AliHLTUInt32_t signdTime=0;
AliHLTUInt64_t time64=0;
if (!isnan(time)) time64=(AliHLTUInt64_t)round(time*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kTime].fScale);
+ if (fMode&kModeDifferentialPadTime) {
+ AliHLTUInt64_t dtime64=0;
+ if (time64<lastTime64) {
+ dtime64=lastTime64-time64;
+ signdTime=1;
+ } else {
+ dtime64=time64-lastTime64;
+ signdTime=0;
+ }
+ lastTime64=time64;
+ time64=dtime64;
+ }
AliHLTUInt64_t sigmaY264=0;
if (!isnan(sigmaY2)) sigmaY264=(AliHLTUInt64_t)round(sigmaY2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaY2].fScale);
AliHLTUInt64_t sigmaZ264=0;
if (!isnan(sigmaZ2)) sigmaZ264=(AliHLTUInt64_t)round(sigmaZ2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaZ2].fScale);
pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPadRow , padrow64);
- pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPad , pad64);
+ pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPad , pad64);
+ if (fMode&kModeDifferentialPadTime) pDeflater->OutputBit(padType);
+ if (fMode&kModeDifferentialPadTime && padType==0) pDeflater->OutputBit(signdPad);
pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kTime , time64);
- pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaY2, sigmaY264);
+ if (fMode&kModeDifferentialPadTime) pDeflater->OutputBit(signdTime);
+ if (padType==0) pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaY2, sigmaY264);
pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaZ2, sigmaZ264);
pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kCharge , input.GetCharge());
pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kQMax , input.GetQMax());
}
bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, part, part);
outputBlocks.push_back(bd);
-
+
size += bd.fSize;
+ if (fWrittenClusterIds && fWrittenClusterIds->size()>0) {
+ AliHLTComponent::FillBlockData(bd);
+ bd.fOffset = size+offset;
+ bd.fSize = fWrittenClusterIds->size()*sizeof(vector<AliHLTUInt32_t>::value_type);
+ if (bd.fSize+size<=capacity) {
+ memcpy(outputPtr+size, &(*fWrittenClusterIds)[0], bd.fSize);
+ bd.fDataType = AliHLTTPCDefinitions::RemainingClusterIdsDataType();
+ bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, part, part);
+ outputBlocks.push_back(bd);
+ size += bd.fSize;
+ } else {
+ iResult=-ENOSPC;
+ }
+ fWrittenClusterIds->clear();
+ }
+
if (iResult<0) return iResult;
return size;
}
<< " " << setw(5) << decoder->GetCharge(fIndex)
<< " " << setw(5) << decoder->GetQMax(fIndex)
<< " " << fTrackId << " " << fMCId << " " << fUsed;
- out << str;
+ out << str.str();
}
ostream& operator<<(ostream &out, const AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties& p)