]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/RCU/AliHLTAltroChannelSelectorComponent.cxx
enhanced version of the selector component for increased performance of selective...
[u/mrichter/AliRoot.git] / HLT / RCU / AliHLTAltroChannelSelectorComponent.cxx
index 23e0e8b485fd5b652549ed72ff852b2d3d13cb89..5af00ea4b638b96a5b91766f67d9e878efdb2973 100644 (file)
@@ -32,6 +32,8 @@
 #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)
@@ -39,8 +41,12 @@ 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
@@ -93,24 +99,59 @@ int AliHLTAltroChannelSelectorComponent::DoInit(int argc, const char** argv)
   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;
   }
@@ -135,6 +176,11 @@ int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData&
   int iResult=0;
   const int cdhSize=32;
 
+  if (!IsDataEvent()) {
+    size=0;
+    return 0;
+  }
+
   // process the DLL input
   int blockno=0;
   const AliHLTComponentBlockData* pDesc=NULL;
@@ -142,10 +188,14 @@ int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData&
   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
@@ -156,10 +206,11 @@ int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData&
       }
     }
     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;
@@ -178,15 +229,25 @@ int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData&
       }
     }
 
-    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;
     }
@@ -198,10 +259,69 @@ int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData&
     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) {
@@ -212,26 +332,19 @@ int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData&
        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) {
@@ -239,17 +352,17 @@ int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData&
            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;
@@ -285,7 +398,7 @@ int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData&
        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;
 
@@ -293,7 +406,20 @@ int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData&
     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;
 }