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