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: Timm Steinbeck, Matthias Richter *
8 //* Developers: Kenneth Aamodt <kenneth.aamodt@student.uib.no> *
9 //* for The ALICE HLT Project. *
11 //* Permission to use, copy, modify and distribute this software and its *
12 //* documentation strictly for non-commercial purposes is hereby granted *
13 //* without fee, provided that the above copyright notice appears in all *
14 //* copies and that both the copyright notice and this permission notice *
15 //* appear in the supporting documentation. The authors make no claims *
16 //* about the suitability of this software for any purpose. It is *
17 //* provided "as is" without express or implied warranty. *
18 //**************************************************************************
20 /** @file AliHLTTPCClusterFinderComponent.cxx
21 @author Kenneth Aamodt <kenneth.aamodt@student.uib.no>
23 @brief The TPC cluster finder processing component
29 #include "AliHLTTPCClusterFinderComponent.h"
30 #include "AliHLTTPCDigitReaderPacked.h"
31 #include "AliHLTTPCDigitReaderUnpacked.h"
32 #include "AliHLTTPCDigitReaderDecoder.h"
33 #include "AliHLTTPCClusterFinder.h"
34 #include "AliHLTTPCSpacePointData.h"
35 #include "AliHLTTPCClusterDataFormat.h"
36 #include "AliHLTTPCTransform.h"
37 #include "AliHLTTPCClusters.h"
38 #include "AliHLTTPCDefinitions.h"
39 #include "AliCDBEntry.h"
40 #include "AliCDBManager.h"
45 #include "TObjString.h"
48 /** ROOT macro for the implementation of ROOT specific class methods */
49 ClassImp(AliHLTTPCClusterFinderComponent)
51 AliHLTTPCClusterFinderComponent::AliHLTTPCClusterFinderComponent(int mode)
57 fClusterDeconv(false),
67 // see header file for class documentation
69 // refer to README to build package
71 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
74 AliHLTTPCClusterFinderComponent::~AliHLTTPCClusterFinderComponent()
76 // see header file for class documentation
79 // Public functions to implement AliHLTComponent's interface.
80 // These functions are required for the registration process
82 const char* AliHLTTPCClusterFinderComponent::GetComponentID()
84 // see header file for class documentation
86 case kClusterFinderPacked:
87 return "TPCClusterFinderPacked";
89 case kClusterFinderUnpacked:
90 return "TPCClusterFinderUnpacked";
92 case kClusterFinderDecoder:
93 return "TPCClusterFinderDecoder";
96 HLTFatal("unknown digit reader type");
100 void AliHLTTPCClusterFinderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
102 // see header file for class documentation
105 case kClusterFinderPacked:
106 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
108 case kClusterFinderUnpacked:
109 list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );
111 case kClusterFinderDecoder:
112 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
117 AliHLTComponentDataType AliHLTTPCClusterFinderComponent::GetOutputDataType()
119 // see header file for class documentation
120 return kAliHLTMultipleDataType;
123 int AliHLTTPCClusterFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
126 // see header file for class documentation
128 tgtList.push_back(AliHLTTPCDefinitions::fgkClustersDataType);
129 tgtList.push_back(kAliHLTDataTypeHwAddr16);
130 return tgtList.size();
133 void AliHLTTPCClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
135 // see header file for class documentation
136 // XXX TODO: Find more realistic values.
140 inputMultiplier = (6 * 0.4);
143 inputMultiplier = 0.4;
146 inputMultiplier = (6 * 0.4);
151 AliHLTComponent* AliHLTTPCClusterFinderComponent::Spawn()
153 // see header file for class documentation
154 return new AliHLTTPCClusterFinderComponent(fModeSwitch);
157 int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
159 // see header file for class documentation
160 if ( fClusterFinder )
163 fClusterFinder = new AliHLTTPCClusterFinder();
165 // Int_t sigthresh = -1;
166 // Double_t sigmathresh= -1;
167 Float_t occulimit = 1.0;
168 // Int_t oldRCUFormat=0;
169 // Data Format version numbers:
170 // 0: RCU Data format as delivered during TPC commissioning, pads/padrows are sorted, RCU trailer is one 32 bit word.
171 // 1: As 0, but pads/padrows are delivered "as is", without sorting
172 // 2: As 0, but RCU trailer is 3 32 bit words.
173 // 3: As 1, but RCU trailer is 3 32 bit words.
174 // -1: use offline raw reader
183 // -- deconvolute-time option
184 if ( !strcmp( argv[i], "-deconvolute-time" ) ) {
190 // -- deconvolute-pad option
191 if ( !strcmp( argv[i], "-deconvolute-pad" ) ) {
197 // -- number of timebins (default 1024)
198 if (!strcmp( argv[i], "-timebins") || !strcmp( argv[i], "timebins" )){
199 TString parameter(argv[i+1]);
200 parameter.Remove(TString::kLeading, ' '); // remove all blanks
201 if (parameter.IsDigit()) {
202 AliHLTTPCTransform::SetNTimeBins(parameter.Atoi());
203 HLTInfo("number of timebins set to %d, zbin=%f", AliHLTTPCTransform::GetNTimeBins(), AliHLTTPCTransform::GetZWidth());
204 fClusterFinder->UpdateLastTimeBin();
206 HLTError("Cannot timebin specifier '%s'.", argv[i+1]);
209 if(!strcmp( argv[i], "timebins")){
210 HLTWarning("Argument 'timebins' is old, please switch to new argument naming convention (-timebins). The timebins argument will still work, but please change anyway.");
216 // -first-timebin (default 0)
217 if ( !strcmp( argv[i], "-first-timebin" ) ) {
218 TString parameter(argv[i+1]);
219 parameter.Remove(TString::kLeading, ' '); // remove all blanks
220 if (parameter.IsDigit()){
221 fFirstTimeBin=parameter.Atoi();
222 HLTDebug("fFirstTimeBin set to %d",fFirstTimeBin);
225 HLTError("Cannot -first-timebin specifier '%s'. Not a number.", argv[i+1]);
232 // -last-timebin (default 1024)
233 if ( !strcmp( argv[i], "-last-timebin" ) ) {
234 TString parameter(argv[i+1]);
235 parameter.Remove(TString::kLeading, ' '); // remove all blanks
236 if (parameter.IsDigit()){
237 fLastTimeBin=parameter.Atoi();
238 HLTDebug("fLastTimeBin set to %d",fLastTimeBin);
241 HLTError("Cannot -last-timebin specifier '%s'. Not a number.", argv[i+1]);
248 // -- unsorted option
249 if ( !strcmp( argv[i], "-sorted" ) ) {
256 // -- checking for active pads, used in 2007 December run
257 if ( !strcmp( argv[i], "-active-pads" ) || !strcmp( argv[i], "activepads" ) ) {
258 if(!strcmp( argv[i], "activepads" )){
259 HLTWarning("Please change to new component argument naming scheme and use '-active-pads' instead of 'active-pads'");
261 fGetActivePads = strtoul( argv[i+1], &cpErr ,0);
263 HLTError("Cannot convert activepads specifier '%s'. Should be 0(off) or 1(on), must be integer", argv[i+1]);
270 // -- pad occupancy limit
271 if ( !strcmp( argv[i], "-occupancy-limit" ) || !strcmp( argv[i], "occupancy-limit" ) ) {
272 if(!strcmp( argv[i], "occupancy-limit" )){
273 HLTWarning("Please switch to new component argument naming convention, use '-occupancy-limit' instead of 'occupancy-limit'");
275 occulimit = strtod( argv[i+1], &cpErr);
277 HLTError("Cannot convert occupancy specifier '%s'.", argv[i+1]);
280 if(fModeSwitch!=kClusterFinderPacked){
281 HLTWarning("Argument '-occupancy-limit' is only used with -sorted set and with the TPCClusterFinderPacked , argument is deprecated");
288 // -- raw reader mode option
289 if ( !strcmp( argv[i], "rawreadermode" ) ) {
291 Logging( kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Missing rawreadermode", "Raw Reader Mode not specified. rawreadermode is no longer a valid argument and will be deprecated even if rawreadermode is specified." );
295 HLTWarning("Argument 'rawreadermode' is deprecated");
303 if ( !strcmp( argv[i], "pp-run") ) {
304 HLTWarning("Argument 'pp-run' is obsolete, deconvolution is swiched off in both time and pad directions by default.");
305 fClusterDeconv = false;
310 // -- zero suppression threshold
311 if ( !strcmp( argv[i], "adc-threshold" ) ) {
312 strtoul( argv[i+1], &cpErr ,0);
314 HLTError("Cannot convert threshold specifier '%s'.", argv[i+1]);
317 HLTWarning("'adc-threshold' is no longer a valid argument, please use TPCZeroSuppression component if you want to zerosuppress data.");
323 // -- checking for rcu format
324 if ( !strcmp( argv[i], "oldrcuformat" ) ) {
325 strtoul( argv[i+1], &cpErr ,0);
327 HLTError("Cannot convert oldrcuformat specifier '%s'. Should be 0(off) or 1(on), must be integer", argv[i+1]);
330 HLTWarning("Argument 'oldrcuformat' is deprecated.");
335 // -- checking for unsorted clusterfinding (default 1)
336 if ( !strcmp( argv[i], "unsorted" ) ) {
337 fUnsorted = strtoul( argv[i+1], &cpErr ,0);
339 HLTError("Cannot convert unsorted specifier '%s'. Should be 0(off) or 1(on), must be integer", argv[i+1]);
342 HLTWarning("Argument 'unsorted' is old and does not follow the new argument naming convention. A change has been made, and the clusterfinder will read the data unsorted by default. For sorted reading, please use '-sorted' as argument. (unsorted 0 will do the same job, but please change anyway.)");
347 // -- checking for nsigma-threshold, used in 2007 December run in ZeroSuppression
348 if ( !strcmp( argv[i], "nsigma-threshold" ) ) {
349 strtoul( argv[i+1], &cpErr ,0);
351 HLTError("Cannot convert nsigma-threshold specifier '%s'. Must be integer", argv[i+1]);
355 HLTWarning("Argument 'nsigma-threshold' argument is obsolete.");
359 Logging(kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
364 //Checking for conflicting arguments
366 if(fDeconvPad==kTRUE || fDeconvTime==kTRUE){
367 HLTWarning("Conflicting arguments: argument 'pp-run' will be ignored.");
370 if(occulimit!=1.0 && fUnsorted){
371 HLTWarning("Argument 'occupancy-limit' is deprecated when doing unsorted data reading.");
373 if(fGetActivePads==kTRUE && fUnsorted==kFALSE){
374 HLTWarning("Argument '-active-pads' only work with unsorted data reading. Active pads list will not be produced.");
379 if (fModeSwitch==kClusterFinderPacked) {
380 HLTDebug("using AliHLTTPCDigitReaderPacked");
381 fReader = new AliHLTTPCDigitReaderPacked();
384 fReader->SetOldRCUFormat(kTRUE);
386 else if(oldRCUFormat!=0){
387 HLTWarning("Wrong oldrcuformat specifier %d; oldrcuformat set to default(kFALSE)",oldRCUFormat);
391 fReader->SetUnsorted(kTRUE);
393 fClusterFinder->SetReader(fReader);
395 else if(fModeSwitch==kClusterFinderUnpacked){
396 HLTDebug("using AliHLTTPCDigitReaderUnpacked");
397 fReader = new AliHLTTPCDigitReaderUnpacked();
398 fClusterFinder->SetReader(fReader);
400 else if(fModeSwitch==kClusterFinderDecoder){
401 HLTDebug("using AliHLTTPCDigitReaderDecoder");
402 fReader = new AliHLTTPCDigitReaderDecoder();
403 fClusterFinder->SetReader(fReader);
406 HLTFatal("No mode set for clusterfindercomponent");
408 // if pp-run use occupancy limit else set to 1. ==> use all
409 if ( !fClusterDeconv )
410 fClusterFinder->SetOccupancyLimit(occulimit);
412 fClusterFinder->SetOccupancyLimit(1.0);
415 fClusterFinder->SetDeconv(fClusterDeconv);
416 fClusterFinder->SetDeconvPad(fDeconvPad);
417 fClusterFinder->SetDeconvTime(fDeconvPad);
418 fClusterFinder->SetXYError( fXYClusterError );
419 fClusterFinder->SetZError( fZClusterError );
420 if ( (fXYClusterError>0) && (fZClusterError>0) ){
421 fClusterFinder->SetCalcErr( false );
423 // fClusterFinder->SetSignalThreshold(sigthresh);
424 // fClusterFinder->SetNSigmaThreshold(sigmathresh);
427 fClusterFinder->SetFirstTimeBin(fFirstTimeBin);
429 if(fLastTimeBin>0 && fLastTimeBin>fFirstTimeBin && fLastTimeBin<=AliHLTTPCTransform::GetNTimeBins()){
430 fClusterFinder->SetLastTimeBin(fLastTimeBin);
436 int AliHLTTPCClusterFinderComponent::DoDeinit()
438 // see header file for class documentation
440 if ( fClusterFinder )
441 delete fClusterFinder;
442 fClusterFinder = NULL;
451 int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponentEventData& evtData,
452 const AliHLTComponentBlockData* blocks,
453 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
454 AliHLTUInt32_t& size,
455 vector<AliHLTComponentBlockData>& outputBlocks )
457 // see header file for class documentation
459 if(GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR )){
464 // == init iter (pointer to datablock)
465 const AliHLTComponentBlockData* iter = NULL;
468 // == OUTdatatype pointer
469 AliHLTTPCClusterData* outPtr;
471 AliHLTUInt8_t* outBPtr;
472 UInt_t offset, mysize, nSize, tSize = 0;
475 outPtr = (AliHLTTPCClusterData*)outBPtr;
477 Int_t slice, patch, row[2];
478 unsigned long maxPoints, realPoints = 0;
480 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
487 if (fModeSwitch==0 || fModeSwitch==2) {
488 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
489 evtData.fEventID, evtData.fEventID,
490 DataType2Text( iter->fDataType).c_str(),
491 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
493 if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
495 HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
496 DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
497 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
500 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
501 iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ) continue;
504 else if(fModeSwitch==1){
505 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
506 evtData.fEventID, evtData.fEventID,
507 DataType2Text( iter->fDataType).c_str(),
508 DataType2Text(AliHLTTPCDefinitions::fgkUnpackedRawDataType).c_str());
510 if ( iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
514 slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
515 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
516 row[0] = AliHLTTPCTransform::GetFirstRow( patch );
517 row[1] = AliHLTTPCTransform::GetLastRow( patch );
521 fClusterFinder->SetUnsorted(fUnsorted);
522 fClusterFinder->SetPatch(patch);
525 outPtr = (AliHLTTPCClusterData*)outBPtr;
527 maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
529 fClusterFinder->InitSlice( slice, patch, row[0], row[1], maxPoints );
530 fClusterFinder->SetOutputArray( (AliHLTTPCSpacePointData*)outPtr->fSpacePoints );
534 fClusterFinder->SetDoPadSelection(kTRUE);
538 fClusterFinder->ReadDataUnsortedDeconvoluteTime(iter->fPtr, iter->fSize);
541 fClusterFinder->ReadDataUnsorted(iter->fPtr, iter->fSize);
544 fClusterFinder->FindClusters();
547 fClusterFinder->Read(iter->fPtr, iter->fSize );
548 fClusterFinder->ProcessDigits();
550 realPoints = fClusterFinder->GetNumberOfClusters();
552 outPtr->fSpacePointCnt = realPoints;
553 nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
554 mysize += nSize+sizeof(AliHLTTPCClusterData);
556 Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Spacepoints",
557 "Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
558 realPoints, slice, patch, row[0], row[1] );
559 AliHLTComponentBlockData bd;
563 bd.fSpecification = iter->fSpecification;
564 bd.fDataType = AliHLTTPCDefinitions::fgkClustersDataType;
565 //AliHLTSubEventDescriptor::FillBlockAttributes( bd.fAttributes );
566 outputBlocks.push_back( bd );
570 outPtr = (AliHLTTPCClusterData*)outBPtr;
575 Logging( kHLTLogFatal, "HLT::TPCClusterFinder::DoEvent", "Too much data",
576 "Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
581 if(fUnsorted && fGetActivePads){
582 Int_t maxNumberOfHW=(Int_t)((size-tSize)/sizeof(AliHLTUInt16_t)-1);
583 AliHLTUInt16_t* outputHWPtr= (AliHLTUInt16_t*)(outputPtr+tSize);
584 Int_t nHWAdd = fClusterFinder->FillHWAddressList(outputHWPtr, maxNumberOfHW);
586 //cout<<"Number of hardwareaddresses: "<<nHWAdd<<endl;
587 for(AliHLTUInt16_t test=0;test<nHWAdd;test++){
588 //cout<<"The HW address is: "<<(AliHLTUInt16_t)outputHWPtr[test]<<endl;
590 AliHLTComponentBlockData bdHW;
591 FillBlockData( bdHW );
592 bdHW.fOffset = tSize ;
593 bdHW.fSize = nHWAdd*sizeof(AliHLTUInt16_t);
594 bdHW.fSpecification = iter->fSpecification;
595 bdHW.fDataType = kAliHLTDataTypeHwAddr16;
596 outputBlocks.push_back( bdHW );
598 tSize+=nHWAdd*sizeof(AliHLTUInt16_t);
607 int AliHLTTPCClusterFinderComponent::Reconfigure(const char* cdbEntry, const char* chainId)
609 // see header file for class documentation
610 const char* path="HLT/ConfigTPC";
611 if (cdbEntry) path=cdbEntry;
613 HLTInfo("reconfigure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
614 AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
616 TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
618 HLTInfo("received configuration object: %s", pString->GetString().Data());
620 HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
623 HLTError("can not fetch object \"%s\" from CDB", path);