From e9f6bf899a2ee434b69a77f292aa7eb2bcaa8797 Mon Sep 17 00:00:00 2001
From: "se.gorbunov" <se.gorbunov@gsi.de>
Date: Tue, 28 Feb 2023 19:17:46 +0000
Subject: [PATCH] bba: draft version of the alignmnet task

---
 reco/L1/ParticleFinder/CbmL1PFFitter.cxx |  56 +++--
 reco/L1/ParticleFinder/CbmL1PFFitter.h   |   6 +-
 reco/alignment/CMakeLists.txt            |   1 +
 reco/alignment/CbmBbaAlignmentTask.cxx   | 287 +++++++++++++++++++++--
 reco/alignment/CbmBbaAlignmentTask.h     |  42 +++-
 5 files changed, 347 insertions(+), 45 deletions(-)

diff --git a/reco/L1/ParticleFinder/CbmL1PFFitter.cxx b/reco/L1/ParticleFinder/CbmL1PFFitter.cxx
index 3264abf8aa..f95f3c6698 100644
--- a/reco/L1/ParticleFinder/CbmL1PFFitter.cxx
+++ b/reco/L1/ParticleFinder/CbmL1PFFitter.cxx
@@ -46,6 +46,7 @@
 //typedef L1Fit1 L1Fit;
 
 using std::vector;
+using namespace std;
 
 namespace NS_L1TrackFitter
 {
@@ -100,7 +101,7 @@ inline CbmL1PFFitter::PFFieldRegion::PFFieldRegion(const L1FieldRegion& fld, int
 void FilterFirst(L1Fit& fit, fvec& x, fvec& y, fvec& dxx, fvec& dxy, fvec& dyy)
 {
   L1TrackPar& tr = fit.Tr();
-  tr.ResetErrors(dxx, dyy, vINF, vINF, 1., 1.e6, 1.e2);
+  tr.ResetErrors(dxx, dyy, 1., 1., 1., 1.e6, 1.e2);
   tr.C10 = dxy;
   tr.x   = x;
   tr.y   = y;
@@ -109,18 +110,13 @@ void FilterFirst(L1Fit& fit, fvec& x, fvec& y, fvec& dxx, fvec& dxy, fvec& dyy)
   tr.NDF = -3.0;
 }
 
-void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo)
+void CbmL1PFFitter::Fit(std::vector<CbmStsTrack>& Tracks, const std::vector<CbmMvdHit>& vMvdHits,
+                        const std::vector<CbmStsHit>& vStsHits, const std::vector<int>& pidHypo)
 {
 
   L1FieldValue b0, b1, b2 _fvecalignment;
   L1FieldRegion fld _fvecalignment;
-
-
-  FairRootManager* fManger  = FairRootManager::Instance();
-  TClonesArray* listStsHits = (TClonesArray*) fManger->GetObject("StsHit");
-  int NMvdStations          = CbmL1::Instance()->fpAlgo->GetNstationsBeforePipe();
-  TClonesArray* listMvdHits = 0;
-  if (NMvdStations > 0.) listMvdHits = (TClonesArray*) fManger->GetObject("MvdHit");
+  // fld.SetUseOriginalField();
 
   static int nHits = CbmL1::Instance()->fpAlgo->GetParameters()->GetNstationsActive();
   int iVec = 0, i = 0;
@@ -169,7 +165,7 @@ void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo)
 
     T.t  = 0.;
     T.vi = 0.;
-    T.ResetErrors(1.e2, 1.e2, 1.e4, 1.e4, 1.e4, 1.e6, 1.e2);
+    T.ResetErrors(1.e2, 1.e2, 1., 1., 1., 1.e6, 1.e2);
 
     if (N_vTracks - itrack < static_cast<unsigned short>(fvec::size())) nTracks_SIMD = N_vTracks - itrack;
     for (i = 0; i < nTracks_SIMD; i++) {
@@ -179,6 +175,8 @@ void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo)
       T.tx[i]  = tr[i]->GetParamFirst()->GetTx();
       T.ty[i]  = tr[i]->GetParamFirst()->GetTy();
       T.qp[i]  = tr[i]->GetParamFirst()->GetQp();
+      T.t[i]   = 0.;
+      T.vi[i]  = 0.;
       T.z[i]   = tr[i]->GetParamFirst()->GetZ();
       T.C00[i] = tr[i]->GetParamFirst()->GetCovariance(0, 0);
       T.C10[i] = tr[i]->GetParamFirst()->GetCovariance(1, 0);
@@ -218,9 +216,8 @@ void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo)
         float posx = 0.f, posy = 0.f, posz = 0.f, time = 0.;
 
         if (i < nHitsTrackMvd) {
-          if (!listMvdHits) continue;
-          int hitIndex   = tr[iVec]->GetMvdHitIndex(i);
-          CbmMvdHit* hit = L1_DYNAMIC_CAST<CbmMvdHit*>(listMvdHits->At(hitIndex));
+          int hitIndex         = tr[iVec]->GetMvdHitIndex(i);
+          const CbmMvdHit* hit = &(vMvdHits[hitIndex]);
 
           posx = hit->GetX();
           posy = hit->GetY();
@@ -236,9 +233,8 @@ void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo)
           dt2[ista][iVec] = hit->GetTimeError() * hit->GetTimeError();
         }
         else {
-          if (!listStsHits) continue;
-          int hitIndex   = tr[iVec]->GetHitIndex(i - nHitsTrackMvd);
-          CbmStsHit* hit = L1_DYNAMIC_CAST<CbmStsHit*>(listStsHits->At(hitIndex));
+          int hitIndex         = tr[iVec]->GetHitIndex(i - nHitsTrackMvd);
+          const CbmStsHit* hit = &(vStsHits[hitIndex]);
 
           posx = hit->GetX();
           posy = hit->GetY();
@@ -291,7 +287,9 @@ void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo)
         }
       }
     }
