coverity warnings 10077 10076 fixed
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCAGlobalMergerComponent.cxx
index 73b3c60..24c005f 100644 (file)
@@ -29,24 +29,28 @@ using namespace std;
 #endif
 
 #include "AliHLTTPCCAGlobalMergerComponent.h"
+#include "AliHLTTPCCASliceOutput.h"
+
+#include "AliHLTTPCCADef.h"
+#include "AliHLTTPCCAMerger.h"
 #include "AliHLTTPCCAMergerOutput.h"
+#include "AliHLTTPCCATrackConvertor.h"
+
+#include "AliHLTTPCGMMerger.h"
+#include "AliHLTTPCGMMergedTrack.h"
+
+#include "AliHLTTPCDefinitions.h"
 #include "AliHLTTPCTransform.h"
-#include "AliHLTTPCCAMerger.h"
-#include "AliHLTTPCVertex.h"
-#include "AliHLTTPCVertexData.h"
 #include "AliHLTTPCTrackSegmentData.h"
 #include "AliHLTTPCTrack.h"
 #include "AliHLTTPCTrackArray.h"
 #include "AliHLTTPCTrackletDataFormat.h"
-#include "AliHLTTPCCADef.h"
-#include "AliHLTTPCDefinitions.h"
-#include "AliHLTTPCCATrackConvertor.h"
-#include "AliHLTTPCCASliceOutput.h"
 
 #include "AliCDBEntry.h"
 #include "AliCDBManager.h"
 #include "TObjString.h"
 #include "TObjArray.h"
+#include "AliHLTExternalTrackParam.h"
 
 #include <climits>
 #include <cstdlib>
@@ -57,15 +61,23 @@ using namespace std;
 ClassImp( AliHLTTPCCAGlobalMergerComponent )
 
 
-// global object for registration
-AliHLTTPCCAGlobalMergerComponent AliHLTTPCCAGlobalMergerComponent::fgAliHLTTPCCAGlobalMergerComponent;
-
 AliHLTTPCCAGlobalMergerComponent::AliHLTTPCCAGlobalMergerComponent()
-    : fGlobalMerger( 0 ), fSolenoidBz( 5 )
+: AliHLTProcessor(), fVersion(1), fGlobalMergerVersion0( 0 ), fGlobalMerger(0), fSolenoidBz( 0 ), fClusterErrorCorrectionY(0), fClusterErrorCorrectionZ(0), fBenchmark("GlobalMerger")
 {
   // see header file for class documentation
 }
 
+AliHLTTPCCAGlobalMergerComponent::AliHLTTPCCAGlobalMergerComponent( const AliHLTTPCCAGlobalMergerComponent & ):AliHLTProcessor(), fVersion(1), fGlobalMergerVersion0( 0 ), fGlobalMerger(0), fSolenoidBz( 0 ), fClusterErrorCorrectionY(0), fClusterErrorCorrectionZ(0), fBenchmark("GlobalMerger")
+{
+// dummy
+}
+
+AliHLTTPCCAGlobalMergerComponent &AliHLTTPCCAGlobalMergerComponent::operator=( const AliHLTTPCCAGlobalMergerComponent & )
+{
+  // dummy
+  return *this;
+}
+
 // Public functions to implement AliHLTComponent's interface.
 // These functions are required for the registration process
 
@@ -87,7 +99,8 @@ void AliHLTTPCCAGlobalMergerComponent::GetInputDataTypes( AliHLTComponentDataTyp
 AliHLTComponentDataType AliHLTTPCCAGlobalMergerComponent::GetOutputDataType()
 {
   // see header file for class documentation
-  return AliHLTTPCDefinitions::fgkTracksDataType;
+  //return AliHLTTPCDefinitions::fgkTracksDataType; // old
+  return kAliHLTDataTypeTrack|kAliHLTDataOriginTPC;
 }
 
 void AliHLTTPCCAGlobalMergerComponent::GetOutputDataSize( unsigned long &constBase, double &inputMultiplier )
@@ -104,16 +117,148 @@ AliHLTComponent *AliHLTTPCCAGlobalMergerComponent::Spawn()
   return new AliHLTTPCCAGlobalMergerComponent;
 }
 
