1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * ALICE Experiment at CERN, All rights reserved. *
5 * Primary Authors: Kenneth Aamodt <Kenneth.Aamodt@student.uib.no> *
6 * for The ALICE HLT Project. *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
17 /** @file AliHLTTPCZeroSuppressionComponent.cxx
18 @author Kenneth Aamodt
20 @brief The TPC ZeroSuppression component
23 // see header file for class documentation //
25 // refer to README to build package //
27 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt //
32 #include "AliHLTTPCZeroSuppressionComponent.h"
33 #include "AliHLTTPCDigitReaderDecoder.h"
34 #include "AliHLTTPCTransform.h"
35 #include "AliHLTTPCDefinitions.h"
36 #include "AliHLTTPCDigitData.h"
41 #include "AliHLTAltroEncoder.h"
42 #include "AliRawDataHeader.h"
44 /** ROOT macro for the implementation of ROOT specific class methods */
45 ClassImp(AliHLTTPCZeroSuppressionComponent)
47 AliHLTTPCZeroSuppressionComponent::AliHLTTPCZeroSuppressionComponent()
51 fNumberOfPadsInRow(NULL),
57 fEndTimeBin(AliHLTTPCTransform::GetNTimeBins()),
61 fMinimumNumberOfSignals(AliHLTTPCTransform::GetNTimeBins()/2),
64 fVectorInitialized(kFALSE),
65 fValueBelowAverage(5),
68 fGetActivePads(kFALSE),
71 // see header file for class documentation
73 // refer to README to build package
75 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
78 AliHLTTPCZeroSuppressionComponent::~AliHLTTPCZeroSuppressionComponent()
80 // see header file for class documentation
81 if(fVectorInitialized){
82 DeInitializePadArray();
84 if(fNumberOfPadsInRow){
85 delete [] fNumberOfPadsInRow;
86 fNumberOfPadsInRow=NULL;
94 // Public functions to implement AliHLTComponent's interface.
95 // These functions are required for the registration process
97 const char* AliHLTTPCZeroSuppressionComponent::GetComponentID()
99 // see header file for class documentation
100 return "TPCZeroSuppression";
103 void AliHLTTPCZeroSuppressionComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
105 // see header file for class documentation
107 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
110 AliHLTComponentDataType AliHLTTPCZeroSuppressionComponent::GetOutputDataType()
112 // see header file for class documentation
113 return kAliHLTMultipleDataType;
114 //return kAliHLTDataTypeDDLRaw;
115 // return AliHLTTPCDefinitions::fgkUnpackedRawDataType;
118 int AliHLTTPCZeroSuppressionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
120 // see header file for class documentation
122 tgtList.push_back(kAliHLTDataTypeDDLRaw);
123 tgtList.push_back(kAliHLTDataTypeHwAddr16);
124 return tgtList.size();
127 void AliHLTTPCZeroSuppressionComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
129 // see header file for class documentation
134 AliHLTComponent* AliHLTTPCZeroSuppressionComponent::Spawn()
136 // see header file for class documentation
137 return new AliHLTTPCZeroSuppressionComponent();
140 int AliHLTTPCZeroSuppressionComponent::DoInit( int argc, const char** argv )
142 // see header file for class documentation
149 // -- zero suppression threshold
150 if ( !strcmp( argv[i], "signal-threshold" ) ) {
151 fSignalThreshold = strtoul( argv[i+1], &cpErr ,0);
153 HLTError("Cannot convert signal-threshold specifier '%s'.", argv[i+1]);
160 // -- checking for nsigma-threshold, used in 2007 December run in ZeroSuppression
161 if ( !strcmp( argv[i], "rms-threshold" ) ) {
162 fNRMSThreshold = strtoul( argv[i+1], &cpErr ,0);
164 HLTError("Cannot convert rms-threshold specifier '%s'. Must be integer", argv[i+1]);
171 // -- number of timebins
172 if ( !strcmp( argv[i], "ntimebins" ) ) {
173 fNTimeBins = strtoul( argv[i+1], &cpErr ,0);
175 HLTError("Cannot convert ntimebins specifier '%s'.", argv[i+1]);
183 if ( !strcmp( argv[i], "start-timebin" ) ) {
184 fStartTimeBin = strtoul( argv[i+1], &cpErr ,0);
186 HLTError("Cannot convert start-timebin specifier '%s'.", argv[i+1]);
194 if ( !strcmp( argv[i], "end-timebin" ) ) {
195 if(strtoul( argv[i+1], &cpErr ,0)<=(UInt_t)AliHLTTPCTransform::GetNTimeBins()){
196 fEndTimeBin = strtoul( argv[i+1], &cpErr ,0);
199 HLTError("Cannot convert end-timebin specifier '%s'.", argv[i+1]);
206 // -- timebins to keep left of signal
207 if ( !strcmp( argv[i], "timebin-left" ) ) {
208 fLeftTimeBin = strtoul( argv[i+1], &cpErr ,0);
210 HLTError("Cannot convert timebin-left specifier '%s'.", argv[i+1]);
217 // -- timebin to keep right of signal
218 if ( !strcmp( argv[i], "timebin-right" ) ) {
219 fRightTimeBin = strtoul( argv[i+1], &cpErr ,0);
221 HLTError("Cannot convert timebin-right specifier '%s'.", argv[i+1]);
228 // -- value below average to subtract
229 if ( !strcmp( argv[i], "value-below-average" ) ) {
230 fValueBelowAverage = strtoul( argv[i+1], &cpErr ,0);
232 HLTError("Cannot convert value-below-average specifier '%s'.", argv[i+1]);
239 // -- pad occupancy limit
240 if ( !strcmp( argv[i], "occupancy-limit" ) ) {
241 fMinimumNumberOfSignals = strtoul( argv[i+1], &cpErr ,0);
243 HLTError("Cannot convert occupancy-limit specifier '%s'.", argv[i+1]);
250 // -- checking for rcu format
251 if ( !strcmp( argv[i], "oldrcuformat" ) ) {
252 fOldRCUFormat = strtoul( argv[i+1], &cpErr ,0);
254 HLTError("Cannot convert oldrcuformat specifier '%s'. Should be 0(off) or 1(on), must be integer", argv[i+1]);
261 // -- checking for rcu format
262 if ( !strcmp( argv[i], "sort-pads" ) ) {
263 fSortPads = strtoul( argv[i+1], &cpErr ,0);
265 HLTError("Cannot convert sort-pads specifier '%s'. Should be 0(off) or 1(on), must be integer", argv[i+1]);
272 Logging(kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
277 HLTDebug("using AliHLTTPCDigitReaderDecoder");
278 fDigitReader = new AliHLTTPCDigitReaderDecoder();
280 fHwAddressList.clear();
285 int AliHLTTPCZeroSuppressionComponent::DoDeinit()
287 // see header file for class documentation
291 Int_t AliHLTTPCZeroSuppressionComponent::DeInitializePadArray()
293 // see header file for class documentation
294 if(fVectorInitialized){
295 for(Int_t i=0;i<fNumberOfRows;i++){
296 for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
297 delete fRowPadVector[i][j];
298 fRowPadVector[i][j]=NULL;
300 fRowPadVector[i].clear();
302 fRowPadVector.clear();
307 void AliHLTTPCZeroSuppressionComponent::InitializePadArray(){
308 // see header file for class documentation
310 HLTFatal("Patch is not set");
314 fFirstRow = AliHLTTPCTransform::GetFirstRow(fCurrentPatch);
315 fLastRow = AliHLTTPCTransform::GetLastRow(fCurrentPatch);
317 fNumberOfRows=fLastRow-fFirstRow+1;
318 fNumberOfPadsInRow= new Int_t[fNumberOfRows];
320 memset( fNumberOfPadsInRow, 0, sizeof(Int_t)*(fNumberOfRows));
322 for(Int_t i=0;i<fNumberOfRows;i++){
323 fNumberOfPadsInRow[i]=AliHLTTPCTransform::GetNPads(i+fFirstRow);
324 AliHLTTPCPadVector tmpRow;
325 for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
326 AliHLTTPCPad *tmpPad = new AliHLTTPCPad();
328 tmpRow.push_back(tmpPad);
330 fRowPadVector.push_back(tmpRow);
332 fVectorInitialized=kTRUE;
336 int AliHLTTPCZeroSuppressionComponent::DoEvent( const AliHLTComponentEventData& evtData,
337 const AliHLTComponentBlockData* blocks,
338 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
339 AliHLTUInt32_t& size,
340 vector<AliHLTComponentBlockData>& outputBlocks )
342 // see header file for class documentation
344 // HLTInfo("Entered DoEvent in AliHLTTPCZeroSuppressionComponent");
346 // == init iter (pointer to datablock)
347 const AliHLTComponentBlockData* iter = NULL;
349 // HLTInfo("Number of blocks: ",evtData.fBlockCnt);
353 fHwAddressList.clear();
355 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
359 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
360 evtData.fEventID, evtData.fEventID,
361 DataType2Text( iter->fDataType).c_str(),
362 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
364 if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
366 HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
367 DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
368 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
371 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
372 iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ){
378 UInt_t slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
379 UInt_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
381 if(!fVectorInitialized){
383 InitializePadArray();
386 fDigitReader->InitBlock(iter->fPtr,iter->fSize,patch,slice);
388 //Here the reading of the data and the zerosuppression takes place
389 while(fDigitReader->NextChannel()){//Pad
390 Int_t row=fDigitReader->GetRow();
391 Int_t pad=fDigitReader->GetPad();
392 if(row==1000 || pad==1000){
395 if(row>=fNumberOfRows||row<0){
398 else if(pad>=fNumberOfPadsInRow[row]||pad<0){
402 AliHLTTPCPad *tmpPad = fRowPadVector[row][pad];
403 tmpPad->SetDataToDefault();
405 //reading data to pad
406 while(fDigitReader->NextBunch()){
407 const UInt_t *bunchData= fDigitReader->GetSignals();
408 Int_t time=fDigitReader->GetTime();
409 for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
410 if(bunchData[i]>0){// disregarding 0 data.
411 if(time+i>=fStartTimeBin && time+i<=fEndTimeBin){
412 tmpPad->SetDataSignal(time+i,bunchData[i]);
417 if(tmpPad->GetNAddedSignals()>=(UInt_t)fMinimumNumberOfSignals){
418 fHwAddressList.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr());
419 tmpPad->ZeroSuppress(fNRMSThreshold, fSignalThreshold, fMinimumNumberOfSignals, fStartTimeBin, fEndTimeBin, fLeftTimeBin, fRightTimeBin, fValueBelowAverage);
424 // HLTDebug("Max number of signals: %d",size/sizeof(Int_t));
427 //if(wasInput && fHwAddressList.size()>0){
429 AliHLTAltroEncoder altroEncoder;
430 altroEncoder.SetBuffer(outputPtr,size); //tests if one overwrite the buffer is done in the encoder
432 // TODO: read the CDH from the data input
433 AliRawDataHeader cdh;
434 altroEncoder.SetCDH((AliHLTUInt8_t*)&cdh,32);
435 for(Int_t row=0;row<fNumberOfRows;row++){
436 for(Int_t pad=0;pad<fNumberOfPadsInRow[row];pad++){
437 AliHLTTPCPad * zeroSuppressedPad= fRowPadVector[row][pad];
440 if(zeroSuppressedPad->GetNAddedSignals()>0){
441 while(zeroSuppressedPad->GetNextGoodSignal(currentTime, bunchSize,0)){
442 for(Int_t i=0;i<bunchSize;i++){
443 altroEncoder.AddSignal(zeroSuppressedPad->GetDataSignal(currentTime+i), currentTime+i);
446 altroEncoder.SetChannel(fDigitReader->GetAltroBlockHWaddr(row, pad));
451 // TODO: read the RCU trailer from the data input
452 AliHLTUInt8_t dummyTrailer=0;
453 altroEncoder.SetRCUTrailer(&dummyTrailer, sizeof(dummyTrailer));
454 int sizeOfData=altroEncoder.SetLength();
457 HLTError("data encoding failed");
460 if(sizeOfData>(int)size){
461 HLTWarning("Buffer too small too add the altrodata: %d of %d byte(s) already used", sizeOfData, size);
465 //Push back the zerosuppressed altro data to the output
466 AliHLTComponentBlockData bd;
469 bd.fSize = sizeOfData;
470 bd.fDataType = kAliHLTDataTypeDDLRaw;
471 bd.fSpecification = iter->fSpecification;
472 Logging( kHLTLogDebug, "HLT::TPCZeroSuppressionComponent::DoEvent", "Event received",
473 "Event 0x%08LX (%Lu) output data block %lu of %lu bytes at offset %lu",
474 evtData.fEventID, evtData.fEventID, ndx,size ,0);
475 outputBlocks.push_back( bd );
477 //Push back the list of hardware addresses to the output
478 AliHLTUInt32_t dataOffsetBeforeHW=sizeOfData;
479 AliHLTUInt32_t sizeOfHWArray=fHwAddressList.size()*sizeof(AliHLTUInt16_t);
481 if(dataOffsetBeforeHW+sizeOfHWArray>size){
482 HLTWarning("Buffer too small too add the active channels: %d of %d byte(s) already used", dataOffsetBeforeHW + sizeOfHWArray, size);
486 AliHLTUInt16_t*outputHWPtr=(AliHLTUInt16_t*)(outputPtr+dataOffsetBeforeHW);
487 outputHWPtr = &fHwAddressList[0];
488 AliHLTComponentBlockData bdHW;
489 FillBlockData( bdHW );
490 bdHW.fOffset = dataOffsetBeforeHW;
491 bdHW.fSize = sizeOfHWArray;
492 bdHW.fDataType = kAliHLTDataTypeHwAddr16;
493 bdHW.fSpecification = iter->fSpecification;
494 Logging( kHLTLogDebug, "HLT::TPCZeroSuppressionComponent::DoEvent", "Event received",
495 "Event 0x%08LX (%Lu) output data block %lu of %lu bytes at offset %lu",
496 evtData.fEventID, evtData.fEventID, ndx,size ,0);
497 outputBlocks.push_back( bdHW );
499 size = dataOffsetBeforeHW+sizeOfHWArray;