3 /**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
6 * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 * Timm Steinbeck <timm@kip.uni-heidelberg.de> *
8 * for The ALICE Off-line 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. *
17 **************************************************************************/
19 /** @file AliHLTTPCSliceTrackerComponent.cxx
20 @author Timm Steinbeck, Matthias Richter
22 @brief The TPC conformal mapping tracker component.
29 #include "AliHLTTPCSliceTrackerComponent.h"
30 #include "AliHLTTPCTransform.h"
31 #include "AliHLTTPCConfMapper.h"
32 #include "AliHLTTPCVertex.h"
33 #include "AliHLTTPCSpacePointData.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 "AliHLTTPC.h"
46 // this is a global object used for automatic component registration, do not use this
47 AliHLTTPCSliceTrackerComponent gAliHLTTPCSliceTrackerComponent;
49 ClassImp(AliHLTTPCSliceTrackerComponent)
51 AliHLTTPCSliceTrackerComponent::AliHLTTPCSliceTrackerComponent()
59 // BEGINN ############################################## MODIFIY JMT
60 fnonvertextracking(kFALSE),
61 fmainvertextracking(kTRUE),
62 // END ################################################# MODIFIY JMT
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 // BEGINN ############################################## MODIFIY JMT
83 fnonvertextracking(kFALSE),
84 fmainvertextracking(kTRUE),
85 // END ################################################# MODIFIY JMT
88 // see header file for class documentation
89 HLTFatal("copy constructor untested");
92 AliHLTTPCSliceTrackerComponent& AliHLTTPCSliceTrackerComponent::operator=(const AliHLTTPCSliceTrackerComponent& src)
94 // see header file for class documentation
95 HLTFatal("assignment operator untested");
99 AliHLTTPCSliceTrackerComponent::~AliHLTTPCSliceTrackerComponent()
103 // Public functions to implement AliHLTComponent's interface.
104 // These functions are required for the registration process
106 const char* AliHLTTPCSliceTrackerComponent::GetComponentID()
109 return "TPCSliceTracker";
112 void AliHLTTPCSliceTrackerComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
115 list.push_back( AliHLTTPCDefinitions::gkClustersDataType );
116 list.push_back( AliHLTTPCDefinitions::gkVertexDataType );
119 AliHLTComponentDataType AliHLTTPCSliceTrackerComponent::GetOutputDataType()
121 return AliHLTTPCDefinitions::gkTrackSegmentsDataType;
124 void AliHLTTPCSliceTrackerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
126 // XXX TODO: Find more realistic values.
128 inputMultiplier = 0.2;
131 AliHLTComponent* AliHLTTPCSliceTrackerComponent::Spawn()
133 return new AliHLTTPCSliceTrackerComponent;
136 void AliHLTTPCSliceTrackerComponent::SetTrackerParam(Int_t phiSegments, Int_t etaSegments,
137 Int_t trackletlength, Int_t tracklength,
138 Int_t rowscopetracklet, Int_t rowscopetrack,
139 Double_t minPtFit, Double_t maxangle,
140 Double_t goodDist, Double_t hitChi2Cut,
141 Double_t goodHitChi2, Double_t trackChi2Cut,
142 Int_t maxdist, Double_t maxphi,Double_t maxeta, bool vertexConstraints )
144 //fTracker->SetClusterFinderParam( fXYClusterError, fZClusterError, kTRUE ); // ??
145 //Set parameters input to the tracker
146 //If no arguments are given, default parameters will be used
148 fTracker->SetNSegments(phiSegments,etaSegments);
149 fTracker->SetMaxDca(minPtFit);
150 // fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
152 // BEGINN ############################################## MODIFIY JMT
154 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "==============================" );
156 if ( fmainvertextracking == kTRUE && fnonvertextracking == kFALSE){
157 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kTRUE);
158 fTracker->SetTrackletCuts(maxangle,goodDist,kTRUE);
160 fTracker->MainVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack, maxphi, maxeta);
161 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "MAINVERTEXTRACKING" );
163 else if ( fmainvertextracking == kTRUE && fnonvertextracking == kTRUE){
164 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kTRUE);
165 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kFALSE);
166 fTracker->SetTrackletCuts(maxangle,goodDist,kTRUE);
167 fTracker->SetTrackletCuts(maxangle,goodDist,kFALSE);
169 fTracker->MainVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack, maxphi, maxeta);
170 fTracker->NonVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack);
171 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "MAINVERTEXTRACKING - NONVERTEXTRACKING" );
173 else if ( fmainvertextracking == kFALSE && fnonvertextracking == kTRUE){
174 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kFALSE);
175 fTracker->SetTrackletCuts(maxangle,goodDist,kFALSE);
177 fTracker->NonVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack);
178 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "NONVERTEXTRACKING" );
181 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,vertexConstraints);
182 fTracker->SetTrackletCuts(maxangle,goodDist,vertexConstraints);
184 if( vertexConstraints )
185 fTracker->MainVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack, maxphi, maxeta);
187 fTracker->NonVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack);
189 // END ################################################# MODIFIY JMT
191 //fTracker->SetParamDone(true);
192 /* Matthias 13.12.2006
193 * the global variable AliHLTTPCS::fgDoVertexFit has never been used so far
194 * and has always been kTRUE.
195 * In order to remove the AliHLTTPC class (which is the old steering class for
196 * HLT (TPC) tracking) from the compilation, this function can not be activated
197 * again. We have to think about a more elegant way to specify the parameters
198 * anyway. The following line was surely for some testing, but was never active
199 * in a tested release.
201 //AliHLTTPC::SetVertexFit( kFALSE );
203 fTracker->InitVolumes();
206 void AliHLTTPCSliceTrackerComponent::SetTrackerParam( bool doPP, int multiplicity, double bField )
208 AliHLTTPCTransform::SetBField( bField );
209 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f T\n", bField );
213 //tracker->SetClusterFinderParam(xyerror,zerror,kTRUE); // ??
214 /* the old setup used during TPC
215 SetTrackerParam( 50, 100, 3, 10,
218 5, 50, 50, 0.1, 0.1, kTRUE);
220 SetTrackerParam( 50, // phi_segments: Devide the space into phi_segments
221 100, // ets_segments: Devide the space into eta_segments
222 3, // trackletlength: Number of hits a tracklet has to have
223 10, // tracklength: Number of hits a track has to have
224 6, // rowscopetracklet: Search range of rows for a tracklet
225 6, // rowscopetrack: Search range of rows for a track
226 0, // min_pt_fit: Cut for moment fit, use:SetMaxDca(min_pt_fit)
227 AliHLTTPCTransform::Deg2Rad(10),
228 // maxangle: AliHLTTPCTransform::Deg2Rad(10), max angle for the three point look aheand
229 5, // goodDist: Threshold distancs between two hits when building tracklets
230 100, // hitChi2Cut: Max chi2 of added hit to track
231 5, // goodHitChi2: Stop looking for next hit to add if chi2 is less then goodHitChi2
232 50, // trackChi2Cut: Max chi2 for track after final fit
233 50, // maxdist: Maximum distance between two clusters when forming segments
234 0.1, // maxphi: Max phi difference for neighboring hits
235 0.1, // maxeta: Max eta difference for neighboring hits
236 kTRUE); // vertexConstrain: False if one want to look for secondary vertex track
240 int mults[] = { 1000, 2000, 4000, 8000 };
244 int multDist, tmpMultDist;
245 if ( multiplicity>mults[closestMult] )
246 multDist = multiplicity-mults[closestMult];
248 multDist = mults[closestMult]-multiplicity;
249 for ( i = 1; i < multCount; i++ )
251 if ( multiplicity>mults[i] )
252 tmpMultDist = multiplicity-mults[i];
254 tmpMultDist = mults[i]-multiplicity;
255 if ( tmpMultDist < multDist )
258 multDist = tmpMultDist;
262 double bfs[] = { 0.2, 0.4 };
265 double bfDist, tmpBFDist;
266 if ( bField>bfs[closestBf] )
267 bfDist = bField-bfs[closestBf];
269 bfDist = bfs[closestBf]-bField;
270 for ( i = 1; i < bfCount; i++ )
273 tmpBFDist = bField-bfs[i];
275 tmpBFDist = bfs[i]-bField;
276 if ( tmpBFDist < bfDist )
283 switch ( closestMult )
289 SetTrackerParam( 50, 100, 3, 10,
292 5, 50, 50, 0.1, 0.1, kTRUE );
295 SetTrackerParam( 50, 100, 3, 10,
298 5, 50, 50, 0.1, 0.1, kTRUE );
306 SetTrackerParam( 50, 100, 3, 10,
309 5, 20, 50, 0.1, 0.1, kTRUE );
312 SetTrackerParam( 50, 100, 3, 10,
315 5, 20, 50, 0.1, 0.1, kTRUE );
323 SetTrackerParam( 50, 100, 3, 10,
326 5, 10 , 50, 0.1, 0.1, kTRUE );
329 SetTrackerParam( 50, 100, 3, 10,
332 5, 10, 50, 0.1, 0.1, kTRUE );
340 SetTrackerParam( 50, 100, 3, 10,
343 5, 5, 50, 0.1, 0.1, kTRUE );
346 SetTrackerParam( 50, 100, 3, 10,
349 5, 5, 50, 0.1, 0.1, kTRUE );
354 // Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f\n", bfs[closestBf] );
355 // AliHLTTPCTransform::SetBField( bfs[closestBf] );
356 // AliHLTTPCTransform::SetBField( bField );
357 // Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f\n", bField );
363 int AliHLTTPCSliceTrackerComponent::DoInit( int argc, const char** argv )
365 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "DoInit", "DoInit()" );
367 if ( fTracker || fVertex )
369 fTracker = new AliHLTTPCConfMapper();
370 fVertex = new AliHLTTPCVertex();
373 fDoNonVertex = false;
374 Bool_t bDoMerger=kTRUE;
375 fMultiplicity = 4000;
383 if ( !strcmp( argv[i], "disable-merger" ) ){
389 if ( !strcmp( argv[i], "pp-run" ) )
395 if ( !strcmp( argv[i], "multiplicity" ) )
399 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Missing event multiplicity specifier." );
402 fMultiplicity = strtoul( argv[i+1], &cpErr, 0 );
405 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Cannot convert event multiplicity specifier '%s'.", argv[i+1] );
411 if ( !strcmp( argv[i], "bfield" ) )
415 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing B-field", "Missing B-field specifier." );
418 fBField = strtod( argv[i+1], &cpErr );
421 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Cannot convert B-field specifier '%s'.", argv[i+1] );
428 // BEGINN ############################################## MODIFIY JMT
429 if ( !strcmp( argv[i], "nonvertextracking" ) ){
430 fnonvertextracking = kTRUE;
435 if ( !strcmp( argv[i], "mainvertextrackingoff" ) ){
436 fmainvertextracking = kFALSE;
441 if ( !strcmp( argv[i], "etarange" ) ){
443 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing Eta range", "Missing Eta-range specifiers." );
446 fEta[1] = strtod( argv[i+1], &cpErr );
448 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing Eta range", "Cannot convert Eta-range specifier '%s'.", argv[i+1] );
455 // END ################################################# MODIFIY JMT
456 Logging(kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
459 // #### -B0-CHANGE-START == JMT
461 // parameter for B=0 T
463 fnonvertextracking = kTRUE;
464 fmainvertextracking = kFALSE;
466 // #### -B0-CHANGE-END == JMT
469 fpInterMerger = new AliHLTTPCInterMerger();
471 SetTrackerParam( fDoPP, fMultiplicity, fBField );
475 int AliHLTTPCSliceTrackerComponent::DoDeinit()
484 delete fpInterMerger;
490 int AliHLTTPCSliceTrackerComponent::DoEvent( const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks,
491 AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr,
492 AliHLTUInt32_t& size, vector<AliHLTComponentBlockData>& outputBlocks )
494 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "DoEvent", "DoEvent()" );
495 if ( evtData.fBlockCnt<=0 )
497 Logging( kHLTLogWarning, "HLT::TPCSliceTracker::DoEvent", "DoEvent", "no blocks in event" );
500 const AliHLTComponentBlockData* iter = NULL;
502 AliHLTTPCClusterData* inPtrSP;
503 AliHLTTPCVertexData* inPtrV = NULL;
504 const AliHLTComponentBlockData* vertexIter=NULL;
505 AliHLTTPCTrackletData* outPtr;
506 AliHLTUInt8_t* outBPtr;
507 AliHLTUInt32_t vSize = 0;
508 UInt_t offset=0, mysize, tSize = 0;
510 Int_t slice=-1, patch=-1, row[2];
511 Int_t minPatch=INT_MAX, maxPatch = 0;
513 std::vector<Int_t> slices;
514 std::vector<Int_t>::iterator slIter, slEnd;
515 std::vector<unsigned> sliceCnts;
516 std::vector<unsigned>::iterator slCntIter;
517 Int_t vertexSlice=-1;
519 // Find min/max rows used in total and find and read out vertex if it is present
520 // also determine correct slice number, if multiple slice numbers are present in event
521 // (which should not happen in the first place) we use the one that occurs the most times
525 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
529 slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
531 slIter = slices.begin();
532 slEnd = slices.end();
533 slCntIter = sliceCnts.begin();
534 while ( slIter != slEnd )
536 if ( *slIter == slice )
546 slices.insert( slices.end(), slice );
547 sliceCnts.insert( sliceCnts.end(), 1 );
552 if ( iter->fDataType == AliHLTTPCDefinitions::gkVertexDataType )
554 inPtrV = (AliHLTTPCVertexData*)(iter->fPtr);
557 fVertex->Read( inPtrV );
560 if ( iter->fDataType == AliHLTTPCDefinitions::gkClustersDataType )
562 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
563 if ( minPatch>patch )
566 row[0] = AliHLTTPCTransform::GetFirstRow( patch );
568 if ( maxPatch<patch )
571 row[1] = AliHLTTPCTransform::GetLastRow( patch );
576 // Determine slice number to really use.
577 if ( slices.size()>1 )
579 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
580 "Multiple slice numbers found in event 0x%08lX (%lu). Determining maximum occuring slice number...",
581 evtData.fEventID, evtData.fEventID );
582 unsigned maxCntSlice=0;
583 slIter = slices.begin();
584 slEnd = slices.end();
585 slCntIter = sliceCnts.begin();
586 while ( slIter != slEnd )
588 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
589 "Slice %lu found %lu times.", *slIter, *slCntIter );
590 if ( maxCntSlice<*slCntIter )
592 maxCntSlice = *slCntIter;
598 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
599 "Using slice %lu.", slice );
601 else if ( slices.size()>0 )
603 slice = *(slices.begin());
610 if ( vertexSlice != slice )
612 // multiple vertex blocks in event and we used the wrong one...
614 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
617 if ( iter->fDataType == AliHLTTPCDefinitions::gkVertexDataType && slice==AliHLTTPCDefinitions::GetMinSliceNr( *iter ) )
619 inPtrV = (AliHLTTPCVertexData*)(iter->fPtr);
622 fVertex->Read( inPtrV );
628 fTracker->InitSector( slice, row, fEta );
629 fTracker->SetVertex(fVertex);
632 std::vector<unsigned long> patchIndices;
633 std::vector<unsigned long>::iterator pIter, pEnd;
634 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
638 if ( iter->fDataType == AliHLTTPCDefinitions::gkClustersDataType && slice==AliHLTTPCDefinitions::GetMinSliceNr( *iter ) )
640 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
641 pIter = patchIndices.begin();
642 pEnd = patchIndices.end();
643 while ( pIter!=pEnd && AliHLTTPCDefinitions::GetMinSliceNr( blocks[*pIter] ) < patch )
645 patchIndices.insert( pIter, ndx );
648 pIter = patchIndices.begin();
649 pEnd = patchIndices.end();
650 while ( pIter!=pEnd )
655 patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
656 inPtrSP = (AliHLTTPCClusterData*)(iter->fPtr);
658 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Reading hits",
659 "Reading hits for slice %d - patch %d", slice, patch );
660 fTracker->ReadHits( inPtrSP->fSpacePointCnt, inPtrSP->fSpacePoints );
664 outPtr = (AliHLTTPCTrackletData*)(outBPtr);
665 // BEGINN ############################################## MODIFIY JMT
667 fTracker->SetPointers();
668 if ( fmainvertextracking == kTRUE && fnonvertextracking == kFALSE){
669 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---MAINVERTEXTRACKING---");
670 fTracker->MainVertexTrackingA();
671 fTracker->MainVertexTrackingB();
672 fTracker->FillTracks();
674 else if ( fmainvertextracking == kTRUE && fnonvertextracking == kTRUE){
675 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---MAINVERTEXTRACKING---");
676 fTracker->MainVertexTrackingA();
677 fTracker->MainVertexTrackingB();
678 fTracker->FillTracks();
679 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---NONVERTEXTRACKING---");
680 fTracker->NonVertexTracking();
682 else if ( fmainvertextracking == kFALSE && fnonvertextracking == kTRUE){
683 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---NONVERTEXTRACKING---");
684 fTracker->NonVertexTracking();
685 fTracker->FillTracks();
688 fTracker->MainVertexTracking_a();
689 fTracker->MainVertexTracking_b();
690 fTracker->FillTracks();
693 fTracker->NonVertexTracking();//Do a second pass for nonvertex tracks
695 // END ################################################# MODIFIY JMT
699 AliHLTTPCMemHandler memory;
700 AliHLTTPCTrackSegmentData *trackdata0 =
701 (AliHLTTPCTrackSegmentData *) memory.Allocate(fTracker->GetTracks());
702 memory.TrackArray2Memory(ntracks0,trackdata0,fTracker->GetTracks());
703 fpInterMerger->Reset();
704 fpInterMerger->Init(row,patch);
705 fpInterMerger->FillTracks(ntracks0,trackdata0);
706 fpInterMerger->Merge();
709 mysize = fTracker->GetTracks()->WriteTracks( ntracks0, outPtr->fTracklets );
710 outPtr->fTrackletCnt = ntracks0;
712 Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracks",
713 "Input: Number of tracks: %lu Slice/MinPatch/MaxPatch/RowMin/RowMax: %lu/%lu/%lu/%lu/%lu.",
714 ntracks0, slice, minPatch, maxPatch, row[0], row[1] );
716 tSize += mysize+sizeof(AliHLTTPCTrackletData);
717 outBPtr += mysize+sizeof(AliHLTTPCTrackletData);
719 AliHLTComponentBlockData bd;
723 bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( slice, slice, minPatch, maxPatch );
724 outputBlocks.push_back( bd );
726 #ifdef FORWARD_VERTEX_BLOCK
729 // Copy the descriptor block for the vertex information.
731 outputBlocks.push_back( bd );
733 #endif // FORWARD_VERTEX_BLOCK