+
     // fit forward
+
     i = 0;
 
     FilterFirst(fit, x_first, y_first, fstC00, fstC10, fstC11);
@@ -359,7 +357,8 @@ void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo)
       tr[iVec]->SetParamLast(&par);
     }
 
-    //fit backward
+    // fit backward
+
     fit.SetQp0(T.qp);
 
     i = nHits - 1;
@@ -441,6 +440,29 @@ void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo)
   delete[] fB;
 }
 
+void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, const vector<int>& pidHypo)
+{
+
+  FairRootManager* fManger  = FairRootManager::Instance();
+  TClonesArray* mvdHitArray = (TClonesArray*) fManger->GetObject("MvdHit");
+  TClonesArray* stsHitArray = (TClonesArray*) fManger->GetObject("StsHit");
+
+  std::vector<CbmMvdHit> vMvdHits;
+  std::vector<CbmStsHit> vStsHits;
+
+  for (int ih = 0; ih < mvdHitArray->GetEntriesFast(); ih++) {
+    CbmMvdHit hit = *dynamic_cast<const CbmMvdHit*>(mvdHitArray->At(ih));
+    vMvdHits.push_back(hit);
+  }
+
+  for (int ih = 0; ih < stsHitArray->GetEntriesFast(); ih++) {
+    vStsHits.push_back(*dynamic_cast<const CbmStsHit*>(stsHitArray->At(ih)));
+  }
+
+  Fit(Tracks, vMvdHits, vStsHits, pidHypo);
+}
+
+
 void CbmL1PFFitter::GetChiToVertex(vector<CbmStsTrack>& Tracks, vector<PFFieldRegion>& field, vector<float>& chiToVtx,
                                    CbmKFVertex& primVtx, float chiPrim)
 {
diff --git a/reco/L1/ParticleFinder/CbmL1PFFitter.h b/reco/L1/ParticleFinder/CbmL1PFFitter.h
index 2189862fad..1955f4db34 100644
--- a/reco/L1/ParticleFinder/CbmL1PFFitter.h
+++ b/reco/L1/ParticleFinder/CbmL1PFFitter.h
@@ -22,6 +22,8 @@
 
 #include <vector>
 
+class CbmMvdHit;
+class CbmStsHit;
 class CbmStsTrack;
 class L1FieldRegion;
 class CbmKFVertex;
@@ -42,7 +44,9 @@ public:
   ~CbmL1PFFitter();
 
   //functions for fitting CbmStsTrack
-  void Fit(std::vector<CbmStsTrack>& Tracks, std::vector<int>& pidHypo);
+  void Fit(std::vector<CbmStsTrack>& Tracks, const std::vector<CbmMvdHit>& vMvdHits,
+           const std::vector<CbmStsHit>& vStsHits, const std::vector<int>& pidHypo);
+  void Fit(std::vector<CbmStsTrack>& Tracks, const std::vector<int>& pidHypo);
   void CalculateFieldRegion(std::vector<CbmStsTrack>& Tracks, std::vector<PFFieldRegion>& Field);
   void CalculateFieldRegionAtLastPoint(std::vector<CbmStsTrack>& Tracks, std::vector<PFFieldRegion>& field);
   void GetChiToVertex(std::vector<CbmStsTrack>& Tracks, std::vector<PFFieldRegion>& field, std::vector<float>& chiToVtx,
diff --git a/reco/alignment/CMakeLists.txt b/reco/alignment/CMakeLists.txt
index 196318ae96..c2e9448ef0 100644
--- a/reco/alignment/CMakeLists.txt
+++ b/reco/alignment/CMakeLists.txt
@@ -19,6 +19,7 @@ set(PUBLIC_DEPENDENCIES
 set(PRIVATE_DEPENDENCIES
   L1
   bba::library
+  CbmStsBase
 )
 
 generate_cbm_library()
diff --git a/reco/alignment/CbmBbaAlignmentTask.cxx b/reco/alignment/CbmBbaAlignmentTask.cxx
index c2cee83ad8..9354603a7f 100644
--- a/reco/alignment/CbmBbaAlignmentTask.cxx
+++ b/reco/alignment/CbmBbaAlignmentTask.cxx
@@ -21,9 +21,13 @@
 #include "TClonesArray.h"
 #include "TFile.h"
 #include "TH1F.h"
+#include "TRandom.h"
 
 //
 
+#include "CbmMvdHit.h"
+#include "CbmStsHit.h"
+#include "CbmStsSetup.h"
 #include "CbmStsTrack.h"
 
 #include "bba/BBA.h"
@@ -70,27 +74,36 @@ InitStatus CbmBbaAlignmentTask::Init()
     return kERROR;
   }
 
+  // Get hits
+
+  fInputMvdHits = (TClonesArray*) ioman->GetObject("MvdHit");
+  fInputStsHits = (TClonesArray*) ioman->GetObject("StsHit");
+
   // Get sts tracks
-  fStsTrackArray = (TClonesArray*) ioman->GetObject("StsTrack");
-  if (!fStsTrackArray) {
+  fInputStsTracks = (TClonesArray*) ioman->GetObject("StsTrack");
+  if (!fInputStsTracks) {
     LOG(error) << "CbmBbaAlignmentTask::Init: Sts track-array not found!";
     return kERROR;
   }
 
   // MC track match
-  fMCTrackArray = (TClonesArray*) ioman->GetObject("MCTrack");
-  if (!fMCTrackArray) {
+  fInputMcTracks = (TClonesArray*) ioman->GetObject("MCTrack");
+  if (!fInputMcTracks) {
     Warning("CbmBbaAlignmentTask::Init", "mc track array not found!");
     return kERROR;
   }
 
   // Track match
-  fStsTrackMatchArray = (TClonesArray*) ioman->GetObject("StsTrackMatch");
-  if (fStsTrackMatchArray == 0) {
+  fInputStsTrackMatches = (TClonesArray*) ioman->GetObject("StsTrackMatch");
+  if (fInputStsTrackMatches == 0) {
     LOG(error) << "CbmBbaAlignmentTask::Init: track match array not found!";
     return kERROR;
   }
 
+  fTracks.clear();
+  fMvdHits.clear();
+  fStsHits.clear();
+
   return kSUCCESS;
 }
 
@@ -101,41 +114,269 @@ void CbmBbaAlignmentTask::Exec(Option_t* /*opt*/)
 
   fNEvents++;
 
-  bba::BBA alignment;
+  if ((int) fTracks.size() >= fMaxNtracks) { return; }
 
-  alignment.printInfo();
+  // select STS tracks for alignment and store them
 
-  // Check fit quality of the STS tracks
+  for (int iTr = 0; iTr < fInputStsTracks->GetEntriesFast(); iTr++) {
 
-  std::vector<CbmStsTrack> vTracks;
-  vTracks.reserve(fStsTrackArray->GetEntriesFast());
+    if ((int) fTracks.size() >= fMaxNtracks) { break; }
 
-  for (int iTr = 0; iTr < fStsTrackArray->GetEntriesFast(); iTr++) {
-    CbmStsTrack* stsTrack = ((CbmStsTrack*) fStsTrackArray->At(iTr));
-    const auto* par       = stsTrack->GetParamFirst();
+    CbmStsTrack* stsTrack = ((CbmStsTrack*) fInputStsTracks->At(iTr));
+
+    if (stsTrack->GetNofStsHits() < 8) continue;
+    const auto* par = stsTrack->GetParamFirst();
     if (!std::isfinite(par->GetQp())) continue;
-    if (fabs(par->GetQp()) > 1.) continue;
-    vTracks.push_back(*stsTrack);
+    if (fabs(par->GetQp()) > 1.) continue;  // select tracks with min 1 GeV momentum
+
+    CbmStsTrack track;
+
+    // copy track parameters
+
+    track.SetParamFirst(stsTrack->GetParamFirst());
+    track.SetParamLast(stsTrack->GetParamLast());
+    track.SetChiSq(stsTrack->GetChiSq());
+    track.SetNDF(stsTrack->GetNDF());
+
+    // copy hits to the local arrays and set the track hit indices correspondingly
+
+    for (int ih = 0; ih < stsTrack->GetNofMvdHits(); ih++) {
+      assert(fInputMvdHits);
+      int hitIndex  = stsTrack->GetMvdHitIndex(ih);
+      CbmMvdHit hit = *dynamic_cast<CbmMvdHit*>(fInputMvdHits->At(hitIndex));
+      track.AddMvdHit(fMvdHits.size());
+      fMvdHits.push_back(hit);
+    }
+
+    for (int ih = 0; ih < stsTrack->GetNofStsHits(); ih++) {
+      assert(fInputStsHits);
+      int hitIndex  = stsTrack->GetStsHitIndex(ih);
+      CbmStsHit hit = *dynamic_cast<CbmStsHit*>(fInputStsHits->At(hitIndex));
+      track.AddStsHit(fStsHits.size());
+      fStsHits.push_back(hit);
+    }
+
+    fTracks.push_back(track);
+
+  }  // tracks
+}
+
+void CbmBbaAlignmentTask::ApplyAlignment(const std::vector<double>& par)
+{
+  // apply alignment parameters to the hits
+  for (unsigned int ih = 0; ih < fStsHits.size(); ih++) {
+
+    const CbmStsHit& hitOrig = fStsHits[ih];
+
+    int iStation = CbmStsSetup::Instance()->GetStationNumber(hitOrig.GetAddress());
+
+    assert(iStation >= 0 && iStation < CbmStsSetup::Instance()->GetNofStations());
+
+    double dx = par[3 * iStation + 0];
+    double dy = par[3 * iStation + 1];
+    double dz = par[3 * iStation + 2];
+
+    CbmStsHit& hitAligned = fStsHitsAligned[ih];
+
+    hitAligned.SetX(hitOrig.GetX() + dx);
+    hitAligned.SetY(hitOrig.GetY() + dy);
+    hitAligned.SetZ(hitOrig.GetZ() + dz);
   }
+}
+
+double CbmBbaAlignmentTask::CostFunction(const std::vector<double>& par)
+{
+
+  // apply new parameters to the hits
+
+  ApplyAlignment(par);
 
-  std::vector<int> pdg(vTracks.size(), 211);  // pion PDG
+  auto newTracks = fTracks;
 
   CbmL1PFFitter fitter;
-  fitter.Fit(vTracks, pdg);
+  fitter.Fit(newTracks, fMvdHits, fStsHitsAligned, fTrackPdg);
 
   double chi2Total  = 0;
   long int ndfTotal = 1;
 
-  for (unsigned int iTr = 0; iTr < vTracks.size(); iTr++) {
-    if (!std::isfinite(vTracks[iTr].GetChiSq())) continue;
-    chi2Total += vTracks[iTr].GetChiSq();
-    ndfTotal += vTracks[iTr].GetNDF();
+  int nGoodTracks = 0;
+  for (unsigned int iTr = 0; iTr < newTracks.size(); iTr++) {
+    if (!std::isfinite(newTracks[iTr].GetChiSq())) continue;
+    if (newTracks[iTr].GetChiSq() < 0.) continue;
+    if (newTracks[iTr].GetNDF() < 0.) continue;
+
+    nGoodTracks++;
+    chi2Total += newTracks[iTr].GetChiSq();
+    ndfTotal += newTracks[iTr].GetNDF();
   }
-  std::cout << "BBA: chi2/ndf = " << chi2Total / ndfTotal << std::endl;
+
+  double cost = chi2Total / ndfTotal;
+  std::cout << "BBA: cost function:  n tracks " << nGoodTracks << ", cost " << cost
+            << ", diff to ideal cost: " << cost - fCostIdeal << std::endl;
+  return cost;
+  if (nGoodTracks == (int) fTracks.size()) { return cost; }
+  return 1.e30;
 }
 
 void CbmBbaAlignmentTask::Finish()
 {
+  //
+  // perform the alignment
+  //
+
+  std::cout << "BBA: start the alignment procedure with " << fTracks.size() << " tracks ..." << std::endl;
+
+  // init auxiliary arrays
+
+  fStsHitsAligned = fStsHits;
+  fTrackPdg.resize(fTracks.size(), 211);  // pion PDG
+
+  // init alignmemt module
+
+  int nStsStations = CbmStsSetup::Instance()->GetNofStations();
+  int nParameters  = 3 * nStsStations;  // x,yz
+
+  std::vector<bba::Parameter> par(nParameters);
+
+  for (int ip = 0; ip < nParameters; ip++) {
+    bba::Parameter& p = par[ip];
+    p.SetActive(0);
+    p.SetValue(0.);
+    p.SetBoundaryMin(-2.);  // +-1 cm alignment range
+    p.SetBoundaryMax(2.);
+    p.SetStepMin(1.e-6);
+    p.SetStepMax(0.1);
+    p.SetStep(10.e-4);
+  }
+
+  par[3 * (nStsStations - 1) + 0].SetActive(0);  // fix the last station
+  par[3 * (nStsStations - 1) + 1].SetActive(0);
+  par[3 * (nStsStations - 1) + 2].SetActive(0);
+
+  //par[3 * 1 + 1].SetActive(1);
+
+  par[3 * 0 + 0].SetActive(1);
+  par[3 * 0 + 1].SetActive(1);
+  par[3 * 0 + 2].SetActive(1);
+
+  par[3 * 1 + 0].SetActive(1);
+  par[3 * 1 + 1].SetActive(1);
+  par[3 * 1 + 2].SetActive(1);
+
+  par[3 * 2 + 0].SetActive(1);
+  par[3 * 2 + 1].SetActive(1);
+  par[3 * 2 + 2].SetActive(1);
+
+  par[3 * 3 + 0].SetActive(1);
+  par[3 * 3 + 1].SetActive(1);
+  par[3 * 3 + 2].SetActive(1);
+
+  par[3 * 4 + 0].SetActive(1);
+  par[3 * 4 + 1].SetActive(1);
+  par[3 * 4 + 2].SetActive(1);
+
+  par[3 * 5 + 0].SetActive(1);
+  par[3 * 5 + 1].SetActive(1);
+  par[3 * 5 + 2].SetActive(1);
+
+  par[3 * 6 + 0].SetActive(1);
+  par[3 * 6 + 1].SetActive(1);
+  par[3 * 6 + 2].SetActive(1);
+
+  par[3 * 7 + 0].SetActive(0);
+  par[3 * 7 + 1].SetActive(0);
+  par[3 * 7 + 2].SetActive(0);
+
+
+  gRandom->SetSeed(1);
+
+  for (int is = 0; is < nStsStations; is++) {
+    bba::Parameter& px = par[3 * is + 0];
+    bba::Parameter& py = par[3 * is + 1];
+    bba::Parameter& pz = par[3 * is + 2];
+    //py.SetActive(1);
+    //pz.SetStepMin(1.e-4);
+    // +- 0.5 cm misalignment
+
+    //if (px.IsActive()) { px.SetValue(.1); }  //gRandom->Uniform(2 * d) - d); }
+    //if (py.IsActive()) { py.SetValue(.1); }  //gRandom->Uniform(2. * d) - d); }
+    //if (pz.IsActive()) { pz.SetValue(.1); }  //gRandom->Uniform(2. * d) - d); }
+    double d = 0.5;
+    if (px.IsActive()) { px.SetValue(gRandom->Uniform(2. * d) - d); }
+    if (py.IsActive()) { py.SetValue(gRandom->Uniform(2. * d) - d); }
+    if (pz.IsActive()) { pz.SetValue(gRandom->Uniform(2. * d) - d); }
+  }
+
+  bba::BBA alignment;
+
+  alignment.setParameters(par);
+
+  auto lambdaCostFunction = [this](const std::vector<double>& p) { return CostFunction(p); };
+
+  alignment.setChi2(lambdaCostFunction);
+  alignment.printInfo();
+
+  std::vector<double> parAligned;
+  std::vector<double> parMisaligned;
+  {
+    const std::vector<double>& r = alignment.getResult();
+    for (unsigned int i = 0; i < r.size(); i++) {
+      parMisaligned.push_back(r[i]);
+      parAligned.push_back(0.);
+    }
+  }
+
+  {
+    ApplyAlignment(parMisaligned);
+
+    CbmL1PFFitter fitter;
+    auto oldTracks = fTracks;
+    auto newTracks = fTracks;
+    fitter.Fit(newTracks, fMvdHits, fStsHitsAligned, fTrackPdg);
+
+    double chi2Total  = 0;
+    long int ndfTotal = 1;
+
+    int nGoodTracks = 0;
+    fTracks.clear();
+    for (unsigned int iTr = 0; iTr < newTracks.size(); iTr++) {
+      if (!std::isfinite(newTracks[iTr].GetChiSq())) continue;
+      if (newTracks[iTr].GetChiSq() < 0.) continue;
+      if (newTracks[iTr].GetNDF() < 0.) continue;
+      fTracks.push_back(oldTracks[iTr]);
+      nGoodTracks++;
+      chi2Total += newTracks[iTr].GetChiSq();
+      ndfTotal += newTracks[iTr].GetNDF();
+    }
+
+    std::cout << "Initial nTracks " << nGoodTracks << " chi2/ndf " << chi2Total / ndfTotal << std::endl;
+  }
+
+  fCostIdeal = CostFunction(parAligned);
+
+  std::cout << " cost function for the true parameters: " << fCostIdeal << std::endl;
+
+  alignment.align();
+
+  std::cout << " cost function for the true parameters: " << fCostIdeal << std::endl;
+
+  std::cout << " Misaligned parameters: " << std::endl;
+  for (int is = 0; is < nStsStations; is++) {
+    const std::vector<double>& r = parMisaligned;
+    std::cout << "Sts station " << is << ": x " << r[3 * is + 0] << " y " << r[3 * is + 1] << " z " << r[3 * is + 2]
+              << std::endl;
+  }
+
+  std::cout << " Alignment results: " << std::endl;
+
+  for (int is = 0; is < nStsStations; is++) {
+    const std::vector<double>& r = alignment.getResult();
+    std::cout << "Sts station " << is << ": x " << r[3 * is + 0] << " y " << r[3 * is + 1] << " z " << r[3 * is + 2]
+              << std::endl;
+  }
+
+  // store the histograms
+
   TDirectory* curr   = gDirectory;
   TFile* currentFile = gFile;
   // Open output file and write histograms
diff --git a/reco/alignment/CbmBbaAlignmentTask.h b/reco/alignment/CbmBbaAlignmentTask.h
index a316f334fb..fb24957a6b 100644
--- a/reco/alignment/CbmBbaAlignmentTask.h
+++ b/reco/alignment/CbmBbaAlignmentTask.h
@@ -12,6 +12,10 @@
 #ifndef CbmBbaAlignmentTask_H
 #define CbmBbaAlignmentTask_H
 
+#include "CbmMvdHit.h"
+#include "CbmStsHit.h"
+#include "CbmStsTrack.h"
+
 #include "FairTask.h"
 
 class TClonesArray;
@@ -19,6 +23,14 @@ class TFile;
 class TDirectory;
 class TH1F;
 
+///
+/// an example of alignment using BBA package
+///
+/// you need to switch to the double precision in /algo/ca/CaSimdVc.h
+/// by uncommenting this line there:
+///
+/// typedef Vc::double_v fvec;
+///
 class CbmBbaAlignmentTask : public FairTask {
 public:
   // Constructors/Destructors ---------
@@ -39,10 +51,28 @@ private:
   void WriteHistosCurFile(TObject* obj);
   int GetHistoIndex(int pdg);
 
-  //input branches
-  TClonesArray* fStsTrackArray {nullptr};
-  TClonesArray* fMCTrackArray {nullptr};
-  TClonesArray* fStsTrackMatchArray {nullptr};
+  void ApplyAlignment(const std::vector<double>& par);
+
+  double CostFunction(const std::vector<double>& par);
+
+  //input data arrays
+  TClonesArray* fInputMvdHits {nullptr};
+  TClonesArray* fInputStsHits {nullptr};
+  TClonesArray* fInputStsTracks {nullptr};
+
+  TClonesArray* fInputMcTracks {nullptr};         // Mc info for debugging
+  TClonesArray* fInputStsTrackMatches {nullptr};  // Mc info for debugging
+
+  // collection of selected tracks and hits
+  std::vector<CbmStsTrack> fTracks;
+  std::vector<CbmMvdHit> fMvdHits;
+  std::vector<CbmStsHit> fStsHits;
+
+  // temporary array with aligned hits
+  std::vector<CbmStsHit> fStsHitsAligned;
+
+  // array with pdg hypothesis for tracks
+  std::vector<int> fTrackPdg;
 
   //output file with histograms
   TString fHistoFileName {"CbmBbaAlignmentHisto.root"};
@@ -51,6 +81,10 @@ private:
 
   Int_t fNEvents {0};
 
+  Int_t fMaxNtracks {10000};
+
+  double fCostIdeal {1.e10};
+
   //histograms
   TH1F* hTestHisto {nullptr};
 
-- 
GitLab