-int AliHLTTPCCAGlobalMergerComponent::DoInit( int argc, const char** argv )
+
+void AliHLTTPCCAGlobalMergerComponent::SetDefaultConfiguration()
+{
+  // Set default configuration for the CA merger component
+  // Some parameters can be later overwritten from the OCDB
+
+  fVersion = 1;
+  fSolenoidBz = -5.00668;
+  fClusterErrorCorrectionY = 0;
+  fClusterErrorCorrectionZ = 1.1;
+  fBenchmark.Reset();
+  fBenchmark.SetTimer(0,"total");
+  fBenchmark.SetTimer(1,"reco");    
+}
+
+int AliHLTTPCCAGlobalMergerComponent::ReadConfigurationString(  const char* arguments )
+{
+  // Set configuration parameters for the CA merger component from the string
+
+  int iResult = 0;
+  if ( !arguments ) return iResult;
+
+  TString allArgs = arguments;
+  TString argument;
+  int bMissingParam = 0;
+
+  TObjArray* pTokens = allArgs.Tokenize( " " );
+
+  int nArgs =  pTokens ? pTokens->GetEntries() : 0;
+
+  for ( int i = 0; i < nArgs; i++ ) {
+    argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
+    if ( argument.IsNull() ) continue;
+
+    if ( argument.CompareTo( "-version" ) == 0 ) {
+      if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
+      fVersion  = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
+      HLTInfo( "Merger version set to: %d", fVersion );
+      continue;
+    }
+
+    if ( argument.CompareTo( "-solenoidBz" ) == 0 ) {
+      if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
+      HLTWarning("argument -solenoidBz is deprecated, magnetic field set up globally (%f)", GetBz());
+      continue;
+    }
+
+    if ( argument.CompareTo( "-errorCorrectionY" ) == 0 ) {
+      if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
+      fClusterErrorCorrectionY = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
+      HLTInfo( "Cluster Y error correction factor set to: %f", fClusterErrorCorrectionY );
+      continue;
+    }
+
+   if ( argument.CompareTo( "-errorCorrectionZ" ) == 0 ) {
+      if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
+      fClusterErrorCorrectionZ = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
+      HLTInfo( "Cluster Z error correction factor set to: %f", fClusterErrorCorrectionZ );
+      continue;
+    }
+
+    HLTError( "Unknown option \"%s\"", argument.Data() );
+    iResult = -EINVAL;
+  }
+  delete pTokens;
+
+  if ( bMissingParam ) {
+    HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
+    iResult = -EINVAL;
+  }
+
+  return iResult;
+}
+
+
+int AliHLTTPCCAGlobalMergerComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
 {
   // see header file for class documentation
-  if ( fGlobalMerger ) {
-    return EINPROGRESS;
+
+  const char* defaultNotify = "";
+
+  if ( !cdbEntry ) {
+    cdbEntry = "HLT/ConfigTPC/TPCCAGlobalMerger";
+    defaultNotify = " (default)";
+    chainId = 0;
+  }
+
+  HLTInfo( "configure from entry \"%s\"%s, chain id %s", cdbEntry, defaultNotify, ( chainId != NULL && chainId[0] != 0 ) ? chainId : "<none>" );
+  AliCDBEntry *pEntry = AliCDBManager::Instance()->Get( cdbEntry );//,GetRunNo());
+
+  if ( !pEntry ) {
+    HLTError( "cannot fetch object \"%s\" from CDB", cdbEntry );
+    return -EINVAL;
+  }
+
+  TObjString* pString = dynamic_cast<TObjString*>( pEntry->GetObject() );
+
+  if ( !pString ) {
+    HLTError( "configuration object \"%s\" has wrong type, required TObjString", cdbEntry );
+    return -EINVAL;
+  }
+
+  HLTInfo( "received configuration object string: \"%s\"", pString->GetString().Data() );
+
+  return  ReadConfigurationString( pString->GetString().Data() );
+}
+
+
+
+int AliHLTTPCCAGlobalMergerComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
+{
+  // Configure the component
+  // There are few levels of configuration,
+  // parameters which are set on one step can be overwritten on the next step
+
+  //* read hard-coded values
+
+  SetDefaultConfiguration();
+
+  //* read the default CDB entry
+
+  int iResult1 = ReadCDBEntry( NULL, chainId );
+
+  //* read magnetic field
+
+  fSolenoidBz = GetBz();
+
+  //* read the actual CDB entry if required
+
+  int iResult2 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) : 0;
+
+  //* read extra parameters from input (if they are)
+
+  int iResult3 = 0;
+
+  if ( commandLine && commandLine[0] != '\0' ) {
+    HLTInfo( "received configuration string from HLT framework: \"%s\"", commandLine );
+    iResult3 = ReadConfigurationString( commandLine );
   }
 
-  // Initialize the merger
 
-  fGlobalMerger = new AliHLTTPCCAMerger();
+  // Initialize the merger
 
   AliHLTTPCCAParam param;
 
@@ -128,9 +273,9 @@ int AliHLTTPCCAGlobalMergerComponent::DoInit( int argc, const char** argv )
     float minusZmax = -0.0799937;
     float dalpha = 0.349066;
     float alpha = 0.174533 + dalpha * iSec;
-    bool zPlus = ( iSec < 18 );
-    float zMin =  zPlus ? plusZmin : minusZmin;
-    float zMax =  zPlus ? plusZmax : minusZmax;
+    bool zPlus = 1;//( iSec < 18 );
+    float zMin =  plusZmin; //zPlus ? plusZmin : minusZmin;
+    float zMax =  plusZmax; //zPlus ? plusZmax : minusZmax;
     int nRows = AliHLTTPCTransform::GetNRows();
     float padPitch = 0.4;
     float sigmaZ = 0.228808;
@@ -141,31 +286,58 @@ int AliHLTTPCCAGlobalMergerComponent::DoInit( int argc, const char** argv )
 
     param.Initialize( iSec, nRows, rowX, alpha, dalpha,
                       inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, fSolenoidBz );
+
+    if( fClusterErrorCorrectionY>1.e-4 ) param.SetClusterError2CorrectionY( fClusterErrorCorrectionY*fClusterErrorCorrectionY );
+    if( fClusterErrorCorrectionZ>1.e-4 ) param.SetClusterError2CorrectionZ( fClusterErrorCorrectionZ*fClusterErrorCorrectionZ );
+    param.Update();
+
     delete[] rowX;
   }
 
 
