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: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * Timm Steinbeck <timm@kip.uni-heidelberg.de> *
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 AliHLTTPCSliceTrackerComponent.cxx
21 @author Timm Steinbeck, Matthias Richter
23 @brief The TPC conformal mapping tracker component.
26 // see header file for class documentation
28 // refer to README to build package
30 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
36 #include "AliHLTTPCSliceTrackerComponent.h"
37 #include "AliHLTTPCTransform.h"
38 #include "AliHLTTPCConfMapper.h"
39 #include "AliHLTTPCVertex.h"
40 #include "AliHLTTPCVertexData.h"
41 #include "AliHLTTPCClusterDataFormat.h"
42 #include "AliHLTTPCTransform.h"
43 #include "AliHLTTPCTrackSegmentData.h"
44 #include "AliHLTTPCTrackArray.h"
45 #include "AliHLTTPCTrackletDataFormat.h"
46 #include "AliHLTTPCInterMerger.h"
47 #include "AliHLTTPCMemHandler.h"
48 #include "AliHLTTPCDefinitions.h"
49 //#include "AliHLTTPC.h"
53 // this is a global object used for automatic component registration, do not use this
54 AliHLTTPCSliceTrackerComponent gAliHLTTPCSliceTrackerComponent;
56 /** ROOT macro for the implementation of ROOT specific class methods */
57 ClassImp(AliHLTTPCSliceTrackerComponent)
59 AliHLTTPCSliceTrackerComponent::AliHLTTPCSliceTrackerComponent()
67 fnonvertextracking(kFALSE),
68 fmainvertextracking(kTRUE),
71 // see header file for class documentation
73 // refer to README to build package
75 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
80 AliHLTTPCSliceTrackerComponent::~AliHLTTPCSliceTrackerComponent()
82 // see header file for class documentation
85 // Public functions to implement AliHLTComponent's interface.
86 // These functions are required for the registration process
88 const char* AliHLTTPCSliceTrackerComponent::GetComponentID()
90 // see header file for class documentation
92 return "TPCSliceTracker";
95 void AliHLTTPCSliceTrackerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
97 // see header file for class documentation
99 list.push_back( AliHLTTPCDefinitions::fgkClustersDataType );
100 list.push_back( AliHLTTPCDefinitions::fgkVertexDataType );
103 AliHLTComponentDataType AliHLTTPCSliceTrackerComponent::GetOutputDataType()
105 // see header file for class documentation
106 return AliHLTTPCDefinitions::fgkTrackSegmentsDataType;
109 void AliHLTTPCSliceTrackerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
111 // see header file for class documentation
112 // XXX TODO: Find more realistic values.
114 inputMultiplier = 0.2;
117 AliHLTComponent* AliHLTTPCSliceTrackerComponent::Spawn()
119 // see header file for class documentation
120 return new AliHLTTPCSliceTrackerComponent;
123 void AliHLTTPCSliceTrackerComponent::SetTrackerParam(Int_t phiSegments, Int_t etaSegments,
124 Int_t trackletlength, Int_t tracklength,
125 Int_t rowscopetracklet, Int_t rowscopetrack,
126 Double_t minPtFit, Double_t maxangle,
127 Double_t goodDist, Double_t hitChi2Cut,
128 Double_t goodHitChi2, Double_t trackChi2Cut,
129 Int_t maxdist, Double_t maxphi,Double_t maxeta, bool /*vertexConstraints*/ )
131 // see header file for class documentation
132 //fTracker->SetClusterFinderParam( fXYClusterError, fZClusterError, kTRUE ); // ??
133 //Set parameters input to the tracker
134 //If no arguments are given, default parameters will be used
136 fTracker->SetNSegments(phiSegments,etaSegments);
137 fTracker->SetMaxDca(minPtFit);
138 // fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
140 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "==============================" );
142 if ( fmainvertextracking == kTRUE && fnonvertextracking == kFALSE){
143 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kTRUE);
144 fTracker->SetTrackletCuts(maxangle,goodDist,kTRUE);
146 fTracker->MainVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack, maxphi, maxeta);
147 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "MAINVERTEXTRACKING" );
149 else if ( fmainvertextracking == kTRUE && fnonvertextracking == kTRUE){
150 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kTRUE);
151 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kFALSE);
152 fTracker->SetTrackletCuts(maxangle,goodDist,kTRUE);
153 fTracker->SetTrackletCuts(maxangle,goodDist,kFALSE);
155 fTracker->MainVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack, maxphi, maxeta);
156 fTracker->NonVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack);
157 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "MAINVERTEXTRACKING - NONVERTEXTRACKING" );
159 else if ( fmainvertextracking == kFALSE && fnonvertextracking == kTRUE){
160 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kFALSE);
161 fTracker->SetTrackletCuts(maxangle,goodDist,kFALSE);
163 fTracker->NonVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack);
164 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "NONVERTEXTRACKING" );
167 //fTracker->SetParamDone(true);
168 /* Matthias 13.12.2006
169 * the global variable AliHLTTPCS::fgDoVertexFit has never been used so far
170 * and has always been kTRUE.
171 * In order to remove the AliHLTTPC class (which is the old steering class for
172 * HLT (TPC) tracking) from the compilation, this function can not be activated
173 * again. We have to think about a more elegant way to specify the parameters
174 * anyway. The following line was surely for some testing, but was never active
175 * in a tested release.
177 //AliHLTTPC::SetVertexFit( kFALSE );
179 fTracker->InitVolumes();
182 void AliHLTTPCSliceTrackerComponent::SetTrackerParam( bool doPP, int multiplicity, double bField )
184 // see header file for class documentation
185 AliHLTTPCTransform::SetBField( bField );
186 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f T\n", bField );
190 //tracker->SetClusterFinderParam(xyerror,zerror,kTRUE); // ??
191 /* the old setup used during TPC
192 SetTrackerParam( 50, 100, 3, 10,
195 5, 50, 50, 0.1, 0.1, kTRUE);
197 SetTrackerParam( 50, // phi_segments: Devide the space into phi_segments
198 100, // ets_segments: Devide the space into eta_segments
199 3, // trackletlength: Number of hits a tracklet has to have
200 50, // tracklength: Number of hits a track has to have
201 6, // rowscopetracklet: Search range of rows for a tracklet
202 6, // rowscopetrack: Search range of rows for a track
203 0, // min_pt_fit: Cut for moment fit, use:SetMaxDca(min_pt_fit)
204 AliHLTTPCTransform::Deg2Rad(10),
205 // maxangle: AliHLTTPCTransform::Deg2Rad(10), max angle for the three point look aheand
206 5, // goodDist: Threshold distancs between two hits when building tracklets
207 100, // hitChi2Cut: Max chi2 of added hit to track
208 5, // goodHitChi2: Stop looking for next hit to add if chi2 is less then goodHitChi2
209 50, // trackChi2Cut: Max chi2 for track after final fit
210 50, // maxdist: Maximum distance between two clusters when forming segments
211 0.1, // maxphi: Max phi difference for neighboring hits
212 0.1, // maxeta: Max eta difference for neighboring hits
213 kTRUE); // vertexConstrain: False if one want to look for secondary vertex track
217 int mults[] = { 1000, 2000, 4000, 8000 };
221 int multDist, tmpMultDist;
222 if ( multiplicity>mults[closestMult] )
223 multDist = multiplicity-mults[closestMult];
225 multDist = mults[closestMult]-multiplicity;
226 for ( i = 1; i < multCount; i++ )
228 if ( multiplicity>mults[i] )
229 tmpMultDist = multiplicity-mults[i];
231 tmpMultDist = mults[i]-multiplicity;
232 if ( tmpMultDist < multDist )
235 multDist = tmpMultDist;
239 double bfs[] = { 0.2, 0.4 };
242 double bfDist, tmpBFDist;
243 if ( bField>bfs[closestBf] )
244 bfDist = bField-bfs[closestBf];
246 bfDist = bfs[closestBf]-bField;
247 for ( i = 1; i < bfCount; i++ )
250 tmpBFDist = bField-bfs[i];
252 tmpBFDist = bfs[i]-bField;
253 if ( tmpBFDist < bfDist )
260 switch ( closestMult )
266 SetTrackerParam( 50, 100, 3, 10,
269 5, 50, 50, 0.1, 0.1, kTRUE );
272 SetTrackerParam( 50, 100, 3, 10,
275 5, 50, 50, 0.1, 0.1, kTRUE );
283 SetTrackerParam( 50, 100, 3, 10,
286 5, 20, 50, 0.1, 0.1, kTRUE );
289 SetTrackerParam( 50, 100, 3, 10,
292 5, 20, 50, 0.1, 0.1, kTRUE );
300 SetTrackerParam( 50, 100, 3, 10,
303 5, 10 , 50, 0.1, 0.1, kTRUE );
306 SetTrackerParam( 50, 100, 3, 10,
309 5, 10, 50, 0.1, 0.1, kTRUE );
317 SetTrackerParam( 50, 100, 3, 10,
320 5, 5, 50, 0.1, 0.1, kTRUE );
323 SetTrackerParam( 50, 100, 3, 10,
326 5, 5, 50, 0.1, 0.1, kTRUE );
331 // Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f\n", bfs[closestBf] );
332 // AliHLTTPCTransform::SetBField( bfs[closestBf] );
333 // AliHLTTPCTransform::SetBField( bField );
334 // Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f\n", bField );
340 int AliHLTTPCSliceTrackerComponent::DoInit( int argc, const char** argv )
342 // see header file for class documentation
343 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "DoInit", "DoInit()" );
345 if ( fTracker || fVertex )
347 fTracker = new AliHLTTPCConfMapper();
348 fVertex = new AliHLTTPCVertex();
351 fDoNonVertex = false;
352 Bool_t bDoMerger=kTRUE;
353 fMultiplicity = 4000;
361 if ( !strcmp( argv[i], "disable-merger" ) ){
367 if ( !strcmp( argv[i], "pp-run" ) )
373 if ( !strcmp( argv[i], "multiplicity" ) )
377 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Missing event multiplicity specifier." );
380 fMultiplicity = strtoul( argv[i+1], &cpErr, 0 );
383 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Cannot convert event multiplicity specifier '%s'.", argv[i+1] );
389 if ( !strcmp( argv[i], "bfield" ) )
393 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing B-field", "Missing B-field specifier." );
396 fBField = strtod( argv[i+1], &cpErr );
399 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Cannot convert B-field specifier '%s'.", argv[i+1] );
406 if ( !strcmp( argv[i], "nonvertextracking" ) ){
407 fnonvertextracking = kTRUE;
412 if ( !strcmp( argv[i], "mainvertextrackingoff" ) ){
413 fmainvertextracking = kFALSE;
418 if ( !strcmp( argv[i], "etarange" ) ){
420 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing Eta range", "Missing Eta-range specifiers." );
423 fEta[1] = strtod( argv[i+1], &cpErr );
425 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing Eta range", "Cannot convert Eta-range specifier '%s'.", argv[i+1] );
432 Logging(kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
436 // parameter for B=0 T
438 fnonvertextracking = kTRUE;
439 fmainvertextracking = kFALSE;
443 fpInterMerger = new AliHLTTPCInterMerger();
445 SetTrackerParam( fDoPP, fMultiplicity, fBField );
449 int AliHLTTPCSliceTrackerComponent::DoDeinit()
451 // see header file for class documentation
459 delete fpInterMerger;
465 int AliHLTTPCSliceTrackerComponent::DoEvent( const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks,
466 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
467 AliHLTUInt32_t& size, AliHLTComponentBlockDataList& outputBlocks )
469 // see header file for class documentation
470 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "DoEvent", "DoEvent()" );
471 if ( evtData.fBlockCnt<=0 )
473 Logging( kHLTLogWarning, "HLT::TPCSliceTracker::DoEvent", "DoEvent", "no blocks in event" );
476 const AliHLTComponentBlockData* iter = NULL;
478 AliHLTTPCClusterData* inPtrSP;
479 AliHLTTPCVertexData* inPtrV = NULL;
480 const AliHLTComponentBlockData* vertexIter=NULL;
481 AliHLTTPCTrackletData* outPtr;
482 AliHLTUInt8_t* outBPtr;
483 AliHLTUInt32_t vSize = 0;
484 UInt_t offset=0, mysize, tSize = 0;
486 Int_t slice=-1, patch=-1, row[2];
487 Int_t minPatch=INT_MAX, maxPatch = 0;
489 std::vector<Int_t> slices;
490 std::vector<Int_t>::iterator slIter, slEnd;
491 std::vector<unsigned> sliceCnts;
492 std::vector<unsigned>::iterator slCntIter;
493 Int_t vertexSlice=-1;
495 // Find min/max rows used in total and find and read out vertex if it is present
496 // also determine correct slice number, if multiple slice numbers are present in event
497 // (which should not happen in the first place) we use the one that occurs the most times
501 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
505 if(iter->fDataType!=AliHLTTPCDefinitions::fgkClustersDataType){
506 HLTDebug("Data block type is not of type AliHLTTPCDefinitions::fgkClustersDataType");
510 slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
512 slIter = slices.begin();
513 slEnd = slices.end();
514 slCntIter = sliceCnts.begin();
515 while ( slIter != slEnd )
517 if ( *slIter == slice )
527 slices.insert( slices.end(), slice );
528 sliceCnts.insert( sliceCnts.end(), 1 );
533 if ( iter->fDataType == AliHLTTPCDefinitions::fgkVertexDataType )
535 inPtrV = (AliHLTTPCVertexData*)(iter->fPtr);
538 fVertex->Read( inPtrV );
541 if ( iter->fDataType == AliHLTTPCDefinitions::fgkClustersDataType )
543 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
544 if ( minPatch>patch )
547 row[0] = AliHLTTPCTransform::GetFirstRow( patch );
549 if ( maxPatch<patch )
552 row[1] = AliHLTTPCTransform::GetLastRow( patch );
557 // Determine slice number to really use.
558 if ( slices.size()>1 )
560 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
561 "Multiple slice numbers found in event 0x%08lX (%lu). Determining maximum occuring slice number...",
562 evtData.fEventID, evtData.fEventID );
563 unsigned maxCntSlice=0;
564 slIter = slices.begin();
565 slEnd = slices.end();
566 slCntIter = sliceCnts.begin();
567 while ( slIter != slEnd )
569 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
570 "Slice %lu found %lu times.", *slIter, *slCntIter );
571 if ( maxCntSlice<*slCntIter )
573 maxCntSlice = *slCntIter;
579 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
580 "Using slice %lu.", slice );
582 else if ( slices.size()>0 )
584 slice = *(slices.begin());
591 if ( vertexSlice != slice )
593 // multiple vertex blocks in event and we used the wrong one...
595 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
598 if ( iter->fDataType == AliHLTTPCDefinitions::fgkVertexDataType && slice==AliHLTTPCDefinitions::GetMinSliceNr( *iter ) )
600 inPtrV = (AliHLTTPCVertexData*)(iter->fPtr);
603 fVertex->Read( inPtrV );
609 fTracker->InitSector( slice, row, fEta );
610 fTracker->SetVertex(fVertex);
613 std::vector<unsigned long> patchIndices;
614 std::vector<unsigned long>::iterator pIter, pEnd;
615 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
619 if ( iter->fDataType == AliHLTTPCDefinitions::fgkClustersDataType && slice==AliHLTTPCDefinitions::GetMinSliceNr( *iter ) )
621 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
622 pIter = patchIndices.begin();
623 pEnd = patchIndices.end();
624 while ( pIter!=pEnd && AliHLTTPCDefinitions::GetMinSliceNr( blocks[*pIter] ) < patch )
626 patchIndices.insert( pIter, ndx );
629 pIter = patchIndices.begin();
630 pEnd = patchIndices.end();
631 while ( pIter!=pEnd )
636 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
637 inPtrSP = (AliHLTTPCClusterData*)(iter->fPtr);
639 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Reading hits",
640 "Reading hits for slice %d - patch %d", slice, patch );
641 fTracker->ReadHits( inPtrSP->fSpacePointCnt, inPtrSP->fSpacePoints );
645 outPtr = (AliHLTTPCTrackletData*)(outBPtr);
647 if ( fmainvertextracking == kTRUE && fnonvertextracking == kFALSE){
648 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---MAINVERTEXTRACKING---");
649 fTracker->MainVertexTrackingA();
650 fTracker->MainVertexTrackingB();
651 fTracker->FillTracks();
653 else if ( fmainvertextracking == kTRUE && fnonvertextracking == kTRUE){
654 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---MAINVERTEXTRACKING---");
655 fTracker->MainVertexTrackingA();
656 fTracker->MainVertexTrackingB();
657 fTracker->FillTracks();
658 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---NONVERTEXTRACKING---");
659 fTracker->NonVertexTracking();
661 else if ( fmainvertextracking == kFALSE && fnonvertextracking == kTRUE){
662 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---NONVERTEXTRACKING---");
663 fTracker->NonVertexTracking();
664 fTracker->FillTracks();
669 AliHLTTPCMemHandler memory;
670 AliHLTTPCTrackSegmentData *trackdata0 =
671 (AliHLTTPCTrackSegmentData *) memory.Allocate(fTracker->GetTracks());
672 memory.TrackArray2Memory(ntracks0,trackdata0,fTracker->GetTracks());
673 fpInterMerger->Reset();
674 fpInterMerger->Init(row,patch);
675 fpInterMerger->FillTracks(ntracks0,trackdata0);
676 fpInterMerger->Merge();
679 AliHLTTPCTrackArray* pArray=fTracker->GetTracks();
680 mysize = pArray->WriteTracks( ntracks0, outPtr->fTracklets );
681 outPtr->fTrackletCnt = ntracks0;
683 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracks",
684 "Input: Number of tracks: %lu Slice/MinPatch/MaxPatch/RowMin/RowMax: %lu/%lu/%lu/%lu/%lu.",
685 ntracks0, slice, minPatch, maxPatch, row[0], row[1] );
689 tSize += mysize+sizeof(AliHLTTPCTrackletData);
690 outBPtr += mysize+sizeof(AliHLTTPCTrackletData);
692 AliHLTComponentBlockData bd;
696 bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( slice, slice, minPatch, maxPatch );
697 outputBlocks.push_back( bd );
699 #ifdef FORWARD_VERTEX_BLOCK
702 // Copy the descriptor block for the vertex information.
704 outputBlocks.push_back( bd );
706 #endif // FORWARD_VERTEX_BLOCK
712 void AliHLTTPCSliceTrackerComponent::SetTrackerParam1()
714 // see header file for class documentation
715 SetTrackerParam( 10, 20, 5, 10, 2,2,
717 50, 100, 50, 0.1, 0.1,