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 "AliHLTTPCDigitReader32Bit.h"
34 #include "AliHLTTPCClusterFinder.h"
35 #include "AliHLTTPCSpacePointData.h"
36 #include "AliHLTTPCClusterDataFormat.h"
37 #include "AliHLTTPCTransform.h"
38 #include "AliHLTTPCClusters.h"
39 #include "AliHLTTPCDefinitions.h"
40 #include "AliCDBEntry.h"
41 #include "AliCDBManager.h"
46 #include "TObjString.h"
47 #include "TObjArray.h"
48 #include "AliCDBEntry.h"
49 #include "AliCDBManager.h"
50 #include "AliCDBStorage.h"
54 /** ROOT macro for the implementation of ROOT specific class methods */
55 ClassImp(AliHLTTPCClusterFinderComponent)
57 AliHLTTPCClusterFinderComponent::AliHLTTPCClusterFinderComponent(int mode)
63 fClusterDeconv(false),
74 // see header file for class documentation
76 // refer to README to build package
78 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
79 if (fModeSwitch!=kClusterFinderPacked &&
80 fModeSwitch!=kClusterFinderUnpacked &&
81 fModeSwitch!=kClusterFinderDecoder &&
82 fModeSwitch!=kClusterFinder32Bit) {
83 HLTFatal("unknown digit reader type");
87 AliHLTTPCClusterFinderComponent::~AliHLTTPCClusterFinderComponent()
89 // see header file for class documentation
92 // Public functions to implement AliHLTComponent's interface.
93 // These functions are required for the registration process
95 const char* AliHLTTPCClusterFinderComponent::GetComponentID()
97 // see header file for class documentation
99 case kClusterFinderPacked:
100 return "TPCClusterFinderPacked";
102 case kClusterFinderUnpacked:
103 return "TPCClusterFinderUnpacked";
105 case kClusterFinderDecoder:
106 return "TPCClusterFinderDecoder";
108 case kClusterFinder32Bit:
109 return "TPCClusterFinder32Bit";
115 void AliHLTTPCClusterFinderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
117 // see header file for class documentation
120 case kClusterFinderPacked:
121 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
123 case kClusterFinderUnpacked:
124 list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );
126 case kClusterFinderDecoder:
127 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
129 case kClusterFinder32Bit:
130 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
135 AliHLTComponentDataType AliHLTTPCClusterFinderComponent::GetOutputDataType()
137 // see header file for class documentation
138 return kAliHLTMultipleDataType;
141 int AliHLTTPCClusterFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
144 // see header file for class documentation
146 tgtList.push_back(AliHLTTPCDefinitions::fgkClustersDataType);
147 tgtList.push_back(kAliHLTDataTypeHwAddr16);
148 return tgtList.size();
151 void AliHLTTPCClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
153 // see header file for class documentation
154 // XXX TODO: Find more realistic values.
157 case kClusterFinderPacked:
158 inputMultiplier = (6 * 0.4);
160 case kClusterFinderUnpacked:
161 inputMultiplier = 0.4;
163 case kClusterFinderDecoder:
164 inputMultiplier = (6 * 0.4);
166 case kClusterFinder32Bit:
167 inputMultiplier = (6 * 0.4);
172 AliHLTComponent* AliHLTTPCClusterFinderComponent::Spawn()
174 // see header file for class documentation
175 return new AliHLTTPCClusterFinderComponent(fModeSwitch);
178 int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
180 // see header file for class documentation
181 if ( fClusterFinder )
184 fClusterFinder = new AliHLTTPCClusterFinder();
187 TString configuration="";
189 for (int i=0; i<argc && iResult>=0; i++) {
191 if (!configuration.IsNull()) configuration+=" ";
192 configuration+=argument;
195 if (!configuration.IsNull()) {
196 iResult=Configure(configuration.Data());
198 iResult=Reconfigure(NULL, NULL);
201 //Checking for conflicting arguments
203 if(fDeconvPad==kTRUE || fDeconvTime==kTRUE){
204 HLTWarning("Conflicting arguments: argument 'pp-run' will be ignored.");
207 if(fClusterFinder->GetOccupancyLimit()!=1.0 && fUnsorted){
208 HLTWarning("Argument 'occupancy-limit' is deprecated when doing unsorted data reading.");
210 if(fGetActivePads==kTRUE && fUnsorted==kFALSE){
211 HLTWarning("Argument '-active-pads' only work with unsorted data reading. Active pads list will not be produced.");
216 if (fModeSwitch==kClusterFinderPacked) {
217 HLTDebug("using AliHLTTPCDigitReaderPacked");
218 fReader = new AliHLTTPCDigitReaderPacked();
219 if(fUnsorted==1){ fReader->SetUnsorted(kTRUE); }
220 fClusterFinder->SetReader(fReader);
222 else if(fModeSwitch==kClusterFinderUnpacked){
223 HLTDebug("using AliHLTTPCDigitReaderUnpacked");
224 fReader = new AliHLTTPCDigitReaderUnpacked();
225 if(fUnsorted==1){ fReader->SetUnsorted(kTRUE); }
226 fClusterFinder->SetReader(fReader);
228 else if(fModeSwitch==kClusterFinderDecoder){
229 HLTDebug("using AliHLTTPCDigitReaderDecoder");
230 fReader = new AliHLTTPCDigitReaderDecoder();
231 fClusterFinder->SetReader(fReader);
233 else if(fModeSwitch==kClusterFinder32Bit){
234 HLTDebug("using AliHLTTPCDigitReader32Bit");
235 fReader = new AliHLTTPCDigitReader32Bit();
236 fClusterFinder->SetReader(fReader);
237 fClusterFinder->Set32BitFormat(kTRUE);
240 HLTFatal("No mode set for clusterfindercomponent");
244 fClusterFinder->SetOccupancyLimit(1.0);
247 fClusterFinder->SetDeconv(fClusterDeconv);
248 fClusterFinder->SetDeconvPad(fDeconvPad);
249 fClusterFinder->SetDeconvTime(fDeconvPad);
250 fClusterFinder->SetXYError( fXYClusterError );
251 fClusterFinder->SetZError( fZClusterError );
252 if ( (fXYClusterError>0) && (fZClusterError>0) ){
253 fClusterFinder->SetCalcErr( false );
257 fClusterFinder->SetFirstTimeBin(fFirstTimeBin);
259 if(fLastTimeBin>0 && fLastTimeBin>fFirstTimeBin && fLastTimeBin<=AliHLTTPCTransform::GetNTimeBins()){
260 fClusterFinder->SetLastTimeBin(fLastTimeBin);
266 int AliHLTTPCClusterFinderComponent::DoDeinit()
268 // see header file for class documentation
270 if ( fClusterFinder )
271 delete fClusterFinder;
272 fClusterFinder = NULL;
281 int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponentEventData& evtData,
282 const AliHLTComponentBlockData* blocks,
283 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
284 AliHLTUInt32_t& size,
285 vector<AliHLTComponentBlockData>& outputBlocks )
287 // see header file for class documentation
290 HLTFatal("Digit reader not initialized, skipping HLT TPC cluster reconstruction.");
295 if(GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR )){
300 // == init iter (pointer to datablock)
301 const AliHLTComponentBlockData* iter = NULL;
304 // == OUTdatatype pointer
305 AliHLTTPCClusterData* outPtr;
307 AliHLTUInt8_t* outBPtr;
308 UInt_t offset, mysize, nSize, tSize = 0;
311 outPtr = (AliHLTTPCClusterData*)outBPtr;
314 unsigned long maxPoints, realPoints = 0;
316 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
323 if (fModeSwitch==0 || fModeSwitch==2 || fModeSwitch==3) {
324 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
325 evtData.fEventID, evtData.fEventID,
326 DataType2Text( iter->fDataType).c_str(),
327 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
329 if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
331 HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
332 DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
333 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
336 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
337 iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ) continue;
340 else if(fModeSwitch==1){
341 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
342 evtData.fEventID, evtData.fEventID,
343 DataType2Text( iter->fDataType).c_str(),
344 DataType2Text(AliHLTTPCDefinitions::fgkUnpackedRawDataType).c_str());
346 if ( iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
350 slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
351 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
354 fClusterFinder->SetUnsorted(fUnsorted);
355 fClusterFinder->SetPatch(patch);
358 outPtr = (AliHLTTPCClusterData*)outBPtr;
360 maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
362 fClusterFinder->InitSlice( slice, patch, maxPoints );
363 fClusterFinder->SetOutputArray( (AliHLTTPCSpacePointData*)outPtr->fSpacePoints );
367 fClusterFinder->SetDoPadSelection(kTRUE);
370 fClusterFinder->ReadDataUnsortedDeconvoluteTime(iter->fPtr, iter->fSize);
373 fClusterFinder->ReadDataUnsorted(iter->fPtr, iter->fSize);
376 fClusterFinder->FindClusters();
379 fClusterFinder->Read(iter->fPtr, iter->fSize );
380 fClusterFinder->ProcessDigits();
383 realPoints = fClusterFinder->GetNumberOfClusters();
385 outPtr->fSpacePointCnt = realPoints;
386 nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
387 mysize += nSize+sizeof(AliHLTTPCClusterData);
389 Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Spacepoints",
390 "Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
391 realPoints, slice, patch,AliHLTTPCTransform::GetFirstRow( patch ) , AliHLTTPCTransform::GetLastRow( patch ) );
392 AliHLTComponentBlockData bd;
396 bd.fSpecification = iter->fSpecification;
397 bd.fDataType = AliHLTTPCDefinitions::fgkClustersDataType;
398 outputBlocks.push_back( bd );
402 outPtr = (AliHLTTPCClusterData*)outBPtr;
407 Logging( kHLTLogFatal, "HLT::TPCClusterFinder::DoEvent", "Too much data",
408 "Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
413 if(fUnsorted && fGetActivePads){
414 Int_t maxNumberOfHW=(Int_t)((size-tSize)/sizeof(AliHLTUInt16_t)-1);
415 AliHLTUInt16_t* outputHWPtr= (AliHLTUInt16_t*)(outputPtr+tSize);
416 Int_t nHWAdd = fClusterFinder->FillHWAddressList(outputHWPtr, maxNumberOfHW);
418 AliHLTComponentBlockData bdHW;
419 FillBlockData( bdHW );
420 bdHW.fOffset = tSize ;
421 bdHW.fSize = nHWAdd*sizeof(AliHLTUInt16_t);
422 bdHW.fSpecification = iter->fSpecification;
423 bdHW.fDataType = kAliHLTDataTypeHwAddr16;
424 outputBlocks.push_back( bdHW );
426 tSize+=nHWAdd*sizeof(AliHLTUInt16_t);
430 Int_t maxNumberOfClusterMCInfo = (Int_t)((size-tSize)/sizeof(AliHLTTPCClusterFinder::ClusterMCInfo)-1);
431 AliHLTTPCClusterFinder::ClusterMCInfo* outputMCInfo= (AliHLTTPCClusterFinder::ClusterMCInfo*)(outputPtr+tSize);
432 Int_t nMCInfo = fClusterFinder->FillOutputMCInfo(outputMCInfo, maxNumberOfClusterMCInfo);
434 AliHLTComponentBlockData bdMCInfo;
435 FillBlockData( bdMCInfo );
436 bdMCInfo.fOffset = tSize ;
437 bdMCInfo.fSize = nMCInfo*sizeof(AliHLTTPCClusterFinder::ClusterMCInfo);
438 bdMCInfo.fSpecification = iter->fSpecification;
439 bdMCInfo.fDataType = AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo;
440 outputBlocks.push_back( bdMCInfo );
442 tSize+=nMCInfo*sizeof(AliHLTTPCClusterFinder::ClusterMCInfo);
454 int AliHLTTPCClusterFinderComponent::Configure(const char* arguments){
455 // see header file for class documentation
457 if (!arguments) return iResult;
459 TString allArgs=arguments;
463 TObjArray* pTokens=allArgs.Tokenize(" ");
466 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
467 argument=((TObjString*)pTokens->At(i))->GetString();
469 if (argument.IsNull()) continue;
471 // -- deconvolute-time option
472 if (argument.CompareTo("-deconvolute-time")==0){
473 HLTDebug("Switching on deconvolution in time direction.");
475 fClusterFinder->SetDeconvTime(fDeconvTime);
477 else if (argument.CompareTo("-deconvolute-pad")==0){
478 HLTDebug("Switching on deconvolution in pad direction.");
480 fClusterFinder->SetDeconvPad(fDeconvPad);
482 else if (argument.CompareTo("-timebins")==0 || argument.CompareTo("timebins" )==0){
483 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
484 AliHLTTPCTransform::SetNTimeBins(((TObjString*)pTokens->At(i))->GetString().Atoi());
485 fClusterFinder->UpdateLastTimeBin();
486 HLTInfo("number of timebins set to %d, zbin=%f", AliHLTTPCTransform::GetNTimeBins(), AliHLTTPCTransform::GetZWidth());
487 if(argument.CompareTo("timebins")==0){
488 HLTWarning("Argument 'timebins' is old, please switch to new argument naming convention (-timebins). The timebins argument will still work, but please change anyway.");
491 else if (argument.CompareTo("-first-timebin")==0){
492 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
493 fFirstTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
494 if(fFirstTimeBin>=0){
495 HLTDebug("fFirstTimeBin set to %d",fFirstTimeBin);
496 fClusterFinder->SetFirstTimeBin(fFirstTimeBin);
499 HLTError("-first-timebin specifier is negative: %d",fFirstTimeBin);
502 else if (argument.CompareTo("-last-timebin")==0){
503 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
504 fLastTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
505 if(fLastTimeBin<AliHLTTPCTransform::GetNTimeBins()){
506 HLTDebug("fLastTimeBin set to %d",fLastTimeBin);
509 HLTError("fLastTimeBins is too big: %d. Maximum: %d",fLastTimeBin,AliHLTTPCTransform::GetNTimeBins());
512 else if (argument.CompareTo("-sorted")==0) {
514 HLTDebug("Swithching unsorted off.");
515 fClusterFinder->SetUnsorted(0);
517 else if (argument.CompareTo("-do-mc")==0) {
519 fClusterFinder->SetDoMC(fDoMC);
520 HLTInfo("Setting fDoMC to true.");
522 else if (argument.CompareTo("-active-pads")==0 || argument.CompareTo("activepads")==0){
523 if(argument.CompareTo("activepads" )==0){
524 HLTWarning("Please change to new component argument naming scheme and use '-active-pads' instead of 'activepads'");
526 HLTDebug("Switching on ActivePads");
528 fClusterFinder->SetDoPadSelection(kTRUE);
530 else if (argument.CompareTo("-occupancy-limit")==0 || argument.CompareTo("occupancy-limit")==0){
531 if(argument.CompareTo("occupancy-limit" )==0){
532 HLTWarning("Please switch to new component argument naming convention, use '-occupancy-limit' instead of 'occupancy-limit'");
534 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
535 fClusterFinder->SetOccupancyLimit(((TObjString*)pTokens->At(i))->GetString().Atof());
536 HLTDebug("Occupancy limit set to occulimit %f", ((TObjString*)pTokens->At(i))->GetString().Atof());
538 else if (argument.CompareTo("rawreadermode")==0){
539 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
540 HLTWarning("Argument 'rawreadermode' is deprecated");
542 else if (argument.CompareTo("pp-run")==0){
543 HLTWarning("Argument 'pp-run' is obsolete, deconvolution is swiched off in both time and pad directions by default.");
544 fClusterDeconv = false;
546 else if (argument.CompareTo("adc-threshold" )==0){
547 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
548 HLTWarning("'adc-threshold' is no longer a valid argument, please use TPCZeroSuppression component if you want to zerosuppress data.");
550 else if (argument.CompareTo("oldrcuformat" )==0){
551 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
552 HLTWarning("Argument 'oldrcuformat' is deprecated.");
554 else if (argument.CompareTo("unsorted" )==0){
555 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
556 HLTDebug("Using unsorted reading.");
557 fClusterFinder->SetUnsorted(1);
559 else if (argument.CompareTo("nsigma-threshold")==0){
560 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
561 HLTWarning("Argument 'nsigma-threshold' argument is obsolete.");
564 HLTError("unknown argument %s", argument.Data());
572 HLTError("missing parameter for argument %s", argument.Data());
578 int AliHLTTPCClusterFinderComponent::Reconfigure(const char* cdbEntry, const char* chainId)
582 // see header file for class documentation
583 const char* path="HLT/ConfigTPC/ClusterFinderComponent";
584 if (cdbEntry) path=cdbEntry;
586 HLTInfo("reconfigure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
587 AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
589 TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
591 HLTInfo("received configuration object: %s", pString->GetString().Data());
592 iResult = Configure(pString->GetString().Data());
594 HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
597 HLTError("can not fetch object \"%s\" from CDB", path);