-  fGlobalMerger->SetSliceParam( param );
+  if( fVersion==0 ) fGlobalMergerVersion0->SetSliceParam( param );
+  else fGlobalMerger->SetSliceParam( param );
 
-  int iResult = 0;
+  return iResult1 ? iResult1 : ( iResult2 ? iResult2 : iResult3 );
+}
+
+
+
+
+int AliHLTTPCCAGlobalMergerComponent::DoInit( int argc, const char** argv )
+{
+  // see header file for class documentation
+
+  if ( fGlobalMergerVersion0 || fGlobalMerger ) {
+    return EINPROGRESS;
+  }
+
+  fGlobalMergerVersion0 = new AliHLTTPCCAMerger();
+  fGlobalMerger         = new AliHLTTPCGMMerger();
 
   TString arguments = "";
   for ( int i = 0; i < argc; i++ ) {
-    TString argument = argv[i];
     if ( !arguments.IsNull() ) arguments += " ";
-    arguments += argument;
+    arguments += argv[i];
   }
-  if ( !arguments.IsNull() ) {
-    iResult = Configure( arguments.Data() );
-  } else {
-    iResult = Reconfigure( NULL, NULL );
-  }
-  return iResult;
+
+  return Configure( NULL, NULL, arguments.Data()  );
+}
+
+int AliHLTTPCCAGlobalMergerComponent::Reconfigure( const char* cdbEntry, const char* chainId )
+{
+  // Reconfigure the component from OCDB
+
+  return Configure( cdbEntry, chainId, NULL );
 }
 
