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"
42 #include "AliTPCcalibDB.h"
43 #include "AliTPCCalPad.h"
44 #include "AliTPCParam.h"
49 #include "TObjString.h"
50 #include "TObjArray.h"
51 #include "AliCDBEntry.h"
52 #include "AliCDBManager.h"
53 #include "AliCDBStorage.h"
57 /** ROOT macro for the implementation of ROOT specific class methods */
58 ClassImp(AliHLTTPCClusterFinderComponent)
60 AliHLTTPCClusterFinderComponent::AliHLTTPCClusterFinderComponent(int mode)
66 fClusterDeconv(false),
77 // see header file for class documentation
79 // refer to README to build package
81 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
82 if (fModeSwitch!=kClusterFinderPacked &&
83 fModeSwitch!=kClusterFinderUnpacked &&
84 fModeSwitch!=kClusterFinderDecoder &&
85 fModeSwitch!=kClusterFinder32Bit) {
86 HLTFatal("unknown digit reader type");
90 AliHLTTPCClusterFinderComponent::~AliHLTTPCClusterFinderComponent()
92 // see header file for class documentation
95 // Public functions to implement AliHLTComponent's interface.
96 // These functions are required for the registration process
98 const char* AliHLTTPCClusterFinderComponent::GetComponentID()
100 // see header file for class documentation
102 case kClusterFinderPacked:
103 return "TPCClusterFinderPacked";
105 case kClusterFinderUnpacked:
106 return "TPCClusterFinderUnpacked";
108 case kClusterFinderDecoder:
109 return "TPCClusterFinderDecoder";
111 case kClusterFinder32Bit:
112 return "TPCClusterFinder32Bit";
118 void AliHLTTPCClusterFinderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
120 // see header file for class documentation
123 case kClusterFinderPacked:
124 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
126 case kClusterFinderUnpacked:
127 list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );
129 case kClusterFinderDecoder:
130 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
132 case kClusterFinder32Bit:
133 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
138 AliHLTComponentDataType AliHLTTPCClusterFinderComponent::GetOutputDataType()
140 // see header file for class documentation
141 return kAliHLTMultipleDataType;
144 int AliHLTTPCClusterFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
147 // see header file for class documentation
149 tgtList.push_back(AliHLTTPCDefinitions::fgkClustersDataType);
150 tgtList.push_back(kAliHLTDataTypeHwAddr16);
151 return tgtList.size();
154 void AliHLTTPCClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
156 // see header file for class documentation
157 // XXX TODO: Find more realistic values.
160 case kClusterFinderPacked:
161 inputMultiplier = (6 * 0.4);
163 case kClusterFinderUnpacked:
164 inputMultiplier = 0.4;
166 case kClusterFinderDecoder:
167 inputMultiplier = (6 * 0.4);
169 case kClusterFinder32Bit:
170 inputMultiplier = (6 * 0.4);
175 AliHLTComponent* AliHLTTPCClusterFinderComponent::Spawn()
177 // see header file for class documentation
178 return new AliHLTTPCClusterFinderComponent(fModeSwitch);
181 int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
183 // see header file for class documentation
184 if ( fClusterFinder )
187 //Test if the OCDB entries used by AliTPCTransform is availible
188 AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
190 AliTPCCalPad * time0TPC = calib->GetPadTime0();
192 HLTError("OCDB entry TPC/Calib/PadTime0 (AliTPCcalibDB::GetPadTime0()) is not available.");
196 AliTPCParam * param = calib->GetParameters();
198 HLTError("OCDB entry TPC/Calib/Parameters (AliTPCcalibDB::GetParameters()) is not available.");
203 fClusterFinder = new AliHLTTPCClusterFinder();
206 TString configuration="";
208 for (int i=0; i<argc && iResult>=0; i++) {
210 if (!configuration.IsNull()) configuration+=" ";
211 configuration+=argument;
214 if (!configuration.IsNull()) {
215 iResult=Configure(configuration.Data());
217 iResult=Reconfigure(NULL, NULL);
220 //Checking for conflicting arguments
222 if(fDeconvPad==kTRUE || fDeconvTime==kTRUE){
223 HLTWarning("Conflicting arguments: argument 'pp-run' will be ignored.");
226 if(fClusterFinder->GetOccupancyLimit()!=1.0 && fUnsorted){
227 HLTWarning("Argument 'occupancy-limit' is deprecated when doing unsorted data reading.");
229 if(fGetActivePads==kTRUE && fUnsorted==kFALSE){
230 HLTWarning("Argument '-active-pads' only work with unsorted data reading. Active pads list will not be produced.");
235 if (fModeSwitch==kClusterFinderPacked) {
236 HLTDebug("using AliHLTTPCDigitReaderPacked");
237 fReader = new AliHLTTPCDigitReaderPacked();
238 if(fUnsorted==1){ fReader->SetUnsorted(kTRUE); }
239 fClusterFinder->SetReader(fReader);
241 else if(fModeSwitch==kClusterFinderUnpacked){
242 HLTDebug("using AliHLTTPCDigitReaderUnpacked");
243 fReader = new AliHLTTPCDigitReaderUnpacked();
244 if(fUnsorted==1){ fReader->SetUnsorted(kTRUE); }
245 fClusterFinder->SetReader(fReader);
247 else if(fModeSwitch==kClusterFinderDecoder){
248 HLTDebug("using AliHLTTPCDigitReaderDecoder");
249 fReader = new AliHLTTPCDigitReaderDecoder();
250 fClusterFinder->SetReader(fReader);
252 else if(fModeSwitch==kClusterFinder32Bit){
253 HLTDebug("using AliHLTTPCDigitReader32Bit");
254 fReader = new AliHLTTPCDigitReader32Bit();
255 fClusterFinder->SetReader(fReader);
256 fClusterFinder->Set32BitFormat(kTRUE);
259 HLTFatal("No mode set for clusterfindercomponent");
263 fClusterFinder->SetOccupancyLimit(1.0);
266 fClusterFinder->SetDeconv(fClusterDeconv);
267 fClusterFinder->SetDeconvPad(fDeconvPad);
268 fClusterFinder->SetDeconvTime(fDeconvPad);
269 fClusterFinder->SetXYError( fXYClusterError );
270 fClusterFinder->SetZError( fZClusterError );
271 if ( (fXYClusterError>0) && (fZClusterError>0) ){
272 fClusterFinder->SetCalcErr( false );
276 fClusterFinder->SetFirstTimeBin(fFirstTimeBin);
278 if(fLastTimeBin>0 && fLastTimeBin>fFirstTimeBin && fLastTimeBin<=AliHLTTPCTransform::GetNTimeBins()){
279 fClusterFinder->SetLastTimeBin(fLastTimeBin);
285 int AliHLTTPCClusterFinderComponent::DoDeinit()
287 // see header file for class documentation
289 if ( fClusterFinder )
290 delete fClusterFinder;
291 fClusterFinder = NULL;
300 int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponentEventData& evtData,
301 const AliHLTComponentBlockData* blocks,
302 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
303 AliHLTUInt32_t& size,
304 vector<AliHLTComponentBlockData>& outputBlocks )
306 // see header file for class documentation
310 HLTFatal("Digit reader not initialized, skipping HLT TPC cluster reconstruction.");
315 if(GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR )){
320 // == init iter (pointer to datablock)
321 const AliHLTComponentBlockData* iter = NULL;
324 // == OUTdatatype pointer
325 AliHLTTPCClusterData* outPtr;
327 AliHLTUInt8_t* outBPtr;
328 UInt_t offset, mysize, nSize, tSize = 0;
331 outPtr = (AliHLTTPCClusterData*)outBPtr;
334 unsigned long maxPoints, realPoints = 0;
336 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
342 // Kenneth 16. July 2009
343 // 32 byte is the size of the common data header (CDH)
344 // this is introduced as a protection of empty files
345 // normally when running with file publisher where
346 // Timms script is used to create the missing files
347 if(iter->fSize <= 32){
352 if (fModeSwitch==0 || fModeSwitch==2 || fModeSwitch==3) {
353 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
354 evtData.fEventID, evtData.fEventID,
355 DataType2Text( iter->fDataType).c_str(),
356 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
358 if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
360 HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
361 DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
362 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
365 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
366 iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ) continue;
369 else if(fModeSwitch==1){
370 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
371 evtData.fEventID, evtData.fEventID,
372 DataType2Text( iter->fDataType).c_str(),
373 DataType2Text(AliHLTTPCDefinitions::fgkUnpackedRawDataType).c_str());
375 if ( iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
379 slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
380 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
383 fClusterFinder->SetUnsorted(fUnsorted);
384 fClusterFinder->SetPatch(patch);
387 outPtr = (AliHLTTPCClusterData*)outBPtr;
389 maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
391 fClusterFinder->InitSlice( slice, patch, maxPoints );
392 fClusterFinder->SetOutputArray( (AliHLTTPCSpacePointData*)outPtr->fSpacePoints );
396 fClusterFinder->SetDoPadSelection(kTRUE);
399 fClusterFinder->ReadDataUnsortedDeconvoluteTime(iter->fPtr, iter->fSize);
402 fClusterFinder->ReadDataUnsorted(iter->fPtr, iter->fSize);
405 fClusterFinder->FindClusters();
408 fClusterFinder->Read(iter->fPtr, iter->fSize );
409 fClusterFinder->ProcessDigits();
413 realPoints = fClusterFinder->GetNumberOfClusters();
415 outPtr->fSpacePointCnt = realPoints;
416 nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
417 mysize += nSize+sizeof(AliHLTTPCClusterData);
419 Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Spacepoints",
420 "Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
421 realPoints, slice, patch,AliHLTTPCTransform::GetFirstRow( patch ) , AliHLTTPCTransform::GetLastRow( patch ) );
422 AliHLTComponentBlockData bd;
426 bd.fSpecification = iter->fSpecification;
427 bd.fDataType = AliHLTTPCDefinitions::fgkClustersDataType;
428 outputBlocks.push_back( bd );
432 outPtr = (AliHLTTPCClusterData*)outBPtr;
437 Logging( kHLTLogFatal, "HLT::TPCClusterFinder::DoEvent", "Too much data",
438 "Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
444 if(fUnsorted && fGetActivePads){
445 Int_t maxNumberOfHW=(Int_t)((size-tSize)/sizeof(AliHLTUInt16_t)-1);
446 AliHLTUInt16_t* outputHWPtr= (AliHLTUInt16_t*)(outputPtr+tSize);
447 Int_t nHWAdd = fClusterFinder->FillHWAddressList(outputHWPtr, maxNumberOfHW);
449 AliHLTComponentBlockData bdHW;
450 FillBlockData( bdHW );
451 bdHW.fOffset = tSize ;
452 bdHW.fSize = nHWAdd*sizeof(AliHLTUInt16_t);
453 bdHW.fSpecification = iter->fSpecification;
454 bdHW.fDataType = kAliHLTDataTypeHwAddr16;
455 outputBlocks.push_back( bdHW );
457 tSize+=nHWAdd*sizeof(AliHLTUInt16_t);
461 Int_t maxNumberOfClusterMCInfo = (Int_t)((size-tSize)/sizeof(AliHLTTPCClusterFinder::ClusterMCInfo)-1);
462 AliHLTTPCClusterFinder::ClusterMCInfo* outputMCInfo= (AliHLTTPCClusterFinder::ClusterMCInfo*)(outputPtr+tSize);
463 Int_t nMCInfo = fClusterFinder->FillOutputMCInfo(outputMCInfo, maxNumberOfClusterMCInfo);
465 AliHLTComponentBlockData bdMCInfo;
466 FillBlockData( bdMCInfo );
467 bdMCInfo.fOffset = tSize ;
468 bdMCInfo.fSize = nMCInfo*sizeof(AliHLTTPCClusterFinder::ClusterMCInfo);
469 bdMCInfo.fSpecification = iter->fSpecification;
470 bdMCInfo.fDataType = AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo;
471 outputBlocks.push_back( bdMCInfo );
473 tSize+=nMCInfo*sizeof(AliHLTTPCClusterFinder::ClusterMCInfo);
484 int AliHLTTPCClusterFinderComponent::Configure(const char* arguments){
485 // see header file for class documentation
487 if (!arguments) return iResult;
489 TString allArgs=arguments;
493 TObjArray* pTokens=allArgs.Tokenize(" ");
496 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
497 argument=((TObjString*)pTokens->At(i))->GetString();
499 if (argument.IsNull()) continue;
501 // -- deconvolute-time option
502 if (argument.CompareTo("-deconvolute-time")==0){
503 HLTDebug("Switching on deconvolution in time direction.");
505 fClusterFinder->SetDeconvTime(fDeconvTime);
507 else if (argument.CompareTo("-deconvolute-pad")==0){
508 HLTDebug("Switching on deconvolution in pad direction.");
510 fClusterFinder->SetDeconvPad(fDeconvPad);
512 else if (argument.CompareTo("-timebins")==0 || argument.CompareTo("timebins" )==0){
513 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
514 AliHLTTPCTransform::SetNTimeBins(((TObjString*)pTokens->At(i))->GetString().Atoi());
515 fClusterFinder->UpdateLastTimeBin();
516 HLTInfo("number of timebins set to %d, zbin=%f", AliHLTTPCTransform::GetNTimeBins(), AliHLTTPCTransform::GetZWidth());
517 if(argument.CompareTo("timebins")==0){
518 HLTWarning("Argument 'timebins' is old, please switch to new argument naming convention (-timebins). The timebins argument will still work, but please change anyway.");
521 else if (argument.CompareTo("-first-timebin")==0){
522 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
523 fFirstTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
524 if(fFirstTimeBin>=0){
525 HLTDebug("fFirstTimeBin set to %d",fFirstTimeBin);
526 fClusterFinder->SetFirstTimeBin(fFirstTimeBin);
529 HLTError("-first-timebin specifier is negative: %d",fFirstTimeBin);
532 else if (argument.CompareTo("-last-timebin")==0){
533 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
534 fLastTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
535 if(fLastTimeBin<AliHLTTPCTransform::GetNTimeBins()){
536 HLTDebug("fLastTimeBin set to %d",fLastTimeBin);
539 HLTError("fLastTimeBins is too big: %d. Maximum: %d",fLastTimeBin,AliHLTTPCTransform::GetNTimeBins());
542 else if (argument.CompareTo("-sorted")==0) {
544 HLTDebug("Swithching unsorted off.");
545 fClusterFinder->SetUnsorted(0);
547 else if (argument.CompareTo("-do-mc")==0) {
549 fClusterFinder->SetDoMC(fDoMC);
550 HLTInfo("Setting fDoMC to true.");
552 else if (argument.CompareTo("-active-pads")==0 || argument.CompareTo("activepads")==0){
553 if(argument.CompareTo("activepads" )==0){
554 HLTWarning("Please change to new component argument naming scheme and use '-active-pads' instead of 'activepads'");
556 HLTDebug("Switching on ActivePads");
558 fClusterFinder->SetDoPadSelection(kTRUE);
560 else if (argument.CompareTo("-occupancy-limit")==0 || argument.CompareTo("occupancy-limit")==0){
561 if(argument.CompareTo("occupancy-limit" )==0){
562 HLTWarning("Please switch to new component argument naming convention, use '-occupancy-limit' instead of 'occupancy-limit'");
564 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
565 fClusterFinder->SetOccupancyLimit(((TObjString*)pTokens->At(i))->GetString().Atof());
566 HLTDebug("Occupancy limit set to occulimit %f", ((TObjString*)pTokens->At(i))->GetString().Atof());
568 else if (argument.CompareTo("rawreadermode")==0){
569 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
570 HLTWarning("Argument 'rawreadermode' is deprecated");
572 else if (argument.CompareTo("pp-run")==0){
573 HLTWarning("Argument 'pp-run' is obsolete, deconvolution is swiched off in both time and pad directions by default.");
574 fClusterDeconv = false;
576 else if (argument.CompareTo("adc-threshold" )==0){
577 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
578 HLTWarning("'adc-threshold' is no longer a valid argument, please use TPCZeroSuppression component if you want to zerosuppress data.");
580 else if (argument.CompareTo("oldrcuformat" )==0){
581 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
582 HLTWarning("Argument 'oldrcuformat' is deprecated.");
584 else if (argument.CompareTo("unsorted" )==0){
585 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
586 HLTDebug("Using unsorted reading.");
587 fClusterFinder->SetUnsorted(1);
589 else if (argument.CompareTo("nsigma-threshold")==0){
590 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
591 HLTWarning("Argument 'nsigma-threshold' argument is obsolete.");
594 HLTError("unknown argument %s", argument.Data());
602 HLTError("missing parameter for argument %s", argument.Data());
608 int AliHLTTPCClusterFinderComponent::Reconfigure(const char* cdbEntry, const char* chainId)
612 // see header file for class documentation
613 const char* path="HLT/ConfigTPC/ClusterFinderComponent";
614 if (cdbEntry) path=cdbEntry;
616 HLTInfo("reconfigure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
617 AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
619 TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
621 HLTInfo("received configuration object: %s", pString->GetString().Data());
622 iResult = Configure(pString->GetString().Data());
624 HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
627 HLTError("can not fetch object \"%s\" from CDB", path);