2d066acdbd85f3ba363ee7e50f0487f191ab99cd
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCSliceTrackerComponent.cxx
1 // $Id$
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
7  *          Timm Steinbeck <timm@kip.uni-heidelberg.de>                   *
8  *          for The ALICE Off-line Project.                               *
9  *                                                                        *
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  **************************************************************************/
18
19 /** @file   AliHLTTPCSliceTrackerComponent.cxx
20     @author Timm Steinbeck, Matthias Richter
21     @date   
22     @brief  The TPC conformal mapping tracker component.
23 */
24
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28
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"
43 #include <stdlib.h>
44 #include <errno.h>
45
46 // this is a global object used for automatic component registration, do not use this
47 AliHLTTPCSliceTrackerComponent gAliHLTTPCSliceTrackerComponent;
48
49 ClassImp(AliHLTTPCSliceTrackerComponent)
50
51 AliHLTTPCSliceTrackerComponent::AliHLTTPCSliceTrackerComponent()
52   :
53   fTracker(NULL),
54   fVertex(NULL),
55   fDoNonVertex(false),
56   fDoPP(false),
57   fMultiplicity(4000),
58   fBField(0.4),
59 // BEGINN ############################################## MODIFIY JMT
60   fnonvertextracking(kFALSE),
61   fmainvertextracking(kTRUE),
62 // END ################################################# MODIFIY JMT
63   fpInterMerger(NULL)
64 {
65   // see header file for class documentation
66   // or
67   // refer to README to build package
68   // or
69   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
70   fEta[0] = 0.;
71   fEta[1] = 1.1;
72 }
73
74 AliHLTTPCSliceTrackerComponent::AliHLTTPCSliceTrackerComponent(const AliHLTTPCSliceTrackerComponent& src)
75   :
76   fTracker(NULL),
77   fVertex(NULL),
78   fDoNonVertex(false),
79   fDoPP(false),
80   fMultiplicity(4000),
81   fBField(0.4),
82 // BEGINN ############################################## MODIFIY JMT
83   fnonvertextracking(kFALSE),
84   fmainvertextracking(kTRUE),
85 // END ################################################# MODIFIY JMT
86   fpInterMerger(NULL)
87 {
88   // see header file for class documentation
89   HLTFatal("copy constructor untested");
90 }
91
92 AliHLTTPCSliceTrackerComponent& AliHLTTPCSliceTrackerComponent::operator=(const AliHLTTPCSliceTrackerComponent& src)
93
94   // see header file for class documentation
95   HLTFatal("assignment operator untested");
96   return *this;
97 }
98
99 AliHLTTPCSliceTrackerComponent::~AliHLTTPCSliceTrackerComponent()
100 {
101 }
102
103 // Public functions to implement AliHLTComponent's interface.
104 // These functions are required for the registration process
105
106 const char* AliHLTTPCSliceTrackerComponent::GetComponentID()
107 {
108
109   return "TPCSliceTracker";
110 }
111
112 void AliHLTTPCSliceTrackerComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
113 {
114   list.clear();
115   list.push_back( AliHLTTPCDefinitions::gkClustersDataType );
116   list.push_back( AliHLTTPCDefinitions::gkVertexDataType );
117 }
118
119 AliHLTComponentDataType AliHLTTPCSliceTrackerComponent::GetOutputDataType()
120 {
121   return AliHLTTPCDefinitions::gkTrackSegmentsDataType;
122 }
123
124 void AliHLTTPCSliceTrackerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
125 {
126   // XXX TODO: Find more realistic values.
127   constBase = 0;
128   inputMultiplier = 0.2;
129 }
130
131 AliHLTComponent* AliHLTTPCSliceTrackerComponent::Spawn()
132 {
133   return new AliHLTTPCSliceTrackerComponent;
134 }
135
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 )
143     {
144     //fTracker->SetClusterFinderParam( fXYClusterError, fZClusterError, kTRUE ); // ??
145     //Set parameters input to the tracker
146     //If no arguments are given, default parameters will be used
147     
148     fTracker->SetNSegments(phiSegments,etaSegments);
149     fTracker->SetMaxDca(minPtFit);
150     //   fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
151
152 // BEGINN ############################################## MODIFIY JMT
153 #if 1
154     Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "==============================" );
155
156     if ( fmainvertextracking == kTRUE && fnonvertextracking == kFALSE){
157         fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kTRUE);
158         fTracker->SetTrackletCuts(maxangle,goodDist,kTRUE);
159
160         fTracker->MainVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack, maxphi, maxeta);    
161         Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "MAINVERTEXTRACKING" );
162     }
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);
168
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" );
172     }
173     else if ( fmainvertextracking == kFALSE && fnonvertextracking == kTRUE){
174         fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,kFALSE);
175         fTracker->SetTrackletCuts(maxangle,goodDist,kFALSE);
176
177         fTracker->NonVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack);
178         Logging( kHLTLogDebug, "HLT::TPCSliceTracker::SetTrackerParam", "Tracking", "NONVERTEXTRACKING" );
179     }
180 #else
181     fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,vertexConstraints);
182     fTracker->SetTrackletCuts(maxangle,goodDist,vertexConstraints);
183     
184     if( vertexConstraints )
185         fTracker->MainVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack, maxphi, maxeta);
186     else
187         fTracker->NonVertexSettings( trackletlength, tracklength, rowscopetracklet, rowscopetrack);
188 #endif
189 // END ################################################# MODIFIY JMT
190
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.
200      */
201     //AliHLTTPC::SetVertexFit( kFALSE );
202     
203     fTracker->InitVolumes();
204     }
205
206 void AliHLTTPCSliceTrackerComponent::SetTrackerParam( bool doPP, int multiplicity, double bField )
207     {
208     AliHLTTPCTransform::SetBField( bField );
209     Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "BField", "Setting b field to %f T\n", bField );
210
211     if ( doPP )
212         {
213         //tracker->SetClusterFinderParam(xyerror,zerror,kTRUE); // ??
214         /* the old setup used during TPC
215         SetTrackerParam( 50, 100, 3, 10,
216                          2, 2,
217                          0, 0.1745, 5, 100,
218                          5, 50, 50, 0.1, 0.1, kTRUE);
219         */
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           
237         }
238     else
239         {
240         int mults[] = { 1000, 2000, 4000, 8000 };
241         int multCount = 4;
242         int closestMult = 0;
243         int i;
244         int multDist, tmpMultDist;
245         if ( multiplicity>mults[closestMult] )
246             multDist = multiplicity-mults[closestMult];
247         else
248             multDist = mults[closestMult]-multiplicity;
249         for ( i = 1; i < multCount; i++ )
250             {
251             if ( multiplicity>mults[i] )
252                 tmpMultDist = multiplicity-mults[i];
253             else
254                 tmpMultDist = mults[i]-multiplicity;
255             if ( tmpMultDist < multDist )
256                 {
257                 closestMult = i;
258                 multDist = tmpMultDist;
259                 }
260             }
261         
262         double bfs[] = { 0.2, 0.4 };
263         int bfCount = 2;
264         int closestBf = 0;
265         double bfDist, tmpBFDist;
266         if ( bField>bfs[closestBf] )
267             bfDist = bField-bfs[closestBf];
268         else
269             bfDist = bfs[closestBf]-bField;
270         for ( i = 1; i < bfCount; i++ )
271             {
272             if ( bField>bfs[i] )
273                 tmpBFDist = bField-bfs[i];
274             else
275                 tmpBFDist = bfs[i]-bField;
276             if ( tmpBFDist < bfDist )
277                 {
278                 closestBf = i;
279                 bfDist = tmpBFDist;
280                 }
281             }
282
283         switch ( closestMult )
284             {
285             case 0: // 1000
286                 switch ( closestBf )
287                     {
288                     case 0: // 0.2
289                         SetTrackerParam( 50, 100, 3, 10,
290                                         2, 4,
291                                         0, 0.1745, 5, 100,
292                                         5, 50, 50, 0.1, 0.1, kTRUE );
293                         break;
294                     case 1: // 0.4
295                         SetTrackerParam( 50, 100, 3, 10,
296                                          2, 4,
297                                          0, 0.1745, 5, 100,
298                                          5, 50, 50, 0.1, 0.1, kTRUE );
299                         break;
300                     }
301                 break;
302             case 1: // 2000
303                 switch ( closestBf )
304                     {
305                     case 0: // 0.2
306                         SetTrackerParam( 50, 100, 3, 10,
307                                          2, 4,
308                                          0, 0.1745, 5, 30,
309                                          5, 20, 50, 0.1, 0.1, kTRUE );
310                         break;
311                     case 1: // 0.4
312                         SetTrackerParam( 50, 100, 3, 10,
313                                          2, 5,
314                                          0, 0.1745, 5, 30,
315                                          5, 20, 50, 0.1, 0.1, kTRUE );
316                         break;
317                     }
318                 break;
319             case 2: // 4000
320                 switch ( closestBf )
321                     {
322                     case 0: // 0.2
323                         SetTrackerParam( 50, 100, 3, 10,
324                                          2 , 10,
325                                          0, 0.1745, 5, 20,
326                                          5, 10 , 50, 0.1, 0.1, kTRUE );
327                         break;
328                     case 1: // 0.4
329                         SetTrackerParam( 50, 100, 3, 10,
330                                          2, 10,
331                                          0, 0.1745, 5, 20,
332                                          5, 10, 50, 0.1, 0.1, kTRUE );
333                         break;
334                     }
335                 break;
336             case 3: // 8000
337                 switch ( closestBf )
338                     {
339                     case 0: // 0.2
340                         SetTrackerParam( 50, 100, 3, 10,
341                                          3, 15,
342                                          0, 0.1745, 5, 10,
343                                          5, 5, 50, 0.1, 0.1, kTRUE );
344                         break;
345                     case 1: // 0.4
346                         SetTrackerParam( 50, 100, 3, 10,
347                                          2, 15,
348                                          0, 0.1745, 5, 15,
349                                          5, 5, 50, 0.1, 0.1, kTRUE );
350                         break;
351                     }
352                 break;
353             }
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 );
358         }
359     }
360
361
362         
363 int AliHLTTPCSliceTrackerComponent::DoInit( int argc, const char** argv )
364     {
365     Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoInit", "DoInit", "DoInit()" );
366
367     if ( fTracker || fVertex )
368         return EINPROGRESS;
369     fTracker = new AliHLTTPCConfMapper();
370     fVertex = new AliHLTTPCVertex();
371     fEta[0] = 0.;
372     fEta[1] = 1.1;
373     fDoNonVertex = false;
374     Bool_t bDoMerger=kTRUE;
375     fMultiplicity = 4000;
376     fBField = 0.4;
377     fDoPP = false;
378
379     int i = 0;
380     char* cpErr;
381     while ( i < argc )
382         {
383         if ( !strcmp( argv[i], "disable-merger" ) ){
384             bDoMerger = kFALSE;
385             i++;
386             continue;       
387         }
388
389         if ( !strcmp( argv[i], "pp-run" ) )
390             {
391             fDoPP = true;
392             i++;
393             continue;
394             }
395         if ( !strcmp( argv[i], "multiplicity" ) )
396             {
397             if ( argc <= i+1 )
398                 {
399                 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Missing event multiplicity specifier." );
400                 return ENOTSUP;
401                 }
402             fMultiplicity = strtoul( argv[i+1], &cpErr, 0 );
403             if ( *cpErr )
404                 {
405                 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Cannot convert event multiplicity specifier '%s'.", argv[i+1] );
406                 return EINVAL;
407                 }
408             i += 2;
409             continue;
410             }
411         if ( !strcmp( argv[i], "bfield" ) )
412             {
413             if ( argc <= i+1 )
414                 {
415                 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing B-field", "Missing B-field specifier." );
416                 return ENOTSUP;
417                 }
418             fBField = strtod( argv[i+1], &cpErr );
419             if ( *cpErr )
420                 {
421                 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing multiplicity", "Cannot convert B-field specifier '%s'.", argv[i+1] );
422                 return EINVAL;
423                 }
424             i += 2;
425             continue;
426             }
427
428 // BEGINN ############################################## MODIFIY JMT
429         if ( !strcmp( argv[i], "nonvertextracking" ) ){
430             fnonvertextracking = kTRUE;
431             i++;
432             continue;       
433         }
434         
435         if ( !strcmp( argv[i], "mainvertextrackingoff" ) ){     
436             fmainvertextracking = kFALSE;
437             i++;
438             continue;       
439         }
440
441         if ( !strcmp( argv[i], "etarange" ) ){  
442             if ( argc <= i+1 ){
443                 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing Eta range", "Missing Eta-range specifiers." );
444                 return ENOTSUP;
445             }
446             fEta[1] = strtod( argv[i+1], &cpErr );
447             if ( *cpErr ){
448                 Logging( kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Missing Eta range", "Cannot convert Eta-range specifier '%s'.", argv[i+1] );
449                 return EINVAL;
450             }
451    
452             i += 2;
453             continue;
454         }
455 // END ################################################# MODIFIY JMT
456         Logging(kHLTLogError, "HLT::TPCSliceTracker::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
457         return EINVAL;
458         }
459 // #### -B0-CHANGE-START == JMT
460     if (fBField == 0.){
461         // parameter for B=0 T 
462         fDoPP = kTRUE;
463         fnonvertextracking = kTRUE;
464         fmainvertextracking = kFALSE;
465     }
466 // #### -B0-CHANGE-END == JMT
467
468     if (bDoMerger)
469       fpInterMerger = new AliHLTTPCInterMerger();
470
471     SetTrackerParam( fDoPP, fMultiplicity, fBField );
472     return 0;
473     }
474
475 int AliHLTTPCSliceTrackerComponent::DoDeinit()
476 {
477   if ( fTracker )
478     delete fTracker;
479   fTracker = NULL;
480   if ( fVertex )
481     delete fVertex;
482   fVertex = NULL;
483   if (fpInterMerger) {
484     delete fpInterMerger;
485   }
486   fpInterMerger=NULL;
487   return 0;
488 }
489
490 int AliHLTTPCSliceTrackerComponent::DoEvent( const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, 
491                                               AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, 
492                                               AliHLTUInt32_t& size, vector<AliHLTComponentBlockData>& outputBlocks )
493     {
494     Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "DoEvent", "DoEvent()" );
495     if ( evtData.fBlockCnt<=0 )
496       {
497         Logging( kHLTLogWarning, "HLT::TPCSliceTracker::DoEvent", "DoEvent", "no blocks in event" );
498         return 0;
499       }
500     const AliHLTComponentBlockData* iter = NULL;
501     unsigned long ndx;
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;
509     outBPtr = outputPtr;
510     Int_t slice=-1, patch=-1, row[2];
511     Int_t minPatch=INT_MAX, maxPatch = 0;
512     offset = 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;
518
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
522     row[0] = 0;
523     row[1] = 0;
524     bool found;
525     for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
526         {
527         iter = blocks+ndx;
528
529         slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
530         found = false;
531         slIter = slices.begin();
532         slEnd = slices.end();
533         slCntIter = sliceCnts.begin();
534         while ( slIter != slEnd )
535             {
536             if ( *slIter == slice )
537                 {
538                 found = true;
539                 break;
540                 }
541             slIter++;
542             slCntIter++;
543             }
544         if ( !found )
545             {
546             slices.insert( slices.end(), slice );
547             sliceCnts.insert( sliceCnts.end(), 1 );
548             }
549         else
550             *slCntIter++;
551
552         if ( iter->fDataType == AliHLTTPCDefinitions::gkVertexDataType )
553             {
554             inPtrV = (AliHLTTPCVertexData*)(iter->fPtr);
555             vertexIter = iter;
556             vSize = iter->fSize;
557             fVertex->Read( inPtrV );
558             vertexSlice = slice;
559             }
560         if ( iter->fDataType == AliHLTTPCDefinitions::gkClustersDataType )
561             {
562             patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
563             if ( minPatch>patch )
564                 {
565                 minPatch = patch;
566                 row[0] = AliHLTTPCTransform::GetFirstRow( patch );
567                 }
568             if ( maxPatch<patch )
569                 {
570                 maxPatch = patch;
571                 row[1] = AliHLTTPCTransform::GetLastRow( patch );
572                 }
573             }
574         }
575
576     // Determine slice number to really use.
577     if ( slices.size()>1 )
578         {
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 )
587             {
588             Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
589                      "Slice %lu found %lu times.", *slIter, *slCntIter );
590             if ( maxCntSlice<*slCntIter )
591                 {
592                 maxCntSlice = *slCntIter;
593                 slice = *slIter;
594                 }
595             slIter++;
596             slCntIter++;
597             }
598         Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
599                  "Using slice %lu.", slice );
600         }
601     else if ( slices.size()>0 )
602       {
603         slice = *(slices.begin());
604       }
605     else
606       {
607         slice = -1;
608       }
609     
610     if ( vertexSlice != slice )
611         {
612         // multiple vertex blocks in event and we used the wrong one...
613         found = false;
614         for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
615             {
616             iter = blocks+ndx;
617             if ( iter->fDataType == AliHLTTPCDefinitions::gkVertexDataType && slice==AliHLTTPCDefinitions::GetMinSliceNr( *iter ) )
618                 {
619                 inPtrV = (AliHLTTPCVertexData*)(iter->fPtr);
620                 vertexIter = iter;
621                 vSize = iter->fSize;
622                 fVertex->Read( inPtrV );
623                 break;
624                 }
625             }
626         }
627
628     fTracker->InitSector( slice, row, fEta );
629     fTracker->SetVertex(fVertex);
630     mysize = 0;
631     // read in all hits
632     std::vector<unsigned long> patchIndices;
633     std::vector<unsigned long>::iterator pIter, pEnd;
634     for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
635         {
636         iter = blocks+ndx;
637
638         if ( iter->fDataType == AliHLTTPCDefinitions::gkClustersDataType && slice==AliHLTTPCDefinitions::GetMinSliceNr( *iter ) )
639             {
640             patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
641             pIter = patchIndices.begin();
642             pEnd = patchIndices.end();
643             while ( pIter!=pEnd && AliHLTTPCDefinitions::GetMinSliceNr( blocks[*pIter] ) < patch )
644                 pIter++;
645             patchIndices.insert( pIter, ndx );
646             }
647         }
648     pIter = patchIndices.begin();
649     pEnd = patchIndices.end();
650     while ( pIter!=pEnd )
651         {
652         ndx = *pIter;
653         iter = blocks+ndx;
654
655         patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
656         inPtrSP = (AliHLTTPCClusterData*)(iter->fPtr);
657             
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 );
661         pIter++;
662         }
663
664     outPtr = (AliHLTTPCTrackletData*)(outBPtr);
665 // BEGINN ############################################## MODIFIY JMT
666 #if 1
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();
673     }
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();
681     }
682     else if ( fmainvertextracking == kFALSE && fnonvertextracking == kTRUE){
683         Logging( kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Tracking", " ---NONVERTEXTRACKING---");
684         fTracker->NonVertexTracking();  
685         fTracker->FillTracks(); 
686     }
687 #else
688     fTracker->MainVertexTracking_a();
689     fTracker->MainVertexTracking_b();
690     fTracker->FillTracks();
691     
692     if ( fDoNonVertex )
693         fTracker->NonVertexTracking();//Do a second pass for nonvertex tracks
694 #endif
695 // END ################################################# MODIFIY JMT
696     
697     UInt_t ntracks0 =0;
698     if(fpInterMerger){
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();
707     } 
708     ntracks0=0;
709     mysize = fTracker->GetTracks()->WriteTracks( ntracks0, outPtr->fTracklets );
710     outPtr->fTrackletCnt = ntracks0;
711
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] );
715
716     tSize += mysize+sizeof(AliHLTTPCTrackletData);
717     outBPtr += mysize+sizeof(AliHLTTPCTrackletData);
718     
719     AliHLTComponentBlockData bd;
720     FillBlockData( bd );
721     bd.fOffset = offset;
722     bd.fSize = tSize;
723     bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( slice, slice, minPatch, maxPatch );
724     outputBlocks.push_back( bd );
725
726 #ifdef FORWARD_VERTEX_BLOCK
727     if ( vertexIter )
728         {
729         // Copy the descriptor block for the vertex information.
730         bd = *vertexIter;
731         outputBlocks.push_back( bd );
732         }
733 #endif // FORWARD_VERTEX_BLOCK
734
735     size = tSize;
736     return 0;
737     }
738
739