+
+
 int AliHLTTPCCAGlobalMergerComponent::DoDeinit()
 {
   // see header file for class documentation
+  delete fGlobalMergerVersion0;
+  fGlobalMergerVersion0 = 0;
   delete fGlobalMerger;
   fGlobalMerger = 0;
 
@@ -188,8 +360,11 @@ int AliHLTTPCCAGlobalMergerComponent::DoEvent( const AliHLTComponentEventData &e
   if ( !IsDataEvent() ) {
     return 0;
   }
+  fBenchmark.StartNewEvent();
+  fBenchmark.Start(0);
 
-  fGlobalMerger->Clear();
+  if( fVersion==0 )  fGlobalMergerVersion0->Clear();
+  else fGlobalMerger->Clear();
 
   const AliHLTComponentBlockData *const blocksEnd = blocks + evtData.fBlockCnt;
   for ( const AliHLTComponentBlockData *block = blocks; block < blocksEnd; ++block ) {
@@ -197,6 +372,8 @@ int AliHLTTPCCAGlobalMergerComponent::DoEvent( const AliHLTComponentEventData &e
       continue;
     }
 
+    fBenchmark.AddInput(block->fSize);
+
     int slice = AliHLTTPCDefinitions::GetMinSliceNr( *block );
     if ( slice < 0 || slice >= AliHLTTPCTransform::GetNSlice() ) {
       HLTError( "invalid slice number %d extracted from specification 0x%08lx,  skipping block of type %s",
@@ -212,181 +389,174 @@ int AliHLTTPCCAGlobalMergerComponent::DoEvent( const AliHLTComponentEventData &e
                   block->fSpecification, DataType2Text( block->fDataType ).c_str() );
     }
     AliHLTTPCCASliceOutput *sliceOut =  reinterpret_cast<AliHLTTPCCASliceOutput *>( block->fPtr );
-    sliceOut->SetPointers();
-    fGlobalMerger->SetSliceData( slice, sliceOut );
+    //sliceOut->SetPointers();
+    if( fVersion==0 ) fGlobalMergerVersion0->SetSliceData( slice, sliceOut );
+    else fGlobalMerger->SetSliceData( slice, sliceOut );
+
+       /*char filename[256];
+       sprintf(filename, "debug%d.out", slice);
+       FILE* fp = fopen(filename, "w+b");
+       if (fp == NULL) printf("Error!!!\n");
+       fwrite(sliceOut, 1, sliceOut->EstimateSize(sliceOut->NTracks(), sliceOut->NTrackClusters()), fp);
+       fclose(fp);*/
   }
-  fGlobalMerger->Reconstruct();
-
-  const AliHLTTPCCAMergerOutput *mergerOutput = fGlobalMerger->Output();
-
-
-  // Fill output tracks
-
-  unsigned int mySize = 0;
-
-  {
-    // check if there was enough space in the output buffer
-
-    int nTracks = mergerOutput->NTracks();
-
-    AliHLTTPCTrackArray array( nTracks );
-
-    int nClusters = 0;
-    for ( int itr = 0; itr < nTracks; itr++ ) {
-
-      // convert AliHLTTPCCAMergedTrack to AliHLTTPCTrack
-
-      const AliHLTTPCCAMergedTrack &track = mergerOutput->Track( itr );
-      AliHLTTPCTrack out;
-
-      // first convert to AliExternalTrackParam ( Kappa to Pt )
-
-      AliExternalTrackParam tp, tpEnd;
-      AliHLTTPCCATrackConvertor::GetExtParam( track.InnerParam(), tp, 0 );
-      AliHLTTPCCATrackConvertor::GetExtParam( track.OuterParam(), tpEnd, 0 );
-
-      // set parameters, with rotation to global coordinates
-
-      out.SetCharge( ( int ) tp.GetSign() );
-      out.SetPt( TMath::Abs( tp.GetSignedPt() ) );
-      out.SetPsi( fmod( TMath::ASin( tp.GetSnp() ) + track.InnerAlpha() , 2*TMath::Pi() ) );
-      out.SetTgl( tp.GetTgl() );
-      {
-        float sinA = TMath::Sin( track.InnerAlpha() );
-        float cosA = TMath::Cos( track.InnerAlpha() );
-
-        out.SetFirstPoint( tp.GetX()*cosA - tp.GetY()*sinA,
-                           tp.GetX()*sinA + tp.GetY()*cosA,
-                           tp.GetZ() );
-      }
-
-      {
-        float sinA = TMath::Sin( track.OuterAlpha() );
-        float cosA = TMath::Cos( track.OuterAlpha() );
-
-        out.SetLastPoint( tpEnd.GetX()*cosA - tpEnd.GetY()*sinA,
-                          tpEnd.GetX()*sinA + tpEnd.GetY()*cosA,
-                          tpEnd.GetZ() );
-      }
-
-      // set parameter errors w/o rotation, as it is done in AliHLTTPCTrackArray
-
-      out.SetY0err( tp.GetSigmaY2() );
-      out.SetZ0err( tp.GetSigmaZ2() );
-      float h = -out.GetPt() * out.GetPt();
-      out.SetPterr( h*h*tp.GetSigma1Pt2() );
-      h = 1. / TMath::Sqrt( 1 - out.GetSnp() * out.GetSnp() );
-      out.SetPsierr( h*h*tp.GetSigmaSnp2() );
-      out.SetTglerr( tp.GetSigmaTgl2() );
-
-      // set cluster ID's
-
-      unsigned int hitID[1000];
-      for ( int i = 0; i < track.NClusters(); i++ ) hitID[i] = mergerOutput->ClusterId( track.FirstClusterRef() + i );
-
-      out.SetNHits( track.NClusters() );
-      out.SetHits( track.NClusters(), hitID );
-
-      out.SetSector( -1 );
-      out.CalculateHelix();
-      if ( !out.CheckConsistency() )  *( array.NextTrack() ) = out;
-      nClusters += track.NClusters();
+  fBenchmark.Start(1);
+  if( fVersion==0 ) fGlobalMergerVersion0->Reconstruct();
+  else fGlobalMerger->Reconstruct();
+  fBenchmark.Stop(1);
+
+  // Fill output 
+
+  if( fVersion==0 ){
+
+    const AliHLTTPCCAMergerOutput *mergerOutput = fGlobalMergerVersion0->Output();
+
+    unsigned int mySize = 0;
+    {
+      AliHLTTracksData* outPtr = ( AliHLTTracksData* )( outputPtr );
+      
+      AliHLTExternalTrackParam* currOutTrack = outPtr->fTracklets;
+      
+      mySize =   ( ( AliHLTUInt8_t * )currOutTrack ) -  ( ( AliHLTUInt8_t * )outputPtr );
+      
+      outPtr->fCount = 0;
+      
+      int nTracks = mergerOutput->NTracks();
+      
+      for ( int itr = 0; itr < nTracks; itr++ ) {
+       
+       // convert AliHLTTPCCAMergedTrack to AliHLTTrack
+       
+       const AliHLTTPCCAMergedTrack &track = mergerOutput->Track( itr );
+       
+       unsigned int dSize = sizeof( AliHLTExternalTrackParam ) + track.NClusters() * sizeof( unsigned int );
+       
+       if ( mySize + dSize > maxBufferSize ) {
+         HLTWarning( "Output buffer size exceed (buffer size %d, current size %d), %d tracks are not stored", maxBufferSize, mySize, nTracks - itr + 1 );
+         iResult = -ENOSPC;
+         break;
+       }
+       
+       // first convert to AliExternalTrackParam
+       
+       AliExternalTrackParam tp, tpEnd;
+       AliHLTTPCCATrackConvertor::GetExtParam( track.InnerParam(), tp,  track.InnerAlpha() );
+       AliHLTTPCCATrackConvertor::GetExtParam( track.OuterParam(), tpEnd, track.OuterAlpha() );
+       
+       // normalize the angle to +-Pi
+       
+       currOutTrack->fAlpha = tp.GetAlpha() - CAMath::Nint(tp.GetAlpha()/CAMath::TwoPi())*CAMath::TwoPi();      
+       currOutTrack->fX = tp.GetX();
+       currOutTrack->fY = tp.GetY();
+       currOutTrack->fZ = tp.GetZ();      
+       {
+         float sinA = TMath::Sin( track.OuterAlpha() - track.InnerAlpha());
+         float cosA = TMath::Cos( track.OuterAlpha() - track.InnerAlpha());
+         currOutTrack->fLastX = tpEnd.GetX()*cosA - tpEnd.GetY()*sinA;
+         currOutTrack->fLastY = tpEnd.GetX()*sinA + tpEnd.GetY()*cosA;
+         currOutTrack->fLastZ = tpEnd.GetZ();
+       }
+       currOutTrack->fq1Pt = tp.GetSigned1Pt();
+       currOutTrack->fSinPsi = tp.GetSnp();
+       currOutTrack->fTgl = tp.GetTgl();
+       for( int i=0; i<15; i++ ) currOutTrack->fC[i] = tp.GetCovariance()[i];
+       currOutTrack->fTrackID = itr;
+       currOutTrack->fFlags = 0;
+       currOutTrack->fNPoints = track.NClusters();    
+       for ( int i = 0; i < track.NClusters(); i++ ) currOutTrack->fPointIDs[i] = mergerOutput->ClusterId( track.FirstClusterRef() + i );
+       
+       currOutTrack = ( AliHLTExternalTrackParam* )( (( Byte_t * )currOutTrack) + dSize );
+       mySize += dSize;
+       outPtr->fCount++;
+      }    
+
+      AliHLTComponentBlockData resultData;
+      FillBlockData( resultData );
+      resultData.fOffset = 0;
+      resultData.fSize = mySize;
+      resultData.fDataType = kAliHLTDataTypeTrack|kAliHLTDataOriginTPC;
+      resultData.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( 0, 35, 0, 5 );
+      outputBlocks.push_back( resultData );
+      fBenchmark.AddOutput(resultData.fSize);
+      
+      size = resultData.fSize;
     }
-
-
-    if ( sizeof( AliHLTTPCTrackletData ) + nTracks*sizeof( AliHLTTPCTrackSegmentData ) + nClusters*sizeof( unsigned int )
-         > maxBufferSize ) {
-      iResult = -ENOSPC;
-    } else {
-      AliHLTTPCTrackletData *outPtr = ( AliHLTTPCTrackletData* )( outputPtr );
-      unsigned int nOutTracks = 0;
-      mySize = array.WriteTracks( nOutTracks, outPtr->fTracklets );
-      mySize += sizeof( AliHLTTPCTrackletData );
-      outPtr->fTrackletCnt = nOutTracks;
-    }
-  }
-
-  AliHLTComponentBlockData resultData;
-  FillBlockData( resultData );
-  resultData.fOffset = 0;
-  resultData.fSize = mySize;
-  resultData.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( 0, 35, 0, 5 );
-  outputBlocks.push_back( resultData );
-  size = resultData.fSize;
-
-  HLTWarning("CAGlobalMerger:: output %d tracks",mergerOutput->NTracks());
-
-  return iResult;
-}
-
-
-
-int AliHLTTPCCAGlobalMergerComponent::Reconfigure( const char* /*cdbEntry*/, const char* /*chainId*/ )
-{
-  // see header file for class documentation
-
-
-  HLTWarning( "TODO: dummy Reconfigure() method" );
-  return 0;
-  /*
-
-  int iResult=0;
-  const char* pathBField=kAliHLTCDBSolenoidBz;
-
-  if (pathBField) {
-    HLTInfo("reconfigure B-Field from entry %s, chain id %s", pathBField,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
-    AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(pathBField);//,GetRunNo());
-    if (pEntry) {
-      TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
-      if (pString) {
-  HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
-  iResult=Configure(pString->GetString().Data());
-      } else {
-  HLTError("configuration object \"%s\" has wrong type, required TObjString", pathBField);
+    
+    HLTInfo( "CAGlobalMerger:: output %d tracks", mergerOutput->NTracks() );
+    fGlobalMergerVersion0->Clear();
+
+  } else { // new merger 
+
+    unsigned int mySize = 0;
+    {
+      AliHLTTracksData* outPtr = ( AliHLTTracksData* )( outputPtr );
+      AliHLTExternalTrackParam* currOutTrack = outPtr->fTracklets;
+      mySize =   ( ( AliHLTUInt8_t * )currOutTrack ) -  ( ( AliHLTUInt8_t * )outputPtr );
+      outPtr->fCount = 0;   
+      int nTracks = fGlobalMerger->NOutputTracks();
+
+      for ( int itr = 0; itr < nTracks; itr++ ) {
+
+       // convert AliHLTTPCGMMergedTrack to AliHLTTrack
+       
+       const AliHLTTPCGMMergedTrack &track = fGlobalMerger->OutputTracks()[ itr ];
+       if( !track.OK() ) continue;
+       unsigned int dSize = sizeof( AliHLTExternalTrackParam ) + track.NClusters() * sizeof( unsigned int );
+       
+       if ( mySize + dSize > maxBufferSize ) {
+         HLTWarning( "Output buffer size exceed (buffer size %d, current size %d), %d tracks are not stored", maxBufferSize, mySize, nTracks - itr + 1 );
+         iResult = -ENOSPC;
+         break;
+       }
+
+       // first convert to AliExternalTrackParam
+
+       AliExternalTrackParam tp;
+       track.GetParam().GetExtParam( tp,  track.GetAlpha() );
+      
+       // normalize the angle to +-Pi
+             
+       currOutTrack->fAlpha = tp.GetAlpha() - CAMath::Nint(tp.GetAlpha()/CAMath::TwoPi())*CAMath::TwoPi();      
+       currOutTrack->fX = tp.GetX();
+       currOutTrack->fY = tp.GetY();
+       currOutTrack->fZ = tp.GetZ();      
+       currOutTrack->fLastX = track.LastX();
+       currOutTrack->fLastY = track.LastY();
+       currOutTrack->fLastZ = track.LastZ();
+      
+       currOutTrack->fq1Pt = tp.GetSigned1Pt();
+       currOutTrack->fSinPsi = tp.GetSnp();
+       currOutTrack->fTgl = tp.GetTgl();
+       for( int i=0; i<15; i++ ) currOutTrack->fC[i] = tp.GetCovariance()[i];
+       currOutTrack->fTrackID = itr;
+       currOutTrack->fFlags = 0;
+       currOutTrack->fNPoints = track.NClusters();    
+       for ( int i = 0; i < track.NClusters(); i++ ) currOutTrack->fPointIDs[i] = fGlobalMerger->OutputClusterIds()[track.FirstClusterRef() + i ];
+       
+       currOutTrack = ( AliHLTExternalTrackParam* )( (( Byte_t * )currOutTrack) + dSize );
+       mySize += dSize;
+       outPtr->fCount++;
       }
-    } else {
-      HLTError("cannot fetch object \"%s\" from CDB", pathBField);
+  
+      AliHLTComponentBlockData resultData;
+      FillBlockData( resultData );
+      resultData.fOffset = 0;
+      resultData.fSize = mySize;
+      resultData.fDataType = kAliHLTDataTypeTrack|kAliHLTDataOriginTPC;
+      resultData.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( 0, 35, 0, 5 );
+      outputBlocks.push_back( resultData );
+      fBenchmark.AddOutput(resultData.fSize);
+      
+      size = resultData.fSize;
     }
-  }
-  return iResult;
-  */
-}
-
-
-int AliHLTTPCCAGlobalMergerComponent::Configure( const char* arguments )
-{
-  //* Set parameters
-
-  int iResult = 0;
-  if ( !arguments ) return iResult;
-
-  TString allArgs = arguments;
-  TString argument;
-  int bMissingParam = 0;
 
-  TObjArray* pTokens = allArgs.Tokenize( " " );
-
-  int nArgs =  pTokens ? pTokens->GetEntries() : 0;
-
-  for ( int i = 0; i < nArgs; i++ ) {
-    argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
-    if ( argument.IsNull() ) {
-    } else if ( argument.CompareTo( "-solenoidBz" ) == 0 ) {
-      if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
-      fSolenoidBz = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
-      HLTInfo( "Magnetic Field set to: %f", fSolenoidBz );
-    } else {
-      HLTError( "Unknown option %s ", argument.Data() );
-      iResult = -EINVAL;
-    }
-  }
-  delete pTokens;
+    HLTInfo( "CAGlobalMerger:: output %d tracks", fGlobalMerger->NOutputTracks() );
 
-  if ( bMissingParam ) {
-    HLTError( "Specifier missed for %s", argument.Data() );
-    iResult = -EINVAL;
+    fGlobalMerger->Clear();
   }
 
+  fBenchmark.Stop(0);
+  HLTInfo( fBenchmark.GetStatistics() );
   return iResult;
 }