2 // **************************************************************************
3 // This file is property of and copyright by the ALICE HLT Project *
4 // ALICE Experiment at CERN, All rights reserved. *
6 // Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
7 // Ivan Kisel <kisel@kip.uni-heidelberg.de> *
8 // for The ALICE HLT Project. *
10 // Permission to use, copy, modify and distribute this software and its *
11 // documentation strictly for non-commercial purposes is hereby granted *
12 // without fee, provided that the above copyright notice appears in all *
13 // copies and that both the copyright notice and this permission notice *
14 // appear in the supporting documentation. The authors make no claims *
15 // about the suitability of this software for any purpose. It is *
16 // provided "as is" without express or implied warranty. *
18 //***************************************************************************
21 ///////////////////////////////////////////////////////////////////////////////
23 // a TPC tracker processing component for the HLT based on CA by Ivan Kisel //
25 ///////////////////////////////////////////////////////////////////////////////
31 #include "AliHLTTPCCATrackerComponent.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTTPCCATracker.h"
34 #include "AliHLTTPCCAOutTrack.h"
35 #include "AliHLTTPCCAParam.h"
36 #include "AliHLTTPCCATrackConvertor.h"
37 #include "AliHLTArray.h"
39 #include "AliHLTTPCSpacePointData.h"
40 #include "AliHLTTPCClusterDataFormat.h"
41 #include "AliHLTTPCTransform.h"
42 #include "AliHLTTPCTrackSegmentData.h"
43 #include "AliHLTTPCTrackArray.h"
44 #include "AliHLTTPCTrackletDataFormat.h"
45 #include "AliHLTTPCDefinitions.h"
46 #include "AliExternalTrackParam.h"
47 #include "TStopwatch.h"
49 #include "AliCDBEntry.h"
50 #include "AliCDBManager.h"
51 #include "TObjString.h"
52 #include "TObjArray.h"
53 #include "AliHLTTPCCASliceOutput.h"
54 #include "AliHLTTPCCAClusterData.h"
56 const AliHLTComponentDataType AliHLTTPCCADefinitions::fgkTrackletsDataType = AliHLTComponentDataTypeInitializer( "CATRACKL", kAliHLTDataOriginTPC );
58 /** ROOT macro for the implementation of ROOT specific class methods */
59 ClassImp( AliHLTTPCCATrackerComponent )
61 AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent()
65 fMinNTrackClusters( 0 ),
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
79 AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent( const AliHLTTPCCATrackerComponent& )
84 fMinNTrackClusters( 30 ),
91 // see header file for class documentation
92 HLTFatal( "copy constructor untested" );
95 AliHLTTPCCATrackerComponent& AliHLTTPCCATrackerComponent::operator=( const AliHLTTPCCATrackerComponent& )
97 // see header file for class documentation
98 HLTFatal( "assignment operator untested" );
102 AliHLTTPCCATrackerComponent::~AliHLTTPCCATrackerComponent()
104 // see header file for class documentation
109 // Public functions to implement AliHLTComponent's interface.
110 // These functions are required for the registration process
113 const char* AliHLTTPCCATrackerComponent::GetComponentID()
115 // see header file for class documentation
116 return "TPCCATracker";
119 void AliHLTTPCCATrackerComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list )
121 // see header file for class documentation
123 list.push_back( AliHLTTPCDefinitions::fgkClustersDataType );
126 AliHLTComponentDataType AliHLTTPCCATrackerComponent::GetOutputDataType()
128 // see header file for class documentation
129 if ( fOutputTRAKSEGS ) return AliHLTTPCDefinitions::fgkTrackSegmentsDataType;
130 else return AliHLTTPCCADefinitions::fgkTrackletsDataType;
133 void AliHLTTPCCATrackerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
135 // define guess for the output data size
136 constBase = 200; // minimum size
137 inputMultiplier = 0.5; // size relative to input
140 AliHLTComponent* AliHLTTPCCATrackerComponent::Spawn()
142 // see header file for class documentation
143 return new AliHLTTPCCATrackerComponent;
146 void AliHLTTPCCATrackerComponent::SetDefaultConfiguration()
148 // Set default configuration for the CA tracker component
149 // Some parameters can be later overwritten from the OCDB
152 fMinNTrackClusters = 0;
160 int AliHLTTPCCATrackerComponent::ReadConfigurationString( const char* arguments )
162 // Set configuration parameters for the CA tracker component from the string
165 if ( !arguments ) return iResult;
167 TString allArgs = arguments;
169 int bMissingParam = 0;
171 TObjArray* pTokens = allArgs.Tokenize( " " );
173 int nArgs = pTokens ? pTokens->GetEntries() : 0;
175 for ( int i = 0; i < nArgs; i++ ) {
176 argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
177 if ( argument.IsNull() ) continue;
179 if ( argument.CompareTo( "-solenoidBz" ) == 0 ) {
180 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
181 fSolenoidBz = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
182 HLTInfo( "Magnetic Field set to: %f", fSolenoidBz );
186 if ( argument.CompareTo( "-minNClustersOnTrack" ) == 0 ) {
187 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
188 fMinNTrackClusters = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
189 HLTInfo( "minNClustersOnTrack set to: %d", fMinNTrackClusters );
193 if ( argument.CompareTo( "-clusterZCut" ) == 0 ) {
194 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
195 fClusterZCut = TMath::Abs( ( ( TObjString* )pTokens->At( i ) )->GetString().Atof() );
196 HLTInfo( "ClusterZCut set to: %f", fClusterZCut );
200 if ( argument.CompareTo( "-outputTRAKSEGS" ) == 0 ) {
202 HLTInfo( "The special output type \"TRAKSEGS\" is set" );
206 HLTError( "Unknown option \"%s\"", argument.Data() );
211 if ( bMissingParam ) {
212 HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
220 int AliHLTTPCCATrackerComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
222 // see header file for class documentation
224 const char* defaultNotify="";
227 cdbEntry="HLT/ConfigTPC/TPCCATracker";
228 defaultNotify=" (default)";
232 HLTInfo("configure from entry \"%s\"%s, chain id %s", cdbEntry, defaultNotify,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
233 AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(cdbEntry);//,GetRunNo());
236 HLTError("cannot fetch object \"%s\" from CDB", cdbEntry);
240 TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
243 HLTError("configuration object \"%s\" has wrong type, required TObjString", cdbEntry);
247 HLTInfo("received configuration object string: \"%s\"", pString->GetString().Data());
249 return ReadConfigurationString( pString->GetString().Data() );
253 int AliHLTTPCCATrackerComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
255 // Configure the component
256 // There are few levels of configuration,
257 // parameters which are set on one step can be overwritten on the next step
259 //* read hard-coded values
261 SetDefaultConfiguration();
263 //* read the default CDB entry
265 int iResult1 = ReadCDBEntry( NULL, chainId );
267 //* read magnetic field
269 int iResult2 = ReadCDBEntry( kAliHLTCDBSolenoidBz, chainId );
271 //* read the actual CDB entry if required
273 int iResult3 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) :0;
275 //* read extra parameters from input (if they are)
279 if( commandLine && commandLine[0]!='\0' ){
280 HLTInfo("received configuration string from HLT framework: \"%s\"", commandLine );
281 iResult4 = ReadConfigurationString( commandLine );
284 // Initialise the tracker here
286 return iResult1 ? iResult1 :(iResult2 ? iResult2 :( iResult3 ? iResult3 :iResult4 ) );
291 int AliHLTTPCCATrackerComponent::DoInit( int argc, const char** argv )
293 // Configure the CA tracker component
295 if ( fTracker ) return EINPROGRESS;
297 fTracker = new AliHLTTPCCATracker();
299 TString arguments = "";
300 for ( int i = 0; i < argc; i++ ) {
301 if ( !arguments.IsNull() ) arguments += " ";
302 arguments += argv[i];
305 return Configure( NULL, NULL,arguments.Data() );
309 int AliHLTTPCCATrackerComponent::DoDeinit()
311 // see header file for class documentation
319 int AliHLTTPCCATrackerComponent::Reconfigure( const char* cdbEntry, const char* chainId )
321 // Reconfigure the component from OCDB .
323 return Configure( cdbEntry, chainId, NULL );
327 bool AliHLTTPCCATrackerComponent::CompareClusters( AliHLTTPCSpacePointData *a, AliHLTTPCSpacePointData *b )
329 //* Comparison function for sort clusters
331 if ( a->fPadRow < b->fPadRow ) return 1;
332 if ( a->fPadRow > b->fPadRow ) return 0;
333 return ( a->fZ < b->fZ );
338 int AliHLTTPCCATrackerComponent::DoEvent
340 const AliHLTComponentEventData& evtData,
341 const AliHLTComponentBlockData* blocks,
342 AliHLTComponentTriggerData& /*trigData*/,
343 AliHLTUInt8_t* outputPtr,
344 AliHLTUInt32_t& size,
345 vector<AliHLTComponentBlockData>& outputBlocks )
349 AliHLTUInt32_t maxBufferSize = size;
350 size = 0; // output size
352 if ( GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR ) ) {
358 // Event reconstruction in one TPC slice with CA Tracker
360 //Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "DoEvent", "CA::DoEvent()" );
361 if ( evtData.fBlockCnt <= 0 ) {
362 HLTWarning( "no blocks in event" );
366 const AliHLTComponentBlockData* iter = NULL;
368 AliHLTTPCClusterData* inPtrSP;
370 // Determine the slice number
374 std::vector<int> slices;
375 std::vector<int>::iterator slIter;
376 std::vector<unsigned> sliceCnts;
377 std::vector<unsigned>::iterator slCntIter;
379 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ) {
381 if ( iter->fDataType != AliHLTTPCDefinitions::fgkClustersDataType ) continue;
383 slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
386 slCntIter = sliceCnts.begin();
387 for ( slIter = slices.begin(); slIter != slices.end(); slIter++, slCntIter++ ) {
388 if ( *slIter == slice ) {
394 slices.push_back( slice );
395 sliceCnts.push_back( 1 );
400 // Determine slice number to really use.
401 if ( slices.size() > 1 ) {
402 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
403 "Multiple slice numbers found in event 0x%08lX (%lu). Determining maximum occuring slice number...",
404 evtData.fEventID, evtData.fEventID );
405 unsigned maxCntSlice = 0;
406 slCntIter = sliceCnts.begin();
407 for ( slIter = slices.begin(); slIter != slices.end(); slIter++, slCntIter++ ) {
408 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
409 "Slice %lu found %lu times.", *slIter, *slCntIter );
410 if ( maxCntSlice < *slCntIter ) {
411 maxCntSlice = *slCntIter;
415 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
416 "Using slice %lu.", slice );
417 } else if ( slices.size() > 0 ) {
418 slice = *( slices.begin() );
423 HLTWarning( "no slices found in event" );
428 // Initialize the tracker
432 if ( !fTracker ) fTracker = new AliHLTTPCCATracker;
434 float inRmin = 83.65;
435 // float inRmax = 133.3;
436 // float outRmin = 133.5;
437 float outRmax = 247.7;
438 float plusZmin = 0.0529937;
439 float plusZmax = 249.778;
440 float minusZmin = -249.645;
441 float minusZmax = -0.0799937;
442 float dalpha = 0.349066;
443 float alpha = 0.174533 + dalpha * iSec;
445 bool zPlus = ( iSec < 18 );
446 float zMin = zPlus ? plusZmin : minusZmin;
447 float zMax = zPlus ? plusZmax : minusZmax;
448 //TPCZmin = -249.645, ZMax = 249.778
449 // float rMin = inRmin;
450 // float rMax = outRmax;
451 int nRows = AliHLTTPCTransform::GetNRows();
453 float padPitch = 0.4;
454 float sigmaZ = 0.228808;
456 float *rowX = new float [nRows];
457 for ( int irow = 0; irow < nRows; irow++ ) {
458 rowX[irow] = AliHLTTPCTransform::Row2X( irow );
461 AliHLTTPCCAParam param;
463 param.Initialize( iSec, nRows, rowX, alpha, dalpha,
464 inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, fSolenoidBz );
465 param.SetHitPickUpFactor( 2 );
467 fTracker->Initialize( param );
472 // min and max patch numbers and row numbers
475 int minPatch = 100, maxPatch = -1;
479 int nClustersTotal = 0;
483 std::vector<unsigned long> patchIndices;
485 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ) {
487 if ( iter->fDataType != AliHLTTPCDefinitions::fgkClustersDataType ) continue;
488 if ( slice != AliHLTTPCDefinitions::GetMinSliceNr( *iter ) ) continue;
489 inPtrSP = ( AliHLTTPCClusterData* )( iter->fPtr );
490 nClustersTotal += inPtrSP->fSpacePointCnt;
491 int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
492 if ( minPatch > patch ) {
494 row[0] = AliHLTTPCTransform::GetFirstRow( patch );
496 if ( maxPatch < patch ) {
498 row[1] = AliHLTTPCTransform::GetLastRow( patch );
500 std::vector<unsigned long>::iterator pIter = patchIndices.begin();
501 while ( pIter != patchIndices.end() && AliHLTTPCDefinitions::GetMinPatchNr( blocks[*pIter] ) < patch ) {
504 patchIndices.insert( pIter, ndx );
508 // pass event to CA Tracker
511 Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reading hits",
512 "Total %d hits to read for slice %d", nClustersTotal, slice );
515 AliHLTTPCCAClusterData clusterData;
516 clusterData.StartReading( slice, nClustersTotal );
518 for ( std::vector<unsigned long>::iterator pIter = patchIndices.begin(); pIter != patchIndices.end(); pIter++ ) {
522 int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
523 inPtrSP = ( AliHLTTPCClusterData* )( iter->fPtr );
525 Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reading hits",
526 "Reading %d hits for slice %d - patch %d", inPtrSP->fSpacePointCnt, slice, patch );
528 for ( unsigned int i = 0; i < inPtrSP->fSpacePointCnt; i++ ) {
529 AliHLTTPCSpacePointData *c = &( inPtrSP->fSpacePoints[i] );
530 if ( CAMath::Abs( c->fZ ) > fClusterZCut ) continue;
531 if( c->fPadRow <0 || c->fPadRow>159 ){
532 HLTError("Wrong TPC cluster with row number %d received",c->fPadRow);
535 clusterData.ReadCluster( c->fID, c->fPadRow, c->fX, c->fY, c->fZ, c->fCharge );
539 clusterData.FinishReading();
541 // reconstruct the event
543 TStopwatch timerReco;
545 fTracker->ReadEvent( &clusterData );
547 fTracker->Reconstruct();
553 Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reconstruct",
554 "%d tracks found for slice %d", fTracker->NOutTracks(), slice );
557 // write reconstructed tracks
559 unsigned int mySize = 0;
560 int ntracks = *fTracker->NOutTracks();
563 if ( fOutputTRAKSEGS ) {
565 AliHLTTPCTrackletData* outPtr = ( AliHLTTPCTrackletData* )( outputPtr );
567 AliHLTTPCTrackSegmentData* currOutTracklet = outPtr->fTracklets;
569 mySize = ( ( AliHLTUInt8_t * )currOutTracklet ) - ( ( AliHLTUInt8_t * )outputPtr );
571 outPtr->fTrackletCnt = 0;
573 for ( int itr = 0; itr < ntracks; itr++ ) {
575 AliHLTTPCCAOutTrack &t = fTracker->OutTracks()[itr];
577 //Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Wrtite output","track %d with %d hits", itr, t.NHits());
579 if ( t.NHits() < fMinNTrackClusters ) continue;
581 // calculate output track size
583 unsigned int dSize = sizeof( AliHLTTPCTrackSegmentData ) + t.NHits() * sizeof( unsigned int );
585 if ( mySize + dSize > maxBufferSize ) {
586 HLTWarning( "Output buffer size exceed (buffer size %d, current size %d), %d tracks are not stored", maxBufferSize, mySize, ntracks - itr + 1 );
591 // convert CA track parameters to HLT Track Segment
593 int iFirstRow = 1000;
595 int iFirstHit = fTracker->OutTrackHits()[t.FirstHitRef()];
596 int iLastHit = iFirstHit;
597 for ( int ih = 0; ih < t.NHits(); ih++ ) {
598 int hitID = fTracker->OutTrackHits()[t.FirstHitRef() + ih ];
599 int iRow = clusterData.RowNumber( hitID );
600 if ( iRow < iFirstRow ) { iFirstRow = iRow; iFirstHit = hitID; }
601 if ( iRow > iLastRow ) { iLastRow = iRow; iLastHit = hitID; }
604 AliHLTTPCCATrackParam par = t.StartPoint();
606 par.TransportToX( clusterData.X( iFirstHit ), .99 );
608 AliExternalTrackParam tp;
609 AliHLTTPCCATrackConvertor::GetExtParam( par, tp, 0 );
611 currOutTracklet->fX = tp.GetX();
612 currOutTracklet->fY = tp.GetY();
613 currOutTracklet->fZ = tp.GetZ();
614 currOutTracklet->fCharge = ( int ) tp.GetSign();
615 currOutTracklet->fPt = TMath::Abs( tp.GetSignedPt() );
616 float snp = tp.GetSnp() ;
617 if ( snp > .999 ) snp = .999;
618 if ( snp < -.999 ) snp = -.999;
619 currOutTracklet->fPsi = TMath::ASin( snp );
620 currOutTracklet->fTgl = tp.GetTgl();
622 currOutTracklet->fY0err = tp.GetSigmaY2();
623 currOutTracklet->fZ0err = tp.GetSigmaZ2();
624 float h = -currOutTracklet->fPt * currOutTracklet->fPt;
625 currOutTracklet->fPterr = h * h * tp.GetSigma1Pt2();
626 h = 1. / TMath::Sqrt( 1 - snp * snp );
627 currOutTracklet->fPsierr = h * h * tp.GetSigmaSnp2();
628 currOutTracklet->fTglerr = tp.GetSigmaTgl2();
630 if ( par.TransportToX( clusterData.X( iLastHit ), .99 ) ) {
631 currOutTracklet->fLastX = par.GetX();
632 currOutTracklet->fLastY = par.GetY();
633 currOutTracklet->fLastZ = par.GetZ();
635 currOutTracklet->fLastX = clusterData.X( iLastHit );
636 currOutTracklet->fLastY = clusterData.Y( iLastHit );
637 currOutTracklet->fLastZ = clusterData.Z( iLastHit );
639 //if( currOutTracklet->fLastX<10. ) {
640 //HLTError("CA last point: hitxyz=%f,%f,%f, track=%f,%f,%f, tracklet=%f,%f,%f, nhits=%d",clusterData.X( iLastHit ),clusterData.Y( iLastHit],clusterData.Z( iLastHit],
641 //par.GetX(), par.GetY(),par.GetZ(),currOutTracklet->fLastX,currOutTracklet->fLastY ,currOutTracklet->fLastZ, t.NHits());
643 #ifdef INCLUDE_TPC_HOUGH
644 #ifdef ROWHOUGHPARAMS
645 currOutTracklet->fTrackID = 0;
646 currOutTracklet->fRowRange1 = clusterData.RowNumber( iFirstHit );
647 currOutTracklet->fRowRange2 = clusterData.RowNumber( iLastHit );
648 currOutTracklet->fSector = slice;
649 currOutTracklet->fPID = 211;
651 #endif // INCLUDE_TPC_HOUGH
654 currOutTracklet->fNPoints = t.NHits();
656 for ( int i = 0; i < t.NHits(); i++ ) {
657 currOutTracklet->fPointIDs[i] = clusterData.Id( fTracker->OutTrackHits()[t.FirstHitRef()+i] );
660 currOutTracklet = ( AliHLTTPCTrackSegmentData* )( ( Byte_t * )currOutTracklet + dSize );
662 outPtr->fTrackletCnt++;
665 } else { // default output type
667 mySize = fTracker->Output()->EstimateSize( fTracker->Output()->NTracks(),
668 fTracker->Output()->NTrackClusters() );
669 if ( mySize <= maxBufferSize ) {
670 const AliHLTUInt8_t* outputevent = reinterpret_cast<const AliHLTUInt8_t*>( fTracker->Output() );
671 for ( unsigned int i = 0; i < mySize; i++ ) outputPtr[i] = outputevent[i];
673 HLTWarning( "Output buffer size exceed (buffer size %d, current size %d), tracks are not stored", maxBufferSize, mySize );
680 AliHLTComponentBlockData bd;
684 bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( slice, slice, minPatch, maxPatch );
685 bd.fDataType = GetOutputDataType();
686 outputBlocks.push_back( bd );
692 fFullTime += timer.RealTime();
693 fRecoTime += timerReco.RealTime();
696 // Set log level to "Warning" for on-line system monitoring
697 int hz = ( int ) ( fFullTime > 1.e-10 ? fNEvents / fFullTime : 100000 );
698 int hz1 = ( int ) ( fRecoTime > 1.e-10 ? fNEvents / fRecoTime : 100000 );
699 HLTInfo( "CATracker slice %d: output %d tracks; input %d clusters, patches %d..%d, rows %d..%d; time: full %d / reco %d Hz",
700 slice, ntracks, nClustersTotal, minPatch, maxPatch, row[0], row[1], hz, hz1 );