#include "AliHLTAltroChannelSelectorComponent.h"
#include "AliAltroDecoder.h"
#include "AliAltroData.h"
+#include "AliAltroBunch.h"
+#include "TMath.h"
/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTAltroChannelSelectorComponent)
AliHLTAltroChannelSelectorComponent::AliHLTAltroChannelSelectorComponent()
:
AliHLTProcessor(),
- fSkipCorrupted(false),
- fTalkative(false)
+ fSkipCorrupted(true),
+ fTalkative(false),
+ fStartTimeBin(0),
+ fEndTimeBin(0),
+ fSignalThreshold(0),
+ fRMSThreshold(0)
{
// see header file for class documentation
// or
int iResult=0;
TString argument="";
bool bMissingParam=0;
- for (int i=0; i<argc && iResult>=0; i++) {
+ char* cpErr=NULL;
+ int i=0;
+ for (; i<argc && iResult>=0; i++) {
+ cpErr=NULL;
argument=argv[i];
if (argument.IsNull()) continue;
- // -skip-corrupted
+ // -skip-corrupted, just for backward compatibility, not announced
if (argument.CompareTo("-skip-corrupted")==0) {
fSkipCorrupted=true;
+ // -keep-corrupted
+ } else if (argument.CompareTo("-keep-corrupted")==0) {
+ fSkipCorrupted=false;
+
// -talkative
} else if (argument.CompareTo("-talkative")==0) {
fTalkative=true;
+
+ // -start-timebin
+ } else if (argument.CompareTo("-start-timebin")==0) {
+ if (bMissingParam=(++i>=argc)) break;
+ fStartTimeBin = strtoul( argv[i], &cpErr ,0);
+ if ( *cpErr ) break;
+
+ // -end-timebin
+ } else if (argument.CompareTo("-end-timebin")==0) {
+ if (bMissingParam=(++i>=argc)) break;
+ fEndTimeBin = strtoul( argv[i], &cpErr ,0);
+ if ( *cpErr ) break;
+
+ // -signal-threshold
+ } else if (argument.CompareTo("-signal-threshold")==0) {
+ if (bMissingParam=(++i>=argc)) break;
+ fSignalThreshold = strtoul( argv[i], &cpErr ,0);
+ if ( *cpErr ) break;
+
+ // -rms-threshold
+ } else if (argument.CompareTo("-rms-threshold")==0) {
+ if (bMissingParam=(++i>=argc)) break;
+ fRMSThreshold = strtoul( argv[i], &cpErr ,0);
+ if ( *cpErr ) break;
+
} else {
HLTError("unknown argument %s", argument.Data());
iResult=-EINVAL;
}
}
- if (bMissingParam) {
+ if (cpErr && *cpErr) {
+ HLTError("Cannot convert specifier '%s' for argument '%s'", argv[i], argument.Data());
+ iResult=-EINVAL;
+ } else if (bMissingParam) {
HLTError("missing parameter for argument %s", argument.Data());
iResult=-EINVAL;
}
int iResult=0;
const int cdhSize=32;
+ if (!IsDataEvent()) {
+ size=0;
+ return 0;
+ }
+
// process the DLL input
int blockno=0;
const AliHLTComponentBlockData* pDesc=NULL;
AliAltroDecoder* decoder=NULL;
for (pDesc=GetFirstInputBlock(kAliHLTDataTypeDDLRaw); pDesc!=NULL; pDesc=GetNextInputBlock(), blockno++) {
iResult=0;
+ if (pDesc->fSize<=32) {
+ continue;
+ }
// search for the active pad information
AliHLTUInt16_t* pActiveHwAddressArray=NULL;
int iArraySize=0;
+ if (fSignalThreshold==0 && fRMSThreshold==0) {
for (int i=0; i<(int)evtData.fBlockCnt; i++ ) {
// search for selection data of hw address type
// which matches the data specification of the block
}
}
if (pActiveHwAddressArray==NULL) {
- HLTWarning("no block of type %s for specification 0x%08x available, data block unchanged",
+ HLTWarning("no block of type %s for specification 0x%08x available, data block skipped",
DataType2Text(kAliHLTDataTypeHwAddr16).c_str(),
pDesc->fSpecification);
- iResult=-EFAULT;
+ break;
+ }
}
if (decoder) delete decoder;
}
}
- int rcuTrailerLength=decoder->GetRCUTrailerSize();
- if (rcuTrailerLength*sizeof(AliHLTUInt32_t)>pDesc->fSize-cdhSize) {
- HLTWarning("corrupted data block: RCU trailer length exceeds buffer size");
+ unsigned int rcuTrailerLength=0;
+ if (iResult>=0 &&
+ ((rcuTrailerLength=decoder->GetRCUTrailerSize())==0 ||
+ rcuTrailerLength>pDesc->fSize-cdhSize)) {
+ if (rcuTrailerLength>0) {
+ HLTWarning("corrupted data block: RCU trailer length exceeds buffer size");
+ } else {
+ HLTWarning("corrupted data block: RCU trailer of zero length");
+ }
iResult=-EFAULT;
}
if (iResult<0) {
- // forward the whole block
- outputBlocks.push_back(*pDesc);
+ // TODO: here the trigger has to come into play. It is up to
+ // policy if a corrupted data block should be kept (original
+ // DDL) or discarded. In any case, the block is not going to
+ // be part of HLTOUT
+ HLTWarning("skipping corrupted data block for event %lu, data block %s 0x%08x", evtData.fEventID,
+ DataType2Text(pDesc->fDataType).c_str(), pDesc->fSpecification);
iResult=0;
continue;
}
AliHLTUInt32_t iNofAltro40=0;
AliHLTUInt32_t iCapacity=size;
AliAltroData channel;
+ AliAltroBunch altrobunch;
+
+ // first add the RCU trailer
+ AliHLTUInt8_t* pSrc=reinterpret_cast<AliHLTUInt8_t*>(pDesc->fPtr);
+ pSrc+=pDesc->fSize-rcuTrailerLength;
+ if ((iResult=CopyBlockToEnd(outputPtr, iCapacity, iOutputSize, pSrc, rcuTrailerLength))>=0) {
+ assert(iResult==(int)rcuTrailerLength);
+ iOutputSize+=rcuTrailerLength;
+ } else {
+ HLTError("failed to write RCU trailer of length %d for block %d, too little space in output buffer?", rcuTrailerLength, blockno);
+ iResult=-ENOSPC;
+ break;
+ }
+
while (decoder->NextChannel(&channel) && iResult>=0) {
iTotal++;
int hwAddress=channel.GetHadd();
+ if (fSignalThreshold!=0) {
+ // treshold by adc counts
+ unsigned int sumSignals=0;
+ unsigned int maxSignal=0;
+ unsigned int nofSignals=0;
+ while(channel.NextBunch(&altrobunch)){
+ const UInt_t *bunchData=altrobunch.GetData();
+ unsigned int time=altrobunch.GetStartTimeBin();
+ for(Int_t i=0;i<altrobunch.GetBunchSize();i++){
+ if(bunchData[i]>0){// disregarding 0 data.
+ if(time+i>=fStartTimeBin && time+i<=fEndTimeBin){
+ sumSignals+=bunchData[i];
+ if (maxSignal<bunchData[i]) maxSignal=bunchData[i];
+ nofSignals++;
+ }
+ }
+ }
+ }
+ if (nofSignals==0 || maxSignal<=(sumSignals/nofSignals)+fSignalThreshold) {
+ continue;
+ }
+
+ } else if (fRMSThreshold!=0) {
+ // treshold by adc counts
+ unsigned int sumSignals=0;
+ unsigned int maxSignal=0;
+ unsigned int nofSignals=0;
+ while(channel.NextBunch(&altrobunch)){
+ const UInt_t *bunchData=altrobunch.GetData();
+ unsigned int time=altrobunch.GetStartTimeBin();
+ for(Int_t i=0;i<altrobunch.GetBunchSize();i++){
+ if(bunchData[i]>0){// disregarding 0 data.
+ if(time+i>=fStartTimeBin && time+i<=fEndTimeBin){
+ sumSignals+=bunchData[i]*bunchData[i];
+ if (maxSignal<bunchData[i]) maxSignal=bunchData[i];
+ nofSignals++;
+ }
+ }
+ }
+ }
+ if (nofSignals==0 || maxSignal<=TMath::Sqrt(sumSignals/nofSignals)*fRMSThreshold) {
+ continue;
+ }
+
+ } else {
int active=0;
for (active=0; active<iArraySize; active++) {
if (pActiveHwAddressArray[active]==(AliHLTUInt16_t)hwAddress) {
HLTDebug("ALTRO block %#x (%d) discarded (inactive)", hwAddress, hwAddress);
continue;
}
+ }
// no of 10 bit words is without the fill words to fill complete 40 bit words
// in addition, align to complete 40 bit words (the '+3')
// also, the 5 bytes of the Altro trailer must be added to get the full size
int channelSize=((channel.GetDataSize()+3)/4)*5;
+ if (channelSize==0) {
+ if (fTalkative) HLTWarning("skipping zero length channel (hw address %d)", hwAddress);
+ iCorrupted++;
+ continue;
+ }
channelSize+=5;
HLTDebug("ALTRO block hwAddress 0x%08x (%d) selected (active), size %d", hwAddress, hwAddress, channelSize);
- if (iOutputSize==0) {
- // first add the RCU trailer
- AliHLTUInt8_t* pSrc=reinterpret_cast<AliHLTUInt8_t*>(pDesc->fPtr);
- pSrc+=pDesc->fSize-rcuTrailerLength;
- if ((iResult=CopyBlockToEnd(outputPtr, iCapacity, iOutputSize, pSrc, rcuTrailerLength))>=0) {
- assert(iResult==rcuTrailerLength);
- iOutputSize+=rcuTrailerLength;
- } else {
- HLTError("failed to write RCU trailer of length %d for block %d, too little space in output buffer?", rcuTrailerLength, blockno);
- iResult=-ENOSPC;
- break;
- }
- }
if ((iResult=decoder->CopyBackward(outputPtr, iCapacity-iOutputSize))>=0) {
if (channelSize == iResult) {
iNofAltro40+=channelSize/5;
iOutputSize+=channelSize;
} else {
- if (fTalkative) HLTWarning("corrupted ALTRO channel: incomplete 40 bit word");
+ if (fTalkative) HLTWarning("corrupted ALTRO channel: incomplete 40 bit word (channel hw address %d)", hwAddress);
iCorrupted++;
continue;
}
} else {
- if (fTalkative) HLTWarning("internal error: failed to copy full channel: %d out of %d bytes", iResult, channelSize);
+ if (fTalkative) HLTWarning("internal error: failed to copy full channel: %d out of %d bytes (hw address %d)", iResult, channelSize, hwAddress);
iCorrupted++;
continue;
}
} else {
- if (fTalkative) HLTError("failed to write ALTRO channel of length %d for block %d", channelSize, blockno);
+ if (fTalkative) HLTError("failed to write ALTRO channel of length %d for block %d (hw address %d)", channelSize, blockno, hwAddress);
// corrupted channel, but keep going
iCorrupted++;
iResult=0;
break;
}
}
- HLTInfo("data block %d (0x%08x): selected %d out of %d ALTRO channel(s), %d corrupted channels skipped", blockno, pDesc->fSpecification, iSelected, iTotal, iCorrupted);
+ if (fTalkative) HLTImportant("data block %d (0x%08x): selected %d out of %d ALTRO channel(s), %d corrupted channels skipped", blockno, pDesc->fSpecification, iSelected, iTotal, iCorrupted);
}
if (decoder) delete decoder;
outputBlocks.clear();
}
- // !!! do not change the size since the output buffer is filled from the end !!!
+ // all data blocks need to be moved to the beginning of the
+ // buffer because PubSub is not able to handle data blocks entirely
+ // at the end of the buffer. The problem is that the component always
+ // indicates to use the full size of the buffer
+ if (outputBlocks.size()>0) {
+ int offset=outputBlocks.back().fOffset;
+ size-=offset;
+ memmove(outputPtr, outputPtr+offset, size);
+ for (AliHLTComponentBlockDataList::iterator block=outputBlocks.begin();
+ block!=outputBlocks.end();
+ block++) {
+ block->fOffset-=offset;
+ }
+ }
return iResult;
}