]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/tracking-ca/AliHLTTPCCATrackerComponent.cxx
Bug in cluster position corected (Diaz, Conesa)
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCATrackerComponent.cxx
1 // @(#) $Id$
2 /**************************************************************************
3  * This file is property of and copyright by the ALICE HLT Project        * 
4  * ALICE Experiment at CERN, All rights reserved.                         *
5  *                                                                        *
6  * Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
7  *                  Ivan Kisel <kisel@kip.uni-heidelberg.de>              *
8  *                  for The ALICE HLT 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 ///////////////////////////////////////////////////////////////////////////////
20 //                                                                           //
21 // a TPC tracker processing component for the HLT based on CA by Ivan Kisel  //
22 //                                                                           //
23 ///////////////////////////////////////////////////////////////////////////////
24
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28
29 #include <climits>
30 #include "AliHLTTPCCATrackerComponent.h"
31 #include "AliHLTTPCTransform.h"
32 #include "AliHLTTPCCATracker.h"
33 #include "AliHLTTPCCAHit.h"
34 #include "AliHLTTPCCAOutTrack.h"
35
36 #include "AliHLTTPCSpacePointData.h"
37 #include "AliHLTTPCClusterDataFormat.h"
38 #include "AliHLTTPCTransform.h"
39 #include "AliHLTTPCTrackSegmentData.h"
40 #include "AliHLTTPCTrackArray.h"
41 #include "AliHLTTPCTrackletDataFormat.h"
42 #include "AliHLTTPCDefinitions.h"
43 #include "TStopwatch.h"
44 #include "TMath.h"
45
46 /** ROOT macro for the implementation of ROOT specific class methods */
47 ClassImp(AliHLTTPCCATrackerComponent)
48
49 AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent()
50   :
51   fTracker(NULL),
52   fBField(0)
53 {
54   // see header file for class documentation
55   // or
56   // refer to README to build package
57   // or
58   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
59 }
60
61 AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent(const AliHLTTPCCATrackerComponent&)
62   :
63   AliHLTProcessor(),
64   fTracker(NULL),
65   fBField(0)
66 {
67   // see header file for class documentation
68   HLTFatal("copy constructor untested");
69 }
70
71 AliHLTTPCCATrackerComponent& AliHLTTPCCATrackerComponent::operator=(const AliHLTTPCCATrackerComponent&)
72 {
73   // see header file for class documentation
74   HLTFatal("assignment operator untested");
75   return *this;
76 }
77
78 AliHLTTPCCATrackerComponent::~AliHLTTPCCATrackerComponent()
79 {
80   // see header file for class documentation
81   delete fTracker;
82 }
83
84 //
85 // Public functions to implement AliHLTComponent's interface.
86 // These functions are required for the registration process
87 //
88
89 const char* AliHLTTPCCATrackerComponent::GetComponentID() 
90 {
91   // see header file for class documentation
92   return "TPCCATracker";
93 }
94
95 void AliHLTTPCCATrackerComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list) 
96 {
97   // see header file for class documentation
98   list.clear();
99   list.push_back( AliHLTTPCDefinitions::fgkClustersDataType );
100 }
101
102 AliHLTComponentDataType AliHLTTPCCATrackerComponent::GetOutputDataType() 
103 {
104   // see header file for class documentation
105   return AliHLTTPCDefinitions::fgkTrackSegmentsDataType;
106 }
107
108 void AliHLTTPCCATrackerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) 
109 {
110   // define guess for the output data size
111   constBase = 200;       // minimum size
112   inputMultiplier = 0.5; // size relative to input 
113 }
114
115 AliHLTComponent* AliHLTTPCCATrackerComponent::Spawn() 
116 {
117   // see header file for class documentation
118   return new AliHLTTPCCATrackerComponent;
119 }
120
121 int AliHLTTPCCATrackerComponent::DoInit( int argc, const char** argv )
122 {
123   // Initialize the CA tracker component 
124   //
125   // arguments could be:
126   // bfield - the magnetic field value
127   //
128
129   if ( fTracker ) return EINPROGRESS;
130   
131   fTracker = new AliHLTTPCCATracker();
132   
133   // read command line
134
135   int i = 0;
136   char* cpErr;
137   while ( i < argc ){
138     if ( !strcmp( argv[i], "bfield" ) ){
139       if ( i+1 >= argc )
140         {
141           Logging( kHLTLogError, "HLT::TPCCATracker::DoInit", "Missing B-field", "Missing B-field specifier." );
142           return ENOTSUP;
143         }
144       fBField = strtod( argv[i+1], &cpErr );
145       if ( *cpErr )
146         {
147           Logging( kHLTLogError, "HLT::TPCCATracker::DoInit", "Missing multiplicity", "Cannot convert B-field specifier '%s'.", argv[i+1] );
148           return EINVAL;
149         }
150
151       Logging( kHLTLogDebug, "HLT::TPCCATracker::DoInit", "Reading command line",
152                "Magnetic field value is set to %f kG", fBField );
153
154       i += 2;
155       continue;
156     }
157     
158     Logging(kHLTLogError, "HLT::TPCCATracker::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
159     return EINVAL;
160   }
161   
162   return 0;
163 }
164
165 int AliHLTTPCCATrackerComponent::DoDeinit()
166 {
167   // see header file for class documentation
168   if ( fTracker ) delete fTracker;
169   fTracker = NULL;  
170   return 0;
171 }
172
173 int AliHLTTPCCATrackerComponent::DoEvent
174
175  const AliHLTComponentEventData& evtData, 
176  const AliHLTComponentBlockData* blocks, 
177  AliHLTComponentTriggerData& /*trigData*/, 
178  AliHLTUInt8_t* outputPtr, 
179  AliHLTUInt32_t& size, 
180  vector<AliHLTComponentBlockData>& outputBlocks )
181 {
182
183   AliHLTUInt32_t MaxBufferSize = size;
184   size = 0; // output size
185
186   TStopwatch timer;
187
188   // Event reconstruction in one TPC slice with CA Tracker
189
190   Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "DoEvent", "DoEvent()" );
191   if ( evtData.fBlockCnt<=0 )
192     {
193       Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "DoEvent", "no blocks in event" );
194       return 0;
195     }
196   
197   const AliHLTComponentBlockData* iter = NULL;
198   unsigned long ndx;
199   AliHLTTPCClusterData* inPtrSP; 
200  
201   // Determine the slice number 
202   
203   Int_t slice=-1;
204   {
205     std::vector<Int_t> slices;
206     std::vector<Int_t>::iterator slIter;
207     std::vector<unsigned> sliceCnts;
208     std::vector<unsigned>::iterator slCntIter;
209   
210     for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ){
211       iter = blocks+ndx;
212       if ( iter->fDataType != AliHLTTPCDefinitions::fgkClustersDataType ) continue;
213
214       slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
215
216       Bool_t found = 0;
217       slCntIter = sliceCnts.begin();
218       for( slIter = slices.begin(); slIter!=slices.end(); slIter++, slCntIter++ ){
219         if ( *slIter == slice ){
220           found = kTRUE;
221           break;
222         }
223       }
224       if ( !found ){
225         slices.push_back( slice );
226         sliceCnts.push_back( 1 );
227       } else *slCntIter++;     
228     }
229   
230     
231     // Determine slice number to really use.
232     if ( slices.size()>1 )
233       {
234         Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
235                  "Multiple slice numbers found in event 0x%08lX (%lu). Determining maximum occuring slice number...",
236                  evtData.fEventID, evtData.fEventID );
237         unsigned maxCntSlice=0;
238         slCntIter = sliceCnts.begin();
239         for( slIter = slices.begin(); slIter != slices.end(); slIter++, slCntIter++ )
240           {
241             Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
242                      "Slice %lu found %lu times.", *slIter, *slCntIter );
243             if ( maxCntSlice<*slCntIter )
244               {
245                 maxCntSlice = *slCntIter;
246                 slice = *slIter;
247               }
248           }
249         Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
250                  "Using slice %lu.", slice );
251       }
252     else if ( slices.size()>0 )
253       {
254         slice = *(slices.begin());
255       }
256   }
257   
258   if( slice<0 ){
259     Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "DoEvent", "no slices found in event" );
260     return 0;
261   }
262
263
264   // Initialize the tracker
265
266   Double_t Bz = fBField;
267   
268   {
269     if( !fTracker ) fTracker = new AliHLTTPCCATracker;
270     Int_t iSec = slice;
271     Double_t inRmin = 83.65; 
272     //    Double_t inRmax = 133.3;
273     //    Double_t outRmin = 133.5; 
274     Double_t outRmax = 247.7;
275     Double_t plusZmin = 0.0529937; 
276     Double_t plusZmax = 249.778; 
277     Double_t minusZmin = -249.645; 
278     Double_t minusZmax = -0.0799937; 
279     Double_t dalpha = 0.349066;
280     Double_t alpha = 0.174533 + dalpha*iSec;
281     
282     Bool_t zPlus = (iSec<18 );
283     Double_t zMin =  zPlus ?plusZmin :minusZmin;
284     Double_t zMax =  zPlus ?plusZmax :minusZmax;
285     //TPCZmin = -249.645, ZMax = 249.778    
286     //    Double_t rMin =  inRmin;
287     //    Double_t rMax =  outRmax;
288     Int_t NRows = AliHLTTPCTransform::GetNRows();
289         
290     Double_t padPitch = 0.4;
291     Double_t sigmaZ = 0.228808;
292     
293      Double_t rowX[NRows];
294     for( Int_t irow=0; irow<NRows; irow++){
295       rowX[irow] = AliHLTTPCTransform::Row2X( irow );
296     }     
297      
298     AliHLTTPCCAParam param;
299     param.Initialize( iSec, NRows, rowX, alpha, dalpha,
300                       inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, Bz );
301     param.YErrorCorrection() = 1;
302     param.ZErrorCorrection() = 2;
303
304     fTracker->Initialize( param ); 
305
306   }
307
308     
309   // min and max patch numbers and row numbers
310
311   Int_t row[2] = {0,0};
312   Int_t minPatch=INT_MAX, maxPatch = -1;
313
314   // total n Hits
315
316   Int_t nHitsTotal = 0;
317
318   // sort patches
319
320   std::vector<unsigned long> patchIndices;
321
322   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ){
323     iter = blocks+ndx;      
324     if( iter->fDataType != AliHLTTPCDefinitions::fgkClustersDataType ) continue;
325     if( slice!=AliHLTTPCDefinitions::GetMinSliceNr( *iter ) ) continue;
326     inPtrSP = (AliHLTTPCClusterData*)(iter->fPtr);
327     nHitsTotal+=inPtrSP->fSpacePointCnt;
328     Int_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
329     if ( minPatch>patch ){
330       minPatch = patch;
331       row[0] = AliHLTTPCTransform::GetFirstRow( patch );
332     }
333     if ( maxPatch<patch ){
334       maxPatch = patch;
335       row[1] = AliHLTTPCTransform::GetLastRow( patch );
336     }
337     std::vector<unsigned long>::iterator pIter = patchIndices.begin(); 
338     while( pIter!=patchIndices.end() && AliHLTTPCDefinitions::GetMinPatchNr( blocks[*pIter] ) < patch ){
339       pIter++;
340     }
341     patchIndices.insert( pIter, ndx );
342   }
343            
344
345   // pass event to CA Tracker
346   
347   fTracker->StartEvent();
348
349   AliHLTTPCCAHit vHits[nHitsTotal]; // CA hit array
350   Double_t vHitStoreX[nHitsTotal];       // hit X coordinates
351   Int_t vHitStoreID[nHitsTotal];            // hit ID's
352   Int_t vHitRowID[nHitsTotal];            // hit ID's
353
354   Int_t nHits = 0;
355  
356   Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reading hits",
357            "Total %d hits to read for slice %d", nHitsTotal, slice );
358
359   Int_t nClusters=0;
360
361   for( std::vector<unsigned long>::iterator pIter = patchIndices.begin(); pIter!=patchIndices.end(); pIter++ ){
362     ndx = *pIter;
363     iter = blocks+ndx;
364       
365     Int_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
366     inPtrSP = (AliHLTTPCClusterData*)(iter->fPtr);
367       
368     Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reading hits",
369              "Reading %d hits for slice %d - patch %d", inPtrSP->fSpacePointCnt, slice, patch );
370       
371     // Read patch hits, row by row
372
373     Int_t oldRow = -1;
374     Int_t nRowHits = 0;
375     Int_t firstRowHit = 0;
376     for (UInt_t i=0; i<inPtrSP->fSpacePointCnt; i++ ){  
377       AliHLTTPCSpacePointData* pSP = &(inPtrSP->fSpacePoints[i]);
378
379       if( pSP->fPadRow != oldRow ){
380         if( oldRow>=0 ) fTracker->ReadHitRow( oldRow, vHits+firstRowHit, nRowHits );
381         oldRow = pSP->fPadRow;
382         firstRowHit = nHits;
383         nRowHits = 0;
384       }
385       AliHLTTPCCAHit &h = vHits[nHits];
386       if( TMath::Abs(pSP->fX- fTracker->Rows()[pSP->fPadRow].X() )>1.e-4 ) cout<<"row "<<(Int_t)pSP->fPadRow<<" "<<fTracker->Rows()[pSP->fPadRow].X()-pSP->fX <<endl;
387
388       h.Y() = pSP->fY;
389       h.Z() = pSP->fZ;
390       h.ErrY() = TMath::Sqrt(TMath::Abs(pSP->fSigmaY2));
391       h.ErrZ() = TMath::Sqrt(TMath::Abs(pSP->fSigmaZ2));  
392       if( h.ErrY()<.1 ) h.ErrY() = .1;
393       if( h.ErrZ()<.1 ) h.ErrZ() = .1;
394       if( h.ErrY()>1. ) h.ErrY() = 1.;
395       if( h.ErrZ()>1. ) h.ErrZ() = 1.;
396       h.ID() = nHits;
397       vHitStoreX[nHits] = pSP->fX;
398       vHitStoreID[nHits] = pSP->fID;
399       vHitRowID[nHits] = pSP->fPadRow;
400       nHits++;  
401       nRowHits++;
402       nClusters++;
403     }   
404     if( oldRow>=0 ) fTracker->ReadHitRow( oldRow, vHits+firstRowHit, nRowHits );
405   }
406
407   // reconstruct the event  
408
409   TStopwatch timerReco;
410
411   fTracker->Reconstruct();
412
413   timerReco.Stop();
414
415   Int_t ret = 0;
416
417   Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reconstruct",
418            "%d tracks found for slice %d",fTracker->NOutTracks(), slice);
419
420   // write reconstructed tracks
421
422   AliHLTTPCTrackletData* outPtr = (AliHLTTPCTrackletData*)(outputPtr);
423
424   AliHLTTPCTrackSegmentData* currOutTracklet = outPtr->fTracklets;
425
426   Int_t ntracks = fTracker->NOutTracks();
427
428   UInt_t mySize =   ((AliHLTUInt8_t *)currOutTracklet) -  ((AliHLTUInt8_t *)outputPtr);
429
430   outPtr->fTrackletCnt = 0; 
431
432   for( int itr=0; itr<ntracks; itr++ ){
433     
434     AliHLTTPCCAOutTrack &t = fTracker->OutTracks()[itr];    
435
436     //Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Wrtite output","track %d with %d hits", itr, t.NHits());
437
438     // calculate output track size
439
440     UInt_t dSize = sizeof(AliHLTTPCTrackSegmentData) + t.NHits()*sizeof(UInt_t);
441     
442     if( mySize + dSize > MaxBufferSize ){
443       Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "Wrtite output","Output buffer size exceed (buffer size %d, current size %d), %d tracks are not stored", MaxBufferSize, mySize, ntracks-itr+1);
444       ret = -ENOSPC;
445       break;
446     }
447     
448     // convert CA track parameters to HLT Track Segment
449
450     Int_t iFirstHit = fTracker->OutTrackHits()[t.FirstHitRef()];
451     Int_t iLastHit = fTracker->OutTrackHits()[t.FirstHitRef()+t.NHits()-1];
452     
453     AliHLTTPCCAHit &firstHit = vHits[iFirstHit];
454     AliHLTTPCCAHit &lastHit = vHits[iLastHit];
455    
456     t.Param().TransportBz(Bz, vHitStoreX[iFirstHit], firstHit.Y(), firstHit.Z() );
457
458     currOutTracklet->fX = t.Param().Par()[0];
459     currOutTracklet->fY = t.Param().Par()[1];
460     currOutTracklet->fZ = t.Param().Par()[2];
461     Double_t qp = t.Param().Par()[6];
462     Double_t p = TMath::Abs(qp)>1.e-5 ?1./TMath::Abs(qp) :1.e5;
463     Double_t ex = t.Param().Par()[3];
464     Double_t ey = t.Param().Par()[4];
465     Double_t ez = t.Param().Par()[5];
466     Double_t et = TMath::Sqrt( ex*ex + ey*ey );
467     
468     currOutTracklet->fCharge = (qp>0) ?+1 :(qp<0 ?-1 :0);
469     currOutTracklet->fPt = p*et;
470
471     Double_t h3 =  TMath::Abs(ex) >1.e-5 ? p*ex/et :0;
472     Double_t h4 =  TMath::Abs(ey) >1.e-5 ? p*ey/et :0;
473     Double_t h5;
474     Double_t h6 =  - currOutTracklet->fCharge * p * currOutTracklet->fPt;
475   
476     currOutTracklet->fPterr = ( h3*h3*t.Param().Cov()[9] + h4*h4*t.Param().Cov()[14] + h6*h6*t.Param().Cov()[27] 
477                                 + 2.*(h3*h4*t.Param().Cov()[13]+h3*h6*t.Param().Cov()[24]+h4*h6*t.Param().Cov()[25] )
478                                 );    
479     currOutTracklet->fPsi = TMath::ATan2(ey, ex);
480     
481     h3 =  ex/(et*et);
482     h4 = -ey/(et*et);
483     currOutTracklet->fPsierr = h3*h3*t.Param().Cov()[9] + h4*h4*t.Param().Cov()[14] + 2.*h3*h4*t.Param().Cov()[13];
484     
485     currOutTracklet->fTgl = TMath::Abs(et)>1.e-5  ? ez/et :1.e5;
486       
487     if( TMath::Abs(et) >1.e-2 ){
488       h3 = -ez*ex/et/et;
489       h4 = -ez*ey/et/et;
490       h5 = 1.;
491       currOutTracklet->fTglerr =  ( h3*h3*t.Param().Cov()[9] + h4*h4*t.Param().Cov()[14] + h5*h5*t.Param().Cov()[20] 
492                                     + 2.*(h3*h4*t.Param().Cov()[13]+h3*h5*t.Param().Cov()[18]+h4*h5*t.Param().Cov()[19] )
493                                     )/et/et;
494     }else{
495       currOutTracklet->fTglerr =  1.e-2;
496     }
497
498     currOutTracklet->fCharge = -currOutTracklet->fCharge;
499     
500     t.Param().TransportBz(Bz, vHitStoreX[iLastHit], lastHit.Y(), lastHit.Z() );
501      
502     currOutTracklet->fLastX = t.Param().Par()[0];
503     currOutTracklet->fLastY = t.Param().Par()[1];
504     currOutTracklet->fLastZ = t.Param().Par()[2];
505
506 #ifdef INCLUDE_TPC_HOUGH
507 #ifdef ROWHOUGHPARAMS
508     currOutTracklet->fTrackID = 0;
509     currOutTracklet->fRowRange1 = vHitRowID[iFirstHit];
510     currOutTracklet->fRowRange2 = vHitRowID[iLastHit];
511     currOutTracklet->fSector = slice;
512     currOutTracklet->fPID = 211;
513 #endif
514 #endif // INCLUDE_TPC_HOUGH
515
516
517     currOutTracklet->fNPoints = t.NHits();
518
519     for( Int_t i=0; i<t.NHits(); i++ ){
520       currOutTracklet->fPointIDs[i] = vHitStoreID[fTracker->OutTrackHits()[t.FirstHitRef()+i]];
521     }
522
523     currOutTracklet = (AliHLTTPCTrackSegmentData*)( (Byte_t *)currOutTracklet + dSize );
524     mySize+=dSize;
525     outPtr->fTrackletCnt++; 
526   }
527   
528   
529   AliHLTComponentBlockData bd;
530   FillBlockData( bd );
531   bd.fOffset = 0;
532   bd.fSize = mySize;
533   bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( slice, slice, minPatch, maxPatch );      
534   outputBlocks.push_back( bd );
535   
536   size = mySize;
537   
538   timerReco.Stop();
539
540   // Set log level to "Warning" for on-line system monitoring
541
542   Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "Tracks",
543            "CATracker slice %d: output %d tracks;  input %d clusters, patches %d..%d, rows %d..%d; reco time %d/%d us", 
544            slice, ntracks, nClusters, minPatch, maxPatch, row[0], row[1], (Int_t) (timer.RealTime()*1.e6), (Int_t) (timerReco.RealTime()*1.e6) );
545
546   return ret;
547
548 }
549
550