TPC CA Global Merger component added
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCAGlobalMergerComponent.cxx
1 // **************************************************************************
2 // This file is property of and copyright by the ALICE HLT Project          * 
3 // ALICE Experiment at CERN, All rights reserved.                           *
4 //                                                                          *
5 // Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
6 //                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
7 //                  Matthias Kretz <kretz@kde.org>                          *
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 /** @file   AliHLTTPCCAGlobalMergerComponent.cxx
22     @author Matthias Kretz
23     @date
24     @brief  HLT TPC CA global merger component.
25 */
26
27 #if __GNUC__>= 3
28 using namespace std;
29 #endif
30
31 #include "AliHLTTPCCAGlobalMergerComponent.h"
32 #include "AliHLTTPCCAMergerOutput.h"
33 #include "AliHLTTPCTransform.h"
34 #include "AliHLTTPCCAMerger.h"
35 #include "AliHLTTPCVertex.h"
36 #include "AliHLTTPCVertexData.h"
37 #include "AliHLTTPCTrackSegmentData.h"
38 #include "AliHLTTPCTrack.h"
39 #include "AliHLTTPCTrackArray.h"
40 #include "AliHLTTPCTrackletDataFormat.h"
41 #include "AliHLTTPCCADef.h"
42 #include "AliHLTTPCDefinitions.h"
43 #include "AliHLTTPCCATrackConvertor.h"
44
45 #include "AliCDBEntry.h"
46 #include "AliCDBManager.h"
47 #include "TObjString.h"
48 #include "TObjArray.h"
49
50 #include <climits>
51 #include <cstdlib>
52 #include <cerrno>
53
54
55 // ROOT macro for the implementation of ROOT specific class methods
56 ClassImp( AliHLTTPCCAGlobalMergerComponent )
57
58
59 // global object for registration
60 AliHLTTPCCAGlobalMergerComponent AliHLTTPCCAGlobalMergerComponent::fgAliHLTTPCCAGlobalMergerComponent;
61
62 AliHLTTPCCAGlobalMergerComponent::AliHLTTPCCAGlobalMergerComponent()
63   : fGlobalMerger( 0 ), fSolenoidBz(5)
64 {
65   // see header file for class documentation
66 }
67
68 // Public functions to implement AliHLTComponent's interface.
69 // These functions are required for the registration process
70
71 const char *AliHLTTPCCAGlobalMergerComponent::GetComponentID()
72 {
73   // see header file for class documentation
74   return "TPCCAGlobalMerger";
75 }
76
77 void AliHLTTPCCAGlobalMergerComponent::GetInputDataTypes( AliHLTComponentDataTypeList &list )
78 {
79   // see header file for class documentation
80   list.clear();
81   list.push_back( AliHLTTPCCADefinitions::fgkTrackletsDataType );
82   //list.push_back( AliHLTTPCDefinitions::fgkTrackSegmentsDataType );
83   //list.push_back( AliHLTTPCDefinitions::fgkVertexDataType );
84 }
85
86 AliHLTComponentDataType AliHLTTPCCAGlobalMergerComponent::GetOutputDataType()
87 {
88   // see header file for class documentation
89   return AliHLTTPCDefinitions::fgkTracksDataType;
90 }
91
92 void AliHLTTPCCAGlobalMergerComponent::GetOutputDataSize( unsigned long &constBase, double &inputMultiplier )
93 {
94   // see header file for class documentation
95   // XXX TODO: Find more realistic values.
96   constBase = 0;
97   inputMultiplier = 1.0;
98 }
99
100 AliHLTComponent *AliHLTTPCCAGlobalMergerComponent::Spawn()
101 {
102   // see header file for class documentation
103   return new AliHLTTPCCAGlobalMergerComponent;
104 }
105
106 int AliHLTTPCCAGlobalMergerComponent::DoInit( int argc, const char** argv )
107 {
108   // see header file for class documentation
109   if ( fGlobalMerger ) {
110     return EINPROGRESS;
111   }
112
113   // Initialize the merger
114
115   fGlobalMerger = new AliHLTTPCCAMerger();
116
117   AliHLTTPCCAParam param;
118   
119   {
120     // get gemetry
121     Int_t iSec = 0;
122     Float_t inRmin = 83.65; 
123     Float_t outRmax = 247.7;
124     Float_t plusZmin = 0.0529937; 
125     Float_t plusZmax = 249.778; 
126     Float_t minusZmin = -249.645; 
127     Float_t minusZmax = -0.0799937; 
128     Float_t dalpha = 0.349066;
129     Float_t alpha = 0.174533 + dalpha*iSec;    
130     Bool_t zPlus = (iSec<18 );
131     Float_t zMin =  zPlus ?plusZmin :minusZmin;
132     Float_t zMax =  zPlus ?plusZmax :minusZmax;
133     Int_t nRows = AliHLTTPCTransform::GetNRows();        
134     Float_t padPitch = 0.4;
135     Float_t sigmaZ = 0.228808;    
136     Float_t *rowX = new Float_t [nRows];
137     for( Int_t irow=0; irow<nRows; irow++){
138       rowX[irow] = AliHLTTPCTransform::Row2X( irow );
139     }
140      
141     param.Initialize( iSec, nRows, rowX, alpha, dalpha,
142                       inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, fSolenoidBz );    
143     delete[] rowX;
144   }
145
146
147   fGlobalMerger->SetSliceParam( param );
148
149   Int_t iResult = EINVAL;
150
151   TString arguments=""; 
152   for (int i=0; i<argc; i++) {
153     TString argument=argv[i];
154     if (!arguments.IsNull()) arguments+=" ";
155     arguments+=argument;
156   }
157   if (!arguments.IsNull()) {
158     iResult=Configure(arguments.Data());
159   } else {
160     iResult=Reconfigure(NULL, NULL);
161   }  
162   return iResult;
163 }
164
165 int AliHLTTPCCAGlobalMergerComponent::DoDeinit()
166 {
167   // see header file for class documentation
168   delete fGlobalMerger;
169   fGlobalMerger = 0;
170
171   return 0;
172 }
173
174 int AliHLTTPCCAGlobalMergerComponent::DoEvent( const AliHLTComponentEventData &evtData,
175                                                const AliHLTComponentBlockData *blocks, AliHLTComponentTriggerData &/*trigData*/,
176     AliHLTUInt8_t *outputPtr, AliHLTUInt32_t &size, AliHLTComponentBlockDataList &outputBlocks )
177 {
178   // see header file for class documentation
179   int iResult = 0;
180   UInt_t maxBufferSize = size;
181
182   size = 0;
183
184   if ( !outputPtr ) {
185       return -ENOSPC;
186   }
187   if ( !IsDataEvent() ) {
188     return 0;
189   }
190
191   fGlobalMerger->Clear();
192
193   const AliHLTComponentBlockData *const blocksEnd = blocks + evtData.fBlockCnt;
194   for ( const AliHLTComponentBlockData *block = blocks; block < blocksEnd; ++block ) {
195     if ( block->fDataType != AliHLTTPCCADefinitions::fgkTrackletsDataType ) {
196       continue;
197     }
198
199     int slice = AliHLTTPCDefinitions::GetMinSliceNr( *block );
200     if ( slice < 0 || slice >= AliHLTTPCTransform::GetNSlice() ) {
201       HLTError( "invalid slice number %d extracted from specification 0x%08lx,  skipping block of type %s",
202           slice, block->fSpecification, DataType2Text(block->fDataType).c_str() );
203       // just remember the error, if there are other valid blocks ignore the error, return code otherwise
204       iResult = -EBADF;
205       continue;
206     }
207
208     if ( slice != AliHLTTPCDefinitions::GetMaxSliceNr( *block ) ) {
209       // the code was not written for/ never used with multiple slices in one data block/ specification
210       HLTWarning("specification 0x%08lx indicates multiple slices in data block %s: never used before, please audit the code",
211           block->fSpecification, DataType2Text(block->fDataType).c_str());
212     }
213
214     fGlobalMerger->SetSliceData( slice, reinterpret_cast<AliHLTTPCCASliceOutput *>( block->fPtr ) );
215   }
216   fGlobalMerger->Reconstruct();
217
218   const AliHLTTPCCAMergerOutput *mergerOutput = fGlobalMerger->Output();
219
220
221   // Fill output tracks
222
223   UInt_t mySize = 0;
224
225   {
226     // check if there was enough space in the output buffer
227
228     Int_t nTracks = mergerOutput->NTracks();
229
230     AliHLTTPCTrackArray array( nTracks );
231
232     Int_t nClusters=0;
233     for( Int_t itr=0; itr<nTracks; itr++){
234  
235       // convert AliHLTTPCCAMergedTrack to AliHLTTPCTrack
236
237       const AliHLTTPCCAMergedTrack &track = mergerOutput->Track( itr );
238       AliHLTTPCTrack out;
239
240       // first convert to AliExternalTrackParam ( Kappa to Pt )
241
242       AliExternalTrackParam tp, tpEnd;
243       AliHLTTPCCATrackConvertor::GetExtParam( track.InnerParam(), tp, 0, fSolenoidBz );      
244       AliHLTTPCCATrackConvertor::GetExtParam( track.OuterParam(), tpEnd, 0, fSolenoidBz );      
245
246       // set parameters, with rotation to global coordinates
247       
248       out.SetCharge((Int_t ) tp.GetSign());
249       out.SetPt( TMath::Abs(tp.GetSignedPt()) );
250       out.SetPsi( fmod( TMath::ASin( tp.GetSnp() ) + track.InnerAlpha() ,2*TMath::Pi() ) );
251       out.SetTgl( tp.GetTgl() );
252       {
253         Float_t sinA = TMath::Sin( track.InnerAlpha() );
254         Float_t cosA = TMath::Cos( track.InnerAlpha() );
255         
256         out.SetFirstPoint( tp.GetX()*cosA - tp.GetY()*sinA,
257                            tp.GetX()*sinA + tp.GetY()*cosA, 
258                            tp.GetZ() );
259       }
260       
261       {
262         Float_t sinA = TMath::Sin( track.OuterAlpha() );
263         Float_t cosA = TMath::Cos( track.OuterAlpha() );
264         
265         out.SetLastPoint( tpEnd.GetX()*cosA - tpEnd.GetY()*sinA,
266                           tpEnd.GetX()*sinA + tpEnd.GetY()*cosA, 
267                           tpEnd.GetZ() );
268       }
269
270       // set parameter errors w/o rotation, as it is done in AliHLTTPCTrackArray
271
272       out.SetY0err(tp.GetSigmaY2());
273       out.SetZ0err(tp.GetSigmaZ2());
274       Float_t h = -out.GetPt()*out.GetPt();
275       out.SetPterr( h*h*tp.GetSigma1Pt2() );
276       h = 1./TMath::Sqrt(1-out.GetSnp()*out.GetSnp());
277       out.SetPsierr(h*h*tp.GetSigmaSnp2());
278       out.SetTglerr(tp.GetSigmaTgl2());  
279  
280       // set cluster ID's
281
282       UInt_t hitID[1000];
283       for( Int_t i=0; i<track.NClusters(); i++ ) hitID[i] = mergerOutput->ClusterIDsrc(track.FirstClusterRef()+i);
284
285       out.SetNHits( track.NClusters() );
286       out.SetHits( track.NClusters(), hitID );
287       
288       out.SetSector(-1);
289       out.CalculateHelix();
290       if( !out.CheckConsistency() )  *(array.NextTrack()) = out;      
291       nClusters+=track.NClusters();
292     }
293
294     
295     if ( sizeof(AliHLTTPCTrackletData) + nTracks*sizeof(AliHLTTPCTrackSegmentData) + nClusters*sizeof(UInt_t)
296          > maxBufferSize ){
297       iResult = -ENOSPC;
298     } else {
299       AliHLTTPCTrackletData *outPtr = (AliHLTTPCTrackletData*)(outputPtr);
300       UInt_t nOutTracks = 0;
301       mySize = array.WriteTracks( nOutTracks, outPtr->fTracklets );
302       mySize += sizeof(AliHLTTPCTrackletData);
303       outPtr->fTrackletCnt = nOutTracks;
304     }
305   }
306   
307   AliHLTComponentBlockData resultData;
308   FillBlockData( resultData );
309   resultData.fOffset = 0;
310   resultData.fSize = mySize;
311   resultData.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( 0, 35, 0, 5 );
312   outputBlocks.push_back( resultData );
313   size = resultData.fSize;
314
315   //HLTWarning("CAGlobalMerger:: output %d tracks",mergerOutput->NTracks());
316
317   return iResult;
318 }
319
320
321
322 Int_t AliHLTTPCCAGlobalMergerComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
323 {
324   // see header file for class documentation
325
326
327   HLTWarning("dummy Reconfigure() method called" );
328   return EINVAL;
329   /*
330
331   Int_t iResult=EINVAL;
332   const char* pathBField=kAliHLTCDBSolenoidBz;
333   
334   if (pathBField) {
335     HLTInfo("reconfigure B-Field from entry %s, chain id %s", pathBField,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
336     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(pathBField);//,GetRunNo());
337     if (pEntry) {
338       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
339       if (pString) {
340         HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
341         iResult=Configure(pString->GetString().Data());
342       } else {
343         HLTError("configuration object \"%s\" has wrong type, required TObjString", pathBField);
344       }
345     } else {
346       HLTError("cannot fetch object \"%s\" from CDB", pathBField);
347     }
348   }  
349   return iResult;  
350 */
351 }
352
353
354 Int_t AliHLTTPCCAGlobalMergerComponent::Configure( const char* arguments )
355 {
356   //* Set parameters
357
358   Int_t iResult=EINVAL;
359   if (!arguments) return iResult;
360   
361   TString allArgs=arguments;
362   TString argument;
363   Int_t bMissingParam=0;
364   
365   TObjArray* pTokens=allArgs.Tokenize(" ");
366
367   Int_t nArgs =  pTokens ?pTokens->GetEntries() :0;
368
369   for (int i=0; i<nArgs; i++ ){
370     argument=((TObjString*)pTokens->At(i))->GetString();
371     if (argument.IsNull()){
372     }
373     else if (argument.CompareTo("-solenoidBz")==0 ){
374       if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;  
375       fSolenoidBz = ((TObjString*)pTokens->At(i))->GetString().Atof();
376       HLTInfo("Magnetic Field set to: %f", fSolenoidBz );
377     }
378     else {
379       HLTError("Unknown option %s ", argument.Data());
380       iResult=-EINVAL;
381     }
382   }
383   delete pTokens;
384
385   if (bMissingParam) {
386     HLTError("Specifier missed for %s", argument.Data());    
387     iResult=-EINVAL;
388   }
389
390   return iResult;
391 }
392