1) Serious bug fix in the backward extrapolation of tracklets (thanks to Matthias...
[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 #include "AliHLTTPCCASliceOutput.h"
45
46 #include "AliCDBEntry.h"
47 #include "AliCDBManager.h"
48 #include "TObjString.h"
49 #include "TObjArray.h"
50
51 #include <climits>
52 #include <cstdlib>
53 #include <cerrno>
54
55
56 // ROOT macro for the implementation of ROOT specific class methods
57 ClassImp( AliHLTTPCCAGlobalMergerComponent )
58
59
60 AliHLTTPCCAGlobalMergerComponent::AliHLTTPCCAGlobalMergerComponent()
61     : fGlobalMerger( 0 ), fSolenoidBz( 0 )
62 {
63   // see header file for class documentation
64 }
65
66 // Public functions to implement AliHLTComponent's interface.
67 // These functions are required for the registration process
68
69 const char *AliHLTTPCCAGlobalMergerComponent::GetComponentID()
70 {
71   // see header file for class documentation
72   return "TPCCAGlobalMerger";
73 }
74
75 void AliHLTTPCCAGlobalMergerComponent::GetInputDataTypes( AliHLTComponentDataTypeList &list )
76 {
77   // see header file for class documentation
78   list.clear();
79   list.push_back( AliHLTTPCCADefinitions::fgkTrackletsDataType );
80   //list.push_back( AliHLTTPCDefinitions::fgkTrackSegmentsDataType );
81   //list.push_back( AliHLTTPCDefinitions::fgkVertexDataType );
82 }
83
84 AliHLTComponentDataType AliHLTTPCCAGlobalMergerComponent::GetOutputDataType()
85 {
86   // see header file for class documentation
87   return AliHLTTPCDefinitions::fgkTracksDataType;
88 }
89
90 void AliHLTTPCCAGlobalMergerComponent::GetOutputDataSize( unsigned long &constBase, double &inputMultiplier )
91 {
92   // see header file for class documentation
93   // XXX TODO: Find more realistic values.
94   constBase = 0;
95   inputMultiplier = 1.0;
96 }
97
98 AliHLTComponent *AliHLTTPCCAGlobalMergerComponent::Spawn()
99 {
100   // see header file for class documentation
101   return new AliHLTTPCCAGlobalMergerComponent;
102 }
103
104
105
106
107 void AliHLTTPCCAGlobalMergerComponent::SetDefaultConfiguration()
108 {
109   // Set default configuration for the CA merger component
110   // Some parameters can be later overwritten from the OCDB
111
112   fSolenoidBz = 5.;
113 }
114
115 int AliHLTTPCCAGlobalMergerComponent::ReadConfigurationString(  const char* arguments )
116 {
117   // Set configuration parameters for the CA merger component from the string
118
119   int iResult = 0;
120   if ( !arguments ) return iResult;
121
122   TString allArgs = arguments;
123   TString argument;
124   int bMissingParam = 0;
125
126   TObjArray* pTokens = allArgs.Tokenize( " " );
127
128   int nArgs =  pTokens ? pTokens->GetEntries() : 0;
129
130   for ( int i = 0; i < nArgs; i++ ) {
131     argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
132     if ( argument.IsNull() ) continue;
133
134     if ( argument.CompareTo( "-solenoidBz" ) == 0 ) {
135       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
136       fSolenoidBz = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
137       HLTInfo( "Magnetic Field set to: %f", fSolenoidBz );
138       continue;
139     }
140
141     HLTError( "Unknown option \"%s\"", argument.Data() );
142     iResult = -EINVAL;
143   }
144   delete pTokens;
145
146   if ( bMissingParam ) {
147     HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
148     iResult = -EINVAL;
149   }
150
151   return iResult;
152 }
153
154
155 int AliHLTTPCCAGlobalMergerComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
156 {
157   // see header file for class documentation
158
159   const char* defaultNotify = "";
160
161   if ( !cdbEntry ) {
162     cdbEntry = "HLT/ConfigTPC/TPCCAGlobalMerger";
163     defaultNotify = " (default)";
164     chainId = 0;
165   }
166
167   HLTInfo( "configure from entry \"%s\"%s, chain id %s", cdbEntry, defaultNotify, ( chainId != NULL && chainId[0] != 0 ) ? chainId : "<none>" );
168   AliCDBEntry *pEntry = AliCDBManager::Instance()->Get( cdbEntry );//,GetRunNo());
169
170   if ( !pEntry ) {
171     HLTError( "cannot fetch object \"%s\" from CDB", cdbEntry );
172     return -EINVAL;
173   }
174
175   TObjString* pString = dynamic_cast<TObjString*>( pEntry->GetObject() );
176
177   if ( !pString ) {
178     HLTError( "configuration object \"%s\" has wrong type, required TObjString", cdbEntry );
179     return -EINVAL;
180   }
181
182   HLTInfo( "received configuration object string: \"%s\"", pString->GetString().Data() );
183
184   return  ReadConfigurationString( pString->GetString().Data() );
185 }
186
187
188
189 int AliHLTTPCCAGlobalMergerComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
190 {
191   // Configure the component
192   // There are few levels of configuration,
193   // parameters which are set on one step can be overwritten on the next step
194
195   //* read hard-coded values
196
197   SetDefaultConfiguration();
198
199   //* read the default CDB entry
200
201   int iResult1 = ReadCDBEntry( NULL, chainId );
202
203   //* read magnetic field
204
205   int iResult2 = ReadCDBEntry( kAliHLTCDBSolenoidBz, chainId );
206
207   //* read the actual CDB entry if required
208
209   int iResult3 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) : 0;
210
211   //* read extra parameters from input (if they are)
212
213   int iResult4 = 0;
214
215   if ( commandLine && commandLine[0] != '\0' ) {
216     HLTInfo( "received configuration string from HLT framework: \"%s\"", commandLine );
217     iResult4 = ReadConfigurationString( commandLine );
218   }
219
220
221   // Initialize the merger
222
223   AliHLTTPCCAParam param;
224
225   {
226     // get gemetry
227     int iSec = 0;
228     float inRmin = 83.65;
229     float outRmax = 247.7;
230     float plusZmin = 0.0529937;
231     float plusZmax = 249.778;
232     float minusZmin = -249.645;
233     float minusZmax = -0.0799937;
234     float dalpha = 0.349066;
235     float alpha = 0.174533 + dalpha * iSec;
236     bool zPlus = ( iSec < 18 );
237     float zMin =  zPlus ? plusZmin : minusZmin;
238     float zMax =  zPlus ? plusZmax : minusZmax;
239     int nRows = AliHLTTPCTransform::GetNRows();
240     float padPitch = 0.4;
241     float sigmaZ = 0.228808;
242     float *rowX = new float [nRows];
243     for ( int irow = 0; irow < nRows; irow++ ) {
244       rowX[irow] = AliHLTTPCTransform::Row2X( irow );
245     }
246
247     param.Initialize( iSec, nRows, rowX, alpha, dalpha,
248                       inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, fSolenoidBz );
249     delete[] rowX;
250   }
251
252
253   fGlobalMerger->SetSliceParam( param );
254
255   return iResult1 ? iResult1 : ( iResult2 ? iResult2 : ( iResult3 ? iResult3 : iResult4 ) );
256 }
257
258
259
260
261 int AliHLTTPCCAGlobalMergerComponent::DoInit( int argc, const char** argv )
262 {
263   // see header file for class documentation
264
265   if ( fGlobalMerger ) {
266     return EINPROGRESS;
267   }
268
269   fGlobalMerger = new AliHLTTPCCAMerger();
270
271   TString arguments = "";
272   for ( int i = 0; i < argc; i++ ) {
273     if ( !arguments.IsNull() ) arguments += " ";
274     arguments += argv[i];
275   }
276
277   return Configure( NULL, NULL, arguments.Data()  );
278 }
279
280 int AliHLTTPCCAGlobalMergerComponent::Reconfigure( const char* cdbEntry, const char* chainId )
281 {
282   // Reconfigure the component from OCDB
283
284   return Configure( cdbEntry, chainId, NULL );
285 }
286
287
288
289 int AliHLTTPCCAGlobalMergerComponent::DoDeinit()
290 {
291   // see header file for class documentation
292   delete fGlobalMerger;
293   fGlobalMerger = 0;
294
295   return 0;
296 }
297
298 int AliHLTTPCCAGlobalMergerComponent::DoEvent( const AliHLTComponentEventData &evtData,
299     const AliHLTComponentBlockData *blocks, AliHLTComponentTriggerData &/*trigData*/,
300     AliHLTUInt8_t *outputPtr, AliHLTUInt32_t &size, AliHLTComponentBlockDataList &outputBlocks )
301 {
302   // see header file for class documentation
303   int iResult = 0;
304   unsigned int maxBufferSize = size;
305
306   size = 0;
307
308   if ( !outputPtr ) {
309     return -ENOSPC;
310   }
311   if ( !IsDataEvent() ) {
312     return 0;
313   }
314
315   fGlobalMerger->Clear();
316
317   const AliHLTComponentBlockData *const blocksEnd = blocks + evtData.fBlockCnt;
318   for ( const AliHLTComponentBlockData *block = blocks; block < blocksEnd; ++block ) {
319     if ( block->fDataType != AliHLTTPCCADefinitions::fgkTrackletsDataType ) {
320       continue;
321     }
322
323     int slice = AliHLTTPCDefinitions::GetMinSliceNr( *block );
324     if ( slice < 0 || slice >= AliHLTTPCTransform::GetNSlice() ) {
325       HLTError( "invalid slice number %d extracted from specification 0x%08lx,  skipping block of type %s",
326                 slice, block->fSpecification, DataType2Text( block->fDataType ).c_str() );
327       // just remember the error, if there are other valid blocks ignore the error, return code otherwise
328       iResult = -EBADF;
329       continue;
330     }
331
332     if ( slice != AliHLTTPCDefinitions::GetMaxSliceNr( *block ) ) {
333       // the code was not written for/ never used with multiple slices in one data block/ specification
334       HLTWarning( "specification 0x%08lx indicates multiple slices in data block %s: never used before, please audit the code",
335                   block->fSpecification, DataType2Text( block->fDataType ).c_str() );
336     }
337     AliHLTTPCCASliceOutput *sliceOut =  reinterpret_cast<AliHLTTPCCASliceOutput *>( block->fPtr );
338     sliceOut->SetPointers();
339     fGlobalMerger->SetSliceData( slice, sliceOut );
340   }
341   fGlobalMerger->Reconstruct();
342
343   const AliHLTTPCCAMergerOutput *mergerOutput = fGlobalMerger->Output();
344
345
346   // Fill output tracks
347
348   unsigned int mySize = 0;
349
350   {
351     // check if there was enough space in the output buffer
352
353     int nTracks = mergerOutput->NTracks();
354
355     AliHLTTPCTrackArray array( nTracks );
356
357     int nClusters = 0;
358     for ( int itr = 0; itr < nTracks; itr++ ) {
359
360       // convert AliHLTTPCCAMergedTrack to AliHLTTPCTrack
361
362       const AliHLTTPCCAMergedTrack &track = mergerOutput->Track( itr );
363
364       AliHLTTPCTrack out;
365
366       // first convert to AliExternalTrackParam
367
368       AliExternalTrackParam tp, tpEnd;
369       AliHLTTPCCATrackConvertor::GetExtParam( track.InnerParam(), tp, 0 );
370       AliHLTTPCCATrackConvertor::GetExtParam( track.OuterParam(), tpEnd, 0 );
371
372       // set parameters, with rotation to global coordinates
373
374       out.SetCharge( ( int ) tp.GetSign() );
375       out.SetPt( TMath::Abs( tp.GetSignedPt() ) );
376       out.SetPsi( fmod( TMath::ASin( tp.GetSnp() ) + track.InnerAlpha() , 2*TMath::Pi() ) );
377       out.SetTgl( tp.GetTgl() );
378       {
379         float sinA = TMath::Sin( track.InnerAlpha() );
380         float cosA = TMath::Cos( track.InnerAlpha() );
381
382         out.SetFirstPoint( tp.GetX()*cosA - tp.GetY()*sinA,
383                            tp.GetX()*sinA + tp.GetY()*cosA,
384                            tp.GetZ() );
385       }
386
387       {
388         float sinA = TMath::Sin( track.OuterAlpha() );
389         float cosA = TMath::Cos( track.OuterAlpha() );
390
391         out.SetLastPoint( tpEnd.GetX()*cosA - tpEnd.GetY()*sinA,
392                           tpEnd.GetX()*sinA + tpEnd.GetY()*cosA,
393                           tpEnd.GetZ() );
394       }
395
396       // set parameter errors w/o rotation, as it is done in AliHLTTPCTrackArray
397
398       out.SetY0err( tp.GetSigmaY2() );
399       out.SetZ0err( tp.GetSigmaZ2() );
400       out.SetPterr( tp.GetSigma1Pt2() );
401       out.SetPsierr( tp.GetSigmaSnp2() );
402       out.SetTglerr( tp.GetSigmaTgl2() );
403
404       // set cluster ID's
405
406       unsigned int hitID[1000];
407       for ( int i = 0; i < track.NClusters(); i++ ) hitID[i] = mergerOutput->ClusterId( track.FirstClusterRef() + i );
408
409       out.SetNHits( track.NClusters() );
410       out.SetHits( track.NClusters(), hitID );
411
412       out.SetSector( -1 );
413       out.CalculateHelix();
414       if ( !out.CheckConsistency() )  *( array.NextTrack() ) = out;
415       nClusters += track.NClusters();
416     }
417
418
419     if ( sizeof( AliHLTTPCTrackletData ) + nTracks*sizeof( AliHLTTPCTrackSegmentData ) + nClusters*sizeof( unsigned int )
420          > maxBufferSize ) {
421       iResult = -ENOSPC;
422     } else {
423       AliHLTTPCTrackletData *outPtr = ( AliHLTTPCTrackletData* )( outputPtr );
424       unsigned int nOutTracks = 0;
425       mySize = array.WriteTracks( nOutTracks, outPtr->fTracklets );
426       mySize += sizeof( AliHLTTPCTrackletData );
427       outPtr->fTrackletCnt = nOutTracks;
428     }
429   }
430
431   AliHLTComponentBlockData resultData;
432   FillBlockData( resultData );
433   resultData.fOffset = 0;
434   resultData.fSize = mySize;
435   resultData.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( 0, 35, 0, 5 );
436   outputBlocks.push_back( resultData );
437   size = resultData.fSize;
438
439   HLTInfo( "CAGlobalMerger:: output %d tracks", mergerOutput->NTracks() );
440
441   return iResult;
442 }
443