]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
adding separate primary vertex and V0 finder components (Timur)
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 21 Jan 2011 11:37:33 +0000 (11:37 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 21 Jan 2011 11:37:33 +0000 (11:37 +0000)
HLT/CMakelibAliHLTGlobal.pkg
HLT/global/AliHLTPrimaryVertexFinderComponent.cxx [new file with mode: 0644]
HLT/global/AliHLTPrimaryVertexFinderComponent.h [new file with mode: 0644]
HLT/global/AliHLTV0FinderComponent.cxx [new file with mode: 0644]
HLT/global/AliHLTV0FinderComponent.h [new file with mode: 0644]
HLT/global/AliHLTVertexFinderBase.cxx [new file with mode: 0644]
HLT/global/AliHLTVertexFinderBase.h [new file with mode: 0644]

index f6cbe8c4c7c4fa2eb035662ffae12f3017bc036e..75b6ed60267f0f29a7e230233d08b9122b15b2af 100644 (file)
 # SHLIBS - Shared Libraries and objects for linking (Executables only)           #
 #--------------------------------------------------------------------------------#
 
-set ( CLASS_HDRS       AliHLTGlobalEsdConverterComponent.h AliHLTGlobalTrackMergerComponent.h AliHLTGlobalTrackMerger.h AliHLTGlobalAgent.h AliHLTGlobalDCSPublisherComponent.h AliHLTGlobalVertexerComponent.h AliHLTGlobalOfflineVertexerComponent.h AliHLTGlobalTrackMatcher.h AliHLTGlobalTrackMatcherComponent.h AliHLTGlobalVertexerHistoComponent.h AliHLTGlobalHistoComponent.h AliHLTGlobalHistoCollector.h physics/AliHLTV0HistoComponent.h physics/AliHLTCaloHistoComponent.h physics/AliHLTCaloHistoProducer.h physics/AliHLTCaloHistoInvMass.h physics/AliHLTCaloHistoMatchedTracks.h physics/AliHLTCaloHistoClusterEnergy.h physics/AliHLTCaloHistoCellEnergy.h physics/AliHLTMultiplicityCorrelations.h physics/AliHLTMultiplicityCorrelationsComponent.h)
+set ( CLASS_HDRS
+    AliHLTGlobalEsdConverterComponent.h
+    AliHLTGlobalTrackMergerComponent.h
+    AliHLTGlobalTrackMerger.h
+    AliHLTGlobalAgent.h
+    AliHLTGlobalDCSPublisherComponent.h
+    AliHLTGlobalVertexerComponent.h
+    AliHLTGlobalOfflineVertexerComponent.h
+    AliHLTGlobalTrackMatcher.h
+    AliHLTGlobalTrackMatcherComponent.h
+    AliHLTGlobalVertexerHistoComponent.h
+    AliHLTGlobalHistoComponent.h
+    AliHLTGlobalHistoCollector.h
+    AliHLTVertexFinderBase.h
+    AliHLTPrimaryVertexFinderComponent.h
+    AliHLTV0FinderComponent.h
+    physics/AliHLTV0HistoComponent.h
+    physics/AliHLTCaloHistoComponent.h
+    physics/AliHLTCaloHistoProducer.h
+    physics/AliHLTCaloHistoInvMass.h
+    physics/AliHLTCaloHistoMatchedTracks.h
+    physics/AliHLTCaloHistoClusterEnergy.h
+    physics/AliHLTCaloHistoCellEnergy.h
+    physics/AliHLTMultiplicityCorrelations.h
+    physics/AliHLTMultiplicityCorrelationsComponent.h
+    )
 
 string ( REPLACE ".h" ".cxx" MODULE_SRCS "${CLASS_HDRS}" )
 
diff --git a/HLT/global/AliHLTPrimaryVertexFinderComponent.cxx b/HLT/global/AliHLTPrimaryVertexFinderComponent.cxx
new file mode 100644 (file)
index 0000000..c41e70b
--- /dev/null
@@ -0,0 +1,347 @@
+// $Id$
+
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Timur Pocheptsov <Timur.Pocheptsov@cern.ch>           *
+//*                  for The ALICE HLT Project.                            *
+//*                                                                        *
+//* Permission to use, copy, modify and distribute this software and its   *
+//* documentation strictly for non-commercial purposes is hereby granted   *
+//* without fee, provided that the above copyright notice appears in all   *
+//* copies and that both the copyright notice and this permission notice   *
+//* appear in the supporting documentation. The authors make no claims     *
+//* about the suitability of this software for any purpose. It is          *
+//* provided "as is" without express or implied warranty.                  *
+//**************************************************************************
+
+/// @file   AliHLTPrimaryVertexFinderComponent.cxx
+/// @author Timur Pocheptsov
+/// @date   2010-12-26
+/// @brief  Primary vertex finder component
+///
+
+#include <algorithm>
+#include <cerrno>
+
+#include "TString.h"
+#include "TMath.h"
+
+#include "AliHLTPrimaryVertexFinderComponent.h"
+#include "AliExternalTrackParam.h"
+#include "AliHLTDataTypes.h"
+
+ClassImp(AliHLTPrimaryVertexFinderComponent)
+
+const double AliHLTPrimaryVertexFinderComponent::fgDefaultDeviation = 4.;
+
+//________________________________________________________________________
+AliHLTPrimaryVertexFinderComponent::AliHLTPrimaryVertexFinderComponent()
+                             : fPrimaryOutput(),
+                               fPrimaryVtx(),
+                               fFitTracksToVertex(true),
+                               fConstrainedTrackDeviation(fgDefaultDeviation)
+{
+  //Default ctor.
+}
+
+//________________________________________________________________________
+const char* AliHLTPrimaryVertexFinderComponent::GetComponentID()
+{
+  //Component's "name".
+  return "PrimaryVertexFinder";
+}
+
+//________________________________________________________________________
+void AliHLTPrimaryVertexFinderComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
+{
+  //Input to the primary vertex finder:
+  //a)tracks from ESD object;
+  //b)hlt tracks (ITS)
+  //c)hlt tracks (TPC)
+  list.clear();
+
+  list.push_back(kAliHLTDataTypeESDObject);
+  list.push_back(kAliHLTDataTypeTrack | kAliHLTDataOriginITS);
+  list.push_back(kAliHLTDataTypeTrack | kAliHLTDataOriginTPC);
+}
+
+//________________________________________________________________________
+AliHLTComponentDataType AliHLTPrimaryVertexFinderComponent::GetOutputDataType()
+{
+  //Data type of output.
+  return kAliHLTMultipleDataType;
+}
+
+//________________________________________________________________________
+int AliHLTPrimaryVertexFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
+{
+  //Types for outputs from primary vertex finder (for V0 finder).
+  list.clear();
+
+  //Indices of tracks, participating in a primary.
+  list.push_back(kAliHLTDataTypePrimaryFinder | kAliHLTDataOriginOut);
+  //KFVertex - primary vertex.
+  list.push_back(kAliHLTDataTypeKFVertex | kAliHLTDataOriginOut);
+
+  return list.size();
+}
+
+//________________________________________________________________________
+void AliHLTPrimaryVertexFinderComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
+{
+  //These numbers are complete crap.
+  constBase = 80000;
+  inputMultiplier = 2.;
+}
+
+//________________________________________________________________________
+AliHLTComponent* AliHLTPrimaryVertexFinderComponent::Spawn()
+{
+  //Create primary vertex finder componet.
+  return new AliHLTPrimaryVertexFinderComponent;
+}
+
+//________________________________________________________________________
+int AliHLTPrimaryVertexFinderComponent::DoInit(int /*argc*/, const char** /*argv*/)
+{
+  //Process options.
+  //1. Default parameters.
+  fFitTracksToVertex = true;
+  fConstrainedTrackDeviation = fgDefaultDeviation;
+
+  //2. Parameters from OCDB.
+  TString cdbPath("HLT/ConfigHLT/");
+  cdbPath += GetComponentID();
+
+  //This part will be uncommented as soon as
+  //OCDB object is added.
+  /*
+  int res = ConfigureFromCDBTObjString(cdbPath);
+
+  if (res < 0)
+    return res;
+
+  //3. "Command line" parameters.
+  if (argc)
+    res = ConfigureFromArgumentString(argc, argv);
+
+  return res;*/
+
+  return 0;
+}
+
+//________________________________________________________________________
+int AliHLTPrimaryVertexFinderComponent::ScanConfigurationArgument(int argc, const char** argv)
+{
+  //Scan the name of option and its parameters from the list.
+  //Return number of processed entries.
+  //Possible arguments:
+  //-fitTracksToVertex 1/0
+  //-constrainedTrackDeviation value
+  AliHLTUtility::CmdLineParser parser;
+  parser.Add("-fitTrackToVertex", &fFitTracksToVertex);
+  parser.Add("-constrainedTrackDeviation", &fConstrainedTrackDeviation);
+
+  const int nParsed = parser.Parse(argc, argv, 0);
+  if (nParsed < 0) {
+    HLTError(parser.GetError().Data());
+    return -EPROTO;
+  }
+
+  return nParsed;
+}
+
+//________________________________________________________________________
+int AliHLTPrimaryVertexFinderComponent::DoDeinit()
+{
+  //Reset parameters to default.
+  fFitTracksToVertex = true;
+  fConstrainedTrackDeviation = fgDefaultDeviation;
+
+  return 0;
+}
+
+//________________________________________________________________________
+int AliHLTPrimaryVertexFinderComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/,
+                                       AliHLTComponentTriggerData& /*trigData*/)
+{
+  //Find primary vertex.
+
+  if (GetFirstInputBlock(kAliHLTDataTypeSOR) || GetFirstInputBlock(kAliHLTDataTypeEOR))
+    return 0;
+
+
+  //Clean all previous track infos and output block.
+  fTrackInfos.clear();
+  fPrimaryOutput.clear();
+
+  //Initialize KF package.
+  AliKFParticle::SetField(GetBz());
+
+  //The logic, how vertex finder reads input tracks,
+  //is taken from the original global vertexer.
+  //First, try to read tracks from ESD event.
+  ReadESDTracks();
+  //If no good esd tracks or no esd at all:
+  if (!fTrackInfos.size())
+    ReadHLTTracks(kAliHLTDataTypeTrack | kAliHLTDataOriginITS);
+  //If no good its tracks:
+  if (!fTrackInfos.size())
+    ReadHLTTracks(kAliHLTDataTypeTrack | kAliHLTDataOriginTPC);
+
+  if (!fTrackInfos.size()) {
+    HLTWarning("No input tracks found");
+    return 0;
+  }
+
+  FindPrimaryVertex();
+
+  return DoOutput();
+}
+
+namespace
+{
+
+struct VertexDeviation
+{
+  int fI; //Index in fTrackInfos array.
+  double fD; //Deviation from primary vertex.
+
+  bool operator < (const VertexDeviation& rhs) const
+  {
+    return fD < rhs.fD;
+  }
+};
+
+}
+
+//________________________________________________________________________
+void AliHLTPrimaryVertexFinderComponent::FindPrimaryVertex()
+{
+  //Find event's primary vertex.
+
+  ///////////////////////////////////////////////////////////////////////
+  //Some changes must be done here to read the initial guess (?)
+  //for primary vertex.
+  //Select rough region (in sigmas) in which the vertex could be found,
+  //all tracks outside these limits are rejected from the primary vertex finding.
+  fPrimaryVtx.Initialize();
+  fPrimaryVtx.SetBeamConstraint(0., 0., 0., 3., 3., 5.3);
+  ////////////////////////////////////////////////////////////////////////
+
+  std::vector<const AliKFParticle*> vSelected(fTrackInfos.size());
+  std::vector<VertexDeviation> devs(fTrackInfos.size());
+
+  int nSelected = 0;
+  for (VectorSize_t i = 0; i < fTrackInfos.size(); ++i) {
+    const AliKFParticle& p = fTrackInfos[i].fParticle;
+    const double chi = p.GetDeviationFromVertex(fPrimaryVtx);
+    if (chi > fConstrainedTrackDeviation)
+      continue;
+
+    devs[nSelected].fI = i;
+    devs[nSelected].fD = chi;
+    vSelected[nSelected] = &fTrackInfos[i].fParticle;
+    nSelected++;
+  }
+
+  //Fit
+  while (nSelected > 2) {
+    //Primary vertex finder with rejection of outliers
+    for (int i = 0; i < nSelected; ++i)
+      vSelected[i] = &fTrackInfos[devs[i].fI].fParticle;
+
+    const double xv = fPrimaryVtx.GetX();
+    const double yv = fPrimaryVtx.GetY();
+    const double zv = fPrimaryVtx.GetZ(); //Values from the previous iteration.
+
+    fPrimaryVtx.Initialize();
+    fPrimaryVtx.SetBeamConstraint(0, 0, 0, 3., 3., 5.3);
+    fPrimaryVtx.SetVtxGuess(xv, yv, zv);
+
+    // refilled for every iteration
+    //0: pointer to production vertex, -1. : mass, true : constrained.
+    fPrimaryVtx.Construct(&vSelected[0], nSelected, 0, -1., true);
+
+    for (int it = 0; it < nSelected; ++it) {
+      const AliKFParticle& p = fTrackInfos[devs[it].fI].fParticle;
+      if (nSelected <= 20) {
+        //Exclude the current track from the sample and recalculate the vertex
+        AliKFVertex tmp(fPrimaryVtx - p);
+        devs[it].fD = p.GetDeviationFromVertex(tmp);
+      } else {
+        devs[it].fD = p.GetDeviationFromVertex(fPrimaryVtx);
+      }
+    }
+
+    //Sort tracks with increasing chi2 (used for rejection)
+    std::sort(&devs[0], &devs[0] + nSelected);
+
+    //Remove 30% of the tracks (done for performance, only if there are more than 20 tracks)
+    int nRemove = int(0.3 * nSelected);
+    if (nSelected - nRemove <= 20)
+      nRemove = 1;// removal based on the chi2 of every track
+
+    int firstRemove = nSelected - nRemove;
+    while (firstRemove < nSelected) {
+      if (devs[firstRemove].fD >= fConstrainedTrackDeviation)
+        break;
+      firstRemove++;
+    }
+
+    if (firstRemove >= nSelected)
+      break;
+
+    nSelected = firstRemove;
+  }
+
+  if (nSelected < 3) {//No vertex for less than 3 contributors.
+    fPrimaryVtx.NDF() = -3;
+    fPrimaryVtx.Chi2() = 0.;
+    nSelected = 0;
+  }
+
+  if (nSelected) {
+    //Prepare output block.
+    fPrimaryOutput.resize(sizeof(PrimaryFinderBlock) + sizeof(int) * (nSelected - 1));
+    PrimaryFinderBlock* out = reinterpret_cast<PrimaryFinderBlock*>(&fPrimaryOutput[0]);
+
+    out->fFitTracksFlag = fFitTracksToVertex;
+    out->fNPrimaryTracks = nSelected;
+
+    int minID = fTrackInfos[devs[0].fI].fID;
+    int maxID = minID;
+    for (int i = 0; i < nSelected; ++i) {
+      const int id = fTrackInfos[devs[i].fI].fID;
+      minID = TMath::Min(minID, id);
+      maxID = TMath::Max(maxID, id);
+      out->fPrimTrackIds[i] = id;
+    }
+
+    out->fMinPrimID = minID;
+    out->fMaxPrimID = maxID;
+  }
+}
+
+//________________________________________________________________________
+int AliHLTPrimaryVertexFinderComponent::DoOutput()
+{
+  //Primary vertex finder output.
+  if (!fPrimaryOutput.size()) {
+    //Vertex not found.
+    //Messages? return values?
+    HLTWarning("No primary vertex was found");
+    return 0;
+  }
+
+  //1. indices of primary tracks;
+  //int - type of PushBack's parameter.
+  const int iResult = PushBack(&fPrimaryOutput[0], fPrimaryOutput.size(),
+                               kAliHLTDataTypePrimaryFinder | kAliHLTDataOriginOut);
+  if (iResult < 0)
+    return iResult;
+  //2. primary vertex (AliKFVertex).
+  return PushBack(&fPrimaryVtx, kAliHLTDataTypeKFVertex | kAliHLTDataOriginOut, 0);
+}
diff --git a/HLT/global/AliHLTPrimaryVertexFinderComponent.h b/HLT/global/AliHLTPrimaryVertexFinderComponent.h
new file mode 100644 (file)
index 0000000..7c3b357
--- /dev/null
@@ -0,0 +1,67 @@
+//-*- Mode: C++ -*-
+// $Id$
+#ifndef ALIHLTPRIMARYVERTEXFINDERCOMPONENT_H
+#define ALIHLTPRIMARYVERTEXFINDERCOMPONENT_H
+/// This file is property of and copyright by the ALICE HLT Project         
+/// ALICE Experiment at CERN, All rights reserved.                         
+/// See cxx source for full Copyright notice                               
+
+/// @file   AliHLTPrimaryVertexFinderComponent.h
+/// @author Timur Pocheptsov
+/// @date   2010-12-26
+/// @brief  Primary vertex finder component
+///
+
+#include <vector>
+
+#include "AliHLTVertexFinderBase.h"
+#include "AliKFVertex.h"
+
+//Primary vertex finder, developed by Sergey Gorbunov.
+//Based on KF package.
+//Produces primary vertex (AliKFVertex object) and
+//indices of input tracks, which participates
+//in primary construction.
+//Can be configured with two options:
+//-fitTracksToVertex 0/1
+//-constrainedTrackDeviation value.
+
+class AliHLTPrimaryVertexFinderComponent : public AliHLTVertexFinderBase
+{
+public:
+  AliHLTPrimaryVertexFinderComponent();
+
+  //AliHLTComponent's final-overriders.
+  const char* GetComponentID();
+  void GetInputDataTypes(AliHLTComponentDataTypeList& list);
+  AliHLTComponentDataType GetOutputDataType();
+  int GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList);
+  void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier);
+  AliHLTComponent* Spawn();
+
+  int DoInit(int argc, const char** argv);
+  int ScanConfigurationArgument(int argc, const char** argv);
+  int DoDeinit();
+
+  using AliHLTProcessor::DoEvent;
+  int DoEvent(const AliHLTComponentEventData& evtData,
+              AliHLTComponentTriggerData& trigData);
+
+private:
+  //Aux. staff.
+  void FindPrimaryVertex();
+  int DoOutput();
+
+  std::vector<char> fPrimaryOutput; //Ids of primary tracks.
+  AliKFVertex fPrimaryVtx; //Reconstructed KF primary vertex.
+  bool fFitTracksToVertex; //Flag to store vertex constrained track parameters
+  double fConstrainedTrackDeviation; //Deviation of a track from prim.vtx <=cut
+
+  static const double fgDefaultDeviation; //Default value for fConstrainedTrackDeviation.
+
+  //Compiler generated dtor, copy-ctor and copy-assignment operators are ok.
+
+  ClassDef(AliHLTPrimaryVertexFinderComponent, 0);
+};
+
+#endif
diff --git a/HLT/global/AliHLTV0FinderComponent.cxx b/HLT/global/AliHLTV0FinderComponent.cxx
new file mode 100644 (file)
index 0000000..412ebcc
--- /dev/null
@@ -0,0 +1,411 @@
+// $Id$
+
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Timur Pocheptsov <Timur.Pocheptsov@cern.ch>           *
+//*                  for The ALICE HLT Project.                            *
+//*                                                                        *
+//* Permission to use, copy, modify and distribute this software and its   *
+//* documentation strictly for non-commercial purposes is hereby granted   *
+//* without fee, provided that the above copyright notice appears in all   *
+//* copies and that both the copyright notice and this permission notice   *
+//* appear in the supporting documentation. The authors make no claims     *
+//* about the suitability of this software for any purpose. It is          *
+//* provided "as is" without express or implied warranty.                  *
+//**************************************************************************
+
+/// @file   AliHLTV0FinderComponent.cxx
+/// @author Timur Pocheptsov
+/// @date   2010-12-26
+/// @brief  V0 finder component
+///
+
+#include "TString.h"
+
+#include "AliHLTDataTypes.h"
+#include "AliHLTV0FinderComponent.h"
+
+ClassImp(AliHLTV0FinderComponent)
+
+const double AliHLTV0FinderComponent::fgDaughterPrimDeviation = 2.5;
+const double AliHLTV0FinderComponent::fgPrimDeviation = 3.5;
+const double AliHLTV0FinderComponent::fgChi = 3.5;
+const double AliHLTV0FinderComponent::fgDecayLengthInSigmas = 3.;
+
+//________________________________________________________________________
+AliHLTV0FinderComponent::AliHLTV0FinderComponent()
+                  : fPrimaryVtx(),
+                    fPrimaryTracks(),
+                    fNPrimaryTracks(0),
+                    fMinPrimID(0),
+                    fMaxPrimID(0),
+                    fDaughterPrimDeviation(fgDaughterPrimDeviation),
+                    fPrimDeviation(fgPrimDeviation),
+                    fChi(fgChi),
+                    fDecayLengthInSigmas(fgDecayLengthInSigmas),
+                    fPosPID(211),
+                    fNegPID(211),
+                    fV0s(),
+                    fGammaFinder(false)
+{
+  //Default ctor.
+}
+
+//________________________________________________________________________
+const char* AliHLTV0FinderComponent::GetComponentID()
+{
+  //Component's "name".
+  return "V0Finder";
+}
+
+//________________________________________________________________________
+void AliHLTV0FinderComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
+{
+  //Input to the primary vertex finder:
+  //a)tracks from ESD object;
+  //b)hlt tracks (ITS)
+  //c)hlt tracks (TPC)
+  //d)primary vertex (AliKFVertex)
+  //e)indices of primary tracks.
+  list.clear();
+  //Input tracks.
+  list.push_back(kAliHLTDataTypeESDObject);
+  list.push_back(kAliHLTDataTypeTrack | kAliHLTDataOriginITS);
+  list.push_back(kAliHLTDataTypeTrack | kAliHLTDataOriginTPC);
+  //Input from primary finder:
+  //Primary vertex.
+  list.push_back(kAliHLTDataTypeKFVertex | kAliHLTDataOriginOut);
+  //Primary tracks' indices.
+  list.push_back(kAliHLTDataTypePrimaryFinder | kAliHLTDataOriginOut);
+}
+
+//________________________________________________________________________
+AliHLTComponentDataType AliHLTV0FinderComponent::GetOutputDataType()
+{
+  //Data type of output.
+  return kAliHLTMultipleDataType;
+}
+
+//________________________________________________________________________
+int AliHLTV0FinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
+{
+  //Output type for V0 finder.
+  tgtList.clear();
+  //Indices of tracks, participating in V0s.
+  tgtList.push_back(kAliHLTDataTypeV0Finder | kAliHLTDataOriginOut);
+
+  return tgtList.size();
+}
+
+//________________________________________________________________________
+void AliHLTV0FinderComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
+{
+  //These numbers are complete crap.
+  constBase = 80000;
+  inputMultiplier = 2.;
+}
+
+//________________________________________________________________________
+AliHLTComponent* AliHLTV0FinderComponent::Spawn()
+{
+  //Create primary vertex finder componet.
+  return new AliHLTV0FinderComponent;
+}
+
+//________________________________________________________________________
+int AliHLTV0FinderComponent::DoInit(int /*argc*/, const char** /*argv*/)
+{
+  //1. Default parameters.
+  fDaughterPrimDeviation = fgDaughterPrimDeviation;
+  fPrimDeviation = fgPrimDeviation;
+  fChi = fgChi;
+  fDecayLengthInSigmas = fgDecayLengthInSigmas;
+  fPosPID = 211;
+  fNegPID = 211;
+  fGammaFinder = false;
+
+  //Part with OCDB and command line arguments is commented
+  //until OCDB is updated.
+/*
+  //2. Parameters from OCDB.
+  TString cdbPath("HLT/ConfigHLT/");
+  cdbPath += GetComponentID();
+
+  int res = ConfigureFromCDBTObjString(cdbPath);
+  if (res < 0)
+    return res;
+
+  //3. "Command line" parameters.
+  if (argc)
+    res = ConfigureFromArgumentString(argc, argv);
+
+  return res;*/
+  return 0;
+}
+
+//________________________________________________________________________
+int AliHLTV0FinderComponent::ScanConfigurationArgument(int argc, const char** argv)
+{
+  //Scan one argument and its parameters from the list
+  //Return number of processed entries.
+  //Possible arguments:
+  //-daughterPrimDeviation num
+  //-primDeviation num
+  //-chi num
+  //-decayLengthInSigmas num
+  //-posPID int_num
+  //-negPid int_num
+  //-gammaFinder 0/1
+
+  AliHLTUtility::CmdLineParser parser;
+  parser.Add("-daughterPrimDeviation", &fDaughterPrimDeviation);
+  parser.Add("-primDeviation", &fPrimDeviation);
+  parser.Add("-chi", &fChi);
+  parser.Add("-decayLengthInSigmas", &fDecayLengthInSigmas);
+  parser.Add("-posPID", &fPosPID);
+  parser.Add("-negPID", &fNegPID);
+  parser.Add("-gammaFinder", &fGammaFinder);
+
+  const int nParsed = parser.Parse(argc, argv, 0);
+  if (nParsed < 0) {
+    HLTError(parser.GetError().Data());
+    return -EPROTO;
+  }
+
+  return nParsed;
+}
+
+//________________________________________________________________________
+int AliHLTV0FinderComponent::DoDeinit()
+{
+  //Reset parameters to default.
+  fDaughterPrimDeviation = fgDaughterPrimDeviation;
+  fPrimDeviation = fgPrimDeviation;
+  fChi = fgChi;
+  fDecayLengthInSigmas = fgDecayLengthInSigmas;
+  fPosPID = 211;
+  fNegPID = 211;
+  fGammaFinder = false;
+
+  return 0;
+}
+
+//________________________________________________________________________
+int AliHLTV0FinderComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/,
+                            AliHLTComponentTriggerData& /*trigData*/)
+{
+  //Find primary vertex.
+  if (GetFirstInputBlock(kAliHLTDataTypeSOR) || GetFirstInputBlock(kAliHLTDataTypeEOR))
+    return 0;
+
+  //Clean all previous track infos.
+  fTrackInfos.clear();
+  fPrimaryTracks.clear();
+
+  //Initialize KF package.
+  AliKFParticle::SetField(GetBz());
+
+  if (!ReadPrimaryVertex())
+    return 0;
+
+  if (!ReadTracks())
+    return 0;
+
+  FindV0s();
+
+  return DoOutput();
+}
+
+//________________________________________________________________________
+bool AliHLTV0FinderComponent::ReadPrimaryVertex()
+{
+  //Primary finder produces primary vertex (AliKFVertex) and
+  //indices for primary tracks.
+  //1. Try to extract primary vertex.
+  const TObject* obj = GetFirstInputObject(kAliHLTDataTypeKFVertex | kAliHLTDataOriginOut);
+  const AliKFVertex* kfVtx = dynamic_cast<const AliKFVertex*>(obj);
+
+  if (!kfVtx) {
+    HLTError("V0 finder requires KF vertex (primary vertex) as input");
+    return false;
+  }
+
+  //2. Try to read primary track indices.
+  const AliHLTComponentBlockData* p = GetFirstInputBlock(kAliHLTDataTypePrimaryFinder
+                                                          | kAliHLTDataOriginOut);
+  if (!p || !p->fSize || !p->fPtr) {
+    HLTError("Array of primary track indices expected");
+    return false;
+  }
+
+  //Data block from primary finder
+  const PrimaryFinderBlock* blk = static_cast<PrimaryFinderBlock*>(p->fPtr);
+  //Track ids must be positive integers.
+  if (blk->fMinPrimID < 0 || blk->fMaxPrimID < 0) {
+    HLTError("Got negative track ID from primary finder, internal HLT error");
+    return false;
+  }
+
+  //3. Got correct data, modify the component's state.
+  //KF vertex.
+  fPrimaryVtx = *kfVtx;
+  //Primary tracks.
+  fNPrimaryTracks = blk->fNPrimaryTracks;
+  fMinPrimID = blk->fMinPrimID;
+  fMaxPrimID = blk->fMaxPrimID;
+
+  fPrimaryTracks.assign(fMaxPrimID + 1, 0);
+  for (int i = 0; i < fNPrimaryTracks; ++i)
+    fPrimaryTracks[blk->fPrimTrackIds[i]] = 1;
+
+  return true;
+}
+
+//________________________________________________________________________
+bool AliHLTV0FinderComponent::ReadTracks()
+{
+  //The logic, how vertex finder reads input tracks,
+  //is taken from the original global vertexer.
+  //First, try to read tracks from ESD event.
+  ReadESDTracks();
+  if (fTrackInfos.size()) {
+    FindPrimaryDeviations();
+    return true;
+  }
+
+  //No good esd tracks, try:
+  ReadHLTTracks(kAliHLTDataTypeTrack | kAliHLTDataOriginITS);
+  if (fTrackInfos.size()) {
+    FindPrimaryDeviations();
+    return true;
+  }
+
+  //If no good its tracks, try:
+  ReadHLTTracks(kAliHLTDataTypeTrack | kAliHLTDataOriginTPC);
+  if (fTrackInfos.size()) {
+    FindPrimaryDeviations();
+    return true;
+  }
+
+  HLTError("No input tracks found for V0 finder");
+
+  return false;
+}
+
+//________________________________________________________________________
+void AliHLTV0FinderComponent::FindPrimaryDeviations()
+{
+  //Quite a tricky part.
+  for (VectorSize_t i = 0; i < fTrackInfos.size(); ++i) {
+    AliHLTTrackInfo& info = fTrackInfos[i];
+    if (IsPrimaryTrack(info.fID)) {
+      info.fPrimUsed = true;
+      //The way primary deviation is computed in primary finder:
+      if (fNPrimaryTracks <= 20) {
+        AliKFVertex tmp(fPrimaryVtx - info.fParticle);
+        info.fPrimDeviation = info.fParticle.GetDeviationFromVertex(tmp);
+      } else
+        info.fPrimDeviation = info.fParticle.GetDeviationFromVertex(fPrimaryVtx);
+    } else {
+      info.fPrimUsed = false;
+      info.fPrimDeviation = info.fParticle.GetDeviationFromVertex(fPrimaryVtx);
+    }
+  }
+}
+
+//________________________________________________________________________
+bool AliHLTV0FinderComponent::IsPrimaryTrack(int id)const
+{
+  if (id < fMinPrimID || id > fMaxPrimID)
+    return false;
+
+  return fPrimaryTracks[id];
+}
+
+//________________________________________________________________________
+void AliHLTV0FinderComponent::FindV0s()
+{
+  //Here's the core.
+  if (fPrimaryVtx.GetNContributors() < 3)
+    return;
+
+  fV0s.clear();
+  fV0s.push_back(0); //Number of v0s.
+
+  for (int iTr = 0, ei = fTrackInfos.size(); iTr < ei; ++iTr) {
+    AliHLTTrackInfo& info = fTrackInfos[iTr];
+    if (info.fParticle.GetQ() > 0)
+      continue;
+    if (info.fPrimDeviation < fDaughterPrimDeviation)
+      continue;
+
+    for (int jTr = 0; jTr < ei; ++jTr) {
+      AliHLTTrackInfo& jnfo = fTrackInfos[jTr];
+      if (jnfo.fParticle.GetQ() < 0)
+        continue;
+      if (jnfo.fPrimDeviation < fDaughterPrimDeviation)
+        continue;
+
+      //Check if the particles fit
+      if (info.fParticle.GetDeviationFromParticle(jnfo.fParticle) > fChi)
+        continue;
+
+      //Construct V0 mother
+      AliKFParticle v0(info.fParticle, jnfo.fParticle /*, bGammaFinder*/);
+      //Check V0 Chi^2
+      if (v0.GetChi2() < 0. || v0.GetChi2() > fChi * fChi * v0.GetNDF())
+        continue;
+
+      //Subtruct daughters from primary vertex
+      AliKFVertex primVtxCopy(fPrimaryVtx);
+
+      if (info.fPrimUsed) {
+        if (primVtxCopy.GetNContributors() <= 2)
+          continue;
+        primVtxCopy -= info.fParticle;
+      }
+
+      if (jnfo.fPrimUsed) {
+        if (primVtxCopy.GetNContributors() <= 2)
+          continue;
+        primVtxCopy -= jnfo.fParticle;
+      }
+
+      //Check v0 Chi^2 deviation from primary vertex
+      if (v0.GetDeviationFromVertex(primVtxCopy) > fPrimDeviation)
+        continue;
+      //Add V0 to primary vertex to improve the primary vertex resolution
+      primVtxCopy += v0;
+      //Set production vertex for V0
+      v0.SetProductionVertex(primVtxCopy);
+      //Get V0 decay length with estimated error
+      double length = 0., sigmaLength = 0.;
+      if (v0.GetDecayLength(length, sigmaLength))
+        continue;
+      //Reject V0 if it decays too close[sigma] to the primary vertex
+      if (length  < fDecayLengthInSigmas * sigmaLength)
+        continue;
+      //Keep v0
+      fV0s.push_back(iTr);
+      fV0s.push_back(jTr);
+
+      fV0s[0] += 1;
+    }
+  }
+}
+
+//________________________________________________________________________
+int AliHLTV0FinderComponent::DoOutput()
+{
+  //Save V0s' track pairs' indices.
+  if (!fV0s.size() || !fV0s[0]) {
+    HLTInfo("No v0s were found");
+    return 0;
+  }
+
+  //Indices of primary tracks.
+  return PushBack(&fV0s[0], fV0s.size() * sizeof(int),
+                  kAliHLTDataTypeV0Finder | kAliHLTDataOriginOut);
+}
diff --git a/HLT/global/AliHLTV0FinderComponent.h b/HLT/global/AliHLTV0FinderComponent.h
new file mode 100644 (file)
index 0000000..1317844
--- /dev/null
@@ -0,0 +1,87 @@
+//-*- Mode: C++ -*-
+// $Id$
+#ifndef ALIHLTV0FINDERCOMPONENT_H
+#define ALIHLTV0FINDERCOMPONENT_H
+/// This file is property of and copyright by the ALICE HLT Project         
+/// ALICE Experiment at CERN, All rights reserved.                         
+/// See cxx source for full Copyright notice                               
+
+/// @file   AliHLTV0FinderComponent.h
+/// @author Timur Pocheptsov
+/// @date   2010-12-26
+/// @brief  V0 finder component
+///
+
+#include <vector>
+
+#include "AliHLTVertexFinderBase.h"
+#include "AliKFVertex.h"
+
+class AliHLTV0FinderComponent : public AliHLTVertexFinderBase
+{
+public:
+  AliHLTV0FinderComponent();
+
+  //AliHLTComponent's final-overriders.
+  const char* GetComponentID();
+  void GetInputDataTypes(AliHLTComponentDataTypeList& list);
+  AliHLTComponentDataType GetOutputDataType();
+  int GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList);
+  void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier);
+  AliHLTComponent* Spawn();
+
+  int DoInit(int argc, const char** argv);
+  int ScanConfigurationArgument(int argc, const char** argv);
+  int DoDeinit();
+
+  using AliHLTProcessor::DoEvent;
+  int DoEvent(const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData);
+
+private:
+  //Aux. staff.
+
+  //Read AliKFVertex, produced by primary finder.
+  bool ReadPrimaryVertex();
+  //Read input tracks.
+  bool ReadTracks();
+  //
+  void FindPrimaryDeviations();
+  //If track (id) is from primary.
+  bool IsPrimaryTrack(int id)const;
+  //
+  void FindV0s();
+  //PushBack the output (v0s pairs' indices).
+  int DoOutput();
+
+  AliKFVertex fPrimaryVtx; //Primary vertex.
+  std::vector<int> fPrimaryTracks; //"bit mask": 1 - track is prim, 0 - no.
+  int fNPrimaryTracks; //Number of primary tracks.
+  int fMinPrimID; //Min id of primary tracks.
+  int fMaxPrimID; //Max id of primary tracks.
+
+  //V0 finder cuts.
+  double fDaughterPrimDeviation; //daughters deviation from prim vertex >= cut
+  double fPrimDeviation; //v0 deviation from prim vertex <= cut
+  double fChi; //v0 sqrt(chi^2/NDF) <= cut
+  double fDecayLengthInSigmas; //v0 decay length/sigma_length >= cut
+  int fPosPID; //Pid for a positive track, when constracting v0.
+  int fNegPID; //Pid for a negative track, when constracting v0.
+
+  //Output of V0 finder.
+  std::vector<int> fV0s; //Indices of track pairs, participating in a V0s.
+
+  //For gammas, special version of AliKFParitcle must be constructed.
+  bool fGammaFinder;
+
+  //defaults for cuts.
+  static const double fgDaughterPrimDeviation;
+  static const double fgPrimDeviation;
+  static const double fgChi;
+  static const double fgDecayLengthInSigmas;
+
+  //Compiler generated dtor, copy-ctor and copy-assignment operators are ok.
+
+  ClassDef(AliHLTV0FinderComponent, 0);
+};
+
+#endif
diff --git a/HLT/global/AliHLTVertexFinderBase.cxx b/HLT/global/AliHLTVertexFinderBase.cxx
new file mode 100644 (file)
index 0000000..313f307
--- /dev/null
@@ -0,0 +1,461 @@
+// $Id$
+
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Timur Pocheptsov <Timur.Pocheptsov@cern.ch>           *
+//*                  for The ALICE HLT Project.                            *
+//*                                                                        *
+//* Permission to use, copy, modify and distribute this software and its   *
+//* documentation strictly for non-commercial purposes is hereby granted   *
+//* without fee, provided that the above copyright notice appears in all   *
+//* copies and that both the copyright notice and this permission notice   *
+//* appear in the supporting documentation. The authors make no claims     *
+//* about the suitability of this software for any purpose. It is          *
+//* provided "as is" without express or implied warranty.                  *
+//**************************************************************************
+
+/// @file   AliHLTVertexFinderBase.cxx
+/// @author Timur Pocheptsov
+/// @date   2010-12-26
+/// @brief  Base class for vertex finder components
+///
+
+#include <stdexcept>
+#include <cmath>
+
+//AliHLTExternalTrackParam uses typedes from Rtypes.h
+//but does not include it.
+#include "Rtypes.h"
+
+#include "AliHLTExternalTrackParam.h"
+#include "AliHLTGlobalBarrelTrack.h"
+#include "AliHLTVertexFinderBase.h"
+#include "AliExternalTrackParam.h"
+#include "AliESDVertex.h"
+#include "AliESDEvent.h"
+#include "AliESDtrack.h"
+#include "AliKFVertex.h"
+#include "AliESDv0.h"
+
+ClassImp(AliHLTVertexFinderBase)
+
+//_________________________________________________________________
+bool AliHLTVertexFinderBase::AliHLTTrackInfo::IsKFFinite()const
+{
+  //Check KF particle.
+
+  //In C99, 'isfinite' is a macro.
+  //But still, I add using directive, in case
+  //it's a function in std.
+  using namespace std;
+
+  for (int i = 0; i < 8; ++i)
+    if (!isfinite(fParticle.GetParameter(i)))
+      return false;
+  for (int i = 0; i < 36; ++i)//Not sure, probably, 27 is enough.
+    if (!isfinite(fParticle.GetCovariance(i)))
+      return false;
+
+  return true;
+}
+
+//_________________________________________________________________
+void AliHLTVertexFinderBase::ReadESDTracks()
+{
+  //Try to read input tracks from AliESDEvent.
+  //Use esd track's index as "track id" (fID).
+  //IMPORTANT: fTrackInfos is _NOT_ cleared here,
+  //must be done externally (if you need to).
+
+  const TObject* iter = GetFirstInputObject(kAliHLTDataTypeESDObject);
+  for (; iter; iter = GetNextInputObject()) {
+    //Cast away constness before dynamic_cast.
+    AliESDEvent* esd = dynamic_cast<AliESDEvent*>((TObject*)iter);
+    if (!esd)//From original code. Not sure, if this is possible at all.
+      continue;
+
+    esd->GetStdContent();
+
+    const int nTracks = esd->GetNumberOfTracks();
+    if (nTracks)
+      fTrackInfos.reserve(nTracks + fTrackInfos.size());
+
+    for (int i = 0; i < nTracks; ++i) {
+      AliESDtrack* pTrack = esd->GetTrack(i);
+      //This checks of track parameters are
+      //from the original global vertexer.
+      if (!pTrack)
+        continue;
+      if (pTrack->GetKinkIndex(0) > 0)
+        continue;
+      if (!(pTrack->GetStatus() & AliESDtrack::kTPCin))
+        continue;
+
+      //i: track id, 211: pid, false: not used in primary, 0.: prim. deviation.
+      AliHLTTrackInfo newTrackInfo(i, *pTrack, 211, false, 0.);
+      if (!newTrackInfo.IsKFFinite())
+        continue;
+
+      fTrackInfos.push_back(newTrackInfo);
+    }
+    //Only one esd event is taken.
+    break;
+  }
+}
+
+//________________________________________________________________________
+void AliHLTVertexFinderBase::ReadHLTTracks(const AliHLTComponentDataType& blockType)
+{
+  //Read HLT tracks as input.
+  //IMPORTANT: fTrackInfos is _NOT_ cleared here,
+  //must be done externally (if you need it).
+
+  const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
+  for (; block; block = GetNextInputBlock()) {
+    const AliHLTTracksData* dataPtr = static_cast<AliHLTTracksData*>(block->fPtr);
+    const AliHLTExternalTrackParam* hltTrk = dataPtr->fTracklets;
+
+    const int nTracks = dataPtr->fCount;
+    if (nTracks)
+      fTrackInfos.reserve(fTrackInfos.size() + nTracks);
+
+    for (int i = 0; i < nTracks; ++i) {
+      //Ugly conversion from one track format to another
+      //and to AliKFParitcle then, to be changed later.
+      AliHLTGlobalBarrelTrack tmpTrk(*hltTrk);
+
+      AliHLTTrackInfo newTrackInfo(hltTrk->fTrackID, tmpTrk, 211, false, 0.);
+      if (!newTrackInfo.IsKFFinite())
+        continue;
+
+      fTrackInfos.push_back(newTrackInfo);
+
+      const unsigned dSize = sizeof(AliHLTExternalTrackParam)
+                            + hltTrk->fNPoints * sizeof(unsigned);
+      hltTrk = (AliHLTExternalTrackParam*)((char *)hltTrk + dSize);
+    }
+  }
+}
+
+//________________________________________________________________________
+void AliHLTVertexFinderBase::FillESD(AliESDEvent* esd, AliKFVertex* vtx,
+                                     const void* primData, const void* v0Data)
+{
+  //Put the output of a primary finder and v0 finder to the esd event.
+  //Code was taken from the original global vertexer.
+  //Code is an absolute mess.
+
+  typedef std::map<int, int> Map_t;
+  typedef Map_t::const_iterator MapIter_t;
+
+  //Map esdId -> esdTrackIndex.
+  Map_t mapId;
+
+  double params[3];
+  for (int i = 0; i < 3; ++i)
+    params[i] = vtx->Parameters()[i];
+  double cov[6];
+  for (int i = 0; i < 6; ++i)
+    cov[i] = vtx->CovarianceMatrix()[i];
+
+  AliESDVertex vESD(params, cov, vtx->GetChi2(), vtx->GetNContributors());
+  esd->SetPrimaryVertexTPC(&vESD);
+  esd->SetPrimaryVertexTracks(&vESD);
+
+  //Relate tracks to the primary vertex
+  const PrimaryFinderBlock* prim = static_cast<const PrimaryFinderBlock*>(primData);
+  const int nESDTracks = esd->GetNumberOfTracks();
+  std::vector<bool> constrainedToVtx(nESDTracks);
+
+  if (prim->fFitTracksFlag) {
+    for (int i = 0; i < nESDTracks; ++i) {
+      if (!esd->GetTrack(i))
+        continue;
+
+      mapId[esd->GetTrack(i)->GetID()] = i;
+    }
+
+    for (int i = 0; i < prim->fNPrimaryTracks; ++i) {
+      MapIter_t it = mapId.find(prim->fPrimTrackIds[i]);
+      if (it == mapId.end())
+        continue;
+      const int itr = it->second;
+      //100. is an argument for parameter maxd in AliESDtrack - cut on impact parameter.
+      esd->GetTrack(itr)->RelateToVertex(&vESD, esd->GetMagneticField(), 100.);
+      constrainedToVtx[itr] = true;
+    }
+  }
+
+  //Add v0s.
+  const int* v0s = static_cast<const int*>(v0Data);
+  const int nV0s = v0s[0];
+  ++v0s;
+  for (int i = 0; i < nV0s; ++i) {
+    MapIter_t it = mapId.find(v0s[2 * i]);
+    if (it==mapId.end())
+      continue;
+    const int iTr = it->second;
+
+    it = mapId.find(v0s[2 * i + 1]);
+    if (it == mapId.end())
+      continue;
+    const int jTr = it->second;
+
+    AliESDv0 v0(*esd->GetTrack(iTr), iTr, *esd->GetTrack(jTr), jTr);
+    esd->AddV0(&v0);
+    // relate the tracks to the vertex
+    if (prim->fFitTracksFlag) {
+      if (constrainedToVtx[iTr] || constrainedToVtx[jTr])
+        continue;
+
+      double pos[3];
+      double sigma[3] = {.1, .1, .1};
+      v0.XvYvZv(pos);
+      AliESDVertex v0ESD(pos, sigma);
+      esd->GetTrack(iTr)->RelateToVertex(&v0ESD, esd->GetMagneticField(), 100.);
+      esd->GetTrack(jTr)->RelateToVertex(&v0ESD, esd->GetMagneticField(), 100.);
+      constrainedToVtx[iTr] = true;
+      constrainedToVtx[jTr] = true;
+    }
+  }
+}
+
+namespace AliHLTUtility
+{
+
+//_______________________________________________________________________
+Parameter::Parameter()
+             : fWasSet(false),
+               fConstraint(none),
+               fBool(0),
+               fInt(0),
+               fDouble(0),
+               fCompound(0),
+               fConstraintChecker(0)
+{
+  //Default ctor.
+}
+
+//_______________________________________________________________________
+Parameter::Parameter(bool* b)
+             : fWasSet(false),
+               fConstraint(none),
+               fBool(b),
+               fInt(0),
+               fDouble(0),
+               fCompound(0),
+               fConstraintChecker(0)
+{
+  //Parameter of type bool.
+}
+
+//_______________________________________________________________________
+Parameter::Parameter(int* i, Constraint c)
+             : fWasSet(false),
+               fConstraint(c),
+               fBool(0),
+               fInt(i),
+               fDouble(0),
+               fCompound(0),
+               fConstraintChecker(0)
+{
+  //Parameter of type int.
+  SetConstraintChecker();
+}
+
+//_______________________________________________________________________
+Parameter::Parameter(double* d, Constraint c)
+             : fWasSet(false),
+               fConstraint(c),
+               fBool(0),
+               fInt(0),
+               fDouble(d),
+               fCompound(0),
+               fConstraintChecker(0)
+{
+  //Parameter of type double.
+  SetConstraintChecker();
+}
+
+//_______________________________________________________________________
+Parameter::Parameter(CompoundType *ct)
+             : fWasSet(false),
+               fConstraint(none),
+               fBool(0),
+               fInt(0),
+               fDouble(0),
+               fCompound(ct),
+               fConstraintChecker(0)
+{
+  //Parameter of more complex user-defined type.
+  //All checks and conversions must be implemented
+  //by user of CompoundType.
+}
+
+//_______________________________________________________________________
+unsigned Parameter::SetParameter(unsigned argc, const char** argv, unsigned currPos)
+{
+  //Set parameter from command line tokens.
+
+  //It's up to compound parameter to parse.
+  if (fCompound)
+    return fCompound->SetParameter(argc, argv, currPos);
+
+  //Now, int, bool or double must be set from a string.
+  //Primitive checks are done here.
+  if (currPos == argc)
+    throw std::runtime_error("value expected");
+  if (fWasSet)
+    throw std::runtime_error("parameter was set already");
+
+  const TString val(argv[currPos]);
+  if (!val.Length())
+    throw std::runtime_error("value expected");
+
+  if (fBool) {
+    if (val.Length() != 1 || (val[0] != '0' && val[0] != '1'))
+      throw std::runtime_error("expected 0 or 1 for bool parameter");
+    *fBool = val[0] - '0';
+  } else if (fInt)
+    *fInt = val.Atoi();
+  else
+    *fDouble = val.Atof();
+
+  if (fConstraintChecker)
+    fConstraintChecker(*this);
+
+  fWasSet = true;
+
+  //For double, int and bool - only one element of argv is processed.
+  return 1;
+}
+
+//_______________________________________________________________________
+void Parameter::SetConstraintChecker()
+{
+  //Set function pointer.
+  if (fConstraint == positive)
+    fConstraintChecker = CheckPositive;
+  else if (fConstraint == nonNegative)
+    fConstraintChecker = CheckNonNegative;
+  //No constraints for bool or CompoundType.
+}
+
+//Aux. functions to check constraints.
+//_______________________________________________________________________
+void Parameter::CheckPositive(const Parameter& param)
+{
+  //val > 0
+  if (param.fInt) {
+    if (*param.fInt <= 0)
+      throw std::runtime_error("integer parameter must be positive");
+  } else if (param.fDouble) {
+     if (*param.fDouble <= 0.)//Hmmmm.
+      throw std::runtime_error("double parameter must be positive");
+  }
+  //For bool or CompoundType there is no check.
+}
+
+//_______________________________________________________________________
+void Parameter::CheckNonNegative(const Parameter& param)
+{
+  //val >= 0
+  if (param.fInt) {
+    if (*param.fInt < 0)
+      throw std::runtime_error("integer parameter must be non-negative");
+  } else if (param.fDouble) {
+    if (*param.fDouble < 0.)
+      throw std::runtime_error("double parameter must be non-negative");
+  }
+  //For bool or CompoundType there is no check.
+}
+
+
+//Command line arguments parser.
+
+//_______________________________________________________________________
+void CmdLineParser::Add(const TString& cmd, bool* b)
+{
+  //Command with bool parameter.
+  if (fParameters.find(cmd) == fParameters.end())
+    fParameters[cmd] = Parameter(b);
+}
+
+//_______________________________________________________________________
+void CmdLineParser::Add(const TString& cmd, int* i, Parameter::Constraint c)
+{
+  //Command with int parameter, with constraint.
+  if (fParameters.find(cmd) == fParameters.end())
+    fParameters[cmd] = Parameter(i, c);
+}
+
+//_______________________________________________________________________
+void CmdLineParser::Add(const TString& cmd, double* d, Parameter::Constraint c)
+{
+  //Coomand with a parameter of type double, possibly with a constraint.
+  if (fParameters.find(cmd) == fParameters.end())
+    fParameters[cmd] = Parameter(d, c);
+}
+
+//_______________________________________________________________________
+void CmdLineParser::Add(const TString& cmd, CompoundType *ct)
+{
+  //Command with a parameter of compound type.
+  if (fParameters.find(cmd) == fParameters.end())
+    fParameters[cmd] = Parameter(ct);
+}
+
+//_______________________________________________________________________
+void CmdLineParser::IgnoreCommand(const TString& cmd, unsigned nParams)
+{
+  //Command and number of parameters to ignore.
+  //I do not check, if it's in map already.
+  fIgnored[cmd] = nParams;
+}
+
+//_______________________________________________________________________
+int CmdLineParser::Parse(unsigned argc, const char** argv, unsigned currPos)
+{
+  //Parse. Returns number of processed arguments.
+  //Negative number - error (as it's in HLT)
+  fError.Clear();
+
+  unsigned nProcessed = 0;
+  while (currPos < argc) {
+    //Command.
+    const TString command(argv[currPos]);
+    //Check, if this command must be ignored.
+    SkipMapIter_t skipCmd = fIgnored.find(command);
+    if (skipCmd != fIgnored.end()) {
+      //Command and its parameters must be skipped
+      nProcessed += 1 + skipCmd->second;
+      currPos += 1 + skipCmd->second;
+      continue;
+    }
+
+    //Corresponding parameter.
+    MapIter_t it = fParameters.find(command);
+    if (it == fParameters.end()) {
+      fError = "Unknown command: " + command;
+      return -1;
+    }
+
+    ++currPos;
+    ++nProcessed;
+
+    try {
+      const unsigned n = it->second.SetParameter(argc, argv, currPos);
+      nProcessed += n;
+      currPos += n;
+    } catch (const std::runtime_error& e) {
+      fError = "Command " + command + " error: " + e.what();
+      return -1;
+    }
+  }
+
+  return nProcessed;
+}
+
+}
diff --git a/HLT/global/AliHLTVertexFinderBase.h b/HLT/global/AliHLTVertexFinderBase.h
new file mode 100644 (file)
index 0000000..d4fdadd
--- /dev/null
@@ -0,0 +1,254 @@
+//-*- Mode: C++ -*-
+// $Id$
+#ifndef ALIHLTVERTEXFINDERBASE_H
+#define ALIHLTVERTEXFINDERBASE_H
+/// This file is property of and copyright by the ALICE HLT Project         
+/// ALICE Experiment at CERN, All rights reserved.                         
+/// See cxx source for full Copyright notice                               
+
+/// @file   AliHLTVertexFinderBase.h
+/// @author Timur Pocheptsov
+/// @date   2010-12-26
+/// @brief  Base class for vertex finder components
+///
+
+
+#include <vector>
+#include <map>
+
+#include "TString.h"
+
+#include "AliHLTProcessor.h"
+#include "AliHLTDataTypes.h"
+#include "AliKFParticle.h"
+
+
+//Auxiliary base class, used by primary and V0 vertex finders.
+//It defines a nested type AliHLTTrackInfo and some
+//functions to read tracks from input blocks -
+//this is usefull for both vertexers.
+//This class has to inherit AliHLTProcessor to be able
+//to call member functions from AliHLTComponent.
+//This class is not for end user, it's just a
+//common base for vertex finders.
+
+class AliESDEvent;
+class AliKFVertex;
+
+class AliHLTVertexFinderBase : public AliHLTProcessor
+{
+protected:
+
+  class AliHLTTrackInfo
+  {
+  public:
+    AliHLTTrackInfo()
+        : fID(0),
+          fParticle(),
+          fPrimUsed(false),
+          fPrimDeviation(0.)
+    {
+    }
+
+    AliHLTTrackInfo(int id, const AliVTrack& track,
+                    int pid, bool primUsed, double dev)
+        : fID(id),
+          fParticle(track, pid),
+          fPrimUsed(primUsed),
+          fPrimDeviation(dev)
+    {
+    }
+
+    //Check AliKFParticle parameters and covariance matrix.
+    bool IsKFFinite()const;
+
+    //Track ID taken from input track, just an index in some "collection".
+    int fID;
+
+    AliKFParticle fParticle; //Corresponding to track KFParticle.
+    bool fPrimUsed; //Particle was used for primary vertex fit.
+    double fPrimDeviation; //Primary deviation.
+  };
+
+  //These data types are
+  //used in FillESD functions,
+  //they also used in vertex finders
+  //(v0 finder uses primary finder's block).
+  struct PrimaryFinderBlock
+  {
+    int fFitTracksFlag;
+    int fNPrimaryTracks;
+    int fMinPrimID;
+    int fMaxPrimID;
+    int fPrimTrackIds[1];
+  };
+
+  struct V0FinderBlock
+  {
+    int fNV0s;
+    int fV0s[1];
+  };
+
+protected:
+
+  //Compiler-generated def ctor will call vector's def
+  //ctor for member, but still, compiler wants mem-init-list.
+  AliHLTVertexFinderBase() : fTrackInfos()
+  {
+  }
+
+  //Read tracks from AliESDEvent
+  //into fTrackInfos.
+  //IMPORTANT: fTrackInfos is not
+  //cleared here before filling,
+  //tracks are appended to the end.
+  //A user (derived class)
+  //has to clear it, if needed.
+  void ReadESDTracks();
+  //Read HLT tracks produced by ITS
+  //or TPC (somewhere else?).
+  //IMPORTANT: fTrackInfos is not
+  //cleared here before filling,
+  //tracks are appended to the end.
+  void ReadHLTTracks(const AliHLTComponentDataType& blockType);
+
+public:
+  //Produce output for ESD collector from primary and v0 finders' outputs.
+  static void FillESD(AliESDEvent* esd, AliKFVertex* primVtx, const void* primData,
+                      const void* v0Data);
+
+protected:
+
+  typedef std::vector<AliHLTTrackInfo> TrackInfoVector_t;
+  typedef TrackInfoVector_t::size_type VectorSize_t;
+
+  TrackInfoVector_t fTrackInfos;
+
+  ClassDef(AliHLTVertexFinderBase, 0);
+};
+
+namespace AliHLTUtility
+{
+
+//Small utility to automate command line parsing.
+//Command line consists of commands and parameters.
+//Currently, parameters can be of type int, double,
+//bool (so, command with one parameter of built-in type)
+//or CompoundType (this is for more complex
+//expressions like -command param1 param2 param3).
+//If SetParameter failes, it MUST throw std::runtime_error
+//with description. CmdLineParser will convert this
+//exception into negative integer and will compose
+//error message.
+
+class CompoundType
+{
+public:
+  virtual ~CompoundType()
+  {
+  }
+
+  virtual unsigned SetParameter(unsigned argc, const char** argv, unsigned currPos) = 0;
+};
+
+//Parameter for a command. If the type is CompoundType, it's up to CompoundType
+//to do all parsing. If it's int, double, bool - checks are done here:
+//1. Check if parameter was set already (user specified the same command more than
+//   once - this is an error).
+//2. Check if parameter for command was specified.
+//3. Parameter has correct value: 0 or 1 for bool and
+//   for int or double non-empty constraint is satisfied
+//
+//Object of type Parameter holds a pointer to real object of type int, bool, double
+//(or CompoundType) and this real objects are updated
+//from command line parameters, using SetParameter function.
+
+class Parameter
+{
+public:
+  enum Constraint
+  {
+    none,
+    positive,
+    nonNegative
+    //Something else.
+  };
+
+  Parameter();
+  Parameter(bool* b);
+  Parameter(int* i, Constraint c);
+  Parameter(double* d, Constraint c);
+  Parameter(CompoundType* cp);
+
+  //Returns number of argv elements processed, starting from
+  //currPos.
+  unsigned SetParameter(unsigned argc, const char** argv, unsigned currPos);
+
+private:
+  //If any constraint was set:
+  void CheckConstraint();
+  //
+  void SetConstraintChecker();
+
+  bool fWasSet; //Parameter was set already.
+  Constraint fConstraint; //Constraint on parameter.
+
+  bool* fBool; //Real object to set of type bool.
+  int* fInt; //Real object to set of type int.
+  double* fDouble; //Real object to set of type double.
+  CompoundType* fCompound; //"Object" to set of complex type.
+
+  void (*fConstraintChecker)(const Parameter& param); //Constraint checker.
+
+  static void CheckPositive(const Parameter& param);
+  static void CheckNonNegative(const Parameter& param);
+  //Something else.
+
+  //Compiler generated dtor, copy-ctor and copy-assignment operators are ok.
+};
+
+//CmdLineParser parses char** argv, which constains commands and
+//options for these commands.
+//Returns the number of processed argv elements.
+
+class CmdLineParser
+{
+public:
+
+  CmdLineParser() : fParameters(), fIgnored(), fError()
+  {
+  }
+
+  void Add(const TString& cmd, bool* b);
+  void Add(const TString& cmd, int* i, Parameter::Constraint c = Parameter::none);
+  void Add(const TString& cmd, double* d, Parameter::Constraint c = Parameter::none);
+  void Add(const TString& cmd, CompoundType* ct);
+
+  //Skip -command nParams * params
+  void IgnoreCommand(const TString& cmd, unsigned nParams);
+
+  int Parse(unsigned argc, const char** argv, unsigned currPos);
+
+  const TString& GetError()const
+  {
+    return fError;
+  }
+
+private:
+
+  typedef std::map<TString, Parameter> ParameterMap_t;
+  typedef ParameterMap_t::iterator MapIter_t;
+  typedef std::map<TString, unsigned> SkipMap_t;
+  typedef SkipMap_t::const_iterator SkipMapIter_t;
+
+  //Map of commands and it's parameters.
+  ParameterMap_t fParameters;
+  //These commands and its parameters (if any) will be skipped.
+  SkipMap_t fIgnored;
+
+  TString fError; //Error message describing parsing errors.
+};
+
+}
+
+#endif