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.
30 #include "AliHLTTPCSliceTrackerComponent.h"
31 #include "AliHLTTPCTransform.h"
32 #include "AliHLTTPCConfMapper.h"
33 #include "AliHLTTPCVertex.h"
34 #include "AliHLTTPCVertexData.h"
35 #include "AliHLTTPCClusterDataFormat.h"
36 #include "AliHLTTPCTransform.h"
37 #include "AliHLTTPCTrackSegmentData.h"
38 #include "AliHLTTPCTrackArray.h"
39 #include "AliHLTTPCTrackletDataFormat.h"
40 #include "AliHLTTPCInterMerger.h"
41 #include "AliHLTTPCMemHandler.h"
42 #include "AliHLTTPCDefinitions.h"
43 //#include "AliHLTTPC.h"
47 // this is a global object used for automatic component registration, do not use this
48 AliHLTTPCSliceTrackerComponent gAliHLTTPCSliceTrackerComponent;
50 /** ROOT macro for the implementation of ROOT specific class methods */
51 ClassImp(AliHLTTPCSliceTrackerComponent)
53 AliHLTTPCSliceTrackerComponent::AliHLTTPCSliceTrackerComponent()
61 fnonvertextracking(kFALSE),
62 fmainvertextracking(kTRUE),
65 // see header file for class documentation
67 // refer to README to build package
69 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
74 AliHLTTPCSliceTrackerComponent::AliHLTTPCSliceTrackerComponent(const AliHLTTPCSliceTrackerComponent& src)
82 fnonvertextracking(kFALSE),
83 fmainvertextracking(kTRUE),
86 // see header file for class documentation
87 HLTFatal("copy constructor untested");
90 AliHLTTPCSliceTrackerComponent& AliHLTTPCSliceTrackerComponent::operator=(const AliHLTTPCSliceTrackerComponent& src)
92 // see header file for class documentation
93 HLTFatal("assignment operator untested");
97 AliHLTTPCSliceTrackerComponent::~AliHLTTPCSliceTrackerComponent()
99 // see header file for class documentation
102 // Public functions to implement AliHLTComponent's interface.
103 // These functions are required for the registration process
105 const char* AliHLTTPCSliceTrackerComponent::GetComponentID()
107 // see header file for class documentation
109 return "TPCSliceTracker";
112 void AliHLTTPCSliceTrackerComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
114 // see header file for class documentation
116 list.push_back( AliHLTTPCDefinitions::fgkClustersDataType );
117 list.push_back( AliHLTTPCDefinitions::fgkVertexDataType );
120 AliHLTComponentDataType AliHLTTPCSliceTrackerComponent::GetOutputDataType()
122 // see header file for class documentation
123 return AliHLTTPCDefinitions::fgkTrackSegmentsDataType;
126 void AliHLTTPCSliceTrackerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
128 // see header file for class documentation
129 // XXX TODO: Find more realistic values.
131 inputMultiplier = 0.2;
134 AliHLTComponent* AliHLTTPCSliceTrackerComponent::Spawn()
136 // see header file for class documentation
137 return new AliHLTTPCSliceTrackerComponent;
140 void AliHLTTPCSliceTrackerComponent::SetTrackerParam(Int_t phiSegments, Int_t etaSegments,
141 Int_t trackletlength, Int_t tracklength,
142 Int_t rowscopetracklet, Int_t rowscopetrack,
143 Double_t minPtFit, Double_t maxangle,
144 Double_t goodDist, Double_t hitChi2Cut,
145 Double_t goodHitChi2, Double_t trackChi2Cut,
146 Int_t maxdist, Double_t maxphi,Double_t maxeta, bool vertexConstraints )
148 // see header file for class documentation
149 //fTracker->SetClusterFinderParam( fXYClusterError, fZClusterError, kTRUE ); // ??
150 //Set parameters input to the tracker
151 //If no arguments are given, default parameters will be used
153 fTracker->SetNSegments(phiSegments,etaSegments);
154 fTracker->SetMaxDca(minPtFit);
155 // fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
157 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "==============================" );
159 if ( fmainvertextracking == kTRUE && fnonvertextracking == kFALSE){
160 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kTRUE);
161 fTracker->SetTrackletCuts(maxangle,goodDist,kTRUE);
163 fTracker->MainVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack, maxphi, maxeta);
164 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "MAINVERTEXTRACKING" );
166 else if ( fmainvertextracking == kTRUE && fnonvertextracking == kTRUE){
167 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kTRUE);
168 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kFALSE);
169 fTracker->SetTrackletCuts(maxangle,goodDist,kTRUE);
170 fTracker->SetTrackletCuts(maxangle,goodDist,kFALSE);
172 fTracker->MainVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack, maxphi, maxeta);
173 fTracker->NonVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack);
174 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "MAINVERTEXTRACKING - NONVERTEXTRACKING" );
176 else if ( fmainvertextracking == kFALSE && fnonvertextracking == kTRUE){
177 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kFALSE);
178 fTracker->SetTrackletCuts(maxangle,goodDist,kFALSE);
180 fTracker->NonVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack);
181 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "NONVERTEXTRACKING" );
184 //fTracker->SetParamDone(true);
185 /* Matthias 13.12.2006
186 * the global variable AliHLTTPCS::fgDoVertexFit has never been used so far
187 * and has always been kTRUE.
188 * In order to remove the AliHLTTPC class (which is the old steering class for
189 * HLT (TPC) tracking) from the compilation, this function can not be activated
190 * again. We have to think about a more elegant way to specify the parameters
191 * anyway. The following line was surely for some testing, but was never active
192 * in a tested release.
194 //AliHLTTPC::SetVertexFit( kFALSE );
196 fTracker->InitVolumes();
199 void AliHLTTPCSliceTrackerComponent::SetTrackerParam( bool doPP, int multiplicity, double bField )
201 AliHLTTPCTransform::SetBField( bField );
202 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f T\n", bField );
206 //tracker->SetClusterFinderParam(xyerror,zerror,kTRUE); // ??
207 /* the old setup used during TPC
208 SetTrackerParam( 50, 100, 3, 10,
211 5, 50, 50, 0.1, 0.1, kTRUE);
213 SetTrackerParam( 50, // phi_segments: Devide the space into phi_segments
214 100, // ets_segments: Devide the space into eta_segments
215 3, // trackletlength: Number of hits a tracklet has to have
216 50, // tracklength: Number of hits a track has to have
217 60, // tracklength: Number of hits a track has to have
218 6, // rowscopetracklet: Search range of rows for a tracklet
219 6, // rowscopetrack: Search range of rows for a track
220 0, // min_pt_fit: Cut for moment fit, use:SetMaxDca(min_pt_fit)
221 AliHLTTPCTransform::Deg2Rad(10),
222 // maxangle: AliHLTTPCTransform::Deg2Rad(10), max angle for the three point look aheand
223 5, // goodDist: Threshold distancs between two hits when building tracklets
224 100, // hitChi2Cut: Max chi2 of added hit to track
225 5, // goodHitChi2: Stop looking for next hit to add if chi2 is less then goodHitChi2
226 50, // trackChi2Cut: Max chi2 for track after final fit
227 50, // maxdist: Maximum distance between two clusters when forming segments
228 0.1, // maxphi: Max phi difference for neighboring hits
229 0.1, // maxeta: Max eta difference for neighboring hits
230 kTRUE); // vertexConstrain: False if one want to look for secondary vertex track
234 int mults[] = { 1000, 2000, 4000, 8000 };
238 int multDist, tmpMultDist;
239 if ( multiplicity>mults[closestMult] )
240 multDist = multiplicity-mults[closestMult];
242 multDist = mults[closestMult]-multiplicity;
243 for ( i = 1; i < multCount; i++ )
245 if ( multiplicity>mults[i] )
246 tmpMultDist = multiplicity-mults[i];
248 tmpMultDist = mults[i]-multiplicity;
249 if ( tmpMultDist < multDist )
252 multDist = tmpMultDist;
256 double bfs[] = { 0.2, 0.4 };
259 double bfDist, tmpBFDist;
260 if ( bField>bfs[closestBf] )
261 bfDist = bField-bfs[closestBf];
263 bfDist = bfs[closestBf]-bField;
264 for ( i = 1; i < bfCount; i++ )
267 tmpBFDist = bField-bfs[i];
269 tmpBFDist = bfs[i]-bField;
270 if ( tmpBFDist < bfDist )
277 switch ( closestMult )
283 SetTrackerParam( 50, 100, 3, 10,
286 5, 50, 50, 0.1, 0.1, kTRUE );
289 SetTrackerParam( 50, 100, 3, 10,
292 5, 50, 50, 0.1, 0.1, kTRUE );
300 SetTrackerParam( 50, 100, 3, 10,
303 5, 20, 50, 0.1, 0.1, kTRUE );
306 SetTrackerParam( 50, 100, 3, 10,
309 5, 20, 50, 0.1, 0.1, kTRUE );
317 SetTrackerParam( 50, 100, 3, 10,
320 5, 10 , 50, 0.1, 0.1, kTRUE );
323 SetTrackerParam( 50, 100, 3, 10,
326 5, 10, 50, 0.1, 0.1, kTRUE );
334 SetTrackerParam( 50, 100, 3, 10,
337 5, 5, 50, 0.1, 0.1, kTRUE );
340 SetTrackerParam( 50, 100, 3, 10,
343 5, 5, 50, 0.1, 0.1, kTRUE );
348 // Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f\n", bfs[closestBf] );
349 // AliHLTTPCTransform::SetBField( bfs[closestBf] );
350 // AliHLTTPCTransform::SetBField( bField );
351 // Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f\n", bField );
357 int AliHLTTPCSliceTrackerComponent::DoInit( int argc, const char** argv )
359 // see header file for class documentation
360 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "DoInit", "DoInit()" );
362 if ( fTracker || fVertex )
364 fTracker = new AliHLTTPCConfMapper();
365 fVertex = new AliHLTTPCVertex();
368 fDoNonVertex = false;
369 Bool_t bDoMerger=kTRUE;
370 fMultiplicity = 4000;
378 if ( !strcmp( argv[i], "disable-merger" ) ){
384 if ( !strcmp( argv[i], "pp-run" ) )
390 if ( !strcmp( argv[i], "multiplicity" ) )
394 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Missing event multiplicity specifier." );
397 fMultiplicity = strtoul( argv[i+1], &cpErr, 0 );
400 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Cannot convert event multiplicity specifier '%s'.", argv[i+1] );
406 if ( !strcmp( argv[i], "bfield" ) )
410 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing B-field", "Missing B-field specifier." );
413 fBField = strtod( argv[i+1], &cpErr );
416 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Cannot convert B-field specifier '%s'.", argv[i+1] );
423 if ( !strcmp( argv[i], "nonvertextracking" ) ){
424 fnonvertextracking = kTRUE;
429 if ( !strcmp( argv[i], "mainvertextrackingoff" ) ){
430 fmainvertextracking = kFALSE;
435 if ( !strcmp( argv[i], "etarange" ) ){
437 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing Eta range", "Missing Eta-range specifiers." );
440 fEta[1] = strtod( argv[i+1], &cpErr );
442 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing Eta range", "Cannot convert Eta-range specifier '%s'.", argv[i+1] );
449 Logging(kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
453 // parameter for B=0 T
455 fnonvertextracking = kTRUE;
456 fmainvertextracking = kFALSE;
460 fpInterMerger = new AliHLTTPCInterMerger();
462 SetTrackerParam( fDoPP, fMultiplicity, fBField );
466 int AliHLTTPCSliceTrackerComponent::DoDeinit()
468 // see header file for class documentation
476 delete fpInterMerger;
482 int AliHLTTPCSliceTrackerComponent::DoEvent( const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks,
483 AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr,
484 AliHLTUInt32_t& size, vector<AliHLTComponentBlockData>& outputBlocks )
486 // see header file for class documentation
487 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "DoEvent", "DoEvent()" );
488 if ( evtData.fBlockCnt<=0 )
490 Logging( kHLTLogWarning, "HLT::TPCSliceTracker::DoEvent", "DoEvent", "no blocks in event" );
493 const AliHLTComponentBlockData* iter = NULL;
495 AliHLTTPCClusterData* inPtrSP;
496 AliHLTTPCVertexData* inPtrV = NULL;
497 const AliHLTComponentBlockData* vertexIter=NULL;
498 AliHLTTPCTrackletData* outPtr;
499 AliHLTUInt8_t* outBPtr;
500 AliHLTUInt32_t vSize = 0;
501 UInt_t offset=0, mysize, tSize = 0;
503 Int_t slice=-1, patch=-1, row[2];
504 Int_t minPatch=INT_MAX, maxPatch = 0;
506 std::vector<Int_t> slices;
507 std::vector<Int_t>::iterator slIter, slEnd;
508 std::vector<unsigned> sliceCnts;
509 std::vector<unsigned>::iterator slCntIter;
510 Int_t vertexSlice=-1;
512 // Find min/max rows used in total and find and read out vertex if it is present
513 // also determine correct slice number, if multiple slice numbers are present in event
514 // (which should not happen in the first place) we use the one that occurs the most times
518 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
522 slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
524 slIter = slices.begin();
525 slEnd = slices.end();
526 slCntIter = sliceCnts.begin();
527 while ( slIter != slEnd )
529 if ( *slIter == slice )
539 slices.insert( slices.end(), slice );
540 sliceCnts.insert( sliceCnts.end(), 1 );
545 if ( iter->fDataType == AliHLTTPCDefinitions::fgkVertexDataType )
547 inPtrV = (AliHLTTPCVertexData*)(iter->fPtr);
550 fVertex->Read( inPtrV );
553 if ( iter->fDataType == AliHLTTPCDefinitions::fgkClustersDataType )
555 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
556 if ( minPatch>patch )
559 row[0] = AliHLTTPCTransform::GetFirstRow( patch );
561 if ( maxPatch<patch )
564 row[1] = AliHLTTPCTransform::GetLastRow( patch );
569 // Determine slice number to really use.
570 if ( slices.size()>1 )
572 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
573 "Multiple slice numbers found in event 0x%08lX (%lu). Determining maximum occuring slice number...",
574 evtData.fEventID, evtData.fEventID );
575 unsigned maxCntSlice=0;
576 slIter = slices.begin();
577 slEnd = slices.end();
578 slCntIter = sliceCnts.begin();
579 while ( slIter != slEnd )
581 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
582 "Slice %lu found %lu times.", *slIter, *slCntIter );
583 if ( maxCntSlice<*slCntIter )
585 maxCntSlice = *slCntIter;
591 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
592 "Using slice %lu.", slice );
594 else if ( slices.size()>0 )
596 slice = *(slices.begin());
603 if ( vertexSlice != slice )
605 // multiple vertex blocks in event and we used the wrong one...
607 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
610 if ( iter->fDataType == AliHLTTPCDefinitions::fgkVertexDataType && slice==AliHLTTPCDefinitions::GetMinSliceNr( *iter ) )
612 inPtrV = (AliHLTTPCVertexData*)(iter->fPtr);
615 fVertex->Read( inPtrV );
621 fTracker->InitSector( slice, row, fEta );
622 fTracker->SetVertex(fVertex);
625 std::vector<unsigned long> patchIndices;
626 std::vector<unsigned long>::iterator pIter, pEnd;
627 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
631 if ( iter->fDataType == AliHLTTPCDefinitions::fgkClustersDataType && slice==AliHLTTPCDefinitions::GetMinSliceNr( *iter ) )
633 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
634 pIter = patchIndices.begin();
635 pEnd = patchIndices.end();
636 while ( pIter!=pEnd && AliHLTTPCDefinitions::GetMinSliceNr( blocks[*pIter] ) < patch )
638 patchIndices.insert( pIter, ndx );
641 pIter = patchIndices.begin();
642 pEnd = patchIndices.end();
643 while ( pIter!=pEnd )
648 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
649 inPtrSP = (AliHLTTPCClusterData*)(iter->fPtr);
651 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Reading hits",
652 "Reading hits for slice %d - patch %d", slice, patch );
653 fTracker->ReadHits( inPtrSP->fSpacePointCnt, inPtrSP->fSpacePoints );
657 outPtr = (AliHLTTPCTrackletData*)(outBPtr);
659 if ( fmainvertextracking == kTRUE && fnonvertextracking == kFALSE){
660 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---MAINVERTEXTRACKING---");
661 fTracker->MainVertexTrackingA();
662 fTracker->MainVertexTrackingB();
663 fTracker->FillTracks();
665 else if ( fmainvertextracking == kTRUE && fnonvertextracking == kTRUE){
666 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---MAINVERTEXTRACKING---");
667 fTracker->MainVertexTrackingA();
668 fTracker->MainVertexTrackingB();
669 fTracker->FillTracks();
670 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---NONVERTEXTRACKING---");
671 fTracker->NonVertexTracking();
673 else if ( fmainvertextracking == kFALSE && fnonvertextracking == kTRUE){
674 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---NONVERTEXTRACKING---");
675 fTracker->NonVertexTracking();
676 fTracker->FillTracks();
681 AliHLTTPCMemHandler memory;
682 AliHLTTPCTrackSegmentData *trackdata0 =
683 (AliHLTTPCTrackSegmentData *) memory.Allocate(fTracker->GetTracks());
684 memory.TrackArray2Memory(ntracks0,trackdata0,fTracker->GetTracks());
685 fpInterMerger->Reset();
686 fpInterMerger->Init(row,patch);
687 fpInterMerger->FillTracks(ntracks0,trackdata0);
688 fpInterMerger->Merge();
691 AliHLTTPCTrackArray* pArray=fTracker->GetTracks();
692 mysize = pArray->WriteTracks( ntracks0, outPtr->fTracklets );
693 outPtr->fTrackletCnt = ntracks0;
695 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracks",
696 "Input: Number of tracks: %lu Slice/MinPatch/MaxPatch/RowMin/RowMax: %lu/%lu/%lu/%lu/%lu.",
697 ntracks0, slice, minPatch, maxPatch, row[0], row[1] );
699 tSize += mysize+sizeof(AliHLTTPCTrackletData);
700 outBPtr += mysize+sizeof(AliHLTTPCTrackletData);
702 AliHLTComponentBlockData bd;
706 bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( slice, slice, minPatch, maxPatch );
707 outputBlocks.push_back( bd );
709 #ifdef FORWARD_VERTEX_BLOCK
712 // Copy the descriptor block for the vertex information.
714 outputBlocks.push_back( bd );
716 #endif // FORWARD_VERTEX_BLOCK
722 void AliHLTTPCSliceTrackerComponent::SetTrackerParam1()
724 SetTrackerParam( 10, 20, 5, 10, 2,2,
726 50, 100, 50, 0.1, 0.1,