3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
7 * Primary Authors: Kenneth Aamodt <Kenneth.Aamodt@student.uib.no> *
8 * for The ALICE HLT Project. *
10 * Permission to use, copy, modify and distribute this software and its *
11 * documentation strictly for non-commercial purposes is hereby granted *
12 * without fee, provided that the above copyright notice appears in all *
13 * copies and that both the copyright notice and this permission notice *
14 * appear in the supporting documentation. The authors make no claims *
15 * about the suitability of this software for any purpose. It is *
16 * provided "as is" without express or implied warranty. *
17 **************************************************************************/
19 /** @file AliHLTTPCZeroSuppressionComponent.cxx
20 @author Kenneth Aamodt
22 @brief The TPC ZeroSuppression component
25 // see header file for class documentation //
27 // refer to README to build package //
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt //
34 #include "AliHLTTPCZeroSuppressionComponent.h"
35 #include "AliHLTTPCDigitReaderDecoder.h"
36 #include "AliHLTTPCTransform.h"
37 #include "AliHLTTPCDefinitions.h"
38 #include "AliHLTTPCDigitData.h"
43 #include "AliHLTAltroEncoder.h"
44 #include "AliRawDataHeader.h"
46 /** ROOT macro for the implementation of ROOT specific class methods */
47 ClassImp(AliHLTTPCZeroSuppressionComponent)
49 AliHLTTPCZeroSuppressionComponent::AliHLTTPCZeroSuppressionComponent()
53 fNumberOfPadsInRow(NULL),
59 fEndTimeBin(AliHLTTPCTransform::GetNTimeBins()),
63 fMinimumNumberOfSignals(AliHLTTPCTransform::GetNTimeBins()/2),
66 fVectorInitialized(kFALSE),
67 fValueBelowAverage(5),
70 fGetActivePads(kFALSE),
73 // see header file for class documentation
75 // refer to README to build package
77 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
80 AliHLTTPCZeroSuppressionComponent::~AliHLTTPCZeroSuppressionComponent()
82 // see header file for class documentation
83 if(fVectorInitialized){
84 DeInitializePadArray();
86 if(fNumberOfPadsInRow){
87 delete [] fNumberOfPadsInRow;
88 fNumberOfPadsInRow=NULL;
96 // Public functions to implement AliHLTComponent's interface.
97 // These functions are required for the registration process
99 const char* AliHLTTPCZeroSuppressionComponent::GetComponentID()
101 // see header file for class documentation
102 return "TPCZeroSuppression";
105 void AliHLTTPCZeroSuppressionComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
107 // see header file for class documentation
109 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
112 AliHLTComponentDataType AliHLTTPCZeroSuppressionComponent::GetOutputDataType()
114 // see header file for class documentation
115 return kAliHLTMultipleDataType;
116 //return kAliHLTDataTypeDDLRaw;
117 // return AliHLTTPCDefinitions::fgkUnpackedRawDataType;
120 int AliHLTTPCZeroSuppressionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
122 // see header file for class documentation
124 tgtList.push_back(kAliHLTDataTypeDDLRaw);
125 tgtList.push_back(kAliHLTDataTypeHwAddr16);
126 return tgtList.size();
129 void AliHLTTPCZeroSuppressionComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
131 // see header file for class documentation
136 AliHLTComponent* AliHLTTPCZeroSuppressionComponent::Spawn()
138 // see header file for class documentation
139 return new AliHLTTPCZeroSuppressionComponent();
142 int AliHLTTPCZeroSuppressionComponent::DoInit( int argc, const char** argv )
144 // see header file for class documentation
151 // -- zero suppression threshold
152 if ( !strcmp( argv[i], "signal-threshold" ) ) {
153 fSignalThreshold = strtoul( argv[i+1], &cpErr ,0);
155 HLTError("Cannot convert signal-threshold specifier '%s'.", argv[i+1]);
162 // -- checking for nsigma-threshold, used in 2007 December run in ZeroSuppression
163 if ( !strcmp( argv[i], "rms-threshold" ) ) {
164 fNRMSThreshold = strtoul( argv[i+1], &cpErr ,0);
166 HLTError("Cannot convert rms-threshold specifier '%s'. Must be integer", argv[i+1]);
173 // -- number of timebins
174 if ( !strcmp( argv[i], "ntimebins" ) ) {
175 fNTimeBins = strtoul( argv[i+1], &cpErr ,0);
177 HLTError("Cannot convert ntimebins specifier '%s'.", argv[i+1]);
185 if ( !strcmp( argv[i], "start-timebin" ) ) {
186 fStartTimeBin = strtoul( argv[i+1], &cpErr ,0);
188 HLTError("Cannot convert start-timebin specifier '%s'.", argv[i+1]);
196 if ( !strcmp( argv[i], "end-timebin" ) ) {
197 if(strtoul( argv[i+1], &cpErr ,0)<=(UInt_t)AliHLTTPCTransform::GetNTimeBins()){
198 fEndTimeBin = strtoul( argv[i+1], &cpErr ,0);
201 HLTError("Cannot convert end-timebin specifier '%s'.", argv[i+1]);
208 // -- timebins to keep left of signal
209 if ( !strcmp( argv[i], "timebin-left" ) ) {
210 fLeftTimeBin = strtoul( argv[i+1], &cpErr ,0);
212 HLTError("Cannot convert timebin-left specifier '%s'.", argv[i+1]);
219 // -- timebin to keep right of signal
220 if ( !strcmp( argv[i], "timebin-right" ) ) {
221 fRightTimeBin = strtoul( argv[i+1], &cpErr ,0);
223 HLTError("Cannot convert timebin-right specifier '%s'.", argv[i+1]);
230 // -- value below average to subtract
231 if ( !strcmp( argv[i], "value-below-average" ) ) {
232 fValueBelowAverage = strtoul( argv[i+1], &cpErr ,0);
234 HLTError("Cannot convert value-below-average specifier '%s'.", argv[i+1]);
241 // -- pad occupancy limit
242 if ( !strcmp( argv[i], "occupancy-limit" ) ) {
243 fMinimumNumberOfSignals = strtoul( argv[i+1], &cpErr ,0);
245 HLTError("Cannot convert occupancy-limit specifier '%s'.", argv[i+1]);
252 // -- checking for rcu format
253 if ( !strcmp( argv[i], "oldrcuformat" ) ) {
254 fOldRCUFormat = strtoul( argv[i+1], &cpErr ,0);
256 HLTError("Cannot convert oldrcuformat specifier '%s'. Should be 0(off) or 1(on), must be integer", argv[i+1]);
263 // -- checking for rcu format
264 if ( !strcmp( argv[i], "sort-pads" ) ) {
265 fSortPads = strtoul( argv[i+1], &cpErr ,0);
267 HLTError("Cannot convert sort-pads specifier '%s'. Should be 0(off) or 1(on), must be integer", argv[i+1]);
274 Logging(kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
279 HLTDebug("using AliHLTTPCDigitReaderDecoder");
280 fDigitReader = new AliHLTTPCDigitReaderDecoder();
282 fHwAddressList.clear();
287 int AliHLTTPCZeroSuppressionComponent::DoDeinit()
289 // see header file for class documentation
293 Int_t AliHLTTPCZeroSuppressionComponent::DeInitializePadArray()
295 // see header file for class documentation
296 if(fVectorInitialized){
297 for(Int_t i=0;i<fNumberOfRows;i++){
298 for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
299 delete fRowPadVector[i][j];
300 fRowPadVector[i][j]=NULL;
302 fRowPadVector[i].clear();
304 fRowPadVector.clear();
309 void AliHLTTPCZeroSuppressionComponent::InitializePadArray(){
310 // see header file for class documentation
312 HLTFatal("Patch is not set");
316 fFirstRow = AliHLTTPCTransform::GetFirstRow(fCurrentPatch);
317 fLastRow = AliHLTTPCTransform::GetLastRow(fCurrentPatch);
319 fNumberOfRows=fLastRow-fFirstRow+1;
320 fNumberOfPadsInRow= new Int_t[fNumberOfRows];
322 memset( fNumberOfPadsInRow, 0, sizeof(Int_t)*(fNumberOfRows));
324 for(Int_t i=0;i<fNumberOfRows;i++){
325 fNumberOfPadsInRow[i]=AliHLTTPCTransform::GetNPads(i+fFirstRow);
326 AliHLTTPCPadVector tmpRow;
327 for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
328 AliHLTTPCPad *tmpPad = new AliHLTTPCPad();
330 tmpRow.push_back(tmpPad);
332 fRowPadVector.push_back(tmpRow);
334 fVectorInitialized=kTRUE;
338 int AliHLTTPCZeroSuppressionComponent::DoEvent( const AliHLTComponentEventData& evtData,
339 const AliHLTComponentBlockData* blocks,
340 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
341 AliHLTUInt32_t& size,
342 vector<AliHLTComponentBlockData>& outputBlocks )
344 // see header file for class documentation
346 // HLTInfo("Entered DoEvent in AliHLTTPCZeroSuppressionComponent");
348 // == init iter (pointer to datablock)
349 const AliHLTComponentBlockData* iter = NULL;
351 // HLTInfo("Number of blocks: ",evtData.fBlockCnt);
355 fHwAddressList.clear();
357 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
361 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
362 evtData.fEventID, evtData.fEventID,
363 DataType2Text( iter->fDataType).c_str(),
364 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
366 if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
368 HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
369 DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
370 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
373 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
374 iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ){
380 UInt_t slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
381 UInt_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
383 if(!fVectorInitialized){
385 InitializePadArray();
388 fDigitReader->InitBlock(iter->fPtr,iter->fSize,patch,slice);
390 //Here the reading of the data and the zerosuppression takes place
391 while(fDigitReader->NextChannel()){//Pad
392 Int_t row=fDigitReader->GetRow();
393 Int_t pad=fDigitReader->GetPad();
394 if(row==1000 || pad==1000){
397 if(row>=fNumberOfRows||row<0){
400 else if(pad>=fNumberOfPadsInRow[row]||pad<0){
404 AliHLTTPCPad *tmpPad = fRowPadVector[row][pad];
405 tmpPad->SetDataToDefault();
407 //reading data to pad
408 while(fDigitReader->NextBunch()){
409 const UInt_t *bunchData= fDigitReader->GetSignals();
410 Int_t time=fDigitReader->GetTime();
411 for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
412 if(bunchData[i]>0){// disregarding 0 data.
413 if(time+i>=fStartTimeBin && time+i<=fEndTimeBin){
414 tmpPad->SetDataSignal(time+i,bunchData[i]);
419 if(tmpPad->GetNAddedSignals()>=(UInt_t)fMinimumNumberOfSignals){
420 fHwAddressList.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr());
421 tmpPad->ZeroSuppress(fNRMSThreshold, fSignalThreshold, fMinimumNumberOfSignals, fStartTimeBin, fEndTimeBin, fLeftTimeBin, fRightTimeBin, fValueBelowAverage);
426 // HLTDebug("Max number of signals: %d",size/sizeof(Int_t));
429 //if(wasInput && fHwAddressList.size()>0){
431 AliHLTAltroEncoder altroEncoder;
432 altroEncoder.SetBuffer(outputPtr,size); //tests if one overwrite the buffer is done in the encoder
434 // TODO: read the CDH from the data input
435 AliRawDataHeader cdh;
436 altroEncoder.SetCDH((AliHLTUInt8_t*)&cdh,32);
437 for(Int_t row=0;row<fNumberOfRows;row++){
438 for(Int_t pad=0;pad<fNumberOfPadsInRow[row];pad++){
439 AliHLTTPCPad * zeroSuppressedPad= fRowPadVector[row][pad];
442 if(zeroSuppressedPad->GetNAddedSignals()>0){
443 while(zeroSuppressedPad->GetNextGoodSignal(currentTime, bunchSize)){
444 for(Int_t i=0;i<bunchSize;i++){
445 altroEncoder.AddSignal(zeroSuppressedPad->GetDataSignal(currentTime+i), currentTime+i);
448 altroEncoder.SetChannel(fDigitReader->GetAltroBlockHWaddr(row, pad));
453 // TODO: read the RCU trailer from the data input
454 AliHLTUInt8_t dummyTrailer=0;
455 altroEncoder.SetRCUTrailer(&dummyTrailer, sizeof(dummyTrailer));
456 int sizeOfData=altroEncoder.SetLength();
459 HLTError("data encoding failed");
462 if(sizeOfData>(int)size){
463 HLTWarning("Buffer too small too add the altrodata: %d of %d byte(s) already used", sizeOfData, size);
467 //Push back the zerosuppressed altro data to the output
468 AliHLTComponentBlockData bd;
471 bd.fSize = sizeOfData;
472 bd.fDataType = kAliHLTDataTypeDDLRaw;
473 bd.fSpecification = iter->fSpecification;
474 Logging( kHLTLogDebug, "HLT::TPCZeroSuppressionComponent::DoEvent", "Event received",
475 "Event 0x%08LX (%Lu) output data block %lu of %lu bytes at offset %lu",
476 evtData.fEventID, evtData.fEventID, ndx,size ,0);
477 outputBlocks.push_back( bd );
479 //Push back the list of hardware addresses to the output
480 AliHLTUInt32_t dataOffsetBeforeHW=sizeOfData;
481 AliHLTUInt32_t sizeOfHWArray=fHwAddressList.size()*sizeof(AliHLTUInt16_t);
483 if(dataOffsetBeforeHW+sizeOfHWArray>size){
484 HLTWarning("Buffer too small too add the active channels: %d of %d byte(s) already used", dataOffsetBeforeHW + sizeOfHWArray, size);
488 AliHLTUInt16_t*outputHWPtr=(AliHLTUInt16_t*)(outputPtr+dataOffsetBeforeHW);
489 outputHWPtr = &fHwAddressList[0];
490 AliHLTComponentBlockData bdHW;
491 FillBlockData( bdHW );
492 bdHW.fOffset = dataOffsetBeforeHW;
493 bdHW.fSize = sizeOfHWArray;
494 bdHW.fDataType = kAliHLTDataTypeHwAddr16;
495 bdHW.fSpecification = iter->fSpecification;
496 Logging( kHLTLogDebug, "HLT::TPCZeroSuppressionComponent::DoEvent", "Event received",
497 "Event 0x%08LX (%Lu) output data block %lu of %lu bytes at offset %lu",
498 evtData.fEventID, evtData.fEventID, ndx,size ,0);
499 outputBlocks.push_back( bdHW );
501 size = dataOffsetBeforeHW+sizeOfHWArray;