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"
46 #include "TObjArray.h"
47 #include "AliCDBEntry.h"
48 #include "AliCDBManager.h"
49 #include "AliCDBStorage.h"
53 /** ROOT macro for the implementation of ROOT specific class methods */
54 ClassImp(AliHLTTPCClusterFinderComponent)
56 AliHLTTPCClusterFinderComponent::AliHLTTPCClusterFinderComponent(int mode)
62 fClusterDeconv(false),
72 // see header file for class documentation
74 // refer to README to build package
76 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
77 if (fModeSwitch!=kClusterFinderPacked &&
78 fModeSwitch!=kClusterFinderUnpacked &&
79 fModeSwitch!=kClusterFinderDecoder) {
80 HLTFatal("unknown digit reader type");
84 AliHLTTPCClusterFinderComponent::~AliHLTTPCClusterFinderComponent()
86 // see header file for class documentation
89 // Public functions to implement AliHLTComponent's interface.
90 // These functions are required for the registration process
92 const char* AliHLTTPCClusterFinderComponent::GetComponentID()
94 // see header file for class documentation
96 case kClusterFinderPacked:
97 return "TPCClusterFinderPacked";
99 case kClusterFinderUnpacked:
100 return "TPCClusterFinderUnpacked";
102 case kClusterFinderDecoder:
103 return "TPCClusterFinderDecoder";
109 void AliHLTTPCClusterFinderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
111 // see header file for class documentation
114 case kClusterFinderPacked:
115 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
117 case kClusterFinderUnpacked:
118 list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );
120 case kClusterFinderDecoder:
121 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
126 AliHLTComponentDataType AliHLTTPCClusterFinderComponent::GetOutputDataType()
128 // see header file for class documentation
129 return kAliHLTMultipleDataType;
132 int AliHLTTPCClusterFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
135 // see header file for class documentation
137 tgtList.push_back(AliHLTTPCDefinitions::fgkClustersDataType);
138 tgtList.push_back(kAliHLTDataTypeHwAddr16);
139 return tgtList.size();
142 void AliHLTTPCClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
144 // see header file for class documentation
145 // XXX TODO: Find more realistic values.
149 inputMultiplier = (6 * 0.4);
152 inputMultiplier = 0.4;
155 inputMultiplier = (6 * 0.4);
160 AliHLTComponent* AliHLTTPCClusterFinderComponent::Spawn()
162 // see header file for class documentation
163 return new AliHLTTPCClusterFinderComponent(fModeSwitch);
166 int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
168 // see header file for class documentation
169 if ( fClusterFinder )
172 fClusterFinder = new AliHLTTPCClusterFinder();
175 TString configuration="";
177 for (int i=0; i<argc && iResult>=0; i++) {
179 if (!configuration.IsNull()) configuration+=" ";
180 configuration+=argument;
183 if (!configuration.IsNull()) {
184 iResult=Configure(configuration.Data());
186 iResult=Reconfigure(NULL, NULL);
189 //Checking for conflicting arguments
191 if(fDeconvPad==kTRUE || fDeconvTime==kTRUE){
192 HLTWarning("Conflicting arguments: argument 'pp-run' will be ignored.");
195 if(fClusterFinder->GetOccupancyLimit()!=1.0 && fUnsorted){
196 HLTWarning("Argument 'occupancy-limit' is deprecated when doing unsorted data reading.");
198 if(fGetActivePads==kTRUE && fUnsorted==kFALSE){
199 HLTWarning("Argument '-active-pads' only work with unsorted data reading. Active pads list will not be produced.");
204 if (fModeSwitch==kClusterFinderPacked) {
205 HLTDebug("using AliHLTTPCDigitReaderPacked");
206 fReader = new AliHLTTPCDigitReaderPacked();
207 if(fUnsorted==1){ fReader->SetUnsorted(kTRUE); }
208 fClusterFinder->SetReader(fReader);
210 else if(fModeSwitch==kClusterFinderUnpacked){
211 HLTDebug("using AliHLTTPCDigitReaderUnpacked");
212 fReader = new AliHLTTPCDigitReaderUnpacked();
213 fClusterFinder->SetReader(fReader);
215 else if(fModeSwitch==kClusterFinderDecoder){
216 HLTDebug("using AliHLTTPCDigitReaderDecoder");
217 fReader = new AliHLTTPCDigitReaderDecoder();
218 fClusterFinder->SetReader(fReader);
221 HLTFatal("No mode set for clusterfindercomponent");
225 fClusterFinder->SetOccupancyLimit(1.0);
228 fClusterFinder->SetDeconv(fClusterDeconv);
229 fClusterFinder->SetDeconvPad(fDeconvPad);
230 fClusterFinder->SetDeconvTime(fDeconvPad);
231 fClusterFinder->SetXYError( fXYClusterError );
232 fClusterFinder->SetZError( fZClusterError );
233 if ( (fXYClusterError>0) && (fZClusterError>0) ){
234 fClusterFinder->SetCalcErr( false );
238 fClusterFinder->SetFirstTimeBin(fFirstTimeBin);
240 if(fLastTimeBin>0 && fLastTimeBin>fFirstTimeBin && fLastTimeBin<=AliHLTTPCTransform::GetNTimeBins()){
241 fClusterFinder->SetLastTimeBin(fLastTimeBin);
247 int AliHLTTPCClusterFinderComponent::DoDeinit()
249 // see header file for class documentation
251 if ( fClusterFinder )
252 delete fClusterFinder;
253 fClusterFinder = NULL;
262 int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponentEventData& evtData,
263 const AliHLTComponentBlockData* blocks,
264 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
265 AliHLTUInt32_t& size,
266 vector<AliHLTComponentBlockData>& outputBlocks )
268 // see header file for class documentation
271 HLTFatal("Digit reader not initialized, aborting event.");
276 if(GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR )){
281 // == init iter (pointer to datablock)
282 const AliHLTComponentBlockData* iter = NULL;
285 // == OUTdatatype pointer
286 AliHLTTPCClusterData* outPtr;
288 AliHLTUInt8_t* outBPtr;
289 UInt_t offset, mysize, nSize, tSize = 0;
292 outPtr = (AliHLTTPCClusterData*)outBPtr;
295 unsigned long maxPoints, realPoints = 0;
297 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
304 if (fModeSwitch==0 || fModeSwitch==2) {
305 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
306 evtData.fEventID, evtData.fEventID,
307 DataType2Text( iter->fDataType).c_str(),
308 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
310 if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
312 HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
313 DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
314 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
317 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
318 iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ) continue;
321 else if(fModeSwitch==1){
322 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
323 evtData.fEventID, evtData.fEventID,
324 DataType2Text( iter->fDataType).c_str(),
325 DataType2Text(AliHLTTPCDefinitions::fgkUnpackedRawDataType).c_str());
327 if ( iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
331 slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
332 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
335 fClusterFinder->SetUnsorted(fUnsorted);
336 fClusterFinder->SetPatch(patch);
339 outPtr = (AliHLTTPCClusterData*)outBPtr;
341 maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
343 fClusterFinder->InitSlice( slice, patch, maxPoints );
344 fClusterFinder->SetOutputArray( (AliHLTTPCSpacePointData*)outPtr->fSpacePoints );
348 fClusterFinder->SetDoPadSelection(kTRUE);
351 fClusterFinder->ReadDataUnsortedDeconvoluteTime(iter->fPtr, iter->fSize);
354 fClusterFinder->ReadDataUnsorted(iter->fPtr, iter->fSize);
357 fClusterFinder->FindClusters();
360 fClusterFinder->Read(iter->fPtr, iter->fSize );
361 fClusterFinder->ProcessDigits();
364 realPoints = fClusterFinder->GetNumberOfClusters();
366 outPtr->fSpacePointCnt = realPoints;
367 nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
368 mysize += nSize+sizeof(AliHLTTPCClusterData);
370 Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Spacepoints",
371 "Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
372 realPoints, slice, patch,AliHLTTPCTransform::GetFirstRow( patch ) , AliHLTTPCTransform::GetLastRow( patch ) );
373 AliHLTComponentBlockData bd;
377 bd.fSpecification = iter->fSpecification;
378 bd.fDataType = AliHLTTPCDefinitions::fgkClustersDataType;
379 outputBlocks.push_back( bd );
383 outPtr = (AliHLTTPCClusterData*)outBPtr;
388 Logging( kHLTLogFatal, "HLT::TPCClusterFinder::DoEvent", "Too much data",
389 "Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
394 if(fUnsorted && fGetActivePads){
395 Int_t maxNumberOfHW=(Int_t)((size-tSize)/sizeof(AliHLTUInt16_t)-1);
396 AliHLTUInt16_t* outputHWPtr= (AliHLTUInt16_t*)(outputPtr+tSize);
397 Int_t nHWAdd = fClusterFinder->FillHWAddressList(outputHWPtr, maxNumberOfHW);
399 AliHLTComponentBlockData bdHW;
400 FillBlockData( bdHW );
401 bdHW.fOffset = tSize ;
402 bdHW.fSize = nHWAdd*sizeof(AliHLTUInt16_t);
403 bdHW.fSpecification = iter->fSpecification;
404 bdHW.fDataType = kAliHLTDataTypeHwAddr16;
405 outputBlocks.push_back( bdHW );
407 tSize+=nHWAdd*sizeof(AliHLTUInt16_t);
417 int AliHLTTPCClusterFinderComponent::Configure(const char* arguments){
418 // see header file for class documentation
420 if (!arguments) return iResult;
422 TString allArgs=arguments;
426 TObjArray* pTokens=allArgs.Tokenize(" ");
429 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
430 argument=((TObjString*)pTokens->At(i))->GetString();
432 if (argument.IsNull()) continue;
435 // -- deconvolute-time option
436 if (argument.CompareTo("-deconvolute-time")==0){
437 HLTDebug("Switching on deconvolution in time direction.");
439 fClusterFinder->SetDeconvTime(fDeconvTime);
441 else if (argument.CompareTo("-deconvolute-pad")==0){
442 HLTDebug("Switching on deconvolution in pad direction.");
444 fClusterFinder->SetDeconvPad(fDeconvPad);
446 else if (argument.CompareTo("-timebins")==0 || argument.CompareTo("timebins" )==0){
447 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
448 AliHLTTPCTransform::SetNTimeBins(((TObjString*)pTokens->At(i))->GetString().Atoi());
449 fClusterFinder->UpdateLastTimeBin();
450 HLTInfo("number of timebins set to %d, zbin=%f", AliHLTTPCTransform::GetNTimeBins(), AliHLTTPCTransform::GetZWidth());
451 if(argument.CompareTo("timebins")==0){
452 HLTWarning("Argument 'timebins' is old, please switch to new argument naming convention (-timebins). The timebins argument will still work, but please change anyway.");
455 else if (argument.CompareTo("-first-timebin")==0){
456 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
457 fFirstTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
458 if(fFirstTimeBin>=0){
459 HLTDebug("fFirstTimeBin set to %d",fFirstTimeBin);
460 fClusterFinder->SetFirstTimeBin(fFirstTimeBin);
463 HLTError("-first-timebin specifier is negative: %d",fFirstTimeBin);
466 else if (argument.CompareTo("-last-timebin")==0){
467 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
468 fLastTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
469 if(fLastTimeBin<AliHLTTPCTransform::GetNTimeBins()){
470 HLTDebug("fLastTimeBin set to %d",fLastTimeBin);
473 HLTError("fLastTimeBins is too big: %d. Maximum: %d",fLastTimeBin,AliHLTTPCTransform::GetNTimeBins());
476 else if (argument.CompareTo("-sorted")==0) {
478 HLTDebug("Swithching unsorted off.");
479 fClusterFinder->SetUnsorted(0);
481 else if (argument.CompareTo("-active-pads")==0 || argument.CompareTo("activepads")==0){
482 if(argument.CompareTo("activepads" )==0){
483 HLTWarning("Please change to new component argument naming scheme and use '-active-pads' instead of 'activepads'");
485 HLTDebug("Switching on ActivePads");
487 fClusterFinder->SetDoPadSelection(kTRUE);
489 else if (argument.CompareTo("-occupancy-limit")==0 || argument.CompareTo("occupancy-limit")==0){
490 if(argument.CompareTo("occupancy-limit" )==0){
491 HLTWarning("Please switch to new component argument naming convention, use '-occupancy-limit' instead of 'occupancy-limit'");
493 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
494 fClusterFinder->SetOccupancyLimit(((TObjString*)pTokens->At(i))->GetString().Atof());
495 HLTDebug("Occupancy limit set to occulimit %f", ((TObjString*)pTokens->At(i))->GetString().Atof());
497 else if (argument.CompareTo("rawreadermode")==0){
498 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
499 HLTWarning("Argument 'rawreadermode' is deprecated");
501 else if (argument.CompareTo("pp-run")==0){
502 HLTWarning("Argument 'pp-run' is obsolete, deconvolution is swiched off in both time and pad directions by default.");
503 fClusterDeconv = false;
505 else if (argument.CompareTo("adc-threshold" )==0){
506 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
507 HLTWarning("'adc-threshold' is no longer a valid argument, please use TPCZeroSuppression component if you want to zerosuppress data.");
509 else if (argument.CompareTo("oldrcuformat" )==0){
510 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
511 HLTWarning("Argument 'oldrcuformat' is deprecated.");
513 else if (argument.CompareTo("unsorted" )==0){
514 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
515 HLTDebug("Using unsorted reading.");
516 fClusterFinder->SetUnsorted(1);
518 else if (argument.CompareTo("nsigma-threshold")==0){
519 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
520 HLTWarning("Argument 'nsigma-threshold' argument is obsolete.");
523 HLTError("unknown argument %s", argument.Data());
531 HLTError("missing parameter for argument %s", argument.Data());
537 int AliHLTTPCClusterFinderComponent::Reconfigure(const char* cdbEntry, const char* chainId)
541 // see header file for class documentation
542 const char* path="HLT/ConfigTPC/ClusterFinderComponent";
543 if (cdbEntry) path=cdbEntry;
545 HLTInfo("reconfigure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
546 AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
548 TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
550 HLTInfo("received configuration object: %s", pString->GetString().Data());
551 iResult = Configure(pString->GetString().Data());
553 HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
556 HLTError("can not fetch object \"%s\" from CDB", path);