diff --git a/analysis/PWGDIL/dielectron/lmvm/CMakeLists.txt b/analysis/PWGDIL/dielectron/lmvm/CMakeLists.txt
index 5ecd75cdc07c7a2f91a44bc61012d7dc28be8c0a..838d44393d9aba0303ff2b4c0be6c0f797052954 100644
--- a/analysis/PWGDIL/dielectron/lmvm/CMakeLists.txt
+++ b/analysis/PWGDIL/dielectron/lmvm/CMakeLists.txt
@@ -47,24 +47,21 @@ ${Boost_LIBRARY_DIRS}
 link_directories( ${LINK_DIRECTORIES})
 
 set(SRCS
-CbmAnaDielectronTask.cxx
-CbmAnaDielectronTaskDraw.cxx
-CbmAnaDielectronTaskDrawAll.cxx
-CbmAnaLmvmDrawStudy.cxx
-CbmLmvmHist.cxx
-CbmAnaDielectronStudyReportAll.cxx
-CbmAnaDielectronReports.cxx
-CbmHaddBase.cxx
+LmvmTask.cxx
+LmvmDraw.cxx
+LmvmDrawAll.cxx
+LmvmHist.cxx
+LmvmUtils.cxx
 )
 
 
 IF (SSE_FOUND)
-  Message(STATUS "Analysis will be compiled with SSE support")
+  Message(STATUS "LMVM analysis will be compiled with SSE support")
   ADD_DEFINITIONS(-DHAVE_SSE)
   SET_SOURCE_FILES_PROPERTIES(${SRCS} PROPERTIES COMPILE_FLAGS 
   "-msse -O3")
 ELSE (SSE_FOUND)
-  MESSAGE(STATUS "Analysis will be compiled without SSE support")
+  MESSAGE(STATUS "LMVM analysis will be compiled without SSE support")
   SET_SOURCE_FILES_PROPERTIES(${SRCS} PROPERTIES COMPILE_FLAGS 
   "-O3")
 ENDIF (SSE_FOUND)
@@ -72,10 +69,10 @@ ENDIF (SSE_FOUND)
 ADD_DEFINITIONS(-DDO_TPCCATRACKER_EFF_PERFORMANCE -DNonhomogeneousField -DCBM -DUSE_TIMERS)
 
 
-Set(LINKDEF CbmDiElectronAnalysisLinkDef.h)
-Set(LIBRARY_NAME CbmDiElectronAnalysis)
+Set(LINKDEF LmvmLinkDef.h)
+Set(LIBRARY_NAME CbmLmvm)
 Set(DEPENDENCIES
-    Littrack KF L1 CbmRichBase CbmRichReco CbmRecoBase CbmBase CbmData)
+    Littrack LittrackQA KF L1 CbmRichBase CbmRichReco CbmRecoBase CbmBase CbmData)
 Set(DEFINITIONS -DDO_TPCCATRACKER_EFF_PERFORMANCE -DNonhomogeneousField -DCBM -DUSE_TIMERS)
 
 GENERATE_LIBRARY()
diff --git a/analysis/PWGDIL/dielectron/lmvm/CbmLmvmKinematicParams.h b/analysis/PWGDIL/dielectron/lmvm/CbmLmvmKinematicParams.h
index 14847a0f3621e74ad29e650942d913f1f2dbd109..8a4e10076f96e46efebda0b6b830d782d1b020e5 100644
--- a/analysis/PWGDIL/dielectron/lmvm/CbmLmvmKinematicParams.h
+++ b/analysis/PWGDIL/dielectron/lmvm/CbmLmvmKinematicParams.h
@@ -1,38 +1,34 @@
-/* Copyright (C) 2015 Justus-Liebig-Universitaet Giessen, Giessen
+/* Copyright (C) 2015-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Elena Lebedeva [committer] */
+   Authors: Elena Lebedeva [committer], Semen Lebedev */
 
-/**
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2015
- * @version 1.0
- **/
+#ifndef CBM_LMVM_KINE_PARAMS_H
+#define CBM_LMVM_KINE_PARAMS_H
 
-#ifndef CBM_LMVM_KINEMATIC_PARAMS_H
-#define CBM_LMVM_KINEMATIC_PARAMS_H
-
-#include "CbmLmvmCandidate.h"
 #include "CbmMCTrack.h"
 
 #include "TLorentzVector.h"
 #include "TMath.h"
 
+#include "LmvmCand.h"
+
 #define M2E 2.6112004954086e-7
 
 class CbmLmvmKinematicParams {
 public:
-  Double_t fMomentumMag;  // Absolute value of momentum
-  Double_t fPt;           // Transverse momentum
-  Double_t fRapidity;     // Rapidity
-  Double_t fMinv;         // Invariant mass
-  Double_t fAngle;        // Opening angle
+  Double_t fMomentumMag = 0.;  // Absolute value of momentum
+  Double_t fPt          = 0.;  // Transverse momentum
+  Double_t fRapidity    = 0.;  // Rapidity
+  Double_t fMinv        = 0.;  // Invariant mass
+  Double_t fAngle       = 0.;  // Opening angle
 
   /*
     * Calculate kinematic parameters for MC tracks.
     */
-  static CbmLmvmKinematicParams KinematicParamsWithMcTracks(const CbmMCTrack* mctrackP, const CbmMCTrack* mctrackM)
+  static CbmLmvmKinematicParams Create(const CbmMCTrack* mctrackP, const CbmMCTrack* mctrackM)
   {
     CbmLmvmKinematicParams params;
+    if (mctrackP == nullptr || mctrackM == nullptr) return params;
 
     TVector3 momP;  //momentum e+
     mctrackP->GetMomentum(momP);
@@ -64,10 +60,10 @@ public:
   /*
     * Calculate kinematic parameters for LMVM candidates.
     */
-  static CbmLmvmKinematicParams KinematicParamsWithCandidates(const CbmLmvmCandidate* candP,
-                                                              const CbmLmvmCandidate* candM)
+  static CbmLmvmKinematicParams Create(const LmvmCand* candP, const LmvmCand* candM)
   {
     CbmLmvmKinematicParams params;
+    if (candP == nullptr || candM == nullptr) return params;
 
     TLorentzVector lorVecP(candP->fMomentum, candP->fEnergy);
     TLorentzVector lorVecM(candM->fMomentum, candM->fEnergy);
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmCand.h b/analysis/PWGDIL/dielectron/lmvm/LmvmCand.h
index 144725dc3f1b4c10c5c3ccc9a5ac247ef8495677..7e04f6e2b9d4fc94a806ed421f2c968d608e835d 100644
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmCand.h
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmCand.h
@@ -1,107 +1,94 @@
-/* Copyright (C) 2015 Justus-Liebig-Universitaet Giessen, Giessen
+/* Copyright (C) 2015-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Elena Lebedeva [committer] */
+   Authors: Elena Lebedeva [committer], Semen Lebedev */
 
-/**
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2015
- * @version .0
- **/
-#ifndef CBM_LMVM_CANDIDATE_H
-#define CBM_LMVM_CANDIDATE_H
+#ifndef LMVM_CAND_H
+#define LMVM_CAND_H
 
 #include "TVector3.h"
 
-class CbmLmvmCandidate {
+#include "LmvmDef.h"
+
+class LmvmCand {
 public:
-  CbmLmvmCandidate()
-    : fPosition()
-    , fMomentum()
-    , fMass(0.)
-    , fEnergy(0.)
-    , fRapidity(0.)
-    , fCharge(0)
-    , fChi2Prim(0.)
-    , fChi2sts(0.)
-    , fMcMotherId(-1)
-    , fEventNumber(0.)
-    , fStsMcTrackId(-1)
-    , fRichMcTrackId(-1)
-    , fTrdMcTrackId(-1)
-    , fTofMcTrackId(-1)
-    , fStsInd(-1)
-    , fRichInd(-1)
-    , fTrdInd(-1)
-    , fTofInd(-1)
-    , fIsElectron(kFALSE)
-    , fIsMcSignalElectron(kFALSE)
-    , fIsMcPi0Electron(kFALSE)
-    , fIsMcGammaElectron(kFALSE)
-    , fIsMcEtaElectron(kFALSE)
-    , fMcPdg(-1)
-    , fIsGamma(kFALSE)
-    , fDSts(0.)
-    , fIsTtCutElectron(kFALSE)
-    , fIsStCutElectron(kFALSE)
-    , fIsRtCutElectron(kFALSE)
-    , fIsMvd1CutElectron(kFALSE)
-    , fIsMvd2CutElectron(kFALSE)
-    , fRichAnn(0.)
-    , fTrdAnn(0.)
-    , fMass2(0.)
+  LmvmCand() {}
+
+  void ResetMcParams()
   {
+    fMcSrc         = ELmvmSrc::Undefined;
+    fMcMotherId    = -1;
+    fStsMcTrackId  = -1;
+    fRichMcTrackId = -1;
+    fTrdMcTrackId  = -1;
+    fTofMcTrackId  = -1;
   }
 
-  void ResetMcParams()
+  void SetIsTopologyCutElectron(ELmvmTopologyCut cut, bool value)
   {
-    fIsMcSignalElectron = false;
-    fIsMcPi0Electron    = false;
-    fIsMcGammaElectron  = false;
-    fIsMcEtaElectron    = false;
-    fMcMotherId         = -1;
-    fStsMcTrackId       = -1;
-    fRichMcTrackId      = -1;
-    fTrdMcTrackId       = -1;
-    fTofMcTrackId       = -1;
+    if (cut == ELmvmTopologyCut::TT) { fIsTtCut = value; }
+    if (cut == ELmvmTopologyCut::ST) { fIsStCut = value; }
+    if (cut == ELmvmTopologyCut::RT) { fIsRtCut = value; }
+  }
+
+  bool IsCutTill(ELmvmAnaStep step) const
+  {
+    if (step == ELmvmAnaStep::Mc || step == ELmvmAnaStep::Acc || step == ELmvmAnaStep::Reco) return true;
+    if (step == ELmvmAnaStep::Chi2Prim && fIsChi2Prim) return true;
+    if (step == ELmvmAnaStep::ElId && IsCutTill(ELmvmAnaStep::Chi2Prim) && fIsElectron) return true;
+    if (step == ELmvmAnaStep::GammaCut && IsCutTill(ELmvmAnaStep::ElId) && fIsGammaCut) return true;
+    if (step == ELmvmAnaStep::Mvd1Cut && IsCutTill(ELmvmAnaStep::GammaCut) && fIsMvd1Cut) return true;
+    if (step == ELmvmAnaStep::Mvd2Cut && IsCutTill(ELmvmAnaStep::Mvd1Cut) && fIsMvd2Cut) return true;
+    if (step == ELmvmAnaStep::StCut && IsCutTill(ELmvmAnaStep::Mvd2Cut) && fIsStCut) return true;
+    if (step == ELmvmAnaStep::RtCut && IsCutTill(ELmvmAnaStep::StCut) && fIsRtCut) return true;
+    if (step == ELmvmAnaStep::TtCut && IsCutTill(ELmvmAnaStep::RtCut) && fIsTtCut) return true;
+    if (step == ELmvmAnaStep::PtCut && IsCutTill(ELmvmAnaStep::TtCut) && fIsPtCut) return true;
+    return false;
   }
 
   // track parameters
   TVector3 fPosition;
   TVector3 fMomentum;
-  Double_t fMass;
-  Double_t fEnergy;
-  Double_t fRapidity;
-  Int_t fCharge;
-  Double_t fChi2Prim;
-  Double_t fChi2sts;
+  double fMass     = 0.;
+  double fEnergy   = 0.;
+  double fRapidity = 0.;
+  int fCharge      = 0;
+  double fChi2Prim = 0.;
+  double fChi2sts  = 0.;
+
+  int fMcMotherId    = -1;
+  int fEventNumber   = 0;
+  int fStsMcTrackId  = -1;
+  int fRichMcTrackId = -1;
+  int fTrdMcTrackId  = -1;
+  int fTofMcTrackId  = -1;
+  int fStsInd        = -1;
+  int fRichInd       = -1;
+  int fTrdInd        = -1;
+  int fTofInd        = -1;
+  int fMcPdg         = -1;
+  double fRichAnn    = 0.;
+  double fTrdAnn     = 0.;
+  double fMass2      = 0.;
 
-  Int_t fMcMotherId;
-  Int_t fEventNumber;
-  Int_t fStsMcTrackId;
-  Int_t fRichMcTrackId;
-  Int_t fTrdMcTrackId;
-  Int_t fTofMcTrackId;
-  Int_t fStsInd;
-  Int_t fRichInd;
-  Int_t fTrdInd;
-  Int_t fTofInd;
-  Bool_t fIsElectron;
-  Bool_t fIsMcSignalElectron;
-  Bool_t fIsMcPi0Electron;
-  Bool_t fIsMcGammaElectron;
-  Bool_t fIsMcEtaElectron;
+  // Cuts. If true then cut is passed
+  bool fIsChi2Prim = false;
+  bool fIsElectron = false;
+  bool fIsGammaCut = false;
+  bool fIsMvd1Cut  = false;
+  bool fIsMvd2Cut  = false;
+  bool fIsTtCut    = false;
+  bool fIsStCut    = false;
+  bool fIsRtCut    = false;
+  bool fIsPtCut    = false;
 
-  Int_t fMcPdg;
-  Bool_t fIsGamma;
-  Double_t fDSts;
-  Bool_t fIsTtCutElectron;
-  Bool_t fIsStCutElectron;
-  Bool_t fIsRtCutElectron;
-  Bool_t fIsMvd1CutElectron;
-  Bool_t fIsMvd2CutElectron;
-  Double_t fRichAnn;
-  Double_t fTrdAnn;
-  Double_t fMass2;
+  // MC
+  ELmvmSrc fMcSrc = ELmvmSrc::Undefined;
+  bool IsMcSignal() const { return fMcSrc == ELmvmSrc::Signal; }
+  bool IsMcPi0() const { return fMcSrc == ELmvmSrc::Pi0; }
+  bool IsMcGamma() const { return fMcSrc == ELmvmSrc::Gamma; }
+  bool IsMcEta() const { return fMcSrc == ELmvmSrc::Eta; }
+  // for candidates BG is all candidates which are not signal
+  bool fIsMcBg() const { return fMcSrc != ELmvmSrc::Signal; }
 };
 
 #endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmCuts.h b/analysis/PWGDIL/dielectron/lmvm/LmvmCuts.h
index 9b7497116cc2ad9025b6c468a4a88f1ab9a9c2b1..f61c5018b1b5b1c122271bd15efb312ea9fa3e16 100644
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmCuts.h
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmCuts.h
@@ -1,128 +1,101 @@
-/* Copyright (C) 2015-2018 Justus-Liebig-Universitaet Giessen, Giessen
+/* Copyright (C) 2015-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Elena Lebedeva [committer], Gregor Pitsch */
+   Authors: Elena Lebedeva [committer], Gregor Pitsch, Semen Lebedev */
 
-/**
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2015
- * @version 1.0
- **/
+#ifndef LMVM_CUTS_H
+#define LMVM_CUTS_H
 
+#include <Logger.h>
 
-#ifndef CBM_LMVM_CUTS_H
-#define CBM_LMVM_CUTS_H
+#include <math.h>
 
-#include "TObject.h"
+#include "LmvmDef.h"
 
-#include <iostream>
 
-class CbmLmvmCuts {
+class LmvmCuts {
 public:
-  CbmLmvmCuts()
-    : fMomentumCut(0.)
-    , fChiPrimCut(0.)
-    , fPtCut(0.)
-    , fAngleCut(0.)
-    , fGammaCut(0.)
-    , fStCutAngle(0.)
-    , fStCutPP(0.)
-    , fTtCutAngle(0.)
-    , fTtCutPP(0.)
-    , fRtCutAngle(0.)
-    , fRtCutPP(0.)
-    , fMvd1CutP(0.)
-    , fMvd1CutD(0.)
-    , fMvd2CutP(0.)
-    , fMvd2CutD(0.)
+  LmvmCuts() {}
+
+  bool IsTopologyCutOk(ELmvmTopologyCut cut, double mom1, double mom2, double minAngle)
   {
-    SetDefaultCuts();
+    double angleCut = 0., ppCut = 0.;
+    if (cut == ELmvmTopologyCut::ST) {
+      angleCut = fStCutAngle;
+      ppCut    = fStCutPP;
+    }
+    else if (cut == ELmvmTopologyCut::RT) {
+      angleCut = fRtCutAngle;
+      ppCut    = fRtCutPP;
+    }
+    else if (cut == ELmvmTopologyCut::TT) {
+      angleCut = fTtCutAngle;
+      ppCut    = fTtCutPP;
+    }
+    else {
+      LOG(error) << "LmvmCuts::IsTopologyCut cut is not defined.";
+    }
+    double sqrt_mom = std::sqrt(mom1 * mom2);
+    double val      = -1. * (angleCut / ppCut) * sqrt_mom + angleCut;
+    if (!(sqrt_mom < ppCut && val > minAngle)) return true;
+    return false;
   }
 
-  /*
-	 * Set default electron ID and analysis cuts.
-	 */
-  void SetDefaultCuts()
-  {
-    //electron ID cuts, we use CbmLitGlobalElectronId for identification
-    fMomentumCut = -1.;  // if cut < 0 it is not used
+  bool IsChi2PrimaryOk(double chi2Prim) { return (chi2Prim < fChi2PrimCut); }
 
-    // analysis cuts auau
-    fPtCut      = 0.2;
-    fAngleCut   = 1.;
-    fChiPrimCut = 3.;
-    fGammaCut   = 0.025;
-    //fStCutAngle = 1.5;
-    //fStCutPP = 1.5;
-    fStCutAngle = 2.4;
-    fStCutPP    = 1.;
-    //fTtCutAngle = 0.75;
-    //fTtCutPP = 4.0;
-    fTtCutAngle = 2.0;
-    fTtCutPP    = 3.0;
-    //fRtCutAngle = 1.0;
-    //fRtCutPP = 2.5;
-    fRtCutAngle = 1.2;
-    fRtCutPP    = 1.6;
-    fMvd1CutP   = 1.2;
-    fMvd1CutD   = 0.4;
-    fMvd2CutP   = 1.5;
-    fMvd2CutD   = 0.5;
+  bool IsGammaCutOk(double minv) { return (minv >= fGammaCut); }
 
-    // analysis cuts agag
-    /*    fPtCut = 0.2;
-		fAngleCut = 1.;
-		fChiPrimCut = 3.;
-		fGammaCut = 0.025;
-		fStCutAngle = 2.4;
-                fStCutPP = 1.;
-		fTtCutAngle = 1.5;
-                fTtCutPP = 1.7;
-	       	fRtCutAngle = 1.2;
-                fRtCutPP = 1.6;
-		fMvd1CutP = 1.2;
-		fMvd1CutD = 0.4;
-		fMvd2CutP = 1.5;
-		fMvd2CutD = 0.5;
-            */
+  bool IsPtCutOk(double pt) { return (pt > fPtCut); }
+
+  bool IsMvdCutOk(int stationNum, double dmvd, double mom)
+  {
+    if (stationNum <= 0 || stationNum > 2) {
+      LOG(error) << "LmvmCuts::IsMvdCut stationNum is not in valid. stationNum = " << stationNum;
+      return false;
+    }
+    // it is assumed that stationNum can be 1 or 2
+    double cutD = (stationNum == 1) ? fMvd1CutD : fMvd2CutD;
+    double cutP = (stationNum == 1) ? fMvd1CutP : fMvd2CutP;
+    double val  = -1. * (cutP / cutD) * dmvd + cutP;
+    if (!(dmvd < cutD && val > mom)) return true;
+    return false;
   }
 
-  /*
-	 * Print out cuts.
-	 */
-  void Print()
+  std::string ToString()
   {
-    std::cout << "Used cuts:" << std::endl
-              << "fChiPrimCut = " << fChiPrimCut << std::endl
-              << "fPtCut = " << fPtCut << std::endl
-              << "fAngleCut = " << fAngleCut << std::endl
-              << "fGammaCut = " << fGammaCut << std::endl
-              << "fStCut (ang,pp) = (" << fStCutAngle << "," << fStCutPP << ")" << std::endl
-              << "fRtCut (ang,pp) = (" << fRtCutAngle << "," << fRtCutPP << ")" << std::endl
-              << "fTtCut (ang,pp) = (" << fTtCutAngle << "," << fTtCutPP << ")" << std::endl
-              << "fMvd1Cut (p,d) = (" << fMvd1CutP << "," << fMvd1CutD << ")" << std::endl
-              << "fMvd2Cut (p,d) = (" << fMvd2CutP << "," << fMvd2CutD << ")" << std::endl
-              << "fMomentumCut = " << fMomentumCut << std::endl;
+    std::stringstream ss;
+    ss << "LMVM cuts:" << std::endl
+       << "fChiPrimCut = " << fChi2PrimCut << std::endl
+       << "fPtCut = " << fPtCut << std::endl
+       << "fAngleCut = " << fAngleCut << std::endl
+       << "fGammaCut = " << fGammaCut << std::endl
+       << "fStCut (ang,pp) = (" << fStCutAngle << "," << fStCutPP << ")" << std::endl
+       << "fRtCut (ang,pp) = (" << fRtCutAngle << "," << fRtCutPP << ")" << std::endl
+       << "fTtCut (ang,pp) = (" << fTtCutAngle << "," << fTtCutPP << ")" << std::endl
+       << "fMvd1Cut (p,d) = (" << fMvd1CutP << "," << fMvd1CutD << ")" << std::endl
+       << "fMvd2Cut (p,d) = (" << fMvd2CutP << "," << fMvd2CutD << ")" << std::endl
+       << "fMomentumCut = " << fMomentumCut << std::endl;
+    return ss.str();
   }
 
 public:
   // ID cuts, we use CbmLitGlobalElectronId for identification
-  Double_t fMomentumCut;  // if cut < 0 then it will not be used
+  double fMomentumCut = -1.;  // if fMomentumCut < 0 it is not used
 
   // Analysis cuts
-  Double_t fChiPrimCut;
-  Double_t fPtCut;
-  Double_t fAngleCut;
-  Double_t fGammaCut;
-  Double_t fStCutAngle;
-  Double_t fStCutPP;
-  Double_t fTtCutAngle;
-  Double_t fTtCutPP;
-  Double_t fRtCutAngle;
-  Double_t fRtCutPP;
-  Double_t fMvd1CutP;
-  Double_t fMvd1CutD;
-  Double_t fMvd2CutP;
-  Double_t fMvd2CutD;
+  double fPtCut       = 0.2;
+  double fAngleCut    = 1.;
+  double fChi2PrimCut = 3.;
+  double fGammaCut    = 0.025;
+  double fStCutAngle  = 2.4;
+  double fStCutPP     = 1.;
+  double fTtCutAngle  = 2.0;
+  double fTtCutPP     = 3.0;
+  double fRtCutAngle  = 1.2;
+  double fRtCutPP     = 1.6;
+  double fMvd1CutP    = 1.2;
+  double fMvd1CutD    = 0.4;
+  double fMvd2CutP    = 1.5;
+  double fMvd2CutD    = 0.5;
 };
 
 #endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmDef.h b/analysis/PWGDIL/dielectron/lmvm/LmvmDef.h
new file mode 100644
index 0000000000000000000000000000000000000000..1fe0053cc8fe81c8bd91884f33c76eae6f788bb9
--- /dev/null
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmDef.h
@@ -0,0 +1,127 @@
+/* Copyright (C) 2021 Justus-Liebig-Universitaet Giessen, Giessen
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Semen Lebedev [committer] */
+
+#ifndef LMVM_DEF_H
+#define LMVM_DEF_H
+
+#include "Rtypes.h"
+
+#include <string>
+
+class TH1D;
+
+enum class ELmvmTopologyCut : int
+{
+  ST,
+  RT,
+  TT
+};
+
+
+enum class ELmvmSrc : int
+{
+  Signal    = 0,
+  Bg        = 1,
+  Pi0       = 2,
+  Gamma     = 3,
+  Eta       = 4,
+  Undefined = 5
+};
+
+
+enum class ELmvmAnaStep : int
+{
+  Mc        = 0,
+  Acc       = 1,
+  Reco      = 2,
+  Chi2Prim  = 3,
+  ElId      = 4,
+  GammaCut  = 5,
+  Mvd1Cut   = 6,
+  Mvd2Cut   = 7,
+  StCut     = 8,
+  RtCut     = 9,
+  TtCut     = 10,
+  PtCut     = 11,
+  Undefined = 12
+};
+
+enum class ELmvmBgPairSrc : int
+{
+  GG        = 0,  // gamma-gamma
+  PP        = 1,  // pi0-pi0
+  OO        = 2,  // other-other
+  GP        = 3,  // gamma-pi0
+  GO        = 4,  // gamma-other
+  PO        = 5,  // pi0-other
+  Undefined = 6
+};
+
+enum class ELmvmSignal : int
+{
+  Inmed  = 0,
+  Qgp    = 1,
+  Omega  = 2,
+  Phi    = 3,
+  OmegaD = 4
+};
+
+class LmvmDataXYInd {
+public:
+  LmvmDataXYInd() {}
+  LmvmDataXYInd(double x, double y, int ind) : fX(x), fY(y), fInd(ind) {}
+  double fX = 0.;
+  double fY = 0.;
+  int fInd  = 0;
+};
+
+class LmvmDataAngMomInd {
+public:
+  LmvmDataAngMomInd() {}
+  LmvmDataAngMomInd(double angle, double mom, int ind) : fAngle(angle), fMom(mom), fInd(ind) {}
+  double fAngle = 0.;
+  double fMom   = 0.;
+  int fInd      = 0;
+};
+
+class LmvmDrawMinvData {
+public:
+  LmvmDrawMinvData() {}
+  LmvmDrawMinvData(TH1D* h, Color_t fillColor, Color_t lineColor, int lineWidth, Style_t fillStyle,
+                   const std::string& legend)
+    : fH(h)
+    , fFillColor(fillColor)
+    , fLineColor(lineColor)
+    , fLineWidth(lineWidth)
+    , fFillStyle(fillStyle)
+    , fLegend(legend)
+  {
+  }
+
+  TH1D* fH            = nullptr;
+  Color_t fFillColor  = 0;
+  Color_t fLineColor  = 0;
+  int fLineWidth      = 0;
+  Style_t fFillStyle  = -1;
+  std::string fLegend = "";
+};
+
+class LmvmSBgResultData {
+public:
+  LmvmSBgResultData() {}
+  LmvmSBgResultData(double sBgRatio, double signallEff, double fitMean, double fitSigma)
+    : fSBgRatio(sBgRatio)
+    , fSignallEff(signallEff)
+    , fFitMean(fitMean)
+    , fFitSigma(fitSigma)
+  {
+  }
+  double fSBgRatio   = 0.;
+  double fSignallEff = 0.;
+  double fFitMean    = 0.;
+  double fFitSigma   = 0;
+};
+
+
+#endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmDraw.cxx b/analysis/PWGDIL/dielectron/lmvm/LmvmDraw.cxx
old mode 100755
new mode 100644
index 119013da6112e11eb8fface5f807a1e18d225a34..b695a27511a9fd4ef25e6090edcf4d9a36a65fad
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmDraw.cxx
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmDraw.cxx
@@ -2,13 +2,7 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev [committer], Elena Lebedeva */
 
-/** CbmAnaDielectronTaskDraw.cxx
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2011
- * @version 1.0
- **/
-
-#include "CbmAnaDielectronTaskDraw.h"
+#include "LmvmDraw.h"
 
 #include "CbmDrawHist.h"
 #include "CbmHistManager.h"
@@ -37,69 +31,57 @@
 #include <sstream>
 #include <string>
 
-ClassImp(CbmAnaDielectronTaskDraw);
+ClassImp(LmvmDraw);
 
 using namespace std;
 using namespace Cbm;
-CbmAnaDielectronTaskDraw::CbmAnaDielectronTaskDraw()
-  : TObject()
-  , fNofEvents(0)
-  , fUseMvd(kFALSE)
-  , fDrawSignificance(kFALSE)
-  , fCuts()
-  , fHM(NULL)
-  , fOutputDir("")
-{
-}
+LmvmDraw::LmvmDraw() {}
 
-void CbmAnaDielectronTaskDraw::DrawHistFromFile(const string& fileName, const string& outputDir, Bool_t useMvd,
-                                                Bool_t drawSig)
+void LmvmDraw::DrawHistFromFile(const string& fileName, const string& outputDir, bool useMvd, bool drawSig)
 {
   SetDefaultDrawStyle();
   fOutputDir        = outputDir;
   fUseMvd           = useMvd;
   fDrawSignificance = drawSig;
 
-  fCuts.SetDefaultCuts();
-
   /// Save old global file and folder pointer to avoid messing with FairRoot
   TFile* oldFile     = gFile;
   TDirectory* oldDir = gDirectory;
 
-  fHM         = new CbmHistManager();
   TFile* file = new TFile(fileName.c_str());
-  fHM->ReadFromFile(file);
-  fNofEvents = (Int_t) H1("fh_event_number")->GetEntries();
+  fH.fHM.ReadFromFile(file);
+  fNofEvents = (int) fH.fHM.H1("hEventNumber")->GetEntries();
   cout << "File name = " << fileName << endl;
   cout << "Number of events = " << fNofEvents << endl;
 
-  fHM->ScaleByPattern(".*", 1. / fNofEvents);
-  SOverBgAll();
+  fH.fHM.ScaleByPattern(".*", 1. / fNofEvents);
   RebinMinvHist();
-  if (!fUseMvd) RemoveMvdCutBins();
-  DrawPtYDistributionAll();
-  DrawPtYEfficiencyAll();
-  DrawRapidityDistributionAll();
-  DrawMomentumDistributionAll();
-  DrawMomentumEfficiencyAll();
-  DrawMotherPdg();
-  DrawPPAngleMCSignal();
-  DrawSourcesBgPairsAll();
+  DrawAnaStepMany("lmvm_pair_pty", [this](ELmvmAnaStep step) { DrawPtY(step); });
+  DrawAnaStepMany("lmvm_pair_rapidity", [this](ELmvmAnaStep step) { DrawRapidity(step); });
+  DrawAnaStepMany("lmvm_pair_pty_efficiency", [this](ELmvmAnaStep step) { DrawPtYEfficiency(step); });
+  DrawAnaStepMany("lmvm_minv_sbg", [this](ELmvmAnaStep step) { DrawMinvSBg(step); });
+  DrawAnaStepMany("lmvm_minv_bgPairSrc", [this](ELmvmAnaStep step) { DrawMinvBgPairSrc(step); });
+  DrawAnaStepMany("lmvm_minv_matching", [this](ELmvmAnaStep step) { DrawMinvMatching(step); });
+  DrawAnaStepMany("lmvm_minv_pt", [this](ELmvmAnaStep step) { DrawMinvPt(step); });
+  DrawAnaStepMany("lmvm_anglePair", [this](ELmvmAnaStep step) { DrawSrcAnaStepH1("hAnglePair", step); });
+
+  // draw momentum histograms
+  for (const string& hName : {"hMom", "hMomPx", "hMomPy", "hMomPz", "hPt", "hRapidity"}) {
+    DrawAnaStepMany("lmvm_" + hName, [this, hName](ELmvmAnaStep step) { DrawSrcAnaStepH1(hName, step); });
+    DrawAnaStepMany("lmvm_" + hName + "EpEm", [this, hName](ELmvmAnaStep step) { DrawSrcAnaStepEpEmH1(hName, step); });
+  }
+  DrawMomAccEpEm();
+
+  DrawMisc();
   DrawGammaVertex();
-  DrawCutDistributions();
-  DrawMinvForEachAnalysisStep();
-  DrawMinvSandBgAll();
-  DrawMinvSourceAll();
+  DrawCuts();
+  DrawMinvAll();
   DrawBgSourceTracks();
   DrawMismatchesAndGhosts();
-  DrawMinvPtAll();
-  DrawBgSourcesVsMomentum();
   DrawMvdCutQa();
   DrawMvdAndStsHist();
-  DrawElPiMomHis();
+  DrawPiMom();
   DrawPmtXY();
-  DrawMomLikeHist();
-  DrawSingleParticleYield();
   SaveCanvasToImage();
 
   /// Restore old global file and folder pointer to avoid messing with FairRoot
@@ -107,842 +89,276 @@ void CbmAnaDielectronTaskDraw::DrawHistFromFile(const string& fileName, const st
   gDirectory = oldDir;
 }
 
-void CbmAnaDielectronTaskDraw::DrawMomLikeHist()
-{
-  TCanvas* c = fHM->CreateCanvas("lmvm_mom_likelihood", "lmvm_mom_likelihood", 1000, 500);
-
-  c->Divide(2, 1);
-  c->cd(1);
-  DrawH2(H2("fh_mom_likelihood_El"));
-  c->cd(2);
-  DrawH2(H2("fh_mom_likelihood_Pi"));
-}
-
-void CbmAnaDielectronTaskDraw::DrawSingleParticleYield()
-{
-  // Draw 1D Histos: Yield vs. Momentum
-  TCanvas* c2 = fHM->CreateCanvas("fh_mom_ElPos_pluto", "fh_mom_ElPos_pluto", 1000, 500);
-  c2->Divide(2, 1);
-  c2->cd(1);
-  Draw1DHistoForEachAnalysisStep("fh_nof_plutoElectrons", true);
-  c2->cd(2);
-  Draw1DHistoForEachAnalysisStep("fh_nof_plutoPositrons", true);
-
-  TCanvas* c3 = fHM->CreateCanvas("fh_mom_ElPos_urqmd", "fh_mom_ElPos_urqmd", 1000, 500);
-  c3->Divide(2, 1);
-  c3->cd(1);
-  Draw1DHistoForEachAnalysisStep("fh_nof_urqmdElectrons", true);
-  c3->cd(2);
-  Draw1DHistoForEachAnalysisStep("fh_nof_urqmdPositrons", true);
-
-  // draw electron and positron yield vs. momentum
-  TH1D* nPlutoElMc    = (TH1D*) H1("fh_nof_plutoElectrons_mc")->Clone();
-  TH1D* nPlutoPosMc   = (TH1D*) H1("fh_nof_plutoPositrons_mc")->Clone();
-  TH1D* nPlutoElAcc   = (TH1D*) H1("fh_nof_plutoElectrons_acc")->Clone();
-  TH1D* nPlutoPosAcc  = (TH1D*) H1("fh_nof_plutoPositrons_acc")->Clone();
-  TH1D* nPlutoElReco  = (TH1D*) H1("fh_nof_plutoElectrons_reco")->Clone();
-  TH1D* nPlutoPosReco = (TH1D*) H1("fh_nof_plutoPositrons_reco")->Clone();
-  TH1D* nPlutoElElid  = (TH1D*) H1("fh_nof_plutoElectrons_elid")->Clone();
-  TH1D* nPlutoPosElid = (TH1D*) H1("fh_nof_plutoPositrons_elid")->Clone();
-  TH1D* nPlutoElTt    = (TH1D*) H1("fh_nof_plutoElectrons_ttcut")->Clone();
-  TH1D* nPlutoPosTt   = (TH1D*) H1("fh_nof_plutoPositrons_ttcut")->Clone();
-  TH1D* nPlutoElPt    = (TH1D*) H1("fh_nof_plutoElectrons_ptcut")->Clone();
-  TH1D* nPlutoPosPt   = (TH1D*) H1("fh_nof_plutoPositrons_ptcut")->Clone();
-  TH1D* nUrqmdElMc    = (TH1D*) H1("fh_nof_urqmdElectrons_mc")->Clone();
-  TH1D* nUrqmdPosMc   = (TH1D*) H1("fh_nof_urqmdPositrons_mc")->Clone();
-  TH1D* nUrqmdElAcc   = (TH1D*) H1("fh_nof_urqmdElectrons_acc")->Clone();
-  TH1D* nUrqmdPosAcc  = (TH1D*) H1("fh_nof_urqmdPositrons_acc")->Clone();
-  TH1D* nUrqmdElReco  = (TH1D*) H1("fh_nof_urqmdElectrons_reco")->Clone();
-  TH1D* nUrqmdPosReco = (TH1D*) H1("fh_nof_urqmdPositrons_reco")->Clone();
-  TH1D* nUrqmdElElid  = (TH1D*) H1("fh_nof_urqmdElectrons_elid")->Clone();
-  TH1D* nUrqmdPosElid = (TH1D*) H1("fh_nof_urqmdPositrons_elid")->Clone();
-  TH1D* nUrqmdElTt    = (TH1D*) H1("fh_nof_urqmdElectrons_ttcut")->Clone();
-  TH1D* nUrqmdPosTt   = (TH1D*) H1("fh_nof_urqmdPositrons_ttcut")->Clone();
-  TH1D* nUrqmdElPt    = (TH1D*) H1("fh_nof_urqmdElectrons_ptcut")->Clone();
-  TH1D* nUrqmdPosPt   = (TH1D*) H1("fh_nof_urqmdPositrons_ptcut")->Clone();
-
-  double min1 = 5e-8;
-  double max1 = 50;
-  nPlutoElMc->SetMinimum(min1);
-  nPlutoElMc->SetMaximum(max1);
-  nPlutoPosMc->SetMinimum(min1);
-  nPlutoPosMc->SetMaximum(max1);
-  nPlutoElAcc->SetMinimum(min1);
-  nPlutoElAcc->SetMaximum(max1);
-  nPlutoPosAcc->SetMinimum(min1);
-  nPlutoPosAcc->SetMaximum(max1);
-  nPlutoElReco->SetMinimum(min1);
-  nPlutoElReco->SetMaximum(max1);
-  nPlutoPosReco->SetMinimum(min1);
-  nPlutoPosReco->SetMaximum(max1);
-  nPlutoElElid->SetMinimum(min1);
-  nPlutoElElid->SetMaximum(max1);
-  nPlutoPosElid->SetMinimum(min1);
-  nPlutoPosElid->SetMaximum(max1);
-  nPlutoElTt->SetMinimum(min1);
-  nPlutoElTt->SetMaximum(max1);
-  nPlutoPosTt->SetMinimum(min1);
-  nPlutoPosTt->SetMaximum(max1);
-  nPlutoElPt->SetMinimum(min1);
-  nPlutoElPt->SetMaximum(max1);
-  nPlutoPosPt->SetMinimum(min1);
-  nPlutoPosPt->SetMaximum(max1);
-  nUrqmdElMc->SetMinimum(min1);
-  nUrqmdElMc->SetMaximum(max1);
-  nUrqmdPosMc->SetMinimum(min1);
-  nUrqmdPosMc->SetMaximum(max1);
-  nUrqmdElAcc->SetMinimum(min1);
-  nUrqmdElAcc->SetMaximum(max1);
-  nUrqmdPosAcc->SetMinimum(min1);
-  nUrqmdPosAcc->SetMaximum(max1);
-  nUrqmdElReco->SetMinimum(min1);
-  nUrqmdElReco->SetMaximum(max1);
-  nUrqmdPosReco->SetMinimum(min1);
-  nUrqmdPosReco->SetMaximum(max1);
-  nUrqmdElElid->SetMinimum(min1);
-  nUrqmdElElid->SetMaximum(max1);
-  nUrqmdPosElid->SetMinimum(min1);
-  nUrqmdPosElid->SetMaximum(max1);
-  nUrqmdElTt->SetMinimum(min1);
-  nUrqmdElTt->SetMaximum(max1);
-  nUrqmdPosTt->SetMinimum(min1);
-  nUrqmdPosTt->SetMaximum(max1);
-  nUrqmdElPt->SetMinimum(min1);
-  nUrqmdElPt->SetMaximum(max1);
-  nUrqmdPosPt->SetMinimum(min1);
-  nUrqmdPosPt->SetMaximum(max1);
-
-  fHM->CreateCanvas("fh_nof_plutoElPos", "fh_nof_plutoElPos", 800, 800);
-  DrawH1({nPlutoElMc, nPlutoPosMc, nPlutoElAcc, nPlutoPosAcc, nPlutoElReco, nPlutoPosReco}, {"", "", "", "", "", ""},
-         kLinear, kLog, false, 0, 0, 0, 0, "Hist p");
-
-  TLegend* legendNofPP = new TLegend(0.65, 0.6, 0.88, 0.93);
-  legendNofPP->SetFillColor(kWhite);
-  legendNofPP->AddEntry(nPlutoElMc, "electrons kMc");
-  legendNofPP->AddEntry(nPlutoPosMc, "positrons kMc");
-  legendNofPP->AddEntry(nPlutoElAcc, "electrons kAcc");
-  legendNofPP->AddEntry(nPlutoPosAcc, "positrons kAcc");
-  legendNofPP->AddEntry(nPlutoElReco, "electrons kReco");
-  legendNofPP->AddEntry(nPlutoPosReco, "positrons kReco");
-  legendNofPP->Draw();
-
-  fHM->CreateCanvas("fh_nof_urqmdElPos", "fh_nof_urqmdElPos", 800, 800);
-  DrawH1({nUrqmdElMc, nUrqmdPosMc, nUrqmdElAcc, nUrqmdPosAcc, nUrqmdElReco, nUrqmdPosReco}, {"", "", "", "", "", ""},
-         kLinear, kLog, false, 0, 0, 0, 0, "Hist p");
-
-  TLegend* legendNofUP = new TLegend(0.65, 0.6, 0.88, 0.93);
-  legendNofUP->SetFillColor(kWhite);
-  legendNofUP->AddEntry(nUrqmdElMc, "electrons kMc");
-  legendNofUP->AddEntry(nUrqmdPosMc, "positrons kMc");
-  legendNofUP->AddEntry(nUrqmdElAcc, "electrons kAcc");
-  legendNofUP->AddEntry(nUrqmdPosAcc, "positrons kAcc");
-  legendNofUP->AddEntry(nUrqmdElReco, "electrons kReco");
-  legendNofUP->AddEntry(nUrqmdPosReco, "positrons kReco");
-  legendNofUP->Draw();
-
-  // Acc. of single particle yield vs. momentum for various detector combinations
-  TH1D* nPlutoElMc2   = (TH1D*) H1("fh_nof_particles_acc_pEl_mc")->Clone();
-  TH1D* nPlutoPosMc2  = (TH1D*) H1("fh_nof_particles_acc_pPos_mc")->Clone();
-  TH1D* nPlutoElSts   = (TH1D*) H1("fh_nof_particles_acc_pEl_sts")->Clone();
-  TH1D* nPlutoPosSts  = (TH1D*) H1("fh_nof_particles_acc_pPos_sts")->Clone();
-  TH1D* nPlutoElRich  = (TH1D*) H1("fh_nof_particles_acc_pEl_rich")->Clone();
-  TH1D* nPlutoPosRich = (TH1D*) H1("fh_nof_particles_acc_pPos_rich")->Clone();
-  TH1D* nPlutoElTrd   = (TH1D*) H1("fh_nof_particles_acc_pEl_trd")->Clone();
-  TH1D* nPlutoPosTrd  = (TH1D*) H1("fh_nof_particles_acc_pPos_trd")->Clone();
-  TH1D* nPlutoElTof   = (TH1D*) H1("fh_nof_particles_acc_pEl_tof")->Clone();
-  TH1D* nPlutoPosTof  = (TH1D*) H1("fh_nof_particles_acc_pPos_tof")->Clone();
-  TH1D* nUrqmdElMc2   = (TH1D*) H1("fh_nof_particles_acc_uEl_mc")->Clone();
-  TH1D* nUrqmdPosMc2  = (TH1D*) H1("fh_nof_particles_acc_uPos_mc")->Clone();
-  TH1D* nUrqmdElSts   = (TH1D*) H1("fh_nof_particles_acc_uEl_sts")->Clone();
-  TH1D* nUrqmdPosSts  = (TH1D*) H1("fh_nof_particles_acc_uPos_sts")->Clone();
-  TH1D* nUrqmdElRich  = (TH1D*) H1("fh_nof_particles_acc_uEl_rich")->Clone();
-  TH1D* nUrqmdPosRich = (TH1D*) H1("fh_nof_particles_acc_uPos_rich")->Clone();
-  TH1D* nUrqmdElTrd   = (TH1D*) H1("fh_nof_particles_acc_uEl_trd")->Clone();
-  TH1D* nUrqmdPosTrd  = (TH1D*) H1("fh_nof_particles_acc_uPos_trd")->Clone();
-  TH1D* nUrqmdElTof   = (TH1D*) H1("fh_nof_particles_acc_uEl_tof")->Clone();
-  TH1D* nUrqmdPosTof  = (TH1D*) H1("fh_nof_particles_acc_uPos_tof")->Clone();
-
-  int n         = 1;
-  int nRebinAcc = 4;
-  nPlutoElMc2->Rebin(n * nRebinAcc);
-  nPlutoElMc2->Scale(1. / (n * nRebinAcc));
-  nPlutoPosMc2->Rebin(n * nRebinAcc);
-  nPlutoPosMc2->Scale(1. / (n * nRebinAcc));
-  nPlutoElSts->Rebin(n * nRebinAcc);
-  nPlutoElSts->Scale(1. / (n * nRebinAcc));
-  nPlutoPosSts->Rebin(n * nRebinAcc);
-  nPlutoPosSts->Scale(1. / (n * nRebinAcc));
-  nPlutoElRich->Rebin(n * nRebinAcc);
-  nPlutoElRich->Scale(1. / (n * nRebinAcc));
-  nPlutoPosRich->Rebin(n * nRebinAcc);
-  nPlutoPosRich->Scale(1. / (n * nRebinAcc));
-  nPlutoElTrd->Rebin(n * nRebinAcc);
-  nPlutoElTrd->Scale(1. / (n * nRebinAcc));
-  nPlutoPosTrd->Rebin(n * nRebinAcc);
-  nPlutoPosTrd->Scale(1. / (n * nRebinAcc));
-  nPlutoElTof->Rebin(n * nRebinAcc);
-  nPlutoElTof->Scale(1. / (n * nRebinAcc));
-  nPlutoPosTof->Rebin(n * nRebinAcc);
-  nPlutoPosTof->Scale(1. / (n * nRebinAcc));
-
-  nUrqmdElMc2->Rebin(n * nRebinAcc);
-  nUrqmdElMc2->Scale(1. / (n * nRebinAcc));
-  nUrqmdPosMc2->Rebin(n * nRebinAcc);
-  nUrqmdPosMc2->Scale(1. / (n * nRebinAcc));
-  nUrqmdElSts->Rebin(n * nRebinAcc);
-  nUrqmdElSts->Scale(1. / (n * nRebinAcc));
-  nUrqmdPosSts->Rebin(n * nRebinAcc);
-  nUrqmdPosSts->Scale(1. / (n * nRebinAcc));
-  nUrqmdElRich->Rebin(n * nRebinAcc);
-  nUrqmdElRich->Scale(1. / (n * nRebinAcc));
-  nUrqmdPosRich->Rebin(n * nRebinAcc);
-  nUrqmdPosRich->Scale(1. / (n * nRebinAcc));
-  nUrqmdElTrd->Rebin(n * nRebinAcc);
-  nUrqmdElTrd->Scale(1. / (n * nRebinAcc));
-  nUrqmdPosTrd->Rebin(n * nRebinAcc);
-  nUrqmdPosTrd->Scale(1. / (n * nRebinAcc));
-  nUrqmdElTof->Rebin(n * nRebinAcc);
-  nUrqmdElTof->Scale(1. / (n * nRebinAcc));
-  nUrqmdPosTof->Rebin(n * nRebinAcc);
-  nUrqmdPosTof->Scale(1. / (n * nRebinAcc));
-
-  nPlutoElMc2->SetMinimum(min1);
-  nPlutoElMc2->SetMaximum(max1);
-  nPlutoPosMc2->SetMinimum(min1);
-  nPlutoPosMc2->SetMaximum(max1);
-  nPlutoElSts->SetMinimum(min1);
-  nPlutoElSts->SetMaximum(max1);
-  nPlutoPosSts->SetMinimum(min1);
-  nPlutoPosSts->SetMaximum(max1);
-  nPlutoElRich->SetMinimum(min1);
-  nPlutoElRich->SetMaximum(max1);
-  nPlutoPosRich->SetMinimum(min1);
-  nPlutoPosRich->SetMaximum(max1);
-  nPlutoElTrd->SetMinimum(min1);
-  nPlutoElTrd->SetMaximum(max1);
-  nPlutoPosTrd->SetMinimum(min1);
-  nPlutoPosTrd->SetMaximum(max1);
-  nPlutoElTof->SetMinimum(min1);
-  nPlutoElTof->SetMaximum(max1);
-  nPlutoPosTof->SetMinimum(min1);
-  nPlutoPosTof->SetMaximum(max1);
-
-  nUrqmdElMc2->SetMinimum(min1);
-  nUrqmdElMc2->SetMaximum(max1);
-  nUrqmdPosMc2->SetMinimum(min1);
-  nUrqmdPosMc2->SetMaximum(max1);
-  nUrqmdElSts->SetMinimum(min1);
-  nUrqmdElSts->SetMaximum(max1);
-  nUrqmdPosSts->SetMinimum(min1);
-  nUrqmdPosSts->SetMaximum(max1);
-  nUrqmdElRich->SetMinimum(min1);
-  nUrqmdElRich->SetMaximum(max1);
-  nUrqmdPosRich->SetMinimum(min1);
-  nUrqmdPosRich->SetMaximum(max1);
-  nUrqmdElTrd->SetMinimum(min1);
-  nUrqmdElTrd->SetMaximum(max1);
-  nUrqmdPosTrd->SetMinimum(min1);
-  nUrqmdPosTrd->SetMaximum(max1);
-  nUrqmdElTof->SetMinimum(min1);
-  nUrqmdElTof->SetMaximum(max1);
-  nUrqmdPosTof->SetMinimum(min1);
-  nUrqmdPosTof->SetMaximum(max1);
-
-  nPlutoElMc2->GetYaxis()->SetTitle("Yield");
-  nPlutoElMc2->SetTitle("Acceptance PLUTO particles");
-  nUrqmdElMc2->GetYaxis()->SetTitle("Yield");
-  nUrqmdElMc2->SetTitle("Acceptance UrQMD particles");
-
-  fHM->CreateCanvas("fh_nof_pluto_det", "fh_nof_pluto_det", 800, 800);
-  DrawH1({nPlutoElMc2, nPlutoPosMc2, nPlutoElSts, nPlutoPosSts, nPlutoElRich, nPlutoPosRich, nPlutoElTrd, nPlutoPosTrd,
-          nPlutoElTof, nPlutoPosTof},
-         {"", "", "", "", "", "", "", "", "", ""}, kLinear, kLog, false, 0.9, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legendNofPP2 = new TLegend(0.45, 0.6, 0.88, 0.93);
-  legendNofPP2->SetFillColor(kWhite);
-  legendNofPP2->AddEntry(nPlutoElMc2, "electrons kMc");
-  legendNofPP2->AddEntry(nPlutoPosMc2, "positrons kMc");
-  legendNofPP2->AddEntry(nPlutoElSts, "electrons kAcc STS");
-  legendNofPP2->AddEntry(nPlutoPosSts, "positrons kAcc STS");
-  legendNofPP2->AddEntry(nPlutoElRich, "electrons kAcc STS + RICH");
-  legendNofPP2->AddEntry(nPlutoPosRich, "positrons kAcc STS + RICH");
-  legendNofPP2->AddEntry(nPlutoElTrd, "electrons kAcc STS + RICH + TRD");
-  legendNofPP2->AddEntry(nPlutoPosTrd, "positrons kAcc STS + RICH + TRD");
-  legendNofPP2->AddEntry(nPlutoElTof, "electrons kAcc STS + RICH + TRD + ToF");
-  legendNofPP2->AddEntry(nPlutoPosTof, "positrons kAcc STS + RICH + TRD + ToF");
-  legendNofPP2->Draw();
-
-  fHM->CreateCanvas("fh_nof_urqmd_det", "fh_nof_urqmd_det", 800, 800);
-  DrawH1({nUrqmdElMc2, nUrqmdPosMc2, nUrqmdElSts, nUrqmdPosSts, nUrqmdElRich, nUrqmdPosRich, nUrqmdElTrd, nUrqmdPosTrd,
-          nUrqmdElTof, nUrqmdPosTof},
-         {"", "", "", "", "", "", "", "", "", ""}, kLinear, kLog, false, 0.9, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legendNofUP2 = new TLegend(0.45, 0.6, 0.88, 0.93);
-  legendNofUP2->SetFillColor(kWhite);
-  legendNofUP2->AddEntry(nUrqmdElMc2, "electrons kMc");
-  legendNofUP2->AddEntry(nUrqmdPosMc2, "positrons kMc");
-  legendNofUP2->AddEntry(nUrqmdElSts, "electrons kAcc STS");
-  legendNofUP2->AddEntry(nUrqmdPosSts, "positrons kAcc STS");
-  legendNofUP2->AddEntry(nUrqmdElRich, "electrons kAcc STS + RICH");
-  legendNofUP2->AddEntry(nUrqmdPosRich, "positrons kAcc STS + RICH");
-  legendNofUP2->AddEntry(nUrqmdElTrd, "electrons kAcc STS + RICH + TRD");
-  legendNofUP2->AddEntry(nUrqmdPosTrd, "positrons kAcc STS + RICH + TRD");
-  legendNofUP2->AddEntry(nUrqmdElTof, "electrons kAcc STS + RICH + TRD + ToF");
-  legendNofUP2->AddEntry(nUrqmdPosTof, "positrons kAcc STS + RICH + TRD + ToF");
-  legendNofUP2->Draw();
-
-  // Draw nofPoints of electrons and positrons in various detectors
-  TH1D* pElSts   = (TH1D*) H1("fh_nof_points_pEl_sts")->Clone();
-  TH1D* pPosSts  = (TH1D*) H1("fh_nof_points_pPos_sts")->Clone();
-  TH1D* pElRich  = (TH1D*) H1("fh_nof_points_pEl_rich")->Clone();
-  TH1D* pPosRich = (TH1D*) H1("fh_nof_points_pPos_rich")->Clone();
-  TH1D* pElTrd   = (TH1D*) H1("fh_nof_points_pEl_trd")->Clone();
-  TH1D* pPosTrd  = (TH1D*) H1("fh_nof_points_pPos_trd")->Clone();
-  TH1D* pElTof   = (TH1D*) H1("fh_nof_points_pEl_tof")->Clone();
-  TH1D* pPosTof  = (TH1D*) H1("fh_nof_points_pPos_tof")->Clone();
-  TH1D* uElSts   = (TH1D*) H1("fh_nof_points_uEl_sts")->Clone();
-  TH1D* uPosSts  = (TH1D*) H1("fh_nof_points_uPos_sts")->Clone();
-  TH1D* uElRich  = (TH1D*) H1("fh_nof_points_uEl_rich")->Clone();
-  TH1D* uPosRich = (TH1D*) H1("fh_nof_points_uPos_rich")->Clone();
-  TH1D* uElTrd   = (TH1D*) H1("fh_nof_points_uEl_trd")->Clone();
-  TH1D* uPosTrd  = (TH1D*) H1("fh_nof_points_uPos_trd")->Clone();
-  TH1D* uElTof   = (TH1D*) H1("fh_nof_points_uEl_tof")->Clone();
-  TH1D* uPosTof  = (TH1D*) H1("fh_nof_points_uPos_tof")->Clone();
-
-  pElSts->SetTitle("STS");
-  pElRich->SetTitle("RICH");
-  pElTrd->SetTitle("TRD");
-  pElTrd->GetXaxis()->SetRangeUser(0., 15.);
-  pElTof->SetTitle("ToF");
-  pElTof->GetXaxis()->SetRangeUser(0., 20.);
-
-  fHM->CreateCanvas("fh_nof_points_sts", "fh_nof_points_sts", 800, 800);
-  DrawH1({pElSts, pPosSts, uElSts, uPosSts}, {"", "", "", ""}, kLinear, kLog, false, 0.9, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legendNofPSts = new TLegend(0.45, 0.7, 0.88, 0.93);
-  legendNofPSts->SetFillColor(kWhite);
-  legendNofPSts->AddEntry(pElSts, "PLUTO electrons");
-  legendNofPSts->AddEntry(pPosSts, "PLUTO positrons");
-  legendNofPSts->AddEntry(uElSts, "UrQMD electrons");
-  legendNofPSts->AddEntry(uPosSts, "UrQMD positrons");
-  legendNofPSts->Draw();
-
-  fHM->CreateCanvas("fh_nof_points_rich", "fh_nof_points_rich", 800, 800);
-  DrawH1({pElRich, pPosRich, uElRich, uPosRich}, {"", "", "", ""}, kLinear, kLog, false, 0.9, 0.8, 0.99, 0.99,
-         "hist p");
-
-  TLegend* legendNofPRich = new TLegend(0.45, 0.7, 0.88, 0.93);
-  legendNofPRich->SetFillColor(kWhite);
-  legendNofPRich->AddEntry(pElRich, "PLUTO electrons");
-  legendNofPRich->AddEntry(pPosRich, "PLUTO positrons");
-  legendNofPRich->AddEntry(uElRich, "UrQMD electrons");
-  legendNofPRich->AddEntry(uPosRich, "UrQMD positrons");
-  legendNofPRich->Draw();
-
-  fHM->CreateCanvas("fh_nof_points_trd", "fh_nof_points_trd", 800, 800);
-  DrawH1({pElTrd, pPosTrd, uElTrd, uPosTrd}, {"", "", "", ""}, kLinear, kLog, false, 0.9, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legendNofPTrd = new TLegend(0.45, 0.7, 0.88, 0.93);
-  legendNofPTrd->SetFillColor(kWhite);
-  legendNofPTrd->AddEntry(pElTrd, "PLUTO electrons");
-  legendNofPTrd->AddEntry(pPosTrd, "PLUTO positrons");
-  legendNofPTrd->AddEntry(uElTrd, "UrQMD electrons");
-  legendNofPTrd->AddEntry(uPosTrd, "UrQMD positrons");
-  legendNofPTrd->Draw();
-
-  fHM->CreateCanvas("fh_nof_points_tof", "fh_nof_points_tof", 800, 800);
-  DrawH1({pElTof, pPosTof, uElTof, uPosTof}, {"", "", "", ""}, kLinear, kLog, false, 0.9, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legendNofPTof = new TLegend(0.45, 0.7, 0.88, 0.93);
-  legendNofPTof->SetFillColor(kWhite);
-  legendNofPTof->AddEntry(pElTof, "PLUTO electrons");
-  legendNofPTof->AddEntry(pPosTof, "PLUTO positrons");
-  legendNofPTof->AddEntry(uElTof, "UrQMD electrons");
-  legendNofPTof->AddEntry(uPosTof, "UrQMD positrons");
-  legendNofPTof->Draw();
-
-  //Draw 2D Histos: Yield vs. Momentum and Pt
-  TH2D* pElMc   = H2("fh_nof_plutoElectrons_p_pt_mc");
-  TH2D* pPosMc  = H2("fh_nof_plutoPositrons_p_pt_mc");
-  TH2D* pElAcc  = H2("fh_nof_plutoElectrons_p_pt_acc");
-  TH2D* pPosAcc = H2("fh_nof_plutoPositrons_p_pt_acc");
-
-  TH2D* uElMc   = H2("fh_nof_urqmdElectrons_p_pt_mc");
-  TH2D* uPosMc  = H2("fh_nof_urqmdPositrons_p_pt_mc");
-  TH2D* uElAcc  = H2("fh_nof_urqmdElectrons_p_pt_acc");
-  TH2D* uPosAcc = H2("fh_nof_urqmdPositrons_p_pt_acc");
-
-  TCanvas* cPMc = fHM->CreateCanvas("fh_nof_plutoParticles_p_pt_mc", "fh_nof_plutoParticles_p_pt_mc", 1000, 500);
-  cPMc->Divide(2, 1);
-  cPMc->cd(1);
-  DrawH2(pElMc);
-  pElMc->SetMinimum(1e-6);
-  pElMc->SetMaximum(1e-1);
-  gPad->SetLogz(true);
-  cPMc->cd(2);
-  DrawH2(pPosMc);
-  pPosMc->SetMinimum(1e-6);
-  pPosMc->SetMaximum(1e-1);
-  gPad->SetLogz(true);
-
-  TCanvas* cPAcc = fHM->CreateCanvas("fh_nof_plutoParticles_p_pt_acc", "fh_nof_plutoParticles_p_pt_acc", 1000, 500);
-  cPAcc->Divide(2, 1);
-  cPAcc->cd(1);
-  DrawH2(pElAcc);
-  pElAcc->SetMinimum(1e-6);
-  pElAcc->SetMaximum(5e-2);
-  gPad->SetLogz(true);
-  cPAcc->cd(2);
-  DrawH2(pPosAcc);
-  pPosAcc->SetMinimum(1e-6);
-  pPosAcc->SetMaximum(5e-2);
-  gPad->SetLogz(true);
-
-  TCanvas* cUMc = fHM->CreateCanvas("fh_nof_urqmdParticles_p_pt_mc", "fh_nof_urqmdParticles_p_pt_mc", 1000, 500);
-  cUMc->Divide(2, 1);
-  cUMc->cd(1);
-  DrawH2(uElMc);
-  uElMc->SetMinimum(1e-6);
-  uElMc->SetMaximum(250);
-  gPad->SetLogz(true);
-  cUMc->cd(2);
-  DrawH2(uPosMc);
-  uPosMc->SetMinimum(1e-6);
-  uPosMc->SetMaximum(250);
-  gPad->SetLogz(true);
-
-  TCanvas* cUAcc = fHM->CreateCanvas("fh_nof_urqmdParticles_p_pt_acc", "fh_nof_urqmdParticles_p_pt_acc", 1000, 500);
-  cUAcc->Divide(2, 1);
-  cUAcc->cd(1);
-  DrawH2(uElAcc);
-  uElAcc->SetMinimum(1e-6);
-  uElAcc->SetMaximum(1e-1);
-  gPad->SetLogz(true);
-  cUAcc->cd(2);
-  DrawH2(uPosAcc);
-  uPosAcc->SetMinimum(1e-6);
-  uPosAcc->SetMaximum(1e-1);
-  gPad->SetLogz(true);
-}
-
-void CbmAnaDielectronTaskDraw::RebinMinvHist()
+bool LmvmDraw::SkipMvd(ELmvmAnaStep step)
 {
-  int nRebin = 20;  // general rebin
-  int nRebCB = 10;  // rebin for CB histos
-  int nRebSP = 4;   // rebin for single particle histos
-  for (int i = 0; i < CbmLmvmHist::fNofAnaSteps; i++) {
-    H1("fh_signal_minv_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebin);
-    H1("fh_bg_minv_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebin);
-    H1("fh_combPairsPM_minv_sameEvent_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebCB);
-    H1("fh_combPairsPP_minv_sameEvent_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebCB);
-    H1("fh_combPairsMM_minv_sameEvent_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebCB);
-    H1("fh_combPairsPM_minv_mixedEvents_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebCB);
-    H1("fh_combPairsPP_minv_mixedEvents_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebCB);
-    H1("fh_combPairsMM_minv_mixedEvents_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebCB);
-    H1("fh_pi0_minv_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebin);
-    H1("fh_eta_minv_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebin);
-    H1("fh_bg_truematch_minv_" + CbmLmvmHist::fAnaSteps[i])->Rebin(2 * nRebin);
-    H1("fh_bg_mismatch_minv_" + CbmLmvmHist::fAnaSteps[i])->Rebin(2 * nRebin);
-    H1("fh_bg_truematch_el_minv_" + CbmLmvmHist::fAnaSteps[i])->Rebin(2 * nRebin);
-    H1("fh_bg_truematch_notel_minv_" + CbmLmvmHist::fAnaSteps[i])->Rebin(2 * nRebin);
-
-    H1("fh_nof_plutoElectrons_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebSP);
-    H1("fh_nof_plutoPositrons_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebSP);
-    H1("fh_nof_urqmdElectrons_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebSP);
-    H1("fh_nof_urqmdPositrons_" + CbmLmvmHist::fAnaSteps[i])->Rebin(nRebSP);
-    H1("fh_nof_plutoElectrons_" + CbmLmvmHist::fAnaSteps[i])->Scale(1. / nRebSP);
-    H1("fh_nof_plutoPositrons_" + CbmLmvmHist::fAnaSteps[i])->Scale(1. / nRebSP);
-    H1("fh_nof_urqmdElectrons_" + CbmLmvmHist::fAnaSteps[i])->Scale(1. / nRebSP);
-    H1("fh_nof_urqmdPositrons_" + CbmLmvmHist::fAnaSteps[i])->Scale(1. / nRebSP);
-
-    for (int iP = 0; iP < CbmLmvmHist::fNofBgPairSources; iP++) {
-      stringstream ss;
-      ss << "fh_source_bg_minv_" << iP << "_" << CbmLmvmHist::fAnaSteps[i];
-      H1(ss.str())->Rebin(8 * nRebin);
-    }
-  }
+  return (!fUseMvd && (step == ELmvmAnaStep::Mvd1Cut || step == ELmvmAnaStep::Mvd2Cut));
 }
 
-TH1D* CbmAnaDielectronTaskDraw::H1(const string& name) { return (TH1D*) fHM->H1(name); }
-/*
-TH2D* CbmAnaDielectronTaskDraw::H2(
-      const string& name)
+void LmvmDraw::RebinMinvHist()
 {
-   return (TH2D*) fHM->H1(name);
+  int nGroup      = 20;
+  int nGroupCB    = 10;  // rebin for CB histos
+  int nGroupMatch = 50;
+  int nGroupBgSrc = 50;
+  fH.Rebin("hMinv", fH.fSrcNames, fH.fAnaStepNames, nGroup);
+  fH.Rebin("hMinvCombPM", {"sameEv", "mixedEv"}, fH.fAnaStepNames, nGroupCB);
+  fH.Rebin("hMinvCombPP", {"sameEv", "mixedEv"}, fH.fAnaStepNames, nGroupCB);
+  fH.Rebin("hMinvCombMM", {"sameEv", "mixedEv"}, fH.fAnaStepNames, nGroupCB);
+  fH.Rebin("hMinvBgMatch", {"trueMatch", "trueMatchEl", "trueMatchNotEl", "mismatch"}, fH.fAnaStepNames, nGroupMatch);
+  fH.Rebin("hMinvBgSource", fH.fBgPairSrcNames, fH.fAnaStepNames, nGroupBgSrc);
 }
-*/
-TH2D* CbmAnaDielectronTaskDraw::H2(const string& name) { return (TH2D*) fHM->H2(name); }
-
-void CbmAnaDielectronTaskDraw::DrawEfficiencyOnHist(TH1* h1, TH1* h2, Double_t xPos, Double_t yPos)
-{
-  string effTxt = "";
-  if (h2->GetEntries() != 0) {
-    effTxt = Cbm::NumberToString<Double_t>(((Double_t) h1->GetEntries() / h2->GetEntries() * 100.), 1);
-  }
-  TText* t = new TText(xPos, yPos, effTxt.c_str());
-  t->SetTextSize(0.1);
-  t->Draw();
-}
-
 
-TH1D* CbmAnaDielectronTaskDraw::CreateSignificanceH1D(TH1D* s, TH1D* bg, const string& name, const string& option)
+TH1D* LmvmDraw::CreateSignificanceH1(TH1D* s, TH1D* bg, const string& name, const string& option)
 {
-  Int_t nBins   = s->GetNbinsX();
-  Double_t xmin = s->GetXaxis()->GetXmin();
-  Double_t xmax = s->GetXaxis()->GetXmax();
-  TH1D* hsig    = new TH1D(name.c_str(), name.c_str(), nBins, xmin, xmax);
+  int nBins  = s->GetNbinsX();
+  TH1D* hsig = new TH1D(name.c_str(), name.c_str(), nBins, s->GetXaxis()->GetXmin(), s->GetXaxis()->GetXmax());
   hsig->GetXaxis()->SetTitle(s->GetXaxis()->GetTitle());
 
-  Double_t sumSignal = 0., sumBg = 0., significance = 0.;
-  // "right" - one wants to reject right part of the histogram.
-  // value > cut -> reject
+  // "right" - reject right part of the histogram. value > cut -> reject
   if (option == "right") {
-    for (Int_t i = 1; i <= nBins; i++) {
-      sumSignal     = s->Integral(1, i, "width");
-      sumBg         = bg->Integral(1, i, "width");
-      Double_t prov = TMath::Sqrt(sumSignal + sumBg);
-      if (prov != 0.) significance = sumSignal / prov;
-      else
-        significance = 0.;
-      hsig->SetBinContent(i, significance);
+    for (int i = 1; i <= nBins; i++) {
+      double sumSignal = s->Integral(1, i, "width");
+      double sumBg     = bg->Integral(1, i, "width");
+      double sign      = (sumSignal + sumBg != 0.) ? sumSignal / std::sqrt(sumSignal + sumBg) : 0.;
+      hsig->SetBinContent(i, sign);
     }
-    // "left" - one wants to reject left part of the histogram.
-    // value < cut -> reject
   }
+  // "left" - reject left part of the histogram. value < cut -> reject
   else if (option == "left") {
-    for (Int_t i = nBins; i >= 1; i--) {
-      sumSignal     = s->Integral(i, nBins, "width");
-      sumBg         = bg->Integral(i, nBins, "width");
-      Double_t prov = TMath::Sqrt(sumSignal + sumBg);
-      if (prov != 0.) significance = sumSignal / prov;
-      else
-        significance = 0.;
-      hsig->SetBinContent(i, significance);
+    for (int i = nBins; i >= 1; i--) {
+      double sumSignal = s->Integral(i, nBins, "width");
+      double sumBg     = bg->Integral(i, nBins, "width");
+      double sign      = (sumSignal + sumBg != 0.) ? sumSignal / std::sqrt(sumSignal + sumBg) : 0.;
+      hsig->SetBinContent(i, sign);
     }
   }
   return hsig;
 }
 
-TH2D* CbmAnaDielectronTaskDraw::CreateSignificanceH2D(TH2D* signal, TH2D* bg, const string& name, const string& title)
+TH2D* LmvmDraw::CreateSignificanceH2(TH2D* signal, TH2D* bg, const string& name, const string& title)
 {
-
-  Double_t xmin  = 1.0;
-  Double_t xmax  = 5.0;
-  Double_t ymin  = 1.0;
-  Double_t ymax  = 5.0;
-  Double_t delta = 0.1;
-  Int_t nStepsX  = (Int_t)((xmax - xmin) / delta);
-  Int_t nStepsY  = (Int_t)((ymax - ymin) / delta);
-  Int_t nBinsX   = signal->GetNbinsX();
-  Int_t nBinsY   = signal->GetNbinsY();
+  double xmin  = 1.0;
+  double xmax  = 5.0;
+  double ymin  = 1.0;
+  double ymax  = 5.0;
+  double delta = 0.1;
+  int nStepsX  = (int) ((xmax - xmin) / delta);
+  int nStepsY  = (int) ((ymax - ymin) / delta);
 
   TH2D* hsig = new TH2D(name.c_str(), title.c_str(), nStepsX, xmin, xmax, nStepsY, ymin, ymax);
 
-  Double_t sumSignal = 0;
-  Double_t sumBg     = 0;
-
-  Int_t binX = 1;
-  for (Double_t xcut = xmin; xcut <= xmax; xcut += delta, binX++) {
-    Int_t binY = 1;
-    cout << "x " << xcut << endl;
-    for (Double_t ycut = ymin; ycut <= ymax; ycut += delta, binY++) {
-      sumSignal = 0;
-      sumBg     = 0;
-      for (Int_t ix = 1; ix <= nBinsX; ix++) {
-        for (Int_t iy = 1; iy <= nBinsY; iy++) {
-          Double_t xcenter = signal->GetXaxis()->GetBinCenter(ix);
-          Double_t ycenter = signal->GetYaxis()->GetBinCenter(iy);
-          Double_t val     = -1 * (ycut / xcut) * xcenter + ycut;
-
-          if (!(xcenter < xcut && ycenter < val)) {
+  int binX = 1;
+  for (double xcut = xmin; xcut <= xmax; xcut += delta, binX++) {
+    int binY = 1;
+    for (double ycut = ymin; ycut <= ymax; ycut += delta, binY++) {
+      double sumSignal = 0;
+      double sumBg     = 0;
+      for (int ix = 1; ix <= signal->GetNbinsX(); ix++) {
+        for (int iy = 1; iy <= signal->GetNbinsY(); iy++) {
+          double xc  = signal->GetXaxis()->GetBinCenter(ix);
+          double yc  = signal->GetYaxis()->GetBinCenter(iy);
+          double val = -1 * (ycut / xcut) * xc + ycut;
+
+          if (!(xc < xcut && yc < val)) {
             sumSignal += signal->GetBinContent(ix, iy);
             sumBg += bg->GetBinContent(ix, iy);
           }
         }
       }
-      Double_t prov         = TMath::Sqrt(sumSignal + sumBg);
-      Double_t significance = 0.;
-      if (prov != 0) significance = sumSignal / prov;
-      hsig->SetBinContent(binX, binY, significance);
+      double sign = (sumSignal + sumBg != 0.) ? sumSignal / std::sqrt(sumSignal + sumBg) : 0.;
+      hsig->SetBinContent(binX, binY, sign);
     }
   }
   return hsig;
 }
 
-void CbmAnaDielectronTaskDraw::SOverBg(CbmLmvmAnalysisSteps step)
+void LmvmDraw::DrawAnaStepMany(const string& cName, function<void(ELmvmAnaStep)> drawFunc)
 {
-  TH1D* s  = H1("fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step]);
-  TH1D* bg = H1("fh_bg_minv_" + CbmLmvmHist::fAnaSteps[step]);
-  //H2("fh_signal_pty_" + CbmLmvmHist::fAnaSteps[step]);	// TODO: commented these lines, what do they do??
-  //H2("fh_signal_pty_" + CbmLmvmHist::fAnaSteps[0]);
-
-  if (s->GetEntries() < 1) return;
-
-  TH1D* sClone = (TH1D*) s->Clone();
-  sClone->Fit("gaus", "Q");
-
-  Double_t mean  = sClone->GetFunction("gaus")->GetParameter("Mean");
-  Double_t sigma = sClone->GetFunction("gaus")->GetParameter("Sigma");
-
-  Int_t minInd = s->FindBin(mean - 2. * sigma);
-  Int_t maxInd = s->FindBin(mean + 2. * sigma);
-
-  Double_t sumSignal = 0.;
-  Double_t sumBg     = 0.;
-  for (Int_t i = minInd + 1; i <= maxInd - 1; i++) {
-    sumSignal += s->GetBinContent(i);
-    sumBg += bg->GetBinContent(i);
+  int hi          = 1;
+  string newCName = cName + "/" + cName + "_all";
+  TCanvas* c      = fH.fHM.CreateCanvas(newCName.c_str(), newCName.c_str(), 1600, 1200);
+  c->Divide(4, 3);
+  for (const auto step : fH.fAnaSteps) {
+    if (SkipMvd(step)) continue;
+    c->cd(hi++);
+    drawFunc(step);
   }
-}
 
-void CbmAnaDielectronTaskDraw::SOverBgAll()
-{
-  fHM->CreateCanvas("lmvm_signal_fitting", "lmvm_signal_fitting", 600, 600);
-  SOverBg(kReco);
-  SOverBg(kChi2Prim);
-  SOverBg(kElId);
-  SOverBg(kGammaCut);
-  if (fUseMvd) SOverBg(kMvd1Cut);
-  if (fUseMvd) SOverBg(kMvd2Cut);
-  SOverBg(kStCut);
-  SOverBg(kTtCut);
-  SOverBg(kPtCut);
+  for (const auto step : fH.fAnaSteps) {
+    if (SkipMvd(step)) continue;
+    newCName = cName + "/" + cName + "_" + fH.fAnaStepNames[static_cast<int>(step)];
+    fH.fHM.CreateCanvas(newCName.c_str(), newCName.c_str(), 800, 800);
+    drawFunc(step);
+  }
 }
 
-void CbmAnaDielectronTaskDraw::DrawPtYDistribution(int step, bool drawAnaStep)
+void LmvmDraw::DrawPtY(ELmvmAnaStep step)
 {
-  TH2D* h   = H2("fh_signal_pty_" + CbmLmvmHist::fAnaSteps[step]);
-  TH2D* hmc = H2("fh_signal_pty_" + CbmLmvmHist::fAnaSteps[0]);
-
+  TH2D* h   = fH.H2("hPtYPairSignal", step);
+  TH2D* hmc = fH.H2("hPtYPairSignal", ELmvmAnaStep::Mc);
   DrawH2(h, kLinear, kLinear, kLinear, "COLZ");
-  if (drawAnaStep) DrawEfficiencyOnHist(h, hmc, 0.2, 1.8);
-  if (drawAnaStep) DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.50, 0.78, 0.70, 0.9);
+  bool drawAnaStep = true;
+  if (drawAnaStep) fH.DrawEfficiency(h, hmc, 0.2, 1.8);
+  if (drawAnaStep) fH.DrawAnaStepOnPad(step);
 }
 
-void CbmAnaDielectronTaskDraw::DrawPtYDistributionAll()
+void LmvmDraw::DrawRapidity(ELmvmAnaStep step)
 {
-  Int_t hi   = 1;
-  TCanvas* c = fHM->CreateCanvas("lmvm_pty", "lmvm_pty", 750, 1000);
-  c->Divide(3, 4);
-  for (int step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    c->cd(hi++);
-    DrawPtYDistribution(step);
-  }
-
-  fHM->CreateCanvas("lmvm_pty_" + CbmLmvmHist::fAnaSteps[kAcc], "lmvm_pty_" + CbmLmvmHist::fAnaSteps[kAcc], 800, 800);
-  DrawPtYDistribution(kAcc, true);
-
-  fHM->CreateCanvas("lmvm_pty_" + CbmLmvmHist::fAnaSteps[kPtCut], "lmvm_pty_" + CbmLmvmHist::fAnaSteps[kPtCut], 800,
-                    800);
-  DrawPtYDistribution(kPtCut, true);
+  DrawH1(fH.H2("hPtYPairSignal", step)->ProjectionX(), kLinear, kLinear, "hist");
+  fH.DrawAnaStepOnPad(step);
 }
 
-
-void CbmAnaDielectronTaskDraw::DrawRapidityDistributionAll()
+void LmvmDraw::DrawPtYEfficiency(ELmvmAnaStep step)
 {
-  Int_t hi   = 1;
-  TCanvas* c = fHM->CreateCanvas("lmvm_signal_rapidity", "lmvm_signal_rapidity", 750, 1000);
-  c->Divide(3, 4);
-  for (int step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    c->cd(hi++);
-    TH1D* proj = H2("fh_signal_pty_" + CbmLmvmHist::fAnaSteps[step])->ProjectionX();
-    DrawH1(proj);
-    DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.70, 0.78, 0.90, 0.9);
-  }
-}
-
-
-void CbmAnaDielectronTaskDraw::DrawPtYEfficiency(int step, bool drawAnaStep)
-{
-  TH2D* h = H2("fh_signal_pty_" + CbmLmvmHist::fAnaSteps[step]);
-  // efficiency is normalized to the previous step (step - 1)
-  TH2D* hmc = H2("fh_signal_pty_" + CbmLmvmHist::fAnaSteps[kMc]);
-
-  TH2D* eff = Cbm::DivideH2(h, hmc);
-  eff->GetZaxis()->SetTitle("Efficiency [%]");
+  TH2D* h   = fH.H2("hPtYPairSignal", step);
+  TH2D* hmc = fH.H2("hPtYPairSignal", ELmvmAnaStep::Mc);
+  TH2D* eff = Cbm::DivideH2(h, hmc, "", 100., "Efficiency [%]");
   DrawH2(eff);
   eff->SetMaximum(10.);
-  if (drawAnaStep) DrawEfficiencyOnHist(h, hmc, 0.2, 1.8);
-  if (drawAnaStep) DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.50, 0.78, 0.70, 0.9);
+  bool drawAnaStep = true;
+  if (drawAnaStep) fH.DrawEfficiency(h, hmc, 0.2, 1.8);
+  if (drawAnaStep) fH.DrawAnaStepOnPad(step);
 }
 
-void CbmAnaDielectronTaskDraw::DrawPtYEfficiencyAll()
+void LmvmDraw::DrawMinvPt(ELmvmAnaStep step)
 {
-  Int_t hi   = 1;
-  TCanvas* c = fHM->CreateCanvas("lmvm_pty_efficiency", "lmvm_pty_efficiency", 1000, 1000);
-  c->Divide(3, 3);
-  for (int step = kAcc; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    c->cd(hi++);
-    DrawPtYEfficiency(step);
-  }
-
-  fHM->CreateCanvas("lmvm_pty_efficiency_ptcut", "lmvm_pty_efficiency_ptcut", 600, 600);
-  DrawPtYEfficiency(kPtCut, true);
+  TH2D* h = fH.H2("hMinvPt", ELmvmSrc::Signal, step);
+  DrawH2(h, kLinear, kLinear, kLinear, "COLZ");
+  fH.DrawAnaStepOnPad(step);
 }
 
-void CbmAnaDielectronTaskDraw::DrawMomentumDistributionAll()
+void LmvmDraw::DrawSrcAnaStepH1(const string& hName, ELmvmAnaStep step)
 {
-  fHM->CreateCanvas("lmvm_signal_momentum_distribution", "lmvm_signal_momentum_distribution", 600, 600);
-  Draw1DHistoForEachAnalysisStep("fh_signal_mom", true);
+  DrawSrcH1(hName, step, false);
+  fH.DrawAnaStepOnPad(step);
 }
 
-void CbmAnaDielectronTaskDraw::DrawMomentumEfficiencyAll()
+void LmvmDraw::DrawSrcAnaStepEpEmH1(const string& hName, ELmvmAnaStep step)
 {
-  //EFFICIENCY vs. MOMENTUM
-  /*    TCanvas *c5 = CreateCanvas("signal_momentum_efficiency","signal_momentum_efficiency", 600, 600);
-    Draw1DHistoForEachAnalysisStep(
-          NULL,
-          NULL, //DivideHisto1D(H1("fh_acc_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_reco_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_chi_prim_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_el_id_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_gammacut_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_dstscut_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_dsts2cut_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_stcut_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_ttcut_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_ptcut_signal_mom"), H1("fh_mc_signal_mom")),
-          DivideHisto1D(H1("fh_anglecut_signal_mom"), H1("fh_mc_signal_mom")),
-          false
-    );*/
+  vector<TH1*> hVec;
+  vector<string> latex;
+  for (const ELmvmSrc src : {ELmvmSrc::Signal, ELmvmSrc::Pi0, ELmvmSrc::Gamma}) {
+    for (const string& pm : {"+", "-"}) {
+      hVec.push_back(fH.H1(hName + pm, src, step));
+      latex.push_back(fH.fSrcLatex[static_cast<int>(src)] + " (e" + pm + ")");
+    }
+  }
+  DrawH1(hVec, latex, kLinear, kLog, true, 0.90, 0.7, 0.99, 0.99, "hist");
+  fH.DrawAnaStepOnPad(step);
 }
 
-void CbmAnaDielectronTaskDraw::DrawMotherPdg()
+void LmvmDraw::DrawMomAccEpEm()
 {
-  fHM->CreateCanvas("lmvm_mother_pdg", "lmvm_mother_pdg", 500, 500);
-  DrawH1({H1("fh_mc_mother_pdg"), H1("fh_acc_mother_pdg")}, {"MC", "acc"}, kLinear, kLog, true, 0.7, 0.7, 0.99, 0.99);
+  for (const string& det : {"sts", "rich", "trd", "tof"}) {
+    vector<TH1*> hVec;
+    vector<string> latex;
+    for (const ELmvmSrc src : {ELmvmSrc::Signal, ELmvmSrc::Pi0, ELmvmSrc::Gamma}) {
+      for (const string& pm : {"+", "-"}) {
+        hVec.push_back(fH.H1("hMomAcc" + pm + "_" + det, src));
+        latex.push_back(fH.fSrcLatex[static_cast<int>(src)] + " (e" + pm + ")");
+      }
+    }
+    fH.fHM.CreateCanvas("lmvm_momDetAcc/lmvm_momDetAcc_" + det, "lmvm_momDetAcc/lmvm_momDetAcc_" + det, 800, 800);
+    DrawH1(hVec, latex, kLinear, kLog, true, 0.90, 0.7, 0.99, 0.99, "hist");
+    DrawTextOnPad(det, 0.4, 0.9, 0.6, 0.999);
+  }
 }
 
-void CbmAnaDielectronTaskDraw::DrawPPAngleMCSignal()
+void LmvmDraw::DrawMisc()
 {
-  fHM->CreateCanvas("mc_signal_mom_angle", "mc_signal_mom_angle", 500, 500);
-  DrawH2(H2("fh_mc_signal_mom_angle"));
+  fH.fHM.CreateCanvas("lmvm_mom_pairSignal", "lmvm_mom_pairSignal", 800, 800);
+  DrawAnaStepH1("hMomPairSignal", true);
+
+  fH.fHM.CreateCanvas("lmvm_mother_pdg", "lmvm_mother_pdg", 800, 800);
+  DrawH1({fH.H1("hMotherPdg_mc"), fH.H1("hMotherPdg_acc")}, {"MC", "acc"}, kLinear, kLog, true, 0.7, 0.7, 0.99, 0.99,
+         "hist");
+
+  fH.fHM.CreateCanvas("lmvm_momVsAngle_pairSignal", "lmvm_momVsAngle_pairSignal", 800, 800);
+  DrawH2(fH.H2("hMomVsAnglePairSignalMc"));
 }
 
-void CbmAnaDielectronTaskDraw::DrawPmtXY()
+void LmvmDraw::DrawPmtXY()
 {
-  TCanvas* c = fHM->CreateCanvas("lmvm_pmt_xy", "lmvm_pmt_xy", 500, 1800);
-  c->Divide(1, 3);
-  c->cd(1);
-  DrawH2(H2("fh_signal_pmtXY"));
-  gPad->SetLogz(true);
-  DrawTextOnPad(CbmLmvmHist::fSourceTypesLatex[kSignal], 0.50, 0.78, 0.70, 0.9);
-  c->cd(2);
-  DrawH2(H2("fh_pi0_pmtXY"));
-  gPad->SetLogz(true);
-  DrawTextOnPad(CbmLmvmHist::fSourceTypesLatex[kPi0], 0.50, 0.78, 0.70, 0.9);
-  c->cd(3);
-  DrawH2(H2("fh_gamma_pmtXY"));
-  gPad->SetLogz(true);
-  DrawTextOnPad(CbmLmvmHist::fSourceTypesLatex[kGamma], 0.50, 0.78, 0.70, 0.9);
+  TCanvas* c = fH.fHM.CreateCanvas("lmvm_pmtXY", "lmvm_pmtXY", 1800, 600);
+  c->Divide(3, 1);
+  vector<ELmvmSrc> src {ELmvmSrc::Signal, ELmvmSrc::Pi0, ELmvmSrc::Gamma};
+  for (size_t i = 0; i < src.size(); i++) {
+    c->cd(i + 1);
+    DrawH2(fH.H2("hPmtXY", src[i]));
+    gPad->SetLogz(true);
+    DrawTextOnPad(fH.fSrcLatex[static_cast<int>(src[i])], 0.40, 0.9, 0.60, 0.99);
+  }
 }
 
-void CbmAnaDielectronTaskDraw::Draw1DSourceTypes(const string& hName, bool doScale)
+void LmvmDraw::DrawSrcH1(const string& hName, ELmvmAnaStep step, bool doScale)
 {
-  vector<TH1*> h;
-  vector<string> hLegend;
-  for (int i = 0; i < CbmLmvmHist::fNofSourceTypes; i++) {
-    string fullName = hName + "_" + CbmLmvmHist::fSourceTypes[i];
-    h.push_back(H1(fullName));
-    h[i]->SetLineWidth(2);
-    h[i]->SetLineColor(CbmLmvmHist::fSourceTypesColor[i]);
-    if (doScale) h[i]->Scale(1. / h[i]->Integral());
-    hLegend.push_back(CbmLmvmHist::fSourceTypesLatex[i]);
+  vector<TH1*> hVec;
+  for (const ELmvmSrc src : fH.fSrcs) {
+    TH1D* h = (step == ELmvmAnaStep::Undefined) ? fH.H1(hName, src) : fH.H1(hName, src, step);
+    h->SetLineWidth(2);
+    h->SetLineColor(fH.fSrcColors[static_cast<int>(src)]);
+    if (doScale) h->Scale(1. / h->Integral());
+    hVec.push_back(h);
   }
-  DrawH1(h, hLegend, kLinear, kLog, true, 0.90, 0.7, 0.99, 0.99);
+  DrawH1(hVec, fH.fSrcLatex, kLinear, kLog, true, 0.90, 0.7, 0.99, 0.99, "hist");
 }
 
-void CbmAnaDielectronTaskDraw::Draw1DCut(const string& hName, const string& sigOption, double cutValue)
+void LmvmDraw::Draw1DCut(const string& hist, const string& sigOption, double cut)
 {
-  Int_t w = 600;
-  Int_t h = 600;
-  if (fDrawSignificance) w = 1200;
-  TCanvas* c = fHM->CreateCanvas(("lmvm_" + hName).c_str(), ("lmvm_" + hName).c_str(), w, h);
+  int w = 800;
+  int h = 800;
+  if (fDrawSignificance) w = 1600;
+  TCanvas* c = fH.fHM.CreateCanvas(("lmvm_" + hist).c_str(), ("lmvm_" + hist).c_str(), w, h);
   if (fDrawSignificance) {
     c->Divide(2, 1);
     c->cd(1);
   }
-  Draw1DSourceTypes(hName);
-  if (cutValue != -999999.) {
-    TLine* cutLine = new TLine(cutValue, 0.0, cutValue, 1.0);
+  DrawSrcH1(hist);
+  if (cut != -999999.) {
+    TLine* cutLine = new TLine(cut, 0.0, cut, 1.0);
     cutLine->SetLineWidth(2);
     cutLine->Draw();
   }
   if (fDrawSignificance) {
     c->cd(2);
-    string sName  = hName + "_" + CbmLmvmHist::fSourceTypes[kSignal];
-    string bgName = hName + "_" + CbmLmvmHist::fSourceTypes[kBg];
-    TH1D* sign    = CreateSignificanceH1D(H1(sName), H1(bgName), hName + "_significance", sigOption);
-    DrawH1(sign);
+    TH1D* sign =
+      CreateSignificanceH1(fH.H1(hist, ELmvmSrc::Signal), fH.H1(hist, ELmvmSrc::Bg), hist + "_significance", sigOption);
+    DrawH1(sign, kLinear, kLinear, "hist");
   }
 }
 
-void CbmAnaDielectronTaskDraw::DrawCutDistributions()
+void LmvmDraw::DrawCuts()
 {
-  //Draw1DCut("fh_richann", "left", CbmLitGlobalElectronId::GetInstance().GetRichAnnCut());
-  //Draw1DCut("fh_trdann", "left", CbmLitGlobalElectronId::GetInstance().GetTrdAnnCut());
-
-  Draw1DCut("fh_richann", "left", -0.4);
-  Draw1DCut("fh_trdann", "left", 0.85);
-
-  Draw2DCut("fh_tofm2");
-
-  Draw1DCut("fh_chi2prim", "right", fCuts.fChiPrimCut);
-  Draw1DCut("fh_pt", "left", fCuts.fPtCut);
-  Draw1DCut("fh_mom", "left");
-  Draw1DCut("fh_chi2sts", "right");
-
-  Draw2DCut("fh_stcut", fCuts.fStCutPP, fCuts.fStCutAngle);
-  Draw2DCut("fh_ttcut", fCuts.fTtCutPP, fCuts.fTtCutAngle);
-  Draw2DCut("fh_rtcut", fCuts.fRtCutPP, fCuts.fRtCutAngle);
-
-  Draw2DCut("fh_stcut_pion", fCuts.fStCutPP, fCuts.fStCutAngle);
-  Draw2DCut("fh_ttcut_pion", fCuts.fTtCutPP, fCuts.fTtCutAngle);
-  Draw2DCut("fh_rtcut_pion", fCuts.fRtCutPP, fCuts.fRtCutAngle);
-  Draw2DCut("fh_stcut_truepair", fCuts.fStCutPP, fCuts.fStCutAngle);
-  Draw2DCut("fh_ttcut_truepair", fCuts.fTtCutPP, fCuts.fTtCutAngle);
-  Draw2DCut("fh_rtcut_truepair", fCuts.fRtCutPP, fCuts.fRtCutAngle);
-
-  /*  TH2D* st = H2("fh_stcut_signal");
-   double sumT = 0.;
-   double sumAll = 0;
-   for (int x = 1; x <= st->GetNbinsX(); x++){
-      for (int y = 1; y <= st->GetNbinsY(); y++){
-         double c = st->GetBinContent(x, y);
-         double xc = (st->GetXaxis()->GetBinLowEdge(x) + st->GetXaxis()->GetBinUpEdge(x))/2.0;
-         double yc = (st->GetYaxis()->GetBinLowEdge(y) + st->GetXaxis()->GetBinUpEdge(y))/2.0;
-
-         Double_t val = -1.*(fStCutAngle/fStCutPP)*xc + fStCutAngle;
-         if ( (xc < fStCutPP && val > yc) ) {
-         // Double_t val = -1.*(fTtCutAngle/fTtCutPP)*xc + fTtCutAngle;
-         // if ( (xc < fTtCutPP && val > yc) ) {
-            sumT += c;
-         }
-         sumAll += c;
-      }
-   }
-   cout << endl << endl << endl << "sumT/sumAll = " << 100*sumT/sumAll << endl;
-*/
+  Draw1DCut("hRichAnn", "left", -0.4);  // CbmLitGlobalElectronId::GetInstance().GetRichAnnCut()
+  Draw1DCut("hTrdAnn", "left", 0.85);   // CbmLitGlobalElectronId::GetInstance().GetTrdAnnCut()
+  Draw2DCut("hTofM2");
+
+  Draw1DCut("hChi2PrimVertex", "right", fCuts.fChi2PrimCut);
+  //Draw1DCut("hPt", "left", fCuts.fPtCut);
+  //Draw1DCut("hMom", "left");
+  Draw1DCut("hChi2Sts", "right");
+
+  for (const string& type : {"all", "pion", "truePair"}) {
+    Draw2DCut("hStCut_" + type, fCuts.fStCutPP, fCuts.fStCutAngle);
+    Draw2DCut("hTtCut_" + type, fCuts.fTtCutPP, fCuts.fTtCutAngle);
+    Draw2DCut("hRtCut_" + type, fCuts.fRtCutPP, fCuts.fRtCutAngle);
+  }
 
   if (fUseMvd) {
-    Draw2DCut("fh_mvd1cut", fCuts.fMvd1CutD, fCuts.fMvd1CutP);
-    Draw2DCut("fh_mvd2cut", fCuts.fMvd2CutD, fCuts.fMvd2CutP);
+    Draw2DCut("hMvdCut_1", fCuts.fMvd1CutD, fCuts.fMvd1CutP);
+    Draw2DCut("hMvdCut_2", fCuts.fMvd2CutD, fCuts.fMvd2CutP);
   }
 }
 
-void CbmAnaDielectronTaskDraw::DrawSourcesBgPairsEpEm(int step, bool inPercent, bool drawAnaStep)
+void LmvmDraw::DrawSrcBgPairs(ELmvmAnaStep step, bool inPercent, bool drawAnaStep)
 {
-  TH2D* h = (TH2D*) H2("fh_source_pairs_epem_" + CbmLmvmHist::fAnaSteps[step])->Clone();
+  TH2D* h = fH.H2Clone("hSrcBgPairsEpEm", step);
   gStyle->SetPaintTextFormat("4.1f");
   string labels[3] = {"#gamma", "#pi^{0}", "oth"};
-  for (Int_t i = 1; i <= 3; i++) {
+  for (int i = 1; i <= 3; i++) {
     h->GetYaxis()->SetBinLabel(i, labels[i - 1].c_str());
     h->GetXaxis()->SetBinLabel(i, labels[i - 1].c_str());
   }
-  //h->SetMarkerColor(0);
   h->SetMarkerSize(3);
   if (inPercent) {
     h->Scale(100. / h->Integral());
@@ -955,178 +371,141 @@ void CbmAnaDielectronTaskDraw::DrawSourcesBgPairsEpEm(int step, bool inPercent,
   DrawH2(h, kLinear, kLinear, kLinear, "text COLZ");
   h->GetXaxis()->SetLabelSize(0.1);
   h->GetYaxis()->SetLabelSize(0.1);
-  if (drawAnaStep) DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.50, 0.90, 0.70, 0.99);
+  if (drawAnaStep) fH.DrawAnaStepOnPad(step);
 }
 
-void CbmAnaDielectronTaskDraw::DrawSourcesBgPairsAll()
+void LmvmDraw::DrawSrcBgPairsAll()
 {
-  Int_t hi    = 1;
-  TCanvas* c1 = fHM->CreateCanvas("lmvm_bg_sources_pairs_epem_abs", "lmvm_bg_sources_pairs_epem_abs", 900, 900);
+  int hi      = 1;
+  TCanvas* c1 = fH.fHM.CreateCanvas("lmvm_srcBgPairs_abs", "lmvm_srcBgPairs_abs", 1500, 1500);
   c1->Divide(3, 3);
-  for (int step = kReco; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
+  for (ELmvmAnaStep step : fH.fAnaSteps) {
+    if (step == ELmvmAnaStep::Mc || step == ELmvmAnaStep::Acc || SkipMvd(step)) continue;
     c1->cd(hi++);
-    DrawSourcesBgPairsEpEm(step, false);
+    DrawSrcBgPairs(step, false);
   }
 
   hi          = 1;
-  TCanvas* c2 = fHM->CreateCanvas("lmvm_bg_sources_pairs_epem_percent", "lmvm_bg_sources_pairs_epem_percent", 900, 900);
+  TCanvas* c2 = fH.fHM.CreateCanvas("lmvm_srcBgPairs_perc", "lmvm_srcBgPairs_perc", 1500, 1500);
   c2->Divide(3, 3);
-  for (int step = kReco; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    c2->cd(hi++);
-    DrawSourcesBgPairsEpEm(step, true);
+  for (ELmvmAnaStep step : fH.fAnaSteps) {
+    if (step == ELmvmAnaStep::Mc || step == ELmvmAnaStep::Acc || SkipMvd(step)) continue;
+    c1->cd(hi++);
+    DrawSrcBgPairs(step, true);
   }
 
-  //Draw pair source histogram for the las step (ptcut)
-  fHM->CreateCanvas("lmvm_bg_sources_pairs_epem_abs_" + CbmLmvmHist::fAnaSteps[kPtCut],
-                    "lmvm_bg_sources_pairs_epem_abs_" + CbmLmvmHist::fAnaSteps[kPtCut], 600, 600);
-  DrawSourcesBgPairsEpEm(kPtCut, false, false);
+  string ptCutName = fH.fAnaStepNames[static_cast<int>(ELmvmAnaStep::PtCut)];
+  fH.fHM.CreateCanvas("lmvm_srcBgPairs_abs_" + ptCutName, "lmvm_srcBgPairs_abs_" + ptCutName, 900, 900);
+  DrawSrcBgPairs(ELmvmAnaStep::PtCut, false, false);
 
-  fHM->CreateCanvas("lmvm_bg_sources_pairs_epem_percent_" + CbmLmvmHist::fAnaSteps[kPtCut],
-                    "lmvm_bg_sources_pairs_epem_percent_" + CbmLmvmHist::fAnaSteps[kPtCut], 600, 600);
-  DrawSourcesBgPairsEpEm(kPtCut, true, false);
+  fH.fHM.CreateCanvas("lmvm_srcBgPairs_perc_" + ptCutName, "lmvm_srcBgPairs_perc_" + ptCutName, 900, 900);
+  DrawSrcBgPairs(ELmvmAnaStep::PtCut, true, false);
 
-  // Draw 2D histogram for sources of BG pairs
-  DrawBgSource2D("lmvm_source_pairs_2d", "fh_source_pairs", CbmLmvmHist::fBgPairSourceLatex, 1000.,
-                 "Pairs per event x10^{3}");
+  DrawBgSource2D("lmvm_srcBgPairs_2d", "hSrcBgPairs", fH.fBgPairSrcLatex, 1000., "Pairs per event x10^{3}");
 }
 
-void CbmAnaDielectronTaskDraw::Draw2DCutTriangle(double xCross, double yCross)
+void LmvmDraw::Draw2DCutTriangle(double xCr, double yCr)
 {
-  if (xCross == -999999. || yCross == -999999.) return;
-  TLine* line1 = new TLine(0., 0., xCross, 0.);
-  line1->SetLineWidth(2.);
-  line1->Draw();
-  TLine* line2 = new TLine(0., 0., 0., yCross);
-  line2->SetLineWidth(2.);
-  line2->Draw();
-  TLine* line3 = new TLine(xCross, 0., 0., yCross);
-  line3->SetLineWidth(2.);
-  line3->Draw();
+  if (xCr == -999999. || yCr == -999999.) return;
+  vector<TLine*> lines {new TLine(0., 0., xCr, 0.), new TLine(0., 0., 0., yCr), new TLine(xCr, 0., 0., yCr)};
+  for (size_t i = 0; i < lines.size(); i++) {
+    lines[i]->SetLineWidth(2.);
+    lines[i]->Draw();
+  }
 }
 
-
-void CbmAnaDielectronTaskDraw::Draw2DCut(const string& hist, double cutCrossX, double cutCrossY)
+void LmvmDraw::Draw2DCut(const string& hist, double cutCrossX, double cutCrossY)
 {
-  TCanvas* c = fHM->CreateCanvas(("lmvm_" + hist).c_str(), ("lmvm_" + hist).c_str(), 600, 900);
+  TCanvas* c = fH.fHM.CreateCanvas(("lmvm_" + hist).c_str(), ("lmvm_" + hist).c_str(), 1000, 1500);
   c->Divide(2, 3);
   vector<TH1*> projX, projY;
-  for (int i = 0; i < CbmLmvmHist::fNofSourceTypes; i++) {
-    c->cd(i + 1);
-    DrawH2(H2(hist + "_" + CbmLmvmHist::fSourceTypes[i]));
-    double nofPerEvent = H2(hist + "_" + CbmLmvmHist::fSourceTypes[i])->GetEntries() / (double) fNofEvents;
-    cout << hist << "_" << CbmLmvmHist::fSourceTypes[i] << " = " << nofPerEvent << endl;
+  vector<string> latex;
+  for (ELmvmSrc src : {ELmvmSrc::Signal, ELmvmSrc::Bg, ELmvmSrc::Pi0, ELmvmSrc::Gamma}) {
+    int srcInt = static_cast<int>(src);
+    c->cd(srcInt + 1);
+    DrawH2(fH.H2(hist, src));
+    double nofPerEvent = fH.H2(hist, src)->GetEntries() / (double) fNofEvents;
     DrawTextOnPad((Cbm::NumberToString(nofPerEvent, 2) + "/ev."), 0.1, 0.9, 0.5, 0.99);
-    DrawTextOnPad(CbmLmvmHist::fSourceTypesLatex[i], 0.6, 0.89, 0.7, 0.99);
+    DrawTextOnPad(fH.fSrcLatex[srcInt], 0.6, 0.89, 0.7, 0.99);
     Draw2DCutTriangle(cutCrossX, cutCrossY);
-    projX.push_back(H2(hist + "_" + CbmLmvmHist::fSourceTypes[i])->ProjectionX());
-    projY.push_back(H2(hist + "_" + CbmLmvmHist::fSourceTypes[i])->ProjectionY());
+    projX.push_back(fH.H2(hist, src)->ProjectionX());
+    projY.push_back(fH.H2(hist, src)->ProjectionY());
+    latex.push_back(fH.fSrcLatex[srcInt]);
   }
 
-  //Draw X projection
   c->cd(5);
-  DrawH1(projX, CbmLmvmHist::fSourceTypesLatex, kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99);
+  DrawH1(projX, latex, kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99, "hist");
 
-  //Draw Y projection
   c->cd(6);
-  DrawH1(projY, CbmLmvmHist::fSourceTypesLatex, kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99);
-
-  fHM->CreateCanvas(("lmvm_" + hist + "_signal").c_str(), ("lmvm_" + hist + "_signal").c_str(), 800, 800);
-  DrawH2(H2(hist + "_" + CbmLmvmHist::fSourceTypes[kSignal]));
-  Draw2DCutTriangle(cutCrossX, cutCrossY);
-  fHM->CreateCanvas(("lmvm_" + hist + "_gamma").c_str(), ("lmvm_" + hist + "_gamma").c_str(), 800, 800);
-  DrawH2(H2(hist + "_" + CbmLmvmHist::fSourceTypes[kGamma]));
-  Draw2DCutTriangle(cutCrossX, cutCrossY);
-  //c->cd(9);
-  //TH2D* fh_significance = CalculateSignificance2D(fh_stcut_signal, fh_stcut_bg, "stcut_2dsignificance", "significance");
-  //fh_significance->Draw("COLZ");
+  DrawH1(projY, latex, kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99, "hist");
 }
 
-void CbmAnaDielectronTaskDraw::DrawGammaVertex()
+void LmvmDraw::DrawGammaVertex()
 {
-  TH2D* xz   = H2("fh_vertex_el_gamma_xz_mc");
-  TH2D* yz   = H2("fh_vertex_el_gamma_yz_mc");
-  TH2D* xy   = H2("fh_vertex_el_gamma_xy_mc");
-  TCanvas* c = fHM->CreateCanvas("lmvm_vertex_el_gamma_mc", "lmvm_vertex_el_gamma_mc", 1200, 400);
+  vector<TH2D*> xyz {fH.H2("hVertexGammaXZ", ELmvmAnaStep::Mc), fH.H2("hVertexGammaYZ", ELmvmAnaStep::Mc),
+                     fH.H2("hVertexGammaXY", ELmvmAnaStep::Mc)};
+
+  TCanvas* c = fH.fHM.CreateCanvas("lmvm_vertexGamma_mc", "lmvm_vertexGamma_mc", 1800, 600);
   c->Divide(3, 1);
-  c->cd(1);
-  DrawH2(xz);
-  xz->SetMinimum(1e-3);
-  gPad->SetLogz(true);
-  c->cd(2);
-  DrawH2(yz);
-  yz->SetMinimum(1e-3);
-  gPad->SetLogz(true);
-  c->cd(3);
-  DrawH2(xy);
-  xy->SetMinimum(1e-3);
-  gPad->SetLogz(true);
+  for (size_t i = 0; i < xyz.size(); i++) {
+    c->cd(i + 1);
+    DrawH2(xyz[i]);
+    xyz[i]->SetMinimum(1e-3);
+    gPad->SetLogz(true);
+  }
 
-  // number of e+- from gamma vs Z.
-  fHM->CreateCanvas("lmvm_vertex_el_gamma_z_mc", "lmvm_vertex_el_gamma_z_mc", 600, 600);
-  TH1D* zProj = (TH1D*) xz->ProjectionX("fh_vertex_el_gamma_pz_mc")->Clone();
-  zProj->GetYaxis()->SetTitle("Counter per event");
-  zProj->GetXaxis()->SetRangeUser(-2., 17.);
-  DrawH1(zProj);
-
-  fHM->CreateCanvas("lmvm_vertex_el_gamma_z_ptcut", "lmvm_vertex_el_gamma_z_ptcut", 600, 600);
-  TH1D* zProjPtCut = (TH1D*) (H2("fh_vertex_el_gamma_xz_ptcut")->ProjectionX("fh_vertex_el_gamma_ptcut_pz")->Clone());
-  zProjPtCut->GetYaxis()->SetTitle("Counter per event");
-  zProjPtCut->GetXaxis()->SetRangeUser(-2., 17.);
-  DrawH1(zProjPtCut);
-
-  TH2D* xzZoom = (TH2D*) xz->Clone();
-  TH2D* yzZoom = (TH2D*) yz->Clone();
-  TH2D* xyZoom = (TH2D*) xy->Clone();
-  TCanvas* cZoom =
-    fHM->CreateCanvas("lmvm_vertex_el_gamma_mc_target_zoom", "lmvm_vertex_el_gamma_mc_target_zoom", 1200, 400);
-  cZoom->Divide(3, 1);
-  cZoom->cd(1);
-  xzZoom->GetXaxis()->SetRangeUser(-1., 11.);
-  xzZoom->GetYaxis()->SetRangeUser(-10., 10.);
-  DrawH2(xzZoom);
-  xzZoom->SetMinimum(1e-3);
-  gPad->SetLogz(true);
-  cZoom->cd(2);
-  yzZoom->GetXaxis()->SetRangeUser(-1., 11.);
-  yzZoom->GetYaxis()->SetRangeUser(-10., 10.);
-  DrawH2(yzZoom);
-  yzZoom->SetMinimum(1e-3);
-  gPad->SetLogz(true);
-  cZoom->cd(3);
-  xyZoom->GetXaxis()->SetRangeUser(-20., 20.);
-  xyZoom->GetYaxis()->SetRangeUser(-20., 20.);
-  DrawH2(xyZoom);
-  xyZoom->SetMinimum(1e-3);
-  gPad->SetLogz(true);
+  TCanvas* cZ = fH.fHM.CreateCanvas("lmvm_vertexGamma_z", "lmvm_vertexGamma_z", 1500, 750);
+  cZ->Divide(2, 1);
+  int counter = 1;
+  for (ELmvmAnaStep step : {ELmvmAnaStep::Mc, ELmvmAnaStep::PtCut}) {
+    cZ->cd(counter++);
+    string name = fH.GetName("hVertexGammaXZ", step);
+    TH1D* zProj = (TH1D*) fH.H2(name)->ProjectionX((name + "pz").c_str())->Clone();
+    zProj->GetYaxis()->SetTitle("Counter per event");
+    zProj->GetXaxis()->SetRangeUser(-2., 17.);
+    DrawH1(zProj, kLinear, kLinear, "hist");
+    fH.DrawAnaStepOnPad(step);
+  }
 
-  fHM->CreateCanvas("lmvm_vertex_el_gamma_rz_mc", "lmvm_vertex_el_gamma_rz_mc", 600, 600);
-  DrawH2(H2("fh_vertex_el_gamma_rz_mc"));
-  H2("fh_vertex_el_gamma_rz_mc")->SetMinimum(1e-3);
+  TCanvas* cZoom = fH.fHM.CreateCanvas("lmvm_vertexGamma_mc_zoom", "lmvm_vertexGamma_mc_zoom", 1800, 600);
+  cZoom->Divide(3, 1);
+  for (size_t i = 0; i < xyz.size(); i++) {
+    TH2D* hZoom = (TH2D*) xyz[i]->Clone();
+    cZoom->cd(i + 1);
+    hZoom->GetXaxis()->SetRangeUser(-1., 11.);
+    hZoom->GetYaxis()->SetRangeUser(-10., 10.);
+    DrawH2(hZoom);
+    hZoom->SetMinimum(1e-3);
+    gPad->SetLogz(true);
+  }
+
+  fH.fHM.CreateCanvas("lmvm_vertexGamma_rz_mc", "lmvm_vertexGamma_rz_mc", 900, 900);
+  DrawH2(fH.H2("hVertexGammaRZ", ELmvmAnaStep::Mc));
+  fH.H2("hVertexGammaRZ", ELmvmAnaStep::Mc)->SetMinimum(1e-3);
   gPad->SetLogz(true);
 }
 
-void CbmAnaDielectronTaskDraw::Draw1DHistoForEachAnalysisStep(const string& hist, Bool_t logy)
-{
-  string drOpt     = "";  // First histogram will be drawn without options.
-  Double_t min     = 9999999999.;
-  TH1D* firstHisto = NULL;
-  TLegend* leg     = new TLegend(0.80, 0.32, 0.99, 0.99);
-  for (int step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    string fullName = hist + "_" + CbmLmvmHist::fAnaSteps[step];
-    TH1D* h         = H1(fullName);
-    if (h == NULL || h->GetEntries() <= 0) continue;
-    leg->AddEntry(h, CbmLmvmHist::fAnaStepsLatex[step].c_str(), "l");
-    int color = CbmLmvmHist::fAnaStepsColor[step];
-    DrawH1(h, kLinear, kLinear, drOpt, color);
-    if (firstHisto == NULL) firstHisto = h;
-    drOpt = "same";  // If the histogram is drawn, next histograms must be drawn with "same" option.
-    if (min > h->GetMinimum()) { min = h->GetMinimum(); }
-  }
-  if (min <= 0.0) min = 1e-9;
-  if (firstHisto != NULL) firstHisto->SetMinimum(min);
+void LmvmDraw::DrawAnaStepH1(const string& name, bool logy)
+{
+  double min   = std::numeric_limits<Double_t>::max();
+  double max   = std::numeric_limits<Double_t>::min();
+  TH1D* h0     = nullptr;
+  TLegend* leg = new TLegend(0.80, 0.32, 0.99, 0.99);
+  for (const auto step : fH.fAnaSteps) {
+    if (SkipMvd(step)) continue;
+    TH1D* h = fH.H1(name, step);
+    LOG(info) << name << " " << h->GetEntries();
+    if (h == nullptr || h->GetEntries() <= 0) continue;
+    leg->AddEntry(h, fH.fAnaStepLatex[static_cast<int>(step)].c_str(), "l");
+    DrawH1(h, kLinear, kLinear, (h0 == nullptr) ? "hist" : "hist,same", fH.fAnaStepColors[static_cast<int>(step)]);
+    if (h0 == nullptr) h0 = h;
+    min = std::min(h->GetMinimum(), min);
+    max = std::max(h->GetMaximum(), max);
+    LOG(info) << name << " min:" << h->GetMinimum() << " max:" << h->GetMaximum();
+  }
+  if (min == 0.) min = std::min(1e-8, max * 1e-6);
+  if (h0 != nullptr) h0->SetMinimum(min);
+  if (h0 != nullptr) h0->SetMaximum(1.1 * max);
 
   leg->SetFillColor(kWhite);
   leg->Draw();
@@ -1136,58 +515,42 @@ void CbmAnaDielectronTaskDraw::Draw1DHistoForEachAnalysisStep(const string& hist
   gPad->SetLogy(logy);
 }
 
-void CbmAnaDielectronTaskDraw::DrawMinvForEachAnalysisStep()
+void LmvmDraw::DrawMinvAll()
 {
-  TCanvas* c1 =
-    fHM->CreateCanvas("lmvm_minv_for_each_analysis_step_s_bg", "lmvm_minv_for_each_analysis_step_s_bg", 1200, 600);
+  TCanvas* c1 = fH.fHM.CreateCanvas("lmvm_minv_sbg_anaStep", "lmvm_minv_sbg_anaStep", 1200, 600);
   c1->Divide(2, 1);
   c1->cd(1);
-  Draw1DHistoForEachAnalysisStep("fh_signal_minv", true);
+  DrawAnaStepH1(fH.GetName("hMinv", ELmvmSrc::Signal), true);
   c1->cd(2);
-  Draw1DHistoForEachAnalysisStep("fh_bg_minv", true);
+  DrawAnaStepH1(fH.GetName("hMinv", ELmvmSrc::Bg), true);
 
-
-  TCanvas* c2 = fHM->CreateCanvas("lmvm_minv_for_each_analysis_step_pi0_eta",
-                                  "lmvm_minv_for_each_analysis_step_pi0_eta", 1200, 600);
-  c2->Divide(2, 1);
+  TCanvas* c2 = fH.fHM.CreateCanvas("lmvm_minv_pi0_eta_gamma_anaStep", "lmvm_minv_pi0_eta_gamma_anaStep", 1800, 600);
+  c2->Divide(3, 1);
   c2->cd(1);
-  Draw1DHistoForEachAnalysisStep("fh_pi0_minv", true);
+  DrawAnaStepH1(fH.GetName("hMinv", ELmvmSrc::Pi0), true);
   c2->cd(2);
-  Draw1DHistoForEachAnalysisStep("fh_eta_minv", true);
-
-  TCanvas* c3 = fHM->CreateCanvas("lmvm_minv_for_each_analysis_step_combinatorial_Pairs_same_Event",
-                                  "lmvm_minv_for_each_analysis_step_combinatorial_Pairs_same_event", 1800, 600);
-  c3->Divide(3, 1);
-  c3->cd(1);
-  Draw1DHistoForEachAnalysisStep("fh_combPairsPM_minv_sameEvent", true);
-  c3->cd(2);
-  Draw1DHistoForEachAnalysisStep("fh_combPairsPP_minv_sameEvent", true);
-  c3->cd(3);
-  Draw1DHistoForEachAnalysisStep("fh_combPairsMM_minv_sameEvent", true);
-
-  TCanvas* c4 = fHM->CreateCanvas("lmvm_minv_for_each_analysis_step_combinatorial_Pairs_mixed_Events",
-                                  "lmvm_minv_for_each_analysis_step_combinatorial_Pairs_mixed_Events", 1800, 600);
-  c4->Divide(3, 1);
-  c4->cd(1);
-  Draw1DHistoForEachAnalysisStep("fh_combPairsPM_minv_mixedEvents", true);
-  c4->cd(2);
-  Draw1DHistoForEachAnalysisStep("fh_combPairsPP_minv_mixedEvents", true);
-  c4->cd(3);
-  Draw1DHistoForEachAnalysisStep("fh_combPairsMM_minv_mixedEvents", true);
-
-  fHM->CreateCanvas("lmvm_minv_for_each_analysis_step_gamma", "lmvm_minv_for_each_analysis_step_gamma", 600, 600);
-  // H1("fh_gamma_minv_mc")->GetXaxis()->SetRangeUser(0., 0.05);
-  Draw1DHistoForEachAnalysisStep("fh_gamma_minv", true);
+  DrawAnaStepH1(fH.GetName("hMinv", ELmvmSrc::Eta), true);
+  c2->cd(3);
+  DrawAnaStepH1(fH.GetName("hMinv", ELmvmSrc::Gamma), true);
+
+  for (const string& name : {"sameEv", "mixedEv"}) {
+    string cName = "lmvm_minv_combPairs_" + name;
+    TCanvas* c3  = fH.fHM.CreateCanvas(cName.c_str(), cName.c_str(), 1800, 600);
+    c3->Divide(3, 1);
+    c3->cd(1);
+    DrawAnaStepH1("hMinvCombPM_" + name, true);
+    c3->cd(2);
+    DrawAnaStepH1("hMinvCombPP_" + name, true);
+    c3->cd(3);
+    DrawAnaStepH1("hMinvCombMM_" + name, true);
+  }
 }
 
-void CbmAnaDielectronTaskDraw::DrawMinvSandBg(int step)
+void LmvmDraw::DrawMinvSBg(ELmvmAnaStep step)
 {
-  TH1* s1  = H1("fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step]);
-  TH1* bg1 = H1("fh_bg_minv_" + CbmLmvmHist::fAnaSteps[step]);
-
-  TH1D* s   = (TH1D*) s1->Clone();
-  TH1D* bg  = (TH1D*) bg1->Clone();
-  TH1D* sbg = (TH1D*) bg->Clone();
+  TH1D* s   = fH.H1Clone("hMinv", ELmvmSrc::Signal, step);
+  TH1D* bg  = fH.H1Clone("hMinv", ELmvmSrc::Bg, step);
+  TH1D* sbg = static_cast<TH1D*>(bg->Clone());
   sbg->Add(s);
   sbg->SetMinimum(1e-8);
 
@@ -1208,486 +571,238 @@ void CbmAnaDielectronTaskDraw::DrawMinvSandBg(int step)
   bg->SetMarkerStyle(1);
   sbg->SetMarkerStyle(1);
 
-  DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.65, 0.78, 0.85, 0.9);
-}
-
-void CbmAnaDielectronTaskDraw::DrawMinvSandBgAll()
-{
-  Int_t hi   = 1;
-  TCanvas* c = fHM->CreateCanvas("lmvm_minv_both_s_and_bg", "lmvm_minv_both_s_and_bg", 900, 900);
-  c->Divide(3, 3);
-  for (int step = kReco; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    c->cd(hi++);
-    DrawMinvSandBg(step);
-  }
-
-  fHM->CreateCanvas("lmvm_minv_both_s_and_bg_ptcut", "lmvm_minv_both_s_and_bg_ptcut", 900, 900);
-  DrawMinvSandBg(kPtCut);
+  fH.DrawAnaStepOnPad(step);
 }
 
-void CbmAnaDielectronTaskDraw::DrawMinvSource(int step, bool drawAnaStep)
+void LmvmDraw::DrawMinvBgPairSrc(ELmvmAnaStep step)
 {
-  double nofBg = H1("fh_bg_minv_" + CbmLmvmHist::fAnaSteps[step])->GetEntries();
-
+  double nofBg = fH.H1("hMinv", ELmvmSrc::Bg, step)->GetEntries();
   vector<TH1*> hists;
-  for (int i = 0; i < CbmLmvmHist::fNofBgPairSources; i++) {
+  vector<string> latex;
+  for (int i = 0; i < fH.fNofBgPairSrc; i++) {
     stringstream ss;
-    ss << "fh_source_bg_minv_" << i << "_" << CbmLmvmHist::fAnaSteps[step];
-    H1(ss.str())->GetXaxis()->SetRangeUser(0, 2.);
-    hists.push_back(H1(ss.str()));
-  }
-
-  DrawH1(hists, CbmLmvmHist::fBgPairSourceLatex, kLinear, kLinear, false, 0.85, 0.15, 0.99, 0.80);
-
-  TLegend* legend = new TLegend(0.78, 0.15, 0.99, 0.90);
-  for (int i = 0; i < CbmLmvmHist::fNofBgPairSources; i++) {
+    ss << "hMinvBgSource_" << fH.fBgPairSrcNames[i] << "_" << fH.fAnaStepNames[static_cast<int>(step)];
+    hists.push_back(fH.H1(ss.str()));
     hists[i]->SetMinimum(1e-8);
-    legend->AddEntry(
-      hists[i],
-      (CbmLmvmHist::fBgPairSourceLatex[i] + "(" + Cbm::NumberToString(100. * hists[i]->GetEntries() / nofBg, 1) + "%)")
-        .c_str(),
-      "f");
+    string perc = Cbm::NumberToString(100. * hists[i]->GetEntries() / nofBg, 1);
+    latex.push_back(fH.fBgPairSrcLatex[i] + "(" + perc + "%)");
   }
-  legend->SetFillColor(kWhite);
-  legend->Draw();
-  if (drawAnaStep) DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.65, 0.78, 0.85, 0.9);
+  DrawH1(hists, latex, kLinear, kLinear, true, 0.7, 0.45, 0.99, 0.9, "hist");
+  bool drawAnaStep = true;
+  if (drawAnaStep) fH.DrawAnaStepOnPad(step);
 }
 
-void CbmAnaDielectronTaskDraw::DrawMinvSourceAll()
+void LmvmDraw::DrawMinvMatching(ELmvmAnaStep step)
 {
-  {
-    Int_t hi   = 1;
-    TCanvas* c = fHM->CreateCanvas("lmvm_minv_source", "lmvm_minv_source", 900, 900);
-    c->Divide(3, 3);
-    for (int step = kReco; step < CbmLmvmHist::fNofAnaSteps; step++) {
-      if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-      c->cd(hi++);
-      DrawMinvSource(step);
-    }
-
-    // Draw histogram for the last step (ptcut) on one histogram
-    fHM->CreateCanvas("lmvm_minv_source_" + CbmLmvmHist::fAnaSteps[kPtCut],
-                      "lmvm_minv_source_" + CbmLmvmHist::fAnaSteps[kPtCut], 600, 600);
-    DrawMinvSource(kPtCut, false);
-
-    fHM->CreateCanvas("lmvm_minv_source_" + CbmLmvmHist::fAnaSteps[kElId],
-                      "lmvm_minv_source_" + CbmLmvmHist::fAnaSteps[kElId], 600, 600);
-    DrawMinvSource(kElId, false);
-  }
-
-  // Draw mismatches and true matches minv
-  {
-    Int_t hi   = 1;
-    TCanvas* c = fHM->CreateCanvas("lmvm_minv_mismatches", "lmvm_minv_mismatches", 900, 900);
-    c->Divide(3, 3);
-    for (int step = kReco; step < CbmLmvmHist::fNofAnaSteps; step++) {
-      if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-      c->cd(hi++);
-      DrawH1({H1("fh_bg_truematch_minv_" + CbmLmvmHist::fAnaSteps[step]),
-              H1("fh_bg_truematch_el_minv_" + CbmLmvmHist::fAnaSteps[step]),
-              H1("fh_bg_truematch_notel_minv_" + CbmLmvmHist::fAnaSteps[step]),
-              H1("fh_bg_mismatch_minv_" + CbmLmvmHist::fAnaSteps[step])},
-             {"true match", "true match (e^{#pm})", "true match (not e^{#pm})", "mismatch"}, kLinear, kLinear, true,
-             0.5, 0.7, 0.99, 0.99);
-    }
-
-    // Draw minv after PtCut
-    double trueMatch      = H1("fh_bg_truematch_minv_" + CbmLmvmHist::fAnaSteps[kPtCut])->GetEntries();
-    double trueMatchEl    = H1("fh_bg_truematch_el_minv_" + CbmLmvmHist::fAnaSteps[kPtCut])->GetEntries();
-    double trueMatchNotEl = H1("fh_bg_truematch_notel_minv_" + CbmLmvmHist::fAnaSteps[kPtCut])->GetEntries();
-    double misMatch       = H1("fh_bg_mismatch_minv_" + CbmLmvmHist::fAnaSteps[kPtCut])->GetEntries();
-    double nofBg          = H1("fh_bg_minv_" + CbmLmvmHist::fAnaSteps[kPtCut])->GetEntries();
-
-    fHM->CreateCanvas("lmvm_minv_mismatches_" + CbmLmvmHist::fAnaSteps[kPtCut],
-                      "lmvm_minv_mismatches_" + CbmLmvmHist::fAnaSteps[kPtCut], 700, 700);
-    DrawH1({H1("fh_bg_truematch_minv_" + CbmLmvmHist::fAnaSteps[kPtCut]),
-            H1("fh_bg_truematch_el_minv_" + CbmLmvmHist::fAnaSteps[kPtCut]),
-            H1("fh_bg_truematch_notel_minv_" + CbmLmvmHist::fAnaSteps[kPtCut]),
-            H1("fh_bg_mismatch_minv_" + CbmLmvmHist::fAnaSteps[kPtCut])},
-           {"true match (" + Cbm::NumberToString(100. * trueMatch / nofBg, 1) + "%)",
-            "true match (e^{#pm}) (" + Cbm::NumberToString(100. * trueMatchEl / nofBg, 1) + "%)",
-            "true match (not e^{#pm}) (" + Cbm::NumberToString(100. * trueMatchNotEl / nofBg, 1) + "%)",
-            "mismatch (" + Cbm::NumberToString(100. * misMatch / nofBg) + "%)"},
-           kLinear, kLinear, true, 0.4, 0.7, 0.99, 0.99);
+  double nofBg = fH.H1("hMinv", ELmvmSrc::Bg, step)->GetEntries();
+  vector<TH1*> hists;
+  vector<string> latex {"true match", "true match (e^{#pm})", "true match (not e^{#pm})", "mismatch "};
+  int i = 0;
+  for (const string& subName : {"trueMatch", "trueMatchEl", "trueMatchNotEl", "mismatch"}) {
+    TH1D* h  = fH.H1("hMinvBgMatch_" + subName, step);
+    latex[i] = latex[i] + " (" + Cbm::NumberToString(100. * h->GetEntries() / nofBg, 1) + "%)";
+    hists.push_back(h);
+    i++;
   }
+  DrawH1(hists, latex, kLinear, kLinear, true, 0.4, 0.6, 0.99, 0.9, "hist");
+  fH.DrawAnaStepOnPad(step);
 }
 
-void CbmAnaDielectronTaskDraw::DrawElPiMomHis()
+void LmvmDraw::DrawPiMom()
 {
-  double binWEl = H1("fh_pi_mom_mc")->GetBinWidth(1);
-
-  fHM->CreateCanvas("lmvm_pi_mom", "lmvm_pi_mom", 800, 800);
-  H1("fh_pi_mom_mc")->Scale(1 / binWEl);
-  H1("fh_pi_mom_acc")->Scale(1 / binWEl);
-  H1("fh_pi_mom_rec")->Scale(1 / binWEl);
-  H1("fh_pi_mom_rec_only_sts")->Scale(1 / binWEl);
-  H1("fh_pi_mom_rec_sts_rich_trd")->Scale(1 / binWEl);
-  H1("fh_pi_mom_rec_sts_rich_trd_tof")->Scale(1 / binWEl);
-  H1("fh_pi_mom_mc")->SetMinimum(2);
-
-  DrawH1(
-    {H1("fh_pi_mom_mc"), H1("fh_pi_mom_acc"), H1("fh_pi_mom_rec"), H1("fh_pi_mom_rec_only_sts"),
-     H1("fh_pi_mom_rec_sts_rich_trd"), H1("fh_pi_mom_rec_sts_rich_trd_tof")},
-    {"MC (" + Cbm::NumberToString(H1("fh_pi_mom_mc")->GetEntries() / fNofEvents, 2) + " per event)",
-     "Acc (" + Cbm::NumberToString(H1("fh_pi_mom_acc")->GetEntries() / fNofEvents, 2) + " per event)",
-     "Rec (" + Cbm::NumberToString(H1("fh_pi_mom_rec")->GetEntries() / fNofEvents, 2) + " per event)",
-     "Rec only STS (" + Cbm::NumberToString(H1("fh_pi_mom_rec_only_sts")->GetEntries() / fNofEvents, 2) + " per event)",
-     "Rec STS-RICH-TRD (" + Cbm::NumberToString(H1("fh_pi_mom_rec_sts_rich_trd")->GetEntries() / fNofEvents, 2)
-       + " per event)",
-     "Rec STS-RICH-TRD-TOF (" + Cbm::NumberToString(H1("fh_pi_mom_rec_sts_rich_trd_tof")->GetEntries() / fNofEvents, 2)
-       + " per event)"},
-    kLinear, kLog, true, 0.1, 0.7, 0.99, 0.99);
-
-  //primary pions vertex < 0.1 cm
-  double binWElPrim = H1("fh_piprim_mom_mc")->GetBinWidth(1);
-  fHM->CreateCanvas("lmvm_piprim_mom", "lmvm_piprim_mom", 800, 800);
-  H1("fh_piprim_mom_mc")->Scale(1 / binWElPrim);
-  H1("fh_piprim_mom_acc")->Scale(1 / binWElPrim);
-  H1("fh_piprim_mom_rec")->Scale(1 / binWElPrim);
-  H1("fh_piprim_mom_rec_only_sts")->Scale(1 / binWElPrim);
-  H1("fh_piprim_mom_rec_sts_rich_trd")->Scale(1 / binWElPrim);
-  H1("fh_piprim_mom_rec_sts_rich_trd_tof")->Scale(1 / binWElPrim);
-  H1("fh_piprim_mom_mc")->SetMinimum(2);
-  DrawH1({H1("fh_piprim_mom_mc"), H1("fh_piprim_mom_acc"), H1("fh_piprim_mom_rec"), H1("fh_piprim_mom_rec_only_sts"),
-          H1("fh_piprim_mom_rec_sts_rich_trd"), H1("fh_piprim_mom_rec_sts_rich_trd_tof")},
-         {"MC (" + Cbm::NumberToString(H1("fh_piprim_mom_mc")->GetEntries() / fNofEvents, 2) + " per event)",
-          "Acc (" + Cbm::NumberToString(H1("fh_piprim_mom_acc")->GetEntries() / fNofEvents, 2) + " per event)",
-          "Rec (" + Cbm::NumberToString(H1("fh_piprim_mom_rec")->GetEntries() / fNofEvents, 2) + " per event)",
-          "Rec only STS (" + Cbm::NumberToString(H1("fh_piprim_mom_rec_only_sts")->GetEntries() / fNofEvents, 2)
-            + " per event)",
-          "Rec STS-RICH-TRD (" + Cbm::NumberToString(H1("fh_piprim_mom_rec_sts_rich_trd")->GetEntries() / fNofEvents, 2)
-            + " per event)",
-          "Rec STS-RICH-TRD-TOF ("
-            + Cbm::NumberToString(H1("fh_piprim_mom_rec_sts_rich_trd_tof")->GetEntries() / fNofEvents, 2)
-            + " per event)"},
-         kLinear, kLog, true, 0.1, 0.7, 0.99, 0.99);
-
-  fHM->CreateCanvas("lmvm_pi_mom_notacc", "lmvm_pi_mom_notacc", 800, 800);
-  TH1D* h1 = ((TH1D*) H1("fh_pi_mom_mc")->Clone());
-  h1->Add(H1("fh_pi_mom_acc"), -1.);
-  DrawH1(h1);
-  fHM->CreateCanvas("lmvm_piprim_mom_notacc", "lmvm_piprim_mom_notacc", 800, 800);
-  TH1D* h2 = ((TH1D*) H1("fh_piprim_mom_mc")->Clone());
-  h2->Add(H1("fh_piprim_mom_acc"), -1.);
-  DrawH1(h2);
-  DrawH1(h2);
-
-  cout << "Number of primary pions minus at rapidity 2 = "
-       << H1("fh_piprim_minus_rapidity_mc")->GetBinContent(H1("fh_piprim_minus_rapidity_mc")->FindFixBin(2)) << endl;
-  cout << "Number of primary pions minus at rapidity (1, 3) = "
-       << H1("fh_piprim_minus_rapidity_mc")
-            ->Integral(H1("fh_piprim_minus_rapidity_mc")->FindFixBin(1),
-                       H1("fh_piprim_minus_rapidity_mc")->FindFixBin(3))
-       << endl;
-
-  cout << "Number of primary pions plus at rapidity 2 = "
-       << H1("fh_piprim_plus_rapidity_mc")->GetBinContent(H1("fh_piprim_plus_rapidity_mc")->FindFixBin(2)) << endl;
-  cout << "Number of primary pions plus at rapidity (1, 3) = "
-       << H1("fh_piprim_plus_rapidity_mc")
-            ->Integral(H1("fh_piprim_plus_rapidity_mc")->FindFixBin(1), H1("fh_piprim_plus_rapidity_mc")->FindFixBin(3))
-       << endl;
-
-
-  double binWRapidity = H1("fh_piprim_minus_rapidity_mc")->GetBinWidth(1);
-  H1("fh_pi_rapidity_mc")->Scale(1 / binWRapidity);
-  H1("fh_piprim_minus_rapidity_mc")->Scale(1 / binWRapidity);
-  H1("fh_piprim_plus_rapidity_mc")->Scale(1 / binWRapidity);
-  H1("fh_pi0prim_rapidity_mc")->Scale(1 / binWRapidity);
-  H1("fh_etaprim_rapidity_mc")->Scale(1 / binWRapidity);
-
-  fHM->CreateCanvas("lmvm_piprim_plus_rapidity", "lmvm_piprim_plus_rapidity", 800, 800);
-  DrawH1(H1("fh_piprim_plus_rapidity_mc"));
-  fHM->CreateCanvas("lmvm_piprim_minus_rapidity", "lmvm_piprim_minus_rapidity", 800, 800);
-  DrawH1(H1("fh_piprim_minus_rapidity_mc"));
-  fHM->CreateCanvas("lmvm_pi0prim_rapidity", "lmvm_pi0prim_rapidity", 800, 800);
-  DrawH1(H1("fh_pi0prim_rapidity_mc"));
-  fHM->CreateCanvas("lmvm_etaprim_rapidity", "lmvm_etaprim_rapidity", 800, 800);
-  DrawH1(H1("fh_etaprim_rapidity_mc"));
-}
+  vector<string> subNames {"mc", "acc", "rec", "recOnlySts", "recStsRichTrd", "recStsRichTrdTof"};
+  vector<string> latex {"MC", "Acc", "Rec", "Rec only STS", "Rec STS-RICH-TRD", "Rec STS-RICH-TRD-TOF"};
+  vector<string> latexAll(latex.size()), latexPrim(latex.size());
+  vector<TH1*> histsAll, histsPrim;
 
-void CbmAnaDielectronTaskDraw::RemoveMvdCutBins()
-{
-  for (int step = kMvd2Cut + 1 + 1; step < CbmLmvmHist::fNofAnaSteps + 1; step++) {
-    H1("fh_nof_bg_tracks")->SetBinContent(step - 2, H1("fh_nof_bg_tracks")->GetBinContent(step));
-    H1("fh_nof_el_tracks")->SetBinContent(step - 2, H1("fh_nof_el_tracks")->GetBinContent(step));
+  int i = 0;
+  for (const string& subName : subNames) {
+    TH1D* hAll  = fH.H1("hPiMom_all_" + subName);
+    latexAll[i] = latex[i] + " (" + Cbm::NumberToString(hAll->GetEntries() / fNofEvents, 2) + "/ev.)";
+    histsAll.push_back(hAll);
 
-    H1("fh_nof_mismatches")->SetBinContent(step - 2, H1("fh_nof_mismatches")->GetBinContent(step));
-    H1("fh_nof_ghosts")->SetBinContent(step - 2, H1("fh_nof_ghosts")->GetBinContent(step));
+    TH1D* hPrim  = fH.H1("hPiMom_prim_" + subName);
+    latexPrim[i] = latex[i] + " (" + Cbm::NumberToString(hPrim->GetEntries() / fNofEvents, 2) + "/ev.)";
+    histsPrim.push_back(hPrim);
+    i++;
+  }
 
-    int ny = H2("fh_source_tracks")->GetYaxis()->GetNbins();
-    for (int y = 1; y <= ny; y++) {
-      H2("fh_source_tracks")->SetBinContent(step - 2, y, H2("fh_source_tracks")->GetBinContent(step, y));
-    }
+  fH.fHM.CreateCanvas("lmvm_piMom", "lmvm_piMom", 900, 900);
+  DrawH1(histsAll, latexAll, kLinear, kLog, true, 0.45, 0.75, 0.99, 0.99, "hist");
 
-    ny = H2("fh_source_pairs")->GetYaxis()->GetNbins();
-    for (int y = 1; y <= ny; y++) {
-      H2("fh_source_pairs")->SetBinContent(step - 2, y, H2("fh_source_pairs")->GetBinContent(step, y));
-    }
-  }
+  fH.fHM.CreateCanvas("lmvm_piMomPrim", "lmvm_piMomPrim", 900, 900);
+  DrawH1(histsPrim, latexPrim, kLinear, kLog, true, 0.45, 0.75, 0.99, 0.99, "hist");
 }
 
-void CbmAnaDielectronTaskDraw::DrawBgSource2D(const string& canvasName, const string& histName,
-                                              const vector<string>& yLabels, double scale, const string& zTitle)
+void LmvmDraw::DrawBgSource2D(const string& cName, const string& hName, const vector<string>& yLabels, double scale,
+                              const string& zTitle)
 {
-  int rangeMax = CbmLmvmHist::fNofAnaSteps;
-  if (!fUseMvd) { rangeMax = CbmLmvmHist::fNofAnaSteps - 2; }
-
-  fHM->CreateCanvas(string(canvasName + "_abs").c_str(), string(canvasName + "_abs").c_str(), 900, 600);
-  TH2D* habs = (TH2D*) H2(histName)->Clone();
+  fH.fHM.CreateCanvas((cName + "_abs").c_str(), (cName + "_abs").c_str(), 900, 600);
+  TH2D* habs = fH.H2Clone(hName);
   habs->SetStats(false);
   habs->Scale(scale);
   habs->GetZaxis()->SetTitle(zTitle.c_str());
-  habs->GetXaxis()->SetRange(kReco + 1, rangeMax);
   habs->SetMarkerSize(1.4);
   DrawH2(habs, kLinear, kLinear, kLog, "text COLZ");
 
-  fHM->CreateCanvas(string(canvasName + "_percent").c_str(), string(canvasName + "_percent").c_str(), 900, 600);
-  TH2D* hperc = (TH2D*) H2(histName)->Clone();
+  fH.fHM.CreateCanvas((cName + "_perc").c_str(), (cName + "_perc").c_str(), 900, 600);
+  TH2D* hperc = fH.H2Clone(hName);
   hperc->SetStats(false);
-  Int_t nBinsX = hperc->GetNbinsX();
-  Int_t nBinsY = hperc->GetNbinsY();
-  for (Int_t x = 1; x <= nBinsX; x++) {
+  for (int x = 1; x <= hperc->GetNbinsX(); x++) {
     // calculate total number of BG tracks (pairs) for a current step
     double nbg = 0.;
-    for (Int_t y = 1; y <= nBinsY; y++) {
+    for (int y = 1; y <= hperc->GetNbinsY(); y++) {
       nbg += habs->GetBinContent(x, y);
     }
-    Double_t sc = 100. / (nbg / scale);
-    for (Int_t y = 1; y <= nBinsY; y++) {
-      Double_t val = sc * hperc->GetBinContent(x, y);
+    double sc = 100. / (nbg / scale);
+    for (int y = 1; y <= hperc->GetNbinsY(); y++) {
+      double val = sc * hperc->GetBinContent(x, y);
       hperc->SetBinContent(x, y, val);
     }
   }
   hperc->GetZaxis()->SetTitle("[%]");
-  hperc->GetXaxis()->SetLabelSize(0.06);
   hperc->GetYaxis()->SetLabelSize(0.06);
   hperc->SetMarkerColor(kBlack);
   hperc->SetMarkerSize(1.8);
-  hperc->GetXaxis()->SetRange(kReco + 1, rangeMax);
   DrawH2(hperc, kLinear, kLinear, kLinear, "text COLZ");
 
-  for (UInt_t y = 1; y <= yLabels.size(); y++) {
+  for (size_t y = 1; y <= yLabels.size(); y++) {
     hperc->GetYaxis()->SetBinLabel(y, yLabels[y - 1].c_str());
     habs->GetYaxis()->SetBinLabel(y, yLabels[y - 1].c_str());
   }
 
-  SetAnalysisStepLabels(hperc);
-  SetAnalysisStepLabels(habs);
+  SetAnalysisStepAxis(hperc);
+  SetAnalysisStepAxis(habs);
 }
 
-void CbmAnaDielectronTaskDraw::DrawBgSourceTracks()
+void LmvmDraw::DrawBgSourceTracks()
 {
   gStyle->SetPaintTextFormat("4.1f");
 
-  int rangeMax = CbmLmvmHist::fNofAnaSteps;
-  if (!fUseMvd) { rangeMax = CbmLmvmHist::fNofAnaSteps - 2; }
-
-  fHM->CreateCanvas("lmvm_nof_bg_tracks", "lmvm_nof_bg_tracks", 600, 600);
-  TH1D* hbg = (TH1D*) H1("fh_nof_bg_tracks")->Clone();
+  fH.fHM.CreateCanvas("lmvm_nofBgTracks", "lmvm_nofBgTracks", 900, 900);
+  TH1D* hbg = fH.H1Clone("hNofBgTracks");
   hbg->Scale(10);
   hbg->GetYaxis()->SetTitle("Tracks/event x10");
-  hbg->GetXaxis()->SetRange(kReco + 1, rangeMax);
   DrawH1(hbg, kLinear, kLog, "hist text0");
   hbg->SetMarkerSize(2.);
 
-  fHM->CreateCanvas("lmvm_nof_el_tracks", "lmvm_nof_el_tracks", 600, 600);
-  TH1D* hel = H1("fh_nof_el_tracks");
-  hel->GetXaxis()->SetRange(kReco + 1, rangeMax);
-  DrawH1(hel, kLinear, kLog);
+  fH.fHM.CreateCanvas("lmvm_nofSignalTracks", "lmvm_nofSignalTracks", 900, 900);
+  TH1D* hel = fH.H1("hNofSignalTracks");
+  DrawH1(hel, kLinear, kLog, "hist");
 
-  fHM->CreateCanvas("lmvm_purity", "lmvm_purity", 600, 600);
-  TH1D* purity =
-    new TH1D("purity", "purity;Analysis steps;Purity", CbmLmvmHist::fNofAnaSteps, 0., CbmLmvmHist::fNofAnaSteps);
-  purity->Divide(H1("fh_nof_bg_tracks"), H1("fh_nof_el_tracks"));
-  purity->GetXaxis()->SetRange(kReco + 1, rangeMax);
+  fH.fHM.CreateCanvas("lmvm_purity", "lmvm_purity", 900, 900);
+  TH1D* purity = new TH1D("purity", "Purity;Analysis steps;Purity", fH.fNofAnaSteps, 0., fH.fNofAnaSteps);
+  purity->Divide(fH.H1("hNofBgTracks"), fH.H1("hNofSignalTracks"));
   DrawH1(purity, kLinear, kLog, "hist text30");
   purity->SetMarkerSize(1.9);
 
-  SetAnalysisStepLabels(hbg);
-  SetAnalysisStepLabels(hel);
-  SetAnalysisStepLabels(purity);
+  SetAnalysisStepAxis(hbg);
+  SetAnalysisStepAxis(hel);
+  SetAnalysisStepAxis(purity);
 
-  DrawBgSource2D("lmvm_source_tracks_2d", "fh_source_tracks",
+  DrawBgSource2D("lmvm_bgSrcTracks_2d", "hBgSrcTracks",
                  {"#gamma", "#pi^{0}", "#pi^{#pm}", "p", "K", "e^{#pm}_{sec}", "oth."}, 100.,
                  "Tracks per event x10^{2}");
 
-
-  fHM->CreateCanvas("fh_nof_topology_pairs_gamma", "fh_nof_topology_pairs_gamma", 600, 600);
-  TH1D* htopologyGamma = (TH1D*) H1("fh_nof_topology_pairs_gamma")->Clone();
-  htopologyGamma->Scale(1. / htopologyGamma->Integral());
-  DrawH1(htopologyGamma, kLinear, kLinear);
-  htopologyGamma->SetMarkerSize(1.);
-
-  fHM->CreateCanvas("fh_nof_topology_pairs_pi0", "fh_nof_topology_pairs_pi0", 600, 600);
-  TH1D* htopologyPi0 = (TH1D*) H1("fh_nof_topology_pairs_pi0")->Clone();
-  htopologyPi0->Scale(1. / htopologyPi0->Integral());
-  DrawH1(htopologyPi0, kLinear, kLinear);
-  htopologyPi0->SetMarkerSize(1.);
+  TCanvas* c = fH.fHM.CreateCanvas("lmvm_nofTopoPairs", "lmvm_nofTopoPairs", 1600, 800);
+  c->Divide(2, 1);
+  int i = 1;
+  for (const string& p : {"gamma", "pi0"}) {
+    c->cd(i++);
+    TH1D* hTopo = fH.H1Clone("hNofTopoPairs_" + p);
+    hTopo->Scale(1. / hTopo->Integral());
+    DrawH1(hTopo, kLinear, kLinear, "hist");
+    hTopo->SetMarkerSize(1.);
+  }
 }
 
-void CbmAnaDielectronTaskDraw::DrawMismatchesAndGhosts()
+void LmvmDraw::DrawMismatchesAndGhosts()
 {
   gStyle->SetPaintTextFormat("4.1f");
-
-  int rangeMax = CbmLmvmHist::fNofAnaSteps;
-  if (!fUseMvd) { rangeMax = CbmLmvmHist::fNofAnaSteps - 2; }
-
-  TCanvas* c1 = fHM->CreateCanvas("lmvm_nof_mismatches", "lmvm_nof_mismatches", 600, 600);
+  TCanvas* c1 = fH.fHM.CreateCanvas("lmvm_nofMismatches", "lmvm_nofMismatches", 1500, 1500);
   c1->Divide(2, 2);
-  c1->cd(1);
-  TH1D* hmismatches = (TH1D*) H1("fh_nof_mismatches")->Clone();
-  hmismatches->Scale(10);
-  hmismatches->GetYaxis()->SetTitle("Mismatch tracks/event x10");
-  hmismatches->GetXaxis()->SetRange(kReco + 1, rangeMax);
-  DrawH1(hmismatches, kLinear, kLog, "hist text0");
-
-  hmismatches->SetMarkerSize(2.);
-  SetAnalysisStepLabels(hmismatches);
-  c1->cd(2);
-  TH1D* hmismatches_rich = (TH1D*) H1("fh_nof_mismatches_rich")->Clone();
-  hmismatches_rich->Scale(10);
-  hmismatches_rich->GetYaxis()->SetTitle("Mismatch tracks (RICH)/event x10");
-  hmismatches_rich->GetXaxis()->SetRange(kReco + 1, rangeMax);
-  DrawH1(hmismatches_rich, kLinear, kLog, "hist text0");
-  hmismatches_rich->SetMarkerSize(2.);
-  SetAnalysisStepLabels(hmismatches_rich);
-  c1->cd(3);
-  TH1D* hmismatches_trd = (TH1D*) H1("fh_nof_mismatches_trd")->Clone();
-  hmismatches_trd->Scale(10);
-  hmismatches_trd->GetYaxis()->SetTitle("Mismatch tracks (TRD)/event x10");
-  hmismatches_trd->GetXaxis()->SetRange(kReco + 1, rangeMax);
-  DrawH1(hmismatches_trd, kLinear, kLog, "hist text0");
-  hmismatches_trd->SetMarkerSize(2.);
-  SetAnalysisStepLabels(hmismatches_trd);
-  c1->cd(4);
-  TH1D* hmismatches_tof = (TH1D*) H1("fh_nof_mismatches")->Clone();
-  hmismatches_tof->Scale(10);
-  hmismatches_tof->GetYaxis()->SetTitle("Mismatch tracks (TOF)/event x10");
-  hmismatches_tof->GetXaxis()->SetRange(kReco + 1, rangeMax);
-  DrawH1(hmismatches_tof, kLinear, kLog, "hist text0");
-  hmismatches_tof->SetMarkerSize(2.);
-  SetAnalysisStepLabels(hmismatches_tof);
-
-  fHM->CreateCanvas("lmvm_nof_ghosts", "lmvm_nof_ghosts", 600, 600);
-  TH1D* hghosts = H1("fh_nof_ghosts");
-  hghosts->GetXaxis()->SetRange(kReco + 1, rangeMax);
-  DrawH1(hghosts, kLinear, kLog);
-  SetAnalysisStepLabels(hghosts);
-}
+  vector<string> dets {"all", "rich", "trd", "tof"};
+  for (size_t i = 0; i < dets.size(); i++) {
+    c1->cd(i + 1);
+    TH1D* h = fH.H1Clone("hNofMismatches_" + dets[i]);
+    h->Scale(10);
+    h->GetYaxis()->SetTitle(("Mismatch tracks (" + dets[i] + ")/event x10").c_str());
+    DrawH1(h, kLinear, kLog, "hist text0");
+    h->SetMarkerSize(2.);
+    SetAnalysisStepAxis(h);
+  }
+
+  fH.fHM.CreateCanvas("lmvm_nofGhosts", "lmvm_nofGhosts", 900, 900);
+  DrawH1(fH.H1("hNofGhosts"), kLinear, kLog, "hist");
+  SetAnalysisStepAxis(fH.H1("hNofGhosts"));
+}
+
+void LmvmDraw::SetAnalysisStepAxis(TH1* h)
+{
+  // Shift histogram content by 2 bins if MVD was not used
+  if (!fUseMvd) {
+    for (int step = static_cast<int>(ELmvmAnaStep::Mvd1Cut) + 1; step <= fH.fNofAnaSteps - 2; step++) {
+      if (h->IsA() == TH2D::Class()) {
+        for (int y = 1; y <= h->GetYaxis()->GetNbins(); y++) {
+          h->SetBinContent(step, y, h->GetBinContent(step + 2, y));
+        }
+      }
+      else if (h->IsA() == TH1D::Class()) {
+        h->SetBinContent(step, h->GetBinContent(step + 2));
+      }
+    }
+  }
 
-void CbmAnaDielectronTaskDraw::SetAnalysisStepLabels(TH1* h)
-{
+  int rangeMax = fH.fNofAnaSteps;
+  if (!fUseMvd) { rangeMax = rangeMax - 2; }
+  h->GetXaxis()->SetRange(static_cast<int>(ELmvmAnaStep::Reco) + 1, rangeMax);
   h->GetXaxis()->SetLabelSize(0.06);
   int x = 1;
-  for (Int_t step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) { continue; }
-    h->GetXaxis()->SetBinLabel(x, CbmLmvmHist::fAnaStepsLatex[step].c_str());
+  for (const auto step : fH.fAnaSteps) {
+    if (SkipMvd(step)) continue;
+    h->GetXaxis()->SetBinLabel(x, fH.fAnaStepLatex[static_cast<int>(step)].c_str());
     x++;
   }
 }
 
-void CbmAnaDielectronTaskDraw::DrawMinvPtAll()
-{
-  Int_t hi   = 1;
-  TCanvas* c = fHM->CreateCanvas("lmvm_fh_signal_minv_pt", "lmvm_fh_signal_minv_pt", 750, 1000);
-  c->Divide(3, 4);
-  for (int step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    c->cd(hi++);
-
-    TH2D* h = H2("fh_signal_minv_pt_" + CbmLmvmHist::fAnaSteps[step]);
-    DrawH2(h, kLinear, kLinear, kLinear, "COLZ");
-    DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.50, 0.78, 0.70, 0.9);
-  }
-}
-
-void CbmAnaDielectronTaskDraw::DrawBgSourcesVsMomentum()
-{
-  fHM->CreateCanvas("lmvm_source_mom_mc_signal", "lmvm_source_mom_mc_signal", 600, 600);
-  DrawH1(H1("fh_source_mom_mc_signal"));
-
-  int hi      = 1;
-  TCanvas* c1 = fHM->CreateCanvas("lmvm_source_mom", "lmvm_source_mom", 900, 900);
-  c1->Divide(3, 3);
-  for (Int_t step = kReco; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    c1->cd(hi++);
-    Draw1DSourceTypes("fh_source_mom_" + CbmLmvmHist::fAnaSteps[step], false);
-    DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.50, 0.90, 0.70, 0.99);
-  }
-  fHM->CreateCanvas("lmvm_source_mom_ttcut", "lmvm_source_mom_ttcut", 600, 600);
-  Draw1DSourceTypes("fh_source_mom_" + CbmLmvmHist::fAnaSteps[kTtCut], false);
-
-  hi          = 1;
-  TCanvas* c3 = fHM->CreateCanvas("lmvm_source_pt", "lmvm_source_pt", 900, 900);
-  c3->Divide(3, 3);
-  for (Int_t step = kReco; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    c3->cd(hi++);
-    Draw1DSourceTypes("fh_source_pt_" + CbmLmvmHist::fAnaSteps[step], false);
-    DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.50, 0.90, 0.70, 0.99);
-  }
-  fHM->CreateCanvas("lmvm_source_pt_ttcut", "lmvm_source_pt_ttcut", 600, 600);
-  Draw1DSourceTypes("fh_source_pt_" + CbmLmvmHist::fAnaSteps[kTtCut], false);
-
-  hi          = 1;
-  TCanvas* c2 = fHM->CreateCanvas("lmvm_opening_angle", "lmvm_opening_angle", 900, 900);
-  c2->Divide(3, 3);
-  for (Int_t step = kReco; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    //cout << "fh_opening_angle_" << step << endl;
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) continue;
-    c2->cd(hi++);
-    Draw1DSourceTypes("fh_opening_angle_" + CbmLmvmHist::fAnaSteps[step]);
-    DrawTextOnPad(CbmLmvmHist::fAnaStepsLatex[step], 0.50, 0.90, 0.70, 0.99);
-  }
-  fHM->CreateCanvas("lmvm_opening_angle_ttcut", "lmvm_opening_angle_ttcut", 600, 600);
-  Draw1DSourceTypes("fh_opening_angle_" + CbmLmvmHist::fAnaSteps[kTtCut], false);
-}
-
-void CbmAnaDielectronTaskDraw::DrawMvdCutQa()
+void LmvmDraw::DrawMvdCutQa()
 {
-  if (fUseMvd) {
-    fHM->CreateCanvas("lmvm_mvd1cut_qa", "lmvm_mvd1cut_qa", 600, 600);
-    Draw1DSourceTypes("fh_mvd1cut_qa");
-    TH1D* h1 = H1("fh_mvd1cut_qa_" + CbmLmvmHist::fSourceTypes[0]);
+  if (!fUseMvd) return;
+  TCanvas* c = fH.fHM.CreateCanvas("lmvm_mvdCutQa", "lmvm_mvd1cut_qa", 1600, 800);
+  c->Divide(2, 1);
+  int i = 1;
+  for (const string& num : {"1", "2"}) {
+    c->cd(i++);
+    DrawSrcH1("hMvdCutQa_" + num);
+    TH1D* h1 = fH.H1("hMvdCutQa_" + num + "_" + fH.fSrcNames[0]);
     h1->GetXaxis()->SetLabelSize(0.06);
     h1->GetXaxis()->SetBinLabel(1, "Correct");
     h1->GetXaxis()->SetBinLabel(2, "Wrong");
     gPad->SetLogy(false);
-
-    fHM->CreateCanvas("lmvm_mvd2cut_qa", "lmvm_mvd2cut_qa", 600, 600);
-    Draw1DSourceTypes("fh_mvd2cut_qa");
-    TH1D* h2 = H1("fh_mvd2cut_qa_" + CbmLmvmHist::fSourceTypes[0]);
-    h2->GetXaxis()->SetLabelSize(0.07);
-    h2->GetXaxis()->SetBinLabel(1, "Correct");
-    h2->GetXaxis()->SetBinLabel(2, "Wrong");
-    gPad->SetLogy(false);
+    DrawTextOnPad("MVD " + num, 0.50, 0.90, 0.70, 0.99);
   }
 }
 
-void CbmAnaDielectronTaskDraw::DrawMvdAndStsHist()
+void LmvmDraw::DrawMvdAndStsHist()
 {
   if (!fUseMvd) return;
-  TCanvas* c1 = fHM->CreateCanvas("lmvm_nofhits_mvd_sts", "lmvm_nofhits_mvd_sts", 900, 450);
+  TCanvas* c1 = fH.fHM.CreateCanvas("lmvm_nofHitsMvdSts", "lmvm_nofHitsMvdSts", 1600, 800);
   c1->Divide(2, 1);
   c1->cd(1);
-  Draw1DSourceTypes("fh_nofMvdHits");
+  DrawSrcH1("hNofMvdHits");
   c1->cd(2);
-  Draw1DSourceTypes("fh_nofStsHits");
+  DrawSrcH1("hNofStsHits");
 
-  Draw2DCut("fh_mvd1xy");
-  fHM->CreateCanvas("lmvm_mvd1r", "lmvm_mvd1r", 600, 600);
-  Draw1DSourceTypes("fh_mvd1r");
+  Draw2DCut("hMvdXY_1");
+  fH.fHM.CreateCanvas("lmvm_mvd1", "lmvm_mvd1", 900, 900);
+  DrawSrcH1("hMvdR_1");
 
-
-  Draw2DCut("fh_mvd2xy");
-  fHM->CreateCanvas("lmvm_mvd2r", "lmvm_mvd2r", 600, 600);
-  Draw1DSourceTypes("fh_mvd2r");
+  Draw2DCut("hMvdXY_2");
+  fH.fHM.CreateCanvas("lmvm_mvd2", "lmvm_mvd2", 900, 900);
+  DrawSrcH1("hMvdR_2");
 }
 
-
-void CbmAnaDielectronTaskDraw::SaveCanvasToImage()
+void LmvmDraw::SaveCanvasToImage()
 {
-  fHM->SaveCanvasToImage(fOutputDir, "png");  // fHM->SaveCanvasToImage(fOutputDir, "png;eps");
+  fH.fHM.SaveCanvasToImage(fOutputDir, "png;eps");  // fHM->SaveCanvasToImage(fOutputDir, "png;eps");
 }
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmDraw.h b/analysis/PWGDIL/dielectron/lmvm/LmvmDraw.h
old mode 100755
new mode 100644
index 63214525e80490d3667ec3af943ab79f3248b2c9..623aab423d889b541b84bc5f97cc9aa5fb1bc7a3
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmDraw.h
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmDraw.h
@@ -1,38 +1,36 @@
-/* Copyright (C) 2011-2020 UGiessen, JINR-LIT
+/* Copyright (C) 2011-2021 UGiessen, JINR-LIT
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev [committer], Elena Lebedeva */
 
-/** CbmAnaDielectronTaskDraw.h
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2011
- * @version 1.0
- **/
-
-#ifndef CBM_ANA_DIELECTRON_TASK_DRAW_H
-#define CBM_ANA_DIELECTRON_TASK_DRAW_H
-
-#include "CbmLmvmCuts.h"
-#include "CbmLmvmHist.h"
+#ifndef LMVM_DRAW_H
+#define LMVM_DRAW_H
 
 #include "TObject.h"
 
+#include <functional>
 #include <string>
 #include <vector>
 
+#include "LmvmCuts.h"
+#include "LmvmDef.h"
+#include "LmvmHist.h"
+
+//#include "CbmHistManager.h"
+
 class TH1;
 class TH2D;
 class TH1D;
 class TFile;
 class TCanvas;
-class CbmHistManager;
+//class CbmHistManager;
 
 
-class CbmAnaDielectronTaskDraw : public TObject {
+class LmvmDraw : public TObject {
 
 public:
-  CbmAnaDielectronTaskDraw();
+  LmvmDraw();
 
-  virtual ~CbmAnaDielectronTaskDraw() { ; }
+  virtual ~LmvmDraw() { ; }
 
   /**
      * \brief Implement functionality of drawing histograms in the macro
@@ -42,19 +40,19 @@ public:
      * \param[in] useMvd draw histograms related to the MVD detector?
      * \param[in] drawSig Do you want to draw significance histograms?
      **/
-  void DrawHistFromFile(const std::string& fileName, const std::string& outputDir = "", Bool_t useMvd = true,
-                        Bool_t drawSig = true);
+  void DrawHistFromFile(const std::string& fileName, const std::string& outputDir = "", bool useMvd = true,
+                        bool drawSig = true);
 
 private:
-  Int_t fNofEvents;  // number of events of current job
+  Int_t fNofEvents = 0;  // number of events of current job
 
-  Bool_t fUseMvd;            // do you want to draw histograms related to the MVD detector?
-  Bool_t fDrawSignificance;  // do you want to draw significance histograms of 1D cuts?
+  bool fUseMvd           = false;  // do you want to draw histograms related to the MVD detector?
+  bool fDrawSignificance = false;  // do you want to draw significance histograms of 1D cuts?
 
-  CbmLmvmCuts fCuts;  // electron identification and analysis cuts
+  LmvmCuts fCuts;  // electron identification and analysis cuts
 
-  CbmHistManager* fHM;     //histogram manager
-  std::string fOutputDir;  // output directory for results
+  LmvmHist fH;
+  std::string fOutputDir = "";  // output directory for results
 
   /**
      * \brief Rebin minv histograms for better drawing. Should be called after
@@ -62,33 +60,11 @@ private:
      */
   void RebinMinvHist();
 
-  /**
-     * \brief Return TH1D* pointer to the specified histogram.
-     * \param[in] name Histogram name.
-     */
-  TH1D* H1(const std::string& name);
-
-  /**
-     * \brief Return TH2D* pointer to the specified histogram.
-     * \param[in] name Histogram name.
-     */
-  TH2D* H2(const std::string& name);
-
   /**
      * \brief Save all created canvases to images.
      */
   void SaveCanvasToImage();
 
-  /**
-     * \brief Draw an integrated efficiency on a histogram (100.*h1->GetEntries()/h2->GetEntries()).
-     * Histogram must be drawn in advance.
-     * \param[in] h1 Pointer to the first histogram.
-     * \param[in] h2 Pointer to the second histogram.
-     * \param[in] xPos X position of the text in absolute coordinates.
-     * \param[in] yPos Y position of the text in absolute coordinates.
-     */
-  void DrawEfficiencyOnHist(TH1* h1, TH1* h2, Double_t xPos, Double_t yPos);
-
   /**
      * Produce 1D significance histogram Significance=S/sqrt(S+BG).
      * \param[in] s Histogram with signal.
@@ -96,138 +72,58 @@ private:
      * \param[in] name Name of new significance histogram.
      * \param[in] option Could be "right" or "left".
      */
-  TH1D* CreateSignificanceH1D(TH1D* s, TH1D* bg, const std::string& name, const std::string& option);
+  TH1D* CreateSignificanceH1(TH1D* s, TH1D* bg, const std::string& name, const std::string& option);
 
   /**
      * Produce 2D significance histogram Significance=S/sqrt(S+BG).
      */
-  TH2D* CreateSignificanceH2D(TH2D* signal, TH2D* bg, const std::string& name, const std::string& title);
-
-  /**
-     * \brief Fit signal histogram using Fit("gaus").
-     * Calculate S/BG ratio in 2 sigma region.
-     * Print summary table of the efficiency, S/BG, sigma etc for each step in cout.
-     * \param[in] step Analysis step.
-     */
-  void SOverBg(CbmLmvmAnalysisSteps step);
-
-  /**
-     * Calculates S/BG ratio for each step of the analysis
-     * using SOverBg method.
-     */
-  void SOverBgAll();
-
-  /**
-     * Draw Pt vs. Y distribution of signal for one step.
-     * Print integrated efficiency using DrawEfficiencyOnHist method.
-     * \param[in] step Analysis step.
-     */
-  void DrawPtYDistribution(int step, bool drawAnaStep = true);
-
-  /**
-     * Draw Pt vs. Y distributions of signal for all steps
-     * using DrawPtYDistribution method.
-     */
-  void DrawPtYDistributionAll();
-
-  /**
-     * Draw Rapidity distributions of signal for all steps
-     */
-  void DrawRapidityDistributionAll();
-
-  /**
-     * \brief Draw efficiency in dependence on Pt and Rapidity.
-     * Efficiency is normalized to the previous step.
-     * \param[in] step Analysis step.
-     */
-  void DrawPtYEfficiency(int step, bool drawAnaStep = true);
+  TH2D* CreateSignificanceH2(TH2D* signal, TH2D* bg, const std::string& name, const std::string& title);
 
-  /**
-     * Draw efficiency in dependence on Pt and Rapidity of signal for all steps.
-     */
-  void DrawPtYEfficiencyAll();
+  void DrawAnaStepMany(const std::string& cName, std::function<void(ELmvmAnaStep)> drawFunc);
 
-  /**
-     * Draw momentum distribution of signal for all steps.
-     */
-  void DrawMomentumDistributionAll();
+  void DrawPtY(ELmvmAnaStep step);
+  void DrawRapidity(ELmvmAnaStep step);
+  void DrawPtYEfficiency(ELmvmAnaStep step);
+  void DrawMinvSBg(ELmvmAnaStep step);
+  void DrawMinvBgPairSrc(ELmvmAnaStep step);
+  void DrawMinvMatching(ELmvmAnaStep step);
+  void DrawSrcAnaStepEpEmH1(const std::string& cName, ELmvmAnaStep step);
 
-  /**
-     * Draw efficiency vs. momentum of pair for all steps.
-     */
-  void DrawMomentumEfficiencyAll();
+  void DrawMisc();
 
-  /**
-     * Draw Mother PDG
-     */
-  void DrawMotherPdg();
-
-  /**
-    * Draw PP Angle hist for MC signal
-    */
-  void DrawPPAngleMCSignal();
-
-  // Draw distribution and significance of 1D analysis cut
-  void Draw1DSourceTypes(const std::string& hName, bool doScale = true);
+  void DrawSrcH1(const std::string& hist, ELmvmAnaStep step = ELmvmAnaStep::Undefined, bool doScale = true);
+  void DrawAnaStepH1(const std::string& hist, bool logy = false);
 
-  void Draw1DCut(const std::string& hName, const std::string& sigOption, double cutValue = -999999.);
+  void Draw1DCut(const std::string& hist, const std::string& sigOption, double cut = -999999.);
+  void Draw2DCut(const std::string& hist, double cutCrossX = -999999., double cutCrossY = -999999.);
+  void DrawCuts();
 
-  void DrawElPiMomHis();
+  void DrawSrcBgPairs(ELmvmAnaStep step, bool inPercent, bool drawAnaStep = true);
+  void DrawSrcBgPairsAll();
 
-  void Draw2DCutTriangle(double xCross, double yCross);
+  void DrawMomAccEpEm();
 
-  void Draw2DCut(const std::string& hist, double cutCrossX = -999999., double cutCrossY = -999999.);
+  void DrawPiMom();
 
-  void DrawCutDistributions();
+  void Draw2DCutTriangle(double xCr, double yCr);
 
   void DrawMismatchesAndGhosts();
 
-  void DrawSourcesBgPairsEpEm(int step, bool inPercent, bool drawAnaStep = true);
-
-  /**
-     * Draw sources of BG pairs for all steps.
-     */
-  void DrawSourcesBgPairsAll();
-
   void DrawGammaVertex();
 
-  void Draw1DHistoForEachAnalysisStep(const std::string& hist, Bool_t logy = false);
-
-  //Draw Invariant mass distributions after each cut
-  void DrawMinvForEachAnalysisStep();
+  void DrawMinvAll();
 
-  void DrawMinvSandBg(int step);
+  void DrawBgSource2D(const std::string& cName, const std::string& hName, const std::vector<std::string>& yLabels,
+                      double scale, const std::string& zTitle);
 
-  // Invariant mass distribution after each cut for source of BG
-  void DrawMinvSandBgAll();
 
-
-  void DrawMinvSource(int step, bool drawAnaStep = true);
-
-  // Invariant mass distribution after each cut for source of BG
-  void DrawMinvSourceAll();
-
-  /*
-     * \brief Remove MVD bins from histograms if MVD detector was not used.
-     */
-  void RemoveMvdCutBins();
-
-
-  void DrawBgSource2D(const std::string& canvasName, const std::string& histName,
-                      const std::vector<std::string>& yLabels, double scale, const std::string& zTitle);
-
-
-  //SOURCE TRACKS
   void DrawBgSourceTracks();
 
-  /**
-     * \brief Set labels of X axis usinf analysis steps names.
-     */
-  void SetAnalysisStepLabels(TH1* h);
+  void SetAnalysisStepAxis(TH1* h);
 
-  void DrawMinvPtAll();
+  void DrawMinvPt(ELmvmAnaStep step);
 
-  void DrawBgSourcesVsMomentum();
+  void DrawSrcAnaStepH1(const std::string& hName, ELmvmAnaStep step);
 
   void DrawMvdCutQa();
 
@@ -235,16 +131,12 @@ private:
 
   void DrawPmtXY();
 
-  // Draw Likelihood vs Momentum
-  void DrawMomLikeHist();
-
-  // Draw yield of electrons and positrons vs. momentum
-  void DrawSingleParticleYield();
+  bool SkipMvd(ELmvmAnaStep step);
 
-  CbmAnaDielectronTaskDraw(const CbmAnaDielectronTaskDraw&);
-  CbmAnaDielectronTaskDraw& operator=(const CbmAnaDielectronTaskDraw&);
+  LmvmDraw(const LmvmDraw&);
+  LmvmDraw& operator=(const LmvmDraw&);
 
-  ClassDef(CbmAnaDielectronTaskDraw, 1);
+  ClassDef(LmvmDraw, 1);
 };
 
 #endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmDrawAll.cxx b/analysis/PWGDIL/dielectron/lmvm/LmvmDrawAll.cxx
index c7043d40e96b9f202282acccaab8ea788b09ebdc..b60d087f20a597d0936a6f9e3922021b9138ac3f 100644
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmDrawAll.cxx
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmDrawAll.cxx
@@ -2,18 +2,14 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Elena Lebedeva, Andrey Lebedev, Semen Lebedev [committer] */
 
-/** CbmAnaDielectronTaskDrawAll.cxx
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2011
- * @version 2.0
- **/
-
-#include "CbmAnaDielectronTaskDrawAll.h"
+#include "LmvmDrawAll.h"
 
 #include "CbmDrawHist.h"
 #include "CbmHistManager.h"
 #include "CbmUtils.h"
 
+#include "Logger.h"
+
 #include "TCanvas.h"
 #include "TClass.h"
 #include "TEllipse.h"
@@ -34,82 +30,48 @@
 #include <iostream>
 #include <string>
 
+#include "LmvmDef.h"
+
 using namespace std;
 using namespace Cbm;
 
-void CbmAnaDielectronTaskDrawAll::DrawHistosFromFile(const string& fileNameInmed, const string& fileNameQgp,
-                                                     const string& fileNameOmega, const string& fileNamePhi,
-                                                     const string& fileNameOmegaDalitz, const string& outputDir,
-                                                     Bool_t useMvd)
+LmvmHist* LmvmDrawAll::H(ELmvmSignal signal) { return fH[static_cast<int>(signal)]; }
+
+void LmvmDrawAll::DrawHistFromFile(const string& fileInmed, const string& fileQgp, const string& fileOmega,
+                                   const string& filePhi, const string& fileOmegaD, const string& outputDir,
+                                   bool useMvd)
 {
+  SetDefaultDrawStyle();
   fOutputDir = outputDir;
   fUseMvd    = useMvd;
-  fDrawQgp   = (fileNameQgp != "");
-
-  nRebin = 100;
 
-  //SetDefaultDrawStyle();
-  vector<string> fileNames = {fileNameInmed, fileNameQgp, fileNameOmega, fileNamePhi, fileNameOmegaDalitz};
+  // order in vector is important, see ELmvmSignal enum.
+  vector<string> fileNames {fileInmed, fileQgp, fileOmega, filePhi, fileOmegaD};
 
-  /// Save old global file and folder pointer to avoid messing with FairRoot
   TFile* oldFile     = gFile;
   TDirectory* oldDir = gDirectory;
 
-  fHM.resize(fNofSignals);
-  for (int i = 0; i < fNofSignals; i++) {
-    fHM[i] = new CbmHistManager();
-    if (!fDrawQgp && i == kQgp) continue;
+  fH.resize(fHMean.fNofSignals);
+  for (size_t i = 0; i < fH.size(); i++) {
+    fH[i]       = new LmvmHist();
     TFile* file = new TFile(fileNames[i].c_str());
-    fHM[i]->ReadFromFile(file);
-    Int_t nofEvents = (int) H1(i, "fh_event_number")->GetEntries();
+    fH[i]->fHM.ReadFromFile(file);
+    int nofEvents = (int) fH[i]->H1("hEventNumber")->GetEntries();
     //fHM[i]->ScaleByPattern(".*", 1. / nofEvents); // TODO: keep this commented?
-    cout << "nofEvents = " << nofEvents << endl;
+    LOG(info) << "Signal:" << fHMean.fSignalNames[i] << " nofEvents:" << nofEvents << endl;
   }
 
-  // index: AnalysisSteps
-  fh_mean_bg_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_eta_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_pi0_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_sum_s_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_eta_minv_pt.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_pi0_minv_pt.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_sbg_vs_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combPairsPM_sameEvent_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combPairsPP_sameEvent_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combPairsMM_sameEvent_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combPairsPM_mixedEvents_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combPairsPP_mixedEvents_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combPairsMM_mixedEvents_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combBg_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combBg_raw_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combBg_assemb_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combBg_GeomMeanSame_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combBg_GeomMeanMixed_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combBg_k_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combSignalNpm_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combSignalNpm_assemb_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combSignalBCoc_assemb_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combBg_errProp_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combSignal_errProp_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_combSBg_vs_minv.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_nof_plutoElectrons.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_nof_plutoPositrons.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_nof_urqmdElectrons.resize(CbmLmvmHist::fNofAnaSteps);
-  fh_mean_nof_urqmdPositrons.resize(CbmLmvmHist::fNofAnaSteps);
-
-  FillMeanHist();  // TODO: Add method RebinHist() after this to rebin all histograms there to have better overview??
-  FillSumSignalsHist();
+  CreateMeanHistAll();
   CalcCutEffRange(0.0, 0.2);
   CalcCutEffRange(0.2, 0.6);
   CalcCutEffRange(0.6, 1.2);
   CalcCombBGHistos();
   SBgRangeAll();
-  DrawSBgSignals();
+  DrawSBgResults();
   DrawMinvAll();
   DrawMinvCombSignalAndBg();
   DrawMinvPtAll();
   DrawSBgVsMinv();
-  //CompareSTSversions();
   SaveHist();
   SaveCanvasToImage();
 
@@ -118,1916 +80,673 @@ void CbmAnaDielectronTaskDrawAll::DrawHistosFromFile(const string& fileNameInmed
   gDirectory = oldDir;
 }
 
-
-TH1D* CbmAnaDielectronTaskDrawAll::H1(int signalType, const string& name) { return (TH1D*) fHM[signalType]->H1(name); }
-
-TH2D* CbmAnaDielectronTaskDrawAll::H2(int signalType, const string& name) { return (TH2D*) fHM[signalType]->H1(name); }
-
-TH1D* CbmAnaDielectronTaskDrawAll::GetCoctailMinv(CbmLmvmAnalysisSteps step)
+int LmvmDrawAll::GetNofTotalEvents()
 {
-  TH1D* sInmed = (TH1D*) H1(kInmed, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH1D* sQgp   = (fDrawQgp) ? (TH1D*) H1(kQgp, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone() : nullptr;
-  TH1D* sOmega = (TH1D*) H1(kOmega, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH1D* sPhi   = (TH1D*) H1(kPhi, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH1D* sEta   = fh_mean_eta_minv[step];
-  TH1D* sPi0   = fh_mean_pi0_minv[step];
-  TH1D* sOmegaDalitz = (TH1D*) H1(kOmegaD, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-
-  Int_t nofEvents = 0;
-  for (int i = 0; i < fNofSignals; i++) {
-    if (!fDrawQgp && i == kQgp) continue;
-    Int_t nofEventsS = (int) H1(i, "fh_event_number")->GetEntries();
-    if (i == 0) sInmed->Scale(1. / nofEventsS);
-    if (i == 1) sQgp->Scale(1. / nofEventsS);
-    if (i == 2) sOmega->Scale(1. / nofEventsS);
-    if (i == 3) sPhi->Scale(1. / nofEventsS);
-    if (i == 4) sOmegaDalitz->Scale(1. / nofEventsS);
-
-    nofEvents += nofEventsS;
-    if (i == 4) cout << "GetCoctailMinv(...): nofEvents = " << nofEvents << endl;
+  int nofEvents = 0;
+  for (ELmvmSignal sig : fHMean.fSignals) {
+    nofEvents += H(sig)->H1("hEventNumber")->GetEntries();
   }
-
-  TH1D* coctail = (TH1D*) sInmed->Clone();
-  if (fDrawQgp) coctail->Add(sQgp);
-  coctail->Add(sOmega);
-  coctail->Add(sPhi);
-  coctail->Add(sEta);
-  coctail->Add(sPi0);
-  coctail->Add(sOmegaDalitz);
-
-  //coctail->Scale(1. / (fNofSignals + 2));	// '+2' because except signals there are two particles (eta and pi0)
-
-  return coctail;
+  return nofEvents;
 }
 
-void CbmAnaDielectronTaskDrawAll::DrawMinvAll()
+template<class T>
+void LmvmDrawAll::CreateMeanHist(const string& name, int nofEvents)
 {
-  fHM[0]->CreateCanvas("minv_all_mc", "minv_all_mc", 800, 800);
-  DrawMinv(kMc);
-
-  fHM[0]->CreateCanvas("minv_all_acc", "minv_all_acc", 800, 800);
-  DrawMinv(kAcc);
-
-  fHM[0]->CreateCanvas("minv_all_ptcut", "minv_all_ptcut", 800, 800);
-  DrawMinv(kPtCut);
-
-  fHM[0]->CreateCanvas("minv_all_ttcut", "minv_all_ttcut", 800, 800);
-  DrawMinv(kTtCut);
-
-  fHM[0]->CreateCanvas("minv_all_elid", "minv_all_elid", 800, 800);
-  DrawMinv(kElId);
+  for (ELmvmSignal sig : fHMean.fSignals) {
+    if (static_cast<int>(sig) == 0) fHMean.fHM.Add(name, static_cast<T*>(H(sig)->GetObject(name)->Clone()));
+    else
+      static_cast<T*>(fHMean.GetObject(name))->Add(static_cast<T*>(H(sig)->GetObject(name)->Clone()));
+  }
+  static_cast<T*>(fHMean.GetObject(name))->Scale(1. / (double) nofEvents);
 }
 
-void CbmAnaDielectronTaskDrawAll::DrawMinv(CbmLmvmAnalysisSteps step)
+void LmvmDrawAll::CreateMeanHistAll()
 {
-  TH1D* sInmed = (TH1D*) H1(kInmed, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH1D* sQgp   = (fDrawQgp) ? (TH1D*) H1(kQgp, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone() : nullptr;
-  TH1D* sOmega = (TH1D*) H1(kOmega, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH1D* sPhi   = (TH1D*) H1(kPhi, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH1D* bg     = (TH1D*) fh_mean_bg_minv[step]->Clone();
-  TH1D* sEta   = (TH1D*) fh_mean_eta_minv[step]->Clone();
-  TH1D* sPi0   = (TH1D*) fh_mean_pi0_minv[step]->Clone();
-  TH1D* sOmegaDalitz = (TH1D*) H1(kOmegaD, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-
-  Int_t nofEvents = 0;
-  for (int i = 0; i < fNofSignals; i++) {
-    if (!fDrawQgp && i == kQgp) continue;
-    Int_t nofEventsS = (int) H1(i, "fh_event_number")->GetEntries();
-    if (i == 0) sInmed->Scale(1. / nofEventsS);
-    if (i == 1) sQgp->Scale(1. / nofEventsS);
-    if (i == 2) sOmega->Scale(1. / nofEventsS);
-    if (i == 3) sPhi->Scale(1. / nofEventsS);
-    if (i == 4) sOmegaDalitz->Scale(1. / nofEventsS);
-
-    nofEvents += nofEventsS;
-    cout << "DrawMinv(...): nofEvents = " << nofEvents << endl;
-  }
+  int nofEvents = GetNofTotalEvents();
 
-  TH1D* coctail = GetCoctailMinv(step);
-
-  TH1D* sbg = (TH1D*) bg->Clone();
-  sbg->Add(sInmed);  // Why here not added coctail instead (is same procedure)?
-  if (fDrawQgp) sbg->Add(sQgp);
-  sbg->Add(sOmega);
-  sbg->Add(sPhi);
-  sbg->Add(sEta);
-  sbg->Add(sPi0);
-  sbg->Add(sOmegaDalitz);
-
-  sbg->Rebin(nRebin);
-  coctail->Rebin(nRebin);
-  bg->Rebin(nRebin);
-  sPi0->Rebin(nRebin);
-  sEta->Rebin(nRebin);
-  sOmegaDalitz->Rebin(nRebin);
-  sOmega->Rebin(nRebin);
-  sInmed->Rebin(nRebin);
-  if (fDrawQgp) sQgp->Rebin(nRebin);
-  sPhi->Rebin(nRebin);
-
-  double binWidth = sbg->GetBinWidth(1);
-  sbg->Scale(1. / binWidth);
-  coctail->Scale(1. / binWidth);
-  bg->Scale(1. / binWidth);
-  sPi0->Scale(1. / binWidth);
-  sEta->Scale(1. / binWidth);
-  sOmegaDalitz->Scale(1. / binWidth);
-  sOmega->Scale(1. / binWidth);
-  sInmed->Scale(1. / binWidth);
-  if (fDrawQgp) sQgp->Scale(1. / binWidth);
-  sPhi->Scale(1. / binWidth);
-
-  sbg->SetMinimum(5e-8);
-  sbg->SetMaximum(2e-2);
-  sbg->GetXaxis()->SetRangeUser(0, 2.);
-  bg->GetXaxis()->SetRangeUser(0, 2.);
-  coctail->GetXaxis()->SetRangeUser(0, 2.);
-  sPi0->GetXaxis()->SetRangeUser(0, 2.);
-  sEta->GetXaxis()->SetRangeUser(0, 2.);
-  sOmegaDalitz->GetXaxis()->SetRangeUser(0, 2.);
-  sOmega->GetXaxis()->SetRangeUser(0, 2.);
-  sInmed->GetXaxis()->SetRangeUser(0, 2.);
-  if (fDrawQgp) sQgp->GetXaxis()->SetRangeUser(0, 2.);
-  sPhi->GetXaxis()->SetRangeUser(0, 2.);
-
-  /*
-    if (step == kMc) {
-        DrawH1({coctail, sPi0, sEta, sOmegaDalitz, sOmega, sInmed, sQgp, sPhi},
-                {"", "", "", "", "", "", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99);
-    } else {
-        DrawH1({sbg, bg, coctail, sPi0, sEta, sOmegaDalitz, sOmega, sInmed, sQgp, sPhi},
-                {"", "", "", "", "", "", "", "", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99);
+  for (auto step : fHMean.fAnaSteps) {
+    for (auto src : {ELmvmSrc::Bg, ELmvmSrc::Eta, ELmvmSrc::Pi0}) {
+      CreateMeanHist<TH1D>(fHMean.GetName("hMinv", src, step), nofEvents);
+      CreateMeanHist<TH2D>(fHMean.GetName("hMinvPt", src, step), nofEvents);
     }
-  */
 
-  if (step == kMc) {
-    if (fDrawQgp) {
-      DrawH1({coctail, sPi0, sEta, sOmegaDalitz, sOmega, sInmed, sQgp, sPhi}, {"", "", "", "", "", "", "", ""}, kLinear,
-             kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-    }
-    else {
-      DrawH1({coctail, sPi0, sEta, sOmegaDalitz, sOmega, sInmed, sPhi}, {"", "", "", "", "", "", ""}, kLinear, kLog,
-             false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-    }
-  }
-  else {
-    if (fDrawQgp) {
-      DrawH1({sbg, bg, coctail, sPi0, sEta, sOmegaDalitz, sOmega, sInmed, sQgp, sPhi},
-             {"", "", "", "", "", "", "", "", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-    }
-    else {
-      DrawH1({sbg, bg, coctail, sPi0, sEta, sOmegaDalitz, sOmega, sInmed, sPhi}, {"", "", "", "", "", "", "", "", ""},
-             kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
+    for (const string& comb : {"PM", "PP", "MM"}) {
+      for (const string& ev : {"sameEv", "mixedEv"}) {
+        // TODO: @Cornelius implement Proper scaling, nofEvents or nofMixedEvents
+        CreateMeanHist<TH2D>(fHMean.GetName("hMinvComb" + comb + "_" + ev, step), nofEvents);
+      }
     }
   }
-
-  string yTitle = "dN/dM_{ee} [GeV/c^{2}]^{-1}";
-  coctail->GetYaxis()->SetTitle(yTitle.c_str());
-  sbg->GetYaxis()->SetTitle(yTitle.c_str());
-  coctail->GetYaxis()->SetLabelSize(0.05);
-  sbg->GetYaxis()->SetLabelSize(0.05);
-
-  sInmed->SetFillColor(kMagenta - 3);
-  sInmed->SetLineColor(kMagenta - 2);
-  sInmed->SetLineStyle(0);
-  sInmed->SetLineWidth(3);
-  sInmed->SetFillStyle(3344);
-
-  if (fDrawQgp) {
-    sQgp->SetFillColor(kOrange - 2);
-    sQgp->SetLineColor(kOrange - 3);
-    sQgp->SetLineStyle(0);
-    sQgp->SetLineWidth(3);
-    sQgp->SetFillStyle(3444);
-  }
-
-  sOmega->SetFillColor(kOrange + 7);
-  sOmega->SetLineColor(kOrange + 4);
-  sOmega->SetLineStyle(0);
-  sOmega->SetLineWidth(2);
-
-  sPhi->SetFillColor(kAzure + 2);
-  sPhi->SetLineColor(kAzure + 3);
-  sPhi->SetLineStyle(0);
-  sPhi->SetLineWidth(2);
-  sPhi->SetFillStyle(3112);
-  gStyle->SetHatchesLineWidth(1);
-  gStyle->SetHatchesSpacing(1.);
-
-
-  bg->SetFillColor(kGray);
-  bg->SetLineColor(kBlack);
-  bg->SetLineStyle(0);
-  bg->SetLineWidth(1);
-
-
-  sEta->SetFillColor(kRed - 4);
-  sEta->SetLineColor(kRed + 2);
-  sEta->SetLineStyle(0);
-  sEta->SetLineWidth(2);
-
-
-  sPi0->SetFillColor(kGreen - 3);
-  sPi0->SetLineColor(kGreen + 3);
-  sPi0->SetLineStyle(0);
-  sPi0->SetLineWidth(2);
-
-  sOmegaDalitz->SetFillColor(kCyan + 2);
-  sOmegaDalitz->SetLineColor(kCyan + 4);
-  sOmegaDalitz->SetLineStyle(0);
-  sOmegaDalitz->SetLineWidth(2);
-
-  sbg->SetFillColor(kBlack);
-  sbg->SetLineColor(kBlack);
-  sbg->SetLineStyle(0);
-  sbg->SetLineWidth(1);
-
-  coctail->SetLineColor(kRed + 2);
-  coctail->SetFillStyle(0);
-  coctail->SetLineWidth(3);
-
-  if (step != kMc) {
-    TLegend* legend = new TLegend(0.7, 0.6, 0.99, 0.99);
-    legend->SetFillColor(kWhite);
-    legend->SetTextSize(0.04);
-    legend->AddEntry(sOmega, "#omega #rightarrow e^{+}e^{-}", "f");
-    legend->AddEntry(sOmegaDalitz, "#omega #rightarrow #pi^{0}e^{+}e^{-}", "f");
-    legend->AddEntry(sPhi, "#phi #rightarrow e^{+}e^{-}", "f");
-    legend->AddEntry(sInmed, "in-medium #rho", "f");
-    if (fDrawQgp) legend->AddEntry(sQgp, "QGP radiation", "f");
-    legend->AddEntry(sEta, "#eta #rightarrow #gammae^{+}e^{-}", "f");
-    legend->AddEntry(sPi0, "#pi^{0} #rightarrow #gammae^{+}e^{-}", "f");
-    legend->AddEntry(coctail, "Cocktail", "f");
-    legend->AddEntry(bg, "Background", "f");
-    legend->AddEntry(sbg, "Cocktail+BG", "f");
-    legend->Draw();
-  }
-  else {
-    TLegend* legend = new TLegend(0.7, 0.7, 0.99, 0.99);
-    legend->SetFillColor(kWhite);
-    legend->SetTextSize(0.04);
-    legend->AddEntry(sOmega, "#omega #rightarrow e^{+}e^{-}", "f");
-    legend->AddEntry(sOmegaDalitz, "#omega #rightarrow #pi^{0}e^{+}e^{-}", "f");
-    legend->AddEntry(sPhi, "#phi #rightarrow e^{+}e^{-}", "f");
-    legend->AddEntry(sInmed, "in-medium #rho", "f");
-    if (fDrawQgp) legend->AddEntry(sQgp, "QGP radiation", "f");
-    legend->AddEntry(sEta, "#eta #rightarrow #gammae^{+}e^{-}", "f");
-    legend->AddEntry(sPi0, "#pi^{0} #rightarrow #gammae^{+}e^{-}", "f");
-    legend->AddEntry(coctail, "Cocktail", "f");
-    legend->Draw();
-  }
-  gPad->SetLogy(true);
 }
 
-void CbmAnaDielectronTaskDrawAll::DrawMinvCombSignalAndBg()
-{
-  /*******************************************************************************
- * MIND: 																	    *
- * 'B' (capital) stands for same event, 'b' (not-capital) for mixed events!    	*
- *																			  	*
- * Order of draw functions:													  	*
- * 1) Yields of single e- and e+ per event					  				  	*
- * 2) e+e- | e+e+ | e-e- pairs from same and mixed events					  	*
- * 3) geometric mean (conv. and assembled)									  	*
- * 4) B_comb with MC BG and B+-												  	*
- * 5) k factor																  	*
- * 6) comb. signal															  	*
- *******************************************************************************/
-
-  double yMin   = 1e-7;
-  double yMax   = 5e-2;
-  string yTitle = "dN/dM_{ee} [GeV/c^{2}]^{-1}";
-  string xTitle = "M_{ee} [GeV/c^2]";
-
-  bool setMinMax = true;
-
-  // Rebin factor for single particle and CB histograms. Their nBin in Task.cxx differ from each other
-
-  /* 1) draw number of e+ and e- per event */
-  // vs. momentum
-  TH1D* nPlutoElMc    = (TH1D*) fh_mean_nof_plutoElectrons[kMc]->Clone();
-  TH1D* nPlutoPosMc   = (TH1D*) fh_mean_nof_plutoPositrons[kMc]->Clone();
-  TH1D* nPlutoElAcc   = (TH1D*) fh_mean_nof_plutoElectrons[kAcc]->Clone();
-  TH1D* nPlutoPosAcc  = (TH1D*) fh_mean_nof_plutoPositrons[kAcc]->Clone();
-  TH1D* nPlutoElReco  = (TH1D*) fh_mean_nof_plutoElectrons[kReco]->Clone();
-  TH1D* nPlutoPosReco = (TH1D*) fh_mean_nof_plutoPositrons[kReco]->Clone();
-  TH1D* nPlutoElElid  = (TH1D*) fh_mean_nof_plutoElectrons[kElId]->Clone();
-  TH1D* nPlutoPosElid = (TH1D*) fh_mean_nof_plutoPositrons[kElId]->Clone();
-  TH1D* nPlutoElTt    = (TH1D*) fh_mean_nof_plutoElectrons[kTtCut]->Clone();
-  TH1D* nPlutoPosTt   = (TH1D*) fh_mean_nof_plutoPositrons[kTtCut]->Clone();
-  TH1D* nPlutoElPt    = (TH1D*) fh_mean_nof_plutoElectrons[kPtCut]->Clone();
-  TH1D* nPlutoPosPt   = (TH1D*) fh_mean_nof_plutoPositrons[kPtCut]->Clone();
-  TH1D* nUrqmdElMc    = (TH1D*) fh_mean_nof_urqmdElectrons[kMc]->Clone();
-  TH1D* nUrqmdPosMc   = (TH1D*) fh_mean_nof_urqmdPositrons[kMc]->Clone();
-  TH1D* nUrqmdElAcc   = (TH1D*) fh_mean_nof_urqmdElectrons[kAcc]->Clone();
-  TH1D* nUrqmdPosAcc  = (TH1D*) fh_mean_nof_urqmdPositrons[kAcc]->Clone();
-  TH1D* nUrqmdElReco  = (TH1D*) fh_mean_nof_urqmdElectrons[kReco]->Clone();
-  TH1D* nUrqmdPosReco = (TH1D*) fh_mean_nof_urqmdPositrons[kReco]->Clone();
-  TH1D* nUrqmdElElid  = (TH1D*) fh_mean_nof_urqmdElectrons[kElId]->Clone();
-  TH1D* nUrqmdPosElid = (TH1D*) fh_mean_nof_urqmdPositrons[kElId]->Clone();
-  TH1D* nUrqmdElTt    = (TH1D*) fh_mean_nof_urqmdElectrons[kTtCut]->Clone();
-  TH1D* nUrqmdPosTt   = (TH1D*) fh_mean_nof_urqmdPositrons[kTtCut]->Clone();
-  TH1D* nUrqmdElPt    = (TH1D*) fh_mean_nof_urqmdElectrons[kPtCut]->Clone();
-  TH1D* nUrqmdPosPt   = (TH1D*) fh_mean_nof_urqmdPositrons[kPtCut]->Clone();
-
-  double min1 = 1e-9;
-  double max1 = 10;
-  nPlutoElMc->SetMinimum(min1);
-  nPlutoElMc->SetMaximum(max1);
-  nPlutoPosMc->SetMinimum(min1);
-  nPlutoPosMc->SetMaximum(max1);
-  nPlutoElAcc->SetMinimum(min1);
-  nPlutoElAcc->SetMaximum(max1);
-  nPlutoPosAcc->SetMinimum(min1);
-  nPlutoPosAcc->SetMaximum(max1);
-  nPlutoElReco->SetMinimum(min1);
-  nPlutoElReco->SetMaximum(max1);
-  nPlutoPosReco->SetMinimum(min1);
-  nPlutoPosReco->SetMaximum(max1);
-  nPlutoElElid->SetMinimum(min1);
-  nPlutoElElid->SetMaximum(max1);
-  nPlutoPosElid->SetMinimum(min1);
-  nPlutoPosElid->SetMaximum(max1);
-  nPlutoElTt->SetMinimum(min1);
-  nPlutoElTt->SetMaximum(max1);
-  nPlutoPosTt->SetMinimum(min1);
-  nPlutoPosTt->SetMaximum(max1);
-  nPlutoElPt->SetMinimum(min1);
-  nPlutoElPt->SetMaximum(max1);
-  nPlutoPosPt->SetMinimum(min1);
-  nPlutoPosPt->SetMaximum(max1);
-
-  nUrqmdElMc->SetMinimum(min1);
-  nUrqmdElMc->SetMaximum(max1);
-  nUrqmdPosMc->SetMinimum(min1);
-  nUrqmdPosMc->SetMaximum(max1);
-  nUrqmdElAcc->SetMinimum(min1);
-  nUrqmdElAcc->SetMaximum(max1);
-  nUrqmdPosAcc->SetMinimum(min1);
-  nUrqmdPosAcc->SetMaximum(max1);
-  nUrqmdElReco->SetMinimum(min1);
-  nUrqmdElReco->SetMaximum(max1);
-  nUrqmdPosReco->SetMinimum(min1);
-  nUrqmdPosReco->SetMaximum(max1);
-  nUrqmdElElid->SetMinimum(min1);
-  nUrqmdElElid->SetMaximum(max1);
-  nUrqmdPosElid->SetMinimum(min1);
-  nUrqmdPosElid->SetMaximum(max1);
-  nUrqmdElTt->SetMinimum(min1);
-  nUrqmdElTt->SetMaximum(max1);
-  nUrqmdPosTt->SetMinimum(min1);
-  nUrqmdPosTt->SetMaximum(max1);
-  nUrqmdElPt->SetMinimum(min1);
-  nUrqmdElPt->SetMaximum(max1);
-  nUrqmdPosPt->SetMinimum(min1);
-  nUrqmdPosPt->SetMaximum(max1);
-
-  nPlutoElMc->GetYaxis()->SetTitle("per event");
-  nPlutoElMc->SetTitle("PLUTO electrons");
-  nUrqmdElMc->GetYaxis()->SetTitle("per event");
-  nUrqmdElMc->SetTitle("UrQMD electrons");
-
-  fHM[0]->CreateCanvas("fh_nof_plutoElPos", "fh_nof_plutoElPos", 800, 800);
-  DrawH1({nPlutoElMc, nPlutoPosMc, nPlutoElAcc, nPlutoPosAcc, nPlutoElReco, nPlutoPosReco, nPlutoElElid, nPlutoPosElid,
-          nPlutoElTt, nPlutoPosTt, nPlutoElPt, nPlutoPosPt},
-         {"", "", "", "", "", "", "", "", "", "", "", ""}, kLinear, kLog, false, 0.9, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legendNofPP = new TLegend(0.65, 0.6, 0.88, 0.93);
-  legendNofPP->SetFillColor(kWhite);
-  legendNofPP->AddEntry(nPlutoElMc, "electrons kMc");
-  legendNofPP->AddEntry(nPlutoPosMc, "positrons kMc");
-  legendNofPP->AddEntry(nPlutoElAcc, "electrons kAcc");
-  legendNofPP->AddEntry(nPlutoPosAcc, "positrons kAcc");
-  legendNofPP->AddEntry(nPlutoElReco, "electrons kReco");
-  legendNofPP->AddEntry(nPlutoPosReco, "positrons kReco");
-  legendNofPP->AddEntry(nPlutoElElid, "electrons kElId");
-  legendNofPP->AddEntry(nPlutoPosElid, "positrons kElId");
-  legendNofPP->AddEntry(nPlutoElTt, "electrons kTt");
-  legendNofPP->AddEntry(nPlutoPosTt, "positrons kTt");
-  legendNofPP->AddEntry(nPlutoElPt, "electrons kPt");
-  legendNofPP->AddEntry(nPlutoPosPt, "positrons kPt");
-  legendNofPP->Draw();
-
-  fHM[0]->CreateCanvas("fh_nof_urqmdElPos", "fh_nof_urqmdElPos", 800, 800);
-  DrawH1({nUrqmdElMc, nUrqmdPosMc, nUrqmdElAcc, nUrqmdPosAcc, nUrqmdElReco, nUrqmdPosReco, nUrqmdElElid, nUrqmdPosElid,
-          nUrqmdElTt, nUrqmdPosTt, nUrqmdElPt, nUrqmdPosPt},
-         {"", "", "", "", "", "", "", "", "", "", "", ""}, kLinear, kLog, false, 0.9, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legendNofUP = new TLegend(0.65, 0.6, 0.88, 0.93);
-  legendNofUP->SetFillColor(kWhite);
-  legendNofUP->AddEntry(nUrqmdElMc, "electrons kMc");
-  legendNofUP->AddEntry(nUrqmdPosMc, "positrons kMc");
-  legendNofUP->AddEntry(nUrqmdElAcc, "electrons kAcc");
-  legendNofUP->AddEntry(nUrqmdPosAcc, "positrons kAcc");
-  legendNofUP->AddEntry(nUrqmdElReco, "electrons kReco");
-  legendNofUP->AddEntry(nUrqmdPosReco, "positrons kReco");
-  legendNofUP->AddEntry(nUrqmdElElid, "electrons kElId");
-  legendNofUP->AddEntry(nUrqmdPosElid, "positrons kElId");
-  legendNofUP->AddEntry(nUrqmdElTt, "electrons kTt");
-  legendNofUP->AddEntry(nUrqmdPosTt, "positrons kTt");
-  legendNofUP->AddEntry(nUrqmdElPt, "electrons kPt");
-  legendNofUP->AddEntry(nUrqmdPosPt, "positrons kPt");
-  legendNofUP->Draw();
-
-  /* 2) Draw Pair Yields */
-
-  // draw ratio e-e-/e+e+
-  TH1D* ratPairsElid = (TH1D*) fh_mean_combPairsMM_sameEvent_minv[kElId]->Clone();
-  TH1D* ratPairsPt   = (TH1D*) fh_mean_combPairsMM_sameEvent_minv[kPtCut]->Clone();
-
-  ratPairsElid->Divide(fh_mean_combPairsPP_sameEvent_minv[kElId]);
-  ratPairsPt->Divide(fh_mean_combPairsPP_sameEvent_minv[kPtCut]);
-
-  ratPairsElid->GetXaxis()->SetRangeUser(0, 2.);
-  ratPairsElid->GetXaxis()->SetTitle(xTitle.c_str());
-  ratPairsElid->GetYaxis()->SetTitle("Ratio");
-  ratPairsElid->SetTitle("Ratio e^{-}e^{-}/e^{+}e^{+}");
-
-  fHM[0]->CreateCanvas("minv_CB_1_Ratio_eMeP", "minv_CB_1_Ratio_eMeP", 800, 800);
-  DrawH1({ratPairsElid, ratPairsPt}, {"", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "");
-
-  TLegend* legendRatio = new TLegend(0.2, 0.2, 0.7, 0.35);
-  legendRatio->SetFillColor(kWhite);
-  legendRatio->AddEntry(ratPairsElid, "ratio e^{-}e^{-}/e^{+}e^{+} pairs after El ID");
-  legendRatio->AddEntry(ratPairsPt, "ratio e^{-}e^{-}/e^{+}e^{+} pairs after Pt Cut");
-  legendRatio->Draw();
-
-  // calculate ratio of e-e-/e+e+ pairs
-  double nElPairsElid  = fh_mean_combPairsMM_sameEvent_minv[kElId]->GetEntries();
-  double nPosPairsElid = fh_mean_combPairsPP_sameEvent_minv[kElId]->GetEntries();
-  double nElPairsPt    = fh_mean_combPairsMM_sameEvent_minv[kPtCut]->GetEntries();
-  double nPosPairsPt   = fh_mean_combPairsPP_sameEvent_minv[kPtCut]->GetEntries();
-
-  double ratioEmEpElid = nElPairsElid / nPosPairsElid;
-  double ratioEmEpPt   = nElPairsPt / nPosPairsPt;
-  cout << "Ratio e-e-/e+e+ (pairs, El ID)  = " << ratioEmEpElid << endl;
-  cout << "Ratio e-e-/e+e+ (pairs, Pt cut) = " << ratioEmEpPt << endl;
-
-  // draw raw pairs
-  TH1D* h21PMElidRaw = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[kElId]->Clone();
-  TH1D* h21PPElidRaw = (TH1D*) fh_mean_combPairsPP_sameEvent_minv[kElId]->Clone();
-  TH1D* h21MMElidRaw = (TH1D*) fh_mean_combPairsMM_sameEvent_minv[kElId]->Clone();
-  TH1D* h21pmElidRaw = (TH1D*) fh_mean_combPairsPM_mixedEvents_minv[kElId]->Clone();
-  TH1D* h21ppElidRaw = (TH1D*) fh_mean_combPairsPP_mixedEvents_minv[kElId]->Clone();
-  TH1D* h21mmElidRaw = (TH1D*) fh_mean_combPairsMM_mixedEvents_minv[kElId]->Clone();
-
-  double bW = h21PMElidRaw->GetBinWidth(1);  // MIND: 'bW' is used throughout this draw method!
-  cout << "DrawMinvCombSignalAndBg(): bW = " << bW << endl;
-
-  Int_t nofEvents = 0;
-  for (int i = 0; i < fNofSignals; i++) {
-    if (!fDrawQgp && i == kQgp) continue;
-    nofEvents += (int) H1(i, "fh_event_number")->GetEntries();
-    cout << "DrawMinvCombSignalAndBg: nofEvents = " << nofEvents << endl;
-  }
-
-  h21PMElidRaw->Scale(bW * nofEvents);
-  h21PPElidRaw->Scale(bW * nofEvents);
-  h21MMElidRaw->Scale(bW * nofEvents);
-  h21pmElidRaw->Scale(bW * nofEvents);
-  h21ppElidRaw->Scale(bW * nofEvents);
-  h21mmElidRaw->Scale(bW * nofEvents);
-
-  h21PMElidRaw->GetXaxis()->SetTitle(xTitle.c_str());
-  h21PMElidRaw->GetYaxis()->SetTitle("absolute number");
-  h21PMElidRaw->SetTitle("same events");
-  h21pmElidRaw->GetXaxis()->SetTitle(xTitle.c_str());
-  h21pmElidRaw->GetYaxis()->SetTitle("absolute number");
-  h21pmElidRaw->SetTitle("mixed events");
-
-  fHM[0]->CreateCanvas("minv_CB_2_rawPairs_same", "minv_CB_2_rawPairs_same", 800, 800);
-  DrawH1({h21PMElidRaw, h21PPElidRaw, h21MMElidRaw}, {"", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "pe1");
-
-  TLegend* legend21 = new TLegend(0.5, 0.8, 0.92, 0.92);
-  legend21->SetFillColor(kWhite);
-  legend21->AddEntry(h21PMElidRaw, "e+e- pairs after El ID");
-  legend21->AddEntry(h21PPElidRaw, "e+e+ pairs after El ID");
-  legend21->AddEntry(h21MMElidRaw, "e-e- pairs after El ID");
-  legend21->Draw();
-
-  fHM[0]->CreateCanvas("minv_CB_2_rawPairs_mixed", "minv_CB_2_rawPairs_mixed", 800, 800);
-  DrawH1({h21pmElidRaw, h21ppElidRaw, h21mmElidRaw}, {"", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "pe1");
-
-  TLegend* legend21b = new TLegend(0.5, 0.8, 0.92, 0.92);
-  legend21b->SetFillColor(kWhite);
-  legend21b->AddEntry(h21pmElidRaw, "e+e- pairs after El ID");
-  legend21b->AddEntry(h21ppElidRaw, "e+e+ pairs after El ID");
-  legend21b->AddEntry(h21mmElidRaw, "e-e- pairs after El ID");
-  legend21b->Draw();
-
-  // draw scaled pairs (same event)
-  TH1D* Bpm = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[kElId]->Clone();
-  TH1D* Bpp = (TH1D*) fh_mean_combPairsPP_sameEvent_minv[kElId]->Clone();
-  TH1D* Bmm = (TH1D*) fh_mean_combPairsMM_sameEvent_minv[kElId]->Clone();
-
-
-  Bpm->GetXaxis()->SetRangeUser(0, 2.);
-  Bpm->GetXaxis()->SetTitle(xTitle.c_str());
-  Bpm->GetYaxis()->SetTitle(yTitle.c_str());
-  Bpm->SetTitle("same event");
-
-  fHM[0]->CreateCanvas("minv_CB_2_pairsSameEvent", "minv_CB_2_pairsSameEvent", 800, 800);
-  DrawH1({Bpm, Bpp, Bmm}, {"", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-
-  TLegend* legendB = new TLegend(0.5, 0.75, 0.95, 0.93);
-  legendB->SetFillColor(kWhite);
-  legendB->AddEntry(Bpm, "e+e- pairs (Elid)");
-  legendB->AddEntry(Bpp, "e+e+ pairs (Elid)");
-  legendB->AddEntry(Bmm, "e-e- pairs (Elid)");
-  legendB->Draw();
-
-  // draw scaled pairs (mixed events)
-  TH1D* bpm = (TH1D*) fh_mean_combPairsPM_mixedEvents_minv[kElId]->Clone();
-  TH1D* bpp = (TH1D*) fh_mean_combPairsPP_mixedEvents_minv[kElId]->Clone();
-  TH1D* bmm = (TH1D*) fh_mean_combPairsMM_mixedEvents_minv[kElId]->Clone();
-
-  bpm->GetXaxis()->SetRangeUser(0, 2.);
-  bpm->GetXaxis()->SetTitle(xTitle.c_str());
-  bpm->GetYaxis()->SetTitle(yTitle.c_str());
-  bpm->SetTitle("mixed events");
-
-  fHM[0]->CreateCanvas("minv_CB_2_pairsMixedEvents", "minv_CB_2_pairsMixedEvents", 800, 800);
-  DrawH1({bpm, bpp, bmm}, {"", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-
-  TLegend* legendb = new TLegend(0.5, 0.75, 0.95, 0.93);
-  legendb->SetFillColor(kWhite);
-  legendb->AddEntry(bpm, "e+e- pairs (Elid)");
-  legendb->AddEntry(bpp, "e+e+ pairs (Elid)");
-  legendb->AddEntry(bmm, "e-e- pairs (Elid)");
-  legendb->Draw();
-
-  // compare B++ with b++ (and -- and +-, resp.); therefor normalize to integral(400,700)
-  // convert MeV into Bin
-  int intFrom    = 400;  // lower and upper range to normalize (in Mev/c^2)
-  int intTo      = 700;
-  int nBinsOrig  = 4000;  // was set in CbmAnaDielectronTask.cxx
-  int upperLimit = 4000;  // in MeV (assumed, that lower limit = 0)
-  double bin400  = (double) (1. * nBinsOrig / nRebin) * (1. * intFrom / upperLimit);
-  double bin700  = (double) (1. * nBinsOrig / nRebin) * (1. * intTo / upperLimit);
-  cout << "bin400 = " << bin400 << endl;
-  cout << "bin700 = " << bin700 << endl;
-
-  // e+e- pairs
-  TH1D* BpmNormed = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[kElId]->Clone();  // norm. factor = 1
-  TH1D* bpmNormed = (TH1D*) fh_mean_combPairsPM_mixedEvents_minv[kElId]->Clone();
-
-  BpmNormed->GetXaxis()->SetRangeUser(0, 2.);
-  BpmNormed->GetXaxis()->SetTitle(xTitle.c_str());
-  BpmNormed->GetYaxis()->SetTitle(yTitle.c_str());
-
-  double intSamePM  = BpmNormed->Integral(bin400, bin700);
-  double intMixedPM = bpmNormed->Integral(bin400, bin700);
-  double normPM     = (double) intSamePM / intMixedPM;  // mixed histograms will be scaled with this factor
-
-  int nofBins = BpmNormed->GetNbinsX();  // MIND: 'nofBins' is used throughout this draw method!
-
-  for (int iBin = 1; iBin <= nofBins; iBin++) {
-    double content = bpmNormed->GetBinContent(iBin);
-    content *= normPM;
-    bpmNormed->SetBinContent(iBin, content);
-  }
-
-  // e+e+ pairs
-  TH1D* BppNormed = (TH1D*) fh_mean_combPairsPP_sameEvent_minv[kElId]->Clone();  // norm. factor = 1
-  TH1D* bppNormed = (TH1D*) fh_mean_combPairsPP_mixedEvents_minv[kElId]->Clone();
-
-  BppNormed->GetXaxis()->SetRangeUser(0, 2.);
-  BppNormed->GetXaxis()->SetTitle(xTitle.c_str());
-  BppNormed->GetYaxis()->SetTitle(yTitle.c_str());
+TH1D* LmvmDrawAll::GetCocktailMinvH1(ELmvmAnaStep step) { return GetCocktailMinv<TH1D>("hMinv", step); }
 
-  double intSamePP  = BppNormed->Integral(bin400, bin700);
-  double intMixedPP = bppNormed->Integral(bin400, bin700);
-  double normPP     = (double) intSamePP / intMixedPP;  // mixed histograms will be scaled with this factor
-
-  for (int iBin = 1; iBin <= nofBins; iBin++) {
-    double content = bppNormed->GetBinContent(iBin);
-    content *= normPP;
-    bppNormed->SetBinContent(iBin, content);
+template<class T>
+T* LmvmDrawAll::GetCocktailMinv(const string& name, ELmvmAnaStep step)
+{
+  T* sEta = dynamic_cast<T*>(fHMean.GetObject(fHMean.GetName(name, ELmvmSrc::Eta, step)));
+  T* sPi0 = dynamic_cast<T*>(fHMean.GetObject(fHMean.GetName(name, ELmvmSrc::Pi0, step)));
+
+  T* coctail = nullptr;
+  for (ELmvmSignal signal : fHMean.fSignals) {
+    string nameFull = fHMean.GetName(name, ELmvmSrc::Signal, step);
+    T* sHist        = dynamic_cast<T*>(H(signal)->GetObject(nameFull)->Clone());
+    int nofEvents   = (int) H(signal)->H1("hEventNumber")->GetEntries();
+    sHist->Scale(1. / nofEvents);
+    if (coctail == nullptr) coctail = sHist;
+    else
+      coctail->Add(sHist);
   }
+  coctail->Add(sEta);
+  coctail->Add(sPi0);
 
-  // e-e- pairs
-  TH1D* BmmNormed = (TH1D*) fh_mean_combPairsMM_sameEvent_minv[kElId]->Clone();  // norm. factor = 1
-  TH1D* bmmNormed = (TH1D*) fh_mean_combPairsMM_mixedEvents_minv[kElId]->Clone();
-
-  BmmNormed->GetXaxis()->SetRangeUser(0, 2.);
-  BmmNormed->GetXaxis()->SetTitle(xTitle.c_str());
-  BmmNormed->GetYaxis()->SetTitle(yTitle.c_str());
-
-  double intSameMM  = BmmNormed->Integral(bin400, bin700);
-  double intMixedMM = bmmNormed->Integral(bin400, bin700);
-  double normMM     = (double) intSameMM / intMixedMM;  // mixed histograms will be scaled with this factor
+  return coctail;
+}
 
-  for (int iBin = 1; iBin <= nofBins; iBin++) {
-    double content = bmmNormed->GetBinContent(iBin);
-    content *= normMM;
-    bmmNormed->SetBinContent(iBin, content);
+void LmvmDrawAll::DrawMinvAll()
+{
+  for (const ELmvmAnaStep step : fHMean.fAnaSteps) {
+    string name = fHMean.GetName("lmvmAll_minv_", step);
+    fHMean.fHM.CreateCanvas(name.c_str(), name.c_str(), 1000, 1000);
+    DrawMinv(step);
   }
+}
 
-  BpmNormed->SetTitle("compare same/mixed e+e- events");
-  BppNormed->SetTitle("compare same/mixed e+e+ events");
-  BmmNormed->SetTitle("compare same/mixed e-e- events");
-
-  TCanvas* c = fHM[0]->CreateCanvas("minv_CB_2_compare_same-mixed", "minv_CB_2_compare_same-mixed", 1800, 600);
-  c->Divide(3, 1);
-
-  c->cd(1);
-  if (setMinMax) {
-    BpmNormed->SetMinimum(yMin);
-    BpmNormed->SetMaximum(2 * yMax);
-  }
-  DrawH1({BpmNormed, bpmNormed}, {"p", "p"}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-  TLegend* leg1 = new TLegend(0.5, 0.78, 0.92, 0.9);
-  leg1->SetFillColor(kWhite);
-  leg1->AddEntry(BpmNormed, "e^{+}-e^{-} same event (Elid)");
-  leg1->AddEntry(bpmNormed, "e^{+}-e^{-} mixed events (Elid)");
-  leg1->Draw();
-
-  c->cd(2);
-  if (setMinMax) {
-    BppNormed->SetMinimum(yMin);
-    BppNormed->SetMaximum(2 * yMax);
-  }
-  DrawH1({BppNormed, bppNormed}, {"p", "p"}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-  TLegend* leg2 = new TLegend(0.5, 0.78, 0.92, 0.9);
-  leg2->SetFillColor(kWhite);
-  leg2->AddEntry(BppNormed, "e^{+}-e^{+} same event (Elid)");
-  leg2->AddEntry(bppNormed, "e^{+}-e^{+} mixed events (Elid)");
-  leg2->Draw();
-
-  c->cd(3);
-  if (setMinMax) {
-    BmmNormed->SetMinimum(yMin);
-    BmmNormed->SetMaximum(2 * yMax);
-  }
-  DrawH1({BmmNormed, bmmNormed}, {"p", "p"}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-  TLegend* leg3 = new TLegend(0.5, 0.78, 0.92, 0.9);
-  leg3->SetFillColor(kWhite);
-  leg3->AddEntry(BmmNormed, "e^{-}-e^{-} same event (Elid)");
-  leg3->AddEntry(bmmNormed, "e^{-}-e^{-} mixed events (Elid)");
-  leg3->Draw();
-
-  // compare B+- with (Cocktail + BG)
-  TH1D* Bpm1Elid   = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[kElId];
-  TH1D* Bpm1Pt     = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[kPtCut];
-  TH1D* cocBg1Elid = (TH1D*) GetCoctailMinv(kElId);
-  TH1D* cocBg1Pt   = (TH1D*) GetCoctailMinv(kPtCut);
-
-  cocBg1Elid->Add(fh_mean_bg_minv[kElId]);
-  cocBg1Pt->Add(fh_mean_bg_minv[kPtCut]);
-
-  cocBg1Elid->Rebin(nRebin);
-  double bWCoc = cocBg1Elid->GetBinWidth(1);
-  cocBg1Elid->Scale(1. / bWCoc);
-  cocBg1Pt->Rebin(nRebin);
-  cocBg1Pt->Scale(1. / bWCoc);
-
-  Bpm1Elid->GetXaxis()->SetRangeUser(0, 2.);
-  Bpm1Elid->GetXaxis()->SetTitle(xTitle.c_str());
-  Bpm1Elid->GetYaxis()->SetTitle(yTitle.c_str());
-
-  fHM[0]->CreateCanvas("minv_CB_2_BpmVsMC", "minv_CB_2_BpmVsMC", 800, 800);
-  DrawH1({Bpm1Elid, cocBg1Elid, Bpm1Pt, cocBg1Pt}, {"", "", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99,
-         "HIST L");
-
-  TLegend* legendCocBg = new TLegend(0.5, 0.7, 0.92, 0.91);
-  legendCocBg->SetFillColor(kWhite);
-  legendCocBg->AddEntry(Bpm1Elid, "N_{same}^{+-} (Elid)");
-  legendCocBg->AddEntry(cocBg1Elid, "Cocktail + BG (Elid)");
-  legendCocBg->AddEntry(Bpm1Pt, "N_{same}^{+-} (P_{t} cut)");
-  legendCocBg->AddEntry(cocBg1Pt, "Cocktail + BG (P_{t} cut)");
-  legendCocBg->Draw();
-
-  TH1D* ratCocBgBpmElid = (TH1D*) cocBg1Elid->Clone();
-  TH1D* ratCocBgBpmPt   = (TH1D*) cocBg1Pt->Clone();
-
-  ratCocBgBpmElid->Divide(Bpm1Elid);
-  ratCocBgBpmPt->Divide(Bpm1Pt);
-
-  ratCocBgBpmElid->GetXaxis()->SetRangeUser(0, 2.);
-  ratCocBgBpmElid->GetYaxis()->SetTitle(0);
-  ratCocBgBpmElid->SetTitle("Ratio (Cocktail + BG) / N_{same}^{+-}");
-
-  fHM[0]->CreateCanvas("minv_CB_2_BpmVsMC2", "minv_CB_2_BpmVsMC2", 800, 800);
-  DrawH1({ratCocBgBpmElid, ratCocBgBpmPt}, {"", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-
-  TLegend* legendCocBg2 = new TLegend(0.55, 0.75, 0.95, 0.91);
-  legendCocBg2->SetFillColor(kWhite);
-  legendCocBg2->AddEntry(ratCocBgBpmElid, "El ID cut");
-  legendCocBg2->AddEntry(ratCocBgBpmPt, "P_{t} cut");
-  legendCocBg2->Draw();
-
-  /* 3) Draw Geometric Mean */
-  TH1D* geomMeanSameElid  = (TH1D*) fh_mean_combBg_GeomMeanSame_minv[kElId]->Clone();
-  TH1D* geomMeanMixedElid = (TH1D*) fh_mean_combBg_GeomMeanMixed_minv[kElId]->Clone();
-  TH1D* geomMeanSamePt    = (TH1D*) fh_mean_combBg_GeomMeanSame_minv[kPtCut]->Clone();
-  TH1D* geomMeanMixedPt   = (TH1D*) fh_mean_combBg_GeomMeanMixed_minv[kPtCut]->Clone();
-
-  double intGMsameElid  = geomMeanSameElid->Integral(bin400, bin700);
-  double intGMmixedElid = geomMeanMixedElid->Integral(bin400, bin700);
-  double normGMElid     = (double) intGMsameElid / intGMmixedElid;  // mixed histograms will be scaled with this factor
-
-  double intGMsamePt  = geomMeanSamePt->Integral(bin400, bin700);
-  double intGMmixedPt = geomMeanMixedPt->Integral(bin400, bin700);
-  double normGMPt     = (double) intGMsamePt / intGMmixedPt;
-
-  for (int iBin = 1; iBin <= nofBins; iBin++) {
-    double contentElid = geomMeanMixedElid->GetBinContent(iBin);
-    double contentPt   = geomMeanMixedPt->GetBinContent(iBin);
-    contentElid *= normGMElid;
-    contentPt *= normGMPt;
-    geomMeanMixedElid->SetBinContent(iBin, contentElid);
-    geomMeanMixedPt->SetBinContent(iBin, contentPt);
-  }
-  if (setMinMax) {
-    geomMeanSameElid->SetMinimum(yMin);
-    geomMeanSameElid->SetMaximum(yMax);
-  }
+void LmvmDrawAll::DrawMinv(ELmvmAnaStep step)
+{
+  TH1D* bg       = fHMean.H1Clone("hMinv", ELmvmSrc::Bg, step);
+  TH1D* pi0      = fHMean.H1Clone("hMinv", ELmvmSrc::Pi0, step);
+  TH1D* eta      = fHMean.H1Clone("hMinv", ELmvmSrc::Eta, step);
+  TH1D* cocktail = GetCocktailMinvH1(step);
+  TH1D* sbg      = static_cast<TH1D*>(bg->Clone());
+  sbg->Add(cocktail);
+
+  vector<TH1D*> sHists(fHMean.fNofSignals);
+  for (ELmvmSignal signal : fHMean.fSignals) {
+    TH1D* sHist = H(signal)->H1Clone("hMinv", ELmvmSrc::Signal, step);
+    sHist->Scale(1. / H(signal)->H1("hEventNumber")->GetEntries());
+    sHists[static_cast<int>(signal)] = sHist;
+  }
+
+  vector<LmvmDrawMinvData> drawData;
+  if (step != ELmvmAnaStep::Mc) {
+    drawData.emplace_back(sbg, kBlack, kBlack, 1, -1, "Cocktail+BG");
+    drawData.emplace_back(bg, kGray, kBlack, 1, -1, "Background");
+  }
+  drawData.emplace_back(sHists[static_cast<int>(ELmvmSignal::OmegaD)], kCyan + 2, kCyan + 4, 2, -1,
+                        "#omega #rightarrow #pi^{0}e^{+}e^{-}");
+  drawData.emplace_back(pi0, kGreen - 3, kGreen + 3, 2, -1, "#pi^{0} #rightarrow #gammae^{+}e^{-}");
+  drawData.emplace_back(eta, kRed - 4, kRed + 2, 2, -1, "#eta #rightarrow #gammae^{+}e^{-}");
+  drawData.emplace_back(sHists[static_cast<int>(ELmvmSignal::Omega)], kOrange + 7, kOrange + 4, 2, -1,
+                        "#omega #rightarrow e^{+}e^{-}");
+  drawData.emplace_back(sHists[static_cast<int>(ELmvmSignal::Phi)], kAzure + 2, kAzure + 3, 2, -1,
+                        "#phi #rightarrow e^{+}e^{-}");
+  drawData.emplace_back(sHists[static_cast<int>(ELmvmSignal::Qgp)], kOrange - 2, kOrange - 3, 4, 3112, "QGP radiation");
+  drawData.emplace_back(sHists[static_cast<int>(ELmvmSignal::Inmed)], kMagenta - 3, kMagenta - 2, 4, 3018,
+                        "in-medium #rho");
+  drawData.emplace_back(cocktail, -1, kRed + 2, 4, -1, "Cocktail");
+
+
+  double binWidth = drawData[0].fH->GetBinWidth(1);
+  double min      = std::numeric_limits<Double_t>::max();
+  double max      = std::numeric_limits<Double_t>::min();
+  TH1D* h0        = nullptr;
+  TLegend* leg    = new TLegend(0.7, 0.6, 0.99, 0.99);
+  for (size_t i = 0; i < drawData.size(); i++) {
+    const auto& d = drawData[i];
+    // TODO: Think about rebin
+    d.fH->Rebin(20);
+    d.fH->Scale(1. / binWidth);
+    d.fH->GetYaxis()->SetTitle("dN/dM_{ee} [GeV/c^{2}]^{-1}");
+    d.fH->GetYaxis()->SetLabelSize(0.05);
+
+    if (d.fFillColor != -1) d.fH->SetFillColor(d.fFillColor);
+    if (d.fFillStyle != -1) d.fH->SetFillStyle(d.fFillStyle);
+    leg->AddEntry(d.fH, d.fLegend.c_str(), "f");
+    DrawH1(d.fH, kLinear, kLinear, (h0 == nullptr) ? "hist" : "hist,same", d.fLineColor, d.fLineWidth, 0);
+    if (h0 == nullptr) h0 = d.fH;
+    min = std::min(d.fH->GetMinimum(), min);
+    max = std::max(d.fH->GetMaximum(), max);
+  }
+  if (min == 0.) min = std::min(1e-4, max * 1e-7);
+  if (h0 != nullptr) h0->SetMinimum(min);
+  if (h0 != nullptr) h0->SetMaximum(1.1 * max);
+
+  leg->SetFillColor(kWhite);
+  leg->Draw();
+  gPad->SetLogy(true);
+  //DrawH1(hists, legendStr, kLinear, kLog, true, 0.7, 0.6, 0.99, 0.99, "HIST L");
+}
 
-  geomMeanSameElid->GetXaxis()->SetRangeUser(0, 2.);
-  geomMeanSameElid->GetXaxis()->SetTitle(xTitle.c_str());
-  geomMeanSameElid->GetYaxis()->SetTitle(yTitle.c_str());
-  geomMeanSameElid->SetTitle("geometric mean (normalized)");
-  geomMeanMixedElid->SetTitle(0);
-
-  fHM[0]->CreateCanvas("minv_CB_3_geomMean", "minv_CB_3_geomMean", 800, 800);
-  DrawH1({geomMeanSameElid, geomMeanMixedElid, geomMeanSamePt, geomMeanMixedPt}, {"", "", "", ""}, kLinear, kLog, false,
-         0.8, 0.8, 0.99, 0.99, "HIST L");
-
-  TLegend* legendgeomMean = new TLegend(0.55, 0.8, 0.92, 0.91);
-  legendgeomMean->SetFillColor(kWhite);
-  legendgeomMean->AddEntry(geomMeanSameElid, "same event (elid)");
-  legendgeomMean->AddEntry(geomMeanMixedElid, "mixed events (elid)");
-  legendgeomMean->AddEntry(geomMeanSamePt, "same event (Pt)");
-  legendgeomMean->AddEntry(geomMeanMixedPt, "mixed events (Pt)");
-  legendgeomMean->Draw();
-
-  //draw geom. mean, assembled of same (<= 0.3 GeV) and normed mixed (> 0.3 GeV) data
-
-  // convert MeV into Bin
-  int rFrom      = 300;  // lower and upper range to normalize (in Mev/c^2)
-  int rTo        = 1000;
-  double binFrom = (double) (1. * nBinsOrig / nRebin) * (1. * rFrom / upperLimit);
-  double binTo   = (double) (1. * nBinsOrig / nRebin) * (1. * rTo / upperLimit);
-
-  TH1D* geomMeanAss = (TH1D*) fh_mean_combBg_GeomMeanSame_minv[kElId]->Clone();
-
-  double intSameGMsp  = geomMeanAss->Integral(binFrom, binTo);
-  double intMixedGMsp = geomMeanMixedElid->Integral(binFrom, binTo);
-  double normGMsp     = (double) intSameGMsp / intMixedGMsp;
-
-  for (int iBin = binFrom + 1; iBin <= nofBins; iBin++) {  // from 300 MeV on normalized data from mixed event
-    double cont = geomMeanMixedElid->GetBinContent(iBin);
-    cont *= normGMsp;
-    geomMeanAss->SetBinContent(iBin, cont);
-  }
-  if (setMinMax) {
-    geomMeanAss->SetMinimum(yMin);
-    geomMeanAss->SetMaximum(yMax);
+void LmvmDrawAll::DrawMinvPtAll()
+{
+  for (const ELmvmAnaStep step : fHMean.fAnaSteps) {
+    string name = fHMean.GetName("lmvmAll_minvPt", step);
+    fHMean.fHM.CreateCanvas(name.c_str(), name.c_str(), 1000, 1000);
+    DrawH2(GetCocktailMinv<TH2D>("hMinvPt", step));
   }
+}
 
-  geomMeanAss->GetXaxis()->SetRangeUser(0, 2.);
-  geomMeanAss->GetXaxis()->SetTitle(xTitle.c_str());
-  geomMeanAss->GetYaxis()->SetTitle(yTitle.c_str());
-  geomMeanAss->SetTitle("geometric mean (splitted)");
-
-  fHM[0]->CreateCanvas("minv_CB_3_geomMean_assembled", "minv_CB_3_geomMean_assembled", 800, 800);
-  DrawH1({geomMeanAss}, {""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "hist l");
-
-  TLegend* legendgeomMeanAss = new TLegend(0.55, 0.8, 0.91, 0.91);
-  legendgeomMeanAss->SetFillColor(kWhite);
-  legendgeomMeanAss->AddEntry(geomMeanAss, "geom. mean");
-  legendgeomMeanAss->Draw();
-
-  /* 4) Draw B_comb with Coc+BG and with Bpm */
-  TH1D* cbgElid  = (TH1D*) fh_mean_combBg_minv[kElId]->Clone();
-  TH1D* cbgPtCut = (TH1D*) fh_mean_combBg_minv[kPtCut]->Clone();
-
-  TH1D* bgCocElid = (TH1D*) GetCoctailMinv(kElId);
-  TH1D* bgCocPt   = (TH1D*) GetCoctailMinv(kPtCut);
-
-  bgCocElid->Add(fh_mean_bg_minv[kElId]);
-  bgCocPt->Add(fh_mean_bg_minv[kPtCut]);
-
-  TH1D* BpmElid = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[kElId]->Clone();  // MIND: BpmElid is also used below!
-  TH1D* BpmPt   = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[kPtCut]->Clone();
-
-  bgCocElid->Rebin(nRebin);  // these histos have to be rebinned and scaled here because not done yet as with CB histos
-  bgCocPt->Rebin(nRebin);
-  bgCocElid->Scale(1. / bW);
-  bgCocPt->Scale(1. / bW);
-
-  cbgElid->GetXaxis()->SetRangeUser(0, 2.);
-  cbgElid->GetXaxis()->SetTitle(xTitle.c_str());
-  cbgElid->GetYaxis()->SetTitle(yTitle.c_str());
-  cbgElid->SetTitle(0);
-
-  if (setMinMax) {
-    cbgElid->SetMinimum(yMin);
-    cbgElid->SetMaximum(yMax);
+void LmvmDrawAll::DrawMinvCombSignalAndBg()
+{
+  // double yMin   = 1e-7;
+  // double yMax   = 5e-2;
+  // string yTitle = "dN/dM_{ee} [GeV/c^{2}]^{-1}";
+  // string xTitle = "M_{ee} [GeV/c^2]";
+
+  // draw MM/PP ratio for same events
+  {
+    TCanvas* c = fHMean.fHM.CreateCanvas("lmvmAll_CBsameEv_RatioMMPP", "lmvmAll_CBsameEv_RatioMMPP", 1800, 1800);
+    c->Divide(3, 3);
+    int i = 1;
+    for (auto step : fHMean.fAnaSteps) {
+      if (step < ELmvmAnaStep::ElId) continue;
+      c->cd(i++);
+      TH1D* pp = fHMean.H1Clone("hMinvCombPP_sameEv", step);
+      TH1D* mm = fHMean.H1Clone("hMinvCombMM_sameEv", step);
+      pp->Rebin(20);
+      mm->Rebin(20);
+      mm->Divide(pp);
+      mm->GetYaxis()->SetTitle("Ratio e^{-}e^{-}/e^{+}e^{+}");
+      DrawH1(mm, kLinear, kLinear, "hist");
+      fHMean.DrawAnaStepOnPad(step);
+    }
   }
 
-  fHM[0]->CreateCanvas("minv_CB_4_bComb", "minv_CB_4_bComb", 800, 800);
-  DrawH1({cbgElid, bgCocElid}, {"", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-
-  TLegend* legendBg = new TLegend(0.55, 0.7, 0.95, 0.9);
-  legendBg->SetFillColor(kWhite);
-  legendBg->AddEntry(cbgElid, "comb. BG (2 * k * geomMean, elid)");
-  legendBg->AddEntry(bgCocElid, "Cocktail + BG (elid)");
-  legendBg->Draw();
-
-  TH1D* ratCocBgCbgElid = (TH1D*) bgCocElid->Clone();
-  TH1D* ratCocBgCbgPt   = (TH1D*) bgCocPt->Clone();
-
-  ratCocBgCbgElid->Divide(cbgElid);
-  ratCocBgCbgPt->Divide(cbgPtCut);
-
-  if (setMinMax) {
-    ratCocBgCbgElid->SetMinimum(2e-1);
-    ratCocBgCbgElid->SetMaximum(50);
-    ratCocBgCbgPt->SetMinimum(2e-1);
-    ratCocBgCbgPt->SetMaximum(50);
-    cbgElid->SetMinimum(yMin);
-    cbgElid->SetMaximum(yMax);
+  // Draw PM, MM, PP in one plot
+  {
+    for (const string& ev : {"sameEv", "mixedEv"}) {
+      string cName = "lmvmAll_CB" + ev;
+      TCanvas* c   = fHMean.fHM.CreateCanvas(cName.c_str(), cName.c_str(), 1800, 1800);
+      c->Divide(3, 3);
+      int i = 1;
+      for (auto step : fHMean.fAnaSteps) {
+        if (step < ELmvmAnaStep::ElId) continue;
+        c->cd(i++);
+        TH1D* pp = fHMean.H1Clone("hMinvCombPP_" + ev, step);
+        TH1D* mm = fHMean.H1Clone("hMinvCombMM_" + ev, step);
+        TH1D* pm = fHMean.H1Clone("hMinvCombPM_" + ev, step);
+        pp->Rebin(20);
+        mm->Rebin(20);
+        pm->Rebin(20);
+        pm->GetYaxis()->SetTitle("M_{ee}");
+        DrawH1({pm, pp, mm}, {"e+e-", "e+e+", "e-e-"}, kLinear, kLog, true, 0.85, 0.7, 0.99, 0.99, "HIST");
+        fHMean.DrawAnaStepOnPad(step);
+      }
+    }
   }
 
-  fHM[0]->CreateCanvas("minv_CB_4_bCombVsBpm", "minv_CB_4_bCombVsBpm", 800, 800);
-  DrawH1({cbgElid, BpmElid, cbgPtCut, BpmPt}, {"", "", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-
-  TLegend* legendBg2 = new TLegend(0.55, 0.7, 0.92, 0.91);
-  legendBg2->SetFillColor(kWhite);
-  legendBg2->AddEntry(cbgElid, "comb. BG, Elid");
-  legendBg2->AddEntry(BpmElid, "N_{same}^{+-}, Elid");
-  legendBg2->AddEntry(cbgPtCut, "comb. BG, PtCut");
-  legendBg2->AddEntry(BpmPt, "N_{same}^{+-}, PtCut");
-  legendBg2->Draw();
-
-  ratCocBgCbgElid->GetXaxis()->SetRangeUser(0, 2.);
-  ratCocBgCbgElid->SetTitle("Ratio (Cocktail + BG) / B_{c}");
-
-  fHM[0]->CreateCanvas("minv_CB_4_bComb_rat", "minv_CB_4_bComb_rat", 800, 800);
-  DrawH1({ratCocBgCbgElid, ratCocBgCbgPt}, {"", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-
-  TLegend* legendBg1 = new TLegend(0.55, 0.8, 0.92, 0.9);
-  legendBg1->SetFillColor(kWhite);
-  legendBg1->AddEntry(ratCocBgCbgElid, "El ID cut");
-  legendBg1->AddEntry(ratCocBgCbgPt, "Pt cut");
-  legendBg1->Draw();
-
-  // draw ass. CB with all steps
-  TH1D* cbgAssElid  = (TH1D*) fh_mean_combBg_assemb_minv[kElId]->Clone();
-  TH1D* cbgAssGamma = (TH1D*) fh_mean_combBg_assemb_minv[kGammaCut]->Clone();
-  TH1D* cbgAssMvd1  = (TH1D*) fh_mean_combBg_assemb_minv[kMvd1Cut]->Clone();
-  TH1D* cbgAssSt    = (TH1D*) fh_mean_combBg_assemb_minv[kStCut]->Clone();
-  TH1D* cbgAssRt    = (TH1D*) fh_mean_combBg_assemb_minv[kRtCut]->Clone();
-  TH1D* cbgAssTt    = (TH1D*) fh_mean_combBg_assemb_minv[kTtCut]->Clone();
-  TH1D* cbgAssPt    = (TH1D*) fh_mean_combBg_assemb_minv[kPtCut]->Clone();
-
-  TH1D* ratCocBgCbgAssElid = (TH1D*) bgCocElid->Clone();
-  TH1D* ratCocBgCbgAssPt   = (TH1D*) bgCocPt->Clone();
-
-  ratCocBgCbgAssElid->Divide(cbgAssElid);
-  ratCocBgCbgAssPt->Divide(cbgAssPt);
-
-  if (setMinMax) {
-    ratCocBgCbgAssElid->SetMinimum(2e-1);
-    ratCocBgCbgAssElid->SetMaximum(50);
-    ratCocBgCbgAssPt->SetMinimum(2e-1);
-    ratCocBgCbgAssPt->SetMaximum(50);
+  // Draw same and mixed for PP, MM, PM cases; normalize to 400 - 700 MeV/c2 interval
+  {
+    for (const string& comb : {"PM", "PP", "MM"}) {
+      string cName = "lmvmAll_CB_sameMixed" + comb;
+      TCanvas* c   = fHMean.fHM.CreateCanvas(cName.c_str(), cName.c_str(), 1800, 1800);
+      c->Divide(3, 3);
+      int i = 1;
+      for (auto step : fHMean.fAnaSteps) {
+        if (step < ELmvmAnaStep::ElId) continue;
+        c->cd(i++);
+        TH1D* same   = fHMean.H1Clone("hMinvComb" + comb + "_sameEv", step);
+        TH1D* mixed  = fHMean.H1Clone("hMinvComb" + comb + "_mixedEv", step);
+        int minBin   = same->FindBin(0.4);
+        int maxBin   = same->FindBin(0.7);
+        double scale = same->Integral(minBin, maxBin) / mixed->Integral(minBin, maxBin);
+        mixed->Scale(scale);
+        same->Rebin(20);
+        mixed->Rebin(20);
+        DrawH1({same, mixed}, {"Same " + comb, "Mixed " + comb}, kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99, "HIST");
+        fHMean.DrawAnaStepOnPad(step);
+      }
+    }
   }
 
-  ratCocBgCbgAssElid->GetXaxis()->SetRangeUser(0, 2.);
-  ratCocBgCbgAssElid->SetTitle("Ratio (Cocktail + BG) / B_{c_ass}");
-
-  fHM[0]->CreateCanvas("minv_CB_4_bComb_rat2", "minv_CB_4_bComb_rat2", 800, 800);
-  DrawH1({ratCocBgCbgAssElid, ratCocBgCbgAssPt}, {"", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-
-  TLegend* legendBg4 = new TLegend(0.55, 0.8, 0.92, 0.9);
-  legendBg4->SetFillColor(kWhite);
-  legendBg4->AddEntry(ratCocBgCbgAssElid, "El ID cut");
-  legendBg4->AddEntry(ratCocBgCbgAssPt, "Pt cut");
-  legendBg4->Draw();
-
-  // conv. vs assembled CB
-  TH1D* h44cbgElid    = (TH1D*) fh_mean_combBg_minv[kElId]->Clone();
-  TH1D* h44cbgAssElid = (TH1D*) fh_mean_combBg_assemb_minv[kElId]->Clone();
-
-  if (setMinMax) {
-    h44cbgElid->SetMinimum(yMin);
-    h44cbgElid->SetMaximum(yMax);
+  // compare PM with sbg (Cocktail + BG)
+  {
+    for (auto step : fHMean.fAnaSteps) {
+      if (step < ELmvmAnaStep::ElId) continue;
+      TH1D* pmSame = fHMean.H1Clone("hMinvCombPM_sameEv", step);
+      TH1D* sbg    = fHMean.H1Clone("hMinv", ELmvmSrc::Bg, step);
+      sbg->Add(GetCocktailMinvH1(step));
+      pmSame->Rebin(20);
+      sbg->Rebin(20);
+      TH1D* ratio = (TH1D*) pmSame->Clone();
+
+      string cName = "lmvmAll_CB_SameVsSbg_" + fHMean.fAnaStepNames[static_cast<int>(step)];
+      TCanvas* c   = fHMean.fHM.CreateCanvas(cName.c_str(), cName.c_str(), 1800, 900);
+      c->Divide(2, 1);
+      c->cd(1);
+      DrawH1({pmSame, sbg}, {"N_{same}^{+-}", "Cocktail + BG"}, kLinear, kLog, true, 0.7, 0.8, 0.99, 0.99, "HIST");
+      pmSame->SetMinimum(1e-5 * sbg->GetMaximum());
+      c->cd(2);
+      ratio->Divide(sbg);
+      DrawH1(ratio, kLinear, kLog, "hist");
+      ratio->SetMinimum(0.01);
+    }
   }
 
-  h44cbgElid->GetXaxis()->SetRangeUser(0, 2.);
-  h44cbgElid->GetXaxis()->SetTitle(xTitle.c_str());
-  h44cbgElid->GetYaxis()->SetTitle(yTitle.c_str());
-  h44cbgElid->SetTitle("Combinatorial BG");
 
-  fHM[0]->CreateCanvas("minv_CB_4_bComb_convVsAss", "minv_CB_4_bComb_convVsAss", 800, 800);
-  DrawH1({h44cbgElid, h44cbgAssElid}, {"", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "pe1");
-
-  TLegend* legendBg3 = new TLegend(0.55, 0.7, 0.92, 0.91);
-  legendBg3->SetFillColor(kWhite);
-  legendBg3->AddEntry(h44cbgElid, "conv. CB, Elid");
-  legendBg3->AddEntry(h44cbgAssElid, "assembled CB, Elid");
-  legendBg3->Draw();
-
-  // assembled CB with all steps
-  if (setMinMax) {
-    cbgAssElid->SetMinimum(yMin);
-    cbgAssElid->SetMaximum(yMax);
-  }
-  cbgAssElid->GetXaxis()->SetRangeUser(0, 2.);
-  cbgAssElid->GetXaxis()->SetTitle(xTitle.c_str());
-  cbgAssElid->GetYaxis()->SetTitle(yTitle.c_str());
-  cbgAssElid->SetTitle("Combinatorial BG");
-
-  fHM[0]->CreateCanvas("minv_CB_4_bComb_assembled_steps", "minv_CB_4_bComb_assembled_steps", 800, 800);
-  DrawH1({cbgAssElid, cbgAssGamma, cbgAssMvd1, cbgAssSt, cbgAssRt, cbgAssTt, cbgAssPt}, {"", "", "", "", "", "", ""},
-         kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "pe1");
-
-  TLegend* legendBg5 = new TLegend(0.7, 0.65, 0.92, 0.91);
-  legendBg5->SetFillColor(kWhite);
-  legendBg5->AddEntry(cbgAssElid, "elid");
-  legendBg5->AddEntry(cbgAssGamma, "gamma cut");
-  legendBg5->AddEntry(cbgAssMvd1, "MVD1 cut");
-  legendBg5->AddEntry(cbgAssSt, "ST cut");
-  legendBg5->AddEntry(cbgAssRt, "RT cut");
-  legendBg5->AddEntry(cbgAssTt, "TT cut");
-  legendBg5->AddEntry(cbgAssPt, "P_{t} cut");
-  legendBg5->Draw();
-
-  /* 5) Draw k Factor */
-  TH1D* kReconst = (TH1D*) fh_mean_combBg_k_minv[kReco]->Clone();
-  TH1D* kChi2    = (TH1D*) fh_mean_combBg_k_minv[kChi2Prim]->Clone();
-  TH1D* kElid    = (TH1D*) fh_mean_combBg_k_minv[kElId]->Clone();
-  TH1D* kGamma   = (TH1D*) fh_mean_combBg_k_minv[kGammaCut]->Clone();
-  TH1D* kMvd1    = (TH1D*) fh_mean_combBg_k_minv[kMvd1Cut]->Clone();
-  TH1D* kSt      = (TH1D*) fh_mean_combBg_k_minv[kStCut]->Clone();
-  TH1D* kRt      = (TH1D*) fh_mean_combBg_k_minv[kRtCut]->Clone();
-  TH1D* kTt      = (TH1D*) fh_mean_combBg_k_minv[kTtCut]->Clone();
-  TH1D* kPt      = (TH1D*) fh_mean_combBg_k_minv[kPtCut]->Clone();
-
-  if (setMinMax) {
-    kReconst->SetMinimum(0.7);
-    kReconst->SetMaximum(1.3);
-    kChi2->SetMinimum(0.7);
-    kChi2->SetMaximum(1.3);
-    kElid->SetMinimum(0.7);
-    kElid->SetMaximum(1.3);
-    kGamma->SetMinimum(0.7);
-    kGamma->SetMaximum(1.3);
-    kMvd1->SetMinimum(0.7);
-    kMvd1->SetMaximum(1.3);
-    kSt->SetMinimum(0.7);
-    kSt->SetMaximum(1.3);
-    kRt->SetMinimum(0.7);
-    kRt->SetMaximum(1.3);
-    kTt->SetMinimum(0.7);
-    kTt->SetMaximum(1.3);
-    kPt->SetMinimum(0.7);
-    kPt->SetMaximum(1.3);
+  //Draw Geometric Mean
+  {
+    TCanvas* c = fHMean.fHM.CreateCanvas("lmvmAll_minvCombGeom", "lmvmAll_minvCombGeom", 1800, 1800);
+    c->Divide(3, 3);
+    int i = 1;
+    for (auto step : fHMean.fAnaSteps) {
+      if (step < ELmvmAnaStep::ElId) continue;
+      c->cd(i++);
+      TH1D* same   = fHMean.H1Clone("hMinvCombGeom_sameEv", step);
+      TH1D* mixed  = fHMean.H1Clone("hMinvCombGeom_mixedEv", step);
+      int minBin   = same->FindBin(0.4);
+      int maxBin   = same->FindBin(0.7);
+      double scale = same->Integral(minBin, maxBin) / mixed->Integral(minBin, maxBin);
+      mixed->Scale(scale);
+      same->Rebin(20);
+      mixed->Rebin(20);
+      same->GetYaxis()->SetTitle("M_{ee}");
+      DrawH1({same, mixed}, {"same", "mixed"}, kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99, "HIST");
+      fHMean.DrawAnaStepOnPad(step);
+    }
   }
 
-  kReconst->GetXaxis()->SetRangeUser(0, 2.);
-  kReconst->GetXaxis()->SetTitle(xTitle.c_str());
-  kReconst->GetYaxis()->SetTitle(0);
-  kReconst->SetTitle("k factor");
-
-  fHM[0]->CreateCanvas("minv_CB_5_k", "minv_CB_5_k", 800, 800);
-  DrawH1({kReconst, kChi2, kElid, kGamma, kMvd1, kSt, kRt, kTt, kPt}, {"", "", "", "", "", "", "", "", ""}, kLinear,
-         kLinear, false, 0.8, 0.8, 0.99, 0.99, "HIST L");
-
-  TLegend* legendK = new TLegend(0.7, 0.7, 0.92, 0.91);
-  legendK->SetFillColor(kWhite);
-  legendK->AddEntry(kReconst, "reco");
-  legendK->AddEntry(kChi2, "#chi^{2} ");
-  legendK->AddEntry(kElid, "elid");
-  legendK->AddEntry(kGamma, "gamma cut");
-  legendK->AddEntry(kMvd1, "MVD1 cut");
-  legendK->AddEntry(kSt, "ST cut");
-  legendK->AddEntry(kRt, "RT cut");
-  legendK->AddEntry(kTt, "TT cut");
-  legendK->AddEntry(kPt, "P_{t} cut");
-  legendK->Draw();
-
-  /* 6) Draw Combinatorial Signal (all from assembled comb. BG) */
-  // from 'N+-same'
-
-  // elid, draw also components
-  TH1D* h61NpmElid    = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[kElId]->Clone();
-  TH1D* h61cbAssElid  = (TH1D*) fh_mean_combBg_assemb_minv[kElId]->Clone();
-  TH1D* h61SigNpmElid = (TH1D*) fh_mean_combSignalNpm_assemb_minv[kElId]->Clone();
-  TH1D* h61coc1Elid   = (TH1D*) GetCoctailMinv(kElId);
-
-  h61coc1Elid->Add(fh_mean_bg_minv[kElId]);
-  h61coc1Elid->Add(fh_mean_bg_minv[kElId], -1.);
-
-  h61coc1Elid->Rebin(nRebin);
-  h61coc1Elid->Scale(1. / bW);
-
-  if (setMinMax) {
-    h61NpmElid->SetMinimum(yMin);
-    h61NpmElid->SetMaximum(yMax);
-    h61cbAssElid->SetMinimum(yMin);
-    h61cbAssElid->SetMaximum(yMax);
-    h61SigNpmElid->SetMinimum(yMin);
-    h61SigNpmElid->SetMaximum(yMax);
-    h61coc1Elid->SetMinimum(yMin);
-    h61coc1Elid->SetMaximum(yMax);
-  }
 
-  h61NpmElid->GetXaxis()->SetRangeUser(0, 2.);
-  h61NpmElid->GetYaxis()->SetTitle(yTitle.c_str());
-  h61NpmElid->SetTitle(0);
-  h61cbAssElid->GetXaxis()->SetRangeUser(0, 2.);
-  h61SigNpmElid->GetXaxis()->SetRangeUser(0, 2.);
-  h61coc1Elid->GetXaxis()->SetRangeUser(0, 2.);
-
-  fHM[0]->CreateCanvas("minv_CB_6_signal_Npm_elid", "minv_CB_6_signal_Npm_elid", 800, 800);
-  DrawH1({h61NpmElid, h61cbAssElid, h61SigNpmElid, h61coc1Elid}, {"", "", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99,
-         0.99, "hist p");
-
-  TLegend* legend61 = new TLegend(0.55, 0.7, 0.98, 0.9);
-  legend61->SetFillColor(kWhite);
-  legend61->AddEntry(h61NpmElid, "N_{same}^{+-} (Elid)");
-  legend61->AddEntry(h61cbAssElid, "B_{c} (assembled, Elid)");
-  legend61->AddEntry(h61SigNpmElid, "Signal (N_{same}^{+-} - B_{c}, Elid)");
-  legend61->AddEntry(h61coc1Elid, "Cocktail, Elid)");
-  legend61->Draw();
-
-  // all steps, draw with and wo error
-  TH1D* h63SigNpmElid  = (TH1D*) fh_mean_combSignalNpm_assemb_minv[kElId]->Clone();
-  TH1D* h63SigNpmGamma = (TH1D*) fh_mean_combSignalNpm_assemb_minv[kGammaCut]->Clone();
-  TH1D* h63SigNpmMvd1  = (TH1D*) fh_mean_combSignalNpm_assemb_minv[kMvd1Cut]->Clone();
-  TH1D* h63SigNpmSt    = (TH1D*) fh_mean_combSignalNpm_assemb_minv[kStCut]->Clone();
-  TH1D* h63SigNpmRt    = (TH1D*) fh_mean_combSignalNpm_assemb_minv[kRtCut]->Clone();
-  TH1D* h63SigNpmTt    = (TH1D*) fh_mean_combSignalNpm_assemb_minv[kTtCut]->Clone();
-  TH1D* h63SigNpmPt    = (TH1D*) fh_mean_combSignalNpm_assemb_minv[kPtCut]->Clone();
-
-  TH1D* h63SigNpmPt2 = (TH1D*) fh_mean_combSignalNpm_assemb_minv[kPtCut]->Clone();
-
-  if (setMinMax) {
-    h63SigNpmElid->SetMinimum(yMin);  // setting min/max somehow makes the histos empty
-    h63SigNpmElid->SetMaximum(yMax);
-    h63SigNpmGamma->SetMinimum(yMin);
-    h63SigNpmGamma->SetMaximum(yMax);
-    h63SigNpmMvd1->SetMinimum(yMin);
-    h63SigNpmMvd1->SetMaximum(yMax);
-    h63SigNpmSt->SetMinimum(yMin);
-    h63SigNpmSt->SetMaximum(yMax);
-    h63SigNpmRt->SetMinimum(yMin);
-    h63SigNpmRt->SetMaximum(yMax);
-    h63SigNpmTt->SetMinimum(yMin);
-    h63SigNpmTt->SetMaximum(yMax);
-    h63SigNpmPt->SetMinimum(yMin);
-    h63SigNpmPt->SetMaximum(yMax);
-    h63SigNpmPt2->SetMinimum(yMin);
-    h63SigNpmPt2->SetMaximum(yMax);
+  // Draw CombBg vs Cocktail+Bg vs combBg(Asm)
+  {
+    for (auto step : fHMean.fAnaSteps) {
+      if (step < ELmvmAnaStep::ElId) continue;
+      TH1D* cbg    = fHMean.H1Clone("hMinvCombBg", step);
+      TH1D* cbgAsm = fHMean.H1Clone("hMinvCombBgAsm", step);
+      TH1D* sbg    = GetCocktailMinvH1(step);
+      sbg->Add(fHMean.H1("hMinv", ELmvmSrc::Bg, step));
+      cbg->Rebin(20);
+      cbgAsm->Rebin(20);
+      sbg->Rebin(20);
+
+      TH1D* ratio1 = static_cast<TH1D*>(sbg->Clone());
+      TH1D* ratio2 = static_cast<TH1D*>(sbg->Clone());
+
+      string cName = "lmvmAll_minvCombBgVsSBgVsCombBgAsm_" + fHMean.fAnaStepNames[static_cast<int>(step)];
+      TCanvas* c   = fHMean.fHM.CreateCanvas(cName.c_str(), cName.c_str(), 1800, 900);
+      c->Divide(2, 1);
+      c->cd(1);
+      DrawH1({cbg, sbg, cbgAsm}, {"CombBG", "Cocktail + BG", "CombBG(Asm)"}, kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99,
+             "HIST");
+      c->cd(2);
+      ratio1->Divide(cbg);
+      ratio2->Divide(cbgAsm);
+      DrawH1({ratio1, ratio2}, {"Cocktail+BG/CombBG", "Cocktail+BG/CombBG(Asm)"}, kLinear, kLog, true, 0.65, 0.85, 0.99,
+             0.99, "HIST");
+
+      fHMean.DrawAnaStepOnPad(step);
+    }
   }
 
-  h63SigNpmElid->GetXaxis()->SetRangeUser(0, 2.);
-  h63SigNpmElid->GetXaxis()->SetTitle(xTitle.c_str());
-  h63SigNpmElid->GetYaxis()->SetTitle(yTitle.c_str());
-  h63SigNpmElid->SetTitle("Signal");
-  h63SigNpmPt2->GetXaxis()->SetRangeUser(0, 2.);
-  h63SigNpmPt2->GetXaxis()->SetTitle(xTitle.c_str());
-  h63SigNpmPt2->GetYaxis()->SetTitle(yTitle.c_str());
-  h63SigNpmPt2->SetTitle("Signal");
-
-  fHM[0]->CreateCanvas("minv_CB_6_signal_Npm_steps", "minv_CB_6_signal_Npm_steps", 800, 800);
-  DrawH1({h63SigNpmElid, h63SigNpmGamma, h63SigNpmMvd1, h63SigNpmSt, h63SigNpmRt, h63SigNpmTt, h63SigNpmPt},
-         {"", "", "", "", "", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legend63 = new TLegend(0.7, 0.6, 0.92, 0.9);
-  legend63->SetFillColor(kWhite);
-  legend63->AddEntry(h63SigNpmElid, "elid");
-  legend63->AddEntry(h63SigNpmGamma, "gamma cut");
-  legend63->AddEntry(h63SigNpmMvd1, "MVD1 cut");
-  legend63->AddEntry(h63SigNpmSt, "ST cut");
-  legend63->AddEntry(h63SigNpmRt, "Rt cut");
-  legend63->AddEntry(h63SigNpmTt, "Tt cut");
-  legend63->AddEntry(h63SigNpmPt, "P_{t} cut");
-  legend63->Draw();
-
-  fHM[0]->CreateCanvas("minv_CB_6_signal_Npm_steps2", "minv_CB_6_signal_Npm_steps2", 800, 800);
-  DrawH1({h63SigNpmElid, h63SigNpmGamma, h63SigNpmMvd1, h63SigNpmSt, h63SigNpmRt, h63SigNpmTt, h63SigNpmPt},
-         {"", "", "", "", "", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "hist pe1");
-
-  TLegend* legend63e = new TLegend(0.7, 0.6, 0.92, 0.9);
-  legend63e->SetFillColor(kWhite);
-  legend63e->AddEntry(h63SigNpmElid, "elid");
-  legend63e->AddEntry(h63SigNpmGamma, "gamma cut");
-  legend63e->AddEntry(h63SigNpmMvd1, "MVD1 cut");
-  legend63e->AddEntry(h63SigNpmSt, "ST cut");
-  legend63e->AddEntry(h63SigNpmRt, "Rt cut");
-  legend63e->AddEntry(h63SigNpmTt, "Tt cut");
-  legend63e->AddEntry(h63SigNpmPt, "P_{t} cut");
-  legend63e->Draw();
-
-  fHM[0]->CreateCanvas("minv_CB_6_signal_Npm_steps3", "minv_CB_6_signal_Npm_steps3", 800, 800);
-  DrawH1({h63SigNpmElid}, {""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "hist pe1");
-
-  TLegend* legend63e3 = new TLegend(0.7, 0.8, 0.92, 0.9);
-  legend63e3->SetFillColor(kWhite);
-  legend63e3->AddEntry(h63SigNpmElid, "elid");
-  legend63e3->Draw();
-
-  fHM[0]->CreateCanvas("minv_CB_6_signal_Npm_steps4", "minv_CB_6_signal_Npm_steps4", 800,
-                       800);  // Wenn aktiviert, sind Elid- und Pt-Kurven oben beide gleichfarbig
-  DrawH1({h63SigNpmPt2}, {""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "hist pe1");
-
-  TLegend* legend63e4 = new TLegend(0.7, 0.8, 0.92, 0.9);
-  legend63e4->SetFillColor(kWhite);
-  legend63e4->AddEntry(h63SigNpmPt2, "P_{t} cut");
-  legend63e4->Draw();
-
-  // from 'Cocktail + BG'
-  // elid
-  TH1D* h65SigCocBgElid = (TH1D*) fh_mean_combSignalBCoc_assemb_minv[kElId]->Clone();
-  TH1D* h65cbAssElid    = (TH1D*) fh_mean_combBg_assemb_minv[kElId]->Clone();
-  TH1D* h65cocBgElid    = (TH1D*) GetCoctailMinv(kElId);
-  TH1D* h65coc1Elid     = (TH1D*) GetCoctailMinv(kElId);
-
-  h65cocBgElid->Add(fh_mean_bg_minv[kElId]);
-
-  h65coc1Elid->Add(fh_mean_bg_minv[kElId]);
-  h65coc1Elid->Add(fh_mean_bg_minv[kElId], -1.);
-
-  h65cocBgElid->Rebin(nRebin);
-  h65cocBgElid->Scale(1. / bW);
-  h65coc1Elid->Rebin(nRebin);
-  h65coc1Elid->Scale(1. / bW);
-
-  if (setMinMax) {
-    h65cocBgElid->SetMinimum(yMin);
-    h65cocBgElid->SetMaximum(yMax);
-  }
 
-  h65cocBgElid->GetXaxis()->SetRangeUser(0, 2.);
-  h65cocBgElid->GetYaxis()->SetTitle(yTitle.c_str());
-  h65cocBgElid->SetTitle(0);
-
-  fHM[0]->CreateCanvas("minv_CB_6_signal_bgCoc_elid", "minv_CB_6_signal_bgCoc_elid", 800, 800);
-  DrawH1({h65cocBgElid, h65cbAssElid, h65SigCocBgElid, h65coc1Elid}, {"", "", "", ""}, kLinear, kLog, false, 0.8, 0.8,
-         0.99, 0.99, "");
-
-  /*h65coc1Elid->SetFillColor(kMagenta - 3);
-  h65coc1Elid->SetLineColor(kMagenta - 2);
-  h65coc1Elid->SetLineStyle(1);
-  h65coc1Elid->SetLineWidth(3);
-  h65coc1Elid->SetFillStyle(3344);*/
-
-  h65cocBgElid->SetLineStyle(0);
-  h65cbAssElid->SetLineStyle(2);
-  h65SigCocBgElid->SetLineStyle(3);
-  h65coc1Elid->SetLineStyle(1);
-
-  TLegend* legend65 = new TLegend(0.55, 0.75, 0.98, 0.9);
-  //legend65->SetFillColor(kWhite);
-  legend65->AddEntry(h65cocBgElid, "Cocktail + BG (Elid)");
-  legend65->AddEntry(h65cbAssElid, "B_{c} (assembled, Elid)");
-  legend65->AddEntry(h65SigCocBgElid, "Signal (Coc + BG - B_{c}, Elid)");
-  legend65->AddEntry(h65coc1Elid, "Cocktail (Elid)");
-  legend65->Draw();
-
-  // Pt cut
-  TH1D* h66SigCocBgPt = (TH1D*) fh_mean_combSignalBCoc_assemb_minv[kPtCut]->Clone();
-  TH1D* h66cbAssPt    = (TH1D*) fh_mean_combBg_assemb_minv[kPtCut]->Clone();
-  TH1D* h66cocBgPt    = (TH1D*) GetCoctailMinv(kPtCut);
-  h66cocBgPt->Add(fh_mean_bg_minv[kPtCut]);
-
-  h66cocBgPt->Rebin(nRebin);
-  h66cocBgPt->Scale(1. / bW);
-
-  if (setMinMax) {
-    h66cocBgPt->SetMinimum(yMin);
-    h66cocBgPt->SetMaximum(yMax);
+  //Draw k factor
+  {
+    fHMean.fHM.CreateCanvas("lmvmAll_minvCombK", "lmvmAll_minvCombK", 1000, 1000);
+    vector<string> legend;
+    vector<TH1*> hists;
+    for (auto step : fHMean.fAnaSteps) {
+      if (step < ELmvmAnaStep::Reco) continue;
+      hists.push_back(fHMean.H1Clone("hMinvCombK", step));
+      hists.back()->Rebin(20);
+      legend.push_back(fHMean.fAnaStepLatex[static_cast<int>(step)]);
+    }
+    hists[0]->GetXaxis()->SetTitle("M_{ee}");
+    hists[0]->GetYaxis()->SetTitle("k factor");
+    DrawH1(hists, legend, kLinear, kLinear, true, 0.8, 0.6, 0.99, 0.99, "HIST");
+  }
+
+  //Draw Combinatorial Signal from N+-same
+  {
+    TCanvas* c = fHMean.fHM.CreateCanvas("lmvmAll_minvCombPMSignalAsm", "lmvmAll_minvCombPMSignalAsm", 1800, 1800);
+    c->Divide(3, 3);
+    int i = 1;
+    for (auto step : fHMean.fAnaSteps) {
+      if (step < ELmvmAnaStep::ElId) continue;
+      c->cd(i++);
+      TH1D* pmSame          = fHMean.H1Clone("hMinvCombPM_sameEv", step);
+      TH1D* combPMSignalAsm = fHMean.H1Clone("hMinvCombPMSignalAsm", step);
+      TH1D* combBgAsm       = fHMean.H1Clone("hMinvCombBgAsm", step);
+      TH1D* coctail         = GetCocktailMinvH1(step);
+      pmSame->Rebin(20);
+      combBgAsm->Rebin(20);
+      combPMSignalAsm->Rebin(20);
+      coctail->Rebin(20);
+      DrawH1({pmSame, combBgAsm, combPMSignalAsm, coctail},
+             {"N_{same}^{+-}", "B_{c} (asm)", "Signal (N_{same}^{+-} - B_{c})", "Cocktail"}, kLinear, kLog, true, 0.8,
+             0.8, 0.99, 0.99, "hist");
+      fHMean.DrawAnaStepOnPad(step);
+    }
   }
 
-  h66cocBgPt->GetXaxis()->SetRangeUser(0, 2.);
-  h66cocBgPt->GetYaxis()->SetTitle(yTitle.c_str());
-  h66cocBgPt->SetTitle(0);
-
-  fHM[0]->CreateCanvas("minv_CB_6_signal_bgCoc_pt", "minv_CB_6_signal_bgCoc_pt", 800, 800);
-  DrawH1({h66cocBgPt, h66cbAssPt, h66SigCocBgPt}, {"", "", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legend66 = new TLegend(0.55, 0.75, 0.98, 0.9);
-  legend66->SetFillColor(kWhite);
-  legend66->AddEntry(h66cocBgPt, "Cocktail + BG (P_{t})");
-  legend66->AddEntry(h66cbAssPt, "B_{c} (assembled, P_{t})");
-  legend66->AddEntry(h66SigCocBgPt, "Signal (Coc + BG - B_{c}, P_{t})");
-  legend66->Draw();
-
-  /* 7) Error */
-  TH1D* h71NpmElid = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[kElId]->Clone();
-  TH1D* h71sigElid = (TH1D*) fh_mean_combSignal_errProp_minv[kElId]->Clone();
-
-  h71NpmElid->GetXaxis()->SetRangeUser(0, 2.);
-  h71NpmElid->GetXaxis()->SetTitle(xTitle.c_str());
-  h71NpmElid->GetYaxis()->SetTitle(yTitle.c_str());
-  h71NpmElid->SetTitle(0);
-
-  for (int iBin = 1; iBin <= nofBins; iBin++) {
-    double errNpm = h71NpmElid->GetBinError(iBin);
-    h71NpmElid->SetBinContent(iBin, errNpm);
+  //Draw Combinatorial Signal from Cocktail+BG
+  {
+    TCanvas* c = fHMean.fHM.CreateCanvas("lmvmAll_minvSbgSignalAsm", "lmvmAll_minvSbgSignalAsm", 1800, 1800);
+    c->Divide(3, 3);
+    int i = 1;
+    for (auto step : fHMean.fAnaSteps) {
+      if (step < ELmvmAnaStep::ElId) continue;
+      c->cd(i++);
+      TH1D* sbg = fHMean.H1Clone("hMinv_bg", step);
+      sbg->Add(GetCocktailMinvH1(step));
+      TH1D* combBgAsm    = fHMean.H1Clone("hMinvCombBgAsm", step);
+      TH1D* sBgSignalAsm = fHMean.H1Clone("hMinvSBgSignalAsm", step);
+      TH1D* coctail      = GetCocktailMinvH1(step);
+      sbg->Rebin(20);
+      combBgAsm->Rebin(20);
+      sBgSignalAsm->Rebin(20);
+      coctail->Rebin(20);
+      DrawH1({sbg, combBgAsm, sBgSignalAsm, coctail},
+             {"Cocktail + BG", "B_{c} (asm)", "Signal (Cocktail+BG - B_{c})", "Cocktail"}, kLinear, kLog, true, 0.8,
+             0.8, 0.99, 0.99, "hist");
+      fHMean.DrawAnaStepOnPad(step);
+    }
   }
-
-  fHM[0]->CreateCanvas("minv_CB_7_error", "minv_CB_7_error", 800, 800);
-  DrawH1({h71NpmElid, h71sigElid}, {"", ""}, kLinear, kLog, false, 0.8, 0.8, 0.99, 0.99, "hist p");
-
-  TLegend* legend71 = new TLegend(0.55, 0.75, 0.98, 0.9);
-  legend71->SetFillColor(kWhite);
-  legend71->AddEntry(h71NpmElid, "error N^{+-}_{same} (Elid)");
-  legend71->AddEntry(h71sigElid, "error Signal = N^{+-}_{same} - B_{c} (Elid)");
-  legend71->Draw();
 }
 
-void CbmAnaDielectronTaskDrawAll::DrawSBgVsMinv()
+void LmvmDrawAll::DrawSBgVsMinv()
 {
-  TH1D* bg      = (TH1D*) fh_mean_bg_minv[kTtCut]->Clone();
-  TH1D* combBg  = (TH1D*) fh_mean_combBg_minv[kTtCut]->Clone();
-  TH1D* coctail = GetCoctailMinv(kTtCut);
-
-  fh_mean_sbg_vs_minv[kTtCut] =
-    new TH1D(("fh_sbg_vs_minv_" + CbmLmvmHist::fAnaSteps[kTtCut]).c_str(),
-             ("fh_sbg_vs_minv_" + CbmLmvmHist::fAnaSteps[kTtCut] + ";M_{ee} [GeV/c^{2}];Cocktail/Background").c_str(),
-             bg->GetNbinsX(), bg->GetXaxis()->GetXmin(), bg->GetXaxis()->GetXmax());
-  fh_mean_sbg_vs_minv[kTtCut]->Divide(coctail, bg, 1., 1., "B");
-  fh_mean_sbg_vs_minv[kTtCut]->Rebin(20);
-  fh_mean_sbg_vs_minv[kTtCut]->Scale(1. / 20.);
-  fh_mean_sbg_vs_minv[kTtCut]->GetXaxis()->SetRangeUser(0, 2.);
-
-  fh_mean_combSBg_vs_minv[kAcc] =
-    new TH1D(("fh_combSBg_vs_minv_" + CbmLmvmHist::fAnaSteps[kAcc]).c_str(),
-             ("fh_combSBg_vs_minv_" + CbmLmvmHist::fAnaSteps[kAcc] + ";M_{ee} [GeV/c^{2}];Cocktail/comb. BG").c_str(),
-             bg->GetNbinsX(), bg->GetXaxis()->GetXmin(), bg->GetXaxis()->GetXmax());
-  fh_mean_combSBg_vs_minv[kAcc]->Divide(coctail, combBg, 1., 1., "B");
-  fh_mean_combSBg_vs_minv[kAcc]->Rebin(20);
-  fh_mean_combSBg_vs_minv[kAcc]->Scale(1. / 20.);
-  fh_mean_combSBg_vs_minv[kAcc]->GetXaxis()->SetRangeUser(0, 2.);
-
-  bg      = (TH1D*) fh_mean_bg_minv[kPtCut]->Clone();
-  combBg  = (TH1D*) fh_mean_combBg_minv[kPtCut]->Clone();
-  coctail = GetCoctailMinv(kPtCut);
-
-  fh_mean_sbg_vs_minv[kPtCut] =
-    new TH1D(("fh_sbg_vs_minv_" + CbmLmvmHist::fAnaSteps[kPtCut]).c_str(),
-             ("fh_sbg_vs_minv_" + CbmLmvmHist::fAnaSteps[kPtCut] + ";M_{ee} [GeV/c^{2}];Cocktail/Background").c_str(),
-             bg->GetNbinsX(), bg->GetXaxis()->GetXmin(), bg->GetXaxis()->GetXmax());
-  fh_mean_sbg_vs_minv[kPtCut]->Divide(coctail, bg, 1., 1., "B");
-  fh_mean_sbg_vs_minv[kPtCut]->Rebin(20);
-  fh_mean_sbg_vs_minv[kPtCut]->Scale(1. / 20.);
-  fh_mean_sbg_vs_minv[kPtCut]->GetXaxis()->SetRangeUser(0, 2.);
-
-  /*fh_mean_combSBg_vs_minv[kPtCut] = new TH1D(
-    ("fh_combSBg_vs_minv_" + CbmLmvmHist::fAnaSteps[kPtCut]).c_str(),
-    ("fh_combSBg_vs_minv_" + CbmLmvmHist::fAnaSteps[kPtCut] + ";M_{ee} [GeV/c^{2}];Cocktail/comb. Background").c_str(),
-    bg->GetNbinsX(), bg->GetXaxis()->GetXmin(), bg->GetXaxis()->GetXmax());
-  fh_mean_combSBg_vs_minv[kPtCut]->Divide(coctail, combBg, 1., 1., "B");
-  fh_mean_combSBg_vs_minv[kPtCut]->Rebin(20);
-  fh_mean_combSBg_vs_minv[kPtCut]->Scale(1. / 20.);
-  fh_mean_combSBg_vs_minv[kPtCut]->GetXaxis()->SetRangeUser(0, 2.);*/
-
-  fHM[0]->CreateCanvas("lmvm_sbg_vs_minv", "lmvm_sbg_vs_minv", 800, 800);
-  DrawH1({fh_mean_sbg_vs_minv[kTtCut], fh_mean_sbg_vs_minv[kPtCut]}, {"Without Pt cut", "With Pt cut"}, kLinear, kLog,
-         true, 0.6, 0.85, 0.99, 0.99);
-  gPad->SetLogy(true);
-
-  /*fHM[0]->CreateCanvas("lmvm_sbgComb_vs_minv", "lmvm_sbgComb_vs_minv", 800, 800);
-  DrawH1({fh_mean_combSBg_vs_minv[kAcc], fh_mean_combSBg_vs_minv[kPtCut]}, {"Without Pt cut", "With Pt cut"}, kLinear,
-         kLog, true, 0.6, 0.85, 0.99, 0.99);*/
-  gPad->SetLogy(true);
-}
-
-void CbmAnaDielectronTaskDrawAll::DrawMinvPtAll()
-{
-  fHM[0]->CreateCanvas("minv_pt_ptcut", "minv_pt_ptcut", 800, 800);
-  DrawMinvPt(kPtCut);
-}
-
-void CbmAnaDielectronTaskDrawAll::DrawMinvPt(CbmLmvmAnalysisSteps step)
-{
-  TH2D* sInmed = (TH2D*) H2(kInmed, "fh_signal_minv_pt_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH2D* sQgp   = (fDrawQgp) ? (TH2D*) H2(kQgp, "fh_signal_minv_pt_" + CbmLmvmHist::fAnaSteps[step])->Clone() : nullptr;
-  TH2D* sOmega = (TH2D*) H2(kOmega, "fh_signal_minv_pt_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH2D* sOmegaDalitz = (TH2D*) H2(kOmegaD, "fh_signal_minv_pt_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH2D* sPhi         = (TH2D*) H2(kPhi, "fh_signal_minv_pt_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-  TH2D* sEta         = fh_mean_eta_minv_pt[step];
-  TH2D* sPi0         = fh_mean_pi0_minv_pt[step];
-  TH2D* coctail      = (TH2D*) sInmed->Clone();
-  if (fDrawQgp) coctail->Add(sQgp);
-  coctail->Add(sOmega);
-  coctail->Add(sPhi);
-  coctail->Add(sOmegaDalitz);
-  coctail->Add(sEta);
-  coctail->Add(sPi0);
-  DrawH2(coctail);
+  vector<TH1*> hists;
+  for (ELmvmAnaStep step : {ELmvmAnaStep::TtCut, ELmvmAnaStep::PtCut}) {
+    TH1D* bg = fHMean.H1Clone("hMinv", ELmvmSrc::Bg, step);
+    //TH1D* combBg  = fHMean.H1Clone("hMinvCombBg", step);
+    TH1D* coctail        = GetCocktailMinvH1(step);
+    TH1D* cocktailOverBg = fHMean.CreateHByClone<TH1D>("hMinv_bg", "hMinvCoctailOverBg", step);
+    bg->Rebin(20);
+    coctail->Rebin(20);
+    cocktailOverBg->Rebin(20);
+    cocktailOverBg->GetYaxis()->SetTitle("Cocktail/Background");
+    cocktailOverBg->Divide(coctail, bg, 1., 1., "B");
+    hists.push_back(cocktailOverBg);
+  }
+
+  fHMean.fHM.CreateCanvas("lmvmAll_minvCoctailOverBg", "lmvmAll_minvCoctailOverBg", 1000, 1000);
+  DrawH1(hists, {"Without Pt cut", "With Pt cut"}, kLinear, kLog, true, 0.6, 0.85, 0.99, 0.99, "hist");
 }
 
-void CbmAnaDielectronTaskDrawAll::FillMeanHist()
-{
-  for (int step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    for (int iS = 0; iS < fNofSignals; iS++) {
-      if (!fDrawQgp && iS == kQgp) continue;
-      if (iS == 0) {
-        fh_mean_bg_minv[step]     = (TH1D*) H1(iS, "fh_bg_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_eta_minv[step]    = (TH1D*) H1(iS, "fh_eta_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_pi0_minv[step]    = (TH1D*) H1(iS, "fh_pi0_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_eta_minv_pt[step] = (TH2D*) H2(iS, "fh_eta_minv_pt_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_pi0_minv_pt[step] = (TH2D*) H2(iS, "fh_pi0_minv_pt_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_combPairsPM_sameEvent_minv[step] =
-          (TH1D*) H1(iS, "fh_combPairsPM_minv_sameEvent_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_combPairsPP_sameEvent_minv[step] =
-          (TH1D*) H1(iS, "fh_combPairsPP_minv_sameEvent_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_combPairsMM_sameEvent_minv[step] =
-          (TH1D*) H1(iS, "fh_combPairsMM_minv_sameEvent_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_combPairsPM_mixedEvents_minv[step] =
-          (TH1D*) H1(iS, "fh_combPairsPM_minv_mixedEvents_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_combPairsPP_mixedEvents_minv[step] =
-          (TH1D*) H1(iS, "fh_combPairsPP_minv_mixedEvents_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_combPairsMM_mixedEvents_minv[step] =
-          (TH1D*) H1(iS, "fh_combPairsMM_minv_mixedEvents_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_nof_plutoElectrons[step] =
-          (TH1D*) H1(iS, "fh_nof_plutoElectrons_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_nof_plutoPositrons[step] =
-          (TH1D*) H1(iS, "fh_nof_plutoPositrons_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_nof_urqmdElectrons[step] =
-          (TH1D*) H1(iS, "fh_nof_urqmdElectrons_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-        fh_mean_nof_urqmdPositrons[step] =
-          (TH1D*) H1(iS, "fh_nof_urqmdPositrons_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-      }
-      else {
-        fh_mean_bg_minv[step]->Add((TH1D*) H1(iS, "fh_bg_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_eta_minv[step]->Add((TH1D*) H1(iS, "fh_eta_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_pi0_minv[step]->Add((TH1D*) H1(iS, "fh_pi0_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_eta_minv_pt[step]->Add((TH2D*) H2(iS, "fh_eta_minv_pt_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_pi0_minv_pt[step]->Add((TH2D*) H2(iS, "fh_pi0_minv_pt_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_combPairsPM_sameEvent_minv[step]->Add(
-          (TH1D*) H1(iS, "fh_combPairsPM_minv_sameEvent_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_combPairsPP_sameEvent_minv[step]->Add(
-          (TH1D*) H1(iS, "fh_combPairsPP_minv_sameEvent_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_combPairsMM_sameEvent_minv[step]->Add(
-          (TH1D*) H1(iS, "fh_combPairsMM_minv_sameEvent_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_combPairsPM_mixedEvents_minv[step]->Add(
-          (TH1D*) H1(iS, "fh_combPairsPM_minv_mixedEvents_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_combPairsPP_mixedEvents_minv[step]->Add(
-          (TH1D*) H1(iS, "fh_combPairsPP_minv_mixedEvents_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_combPairsMM_mixedEvents_minv[step]->Add(
-          (TH1D*) H1(iS, "fh_combPairsMM_minv_mixedEvents_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_nof_plutoElectrons[step]->Add(
-          (TH1D*) H1(iS, "fh_nof_plutoElectrons_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_nof_plutoPositrons[step]->Add(
-          (TH1D*) H1(iS, "fh_nof_plutoPositrons_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_nof_urqmdElectrons[step]->Add(
-          (TH1D*) H1(iS, "fh_nof_urqmdElectrons_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-        fh_mean_nof_urqmdPositrons[step]->Add(
-          (TH1D*) H1(iS, "fh_nof_urqmdPositrons_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-      }
-    }
-
-    Int_t nofEvents = 0;
-    for (int i = 0; i < fNofSignals; i++) {
-      if (!fDrawQgp && i == kQgp) continue;
-      nofEvents += (int) H1(i, "fh_event_number")->GetEntries();
-      cout << "FillMeanHist: nofEvents = " << nofEvents << endl;
-    }
-    cout << "FillMeanHist: final nofEvents = " << nofEvents << endl;
-
-    // Scaling; Comb. BG histograms are scaled in CalcCombBGHistos()
-    fh_mean_bg_minv[step]->Scale(1. / (double) (nofEvents));
-    fh_mean_eta_minv[step]->Scale(1. / (double) (nofEvents));
-    fh_mean_pi0_minv[step]->Scale(1. / (double) (nofEvents));
-    fh_mean_eta_minv_pt[step]->Scale(1. / (double) (nofEvents));
-    fh_mean_pi0_minv_pt[step]->Scale(1. / (double) (nofEvents));
-    fh_mean_nof_plutoElectrons[step]->Scale(1. / (double) (nofEvents));
-    fh_mean_nof_plutoPositrons[step]->Scale(1. / (double) (nofEvents));
-    fh_mean_nof_urqmdElectrons[step]->Scale(1. / (double) (nofEvents));
-    fh_mean_nof_urqmdPositrons[step]->Scale(1. / (double) (nofEvents));
-  }  // steps
-}
-
-void CbmAnaDielectronTaskDrawAll::SaveHist()
+void LmvmDrawAll::SaveHist()
 {
   if (fOutputDir != "") {
     gSystem->mkdir(fOutputDir.c_str(), true);
     TFile* f = TFile::Open(string(fOutputDir + "/draw_all_hist.root").c_str(), "RECREATE");
-    for (int i = 0; i < CbmLmvmHist::fNofAnaSteps; i++) {
-      fh_mean_bg_minv[i]->Write();
-      fh_mean_combBg_minv[i]->Write();
-      fh_mean_combBg_GeomMeanSame_minv[i]->Write();
-      fh_mean_combBg_GeomMeanMixed_minv[i]->Write();
-      //fh_mean_combSignalNpm_minv[i]->Write();
-      fh_mean_eta_minv[i]->Write();
-    }
-    fh_mean_sbg_vs_minv[kTtCut]->Write();
-    fh_mean_sbg_vs_minv[kPtCut]->Write();
+    fHMean.WriteToFile();
     f->Close();
   }
 }
 
-void CbmAnaDielectronTaskDrawAll::FillSumSignalsHist()
-{
-  for (int step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    fh_sum_s_minv[step] = (TH1D*) H1(kInmed, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-    if (fDrawQgp) fh_sum_s_minv[step]->Add((TH1D*) H1(kQgp, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-    fh_sum_s_minv[step]->Add((TH1D*) H1(kOmega, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-    fh_sum_s_minv[step]->Add((TH1D*) H1(kPhi, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-    fh_sum_s_minv[step]->Add((TH1D*) H1(kOmegaD, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone());
-    fh_sum_s_minv[step]->Add((TH1D*) fh_mean_eta_minv[step]->Clone());
-    fh_sum_s_minv[step]->Add((TH1D*) fh_mean_pi0_minv[step]->Clone());
-  }
-}
-
-void CbmAnaDielectronTaskDrawAll::CalcCutEffRange(Double_t minMinv, Double_t maxMinv)
+void LmvmDrawAll::CalcCombBGHistos()
 {
-  stringstream ss1;
-  ss1 << minMinv << "_" << maxMinv;
-  TH1D* grS = new TH1D(("grS_" + ss1.str()).c_str(), ";Analysis step;Efficiency [%]", CbmLmvmHist::fNofAnaSteps, 0,
-                       CbmLmvmHist::fNofAnaSteps);
-  TH1D* grB = new TH1D(("grB_" + ss1.str()).c_str(), ";Analysis step;Efficiency [%]", CbmLmvmHist::fNofAnaSteps, 0,
-                       CbmLmvmHist::fNofAnaSteps);
-  int x     = 1;
-  for (int step = kElId; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) { continue; }
-    Int_t x1 = fh_sum_s_minv[step]->FindBin(minMinv);
-    Int_t x2 = fh_sum_s_minv[step]->FindBin(maxMinv);
-
-    double yS = 100. * fh_sum_s_minv[step]->Integral(x1, x2) / fh_sum_s_minv[kElId]->Integral(x1, x2);
-    double yB = 100. * fh_mean_bg_minv[step]->Integral(x1, x2) / fh_mean_bg_minv[kElId]->Integral(x1, x2);
-
-    grB->GetXaxis()->SetBinLabel(x, CbmLmvmHist::fAnaStepsLatex[step].c_str());
-    grB->SetBinContent(x, yB);
-    grS->SetBinContent(x, yS);
-    x++;
-  }
-
-  grB->GetXaxis()->SetLabelSize(0.06);
-  grB->GetXaxis()->SetRange(1, x - 1);
-  grS->GetXaxis()->SetRange(1, x - 1);
-
-  stringstream ss;
-  ss << "lmvm_cut_eff_" << minMinv << "_" << maxMinv;
-  fHM[0]->CreateCanvas(ss.str().c_str(), ss.str().c_str(), 700, 700);
-  DrawH1({grB, grS}, {"BG", "Signal"}, kLinear, kLinear, true, 0.75, 0.85, 1.0, 1.0);
-  grS->SetLineWidth(4);
-  grB->SetLineWidth(4);
-  grB->SetMinimum(1);
-  grB->SetMaximum(105);
-
-  stringstream ss2;
-  ss2 << minMinv << "<M [GeV/c^2]<" << maxMinv;
-  TText* t = new TText(0.5, 110, ss2.str().c_str());
-  t->Draw();
-}
-
-void CbmAnaDielectronTaskDrawAll::CalcCombBGHistos()
-{
-  int nofBins;
-  double bW       = 0;
-  Int_t nofEvents = 0;
-  for (int i = 0; i < fNofSignals; i++) {
-    if (!fDrawQgp && i == kQgp) continue;
-    nofEvents += (int) H1(i, "fh_event_number")->GetEntries();
-    cout << "CalcCombBGHistos: nofEvents = " << nofEvents << endl;
-  }
-
-  // first convert MeV into Bin for later normalization
-  int nBinsOrig  = 4000;  // was set in CbmAnaDielectronTask.cxx
-  int upperLimit = 4000;  // in MeV (assumed, that lower limit of histo = 0)
-
-  int rFrom      = 300;  // lower and upper range to normalize (in Mev/c^2)
-  int rTo        = 1000;
-  double binFrom = (double) (1. * nBinsOrig / nRebin) * (1. * rFrom / upperLimit);
-  double binTo   = (double) (1. * nBinsOrig / nRebin) * (1. * rTo / upperLimit);
-
-  for (Int_t step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    fh_mean_combPairsPM_sameEvent_minv[step]->Rebin(nRebin);
-    fh_mean_combPairsPP_sameEvent_minv[step]->Rebin(nRebin);
-    fh_mean_combPairsMM_sameEvent_minv[step]->Rebin(nRebin);
-    fh_mean_combPairsPM_mixedEvents_minv[step]->Rebin(nRebin);
-    fh_mean_combPairsPP_mixedEvents_minv[step]->Rebin(nRebin);
-    fh_mean_combPairsMM_mixedEvents_minv[step]->Rebin(nRebin);
-
-    /*fh_mean_combPairsPM_sameEvent_minv_raw[step]->Rebin(nRebin);
-    fh_mean_combPairsPP_sameEvent_minv_raw[step]->Rebin(nRebin);
-    fh_mean_combPairsMM_sameEvent_minv_raw[step]->Rebin(nRebin);
-    fh_mean_combPairsPM_mixedEvents_minv_raw[step]->Rebin(nRebin);
-    fh_mean_combPairsPP_mixedEvents_minv_raw[step]->Rebin(nRebin);
-    fh_mean_combPairsMM_mixedEvents_minv_raw[step]->Rebin(nRebin);*/
-
-    //int nofBins = hBpp->GetNbinsX();  	TODO: test; delete
-    //nofBinsRaw = fh_mean_combPairsPM_sameEvent_minv_raw[step]->GetNbinsX(); _RAW_
-    nofBins = fh_mean_combPairsPM_sameEvent_minv[step]->GetNbinsX();  // MIND: 'nofBins' is used throughout this method!
-
-    // calculate geom. mean of same events
-    TH1D* hBpp = (TH1D*) fh_mean_combPairsPP_sameEvent_minv[step]->Clone();
-    TH1D* hBmm = (TH1D*) fh_mean_combPairsMM_sameEvent_minv[step]->Clone();
-
-    fh_mean_combBg_GeomMeanSame_minv[step] = (TH1D*) hBpp->Clone();
-
-    for (int iBin = 1; iBin <= nofBins; iBin++) {
-      double m1      = hBpp->GetBinContent(iBin);
-      double m2      = hBmm->GetBinContent(iBin);
-      double content = TMath::Sqrt(m1 * m2);
-      fh_mean_combBg_GeomMeanSame_minv[step]->SetBinContent(iBin, content);
-    }
-
-    // calculate geom. mean of mixed events
-    TH1D* hbpp = (TH1D*) fh_mean_combPairsPP_mixedEvents_minv[step]->Clone();
-    TH1D* hbmm = (TH1D*) fh_mean_combPairsMM_mixedEvents_minv[step]->Clone();
-
-    fh_mean_combBg_GeomMeanMixed_minv[step] = (TH1D*) hbpp->Clone();
-
-    for (int iBin = 1; iBin <= nofBins; iBin++) {
-      double m1      = hbpp->GetBinContent(iBin);
-      double m2      = hbmm->GetBinContent(iBin);
-      double content = 0;
-      if (m1 == 0 && m2 != 0) content = m2;
-      else if (m1 != 0 && m2 == 0)
-        content = m1;
-      else
-        content = TMath::Sqrt(m1 * m2);
-      fh_mean_combBg_GeomMeanMixed_minv[step]->SetBinContent(iBin, content);
+  // TODO : think about normalization
+  //int nofEvents = GetNofTotalEvents();
+
+  // Geometrical mean
+  for (ELmvmAnaStep step : fHMean.fAnaSteps) {
+    for (const string& ev : {"sameEv", "mixedEv"}) {
+      TH1D* pp   = fHMean.H1Clone("hMinvCombPP_" + ev, step);
+      TH1D* mm   = fHMean.H1Clone("hMinvCombMM_" + ev, step);
+      TH1D* geom = fHMean.CreateHByClone<TH1D>("hMinvCombMM_" + ev, "hMinvCombGeom_" + ev, step);
+      for (int i = 1; i <= geom->GetNbinsX(); i++) {
+        double cpp     = pp->GetBinContent(i);
+        double cmm     = mm->GetBinContent(i);
+        double content = std::sqrt(cpp * cmm);
+        if (cpp == 0 && cmm != 0) content = cmm;
+        else if (cpp != 0 && cmm == 0)
+          content = cpp;
+        geom->SetBinContent(i, content);
+      }
     }
 
-    // normalization factor for same/mixed geom. mean
-    double intSameGM  = fh_mean_combBg_GeomMeanSame_minv[step]->Integral(binFrom, binTo);
-    double intMixedGM = fh_mean_combBg_GeomMeanMixed_minv[step]->Integral(binFrom, binTo);
-    double normGM     = (double) intSameGM / intMixedGM;
-    cout << "step " << step << ": normGM = " << normGM << endl;
+    // 300 - 1000 MeV/c2 interval
+    TH1D* hGeomSame  = fHMean.H1("hMinvCombGeom_sameEv", step);
+    TH1D* hGeomMixed = fHMean.H1("hMinvCombGeom_mixedEv", step);
+    int minBin       = hGeomSame->FindBin(0.3);
+    int maxBin       = hGeomSame->FindBin(1.0);
+    double normGM    = hGeomSame->Integral(minBin, maxBin) / hGeomMixed->Integral(minBin, maxBin);
 
     // calculate k factor
-    TH1D* k = (TH1D*) fh_mean_combPairsPM_mixedEvents_minv[step]->Clone();
-    k->Divide(fh_mean_combBg_GeomMeanMixed_minv[step]);
-    k->Scale(1. / 2);
-    fh_mean_combBg_k_minv[step] = (TH1D*) k->Clone();
+    //fh_mean_combBg_k_minv
+    TH1D* hK = fHMean.CreateHByClone<TH1D>("hMinvCombPM_mixedEv", "hMinvCombK", step);
+    hK->Divide(fHMean.H1("hMinvCombGeom_mixedEv", step));
+    hK->Scale(0.5);
 
     // calculate combinatorial BG
-    TH1D* Bc = (TH1D*) k->Clone();
-    Bc->Multiply(fh_mean_combBg_GeomMeanSame_minv[step]);
-    Bc->Scale(2.);
-    fh_mean_combBg_minv[step]     = (TH1D*) Bc->Clone();
-    fh_mean_combBg_raw_minv[step] = (TH1D*) Bc->Clone();
-    fh_mean_combBg_raw_minv[step]->Scale(fNofSignals * nofEvents);
+    // fh_mean_combBg_minv
+    TH1D* hCBg = fHMean.CreateHByClone<TH1D>("hMinvCombK", "hMinvCombBg", step);
+    hCBg->Multiply(fHMean.H1("hMinvCombGeom_sameEv", step));
+    hCBg->Scale(2.);
 
     // calculate assembled combinatorial BG from same (<= 0.3 GeV) and mixed (> 0.3 GeV) events data
-    fh_mean_combBg_assemb_minv[step] = (TH1D*) fh_mean_combBg_minv[step]->Clone();
-
-    for (int iBin = binFrom + 1; iBin <= nofBins; iBin++) {  // from > 300 MeV on normalized data from mixed event
-      double k2      = fh_mean_combBg_k_minv[step]->GetBinContent(iBin);
-      double gm2     = fh_mean_combBg_GeomMeanMixed_minv[step]->GetBinContent(iBin);
-      double content = 2 * k2 * gm2 * normGM;
-      fh_mean_combBg_assemb_minv[step]->SetBinContent(iBin, content);
+    //fh_mean_combBg_assemb_minv
+    {
+      TH1D* hAsm = fHMean.CreateHByClone<TH1D>("hMinvCombBg", "hMinvCombBgAsm", step);
+      // from > 300 MeV on normalized data from mixed event
+      for (int i = minBin + 1; i <= hAsm->GetNbinsX(); i++) {
+        double k  = fHMean.H1("hMinvCombK", step)->GetBinContent(i);
+        double gm = fHMean.H1("hMinvCombGeom_mixedEv", step)->GetBinContent(i);
+        hAsm->SetBinContent(i, 2 * k * gm * normGM);
+      }
     }
 
-    // calculate comb. signal
-    // from 'N+-same'
-    fh_mean_combSignalNpm_minv[step] = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[step]->Clone();
-    fh_mean_combSignalNpm_minv[step]->Add(fh_mean_combBg_minv[step], -1.);
-
-
-    // from 'Cocktail + BG'
-
-    TH1D* cock = nullptr;
-
-    if (step == kMc) cock = (TH1D*) GetCoctailMinv(kMc);
-    else if (step == kAcc)
-      cock = (TH1D*) GetCoctailMinv(kAcc);
-    else if (step == kReco)
-      cock = (TH1D*) GetCoctailMinv(kReco);
-    else if (step == kChi2Prim)
-      cock = (TH1D*) GetCoctailMinv(kChi2Prim);
-    else if (step == kElId)
-      cock = (TH1D*) GetCoctailMinv(kElId);
-    else if (step == kGammaCut)
-      cock = (TH1D*) GetCoctailMinv(kGammaCut);
-    else if (step == kMvd1Cut)
-      cock = (TH1D*) GetCoctailMinv(kMvd1Cut);
-    else if (step == kMvd2Cut)
-      cock = (TH1D*) GetCoctailMinv(kMvd2Cut);
-    else if (step == kStCut)
-      cock = (TH1D*) GetCoctailMinv(kStCut);
-    else if (step == kRtCut)
-      cock = (TH1D*) GetCoctailMinv(kRtCut);
-    else if (step == kTtCut)
-      cock = (TH1D*) GetCoctailMinv(kTtCut);
-    else if (step == kPtCut)
-      cock = (TH1D*) GetCoctailMinv(kPtCut);
-
-    if (cock != NULL) cock->Rebin(nRebin);
-    fh_mean_combSignalNpm_minv[step] = (TH1D*) fh_mean_bg_minv[step]->Clone();
-    fh_mean_combSignalNpm_minv[step]->Add(cock);
-    fh_mean_combSignalNpm_minv[step]->Add(fh_mean_combBg_minv[step], -1.);
-
     // calculate assembled comb. signal from same (<= 0.3 GeV) and mixed (> 0.3 GeV) events data
-    // from 'N+-same'
-    fh_mean_combSignalNpm_assemb_minv[step] = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[step]->Clone();
-    fh_mean_combSignalNpm_assemb_minv[step]->Add(fh_mean_combBg_assemb_minv[step], -1.);
-    fh_mean_combSignalNpm_assemb_minv[step]->SetTitle("Signal (N^{+-}_{same} - B_{C})");
+    // from 'N+-same', Signal (N^{+-}_{same} - B_{C})
+    //fh_mean_combSignalNpm_assemb_minv
+    TH1D* hCombPMSignalAsm = fHMean.CreateHByClone<TH1D>("hMinvCombPM_sameEv", "hMinvCombPMSignalAsm", step);
+    hCombPMSignalAsm->Add(fHMean.H1("hMinvCombBgAsm", step), -1.);
 
     // from 'Cocktail + BG'
-    fh_mean_combSignalBCoc_assemb_minv[step] = (TH1D*) fh_mean_bg_minv[step]->Clone();
-    fh_mean_combSignalBCoc_assemb_minv[step]->Add(cock);
-    TH1D* cbAss = (TH1D*) fh_mean_combBg_assemb_minv[step]->Clone();
-    cbAss->Scale(1. / nofEvents);
-    fh_mean_combSignalBCoc_assemb_minv[step]->Add(cbAss, -1.);
-
-    // error calculation
-    TH1D* err = (TH1D*) fh_mean_combPairsPM_sameEvent_minv[step]->Clone();
-    err->Reset("ice");
-    fh_mean_combBg_errProp_minv[step]     = (TH1D*) err->Clone();
-    fh_mean_combSignal_errProp_minv[step] = (TH1D*) err->Clone();
-
-    for (int iBin = 1; iBin <= nofBins; iBin++) {  // calculate error propagation
-      double Npm = fh_mean_combPairsPM_sameEvent_minv[step]->GetBinContent(iBin);
-      double Bpp = fh_mean_combPairsPP_sameEvent_minv[step]->GetBinContent(iBin);
-      double Bmm = fh_mean_combPairsMM_sameEvent_minv[step]->GetBinContent(iBin);
-      double bpm = fh_mean_combPairsPM_mixedEvents_minv[step]->GetBinContent(iBin);
-      double bpp = fh_mean_combPairsPP_mixedEvents_minv[step]->GetBinContent(iBin);
-      double bmm = fh_mean_combPairsMM_mixedEvents_minv[step]->GetBinContent(iBin);
-
-      // calculation of error propagation
-      double DNpm = TMath::Sqrt(Npm);  // Δ<B+->
-      double DBpp = TMath::Sqrt(Bpp);  // Δ<B++>
-      double DBmm = TMath::Sqrt(Bmm);  // Δ<B-->
-      double Dbpm = TMath::Sqrt(bpm);  // Δ<b+->
-      double Dbpp = TMath::Sqrt(bpp);  // Δ<b++>
-      double Dbmm = TMath::Sqrt(bmm);  // Δ<b-->
-
-      double dNpm = (double) 1.;  // derivatives of B_c and signal resp. to single contributions
-      double dBpp = (double) (1. / 2) * bpm * Bmm * (1. / TMath::Sqrt(Bpp * Bmm * bpp * bmm));
-      double dBmm = (double) (1. / 2) * bpm * Bpp * (1. / TMath::Sqrt(Bpp * Bmm * bpp * bmm));
-      double dbpm = (double) TMath::Sqrt((Bpp * Bmm) / (bpp * bmm));
-      double dbpp = (double) ((-1.) / 2) * bpm * bmm * TMath::Sqrt(Bpp * Bmm)
-                    / (TMath::Sqrt(bpp * bmm) * TMath::Sqrt(bpp * bmm) * TMath::Sqrt(bpp * bmm));
-      double dbmm = (double) ((-1.) / 2) * bpm * bpp * TMath::Sqrt(Bpp * Bmm)
-                    / (TMath::Sqrt(bpp * bmm) * TMath::Sqrt(bpp * bmm) * TMath::Sqrt(bpp * bmm));
-      double dbpm2 = (double) normGM;  // for > 300 MeV
-
-      double fNpm  = (DNpm * dNpm) * (DNpm * dNpm);
-      double fBpp  = (DBpp * dBpp) * (DBpp * dBpp);  // single contribution factors to error propagation
-      double fBmm  = (DBmm * dBmm) * (DBmm * dBmm);
-      double fbpm  = (Dbpm * dbpm) * (Dbpm * dbpm);
-      double fbpp  = (Dbpp * dbpp) * (Dbpp * dbpp);  // for > 300 MeV
-      double fbmm  = (Dbmm * dbmm) * (Dbmm * dbmm);
-      double fbpm2 = (Dbpm * dbpm2) * (Dbpm * dbpm2);  // for > 300 MeV
-
-      double errorBc  = TMath::Sqrt(fBpp + fBmm + fbpm + fbpp + fbmm);  // final error propagation value
-      double errorBc2 = TMath::Sqrt(fbpm2);
-
-      double errorSig  = TMath::Sqrt(fNpm + fBpp + fBmm + fbpm + fbpp + fbmm);
-      double errorSig2 = TMath::Sqrt(fNpm + fbpm2);
-
-      // fill error histograms (histos with error information only)
-      if (iBin <= binFrom) fh_mean_combBg_errProp_minv[step]->SetBinContent(iBin, errorBc);
-      if (iBin > binFrom) fh_mean_combBg_errProp_minv[step]->SetBinContent(iBin, errorBc2);
-      if (iBin <= binFrom) fh_mean_combSignal_errProp_minv[step]->SetBinContent(iBin, errorSig);
-      if (iBin > binFrom) fh_mean_combSignal_errProp_minv[step]->SetBinContent(iBin, errorSig2);
-
-      // set error value in CB histograms
-      fh_mean_combBg_minv[step]->SetBinError(iBin, errorBc);
-      if (iBin <= binFrom) fh_mean_combBg_assemb_minv[step]->SetBinError(iBin, errorBc);
-      if (iBin > binFrom) fh_mean_combBg_assemb_minv[step]->SetBinError(iBin, errorBc2);
-      if (iBin <= binFrom) fh_mean_combSignalNpm_assemb_minv[step]->SetBinError(iBin, errorSig);
-      if (iBin > binFrom) fh_mean_combSignalNpm_assemb_minv[step]->SetBinError(iBin, errorSig2);
-
-      if (iBin == 3 || iBin == 4 || ((iBin % (500 / nRebin) == 0 && iBin <= (2000 / nRebin)))) {
-        cout << "step    = " << step << endl;
-        cout << "iBin    = " << iBin << endl;
-        cout << "Npm     = " << Npm << endl;
-        cout << "bpm     = " << bpm << endl;
-        cout << "bp      = " << bpp << endl;
-        cout << "bm      = " << bmm << endl;
-        cout << "Bp      = " << Bpp << endl;
-        cout << "Bm      = " << Bmm << endl;
-        cout << "Dbpm    = " << Dbpm << endl;
-        cout << "Dbp     = " << Dbpp << endl;
-        cout << "Dbm     = " << Dbmm << endl;
-        cout << "DBp     = " << DBpp << endl;
-        cout << "DBm     = " << DBmm << endl;
-        cout << "dbpm    = " << dbpm << endl;
-        cout << "dbp     = " << dbpp << endl;
-        cout << "dbm     = " << dbmm << endl;
-        cout << "dBp     = " << dBpp << endl;
-        cout << "dBm     = " << dBmm << endl;
-        cout << "fbpm    = " << fbpm << endl;
-        cout << "fbp     = " << fbpp << endl;
-        cout << "fbm     = " << fbmm << endl;
-        cout << "fBp     = " << fBpp << endl;
-        cout << "fBm     = " << fBmm << endl;
-        cout << "errPropBc  = " << errorBc << endl;
-        cout << "errPropBc2 = " << errorBc2 << endl;
-        cout << "errorSig   = " << errorSig << endl;
-        cout << "errorSig2  = " << errorSig2 << endl;
-        cout << "Bin error CB     = " << fh_mean_combBg_errProp_minv[step]->GetBinContent(iBin) << endl;
-        cout << "Bin error Signal = " << fh_mean_combSignal_errProp_minv[step]->GetBinContent(iBin) << endl;
-        cout << "Bin error Npm    = " << fh_mean_combPairsPM_sameEvent_minv[step]->GetBinError(iBin) << endl;
-      }
-    }  // error propagation
-
-    // scale histograms
-    bW = fh_mean_combPairsPM_sameEvent_minv[step]->GetBinWidth(1);
-    cout << "bW = " << bW << endl;
-    fh_mean_combPairsPM_sameEvent_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combPairsPP_sameEvent_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combPairsMM_sameEvent_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combPairsPM_mixedEvents_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combPairsPP_mixedEvents_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combPairsMM_mixedEvents_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combBg_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combBg_assemb_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combBg_GeomMeanSame_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combBg_GeomMeanMixed_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combSignalNpm_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combSignalNpm_assemb_minv[step]->Scale(1. / (nofEvents * bW));
-    fh_mean_combSignalBCoc_assemb_minv[step]->Scale(1. / (bW));  // had been normalized earlier due to Cocktail
-
-    for (int iBin = 1; iBin <= nofBins; iBin++) {  // TODO: only to check error value after sacling
-      if (iBin == 3 || iBin == 4 || (iBin % (500 / nRebin) == 0 && iBin <= (2000 / nRebin))) {
-        double Npm = fh_mean_combPairsPM_sameEvent_minv[step]->GetBinContent(iBin);
-        double Bm  = fh_mean_combPairsMM_sameEvent_minv[step]->GetBinContent(iBin);
-        cout << "CHECK: step    = " << step << endl;
-        cout << "CHECK: iBin    = " << iBin << endl;
-        cout << "CHECK: Npm = " << Npm * nofEvents * bW << endl;
-        cout << "CHECK: Bm  = " << Bm * nofEvents * bW << endl;
-        cout << "CHECK: Bin error Npm              = " << fh_mean_combPairsPM_sameEvent_minv[step]->GetBinError(iBin)
-             << endl;
-        cout << "CHECK: Bin error Sig_ass (Npm)    = " << fh_mean_combSignalNpm_assemb_minv[step]->GetBinError(iBin)
-             << endl;
-      }
+    //fh_mean_combSignalBCoc_assemb_minv
+    TH1D* hBCSignalAsm = fHMean.CreateHByClone<TH1D>("hMinv_bg", "hMinvSBgSignalAsm", step);
+    hBCSignalAsm->Add(GetCocktailMinvH1(step));
+    hBCSignalAsm->Add(fHMean.H1("hMinvCombBgAsm", step), -1.);
+
+    // TODO: @Cornelius check if calculations are correct
+    int nofBins = fHMean.H1("hMinvCombPM_sameEv", step)->GetNbinsX();
+    for (int i = 1; i <= nofBins; i++) {
+      //s_ for same, m_ for mixed
+      double s_pm = fHMean.H1("hMinvCombPM_sameEv", step)->GetBinContent(i);
+      double s_pp = fHMean.H1("hMinvCombPP_sameEv", step)->GetBinContent(i);
+      double s_mm = fHMean.H1("hMinvCombMM_sameEv", step)->GetBinContent(i);
+      double m_pm = fHMean.H1("hMinvCombPM_mixedEv", step)->GetBinContent(i);
+      double m_pp = fHMean.H1("hMinvCombPP_mixedEv", step)->GetBinContent(i);
+      double m_mm = fHMean.H1("hMinvCombMM_mixedEv", step)->GetBinContent(i);
+
+      double s_dpm  = 1.;  // derivatives of B_c and signal resp. to single contributions
+      double d1     = 1. / std::sqrt(s_pp * s_mm * m_pp * m_mm);
+      double s_dpp  = 0.5 * m_pm * s_mm * d1;
+      double s_dmm  = 0.5 * m_pm * s_pp * d1;
+      double m_dpm  = std::sqrt((s_pp * s_mm) / (m_pp * m_mm));
+      double d2     = std::sqrt(s_pp * s_mm) / std::pow(std::sqrt(m_pp * m_mm), 3);
+      double m_dpp  = -0.5 * m_pm * m_mm * d2;
+      double m_dmm  = -0.5 * m_pm * m_pp * d2;
+      double m_dpm2 = normGM;  // for > 300 MeV
+
+      double s_fpm = std::pow(std::sqrt(s_pm) * s_dpm, 2);
+      double s_fpp = std::pow(std::sqrt(s_pp) * s_dpp, 2);  // single contribution factors to error propagation
+      double s_fmm = std::pow(std::sqrt(s_mm) * s_dmm, 2);
+      double m_fpm = std::pow(std::sqrt(m_pm) * m_dpm, 2);
+      double m_fpp =
+        std::pow(std::sqrt(m_pp) * m_dpp, 2);  //TODO: @Cornelius check, changed from s_pp2 to m_pp2  // for > 300 MeV
+      double m_fmm  = std::pow(std::sqrt(m_mm) * m_dmm, 2);   //TODO: @Cornelius check, changed from s_mm2 to m_mm2
+      double m_fpm2 = std::pow(std::sqrt(m_pm) * m_dpm2, 2);  // for > 300 MeV
+
+      double errorBc   = std::sqrt(s_fpp + s_fmm + m_fpm + m_fpp + m_fmm);  // final error propagation value
+      double errorBc2  = std::sqrt(m_fpm2);
+      double errorSig  = std::sqrt(s_fpm + s_fpp + s_fmm + m_fpm + m_fpp + m_fmm);
+      double errorSig2 = std::sqrt(s_fpm + m_fpm2);
+
+      fHMean.H1("hMinvCombBg", step)->SetBinError(i, errorBc);
+      if (i <= minBin) fHMean.H1("hMinvCombBgAsm", step)->SetBinError(i, errorBc);
+      if (i > minBin) fHMean.H1("hMinvCombBgAsm", step)->SetBinError(i, errorBc2);
+      if (i <= minBin) fHMean.H1("hMinvCombPMSignalAsm", step)->SetBinError(i, errorSig);
+      if (i > minBin) fHMean.H1("hMinvCombPMSignalAsm", step)->SetBinError(i, errorSig2);
     }
-  }  // steps
+  }
 }
 
-/*void CbmAnaDielectronTaskDrawAll::CompareSTSversions()
+void LmvmDrawAll::CalcCutEffRange(double minMinv, double maxMinv)
 {
-  TFile* _Input_file_v16g = TFile::Open("/lustre/cbm/users/criesen/cbm/data/lmvm/inmed/analysis.all.root");
-  TFile* _Input_file_v19a = TFile::Open("/lustre/cbm/users/criesen/cbm/data/lmvm_sts-v19a_5M/inmed/analysis.all.root");
-
-  TH1D* hv16g = (TH1D*) _Input_file_v16g->Get("fh_signal_minv_mc");
-  TH1D* hv19a = (TH1D*) _Input_file_v19a->Get("fh_signal_minv_mc");
-  
-  hv16g->Divide(hv19a);
-
-  hv16g->Rebin(nRebin);
-  hv16g->Scale(1. / nRebin);
-
-  hv16g->GetXaxis()->SetRangeUser(0, 2.);
-  hv16g->GetXaxis()->SetTitle("M_{ee} [GeV/c^{2}]");
+  stringstream ss1;
+  ss1 << "hCutEff_" << minMinv << "to" << maxMinv;
+  fHMean.CreateH1(ss1.str() + "_bg", "Analysis step", "Efficiency [%]", fHMean.fNofAnaSteps, 0, fHMean.fNofAnaSteps);
+  fHMean.CreateH1(ss1.str() + "_s", "Analysis step", "Efficiency [%]", fHMean.fNofAnaSteps, 0, fHMean.fNofAnaSteps);
+  TH1D* hS         = fHMean.H1(ss1.str() + "_s");
+  TH1D* hBg        = fHMean.H1(ss1.str() + "_bg");
+  int x            = 1;
+  TH1D* cocktail   = GetCocktailMinvH1(ELmvmAnaStep::ElId);
+  int binMin       = cocktail->FindBin(minMinv);
+  int binMax       = cocktail->FindBin(maxMinv);
+  double sIntElId  = cocktail->Integral(binMin, binMax);
+  double bgIntElId = fHMean.H1("hMinv", ELmvmSrc::Bg, ELmvmAnaStep::ElId)->Integral(binMin, binMax);
+  for (ELmvmAnaStep step : fHMean.fAnaSteps) {
+    if (step < ELmvmAnaStep::ElId) continue;
+    if (!fUseMvd && (step == ELmvmAnaStep::Mvd1Cut || step == ELmvmAnaStep::Mvd2Cut)) continue;
+
+    double effS = 100. * GetCocktailMinvH1(step)->Integral(binMin, binMax) / sIntElId;
+    double effB = 100. * fHMean.H1("hMinv", ELmvmSrc::Bg, step)->Integral(binMin, binMax) / bgIntElId;
+
+    hBg->GetXaxis()->SetBinLabel(x, fHMean.fAnaStepLatex[static_cast<int>(step)].c_str());
+    hBg->SetBinContent(x, effB);
+    hS->SetBinContent(x, effS);
+    x++;
+  }
 
-  hv16g->SetTitle(0);
+  hBg->GetXaxis()->SetLabelSize(0.06);
+  hBg->GetXaxis()->SetRange(1, x - 1);
+  hS->GetXaxis()->SetRange(1, x - 1);
 
-  DrawH1({hv16g}, {""}, kLinear, kLog, false, 0.8, 0.8, 0.95, 0.95, "HIST L");
-  hv16g->GetYaxis()->SetTitle("ratio v16g/v19a");
-  hv16g->GetYaxis()->SetLabelSize(0.05);
+  stringstream ss;
+  ss << "lmvmAll_cutEff_" << minMinv << "to" << maxMinv;
+  fHMean.fHM.CreateCanvas(ss.str(), ss.str(), 1000, 1000);
+  DrawH1({hBg, hS}, {"BG", "Coctail"}, kLinear, kLinear, true, 0.75, 0.85, 1.0, 1.0, "hist");
+  hBg->SetLineWidth(4);
+  hS->SetLineWidth(4);
+  hBg->SetMinimum(1);
+  hBg->SetMaximum(110);
 
-  hv16g->Draw();
-}*/
+  stringstream ss2;
+  ss2 << minMinv << "<M [GeV/c^2]<" << maxMinv;
+  TText* t = new TText(0.5, hBg->GetMaximum() + 5, ss2.str().c_str());
+  t->Draw();
+}
 
-TH1D* CbmAnaDielectronTaskDrawAll::SBgRange(Double_t min, Double_t max)
+TH1D* LmvmDrawAll::SBgRange(double minMinv, double maxMinv)
 {
   stringstream ss;
-  ss << "lmvm_s_bg_region_" << min << "_" << max;
-  TH1D* h_s_bg = new TH1D(ss.str().c_str(), string(ss.str() + ";Analysis steps;S/BG").c_str(),
-                          CbmLmvmHist::fNofAnaSteps, 0, CbmLmvmHist::fNofAnaSteps);
-  h_s_bg->GetXaxis()->SetLabelSize(0.06);
-  int x = 1;
-  for (int step = kElId; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) { continue; }
-    Int_t bin1 = fh_sum_s_minv[step]->FindBin(min);
-    Int_t bin2 = fh_sum_s_minv[step]->FindBin(max);
-    double y   = fh_sum_s_minv[step]->Integral(bin1, bin2) / fh_mean_bg_minv[step]->Integral(bin1, bin2);
-
-    h_s_bg->GetXaxis()->SetBinLabel(x, CbmLmvmHist::fAnaStepsLatex[step].c_str());
-    h_s_bg->SetBinContent(x, y);
-    // replace "." with "_"
-    string str = ss.str();
-    for (string::iterator it = str.begin(); it < str.end(); it++) {
-      if (*it == '.') *it = '_';
-    }
+  ss << "hSBgRatio_" << minMinv << "to" << maxMinv;
+  fHMean.CreateH1(ss.str(), "Analysis step", "Cocktail/BG", fHMean.fNofAnaSteps, 0, fHMean.fNofAnaSteps);
+  TH1D* hSBg = fHMean.H1(ss.str());
+  hSBg->GetXaxis()->SetLabelSize(0.06);
+  int x          = 1;
+  TH1D* cocktail = GetCocktailMinvH1(ELmvmAnaStep::ElId);
+  int binMin     = cocktail->FindBin(minMinv);
+  int binMax     = cocktail->FindBin(maxMinv);
+  for (ELmvmAnaStep step : fHMean.fAnaSteps) {
+    if (step < ELmvmAnaStep::ElId) continue;
+    if (!fUseMvd && (step == ELmvmAnaStep::Mvd1Cut || step == ELmvmAnaStep::Mvd2Cut)) continue;
+
+    double intS  = 100. * GetCocktailMinvH1(step)->Integral(binMin, binMax);
+    double intBg = 100. * fHMean.H1("hMinv", ELmvmSrc::Bg, step)->Integral(binMin, binMax);
+    double sbg   = intS / intBg;
+
+    hSBg->GetXaxis()->SetBinLabel(x, fHMean.fAnaStepLatex[static_cast<int>(step)].c_str());
+    hSBg->SetBinContent(x, sbg);
     x++;
   }
-  h_s_bg->GetXaxis()->SetRange(1, x - 1);
-  return h_s_bg;
+  hSBg->GetXaxis()->SetRange(1, x - 1);
+  return hSBg;
 }
 
-void CbmAnaDielectronTaskDrawAll::SBgRangeAll()
+void LmvmDrawAll::SBgRangeAll()
 {
-  TH1D* h_00_02 = SBgRange(0.0, 0.2);
-  TH1D* h_02_06 = SBgRange(0.2, 0.6);
-  TH1D* h_06_12 = SBgRange(0.6, 1.2);
-
-  fHM[0]->CreateCanvas("lmvm_s_bg_ranges", "lmvm_s_bg_ranges", 700, 700);
-  DrawH1({h_00_02, h_02_06, h_06_12}, {"0.0<M [GeV/c^{2}]<0.2", "0.2<M [GeV/c^{2}]<0.6", "0.6<M [GeV/c^{2}]<1.2"},
-         kLinear, kLog, true, 0.25, 0.8, 0.75, 0.99);
-
-  h_00_02->SetMinimum(1e-3);
-  h_00_02->SetMaximum(3);
-  h_00_02->SetLineWidth(4);
-  h_02_06->SetLineWidth(4);
-  h_06_12->SetLineWidth(4);
-
-  TH1D* h_05_06 = SBgRange(0.5, 0.6);
-  fHM[0]->CreateCanvas("lmvm_s_bg_ranges_05_06", "lmvm_s_bg_ranges_05_06", 700, 700);
-  DrawH1(h_05_06, kLinear, kLinear);
-  h_05_06->SetMinimum(1e-3);
-  h_05_06->SetMaximum(2e-2);
-  h_05_06->SetLineWidth(4);
+  TH1D* h1 = SBgRange(0.0, 0.2);
+  TH1D* h2 = SBgRange(0.2, 0.6);
+  TH1D* h3 = SBgRange(0.6, 1.2);
+
+  fHMean.fHM.CreateCanvas("lmvmAll_sBgRatio_Ranges", "lmvmAll_sBgRatio_Ranges", 1000, 1000);
+  DrawH1({h1, h2, h3}, {"0.0<M [GeV/c^{2}]<0.2", "0.2<M [GeV/c^{2}]<0.6", "0.6<M [GeV/c^{2}]<1.2"}, kLinear, kLog, true,
+         0.25, 0.83, 0.75, 0.99, "hist");
+
+  h1->SetMinimum(0.9 * std::min({h1->GetMinimum(), h2->GetMinimum(), h3->GetMinimum()}));
+  h1->SetMaximum(1.1 * std::max({h1->GetMaximum(), h2->GetMaximum(), h3->GetMaximum()}));
+  h1->SetLineWidth(4);
+  h2->SetLineWidth(4);
+  h3->SetLineWidth(4);
+
+  TH1D* h4 = SBgRange(0.5, 0.6);
+  fHMean.fHM.CreateCanvas("lmvmAll_sBgRatio_Range05to06", "lmvmAll_sBgRatio_Range05to06", 1000, 1000);
+  DrawH1(h4, kLinear, kLinear);
+  h4->SetLineWidth(4);
 }
 
-void CbmAnaDielectronTaskDrawAll::DrawSBgSignals()
+void LmvmDrawAll::DrawSBgResults()
 {
-  //   Double_t y[CbmLmvmHist::fNofAnaSteps];
-  TCanvas* cFit       = fHM[0]->CreateCanvas("lmvm_signal_fit", "lmvm_signal_fit", 600, 600);
-  TCanvas* cDashboard = fHM[0]->CreateCanvas("lmvm_dashboard", "lmvm_dashboard", 1000, 900);
-  int iDash           = 2;
-  TLatex* latex       = new TLatex();
-  latex->SetTextSize(0.03);
-  latex->DrawLatex(0.05, 0.95, "signal");
-  latex->DrawLatex(0.2, 0.95, "step");
-  latex->DrawLatex(0.4, 0.95, "eff, %");
-  latex->DrawLatex(0.55, 0.95, "S/BG");
-  latex->DrawLatex(0.7, 0.95, "mean");
-  latex->DrawLatex(0.85, 0.95, "sigma");
-  TString str;
-  for (int iF = 0; iF < fNofSignals - 1; iF++) {
-    if (!fDrawQgp && iF == kQgp) continue;
-    string signalName = CbmLmvmHist::fSignalNames[iF];
-    cout << "Signal: " << signalName << endl;
-    stringstream ss;
-    ss << "lmvm_s_bg_cuts_" << signalName;
-
-    TH1D* h_s_bg = new TH1D(ss.str().c_str(), string(ss.str() + ";Analysis steps;S/BG").c_str(),
-                            CbmLmvmHist::fNofAnaSteps, 0, CbmLmvmHist::fNofAnaSteps);
-    h_s_bg->GetXaxis()->SetLabelSize(0.06);
-    h_s_bg->SetLineWidth(4);
+  TCanvas* cFit = fHMean.fHM.CreateCanvas("lmvmAll_signalFit", "lmvmAll_signalFit", 1000, 1000);
+  ofstream resultFile(fOutputDir + "/lmvmAll_results.txt");
+  for (auto signal : fHMean.fSignals) {
+    string signalName = fHMean.fSignalNames[static_cast<int>(signal)];
+    fHMean.CreateH1("hSBgRatio_" + signalName, "Analysis steps", "S/BG", fHMean.fNofAnaSteps, 0, fHMean.fNofAnaSteps);
+    TH1D* hSBg = fHMean.H1("hSBgRatio_" + signalName);
+    hSBg->GetXaxis()->SetLabelSize(0.06);
+    hSBg->SetLineWidth(4);
     int x = 1;
-    iDash++;  // empty string after each signal
-    for (int step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-      if (step < kElId) continue;
-      if (!fUseMvd && (step == kMvd1Cut || step == kMvd2Cut)) { continue; }
-
-      TH1D* s         = (TH1D*) H1(iF, "fh_signal_minv_" + CbmLmvmHist::fAnaSteps[step])->Clone();
-      TH1D* bg = (TH1D*) fh_mean_bg_minv[step]->Clone();  // TODO: not better to take BG of PP intead of mean BG??
-      Int_t nofEvents = (int) H1(iF, "fh_event_number")->GetEntries();
-      s->Scale(1. / nofEvents);
+    for (ELmvmAnaStep step : fHMean.fAnaSteps) {
+      if (step < ELmvmAnaStep::ElId) continue;
+      if (!fUseMvd && (step == ELmvmAnaStep::Mvd1Cut || step == ELmvmAnaStep::Mvd2Cut)) continue;
       cFit->cd();
-      if (iF == kPhi) {
-        if (s->GetEntries() > 0) s->Fit("gaus", "Q", "", 0.95, 1.05);
-      }
-      else if (iF == kOmega) {
-        if (s->GetEntries() > 0) s->Fit("gaus", "Q", "", 0.69, 0.81);
-      }
-      else {
-        if (s->GetEntries() > 0) s->Fit("gaus", "Q");
-      }
+      LmvmSBgResultData result = CalculateSBgResult(signal, step);
 
-      TF1* func      = s->GetFunction("gaus");
-      Double_t mean  = (func != NULL) ? func->GetParameter("Mean") : 0.;
-      Double_t sigma = (func != NULL) ? func->GetParameter("Sigma") : 0.;
-      Int_t minInd   = s->FindBin(mean - 2. * sigma);
-      Int_t maxInd   = s->FindBin(mean + 2. * sigma);
-
-      Double_t sumSignal = 0.;
-      Double_t sumBg     = 0.;
-      for (Int_t i = minInd + 1; i <= maxInd - 1; i++) {
-        sumSignal += s->GetBinContent(i);
-        sumBg += bg->GetBinContent(i);
-      }
-      Double_t sbg = sumSignal / sumBg;
-      double eff   = 100. * H1(iF, "fh_signal_pty_" + CbmLmvmHist::fAnaSteps[step])->GetEntries()
-                   / H1(iF, "fh_signal_pty_" + CbmLmvmHist::fAnaSteps[kMc])->GetEntries();
-
-      bool isOmegaOrPhi = (iF == kPhi || iF == kOmega);
-      cDashboard->cd();
-      latex->DrawLatex(0.05, 1.0 - iDash * 0.033, signalName.c_str());
-      latex->DrawLatex(0.2, 1.0 - iDash * 0.033, CbmLmvmHist::fAnaSteps[step].c_str());
-      str.Form("%.2f", eff);
-      latex->DrawLatex(0.4, 1.0 - iDash * 0.033, str.Data());
-      str.Form("%.3f", sumSignal / sumBg);
-      latex->DrawLatex(0.55, 1.0 - iDash * 0.033, (isOmegaOrPhi) ? str.Data() : "-");
-      str.Form("%.1f", 1000. * mean);
-      latex->DrawLatex(0.7, 1.0 - iDash * 0.033, (isOmegaOrPhi) ? str.Data() : "-");
-      str.Form("%.1f", 1000. * sigma);
-      latex->DrawLatex(0.85, 1.0 - iDash * 0.033, (isOmegaOrPhi) ? str.Data() : "-");
-
-      h_s_bg->GetXaxis()->SetBinLabel(x, CbmLmvmHist::fAnaStepsLatex[step].c_str());
-      if (sbg < 1000.) h_s_bg->SetBinContent(x, sbg);
+      hSBg->GetXaxis()->SetBinLabel(x, fHMean.fAnaStepLatex[static_cast<int>(step)].c_str());
+      if (result.fSBgRatio < 1000.) hSBg->SetBinContent(x, result.fSBgRatio);
       x++;
-      iDash++;
+      resultFile << signalName << " " << fHMean.fAnaStepNames[static_cast<int>(step)] << " " << result.fSignallEff
+                 << " " << result.fSBgRatio << " " << result.fFitMean << " " << result.fFitSigma;
     }
-    h_s_bg->GetXaxis()->SetRange(1, x - 1);
-    fHM[0]->CreateCanvas(ss.str().c_str(), ss.str().c_str(), 800, 800);
-    DrawH1(h_s_bg);
-    h_s_bg->SetLineWidth(4);
+    hSBg->GetXaxis()->SetRange(1, x - 1);
+    fHMean.fHM.CreateCanvas("lmvmAll_sBgRatio_" + signalName, "lmvmAll_sBgRatio_" + signalName, 1000, 1000);
+    DrawH1(hSBg);
+    hSBg->SetLineWidth(4);
+  }
+  resultFile.close();
+}
+
+LmvmSBgResultData LmvmDrawAll::CalculateSBgResult(ELmvmSignal signal, ELmvmAnaStep step)
+{
+  TH1D* s  = H(signal)->H1("hMinv", ELmvmSrc::Signal, step);
+  TH1D* bg = H(signal)->H1("hMinv", ELmvmSrc::Bg, step);
 
-    cDashboard->Draw();
+  if (s->GetEntries() < 10) return LmvmSBgResultData(0., 0., 0., 0.);
+
+  TH1D* sClone = static_cast<TH1D*>(s->Clone());
+  if (signal == ELmvmSignal::Phi) sClone->Fit("gaus", "Q", "", 0.95, 1.05);
+  else if (signal == ELmvmSignal::Omega)
+    sClone->Fit("gaus", "Q", "", 0.69, 0.81);
+  else
+    sClone->Fit("gaus", "Q");
+
+  TF1* func    = sClone->GetFunction("gaus");
+  double mean  = (func != nullptr) ? func->GetParameter("Mean") : 0.;
+  double sigma = (func != nullptr) ? func->GetParameter("Sigma") : 0.;
+  int minInd   = s->FindBin(mean - 2. * sigma);
+  int maxInd   = s->FindBin(mean + 2. * sigma);
+
+  double sumSignal = 0.;
+  double sumBg     = 0.;
+  for (int i = minInd + 1; i <= maxInd - 1; i++) {
+    sumSignal += s->GetBinContent(i);
+    sumBg += bg->GetBinContent(i);
   }
+  double sbg = (sumBg != 0.) ? sumSignal / sumBg : 0.;
+
+  double eff = 100. * H(signal)->H1("hPtYPairSignal", step)->GetEntries()
+               / H(signal)->H1("hPtYPairSignal", ELmvmAnaStep::Mc)->GetEntries();
+
+  return LmvmSBgResultData(sbg, eff, mean, sigma);
 }
 
-void CbmAnaDielectronTaskDrawAll::SaveCanvasToImage()
+void LmvmDrawAll::SaveCanvasToImage()
 {
   cout << "Images output dir:" << fOutputDir << endl;
-  fHM[0]->SaveCanvasToImage(fOutputDir, "png");  // fHM[0]->SaveCanvasToImage(fOutputDir, "eps;png");
+  fHMean.fHM.SaveCanvasToImage(fOutputDir, "png;eps");  // fHM[0]->SaveCanvasToImage(fOutputDir, "eps;png");
 }
 
-ClassImp(CbmAnaDielectronTaskDrawAll);
+ClassImp(LmvmDrawAll);
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmDrawAll.h b/analysis/PWGDIL/dielectron/lmvm/LmvmDrawAll.h
old mode 100755
new mode 100644
index 6476b6b51d05419a14a108fc999d3ee8101222fc..f6059c6b4b33f56b6daa7b4e2389578b9fec1daf
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmDrawAll.h
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmDrawAll.h
@@ -1,17 +1,9 @@
-/* Copyright (C) 2011-2018 UGiessen, JINR-LIT
+/* Copyright (C) 2011-2021 UGiessen, JINR-LIT
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Elena Lebedeva, Andrey Lebedev, Semen Lebedev [committer], Florian Uhlig */
 
-/** CbmAnaDielectronTaskDrawAll.h
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2011
- * @version 2.0
- **/
-
-#ifndef CBM_ANA_DIELECTRON_TASK_DRAW_ALL
-#define CBM_ANA_DIELECTRON_TASK_DRAW_ALL
-
-#include "CbmLmvmHist.h"
+#ifndef LMVM_DRAW_ALL
+#define LMVM_DRAW_ALL
 
 #include "TObject.h"
 
@@ -19,6 +11,8 @@
 #include <string>
 #include <vector>
 
+#include "LmvmHist.h"
+
 class TH1;
 class TH2D;
 class TH1D;
@@ -26,142 +20,42 @@ class TFile;
 class TCanvas;
 class CbmHistManager;
 
-enum SignalType
-{
-  kInmed  = 0,
-  kQgp    = 1,
-  kOmega  = 2,
-  kPhi    = 3,
-  kOmegaD = 4
-};
-
-class CbmAnaDielectronTaskDrawAll : public TObject {
+class LmvmDrawAll : public TObject {
 
 public:
-  /**
-     * \brief Default constructor.
-     */
-  CbmAnaDielectronTaskDrawAll()
-    : TObject()
-    , fUseMvd(false)
-    , fDrawQgp(false)
-    , fHM()
-    , fh_mean_bg_minv()
-    , fh_mean_eta_minv()
-    , fh_mean_pi0_minv()
-    , fh_mean_eta_minv_pt()
-    , fh_mean_pi0_minv_pt()
-    , fh_mean_sbg_vs_minv()
-    , fh_sum_s_minv()
-    , fOutputDir("")
-  {
-    ;
-  }
+  LmvmDrawAll() { ; }
+  virtual ~LmvmDrawAll() { ; }
 
-  /**
-     * \brief Destructor.
-     */
-  virtual ~CbmAnaDielectronTaskDrawAll() { ; }
 
-  /**
-     * \brief Implement functionality of drawing histograms in the macro
-     * from the specified files, this function should be called from macro.
-     * \param[in] fileNameRho0 Name of the file with rho0 histograms.
-     * \param[in] fileNameOmega Name of the file with omega histograms.
-     * \param[in] fileNamePhi Name of the file with phi histograms.
-     * \param[in] fileNameOmegaDalitz Name of the file with omegaDalitz histograms.
-     * \param[in] outputDir Output directory for figures and .json file.
-     * \param useMvd draw histograms related to the MVD detector?
-     **/
-  void DrawHistosFromFile(const std::string& fileNameInmed, const std::string& fileNameQgp,
-                          const std::string& fileNameOmega, const std::string& fileNamePhi,
-                          const std::string& fileNameOmegaDalitz, const std::string& outputDir = "",
-                          Bool_t useMvd = false);
+  void DrawHistFromFile(const std::string& fileInmed, const std::string& fileQgp, const std::string& fileOmega,
+                        const std::string& filePhi, const std::string& fileOmegaD, const std::string& outputDir = "",
+                        bool useMvd = false);
 
 private:
-  static const int fNofSignals = 5;
-
-  int nRebin;
-
-  Bool_t fUseMvd;   // do you want to draw histograms related to the MVD detector?
-  Bool_t fDrawQgp;  // do you wan to draq QGP signal
-
-  //[0]=rho0, [1]=omega, [2]=phi, [3]=omegaDalitz
-  std::vector<CbmHistManager*> fHM;
-
-  // index: AnalysisSteps
-  std::vector<TH1D*> fh_mean_bg_minv;  //mean histograms from all files
-  std::vector<TH1D*> fh_mean_eta_minv;
-  std::vector<TH1D*> fh_mean_pi0_minv;
-  std::vector<TH2D*> fh_mean_eta_minv_pt;
-  std::vector<TH2D*> fh_mean_pi0_minv_pt;
-  std::vector<TH1D*> fh_mean_sbg_vs_minv;  //Coctail/BG vs. invariant mass for different analysis steps
-
-  // Combinatorial histograms
-  std::vector<TH1D*> fh_mean_combPairsPM_sameEvent_minv;
-  std::vector<TH1D*> fh_mean_combPairsPP_sameEvent_minv;
-  std::vector<TH1D*> fh_mean_combPairsMM_sameEvent_minv;
-  std::vector<TH1D*> fh_mean_combPairsPM_mixedEvents_minv;
-  std::vector<TH1D*> fh_mean_combPairsPP_mixedEvents_minv;
-  std::vector<TH1D*> fh_mean_combPairsMM_mixedEvents_minv;
-  std::vector<TH1D*> fh_mean_combPairsPM_sameEvent_minv_raw;  // won't be scaled with binWidth
-  std::vector<TH1D*> fh_mean_combPairsPP_sameEvent_minv_raw;
-  std::vector<TH1D*> fh_mean_combPairsMM_sameEvent_minv_raw;
-  std::vector<TH1D*> fh_mean_combPairsPM_mixedEvents_minv_raw;
-  std::vector<TH1D*> fh_mean_combPairsPP_mixedEvents_minv_raw;
-  std::vector<TH1D*> fh_mean_combPairsMM_mixedEvents_minv_raw;
-  std::vector<TH1D*> fh_mean_combBg_errProp_minv;  // to observe error propagation
-  std::vector<TH1D*> fh_mean_combSignal_errProp_minv;
-  std::vector<TH1D*> fh_mean_combBg_GeomMeanSame_minv;   // geom. mean of comb. BG ( := SQRT[(B++) * (B--)] )
-  std::vector<TH1D*> fh_mean_combBg_GeomMeanMixed_minv;  // geom. mean of comb. BG ( := SQRT[(b++) * (b--)] )
-  std::vector<TH1D*> fh_mean_combBg_k_minv;              // k = (b+-) / ( 2 * Sqrt[(b++) * (b--)] )
-  std::vector<TH1D*> fh_mean_combBg_minv;                // combinatorial BG ( := B = 2 * geomMean * k )
-  std::vector<TH1D*> fh_mean_combBg_raw_minv;            // won't be scaled; for error propagation
-  std::vector<TH1D*>
-    fh_mean_combBg_assemb_minv;  // as previous, but with assembled same (0 - 0.3 GeV) and mixed (0.3 - 2 GeV) data
-  std::vector<TH1D*> fh_mean_combSignalNpm_minv;  // combinatorial signal ( := cSig = (N+-) - B )
-  std::vector<TH1D*>
-    fh_mean_combSignalNpm_assemb_minv;  // as previous, but with assembled same (0 - 0.3 GeV) and mixed (0.3 - 2 GeV) data
-  std::vector<TH1D*> fh_mean_combSignalBCoc_minv;  // combinatorial signal ( := cSig = (Coc + BG) - B )
-  std::vector<TH1D*>
-    fh_mean_combSignalBCoc_assemb_minv;  // as previous, but with assembled same (0 - 0.3 GeV) and mixed (0.3 - 2 GeV) data
-  std::vector<TH1D*> fh_mean_combSBg_vs_minv;  // cocktail/combBG
-
-  // Number of charged particles vs. momentum
-  std::vector<TH1D*> fh_mean_nof_plutoElectrons;
-  std::vector<TH1D*> fh_mean_nof_plutoPositrons;
-  std::vector<TH1D*> fh_mean_nof_urqmdElectrons;
-  std::vector<TH1D*> fh_mean_nof_urqmdPositrons;
-
-  // index: AnalysisSteps
-  std::vector<TH1D*> fh_sum_s_minv;  // sum of all signals
+  bool fUseMvd;  // do you want to draw histograms related to the MVD detector?
+
+  std::vector<LmvmHist*> fH;
+  LmvmHist fHMean;
 
   std::string fOutputDir;  // output directory for figures
 
-  TH1D* H1(int signalType, const std::string& name);
+  LmvmHist* H(ELmvmSignal signal);
 
-  TH2D* H2(int signalType, const std::string& name);
+  int GetNofTotalEvents();
 
-  /**
-     * \brief Create and return cotail vs. minv
-     */
-  TH1D* GetCoctailMinv(CbmLmvmAnalysisSteps step);
+
+  template<class T>
+  T* GetCocktailMinv(const std::string& name, ELmvmAnaStep step);
+
+  TH1D* GetCocktailMinvH1(ELmvmAnaStep step);
 
   /**
      * \brief Draw S/Bg vs minv.
      */
   void DrawSBgVsMinv();
-
-  /**
-     * \brief Draw invariant mass histograms.
-     */
   void DrawMinvAll();
-
-  /**
-     * \brief Draw invariant mass spectra for all signal types for specified analysis step.
-     * \param[in] step Analysis step.
-     */
-  void DrawMinv(CbmLmvmAnalysisSteps step);
+  void DrawMinv(ELmvmAnaStep step);
+  void DrawMinvPtAll();
 
   /**
      * \brief Draw invariant mass spectra for all signal types for specified analysis step with BG reduced by combinatorial BG.
@@ -169,65 +63,43 @@ private:
      */
   void DrawMinvCombSignalAndBg();
 
-  /**
-     * \brief Draw invariant mass vs Pt histograms.
-     */
-  void DrawMinvPtAll();
-
-  /**
-     * \brief Draw invariant mass spectra vs Pt for all signal types for specified analysis step.
-     * \param[in] step Analysis step.
-     */
-  void DrawMinvPt(CbmLmvmAnalysisSteps step);
-
-  /**
-     * \brief It creates a mean histogram from 4 files.
-     */
-  void FillMeanHist();
+  template<class T>
+  void CreateMeanHist(const std::string& name, int nofEvents);
+  void CreateMeanHistAll();
 
   /**
      * \brief Save histograms for the study report
      */
   void SaveHist();
 
-  /**
-     * \brief Fill sum signals.
-     */
-  void FillSumSignalsHist();
-
   /**
      * \brief Calculate cut efficiency in specified invariant mass region.
      * \param[in] min Minimum invariant mass.
      * \param[in] max Maximum invariant mass.
      */
-  void CalcCutEffRange(Double_t minMinv, Double_t maxMinv);
+  void CalcCutEffRange(double minMinv, double maxMinv);
 
   /**
      * \brief Calculate combinatorial BG contribution.
      */
   void CalcCombBGHistos();
 
-  /**
-     * \brief To compare outputs from simulations with different STS versions
-     */
-  void CompareSTSversions();
-
   /**
      * \brief Create S/BG vs cuts for specified invariant mass range.
      * \param[in] min Minimum invariant mass.
      * \param[in] max Maximum invariant mass.
      */
-  TH1D* SBgRange(Double_t minMinv, Double_t maxMinv);
+  TH1D* SBgRange(double minMinv, double maxMinv);
 
   /**
      * \brief Draw S/BG vs plots for different mass ranges.
      */
   void SBgRangeAll();
 
-  /**
-     * \brief Draw S/BG vs plots for different signals.
-     */
-  void DrawSBgSignals();
+
+  void DrawSBgResults();
+
+  LmvmSBgResultData CalculateSBgResult(ELmvmSignal signal, ELmvmAnaStep step);
 
   /**
      * \brief Save all created canvases to images.
@@ -235,10 +107,10 @@ private:
   void SaveCanvasToImage();
 
 
-  CbmAnaDielectronTaskDrawAll(const CbmAnaDielectronTaskDrawAll&);
-  CbmAnaDielectronTaskDrawAll operator=(const CbmAnaDielectronTaskDrawAll&);
+  LmvmDrawAll(const LmvmDrawAll&);
+  LmvmDrawAll operator=(const LmvmDrawAll&);
 
-  ClassDef(CbmAnaDielectronTaskDrawAll, 1);
+  ClassDef(LmvmDrawAll, 1);
 };
 
 #endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmHist.cxx b/analysis/PWGDIL/dielectron/lmvm/LmvmHist.cxx
index 2755325ab5b78e7397142657a84c9d1da092a011..b4fcdf345ffd147490e9c04957a2e4d3ace4bdcf 100644
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmHist.cxx
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmHist.cxx
@@ -1,37 +1,222 @@
-/* Copyright (C) 2012-2016 UGiessen, JINR-LIT
+/* Copyright (C) 2012-2021 UGiessen, JINR-LIT
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Elena Lebedeva, Semen Lebedev [committer] */
 
-/**
- * \brief Helper class for histogram names.
- * \date 2012
- */
-#include "CbmLmvmHist.h"
+#include "LmvmHist.h"
 
-#include "TColor.h"
+#include "CbmDrawHist.h"
+#include "CbmHistManager.h"
+#include "utils/CbmUtils.h"
+
+#include "Logger.h"
+
+#include "TText.h"
 
-#include <boost/assign/list_of.hpp>
 
-using boost::assign::list_of;
 using std::string;
 using std::vector;
 
-const vector<string> CbmLmvmHist::fSourceTypes = list_of("signal")("bg")("pi0")("gamma");
+const vector<ELmvmSrc> LmvmHist::fSrcs        = {ELmvmSrc::Signal, ELmvmSrc::Bg, ELmvmSrc::Pi0, ELmvmSrc::Gamma,
+                                          ELmvmSrc::Eta};
+const vector<std::string> LmvmHist::fSrcNames = {"signal", "bg", "pi0", "gamma", "eta"};
+const vector<std::string> LmvmHist::fSrcLatex = {"S", "BG_{oth}", "#pi^{0}", "#gamma", "#eta"};
+const vector<int> LmvmHist::fSrcColors        = {kRed, kBlue, kGreen, kOrange, kMagenta};
+
+const vector<ELmvmAnaStep> LmvmHist::fAnaSteps    = {ELmvmAnaStep::Mc,       ELmvmAnaStep::Acc,     ELmvmAnaStep::Reco,
+                                                  ELmvmAnaStep::Chi2Prim, ELmvmAnaStep::ElId,    ELmvmAnaStep::GammaCut,
+                                                  ELmvmAnaStep::Mvd1Cut,  ELmvmAnaStep::Mvd2Cut, ELmvmAnaStep::StCut,
+                                                  ELmvmAnaStep::RtCut,    ELmvmAnaStep::TtCut,   ELmvmAnaStep::PtCut};
+const vector<std::string> LmvmHist::fAnaStepNames = {"mc",      "acc",     "reco",  "chi2prim", "elid",  "gammacut",
+                                                     "mvd1cut", "mvd2cut", "stcut", "rtcut",    "ttcut", "ptcut"};
+const vector<std::string> LmvmHist::fAnaStepLatex = {
+  "MC", "ACC", "REC", "#chi^{2}_{prim}", "ID", "m_{#gamma}", "mvd1", "mvd2", "ST", "RT", "TT", "P_{t}"};
+const vector<int> LmvmHist::fAnaStepColors = {kGreen + 3,   kOrange + 3, kBlack,   kOrange + 7,
+                                              kRed,         kPink - 6,   kGreen,   kOrange - 3,
+                                              kViolet + 10, kGreen - 3,  kMagenta, kYellow + 1};
+
+const vector<std::string> LmvmHist::fSignalNames = {"immed", "qgp", "omega", "phi", "omegaD"};
+const vector<ELmvmSignal> LmvmHist::fSignals     = {ELmvmSignal::Inmed, ELmvmSignal::Qgp, ELmvmSignal::Omega,
+                                                ELmvmSignal::Phi, ELmvmSignal::OmegaD};
+
+const vector<std::string> LmvmHist::fBgPairSrcNames = {"GG", "PP", "OO", "GP", "GO", "PO"};
+const vector<std::string> LmvmHist::fBgPairSrcLatex = {"#gamma-#gamma",  "#pi^{0}-#pi^{0}", "o.-o.",
+                                                       "#gamma-#pi^{0}", "#gamma-o.",       "#pi^{0}-o."};
+
+
+LmvmHist::LmvmHist() {}
+
+vector<string> LmvmHist::CombineNames(const string& name, const vector<string>& subNames)
+{
+  vector<string> result;
+  for (const auto& subName : subNames) {
+    result.push_back(name + "_" + subName);
+  }
+  return result;
+}
+
+vector<string> LmvmHist::CombineNames(const string& name, const vector<string>& subNames1,
+                                      const vector<string>& subNames2)
+{
+  vector<string> result;
+  for (const auto& subName1 : subNames1) {
+    for (const auto& subName2 : subNames2) {
+      result.push_back(name + "_" + subName1 + "_" + subName2);
+    }
+  }
+  return result;
+}
+
+void LmvmHist::CreateH1(const string& name, const string& axisX, const string& axisY, double nBins, double min,
+                        double max)
+{
+  string title = name + ";" + axisX + ";" + axisY;
+  fHM.Create1<TH1D>(name, title, nBins, min, max);
+}
+
+void LmvmHist::CreateH2(const string& name, const string& axisX, const string& axisY, const string& axisZ,
+                        double nBinsX, double minX, double maxX, double nBinsY, double minY, double maxY)
+{
+  string title = name + ";" + axisX + ";" + axisY + ";" + axisZ;
+  fHM.Create2<TH2D>(name, title, nBinsX, minX, maxX, nBinsY, minY, maxY);
+}
+
+
+void LmvmHist::CreateH1(const string& name, const vector<string>& subNames, const string& axisX, const string& axisY,
+                        double nBins, double min, double max)
+{
+  vector<string> names = CombineNames(name, subNames);
+  for (const auto& curName : names) {
+    string title = curName + ";" + axisX + ";" + axisY;
+    fHM.Create1<TH1D>(curName, title, nBins, min, max);
+  }
+}
+
+void LmvmHist::CreateH2(const string& name, const vector<string>& subNames, const string& axisX, const string& axisY,
+                        const string& axisZ, double nBinsX, double minX, double maxX, double nBinsY, double minY,
+                        double maxY)
+{
+  vector<string> names = CombineNames(name, subNames);
+  for (const auto& curName : names) {
+    string title = curName + ";" + axisX + ";" + axisY + ";" + axisZ;
+    fHM.Create2<TH2D>(curName, title, nBinsX, minX, maxX, nBinsY, minY, maxY);
+  }
+}
+
+void LmvmHist::CreateH1(const string& name, const vector<string>& subNames1, const vector<string>& subNames2,
+                        const string& axisX, const string& axisY, double nBins, double min, double max)
+{
+  vector<string> names = CombineNames(name, subNames1, subNames2);
+  for (const auto& curName : names) {
+    string title = curName + ";" + axisX + ";" + axisY;
+    fHM.Create1<TH1D>(curName, title, nBins, min, max);
+  }
+}
+
+void LmvmHist::CreateH2(const string& name, const vector<string>& subNames1, const vector<string>& subNames2,
+                        const string& axisX, const string& axisY, const string& axisZ, double nBinsX, double minX,
+                        double maxX, double nBinsY, double minY, double maxY)
+{
+  vector<string> names = CombineNames(name, subNames1, subNames2);
+  for (const auto& curName : names) {
+    string title = curName + ";" + axisX + ";" + axisY + ";" + axisZ;
+    fHM.Create2<TH2D>(curName, title, nBinsX, minX, maxX, nBinsY, minY, maxY);
+  }
+}
+
+void LmvmHist::FillH1(const string& name, double x, double w) { H1(name)->Fill(x, w); }
+
+void LmvmHist::FillH2(const string& name, double x, double y, double w) { H2(name)->Fill(x, y, w); }
+
+void LmvmHist::FillH1(const string& name, ELmvmSrc src, double x, double wSignal)
+{
+  if (src == ELmvmSrc::Undefined) return;
+  double myWeight = (src == ELmvmSrc::Signal) ? wSignal : 1.;
+  H1(name, src)->Fill(x, myWeight);
+}
+
+void LmvmHist::FillH2(const string& name, ELmvmSrc src, double x, double y, double wSignal)
+{
+  if (src == ELmvmSrc::Undefined) return;
+  double myWeight = (src == ELmvmSrc::Signal) ? wSignal : 1.;
+  H2(name, src)->Fill(x, y, myWeight);
+}
+
+void LmvmHist::FillH1(const string& name, ELmvmAnaStep step, double x, double w) { H1(name, step)->Fill(x, w); }
+
+void LmvmHist::FillH2(const string& name, ELmvmAnaStep step, double x, double y, double w)
+{
+  H2(name, step)->Fill(x, y, w);
+}
+
+void LmvmHist::FillH1(const string& name, ELmvmSrc src, ELmvmAnaStep step, double x, double wSignal)
+{
+  if (src == ELmvmSrc::Undefined || step == ELmvmAnaStep::Undefined) return;
+  FillH1(GetName(name, src, step), x, wSignal);
+}
+
+void LmvmHist::FillH2(const string& name, ELmvmSrc src, ELmvmAnaStep step, double x, double y, double wSignal)
+{
+  if (src == ELmvmSrc::Undefined || step == ELmvmAnaStep::Undefined) return;
+  FillH2(GetName(name, src, step), x, y, wSignal);
+}
+
+
+string LmvmHist::GetName(const string& name, ELmvmAnaStep step)
+{
+  if (step == ELmvmAnaStep::Undefined) {
+    LOG(error) << "LmvmHist::GetName step == ELmvmAnaStep::Undefined";
+    return name;
+  }
+  return name + "_" + fAnaStepNames[static_cast<int>(step)];
+}
+
+string LmvmHist::GetName(const string& name, ELmvmSrc src)
+{
+  if (src == ELmvmSrc::Undefined) {
+    LOG(error) << "LmvmHist::GetName src == ELmvmSrc::Undefined";
+    return name;
+  }
+  return name + "_" + fSrcNames[static_cast<int>(src)];
+}
+
+string LmvmHist::GetName(const string& name, ELmvmSrc src, ELmvmAnaStep step)
+{
+  return GetName(GetName(name, src), step);
+}
+
 
-const vector<string> CbmLmvmHist::fSourceTypesLatex = list_of("S")("BG")("#pi^{0}")("#gamma");
+void LmvmHist::Rebin(const string& name, int nGroup) { fHM.Rebin(name, nGroup); }
 
-const vector<int> CbmLmvmHist::fSourceTypesColor = list_of(kRed)(kBlue)(kGreen)(kOrange);
+void LmvmHist::Rebin(const string& name, const vector<string>& subNames, int nGroup)
+{
+  vector<string> names = CombineNames(name, subNames);
+  for (const auto& curName : names) {
+    fHM.Rebin(curName, nGroup);
+  }
+}
 
-const vector<string> CbmLmvmHist::fAnaSteps = list_of("mc")("acc")("reco")("chi2prim")("elid")("gammacut")("mvd1cut")(
-  "mvd2cut")("stcut")("rtcut")("ttcut")("ptcut");
+void LmvmHist::Rebin(const string& name, const vector<string>& subNames1, const vector<string>& subNames2, int nGroup)
+{
+  vector<string> names = CombineNames(name, subNames1, subNames2);
+  for (const auto& curName : names) {
+    fHM.Rebin(curName, nGroup);
+  }
+}
 
-const vector<string> CbmLmvmHist::fAnaStepsLatex =
-  list_of("MC")("ACC")("REC")("#chi^{2}_{prim}")("ID")("m_{#gamma}")("mvd1")("mvd2")("ST")("RT")("TT")("P_{t}");
+void LmvmHist::WriteToFile() { fHM.WriteToFile(); }
 
-const vector<int> CbmLmvmHist::fAnaStepsColor = list_of(kGreen + 3)(kOrange + 3)(kBlack)(kOrange + 7)(kRed)(kPink - 6)(
-  kGreen)(kOrange - 3)(kViolet + 10)(kGreen - 3)(kMagenta)(kYellow + 1);
+void LmvmHist::DrawEfficiency(TH1* h1, TH1* h2, double xPos, double yPos)
+{
+  string effTxt =
+    (h2->GetEntries() != 0.) ? Cbm::NumberToString<double>((h1->GetEntries() / h2->GetEntries() * 100.), 1) : "";
+  TText* t = new TText(xPos, yPos, effTxt.c_str());
+  t->SetTextSize(0.1);
+  t->Draw();
+}
 
-const vector<string> CbmLmvmHist::fSignalNames = list_of("im_rho")("qgp")("omega")("phi")("omega_dalitz");
+void LmvmHist::DrawAnaStepOnPad(ELmvmAnaStep step)
+{
+  DrawTextOnPad(LmvmHist::fAnaStepLatex[static_cast<int>(step)], 0.4, 0.9, 0.6, 0.999);
+}
 
-const vector<string> CbmLmvmHist::fBgPairSourceLatex =
-  list_of("#gamma-#gamma")("#pi^{0}-#pi^{0}")("o.-o.")("#gamma-#pi^{0}")("#gamma-o.")("#pi^{0}-o.");
+ClassImp(LmvmHist);
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmHist.h b/analysis/PWGDIL/dielectron/lmvm/LmvmHist.h
index eae25a96ed63046e69defb0e44e43980f700ab2c..fd431835b718e59a5bad38b4858bd5b9084cf63b 100644
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmHist.h
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmHist.h
@@ -1,72 +1,145 @@
-/* Copyright (C) 2012-2016 UGiessen, JINR-LIT
+/* Copyright (C) 2012-2021 UGiessen, JINR-LIT
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev [committer], Elena Lebedeva, Florian Uhlig */
 
-#ifndef CBM_LMVM_HIST_H
-#define CBM_LMVM_HIST_H
+#ifndef LMVM_HIST_H
+#define LMVM_HIST_H
+
+#include "CbmHistManager.h"
+
+#include "TH1D.h"
+#include "TH2D.h"
+#include "TObject.h"
 
 #include <string>
 #include <vector>
 
-/*
- * \brief Enumeration for different sources.
- */
-enum CbmLmvmSourceTypes
-{
-  kSignal = 0,
-  kBg     = 1,
-  kPi0    = 2,
-  kGamma  = 3
-};
-
-/*
- * \brief Enumeration for analysis steps.
- */
-enum CbmLmvmAnalysisSteps
-{
-  kMc       = 0,
-  kAcc      = 1,
-  kReco     = 2,
-  kChi2Prim = 3,
-  kElId     = 4,
-  kGammaCut = 5,
-  kMvd1Cut  = 6,
-  kMvd2Cut  = 7,
-  kStCut    = 8,
-  kRtCut    = 9,
-  kTtCut    = 10,
-  kPtCut    = 11
-};
+#include "LmvmDef.h"
 
-/*
- * \brief Enumeration for different sources of BG pairs
- */
-enum CbmLmvmBgPairSource
-{
-  kGG = 0,  // gamma-gamma
-  kPP = 1,  // pi0-pi0
-  kOO = 2,  // other-other
-  kGP = 3,  // gamma-pi0
-  kGO = 4,  // gamma-other
-  kPO = 5   // pi0-other
-};
 
-class CbmLmvmHist {
+class LmvmHist {
 public:
-  const static int fNofSourceTypes = 4;
-  const static std::vector<std::string> fSourceTypes;
-  const static std::vector<std::string> fSourceTypesLatex;
-  const static std::vector<int> fSourceTypesColor;
+  LmvmHist();
+  virtual ~LmvmHist() { ; }
+
+  const static int fNofSrc = 5;
+  const static std::vector<ELmvmSrc> fSrcs;
+  const static std::vector<std::string> fSrcNames;
+  const static std::vector<std::string> fSrcLatex;
+  const static std::vector<int> fSrcColors;
 
   const static int fNofAnaSteps = 12;
-  const static std::vector<std::string> fAnaSteps;
-  const static std::vector<std::string> fAnaStepsLatex;
-  const static std::vector<int> fAnaStepsColor;
+  const static std::vector<ELmvmAnaStep> fAnaSteps;
+  const static std::vector<std::string> fAnaStepNames;
+  const static std::vector<std::string> fAnaStepLatex;
+  const static std::vector<int> fAnaStepColors;
 
+  static const int fNofSignals = 5;
   const static std::vector<std::string> fSignalNames;
+  const static std::vector<ELmvmSignal> fSignals;
+
+  const static int fNofBgPairSrc = 6;
+  const static std::vector<std::string> fBgPairSrcNames;
+  const static std::vector<std::string> fBgPairSrcLatex;
+
+  std::vector<std::string> CombineNames(const std::string& name, const std::vector<std::string>& subNames);
+
+  std::vector<std::string> CombineNames(const std::string& name, const std::vector<std::string>& subNames1,
+                                        const std::vector<std::string>& subNames2);
+
+  // Probably one can move these many methods to main CbmHistManager class
+  void CreateH1(const std::string& name, const std::string& axisX, const std::string& axisY, double nBins, double min,
+                double max);
+
+  void CreateH2(const std::string& name, const std::string& axisX, const std::string& axisY, const std::string& axisZ,
+                double nBinsX, double minX, double maxX, double nBinsY, double minY, double maxY);
+
+  void CreateH1(const std::string& name, const std::vector<std::string>& subNames, const std::string& axisX,
+                const std::string& axisY, double nBins, double min, double max);
+
+  void CreateH2(const std::string& name, const std::vector<std::string>& subNames, const std::string& axisX,
+                const std::string& axisY, const std::string& axisZ, double nBinsX, double minX, double maxX,
+                double nBinsY, double minY, double maxY);
+
+  void CreateH1(const std::string& name, const std::vector<std::string>& subNames1,
+                const std::vector<std::string>& subNames2, const std::string& axisX, const std::string& axisY,
+                double nBins, double min, double max);
+
+  void CreateH2(const std::string& name, const std::vector<std::string>& subNames1,
+                const std::vector<std::string>& subNames2, const std::string& axisX, const std::string& axisY,
+                const std::string& axisZ, double nBinsX, double minX, double maxX, double nBinsY, double minY,
+                double maxY);
+
+
+  template<typename T>
+  T* CreateHByClone(const std::string& name, const std::string& newName)
+  {
+    T* hNew = static_cast<T*>(fHM.GetObject(name)->Clone());
+    hNew->SetNameTitle(newName.c_str(), newName.c_str());
+    fHM.Add(newName, hNew);
+    return hNew;
+  }
+
+  template<typename T>
+  T* CreateHByClone(const std::string& name, const std::string& newName, ELmvmAnaStep step)
+  {
+    return CreateHByClone<T>(GetName(name, step), GetName(newName, step));
+  }
+
+  void FillH1(const std::string& name, double x, double w = 1.);
+  void FillH2(const std::string& name, double x, double y, double w = 1.);
+  void FillH1(const std::string& name, ELmvmAnaStep step, double x, double w = 1.);
+  void FillH2(const std::string& name, ELmvmAnaStep step, double x, double y, double w = 1.);
+  void FillH1(const std::string& name, ELmvmSrc src, double x, double wSignal);
+  void FillH2(const std::string& name, ELmvmSrc src, double x, double y, double wSignal);
+  void FillH1(const std::string& name, ELmvmSrc src, ELmvmAnaStep step, double x, double wSignal);
+  void FillH2(const std::string& name, ELmvmSrc src, ELmvmAnaStep step, double x, double y, double wSignal);
+
+  TNamed* GetObject(const std::string& name) { return fHM.GetObject(name); }
+
+  TH1D* H1(const std::string& name) { return static_cast<TH1D*>(fHM.H1(name)); }
+  TH2D* H2(const std::string& name) { return static_cast<TH2D*>(fHM.H2(name)); }
+  TH1D* H1(const std::string& name, ELmvmAnaStep step) { return H1(GetName(name, step)); }
+  TH2D* H2(const std::string& name, ELmvmAnaStep step) { return H2(GetName(name, step)); }
+  TH1D* H1(const std::string& name, ELmvmSrc src) { return H1(GetName(name, src)); }
+  TH2D* H2(const std::string& name, ELmvmSrc src) { return H2(GetName(name, src)); }
+  TH1D* H1(const std::string& name, ELmvmSrc src, ELmvmAnaStep step) { return H1(GetName(name, src, step)); }
+  TH2D* H2(const std::string& name, ELmvmSrc src, ELmvmAnaStep step) { return H2(GetName(name, src, step)); }
+
+  TH1D* H1Clone(const std::string& name) { return static_cast<TH1D*>(H1(name)->Clone()); }
+  TH2D* H2Clone(const std::string& name) { return static_cast<TH2D*>(H2(name)->Clone()); }
+  TH1D* H1Clone(const std::string& name, ELmvmAnaStep step) { return static_cast<TH1D*>(H1(name, step)->Clone()); }
+  TH2D* H2Clone(const std::string& name, ELmvmAnaStep step) { return static_cast<TH2D*>(H2(name, step)->Clone()); }
+  TH1D* H1Clone(const std::string& name, ELmvmSrc src) { return static_cast<TH1D*>(H1(name, src)->Clone()); }
+  TH2D* H2Clone(const std::string& name, ELmvmSrc src) { return static_cast<TH2D*>(H2(name, src)->Clone()); }
+  TH1D* H1Clone(const std::string& name, ELmvmSrc src, ELmvmAnaStep step)
+  {
+    return static_cast<TH1D*>(H1(name, src, step)->Clone());
+  }
+  TH2D* H2Clone(const std::string& name, ELmvmSrc src, ELmvmAnaStep step)
+  {
+    return static_cast<TH2D*>(H2(name, src, step)->Clone());
+  }
+
+  std::string GetName(const std::string& name, ELmvmAnaStep step);
+  std::string GetName(const std::string& name, ELmvmSrc src);
+  std::string GetName(const std::string& name, ELmvmSrc src, ELmvmAnaStep step);
+
+
+  void Rebin(const std::string& name, int nGroup);
+  void Rebin(const std::string& name, const std::vector<std::string>& subNames, int nGroup);
+  void Rebin(const std::string& name, const std::vector<std::string>& subNames1,
+             const std::vector<std::string>& subNames2, int nGroup);
+
+  void WriteToFile();
+
+  void DrawEfficiency(TH1* h1, TH1* h2, double xPos, double yPos);
+
+  static void DrawAnaStepOnPad(ELmvmAnaStep step);
+
+  CbmHistManager fHM;
 
-  const static int fNofBgPairSources = 6;
-  const static std::vector<std::string> fBgPairSourceLatex;
+  ClassDef(LmvmHist, 1);
 };
 
 #endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmLinkDef.h b/analysis/PWGDIL/dielectron/lmvm/LmvmLinkDef.h
index 99f61b12aca1966a680b0400265e1add73c7c669..b1f0f06dfc7b7a95c0866ba64a19a4ac8b69c778 100644
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmLinkDef.h
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmLinkDef.h
@@ -1,6 +1,6 @@
-/* Copyright (C) 2016 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+/* Copyright (C) 2016-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Florian Uhlig [committer] */
+   Authors: Florian Uhlig [committer], Semen Lebedev */
 
 #ifdef __CINT__
 
@@ -9,11 +9,10 @@
 #pragma link off all functions;
 
 
-#pragma link C++ class CbmAnaDielectronTask + ;
-#pragma link C++ class CbmAnaDielectronTaskDraw + ;
-#pragma link C++ class CbmAnaDielectronTaskDrawAll + ;
-#pragma link C++ class CbmAnaLmvmDrawStudy + ;
-#pragma link C++ class CbmAnaDielectronReports + ;
-#pragma link C++ class CbmHaddBase + ;
+#pragma link C++ class LmvmTask + ;
+#pragma link C++ class LmvmDraw + ;
+#pragma link C++ class LmvmDrawAll + ;
+#pragma link C++ class LmvmHist + ;
+#pragma link C++ class LmvmUtils + ;
 
 #endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmSimParam.h b/analysis/PWGDIL/dielectron/lmvm/LmvmSimParam.h
new file mode 100644
index 0000000000000000000000000000000000000000..53e553c3a16673ec51e248a5d416e51953c550ae
--- /dev/null
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmSimParam.h
@@ -0,0 +1,58 @@
+/* Copyright (C) 2021 Justus-Liebig-Universitaet Giessen, Giessen
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Semen Lebedev [committer] */
+
+#ifndef LMVM_SIM_PARAM_H
+#define LMVM_SIM_PARAM_H
+
+#include "Logger.h"
+
+#include "TObject.h"
+
+#include <string>
+
+class LmvmSimParam {
+public:
+  static Double_t GetWeight(const std::string& energy, const std::string& particle)
+  {
+    // TODO: check all weights for all energies and particles
+    // Weight = Multiplicity * Branching Ratio
+    if (energy == "8gev" || energy == "12gev") {
+      // TODO: add weights for 12geV
+      if (particle == "omegaepem" || particle == "w") return 2.28721 * 7.36e-5;
+      if (particle == "omegadalitz" || particle == "wdalitz") return 2.28721 * 7.7e-4;
+      if (particle == "phi") return 0.311619 * 2.97e-4;
+      if (particle == "inmed" || particle == "rho0") return 0.0304706 * 4.72e-5;
+      if (particle == "qgp" || particle == "qgp_epem") return 4.52941e-4 * 1.15e-2;  // TODO: check BR
+    }
+    else if (energy == "25gev") {
+      if (particle == "rho0") return 23 * 4.7e-5;
+      if (particle == "omegaepem" || particle == "w") return 38 * 7.28e-5;
+      if (particle == "omegadalitz" || particle == "wdalitz") return 38 * 7.7e-4;
+      if (particle == "phi") return 1.28 * 2.97e-4;
+      if (particle == "inmed") return 4.45e-2;
+      if (particle == "qgp" || particle == "qgp_epem") return 1.15e-2;
+    }
+    else if (energy == "3.5gev") {
+      if (particle == "rho0") return 1.0 * 4.7e-5;
+      if (particle == "omegaepem" || particle == "w") return 1.2 * 7.28e-5;
+      if (particle == "omegadalitz" || particle == "wdalitz") return 1.2 * 7.7e-5;
+      if (particle == "phi") return 0.1 * 2.97e-4;
+    }
+    else if (energy == "4.5gev") {
+      if (particle == "omegadalitz" || particle == "wdalitz") return 1.2 * 7.7e-5;
+      if (particle == "omegaepem" || particle == "w") return 1.2 * 7.28e-6;
+      if (particle == "phi") return 1.2 * 2.97e-6;
+      if (particle == "inmed") return 2.4 * 10e-3;
+    }
+    else {
+      LOG(fatal) << "LmvmSimParam::SetEnergyAndParticle energy or particle is not correct, energy:" << energy
+                 << " particle:" << particle;
+      return 0.;
+    }
+    return 0.;
+  }
+};
+
+
+#endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmTask.cxx b/analysis/PWGDIL/dielectron/lmvm/LmvmTask.cxx
index bb1d36895b49b3e4d58c1aa4c489c24b3ae00b86..5bf25f37e7e7c455520ce950a3e5c635e437a716 100644
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmTask.cxx
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmTask.cxx
@@ -2,19 +2,11 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Andrey Lebedev, Elena Lebedeva, Semen Lebedev [committer] */
 
-/** CbmAnaDielectronTask.cxx
- * based on class by T.Galatyuk
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2010
- * @version 3.0
- **/
-
-#include "CbmAnaDielectronTask.h"
+#include "LmvmTask.h"
 
 #include "CbmGlobalTrack.h"
 #include "CbmKF.h"
 #include "CbmL1PFFitter.h"
-#include "CbmLmvmUtils.h"
 #include "CbmMCTrack.h"
 #include "CbmMatch.h"
 #include "CbmMvdHit.h"
@@ -31,2739 +23,1084 @@
 #include "CbmTrdTrack.h"
 #include "CbmVertex.h"
 #include "cbm/elid/CbmLitGlobalElectronId.h"
+#include "cbm/qa/mc/CbmLitMCTrackCreator.h"
 
-#include "FairBaseParSet.h"
 #include "FairEventHeader.h"
-#include "FairGeoMedium.h"
-#include "FairGeoNode.h"
-#include "FairGeoTransform.h"
-#include "FairGeoVector.h"
-#include "FairGeoVolume.h"
 #include "FairMCPoint.h"
 #include "FairRootManager.h"
 #include "FairRunAna.h"
-#include "FairRuntimeDb.h"
 #include "FairTask.h"
 #include "FairTrackParam.h"
 
 #include "TClonesArray.h"
 #include "TDatabasePDG.h"
-#include "TF1.h"
-#include "TGraph.h"
-#include "TH1D.h"
-#include "TH2D.h"
-#include "TLorentzVector.h"
-#include "TMath.h"
-#include "TObjArray.h"
-#include "TObject.h"
-#include "TProfile.h"
+#include "TFile.h"
 #include "TRandom3.h"
-#include "TStopwatch.h"
-#include "TString.h"
-#include "TSystem.h"
 #include "TVector3.h"
-#include <TFile.h>
 
 #include <sstream>
 #include <vector>
 
-#include "L1Field.h"
-
-using namespace std;
-
-ClassImp(CbmAnaDielectronTask);
-
+#include "LmvmSimParam.h"
+#include "LmvmUtils.h"
 
-void CbmAnaDielectronTask::CreateAnalysisStepsH1(vector<TH1D*>& hist, const string& name, const string& axisX,
-                                                 const string& axisY, double nBins, double min, double max)
-{
-  string hname = "";
-  hist.resize(CbmLmvmHist::fNofAnaSteps);
-  for (Int_t i = 0; i < CbmLmvmHist::fNofAnaSteps; i++) {
-    hname   = name + "_" + CbmLmvmHist::fAnaSteps[i];
-    hist[i] = new TH1D(hname.c_str(), hname.c_str(), nBins, min, max);
-    hist[i]->GetXaxis()->SetTitle(axisX.c_str());
-    hist[i]->GetYaxis()->SetTitle(axisY.c_str());
-    fHistoList.push_back(hist[i]);
-  }
-}
 
-void CbmAnaDielectronTask::CreateAnalysisStepsH2(vector<TH2D*>& hist, const string& name, const string& axisX,
-                                                 const string& axisY, const string& axisZ, double nBinsX, double minX,
-                                                 double maxX, double nBinsY, double minY, double maxY)
-{
-  string hname = "";
-  hist.resize(CbmLmvmHist::fNofAnaSteps);
-  for (Int_t i = 0; i < CbmLmvmHist::fNofAnaSteps; i++) {
-    hname   = name + "_" + CbmLmvmHist::fAnaSteps[i];
-    hist[i] = new TH2D(hname.c_str(), hname.c_str(), nBinsX, minX, maxX, nBinsY, minY, maxY);
-    hist[i]->GetXaxis()->SetTitle(axisX.c_str());
-    hist[i]->GetYaxis()->SetTitle(axisY.c_str());
-    hist[i]->GetZaxis()->SetTitle(axisZ.c_str());
-    fHistoList.push_back(hist[i]);
-  }
-}
+using namespace std;
 
-void CbmAnaDielectronTask::CreateSourceTypesH1(vector<TH1D*>& hist, const string& name, const string& axisX,
-                                               const string& axisY, double nBins, double min, double max)
-{
-  string hname = "";
-  hist.resize(CbmLmvmHist::fNofSourceTypes);
-  for (Int_t i = 0; i < CbmLmvmHist::fNofSourceTypes; i++) {
-    hname   = name + "_" + CbmLmvmHist::fSourceTypes[i];
-    hist[i] = new TH1D(hname.c_str(), hname.c_str(), nBins, min, max);
-    hist[i]->GetXaxis()->SetTitle(axisX.c_str());
-    hist[i]->GetYaxis()->SetTitle(axisY.c_str());
-    fHistoList.push_back(hist[i]);
-  }
-}
+ClassImp(LmvmTask);
 
-void CbmAnaDielectronTask::CreateSourceTypesH2(vector<TH2D*>& hist, const string& name, const string& axisX,
-                                               const string& axisY, const string& axisZ, double nBinsX, double minX,
-                                               double maxX, double nBinsY, double minY, double maxY)
-{
-  string hname = "";
-  hist.resize(CbmLmvmHist::fNofSourceTypes);
-  for (Int_t i = 0; i < CbmLmvmHist::fNofSourceTypes; i++) {
-    hname   = name + "_" + CbmLmvmHist::fSourceTypes[i];
-    hist[i] = new TH2D(hname.c_str(), hname.c_str(), nBinsX, minX, maxX, nBinsY, minY, maxY);
-    hist[i]->GetXaxis()->SetTitle(axisX.c_str());
-    hist[i]->GetYaxis()->SetTitle(axisY.c_str());
-    hist[i]->GetZaxis()->SetTitle(axisZ.c_str());
-    fHistoList.push_back(hist[i]);
-  }
-}
 
-CbmAnaDielectronTask::CbmAnaDielectronTask()
-  : FairTask("CbmAnaDielectronTask")
-  , fMCEventHeader(NULL)
-  , fMCTracks(NULL)
-  , fRichRings(NULL)
-  , fRichProj(NULL)
-  , fRichPoints(NULL)
-  , fRichRingMatches(NULL)
-  , fRichHits(NULL)
-  , fGlobalTracks(NULL)
-  , fStsTracks(NULL)
-  , fStsTrackMatches(NULL)
-  , fStsHits(NULL)
-  , fMvdHits(NULL)
-  , fMvdPoints(NULL)
-  , fMvdHitMatches(NULL)
-  , fTrdTracks(NULL)
-  , fTrdHits(NULL)
-  , fTrdTrackMatches(NULL)
-  , fTofHits(NULL)
-  , fTofHitsMatches(NULL)
-  , fTofPoints(NULL)
-  , fPrimVertex(NULL)
-  , fKFVertex()
-  , fKFFitter()
-  ,
-  //  fMCTrackCreator(NULL),
-  fUseMvd(kFALSE)
-  , fUseRich(kTRUE)
-  , fUseTrd(kTRUE)
-  , fUseTof(kTRUE)
-  , fCandidates()
-  , fCandidatesTotal()
-  , fSTCandidates()
-  , fTTCandidates()
-  , fRTCandidates()
-  , fWeight(0.)
-  , fPionMisidLevel(-1.)
-  , fRandom3(new TRandom3(0))
-  , fCuts()
-  , fHistoList()
-  , fNofHitsInRingMap()
-  , fh_mc_signal_mom_angle()
-  , fh_nof_charged_particles()
-  , fh_nof_charged_particles_acc()
-  , fh_mc_mother_pdg(NULL)
-  , fh_acc_mother_pdg(NULL)
-  , fh_signal_pmtXY(NULL)
-  , fh_pi0_pmtXY(NULL)
-  , fh_gamma_pmtXY(NULL)
-  , fh_vertex_el_gamma_xz()
-  , fh_vertex_el_gamma_yz()
-  , fh_vertex_el_gamma_xy()
-  , fh_vertex_el_gamma_rz()
-  , fh_signal_minv()
-  , fh_bg_minv()
-  , fh_combPairsPM_minv_sameEvent()
-  , fh_combPairsPP_minv_sameEvent()
-  , fh_combPairsMM_minv_sameEvent()
-  , fh_combPairsPM_minv_mixedEvents()
-  , fh_combPairsPP_minv_mixedEvents()
-  , fh_combPairsMM_minv_mixedEvents()
-  , fh_nof_plutoElectrons()
-  , fh_nof_plutoPositrons()
-  , fh_nof_urqmdElectrons()
-  , fh_nof_urqmdPositrons()
-  , fh_nof_plutoElectrons_p_pt()
-  , fh_nof_plutoPositrons_p_pt()
-  , fh_nof_urqmdElectrons_p_pt()
-  , fh_nof_urqmdPositrons_p_pt()
-  , fh_nof_particles_acc()
-  , fh_nof_points()
-  , fh_pi0_minv()
-  , fh_eta_minv()
-  , fh_gamma_minv()
-  , fh_signal_mom()
-  , fh_signal_pty()
-  , fh_signal_minv_pt()
-  , fh_eta_minv_pt()
-  , fh_pi0_minv_pt()
-  , fh_bg_truematch_minv()
-  , fh_bg_truematch_el_minv()
-  , fh_bg_truematch_notel_minv()
-  , fh_bg_mismatch_minv()
-  , fh_source_bg_minv()
-  , fh_pt()
-  , fh_mom()
-  , fh_chi2sts()
-  , fh_chi2prim()
-  , fh_ttcut()
-  , fh_stcut()
-  , fh_rtcut()
-  , fh_mvd1cut()
-  , fh_mvd2cut()
-  , fh_richann()
-  , fh_trdann()
-  , fh_tofm2()
-  , fh_ttcut_pion()
-  , fh_ttcut_truepair()
-  , fh_stcut_pion()
-  , fh_stcut_truepair()
-  , fh_rtcut_pion()
-  , fh_rtcut_truepair()
-  , fh_nofMvdHits()
-  , fh_nofStsHits()
-  , fh_mvd1xy()
-  , fh_mvd1r()
-  , fh_mvd2xy()
-  , fh_mvd2r()
-  , fh_mvd1cut_mc_dist_gamma(NULL)
-  , fh_mvd1cut_mc_dist_pi0(NULL)
-  , fh_mvd2cut_mc_dist_gamma(NULL)
-  , fh_mvd2cut_mc_dist_pi0(NULL)
-  , fh_mvd1cut_qa()
-  , fh_mvd2cut_qa()
-  , fh_source_pairs_epem()
-  , fh_source_pairs(NULL)
-  , fh_event_number(NULL)
-  , fh_event_number_mixed(NULL)
-  , fh_nof_bg_tracks(NULL)
-  , fh_nof_el_tracks(NULL)
-  , fh_source_tracks(NULL)
-  , fh_nof_topology_pairs_gamma(NULL)
-  , fh_nof_topology_pairs_pi0(NULL)
-  , fh_nof_rec_pairs_gamma(NULL)
-  , fh_nof_rec_pairs_pi0(NULL)
-  , fh_nof_rec_gamma(NULL)
-  , fh_nof_rec_pi0(NULL)
-  , fh_nof_mismatches(NULL)
-  , fh_nof_mismatches_rich(NULL)
-  , fh_nof_mismatches_trd(NULL)
-  , fh_nof_mismatches_tof(NULL)
-  , fh_nof_ghosts(NULL)
-  , fh_source_mom()
-  , fh_source_pt()
-  , fh_opening_angle()
-  , fh_pi_mom_mc(NULL)
-  , fh_pi_mom_acc(NULL)
-  , fh_pi_mom_rec(NULL)
-  , fh_pi_mom_rec_only_sts(NULL)
-  , fh_pi_mom_rec_sts_rich_trd(NULL)
-  , fh_pi_mom_rec_sts_rich_trd_tof(NULL)
-  , fh_pi_rapidity_mc(NULL)
-  , fh_piprim_mom_mc(NULL)
-  , fh_piprim_mom_acc(NULL)
-  , fh_piprim_mom_rec(NULL)
-  , fh_piprim_mom_rec_only_sts(NULL)
-  , fh_piprim_mom_rec_sts_rich_trd(NULL)
-  , fh_piprim_mom_rec_sts_rich_trd_tof(NULL)
-  , fh_piprim_plus_rapidity_mc(NULL)
-  , fh_piprim_minus_rapidity_mc(NULL)
-  , fh_pi0prim_rapidity_mc(NULL)
-  , fh_etaprim_rapidity_mc(NULL)
-  , fh_mom_likelihood_El(NULL)
-  , fh_mom_likelihood_Pi(NULL)
-{
-  // weight for rho0 = 0.001081; omega_ee = 0.0026866; omega_dalitz = 0.02242; phi = 0.00039552; pi0 = 4.38   ------ Au + Au, for 25 GeV central collision
-  fWeight         = 0.0;
-  fUseRich        = true;
-  fUseTrd         = true;
-  fUseTof         = true;
-  fPionMisidLevel = -1.;
-  fRandom3        = new TRandom3(0);
-
-  fCuts.SetDefaultCuts();
-}
+LmvmTask::LmvmTask() : FairTask("LmvmTask") {}
 
 
-CbmAnaDielectronTask::~CbmAnaDielectronTask() {}
+LmvmTask::~LmvmTask() {}
 
 
-void CbmAnaDielectronTask::InitHists()
+void LmvmTask::InitHists()
 {
-  fHistoList.clear();
-
-
-  //MC Pairs
-  fh_mc_signal_mom_angle = new TH2D("fh_mc_signal_mom_angle",
-                                    "fh_mc_signal_mom_angle; #sqrt{p_{e^{#pm}} p_{e^{#mp}}} [GeV/c]; "
-                                    "#theta_{e^{+},e^{-}} [deg] ;Counter",
-                                    100, 0., 5., 1000, 0., 50.);
-  fHistoList.push_back(fh_mc_signal_mom_angle);
-
-  //Number of Particles per Event
-  fh_nof_charged_particles =
-    new TH1D("fh_nof_charged_particles", "fh_nof_charged_particles; nof charged particles; Yield", 500, 0., 500.);
-  fHistoList.push_back(fh_nof_charged_particles);
-  fh_nof_charged_particles_acc = new TH1D("fh_nof_charged_particles_acc",
-                                          "fh_nof_charged_particles_acc; nof charged particles; Yield", 500, 0., 500);
-  fHistoList.push_back(fh_nof_charged_particles_acc);
-
-  // Mother PDG
-  fh_mc_mother_pdg =
-    new TH1D("fh_mc_mother_pdg", "fh_mc_mother_pdg; Pdg code; Particles per event", 7000, -3500., 3500.);
-  fHistoList.push_back(fh_mc_mother_pdg);
-  fh_acc_mother_pdg =
-    new TH1D("fh_acc_mother_pdg", "fh_acc_mother_pdg; Pdg code; Particles per event", 7000, -3500., 3500.);
-  fHistoList.push_back(fh_acc_mother_pdg);
-
-  //X-Y distribution of MC points on PMT
-  fh_signal_pmtXY =
-    new TH2D("fh_signal_pmtXY", "fh_signal_pmtXY;X [cm];Y [cm];Counter", 110, -110, 110, 200, -200, 200);
-  fHistoList.push_back(fh_signal_pmtXY);
-  fh_pi0_pmtXY = new TH2D("fh_pi0_pmtXY", "fh_pi0_pmtXY;X [cm];Y [cm];Counter", 110, -110, 110, 200, -200, 200);
-  fHistoList.push_back(fh_pi0_pmtXY);
-  fh_gamma_pmtXY = new TH2D("fh_gamma_pmtXY", "fh_gamma_pmtXY;X [cm];Y [cm];Counter", 110, -110, 110, 200, -200, 200);
-  fHistoList.push_back(fh_gamma_pmtXY);
-
-  //vertex of the secondary electrons from gamma conversion
-  CreateAnalysisStepsH2(fh_vertex_el_gamma_xz, "fh_vertex_el_gamma_xz", "Z [cm]", "X [cm]", "Counter per event", 200,
-                        -10., 190., 400, -130., 130.);
-  CreateAnalysisStepsH2(fh_vertex_el_gamma_yz, "fh_vertex_el_gamma_yz", "Z [cm]", "Y [cm]", "Counter per event", 200,
-                        -10., 190., 400, -130., 130.);
-  CreateAnalysisStepsH2(fh_vertex_el_gamma_xy, "fh_vertex_el_gamma_xy", "X [cm]", "Y [cm]", "Counter per event", 400,
-                        -130., 130., 400, -130., 130.);
-  CreateAnalysisStepsH2(fh_vertex_el_gamma_rz, "fh_vertex_el_gamma_rz", "Z [cm]", "#sqrt{X^{2}+Y^{2}} [cm]",
-                        "Counter per event", 300, -10., 190., 300, 0., 150.);
-
-  // Number of BG and signal tracks after each cut
-  fh_nof_bg_tracks = new TH1D("fh_nof_bg_tracks", "fh_nof_bg_tracks;Analysis steps;Tracks/event",
-                              CbmLmvmHist::fNofAnaSteps, 0., CbmLmvmHist::fNofAnaSteps);
-  fHistoList.push_back(fh_nof_bg_tracks);
-  fh_nof_el_tracks = new TH1D("fh_nof_el_tracks", "fh_nof_el_tracks;Analysis steps;Tracks/event",
-                              CbmLmvmHist::fNofAnaSteps, 0., CbmLmvmHist::fNofAnaSteps);
-  fHistoList.push_back(fh_nof_el_tracks);
-  fh_source_tracks = new TH2D("fh_source_tracks", "fh_source_tracks;Analysis steps;Particle", CbmLmvmHist::fNofAnaSteps,
-                              0., CbmLmvmHist::fNofAnaSteps, 7, 0., 7.);
-  fHistoList.push_back(fh_source_tracks);
-
-  fh_nof_topology_pairs_gamma =
-    new TH1D("fh_nof_topology_pairs_gamma", "fh_nof_topology_pairs_gamma;Pair type;Pairs/event", 8, 0., 8);
-  fHistoList.push_back(fh_nof_topology_pairs_gamma);
-
-  fh_nof_topology_pairs_pi0 =
-    new TH1D("fh_nof_topology_pairs_pi0", "fh_nof_topology_pairs_pi0;Pair type;Pairs/event", 8, 0., 8);
-  fHistoList.push_back(fh_nof_topology_pairs_pi0);
-
-  //Number of mismatches and ghosts after each cut
-  fh_nof_mismatches = new TH1D("fh_nof_mismatches", "fh_nof_mismatches;Analysis steps;Tracks/event",
-                               CbmLmvmHist::fNofAnaSteps, 0., CbmLmvmHist::fNofAnaSteps);
-  fHistoList.push_back(fh_nof_mismatches);
-  fh_nof_mismatches_rich = new TH1D("fh_nof_mismatches_rich", "fh_nof_mismatches_rich;Analysis steps;Tracks/event",
-                                    CbmLmvmHist::fNofAnaSteps, 0., CbmLmvmHist::fNofAnaSteps);
-  fHistoList.push_back(fh_nof_mismatches_rich);
-  fh_nof_mismatches_trd = new TH1D("fh_nof_mismatches_trd", "fh_nof_mismatches_trd;Analysis steps;Tracks/event",
-                                   CbmLmvmHist::fNofAnaSteps, 0., CbmLmvmHist::fNofAnaSteps);
-  fHistoList.push_back(fh_nof_mismatches_trd);
-  fh_nof_mismatches_tof = new TH1D("fh_nof_mismatches_tof", "fh_nof_mismatches_tof;Analysis steps;Tracks/event",
-                                   CbmLmvmHist::fNofAnaSteps, 0., CbmLmvmHist::fNofAnaSteps);
-  fHistoList.push_back(fh_nof_mismatches_tof);
-  fh_nof_ghosts = new TH1D("fh_nof_ghosts", "fh_nof_ghosts;Analysis steps;Tracks/event", CbmLmvmHist::fNofAnaSteps, 0.,
-                           CbmLmvmHist::fNofAnaSteps);
-  fHistoList.push_back(fh_nof_ghosts);
-
-  // BG pair source
-  fh_source_pairs =
-    new TH2D("fh_source_pairs", "fh_source_pairs;Analysis steps;Pair", CbmLmvmHist::fNofAnaSteps, 0.,
-             CbmLmvmHist::fNofAnaSteps, CbmLmvmHist::fNofBgPairSources, 0., CbmLmvmHist::fNofBgPairSources);
-  fHistoList.push_back(fh_source_pairs);
-
-  // Event number counter
-  fh_event_number = new TH1D("fh_event_number", "fh_event_number", 1, 0, 1.);
-  fHistoList.push_back(fh_event_number);
-  fh_event_number_mixed = new TH1D("fh_event_number_mixed", "fh_event_number_mixed", 1, 0, 1.);
-  fHistoList.push_back(fh_event_number_mixed);
-
-  CreateSourceTypesH1(fh_richann, "fh_richann", "ANN output", "Yield", 100, -1.1, 1.1);
-  CreateSourceTypesH1(fh_trdann, "fh_trdann", "ANN output", "Yield", 100, -1.1, 1.1);
-  CreateSourceTypesH2(fh_tofm2, "fh_tofm2", "P [GeV/c]", "m^{2} [GeV/c^{2}]^{2}", "Yield", 100, 0., 4., 600, -0.000001,
-                      0.00001);
-
-  // Distributions of analysis cuts.
-  // Transverse momentum of tracks.
-  CreateSourceTypesH1(fh_pt, "fh_pt", "P_{t} [GeV/c]", "Yield", 200, 0., 2.);
-  // Momentum of tracks
-  CreateSourceTypesH1(fh_mom, "fh_mom", "P [GeV/c]", "Yield", 200, 0., 10.);
-  // Chi2 of the STS tracks
-  CreateSourceTypesH1(fh_chi2sts, "fh_chi2sts", "#chi^{2}", "Yield", 200, 0., 20.);
-  // Chi2 of the primary vertex
-  CreateSourceTypesH1(fh_chi2prim, "fh_chi2prim", "#chi^{2}_{prim}", "Yield", 200, 0., 20.);
-  // TT cut
-  CreateSourceTypesH2(fh_ttcut, "fh_ttcut", "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]", "#theta_{e^{+},e^{-}} [deg]", "Yield",
-                      100, 0., 5., 100, 0., 5.);
-  // ST cut
-  CreateSourceTypesH2(fh_stcut, "fh_stcut", "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]", "#theta_{e^{#pm},rec} [deg]", "Yield",
-                      100, 0., 5., 100, 0., 5.);
-  // RT cut
-  CreateSourceTypesH2(fh_rtcut, "fh_rtcut", "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]", "#theta_{e^{#pm},rec} [deg]", "Yield",
-                      100, 0., 5., 100, 0., 5.);
-  // MVD cut at the first station
-  CreateSourceTypesH2(fh_mvd1cut, "fh_mvd1cut", "d_{MVD} [cm]", "P_{e} [GeV/c]", "Yield", 100, 0., 1., 100, 0., 5.);
-  // MVD cut at the second station
-  CreateSourceTypesH2(fh_mvd2cut, "fh_mvd2cut", "d_{MVD} [cm]", "P_{e} [GeV/c]", "Yield", 100, 0., 1., 100, 0., 5.);
-
-  CreateSourceTypesH2(fh_ttcut_pion, "fh_ttcut_pion", "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]",
-                      "#theta_{e^{+},e^{-}} [deg]", "Yield", 100, 0., 5., 100, 0., 5.);
-  CreateSourceTypesH2(fh_ttcut_truepair, "fh_ttcut_truepair", "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]",
-                      "#theta_{e^{+},e^{-}} [deg]", "Yield", 100, 0., 5., 100, 0., 5.);
-  CreateSourceTypesH2(fh_stcut_pion, "fh_stcut_pion", "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]",
-                      "#theta_{e^{+},e^{-}} [deg]", "Yield", 100, 0., 5., 100, 0., 5.);
-  CreateSourceTypesH2(fh_stcut_truepair, "fh_stcut_truepair", "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]",
-                      "#theta_{e^{+},e^{-}} [deg]", "Yield", 100, 0., 5., 100, 0., 5.);
-  CreateSourceTypesH2(fh_rtcut_pion, "fh_rtcut_pion", "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]",
-                      "#theta_{e^{+},e^{-}} [deg]", "Yield", 100, 0., 5., 100, 0., 5.);
-  CreateSourceTypesH2(fh_rtcut_truepair, "fh_rtcut_truepair", "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]",
-                      "#theta_{e^{+},e^{-}} [deg]", "Yield", 100, 0., 5., 100, 0., 5.);
-
-  CreateSourceTypesH1(fh_nofMvdHits, "fh_nofMvdHits", "Number of hits in MVD", "Yield", 5, -0.5, 4.5);
-  CreateSourceTypesH1(fh_nofStsHits, "fh_nofStsHits", "Number of hits in STS", "Yield", 9, -0.5, 8.5);
-  CreateSourceTypesH2(fh_mvd1xy, "fh_mvd1xy", "X [cm]", "Y [cm]", "Yield", 60, -3., 3., 60, -3., 3.);
-  CreateSourceTypesH1(fh_mvd1r, "fh_mvd1r", "#sqrt{X^{2}+Y^{2}} [cm]", "Yield", 60, 0., 3.);
-  CreateSourceTypesH2(fh_mvd2xy, "fh_mvd2xy", "X [cm]", "Y [cm]", "Yield", 60, -6., 6., 60, -6., 6.);
-  CreateSourceTypesH1(fh_mvd2r, "fh_mvd2r", "#sqrt{X^{2}+Y^{2}} [cm]", "Yield", 60, 0., 6.);
-
-  // Check MVD cut quality. [0.5]-correct, [1.5]-wrong
-  CreateSourceTypesH1(fh_mvd1cut_qa, "fh_mvd1cut_qa", "MVD hit assignment", "Yield", 2, 0., 2.);
-  CreateSourceTypesH1(fh_mvd2cut_qa, "fh_mvd2cut_qa", "MVD hit assignment", "Yield", 2, 0., 2.);
-
-  //Create invariant mass histograms
-  CreateAnalysisStepsH1(fh_signal_minv, "fh_signal_minv", "M_{ee} [GeV/c^{2}]", "Yield", 4000, 0., 4.);
-  CreateAnalysisStepsH1(fh_bg_minv, "fh_bg_minv", "M_{ee} [GeV/c^{2}]", "Yield", 4000, 0., 4.);
-  CreateAnalysisStepsH1(fh_pi0_minv, "fh_pi0_minv", "M_{ee} [GeV/c^{2}]", "Yield", 4000, 0., 4.);
-  CreateAnalysisStepsH1(fh_eta_minv, "fh_eta_minv", "M_{ee} [GeV/c^{2}]", "Yield", 4000, 0., 4.);
-  CreateAnalysisStepsH1(fh_gamma_minv, "fh_gamma_minv", "M_{ee} [GeV/c^{2}]", "Yield", 4000, 0., 4.);
-
-  // Histograms for combinatorial BG
-  CreateAnalysisStepsH1(fh_combPairsPM_minv_sameEvent, "fh_combPairsPM_minv_sameEvent", "M_{e+e-} [GeV/c^{2}]", "Yield",
-                        4000, 0., 4.);
-  CreateAnalysisStepsH1(fh_combPairsPP_minv_sameEvent, "fh_combPairsPP_minv_sameEvent", "M_{e+e+} [GeV/c^{2}]", "Yield",
-                        4000, 0., 4.);
-  CreateAnalysisStepsH1(fh_combPairsMM_minv_sameEvent, "fh_combPairsMM_minv_sameEvent", "M_{e-e-} [GeV/c^{2}]", "Yield",
-                        4000, 0., 4.);
-
-  CreateAnalysisStepsH1(fh_combPairsPM_minv_mixedEvents, "fh_combPairsPM_minv_mixedEvents", "M_{e+e-} [GeV/c^{2}]",
-                        "Yield", 4000, 0., 4.);
-  CreateAnalysisStepsH1(fh_combPairsPP_minv_mixedEvents, "fh_combPairsPP_minv_mixedEvents", "M_{e+e+} [GeV/c^{2}]",
-                        "Yield", 4000, 0., 4.);
-  CreateAnalysisStepsH1(fh_combPairsMM_minv_mixedEvents, "fh_combPairsMM_minv_mixedEvents", "M_{e-e-} [GeV/c^{2}]",
-                        "Yield", 4000, 0., 4.);
-
-  // 1D Histograms for single particle yield vs. momentum
-  CreateAnalysisStepsH1(fh_nof_plutoElectrons, "fh_nof_plutoElectrons", "P [Gev/c]", "yield pluto electrons", 100, 0,
-                        10.);
-  CreateAnalysisStepsH1(fh_nof_plutoPositrons, "fh_nof_plutoPositrons", "P [Gev/c]", "yield pluto positrons", 100, 0,
-                        10.);
-  CreateAnalysisStepsH1(fh_nof_urqmdElectrons, "fh_nof_urqmdElectrons", "P [Gev/c]", "yield urqmd electrons", 100, 0,
-                        10.);
-  CreateAnalysisStepsH1(fh_nof_urqmdPositrons, "fh_nof_urqmdPositrons", "P [Gev/c]", "yield urqmd positrons", 100, 0,
-                        10.);
-  // 2D Histograms for single particle yield vs. momentum and Pt
-  CreateAnalysisStepsH2(fh_nof_plutoElectrons_p_pt, "fh_nof_plutoElectrons_p_pt", "P [GeV/c]", "P_{t} [Gev/c]",
-                        "yield pluto electrons", 100, 0, 10., 40, 0., 4.);
-  CreateAnalysisStepsH2(fh_nof_plutoPositrons_p_pt, "fh_nof_plutoPositrons_p_pt", "P [GeV/c]", "P_{t} [Gev/c]",
-                        "yield pluto positrons", 100, 0, 10., 40, 0., 4.);
-  CreateAnalysisStepsH2(fh_nof_urqmdElectrons_p_pt, "fh_nof_urqmdElectrons_p_pt", "P [GeV/c]", "P_{t} [Gev/c]",
-                        "yield urqmd electrons", 100, 0, 10., 40, 0., 4.);
-  CreateAnalysisStepsH2(fh_nof_urqmdPositrons_p_pt, "fh_nof_urqmdPositrons_p_pt", "P [GeV/c]", "P_{t} [Gev/c]",
-                        "yield urqmd positrons", 100, 0, 10., 40, 0., 4.);
-
-  // minv for true matched and mismatched tracks
-  CreateAnalysisStepsH1(fh_bg_truematch_minv, "fh_bg_truematch_minv", "M_{ee} [GeV/c^{2}]", "Yield", 4000, 0., 4.);
-  CreateAnalysisStepsH1(fh_bg_truematch_el_minv, "fh_bg_truematch_el_minv", "M_{ee} [GeV/c^{2}]", "Yield", 4000, 0.,
-                        4.);
-  CreateAnalysisStepsH1(fh_bg_truematch_notel_minv, "fh_bg_truematch_notel_minv", "M_{ee} [GeV/c^{2}]", "Yield", 4000,
-                        0., 4.);
-  CreateAnalysisStepsH1(fh_bg_mismatch_minv, "fh_bg_mismatch_minv", "M_{ee} [GeV/c^{2}]", "Yield", 4000, 0., 4.);
-  // Minv for different sources
-  fh_source_bg_minv.resize(CbmLmvmHist::fNofBgPairSources);
-  for (int i = 0; i < CbmLmvmHist::fNofBgPairSources; i++) {
-    stringstream ss;
-    ss << "fh_source_bg_minv_" << i;
-    CreateAnalysisStepsH1(fh_source_bg_minv[i], ss.str(), "M_{ee} [GeV/c^{2}]", "Yield", 4000, 0., 4.);
-  }
-  //Invariant mass vs. Mc Pt
-  CreateAnalysisStepsH2(
-    fh_signal_minv_pt, "fh_signal_minv_pt", "M_{ee} [GeV/c^{2}]", "P_{t} [GeV/c]", "Yield", 100, 0., 4., 20, 0.,
-    2.);  // MIND: CHANGED "100, 0., 2." to 100, 0., 4., since in DrawAll.cxx this histo is added with the others below and compiler complains about various axes
-  CreateAnalysisStepsH2(fh_pi0_minv_pt, "fh_pi0_minv_pt", "M_{ee} [GeV/c^{2}]", "P_{t} [GeV/c]", "Yield", 100, 0., 4.,
-                        20, 0., 2.);
-  CreateAnalysisStepsH2(fh_eta_minv_pt, "fh_eta_minv_pt", "M_{ee} [GeV/c^{2}]", "P_{t} [GeV/c]", "Yield", 100, 0., 4.,
-                        20, 0., 2.);
-
-  // Momentum distribution of the signal
-  CreateAnalysisStepsH1(fh_signal_mom, "fh_signal_mom", "P [GeV/c]", "Yield", 100, 0., 15.);
-  //Pt/y distibution of the signal
-  CreateAnalysisStepsH2(fh_signal_pty, "fh_signal_pty", "Rapidity", "P_{t} [GeV/c]", "Yield", 40, 0., 4., 20, 0., 2.);
-  //Sources pairs 2D
-  CreateAnalysisStepsH2(fh_source_pairs_epem, "fh_source_pairs_epem", "mother particle e+", "mother particle e-",
-                        "Yield", 3, 0., 3., 3, 0., 3.);
-
-  fh_opening_angle.resize(CbmLmvmHist::fNofSourceTypes);
-  fh_source_mom.resize(CbmLmvmHist::fNofSourceTypes);
-  fh_source_pt.resize(CbmLmvmHist::fNofSourceTypes);
-  for (Int_t i = 0; i < CbmLmvmHist::fNofSourceTypes; i++) {
-    fh_opening_angle[i].resize(CbmLmvmHist::fNofAnaSteps);
-    fh_source_mom[i].resize(CbmLmvmHist::fNofAnaSteps);
-    fh_source_pt[i].resize(CbmLmvmHist::fNofAnaSteps);
+  string ax = "Yield";
+
+  fH.CreateH2("hMomVsAnglePairSignalMc", "#sqrt{P_{e^{#pm}} P_{e^{#mp}}} [GeV/c]", "#theta_{e^{+},e^{-}} [deg]",
+              "Counter", 100, 0., 5., 1000, 0., 50.);
+
+  fH.CreateH1("hMotherPdg", {"mc", "acc"}, "Pdg code", "Particles/event", 7000, -3500., 3500.);
+
+  fH.CreateH2("hPmtXY", fH.fSrcNames, "X [cm]", "Y [cm]", "Counter", 110, -110, 110, 200, -200, 200);
+
+  fH.CreateH2("hVertexGammaXZ", fH.fAnaStepNames, "Z [cm]", "X [cm]", ax, 200, -10., 190., 400, -130., 130.);
+  fH.CreateH2("hVertexGammaYZ", fH.fAnaStepNames, "Z [cm]", "Y [cm]", ax, 200, -10., 190., 400, -130., 130.);
+  fH.CreateH2("hVertexGammaXY", fH.fAnaStepNames, "X [cm]", "Y [cm]", ax, 400, -130., 130., 400, -130., 130.);
+  fH.CreateH2("hVertexGammaRZ", fH.fAnaStepNames, "Z [cm]", "#sqrt{X^{2}+Y^{2}} [cm]", ax, 300, -10., 190., 300, 0.,
+              150.);
+
+  fH.CreateH1("hNofBgTracks", "Analysis step", "Tracks/event", fH.fNofAnaSteps, 0., fH.fNofAnaSteps);
+  fH.CreateH1("hNofSignalTracks", "Analysis step", "Tracks/event", fH.fNofAnaSteps, 0., fH.fNofAnaSteps);
+  fH.CreateH2("hBgSrcTracks", "Analysis step", "Particle", ax, fH.fNofAnaSteps, 0., fH.fNofAnaSteps, 7, 0., 7.);
+
+  fH.CreateH1("hNofTopoPairs", {"gamma", "pi0"}, "Pair type", "Pairs/event", 8, 0., 8);
+  fH.CreateH1("hNofMismatches", {"all", "rich", "trd", "tof"}, "Analysis step", "Tracks/event", fH.fNofAnaSteps, 0.,
+              fH.fNofAnaSteps);
+
+  fH.CreateH1("hNofGhosts", "Analysis step", "Tracks/event", fH.fNofAnaSteps, 0., fH.fNofAnaSteps);
+
+  fH.CreateH2("hSrcBgPairs", "Analysis step", "Pair", ax, fH.fNofAnaSteps, 0., fH.fNofAnaSteps, fH.fNofBgPairSrc, 0.,
+              fH.fNofBgPairSrc);
+  fH.CreateH2("hSrcBgPairsEpEm", fH.fAnaStepNames, "mother particle e+", "mother particle e-", ax, 3, 0., 3., 3, 0.,
+              3.);
+
+  fH.CreateH1("hEventNumber", "", "", 1, 0, 1.);
+  fH.CreateH1("hEventNumberMixed", "", "", 1, 0, 1.);
+
+  fH.CreateH1("hRichAnn", fH.fSrcNames, "RICH ANN output", ax, 100, -1.1, 1.1);
+  fH.CreateH1("hTrdAnn", fH.fSrcNames, "TRD ANN output", ax, 100, -.1, 1.1);
+  fH.CreateH2("hTofM2", fH.fSrcNames, "P [GeV/c]", "m^{2} [GeV/c^{2}]^{2}", ax, 100, 0., 4., 200, -0.1, 1.0);
+  fH.CreateH1("hChi2Sts", fH.fSrcNames, "#chi^{2}", ax, 200, 0., 20.);
+  fH.CreateH1("hChi2PrimVertex", fH.fSrcNames, "#chi^{2}_{prim}", ax, 200, 0., 20.);
+  fH.CreateH1("hNofMvdHits", fH.fSrcNames, "Number of hits in MVD", ax, 5, -0.5, 4.5);
+  fH.CreateH1("hNofStsHits", fH.fSrcNames, "Number of hits in STS", ax, 9, -0.5, 8.5);
+
+  fH.CreateH2("hTtCut", {"all", "pion", "truePair"}, fH.fSrcNames, "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]",
+              "#theta_{e^{+},e^{-}} [deg]", ax, 100, 0., 5., 100, 0., 5.);
+  fH.CreateH2("hStCut", {"all", "pion", "truePair"}, fH.fSrcNames, "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]",
+              "#theta_{e^{#pm},rec} [deg]", ax, 100, 0., 5., 100, 0., 5.);
+  fH.CreateH2("hRtCut", {"all", "pion", "truePair"}, fH.fSrcNames, "#sqrt{p_{e^{#pm}} p_{rec}} [GeV/c]",
+              "#theta_{e^{#pm},rec} [deg]", ax, 100, 0., 5., 100, 0., 5.);
+
+  fH.CreateH2("hMvdCut", {"1", "2"}, fH.fSrcNames, "d_{MVD} [cm]", "P_{e} [GeV/c]", ax, 100, 0., 1., 100, 0., 5.);
+  fH.CreateH2("hMvdXY", {"1", "2"}, fH.fSrcNames, "X [cm]", "Y [cm]", ax, 60, -6., 6., 60, -6., 6.);
+  fH.CreateH1("hMvdR", {"1", "2"}, fH.fSrcNames, "#sqrt{X^{2}+Y^{2}} [cm]", ax, 60, 0., 6.);
+  fH.CreateH1("hMvdCutQa", {"1", "2"}, fH.fSrcNames, "MVD hit assignment", ax, 2, 0.,
+              2.);  // [0.5]-correct, [1.5]-wrong
+  fH.CreateH1("hMvdMcDist", {"1", "2"}, fH.fSrcNames, "Track-Hit distance [cm]", ax, 100, 0., 10.);
+
+  fH.CreateH1("hMinv", fH.fSrcNames, fH.fAnaStepNames, "M_{ee} [GeV/c^{2}]", ax, 2000, 0., 2.);
+  fH.CreateH1("hMinvCombPM", {"sameEv", "mixedEv"}, fH.fAnaStepNames, "M_{e+e-} [GeV/c^{2}]", ax, 2000, 0., 2.);
+  fH.CreateH1("hMinvCombPP", {"sameEv", "mixedEv"}, fH.fAnaStepNames, "M_{e+e+} [GeV/c^{2}]", ax, 2000, 0., 2.);
+  fH.CreateH1("hMinvCombMM", {"sameEv", "mixedEv"}, fH.fAnaStepNames, "M_{e-e-} [GeV/c^{2}]", ax, 2000, 0., 2.);
+  fH.CreateH1("hMinvBgMatch", {"trueMatch", "trueMatchEl", "trueMatchNotEl", "mismatch"}, fH.fAnaStepNames,
+              "M_{ee} [GeV/c^{2}]", ax, 2000, 0., 2.);
+  fH.CreateH1("hMinvBgSource", fH.fBgPairSrcNames, fH.fAnaStepNames, "M_{ee} [GeV/c^{2}]", ax, 2000, 0., 2.);
+
+  fH.CreateH2("hMinvPt", fH.fSrcNames, fH.fAnaStepNames, "M_{ee} [GeV/c^{2}]", "P_{t} [GeV/c]", ax, 100, 0., 2., 20, 0.,
+              2.);
+
+  fH.CreateH1("hMomPairSignal", fH.fAnaStepNames, "P [GeV/c]", ax, 100, 0., 15.);
+  fH.CreateH2("hPtYPairSignal", fH.fAnaStepNames, "Rapidity", "P_{t} [GeV/c]", ax, 40, 0., 4., 20, 0., 2.);
+  fH.CreateH1("hAnglePair", fH.fSrcNames, fH.fAnaStepNames, "#Theta_{1,2} [deg]", ax, 160, 0., 80.);
+
+  for (const string& suff : {"", "+", "-"}) {
+    fH.CreateH1("hMom" + suff, fH.fSrcNames, fH.fAnaStepNames, "P [GeV/c]", ax, 100, 0., 10.);
+    fH.CreateH1("hMomPx" + suff, fH.fSrcNames, fH.fAnaStepNames, "Px [GeV/c]", ax, 100, -3., 3.);
+    fH.CreateH1("hMomPy" + suff, fH.fSrcNames, fH.fAnaStepNames, "Py [GeV/c]", ax, 100, -3., 3.);
+    fH.CreateH1("hMomPz" + suff, fH.fSrcNames, fH.fAnaStepNames, "Pz [GeV/c]", ax, 120, -1., 11.);
+    fH.CreateH1("hPt" + suff, fH.fSrcNames, fH.fAnaStepNames, "P_{t} [GeV/c]", ax, 100, 0., 4.);
+    fH.CreateH1("hRapidity" + suff, fH.fSrcNames, fH.fAnaStepNames, "Rapidity", ax, 100, 0., 5.);
   }
 
-  for (Int_t i = 0; i < CbmLmvmHist::fNofSourceTypes; i++) {
-    for (Int_t step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-      string hname = "", htitle = "";
-      hname  = "fh_opening_angle_" + CbmLmvmHist::fAnaSteps[step] + "_" + CbmLmvmHist::fSourceTypes[i];
-      htitle = hname + ";#Theta_{1,2} [deg];Yield";
-      fh_opening_angle[i][step] = new TH1D(hname.c_str(), htitle.c_str(), 160, 0., 80.);
-      fHistoList.push_back(fh_opening_angle[i][step]);
-
-      hname                  = "fh_source_mom_" + CbmLmvmHist::fAnaSteps[step] + "_" + CbmLmvmHist::fSourceTypes[i];
-      htitle                 = hname + ";P [GeV/c];Yield";
-      fh_source_mom[i][step] = new TH1D(hname.c_str(), htitle.c_str(), 300, 0., 15.);
-      fHistoList.push_back(fh_source_mom[i][step]);
-
-      hname                 = "fh_source_pt_" + CbmLmvmHist::fAnaSteps[step] + "_" + CbmLmvmHist::fSourceTypes[i];
-      htitle                = hname + ";P_{t} [GeV/c];Yield";
-      fh_source_pt[i][step] = new TH1D(hname.c_str(), htitle.c_str(), 100, 0., 5.);
-      fHistoList.push_back(fh_source_pt[i][step]);
-    }
-  }
+  fH.CreateH1("hMomAcc+", {"sts", "rich", "trd", "tof"}, fH.fSrcNames, "P [GeV/c]", ax, 100, 0., 10.);
+  fH.CreateH1("hMomAcc-", {"sts", "rich", "trd", "tof"}, fH.fSrcNames, "P [GeV/c]", ax, 100, 0., 10.);
 
-  //pions vs momentum
-  fh_pi_mom_mc = new TH1D("fh_pi_mom_mc", "fh_pi_mom_mc;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_pi_mom_mc);
-  fh_pi_mom_acc = new TH1D("fh_pi_mom_acc", "fh_pi_mom_acc;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_pi_mom_acc);
-  fh_pi_mom_rec = new TH1D("fh_pi_mom_rec", "fh_pi_mom_rec;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_pi_mom_rec);
-  fh_pi_mom_rec_only_sts =
-    new TH1D("fh_pi_mom_rec_only_sts", "fh_pi_mom_rec_only_sts;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_pi_mom_rec_only_sts);
-  fh_pi_mom_rec_sts_rich_trd =
-    new TH1D("fh_pi_mom_rec_sts_rich_trd", "fh_pi_mom_rec_sts_rich_trd;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_pi_mom_rec_sts_rich_trd);
-  fh_pi_mom_rec_sts_rich_trd_tof =
-    new TH1D("fh_pi_mom_rec_sts_rich_trd_tof", "fh_pi_mom_rec_sts_rich_trd_tof;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_pi_mom_rec_sts_rich_trd_tof);
-  fh_pi_rapidity_mc = new TH1D("fh_pi_rapidity_mc", "fh_pi_rapidity_mc;Rapidity;dN/dY", 400, 0., 4.);
-  fHistoList.push_back(fh_pi_rapidity_mc);
-
-
-  //pions vs momentum for primary pions
-  fh_piprim_mom_mc = new TH1D("fh_piprim_mom_mc", "fh_piprim_mom_mc;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_piprim_mom_mc);
-  fh_piprim_mom_acc = new TH1D("fh_piprim_mom_acc", "fh_piprim_mom_acc;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_piprim_mom_acc);
-  fh_piprim_mom_rec = new TH1D("fh_piprim_mom_rec", "fh_piprim_mom_rec;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_piprim_mom_rec);
-  fh_piprim_mom_rec_only_sts =
-    new TH1D("fh_piprim_mom_rec_only_sts", "fh_piprim_mom_rec_only_sts;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_piprim_mom_rec_only_sts);
-  fh_piprim_mom_rec_sts_rich_trd =
-    new TH1D("fh_piprim_mom_rec_sts_rich_trd", "fh_piprim_mom_rec_sts_rich_trd;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_piprim_mom_rec_sts_rich_trd);
-  fh_piprim_mom_rec_sts_rich_trd_tof = new TH1D(
-    "fh_piprim_mom_rec_sts_rich_trd_tof", "fh_piprim_mom_rec_sts_rich_trd_tof;p [GeV/c];dN/dP [1/GeV/c]", 30, 0., 3.);
-  fHistoList.push_back(fh_piprim_mom_rec_sts_rich_trd_tof);
-
-  fh_piprim_plus_rapidity_mc =
-    new TH1D("fh_piprim_plus_rapidity_mc", "fh_piprim_plus_rapidity_mc;Rapidity;dN/dY", 400, 0., 4.);
-  fHistoList.push_back(fh_piprim_plus_rapidity_mc);
-  fh_piprim_minus_rapidity_mc =
-    new TH1D("fh_piprim_minus_rapidity_mc", "fh_piprim_minus_rapidity_mc;Rapidity;dN/dY", 400, 0., 4.);
-  fHistoList.push_back(fh_piprim_minus_rapidity_mc);
-  fh_pi0prim_rapidity_mc = new TH1D("fh_pi0prim_rapidity_mc", "fh_pi0prim_rapidity_mc;Rapidity;dN/dY", 400, 0., 4.);
-  fHistoList.push_back(fh_pi0prim_rapidity_mc);
-  fh_etaprim_rapidity_mc = new TH1D("fh_etaprim_rapidity_mc", "fh_etaprim_rapidity_mc;Rapidity;dN/dY", 400, 0., 4.);
-  fHistoList.push_back(fh_etaprim_rapidity_mc);
-
-
-  fh_nof_rec_pairs_gamma =
-    new TH1D("fh_nof_rec_pairs_gamma", "fh_nof_rec_pairs_gamma;Pair category; Number per event", 3, -0.5, 2.5);
-  fHistoList.push_back(fh_nof_rec_pairs_gamma);
-  fh_nof_rec_pairs_pi0 =
-    new TH1D("fh_nof_rec_pairs_pi0", "fh_nof_rec_pairs_pi0;Pair category; Number per event", 3, -0.5, 2.5);
-  fHistoList.push_back(fh_nof_rec_pairs_pi0);
-
-  fh_nof_rec_gamma = new TH1D("fh_nof_rec_gamma", "fh_nof_rec_gamma;Track category; Number per event", 3, -0.5, 2.5);
-  fHistoList.push_back(fh_nof_rec_gamma);
-  fh_nof_rec_pi0 = new TH1D("fh_nof_rec_pi0", "fh_nof_rec_pi0;Track category; Number per event", 3, -0.5, 2.5);
-  fHistoList.push_back(fh_nof_rec_pi0);
-
-  //Occurency vs Likelihood and Momentum
-  fh_mom_likelihood_El = new TH2D(
-    "fh_mom_likelihood_El", "fh_mom_likelihood_El;p [GeV/c]; likelihood electron; counter", 100, 0., 6., 100, 0., 1.);
-  fh_mom_likelihood_Pi = new TH2D("fh_mom_likelihood_Pi", "fh_mom_likelihood_Pi;p [GeV/c]; likelihood pion; counter",
-                                  100, 0., 6., 100, 0., 1.);
-
-  fHistoList.push_back(fh_mom_likelihood_El);
-  fHistoList.push_back(fh_mom_likelihood_Pi);
-
-  // Acceptance of single particles vs. momentum for various detector combinations
-  fh_nof_particles_acc.resize(20);
-  fh_nof_particles_acc[0] = new TH1D("fh_nof_particles_acc_pEl_mc", "fh_nof_particles_acc_pEl_mc", 100., 0., 10.);
-  fh_nof_particles_acc[1] = new TH1D("fh_nof_particles_acc_pPos_mc", "fh_nof_particles_acc_pPos_mc", 100., 0., 10.);
-  fh_nof_particles_acc[2] = new TH1D("fh_nof_particles_acc_pEl_sts", "fh_nof_particles_acc_pEl_sts", 100., 0., 10.);
-  fh_nof_particles_acc[3] = new TH1D("fh_nof_particles_acc_pPos_sts", "fh_nof_particles_acc_pPos_sts", 100., 0., 10.);
-  fh_nof_particles_acc[4] = new TH1D("fh_nof_particles_acc_pEl_rich", "fh_nof_particles_acc_pEl_rich", 100., 0., 10.);
-  fh_nof_particles_acc[5] = new TH1D("fh_nof_particles_acc_pPos_rich", "fh_nof_particles_acc_pPos_rich", 100., 0., 10.);
-  fh_nof_particles_acc[6] = new TH1D("fh_nof_particles_acc_pEl_trd", "fh_nof_particles_acc_pEl_trd", 100., 0., 10.);
-  fh_nof_particles_acc[7] = new TH1D("fh_nof_particles_acc_pPos_trd", "fh_nof_particles_acc_pPos_trd", 100., 0., 10.);
-  fh_nof_particles_acc[8] = new TH1D("fh_nof_particles_acc_pEl_tof", "fh_nof_particles_acc_pEl_tof", 100., 0., 10.);
-  fh_nof_particles_acc[9] = new TH1D("fh_nof_particles_acc_pPos_tof", "fh_nof_particles_acc_pPos_tof", 100., 0., 10.);
-  fh_nof_particles_acc[10] = new TH1D("fh_nof_particles_acc_uEl_mc", "fh_nof_particles_acc_uEl_mc", 100., 0., 10.);
-  fh_nof_particles_acc[11] = new TH1D("fh_nof_particles_acc_uPos_mc", "fh_nof_particles_acc_uPos_mc", 100., 0., 10.);
-  fh_nof_particles_acc[12] = new TH1D("fh_nof_particles_acc_uEl_sts", "fh_nof_particles_acc_uEl_sts", 100., 0., 10.);
-  fh_nof_particles_acc[13] = new TH1D("fh_nof_particles_acc_uPos_sts", "fh_nof_particles_acc_uPos_sts", 100., 0., 10.);
-  fh_nof_particles_acc[14] = new TH1D("fh_nof_particles_acc_uEl_rich", "fh_nof_particles_acc_uEl_rich", 100., 0., 10.);
-  fh_nof_particles_acc[15] =
-    new TH1D("fh_nof_particles_acc_uPos_rich", "fh_nof_particles_acc_uPos_rich", 100., 0., 10.);
-  fh_nof_particles_acc[16] = new TH1D("fh_nof_particles_acc_uEl_trd", "fh_nof_particles_acc_uEl_trd", 100., 0., 10.);
-  fh_nof_particles_acc[17] = new TH1D("fh_nof_particles_acc_uPos_trd", "fh_nof_particles_acc_uPos_trd", 100., 0., 10.);
-  fh_nof_particles_acc[18] = new TH1D("fh_nof_particles_acc_uEl_tof", "fh_nof_particles_acc_uEl_tof", 100., 0., 10.);
-  fh_nof_particles_acc[19] = new TH1D("fh_nof_particles_acc_uPos_tof", "fh_nof_particles_acc_uPos_tof", 100., 0., 10.);
-
-  int nHist = fh_nof_particles_acc.size();
-  for (Int_t i = 0; i < nHist; i++) {
-    fh_nof_particles_acc[i]->GetXaxis()->SetTitle("P [GeV/c]");
-    fh_nof_particles_acc[i]->GetYaxis()->SetTitle("Yield");
-    fHistoList.push_back(fh_nof_particles_acc[i]);
-  }
-
-  // Number of points the electrons and positrons left in various detectors
-  fh_nof_points.resize(16);
-  fh_nof_points[0]  = new TH1D("fh_nof_points_pEl_sts", "fh_nof_points_pEl_sts", 50., 0., 50.);
-  fh_nof_points[1]  = new TH1D("fh_nof_points_pPos_sts", "fh_nof_points_pPos_sts", 50., 0., 50.);
-  fh_nof_points[2]  = new TH1D("fh_nof_points_pEl_rich", "fh_nof_points_pEl_rich", 50., 0., 50.);
-  fh_nof_points[3]  = new TH1D("fh_nof_points_pPos_rich", "fh_nof_points_pPos_rich", 50., 0., 50.);
-  fh_nof_points[4]  = new TH1D("fh_nof_points_pEl_trd", "fh_nof_points_pEl_trd", 50., 0., 50.);
-  fh_nof_points[5]  = new TH1D("fh_nof_points_pPos_trd", "fh_nof_points_pPos_trd", 50., 0., 50.);
-  fh_nof_points[6]  = new TH1D("fh_nof_points_pEl_tof", "fh_nof_points_pEl_tof", 50., 0., 50.);
-  fh_nof_points[7]  = new TH1D("fh_nof_points_pPos_tof", "fh_nof_points_pPos_tof", 50., 0., 50.);
-  fh_nof_points[8]  = new TH1D("fh_nof_points_uEl_sts", "fh_nof_points_uEl_sts", 50., 0., 50.);
-  fh_nof_points[9]  = new TH1D("fh_nof_points_uPos_sts", "fh_nof_points_uPos_sts", 50., 0., 50.);
-  fh_nof_points[10] = new TH1D("fh_nof_points_uEl_rich", "fh_nof_points_uEl_rich", 50., 0., 50.);
-  fh_nof_points[11] = new TH1D("fh_nof_points_uPos_rich", "fh_nof_points_uPos_rich", 50., 0., 50.);
-  fh_nof_points[12] = new TH1D("fh_nof_points_uEl_trd", "fh_nof_points_uEl_trd", 50., 0., 50.);
-  fh_nof_points[13] = new TH1D("fh_nof_points_uPos_trd", "fh_nof_points_uPos_trd", 50., 0., 50.);
-  fh_nof_points[14] = new TH1D("fh_nof_points_uEl_tof", "fh_nof_points_uEl_tof", 50., 0., 50.);
-  fh_nof_points[15] = new TH1D("fh_nof_points_uPos_tof", "fh_nof_points_uPos_tof", 50., 0., 50.);
-
-  int nHistPoints = fh_nof_points.size();
-  for (Int_t i = 0; i < nHistPoints; i++) {
-    fh_nof_points[i]->GetXaxis()->SetTitle("nofPoints");
-    fh_nof_points[i]->GetYaxis()->SetTitle("Entries");
-    fHistoList.push_back(fh_nof_points[i]);
-  }
+  fH.CreateH1("hPiMom", {"all", "prim"}, {"mc", "acc", "rec", "recOnlySts", "recStsRichTrd", "recStsRichTrdTof"},
+              "P [GeV/c]", ax, 30, 0., 3.);
 }
 
-InitStatus CbmAnaDielectronTask::Init()
+InitStatus LmvmTask::Init()
 {
-  cout << "InitStatus CbmAnaDielectronTask::Init" << endl;
-
-  FairRootManager* ioman = FairRootManager::Instance();
-  if (NULL == ioman) { Fatal("CbmAnaDielectronTask::Init", "No FairRootManager!"); }
-
-  fMCEventHeader = (FairMCEventHeader*) ioman->GetObject("MCEventHeader.");
-  if (NULL == fMCEventHeader) { Fatal("CbmAnaDielectronTask::Init", "No MCEventHeader array!"); }
-
-  fMCTracks = (TClonesArray*) ioman->GetObject("MCTrack");
-  if (NULL == fMCTracks) { Fatal("CbmAnaDielectronTask::Init", "No MCTrack array!"); }
-
-  if (fUseRich == true) {
-    fRichHits = (TClonesArray*) ioman->GetObject("RichHit");
-    if (NULL == fRichHits) { Fatal("CbmAnaDielectronTask::Init", "No RichHit array!"); }
-
-    fRichRings = (TClonesArray*) ioman->GetObject("RichRing");
-    if (NULL == fRichRings) { Fatal("CbmAnaDielectronTask::Init", "No RichRing array!"); }
-
-    fRichPoints = (TClonesArray*) ioman->GetObject("RichPoint");
-    if (NULL == fRichPoints) { Fatal("CbmAnaDielectronTask::Init", "No RichPoint array!"); }
-
-    fRichRingMatches = (TClonesArray*) ioman->GetObject("RichRingMatch");
-    if (NULL == fRichRingMatches) { Fatal("CbmAnaDielectronTask::Init", "No RichRingMatch array!"); }
-
-    fRichProj = (TClonesArray*) ioman->GetObject("RichProjection");
-    if (NULL == fRichProj) { Fatal("CbmAnaDielectronTask::Init", "No RichProjection array!"); }
-  }  //fUseRich
-
-  fStsTrackMatches = (TClonesArray*) ioman->GetObject("StsTrackMatch");
-  if (NULL == fStsTrackMatches) { Fatal("CbmAnaDielectronTask::Init", "No StsTrackMatch array!"); }
-
-  fStsTracks = (TClonesArray*) ioman->GetObject("StsTrack");
-  if (NULL == fStsTracks) { Fatal("CbmAnaDielectronTask::Init", "No StsTrack array!"); }
-
-  fStsHits = (TClonesArray*) ioman->GetObject("StsHit");
-  if (NULL == fStsHits) { Fatal("CbmAnaDielectronTask::Init", "No StsHit array!"); }
-
+  fMCEventHeader   = InitOrFatal<FairMCEventHeader>("MCEventHeader.");
+  fMCTracks        = InitOrFatal<TClonesArray>("MCTrack");
+  fRichHits        = InitOrFatal<TClonesArray>("RichHit");
+  fRichRings       = InitOrFatal<TClonesArray>("RichRing");
+  fRichPoints      = InitOrFatal<TClonesArray>("RichPoint");
+  fRichRingMatches = InitOrFatal<TClonesArray>("RichRingMatch");
+  fRichProj        = InitOrFatal<TClonesArray>("RichProjection");
+  fStsTrackMatches = InitOrFatal<TClonesArray>("StsTrackMatch");
+  fStsTracks       = InitOrFatal<TClonesArray>("StsTrack");
+  fStsHits         = InitOrFatal<TClonesArray>("StsHit");
   if (fUseMvd) {
-    fMvdHits = (TClonesArray*) ioman->GetObject("MvdHit");
-    if (NULL == fMvdHits) { Fatal("CbmAnaDielectronTask::Init", "No MvdHit array!"); }
-
-    fMvdPoints = (TClonesArray*) ioman->GetObject("MvdPoint");
-    if (NULL == fMvdPoints) { Fatal("CbmAnaDielectronTask::Init", ": No MvdPoint array!"); }
-
-    fMvdHitMatches = (TClonesArray*) ioman->GetObject("MvdHitMatch");
-    if (NULL == fMvdHitMatches) { Fatal("CbmAnaDielectronTask::Init", ": No MvdHitMatch array!"); }
+    fMvdHits       = InitOrFatal<TClonesArray>("MvdHit");
+    fMvdPoints     = InitOrFatal<TClonesArray>("MvdPoint");
+    fMvdHitMatches = InitOrFatal<TClonesArray>("MvdHitMatch");
   }
-
-  fGlobalTracks = (TClonesArray*) ioman->GetObject("GlobalTrack");
-  if (NULL == fGlobalTracks) { Fatal("CbmAnaDielectronTask::Init", "No GlobalTrack array!"); }
-
-  if (fUseTrd == true) {
-    fTrdTracks = (TClonesArray*) ioman->GetObject("TrdTrack");
-    if (NULL == fTrdTracks) { Fatal("CbmAnaDielectronTask::Init", "No TrdTrack array!"); }
-
-    fTrdTrackMatches = (TClonesArray*) ioman->GetObject("TrdTrackMatch");
-    if (NULL == fTrdTrackMatches) { Fatal("CbmAnaDielectronTask::Init", "No TrdTrackMatch array!"); }
-  }  //fUseTrd
-
-  if (fUseTof == true) {
-    fTofPoints = (TClonesArray*) ioman->GetObject("TofPoint");
-    if (NULL == fTofPoints) { Fatal("CbmAnaDielectronTask::Init", "No TofPoint array!"); }
-
-    fTofHits = (TClonesArray*) ioman->GetObject("TofHit");
-    if (NULL == fTofHits) { Fatal("CbmAnaDielectronTask::Init", "No TofHit array!"); }
-
-    fTofHitsMatches = (TClonesArray*) ioman->GetObject("TofHitMatch");
-    if (NULL == fTofHitsMatches) { Fatal("CbmAnaDielectronTask::Init", "No TofHitMatch Array! "); }
-  }  //fUseTof
-
-
-  // Get pointer to PrimaryVertex object from IOManager if it exists
-  // The old name for the object is "PrimaryVertex" the new one
-  // "PrimaryVertex." Check first for the new name
-  fPrimVertex = dynamic_cast<CbmVertex*>(ioman->GetObject("PrimaryVertex."));
-  if (nullptr == fPrimVertex) { fPrimVertex = dynamic_cast<CbmVertex*>(ioman->GetObject("PrimaryVertex")); }
-  if (nullptr == fPrimVertex) { LOG(fatal) << "No PrimaryVertex array!"; }
+  fGlobalTracks    = InitOrFatal<TClonesArray>("GlobalTrack");
+  fTrdTracks       = InitOrFatal<TClonesArray>("TrdTrack");
+  fTrdTrackMatches = InitOrFatal<TClonesArray>("TrdTrackMatch");
+  fTofPoints       = InitOrFatal<TClonesArray>("TofPoint");
+  fTofHits         = InitOrFatal<TClonesArray>("TofHit");
+  fTofHitsMatches  = InitOrFatal<TClonesArray>("TofHitMatch");
+  fPrimVertex      = InitOrFatal<CbmVertex>("PrimaryVertex.");
 
   InitHists();
 
   fKFFitter.Init();
-
   CbmLitMCTrackCreator::Instance();
-
-  // if TRD detector us not used the momentum cut at 5.5GeV/c are used
-  if (!fUseTrd) { fCuts.fMomentumCut = 5.5; }
-
-  // CbmLitMCTrackCreator::Instance()->CreateMC();
+  CbmLitGlobalElectronId::GetInstance();
 
   return kSUCCESS;
 }
 
-void CbmAnaDielectronTask::Exec(Option_t*)
+void LmvmTask::Exec(Option_t*)
 {
-  fh_event_number->Fill(0.5);
-
-  fEventNumber = fh_event_number->GetEntries();
-
-  Bool_t useMbias = false;  // false for 40% central agag collisions (b<7.7fm)
-
-  Bool_t isCentralCollision = false;
-
-  if (!useMbias) {
-    Double_t impactPar = fMCEventHeader->GetB();
-    if (impactPar <= 7.7) isCentralCollision = true;
-  }
-
-  cout << "-I- CbmAnaDielectronTask,  event number " << fEventNumber << endl;
-  cout << "fPionMisidLevel = " << fPionMisidLevel << endl;
-  fCuts.Print();
-  cout << "fWeight = " << fWeight << endl;
-
-  if (fPrimVertex != NULL) { fKFVertex = CbmKFVertex(*fPrimVertex); }
+  fH.FillH1("hEventNumber", 0.5);
+  fEventNumber++;
+  // bool useMbias = false;  // false for 40% central agag collisions (b<7.7fm)
+  // bool isCentralCollision = false;
+
+  // if (!useMbias) {
+  //   double impactPar = fMCEventHeader->GetB();
+  //   if (impactPar <= 7.7) isCentralCollision = true;
+  // }
+
+  LOG(info) << "LmvmTask  event number " << fEventNumber;
+  LOG(info) << "fPionMisidLevel = " << fPionMisidLevel;
+  LOG(info) << fCuts.ToString();
+  LOG(info) << "fW = " << fW;
+
+  if (fPrimVertex != nullptr) { fKFVertex = CbmKFVertex(*fPrimVertex); }
   else {
-    Fatal("CbmAnaDielectronTask::Exec", "No PrimaryVertex array!");
-  }
-  // CbmLitMCTrackCreator::Instance()->CreateReco();
-
-  if (useMbias || (!useMbias && isCentralCollision)) {
-    FillRichRingNofHits();
-    MCPairs();
-    RichPmtXY();
-    SingleParticleAcceptance();
-    PairMcAndAcceptance();
-    FillTopologyCandidates();
-    FillCandidates();
-    CalculateNofTopologyPairs(fh_nof_topology_pairs_gamma, "gamma");
-    CalculateNofTopologyPairs(fh_nof_topology_pairs_pi0, "pi0");
-    DifferenceSignalAndBg();
-    SignalAndBgReco();
-    FillElPiMomHist();
-    FillNofChargedParticles();
-    FillMomLikeHist();
+    Fatal("LmvmTask::Exec", "No PrimaryVertex array!");
   }
-}  // Exec
-
-void CbmAnaDielectronTask::FillMomLikeHist()
-{
-  Int_t ngTracks = fGlobalTracks->GetEntriesFast();
-
-  for (int i = 0; i < ngTracks; i++) {
-
-    CbmGlobalTrack* gTrack = (CbmGlobalTrack*) fGlobalTracks->At(i);
-    if (NULL == gTrack) continue;
-
-    // getting TRD index and likelihood value
-    int trdInd = gTrack->GetTrdTrackIndex();
-    if (trdInd < 0) continue;
-    CbmTrdTrack* trdTrack = (CbmTrdTrack*) fTrdTracks->At(trdInd);
-    if (NULL == trdTrack) continue;
-    double_t likelihoodEl = trdTrack->GetPidLikeEL();
-    double_t likelihoodPi = trdTrack->GetPidLikePI();
-
-    // getting momentum via matching STS track with corresponding MC track
-    int stsInd = gTrack->GetStsTrackIndex();
-    if (stsInd < 0) continue;
-    CbmStsTrack* stsTrack = (CbmStsTrack*) fStsTracks->At(stsInd);
-    if (stsTrack == NULL) continue;
-    CbmTrackMatchNew* stsMatch = (CbmTrackMatchNew*) fStsTrackMatches->At(stsInd);
-    if (stsMatch == NULL) continue;
-    if (stsMatch->GetNofLinks() == 0) continue;  // what is this for?
-    int stsMcTrackId = stsMatch->GetMatchedLink().GetIndex();
-    if (stsMcTrackId < 0) continue;
-    CbmMCTrack* mcTrack1 = (CbmMCTrack*) fMCTracks->At(stsMcTrackId);
-    if (mcTrack1 == NULL) continue;
-    double momentum = mcTrack1->GetP();  // momentum of MC track
 
-    fh_mom_likelihood_El->Fill(momentum, likelihoodEl);
-    fh_mom_likelihood_Pi->Fill(momentum, likelihoodPi);
-  }
-}
+  //if (useMbias || (!useMbias && isCentralCollision)) {
+  FillRichRingNofHits();
+  DoMcTrack();
+  DoMcPair();
+  RichPmtXY();
+  FillTopologyCands();
+  FillCands();
+  CalculateNofTopologyPairs("hNofTopoPairs_gamma", ELmvmSrc::Gamma);
+  CalculateNofTopologyPairs("hNofTopoPairs_pi0", ELmvmSrc::Pi0);
+  DifferenceSignalAndBg();
+  SignalAndBgReco();
+  FillPionsHist();
+
+  fCandsTotal.insert(fCandsTotal.end(), fCands.begin(), fCands.end());
+  LOG(info) << "fCandsTotal.size = " << fCandsTotal.size();
+
+  //}
+}  // Exec
 
-void CbmAnaDielectronTask::FillRichRingNofHits()
+//TODO: Move this functionality to RichUtil class
+void LmvmTask::FillRichRingNofHits()
 {
   fNofHitsInRingMap.clear();
-  Int_t nofRichHits = fRichHits->GetEntriesFast();
-  for (Int_t iHit = 0; iHit < nofRichHits; iHit++) {
+  int nofRichHits = fRichHits->GetEntriesFast();
+  for (int iHit = 0; iHit < nofRichHits; iHit++) {
     CbmRichHit* hit = static_cast<CbmRichHit*>(fRichHits->At(iHit));
-    if (NULL == hit) continue;
-
-    Int_t iPoint = hit->GetRefId();
-    if (iPoint < 0) continue;
-
-    FairMCPoint* point = static_cast<FairMCPoint*>(fRichPoints->At(iPoint));
-    if (NULL == point) continue;
-
-    Int_t iMCTrack    = point->GetTrackID();
-    CbmMCTrack* track = static_cast<CbmMCTrack*>(fMCTracks->At(iMCTrack));
-    if (NULL == track) continue;
-
-    Int_t iMother = track->GetMotherId();
-    if (iMother == -1) continue;
-
-    fNofHitsInRingMap[iMother]++;
+    if (hit == nullptr || hit->GetRefId() < 0) continue;
+    FairMCPoint* point = static_cast<FairMCPoint*>(fRichPoints->At(hit->GetRefId()));
+    if (point == nullptr) continue;
+    CbmMCTrack* track = static_cast<CbmMCTrack*>(fMCTracks->At(point->GetTrackID()));
+    if (track == nullptr || track->GetMotherId() < 0) continue;
+    fNofHitsInRingMap[track->GetMotherId()]++;
   }
 }
 
 
-void CbmAnaDielectronTask::MCPairs()
+void LmvmTask::FillMomHists(const CbmMCTrack* mct, const LmvmCand* cand, ELmvmSrc src, ELmvmAnaStep step)
 {
-  Int_t nMcTracks = fMCTracks->GetEntries();
-  for (Int_t i = 0; i < nMcTracks; i++) {
-    CbmMCTrack* mctrack = (CbmMCTrack*) fMCTracks->At(i);
-    Int_t motherId      = mctrack->GetMotherId();
-    Int_t pdg           = TMath::Abs(mctrack->GetPdgCode());
-    Double_t mom        = mctrack->GetP();
-
-    Bool_t isMcSignalElectron = CbmLmvmUtils::IsMcSignalElectron(mctrack);
-    Bool_t isMcGammaElectron  = CbmLmvmUtils::IsMcGammaElectron(mctrack, fMCTracks);
-    if (isMcSignalElectron) {
-      fh_source_mom[kSignal][kMc]->Fill(mom, fWeight);
-      for (Int_t iMc2 = 0; iMc2 < nMcTracks; iMc2++) {
-        if (i == iMc2) continue;
-        CbmMCTrack* mctrack2 = (CbmMCTrack*) fMCTracks->At(iMc2);
-        Int_t motherIdMc2    = mctrack2->GetMotherId();
-        if (motherId == motherIdMc2 && CbmLmvmUtils::IsMcSignalElectron(mctrack2)) {
-          CbmLmvmKinematicParams pKin = CbmLmvmKinematicParams::KinematicParamsWithMcTracks(mctrack, mctrack2);
-          Double_t angle              = pKin.fAngle;
-          Double_t pMc                = mctrack->GetP();
-          Double_t pMc2               = mctrack2->GetP();
-          Double_t sqrtPMc            = TMath::Sqrt(pMc * pMc2);
-          fh_mc_signal_mom_angle->Fill(sqrtPMc, angle);
-        }
-      }
-    }
-    if (isMcGammaElectron) {
-      TVector3 v;
-      mctrack->GetStartVertex(v);
-      fh_vertex_el_gamma_xz[kMc]->Fill(v.Z(), v.X());
-      fh_vertex_el_gamma_yz[kMc]->Fill(v.Z(), v.Y());
-      fh_vertex_el_gamma_xy[kMc]->Fill(v.X(), v.Y());
-      fh_vertex_el_gamma_rz[kMc]->Fill(v.Z(), sqrt(v.X() * v.X() + v.Y() * v.Y()));
-    }
-
-    // mother pdg of e-/e+
-    Int_t mcMotherPdg = 0;
-    if (pdg == 11) {
-      if (motherId != -1) {
-        CbmMCTrack* mother = (CbmMCTrack*) fMCTracks->At(motherId);
-        if (NULL != mother) mcMotherPdg = mother->GetPdgCode();
-      }
-      else {
-        mcMotherPdg = 0;
-      }
-      fh_mc_mother_pdg->Fill(mcMotherPdg);
-    }
-  }  // nMcTracks
-}  //MC Pairs
-
-void CbmAnaDielectronTask::RichPmtXY()
-{
-  Int_t nofRichHits = fRichHits->GetEntriesFast();
-  for (Int_t iH = 0; iH < nofRichHits; iH++) {
-    CbmRichHit* richHit = static_cast<CbmRichHit*>(fRichHits->At(iH));
-    if (richHit == NULL) continue;
-    Int_t pointInd = richHit->GetRefId();
-    if (pointInd < 0) continue;
-
-    FairMCPoint* pointPhoton = static_cast<FairMCPoint*>(fRichPoints->At(pointInd));
-    if (NULL == pointPhoton) continue;
-
-    Int_t iMCTrackPhoton    = pointPhoton->GetTrackID();
-    CbmMCTrack* trackPhoton = static_cast<CbmMCTrack*>(fMCTracks->At(iMCTrackPhoton));
-    if (NULL == trackPhoton) continue;
-
-    Int_t iMCTrack = trackPhoton->GetMotherId();
-    if (iMCTrack == -1) continue;
-
-    CbmMCTrack* mctrack = static_cast<CbmMCTrack*>(fMCTracks->At(iMCTrack));
-    if (NULL == mctrack) continue;
-
-    TVector3 v;
-    mctrack->GetStartVertex(v);
-    Bool_t isPrim = (v.Z() < 2.);
-
-    Bool_t isMcSignalElectron = CbmLmvmUtils::IsMcSignalElectron(mctrack);
-    Bool_t isMcGammaElectron  = CbmLmvmUtils::IsMcGammaElectron(mctrack, fMCTracks);
-    Bool_t isMcPi0Electron    = CbmLmvmUtils::IsMcPi0Electron(mctrack, fMCTracks);
-
-    if (isMcSignalElectron) { fh_signal_pmtXY->Fill(richHit->GetX(), richHit->GetY(), fWeight); }
-    if (isMcGammaElectron && isPrim) { fh_gamma_pmtXY->Fill(richHit->GetX(), richHit->GetY()); }
-    if (isMcPi0Electron && isPrim) { fh_pi0_pmtXY->Fill(richHit->GetX(), richHit->GetY()); }
+  if ((mct != nullptr && cand != nullptr) || (mct == nullptr && cand == nullptr)) {
+    LOG(error) << "LmvmTask::FillMomHists: Both mct and cand are [not nullptr] or [nullptr].";
+    return;
+  }
+  bool isMc        = (mct != nullptr);
+  string chargeStr = (isMc) ? LmvmUtils::GetChargeStr(mct) : LmvmUtils::GetChargeStr(cand);
+
+  for (const string& suff : {string(""), chargeStr}) {
+    if (suff == "0") continue;
+    fH.FillH1("hMom" + suff, src, step, (isMc) ? mct->GetP() : cand->fMomentum.Mag(), fW);
+    fH.FillH1("hMomPx" + suff, src, step, (isMc) ? mct->GetPx() : cand->fMomentum.X(), fW);
+    fH.FillH1("hMomPy" + suff, src, step, (isMc) ? mct->GetPy() : cand->fMomentum.Y(), fW);
+    fH.FillH1("hMomPz" + suff, src, step, (isMc) ? mct->GetPz() : cand->fMomentum.Z(), fW);
+    fH.FillH1("hPt" + suff, src, step, (isMc) ? mct->GetPt() : cand->fMomentum.Perp(), fW);
+    fH.FillH1("hRapidity" + suff, src, step, (isMc) ? mct->GetRapidity() : cand->fRapidity, fW);
   }
 }
 
-void CbmAnaDielectronTask::FillNofChargedParticles()
+void LmvmTask::DoMcTrack()
 {
-  Int_t nofMcTracks                 = fMCTracks->GetEntries();
-  Int_t nCand                       = fCandidates.size();
-  Int_t nofChargedUrqmdParticles    = 0;
-  Int_t nofChargedUrqmdParticlesAcc = 0;
-
-  cout << "FillNofChargedParticles: nofMcTracks = " << nofMcTracks << endl;
-  cout << "FillNofChargedParticles: nCand = " << nCand << endl;
-
-  int nChargeMC   = 0;
-  int nChargeCand = 0;
-
-  for (Int_t i = 0; i < nofMcTracks; i++) {
-    CbmMCTrack* mcTrack = (CbmMCTrack*) fMCTracks->At(i);
-    Int_t motherId      = mcTrack->GetMotherId();
-    Int_t pdg           = TMath::Abs(mcTrack->GetPdgCode());
-    bool isMcElectron   = (pdg == 11) ? true : false;
-    double mom          = mcTrack->GetP();
-    double momT         = mcTrack->GetPt();
-    double charge =
-      mcTrack
-        ->GetCharge();  // FIXME: TODO: uncomment when bug is fixed; issue https://lxcbmredmine01.gsi.de/issues/1826; gives charge = +/- 3!
-    Bool_t isMcTrackCharged   = (charge == 0) ? false : true;
-    Bool_t isMcSignalElectron = CbmLmvmUtils::IsMcSignalElectron(mcTrack);
-    Bool_t isUrqmdElectron    = (!isMcSignalElectron && isMcElectron) ? true : false;
-    Bool_t isMcTrAcc          = IsMcTrackAccepted(i);
-    Bool_t isPrimary = (motherId == -1) ? true : false;
-
-    CbmMCTrack* tr    = (CbmMCTrack*) fMCTracks->At(i);
-    Int_t nRichPoints = fNofHitsInRingMap[i];
-    int nStsPoints    = tr->GetNPoints(ECbmModuleId::kSts);
-    int nTrdPoints    = tr->GetNPoints(ECbmModuleId::kTrd);
-    int nTofPoints    = tr->GetNPoints(ECbmModuleId::kTof);
-
-    bool isStsAcc = (tr->GetNPoints(ECbmModuleId::kMvd) + tr->GetNPoints(ECbmModuleId::kSts) >= 4) ? true : false;
-    bool isRichAcc =
-      (tr->GetNPoints(ECbmModuleId::kMvd) + tr->GetNPoints(ECbmModuleId::kSts) >= 4 && nRichPoints >= 7) ? true : false;
-    bool isTrdAcc = (tr->GetNPoints(ECbmModuleId::kMvd) + tr->GetNPoints(ECbmModuleId::kSts) >= 4 && nRichPoints >= 7
-                     && tr->GetNPoints(ECbmModuleId::kTrd) >= 2)
-                      ? true
-                      : false;
-    bool isTofAcc = (tr->GetNPoints(ECbmModuleId::kMvd) + tr->GetNPoints(ECbmModuleId::kSts) >= 4 && nRichPoints >= 7
-                     && tr->GetNPoints(ECbmModuleId::kTrd) >= 2 && tr->GetNPoints(ECbmModuleId::kTof) > 1)
-                      ? true
-                      : false;  // Mind: kTof was '0' before! changed on 2.7.21; same in IsMcTrackAccepted(int)
-
-    if (charge != 0) {
-      cout << "charge (from GetCharge()) = " << charge << endl;
-      nChargeMC++;
+  int nMcTracks = fMCTracks->GetEntriesFast();
+  for (int i = 0; i < nMcTracks; i++) {
+    CbmMCTrack* mct = static_cast<CbmMCTrack*>(fMCTracks->At(i));
+    if (mct == nullptr) continue;
+    ELmvmSrc src     = LmvmUtils::GetMcSrc(mct, fMCTracks);
+    string chargeStr = (mct->GetCharge() > 0) ? "+" : "-";
+    bool isAcc       = IsMcTrackAccepted(i);
+    double mom       = mct->GetP();
+
+    FillMomHists(mct, nullptr, src, ELmvmAnaStep::Mc);
+    if (isAcc) FillMomHists(mct, nullptr, src, ELmvmAnaStep::Acc);
+
+    if (mct->GetNPoints(ECbmModuleId::kMvd) + mct->GetNPoints(ECbmModuleId::kSts) >= 4)
+      fH.FillH1("hMomAcc" + chargeStr + "_sts", src, mom, fW);
+    if (fNofHitsInRingMap[i] >= 7) fH.FillH1("hMomAcc" + chargeStr + "_rich", src, mom, fW);
+    if (mct->GetNPoints(ECbmModuleId::kTrd) >= 2) fH.FillH1("hMomAcc" + chargeStr + "_trd", src, mom, fW);
+    if (mct->GetNPoints(ECbmModuleId::kTof) >= 1) fH.FillH1("hMomAcc" + chargeStr + "_tof", src, mom, fW);
+
+    if (std::abs(mct->GetPdgCode()) == 11) {
+      int mcMotherPdg = 0;
+      if (mct->GetMotherId() != -1) {
+        CbmMCTrack* mother = static_cast<CbmMCTrack*>(fMCTracks->At(mct->GetMotherId()));
+        if (mother != nullptr) mcMotherPdg = mother->GetPdgCode();
+      }
+      fH.FillH1("hMotherPdg_mc", mcMotherPdg);
+      if (isAcc) fH.FillH1("hMotherPdg_acc", mcMotherPdg);
     }
 
-    if (!isMcSignalElectron && isMcTrackCharged && isPrimary) nofChargedUrqmdParticles++;
-    if (!isMcSignalElectron && isMcTrackCharged && isMcTrAcc && isPrimary) nofChargedUrqmdParticlesAcc++;
-
-    // 1D Histos: Yield vs. Momentum
-    if (isMcSignalElectron && charge < 0)
-      fh_nof_plutoElectrons[kMc]->Fill(mom);  // 'isMcEl' was redundant here and in next lines with cond. 'isMcSignalEl'
-    if (isMcSignalElectron && charge > 0) fh_nof_plutoPositrons[kMc]->Fill(mom);
-    if (isMcSignalElectron && isMcTrAcc && charge < 0) fh_nof_plutoElectrons[kAcc]->Fill(mom);
-    if (isMcSignalElectron && isMcTrAcc && charge > 0) fh_nof_plutoPositrons[kAcc]->Fill(mom);
-    if (isUrqmdElectron && charge < 0) fh_nof_urqmdElectrons[kMc]->Fill(mom);
-    if (isUrqmdElectron && charge > 0) fh_nof_urqmdPositrons[kMc]->Fill(mom);
-    if (isUrqmdElectron && isMcTrAcc && charge < 0) fh_nof_urqmdElectrons[kAcc]->Fill(mom);
-    if (isUrqmdElectron && isMcTrAcc && charge > 0) fh_nof_urqmdPositrons[kAcc]->Fill(mom);
-
-    // 2D Histos: Yield vs. Momentum and Pt
-    if (isMcSignalElectron && charge < 0) fh_nof_plutoElectrons_p_pt[kMc]->Fill(mom, momT);
-    if (isMcSignalElectron && charge > 0) fh_nof_plutoPositrons_p_pt[kMc]->Fill(mom, momT);
-    if (isMcSignalElectron && isMcTrAcc && charge < 0) fh_nof_plutoElectrons_p_pt[kAcc]->Fill(mom, momT);
-    if (isMcSignalElectron && isMcTrAcc && charge > 0) fh_nof_plutoPositrons_p_pt[kAcc]->Fill(mom, momT);
-    if (isUrqmdElectron && charge < 0) fh_nof_urqmdElectrons_p_pt[kMc]->Fill(mom, momT);
-    if (isUrqmdElectron && charge > 0) fh_nof_urqmdPositrons_p_pt[kMc]->Fill(mom, momT);
-    if (isUrqmdElectron && isMcTrAcc && charge < 0) fh_nof_urqmdElectrons_p_pt[kAcc]->Fill(mom, momT);
-    if (isUrqmdElectron && isMcTrAcc && charge > 0) fh_nof_urqmdPositrons_p_pt[kAcc]->Fill(mom, momT);
-
-    // Checking Acceptance of diff. Detectors
-    if (isMcSignalElectron && charge < 0) fh_nof_particles_acc[0]->Fill(mom);              // PLUTO electron
-    if (isMcSignalElectron && charge > 0) fh_nof_particles_acc[1]->Fill(mom);              // PLUTO positron
-    if (isMcSignalElectron && isStsAcc && charge < 0) fh_nof_particles_acc[2]->Fill(mom);  // PLUTO electron
-    if (isMcSignalElectron && isStsAcc && charge > 0) fh_nof_particles_acc[3]->Fill(mom);  // PLUTO positron
-    if (isMcSignalElectron && isStsAcc && isRichAcc && charge < 0)
-      fh_nof_particles_acc[4]->Fill(mom);  // PLUTO electron
-    if (isMcSignalElectron && isStsAcc && isRichAcc && charge > 0)
-      fh_nof_particles_acc[5]->Fill(mom);  // PLUTO positron
-    if (isMcSignalElectron && isStsAcc && isRichAcc && isTrdAcc && charge < 0)
-      fh_nof_particles_acc[6]->Fill(mom);  // PLUTO electron
-    if (isMcSignalElectron && isStsAcc && isRichAcc && isTrdAcc && charge > 0)
-      fh_nof_particles_acc[7]->Fill(mom);  // PLUTO positron
-    if (isMcSignalElectron && isStsAcc && isRichAcc && isTrdAcc && isTofAcc && charge < 0)
-      fh_nof_particles_acc[8]->Fill(mom);  // PLUTO electron
-    if (isMcSignalElectron && isStsAcc && isRichAcc && isTrdAcc && isTofAcc && charge > 0)
-      fh_nof_particles_acc[9]->Fill(mom);                                                             // PLUTO positron
-    if (isUrqmdElectron && charge < 0) fh_nof_particles_acc[10]->Fill(mom);                           // UrQMD electron
-    if (isUrqmdElectron && charge > 0) fh_nof_particles_acc[11]->Fill(mom);                           // UrQMD positron
-    if (isUrqmdElectron && isStsAcc && charge < 0) fh_nof_particles_acc[12]->Fill(mom);               // UrQMD electron
-    if (isUrqmdElectron && isStsAcc && charge > 0) fh_nof_particles_acc[13]->Fill(mom);               // UrQMD positron
-    if (isUrqmdElectron && isStsAcc && isRichAcc && charge < 0) fh_nof_particles_acc[14]->Fill(mom);  // UrQMD electron
-    if (isUrqmdElectron && isStsAcc && isRichAcc && charge > 0) fh_nof_particles_acc[15]->Fill(mom);  // UrQMD positron
-    if (isUrqmdElectron && isStsAcc && isRichAcc && isTrdAcc && charge < 0)
-      fh_nof_particles_acc[16]->Fill(mom);  // UrQMD electron
-    if (isUrqmdElectron && isStsAcc && isRichAcc && isTrdAcc && charge > 0)
-      fh_nof_particles_acc[17]->Fill(mom);  // UrQMD positron
-    if (isUrqmdElectron && isStsAcc && isRichAcc && isTrdAcc && isTofAcc && charge < 0)
-      fh_nof_particles_acc[18]->Fill(mom);  // UrQMD electron
-    if (isUrqmdElectron && isStsAcc && isRichAcc && isTrdAcc && isTofAcc && charge > 0)
-      fh_nof_particles_acc[19]->Fill(mom);  // UrQMD positron
-
-    // Fill histos with number of points
-    if (isMcSignalElectron && charge < 0) {
-      fh_nof_points[0]->Fill(nStsPoints);
-      fh_nof_points[2]->Fill(nRichPoints);
-      fh_nof_points[4]->Fill(nTrdPoints);
-      fh_nof_points[6]->Fill(nTofPoints);
-    }
-    if (isMcSignalElectron && charge > 0) {
-      fh_nof_points[1]->Fill(nStsPoints);
-      fh_nof_points[3]->Fill(nRichPoints);
-      fh_nof_points[5]->Fill(nTrdPoints);
-      fh_nof_points[7]->Fill(nTofPoints);
-    }
-    if (isUrqmdElectron && charge < 0) {
-      fh_nof_points[8]->Fill(nStsPoints);
-      fh_nof_points[10]->Fill(nRichPoints);
-      fh_nof_points[12]->Fill(nTrdPoints);
-      fh_nof_points[14]->Fill(nTofPoints);
-    }
-    if (isUrqmdElectron && charge > 0) {
-      fh_nof_points[9]->Fill(nStsPoints);
-      fh_nof_points[11]->Fill(nRichPoints);
-      fh_nof_points[13]->Fill(nTrdPoints);
-      fh_nof_points[15]->Fill(nTofPoints);
-    }
-  }
-  fh_nof_charged_particles->Fill(nofChargedUrqmdParticles);
-  fh_nof_charged_particles_acc->Fill(nofChargedUrqmdParticlesAcc);
-
-  for (Int_t i = 0; i < nCand; i++) {
-    int charge = fCandidates[i].fCharge;
-    if (charge != 0) {
-      cout << "fCandidates[i].fCharge = " << charge << endl;
-      nChargeCand++;
+    if (LmvmUtils::IsMcGammaEl(mct, fMCTracks)) {
+      TVector3 v;
+      mct->GetStartVertex(v);
+      for (const auto step : {ELmvmAnaStep::Mc, ELmvmAnaStep::Acc}) {
+        if (step == ELmvmAnaStep::Acc && !isAcc) continue;
+        fH.FillH2("hVertexGammaXZ", step, v.Z(), v.X());
+        fH.FillH2("hVertexGammaYZ", step, v.Z(), v.Y());
+        fH.FillH2("hVertexGammaXY", step, v.X(), v.Y());
+        fH.FillH2("hVertexGammaRZ", step, v.Z(), sqrt(v.X() * v.X() + v.Y() * v.Y()));
+      }
     }
-    Bool_t isMcSignalElectron = fCandidates[i].fIsMcSignalElectron;
-    Bool_t isMcElectron =
-      (fCandidates[i].fIsMcPi0Electron || fCandidates[i].fIsMcEtaElectron || fCandidates[i].fIsMcGammaElectron) ? true
-                                                                                                                : false;
-    Bool_t isUrqmdElectron = (!isMcSignalElectron && isMcElectron) ? true : false;
-    Bool_t isChiPrimary    = fCandidates[i].fChi2Prim < fCuts.fChiPrimCut;
-    Bool_t isElectron      = fCandidates[i].fIsElectron;
-    Bool_t isGammaCut      = !fCandidates[i].fIsGamma;
-    //Bool_t isMvd1Cut	= fCandidates[i].fIsMvd1CutElectron;
-    //Bool_t isMvd2Cut	= fCandidates[i].fIsMvd2CutElectron;
-    Bool_t isStCut = fCandidates[i].fIsStCutElectron;
-    Bool_t isRtCut = fCandidates[i].fIsRtCutElectron;
-    Bool_t isTtCut = fCandidates[i].fIsTtCutElectron;
-    Bool_t isPtCut = fCandidates[i].fMomentum.Perp() > fCuts.fPtCut;
-
-    if (isMcSignalElectron && charge < 0) fh_nof_plutoElectrons[kReco]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isMcSignalElectron && charge > 0) fh_nof_plutoPositrons[kReco]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isMcSignalElectron && isChiPrimary && isElectron && charge < 0)
-      fh_nof_plutoElectrons[kElId]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isMcSignalElectron && isChiPrimary && isElectron && charge > 0)
-      fh_nof_plutoPositrons[kElId]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isChiPrimary && isElectron && charge < 0)
-      fh_nof_plutoElectrons[kChi2Prim]->Fill(
-        fCandidates[i]
-          .fMomentum.Mag());  // !!!TODO: is NOT kChi2Prim step but El-ID wo. MC info; to show difference between with
-    if (isChiPrimary && isElectron && charge > 0)
-      fh_nof_plutoPositrons[kChi2Prim]->Fill(
-        fCandidates[i].fMomentum.Mag());  // ... and wo MC info!! Remove afterwards !!
-    if (isMcSignalElectron && isChiPrimary && isElectron && isGammaCut && isStCut && isRtCut && isTtCut && charge < 0)
-      fh_nof_plutoElectrons[kTtCut]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isMcSignalElectron && isChiPrimary && isElectron && isGammaCut && isStCut && isRtCut && isTtCut && charge > 0)
-      fh_nof_plutoPositrons[kTtCut]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isMcSignalElectron && isChiPrimary && isElectron && isGammaCut && isStCut && isRtCut && isTtCut && isPtCut
-        && charge < 0)
-      fh_nof_plutoElectrons[kPtCut]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isMcSignalElectron && isChiPrimary && isElectron && isGammaCut && isStCut && isRtCut && isTtCut && isPtCut
-        && charge > 0)
-      fh_nof_plutoPositrons[kPtCut]->Fill(fCandidates[i].fMomentum.Mag());
-
-    if (isUrqmdElectron && charge < 0) fh_nof_urqmdElectrons[kReco]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isUrqmdElectron && charge > 0) fh_nof_urqmdPositrons[kReco]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isUrqmdElectron && isChiPrimary && isElectron && charge < 0)
-      fh_nof_urqmdElectrons[kElId]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isUrqmdElectron && isChiPrimary && isElectron && charge > 0)
-      fh_nof_urqmdPositrons[kElId]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isChiPrimary && isElectron && charge < 0)
-      fh_nof_urqmdElectrons[kChi2Prim]->Fill(
-        fCandidates[i]
-          .fMomentum.Mag());  // !!!TODO: is NOT kChi2Prim step but El-ID wo. MC info; to show difference between with
-    if (isChiPrimary && isElectron && charge > 0)
-      fh_nof_urqmdPositrons[kChi2Prim]->Fill(
-        fCandidates[i].fMomentum.Mag());  // ... and wo MC info!! Remove afterwards !!
-    if (isUrqmdElectron && isChiPrimary && isElectron && isGammaCut && isStCut && isRtCut && isTtCut && charge < 0)
-      fh_nof_urqmdElectrons[kTtCut]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isUrqmdElectron && isChiPrimary && isElectron && isGammaCut && isStCut && isRtCut && isTtCut && charge > 0)
-      fh_nof_urqmdPositrons[kTtCut]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isUrqmdElectron && isChiPrimary && isElectron && isGammaCut && isStCut && isRtCut && isTtCut && isPtCut
-        && charge < 0)
-      fh_nof_urqmdElectrons[kPtCut]->Fill(fCandidates[i].fMomentum.Mag());
-    if (isUrqmdElectron && isChiPrimary && isElectron && isGammaCut && isStCut && isRtCut && isTtCut && isPtCut
-        && charge > 0)
-      fh_nof_urqmdPositrons[kPtCut]->Fill(fCandidates[i].fMomentum.Mag());
   }
-  cout << "nChargeMC = " << nChargeMC << ", nChargeCand = " << nChargeCand << endl;
 }
 
-Bool_t CbmAnaDielectronTask::IsMcTrackAccepted(Int_t mcTrackInd)
+void LmvmTask::DoMcPair()
 {
-  CbmMCTrack* tr = (CbmMCTrack*) fMCTracks->At(mcTrackInd);
-  if (tr == NULL) return false;
-  Int_t nRichPoints = fNofHitsInRingMap[mcTrackInd];
-  return (tr->GetNPoints(ECbmModuleId::kMvd) + tr->GetNPoints(ECbmModuleId::kSts) >= 4 && nRichPoints >= 7
-          && tr->GetNPoints(ECbmModuleId::kTrd) >= 2 && tr->GetNPoints(ECbmModuleId::kTof) > 1);
-}
-
-void CbmAnaDielectronTask::SingleParticleAcceptance()
-{
-  Int_t nMcTracks = fMCTracks->GetEntries();
-  for (Int_t i = 0; i < nMcTracks; i++) {
-    CbmMCTrack* mctrack = (CbmMCTrack*) fMCTracks->At(i);
-    Int_t motherId      = mctrack->GetMotherId();
-    Int_t pdg           = TMath::Abs(mctrack->GetPdgCode());
-    Int_t nMvdPoints    = mctrack->GetNPoints(ECbmModuleId::kMvd);
-    Int_t nStsPoints    = mctrack->GetNPoints(ECbmModuleId::kSts);
-    Int_t nRichPoints   = fNofHitsInRingMap[i];
-
-    Bool_t isAcc             = (nMvdPoints + nStsPoints >= 4 && nRichPoints >= 7);
-    Bool_t isMcGammaElectron = CbmLmvmUtils::IsMcGammaElectron(mctrack, fMCTracks);
-
-    if (isMcGammaElectron) {
-      TVector3 v;
-      mctrack->GetStartVertex(v);
-      fh_vertex_el_gamma_xz[kAcc]->Fill(v.Z(), v.X());
-      fh_vertex_el_gamma_yz[kAcc]->Fill(v.Z(), v.Y());
-      fh_vertex_el_gamma_xy[kAcc]->Fill(v.X(), v.Y());
-      fh_vertex_el_gamma_rz[kAcc]->Fill(v.Z(), sqrt(v.X() * v.X() + v.Y() * v.Y()));
-    }
-
-    Int_t mcMotherPdg = 0;
-    if (pdg == 11 && isAcc) {
-      if (motherId != -1) {
-        CbmMCTrack* mother = (CbmMCTrack*) fMCTracks->At(motherId);
-        if (NULL != mother) mcMotherPdg = mother->GetPdgCode();
-      }
-      else {
-        mcMotherPdg = 0;
+  int nMcTracks = fMCTracks->GetEntries();
+  for (int iMc1 = 0; iMc1 < nMcTracks; iMc1++) {
+    CbmMCTrack* mct1 = static_cast<CbmMCTrack*>(fMCTracks->At(iMc1));
+    ELmvmSrc src     = LmvmUtils::GetMcSrc(mct1, fMCTracks);
+    // To speed up: select only signal, eta and pi0 electrons
+    if (!(src == ELmvmSrc::Signal || src == ELmvmSrc::Pi0 || src == ELmvmSrc::Eta)) continue;
+
+    bool isAcc1 = IsMcTrackAccepted(iMc1);
+    for (int iMc2 = iMc1 + 1; iMc2 < nMcTracks; iMc2++) {
+      CbmMCTrack* mct2            = static_cast<CbmMCTrack*>(fMCTracks->At(iMc2));
+      bool isAccPair              = isAcc1 && IsMcTrackAccepted(iMc2);
+      ELmvmSrc srcPair            = LmvmUtils::GetMcPairSrc(mct1, mct2, fMCTracks);
+      CbmLmvmKinematicParams pKin = CbmLmvmKinematicParams::Create(mct1, mct2);
+
+      if (srcPair == ELmvmSrc::Signal) {
+        fH.FillH2("hMomVsAnglePairSignalMc", std::sqrt(mct1->GetP() * mct2->GetP()), pKin.fAngle);
+      }
+
+      for (const auto step : {ELmvmAnaStep::Mc, ELmvmAnaStep::Acc}) {
+        if (step == ELmvmAnaStep::Acc && !isAccPair) continue;
+        //fH.FillH1("hAnglePair", srcPair, step, pKin.fAngle, fW);
+        if (srcPair == ELmvmSrc::Signal) {
+          fH.FillH2("hPtYPairSignal", step, pKin.fRapidity, pKin.fPt, fW);
+          fH.FillH1("hMomPairSignal", step, pKin.fMomentumMag, fW);
+        }
+        // MC and Acc minv only for signal, eta and pi0
+        if (srcPair == ELmvmSrc::Signal || srcPair == ELmvmSrc::Pi0 || srcPair == ELmvmSrc::Eta) {
+          fH.FillH1("hMinv", srcPair, step, pKin.fMinv, fW);
+        }
       }
-      fh_acc_mother_pdg->Fill(mcMotherPdg);
     }
   }
 }
 
-void CbmAnaDielectronTask::PairMcAndAcceptance()
+void LmvmTask::RichPmtXY()
 {
-  Int_t nMcTracks = fMCTracks->GetEntries();
-  for (Int_t iP = 0; iP < nMcTracks; iP++) {
-    CbmMCTrack* mctrackP = (CbmMCTrack*) fMCTracks->At(iP);
-    //		Int_t motherIdP = mctrackP->GetMotherId();
-    Int_t pdgP = mctrackP->GetPdgCode();
-    if (pdgP != 11) continue;
-    Bool_t isAccP = IsMcTrackAccepted(iP);
-    for (Int_t iM = 0; iM < nMcTracks; iM++) {
-      if (iP == iM) continue;
-      CbmMCTrack* mctrackM = (CbmMCTrack*) fMCTracks->At(iM);
-      //			Int_t motherIdM = mctrackM->GetMotherId();
-      Int_t pdgM = mctrackM->GetPdgCode();
-      if (pdgM != -11) continue;
-      Bool_t isAccM            = IsMcTrackAccepted(iM);
-      CbmLmvmKinematicParams p = CbmLmvmKinematicParams::KinematicParamsWithMcTracks(mctrackP, mctrackM);
-      Bool_t isMcSignal = CbmLmvmUtils::IsMcSignalElectron(mctrackM) && CbmLmvmUtils::IsMcSignalElectron(mctrackP);
-      Bool_t isMcPi0    = (mctrackM->GetMotherId() == mctrackP->GetMotherId())
-                       && CbmLmvmUtils::IsMcPi0Electron(mctrackM, fMCTracks)
-                       && CbmLmvmUtils::IsMcPi0Electron(mctrackP, fMCTracks);
-      Bool_t isMcEta = (mctrackM->GetMotherId() == mctrackP->GetMotherId())
-                       && CbmLmvmUtils::IsMcEtaElectron(mctrackM, fMCTracks)
-                       && CbmLmvmUtils::IsMcEtaElectron(mctrackP, fMCTracks);
-
-      if (isMcSignal) {
-        fh_signal_pty[kMc]->Fill(p.fRapidity, p.fPt, fWeight);
-        fh_signal_mom[kMc]->Fill(p.fMomentumMag, fWeight);
-        fh_signal_minv[kMc]->Fill(p.fMinv, fWeight);
-
-        if (isAccP && isAccM) {
-          fh_signal_pty[kAcc]->Fill(p.fRapidity, p.fPt, fWeight);
-          fh_signal_mom[kAcc]->Fill(p.fMomentumMag, fWeight);
-          fh_signal_minv[kAcc]->Fill(p.fMinv, fWeight);
-        }
-      }
-
-      if (isMcPi0) {
-        fh_pi0_minv[kMc]->Fill(p.fMinv);
-        if (isAccP && isAccM) fh_pi0_minv[kAcc]->Fill(p.fMinv);
-      }
+  int nofRichHits = fRichHits->GetEntriesFast();
+  for (int iH = 0; iH < nofRichHits; iH++) {
+    CbmRichHit* richHit = static_cast<CbmRichHit*>(fRichHits->At(iH));
+    if (richHit == nullptr || richHit->GetRefId() < 0) continue;
+    FairMCPoint* pointPhoton = static_cast<FairMCPoint*>(fRichPoints->At(richHit->GetRefId()));
+    if (pointPhoton == nullptr) continue;
+    CbmMCTrack* trackPhoton = static_cast<CbmMCTrack*>(fMCTracks->At(pointPhoton->GetTrackID()));
+    if (trackPhoton == nullptr || trackPhoton->GetMotherId() < 0) continue;
+    CbmMCTrack* mct = static_cast<CbmMCTrack*>(fMCTracks->At(trackPhoton->GetMotherId()));
+    if (mct == nullptr) continue;
 
-      if (isMcEta) {
-        fh_eta_minv[kMc]->Fill(p.fMinv);
-        if (isAccP && isAccM) fh_eta_minv[kAcc]->Fill(p.fMinv);
-      }
-    }  //iM
-  }    //iP
-}  // PairsAcceptance
+    TVector3 v;
+    mct->GetStartVertex(v);
+    ELmvmSrc src = LmvmUtils::GetMcSrc(mct, fMCTracks);
+    if (v.Z() < 2.) { fH.FillH2("hPmtXY", src, richHit->GetX(), richHit->GetY(), fW); }
+  }
+}
 
+bool LmvmTask::IsMcTrackAccepted(int mcTrackInd)
+{
+  CbmMCTrack* tr = static_cast<CbmMCTrack*>(fMCTracks->At(mcTrackInd));
+  if (tr == nullptr) return false;
+  int nRichPoints = fNofHitsInRingMap[mcTrackInd];
+  return (tr->GetNPoints(ECbmModuleId::kMvd) + tr->GetNPoints(ECbmModuleId::kSts) >= 4 && nRichPoints >= 7
+          && tr->GetNPoints(ECbmModuleId::kTrd) >= 2 && tr->GetNPoints(ECbmModuleId::kTof) > 1);
+}
 
-void CbmAnaDielectronTask::FillElPiMomHist()
+void LmvmTask::FillPionsHist()
 {
-  Int_t nMcTracks = fMCTracks->GetEntries();
-  for (Int_t i = 0; i < nMcTracks; i++) {
-    CbmMCTrack* mctrack = (CbmMCTrack*) fMCTracks->At(i);
-    //       Int_t motherId = mctrack->GetMotherId();
-    Int_t pdg        = TMath::Abs(mctrack->GetPdgCode());
-    double momentum  = mctrack->GetP();
-    double rapidity  = mctrack->GetRapidity();
-    Int_t nMvdPoints = mctrack->GetNPoints(ECbmModuleId::kMvd);
-    Int_t nStsPoints = mctrack->GetNPoints(ECbmModuleId::kSts);
-    Bool_t isAcc     = (nMvdPoints + nStsPoints >= 4);
+  int nofMcTracks = fMCTracks->GetEntriesFast();
+  for (int i = 0; i < nofMcTracks; i++) {
+    CbmMCTrack* mct = static_cast<CbmMCTrack*>(fMCTracks->At(i));
+    bool isAccSts   = (mct->GetNPoints(ECbmModuleId::kMvd) + mct->GetNPoints(ECbmModuleId::kSts) >= 4);
     TVector3 vertex;
-    mctrack->GetStartVertex(vertex);
+    mct->GetStartVertex(vertex);
 
-    if (pdg == 211) {
-      fh_pi_mom_mc->Fill(momentum);
-      fh_pi_rapidity_mc->Fill(rapidity);
-      if (isAcc) fh_pi_mom_acc->Fill(momentum);
+    if (std::abs(mct->GetPdgCode()) == 211) {
+      fH.FillH1("hPiMom_all_mc", mct->GetP());
+      if (isAccSts) fH.FillH1("hPiMom_all_acc", mct->GetP());
 
       if (vertex.Mag() < 0.1) {
-        fh_piprim_mom_mc->Fill(momentum);
-        if (mctrack->GetPdgCode() == 211) fh_piprim_plus_rapidity_mc->Fill(rapidity);
-        if (mctrack->GetPdgCode() == -211) fh_piprim_minus_rapidity_mc->Fill(rapidity);
-        if (isAcc) fh_piprim_mom_acc->Fill(momentum);
+        fH.FillH1("hPiMom_prim_mc", mct->GetP());
+        if (isAccSts) fH.FillH1("hPiMom_prim_acc", mct->GetP());
       }
     }
-
-    if (pdg == 111 && vertex.Mag() < 0.1) { fh_pi0prim_rapidity_mc->Fill(rapidity); }
-
-    if (pdg == 221 && vertex.Mag() < 0.1) { fh_etaprim_rapidity_mc->Fill(rapidity); }
   }
 
-  Int_t ngTracks = fGlobalTracks->GetEntriesFast();
-  for (Int_t i = 0; i < ngTracks; i++) {
-    CbmGlobalTrack* gTrack = (CbmGlobalTrack*) fGlobalTracks->At(i);
-    if (NULL == gTrack) continue;
+  int ngTracks = fGlobalTracks->GetEntriesFast();
+  for (int i = 0; i < ngTracks; i++) {
+    CbmGlobalTrack* gTrack = static_cast<CbmGlobalTrack*>(fGlobalTracks->At(i));
+    if (gTrack == nullptr) continue;
     int stsInd  = gTrack->GetStsTrackIndex();
-    int richInd = gTrack->GetRichRingIndex();
-    int trdInd  = gTrack->GetTrdTrackIndex();
-    int tofInd  = gTrack->GetTofHitIndex();
+    bool isRich = (gTrack->GetRichRingIndex() >= 0);
+    bool isTrd  = (gTrack->GetTrdTrackIndex() >= 0);
+    bool isTof  = (gTrack->GetTofHitIndex() >= 0);
 
     if (stsInd < 0) continue;
-    CbmStsTrack* stsTrack = (CbmStsTrack*) fStsTracks->At(stsInd);
-    if (stsTrack == NULL) continue;
-    CbmTrackMatchNew* stsMatch = (CbmTrackMatchNew*) fStsTrackMatches->At(stsInd);
-    if (stsMatch == NULL) continue;
-    if (stsMatch->GetNofLinks() == 0) continue;
+    CbmStsTrack* stsTrack = static_cast<CbmStsTrack*>(fStsTracks->At(stsInd));
+    if (stsTrack == nullptr) continue;
+    CbmTrackMatchNew* stsMatch = static_cast<CbmTrackMatchNew*>(fStsTrackMatches->At(stsInd));
+    if (stsMatch == nullptr || stsMatch->GetNofLinks() == 0) continue;
     int stsMcTrackId = stsMatch->GetMatchedLink().GetIndex();
     if (stsMcTrackId < 0) continue;
-    CbmMCTrack* mcTrack1 = (CbmMCTrack*) fMCTracks->At(stsMcTrackId);
-    if (mcTrack1 == NULL) continue;
-    int pdg = TMath::Abs(mcTrack1->GetPdgCode());
-    //       int motherId = mcTrack1->GetMotherId();
-    double momentum = mcTrack1->GetP();
-
+    CbmMCTrack* mct = (CbmMCTrack*) fMCTracks->At(stsMcTrackId);
+    if (mct == nullptr) continue;
     TVector3 vertex;
-    mcTrack1->GetStartVertex(vertex);
+    mct->GetStartVertex(vertex);
 
-    if (pdg == 211) {
-      fh_pi_mom_rec->Fill(momentum);
-      if (richInd < 0 && trdInd < 0 && tofInd < 0) { fh_pi_mom_rec_only_sts->Fill(momentum); }
-      if (richInd >= 0 && trdInd >= 0) { fh_pi_mom_rec_sts_rich_trd->Fill(momentum); }
-      if (richInd >= 0 && trdInd >= 0 && tofInd >= 0) { fh_pi_mom_rec_sts_rich_trd_tof->Fill(momentum); }
+    if (std::abs(mct->GetPdgCode()) == 211) {
+      fH.FillH1("hPiMom_all_rec", mct->GetP());
+      if (!isRich && !isTrd && !isTof) { fH.FillH1("hPiMom_all_recOnlySts", mct->GetP()); }
+      if (isRich && isTrd) { fH.FillH1("hPiMom_all_recStsRichTrd", mct->GetP()); }
+      if (isRich && isTrd && isTof) { fH.FillH1("hPiMom_all_recStsRichTrdTof", mct->GetP()); }
 
       if (vertex.Mag() < 0.1) {
-        fh_piprim_mom_rec->Fill(momentum);
-        if (richInd < 0 && trdInd < 0 && tofInd < 0) { fh_piprim_mom_rec_only_sts->Fill(momentum); }
-        if (richInd >= 0 && trdInd >= 0) { fh_piprim_mom_rec_sts_rich_trd->Fill(momentum); }
-        if (richInd >= 0 && trdInd >= 0 && tofInd >= 0) { fh_piprim_mom_rec_sts_rich_trd_tof->Fill(momentum); }
+        fH.FillH1("hPiMom_prim_rec", mct->GetP());
+        if (!isRich && !isTrd && !isTof) { fH.FillH1("hPiMom_prim_recOnlySts", mct->GetP()); }
+        if (isRich && isTrd) { fH.FillH1("hPiMom_prim_recStsRichTrd", mct->GetP()); }
+        if (isRich && isTrd && isTof) { fH.FillH1("hPiMom_prim_recStsRichTrdTof", mct->GetP()); }
       }
     }
-  }  //gTracks
+  }
 }
 
 
-void CbmAnaDielectronTask::FillTopologyCandidates()
+void LmvmTask::FillTopologyCands()
 {
-  fSTCandidates.clear();
-  fRTCandidates.clear();
-  Int_t ngTracks = fGlobalTracks->GetEntriesFast();
+  fSTCands.clear();
+  fRTCands.clear();
+  int ngTracks = fGlobalTracks->GetEntriesFast();
 
-  for (Int_t iGTrack = 0; iGTrack < ngTracks; iGTrack++) {
-    CbmLmvmCandidate cand;
+  for (int iGTrack = 0; iGTrack < ngTracks; iGTrack++) {
+    LmvmCand cand;
 
     CbmGlobalTrack* gTrack = (CbmGlobalTrack*) fGlobalTracks->At(iGTrack);
-    if (NULL == gTrack) continue;
+    if (gTrack == nullptr) continue;
 
     cand.fStsInd = gTrack->GetStsTrackIndex();
     if (cand.fStsInd < 0) continue;
-    CbmStsTrack* stsTrack = (CbmStsTrack*) fStsTracks->At(cand.fStsInd);
-    if (stsTrack == NULL) continue;
+    CbmStsTrack* stsTrack = static_cast<CbmStsTrack*>(fStsTracks->At(cand.fStsInd));
+    if (stsTrack == nullptr) continue;
 
     cand.fRichInd = gTrack->GetRichRingIndex();
     cand.fTrdInd  = gTrack->GetTrdTrackIndex();
     cand.fTofInd  = gTrack->GetTofHitIndex();
 
-    CbmLmvmUtils::CalculateAndSetTrackParamsToCandidate(&cand, stsTrack, fKFVertex);
-
-    // select tracks from vertex
-    if (cand.fChi2Prim > fCuts.fChiPrimCut) continue;
+    LmvmUtils::CalculateAndSetTrackParams(&cand, stsTrack, fKFVertex);
+    cand.fIsChi2Prim = fCuts.IsChi2PrimaryOk(cand.fChi2Prim);
+    if (!cand.fIsChi2Prim) continue;
 
     // ST cut candidates, only STS
-    if (cand.fRichInd < 0 && cand.fTrdInd < 0 && cand.fTofInd < 0) fSTCandidates.push_back(cand);
+    if (cand.fRichInd < 0 && cand.fTrdInd < 0 && cand.fTofInd < 0) fSTCands.push_back(cand);
 
     // RT cut candidates, STS + at least one detector (RICH, TRD, TOF) but not all
     // Candidates must be identified as electron in registered detectors:
     // if it is registered in RICH it must be identified in the RICH as electron
     // RICH
-    Bool_t isRichRT = (cand.fRichInd < 0) ? false : true;
+    bool isRichRT = (cand.fRichInd < 0) ? false : true;
     if (isRichRT) {
-      CbmRichRing* richRing = (CbmRichRing*) fRichRings->At(cand.fRichInd);
-      if (richRing == NULL) isRichRT = false;
+      CbmRichRing* richRing = static_cast<CbmRichRing*>(fRichRings->At(cand.fRichInd));
+      if (richRing == nullptr) isRichRT = false;
       if (isRichRT) isRichRT = CbmLitGlobalElectronId::GetInstance().IsRichElectron(iGTrack, cand.fMomentum.Mag());
     }
 
     // TRD
-    Bool_t isTrdRT = (cand.fTrdInd < 0) ? false : true;
-    if (isTrdRT) isTrdRT = fUseTrd;
+    bool isTrdRT = (cand.fTrdInd < 0) ? false : true;
     if (isTrdRT) {
-      CbmTrdTrack* trdTrack = (CbmTrdTrack*) fTrdTracks->At(cand.fTrdInd);
-      if (trdTrack == NULL) isTrdRT = false;
+      CbmTrdTrack* trdTrack = static_cast<CbmTrdTrack*>(fTrdTracks->At(cand.fTrdInd));
+      if (trdTrack == nullptr) isTrdRT = false;
       if (isTrdRT) isTrdRT = CbmLitGlobalElectronId::GetInstance().IsTrdElectron(iGTrack, cand.fMomentum.Mag());
     }
 
     // ToF
-    Bool_t isTofRT = (cand.fTofInd < 0) ? false : true;
+    bool isTofRT = (cand.fTofInd < 0) ? false : true;
     if (isTofRT) {
-      CbmTofHit* tofHit = (CbmTofHit*) fTofHits->At(cand.fTofInd);
-      if (tofHit == NULL) isTofRT = false;
+      CbmTofHit* tofHit = static_cast<CbmTofHit*>(fTofHits->At(cand.fTofInd));
+      if (tofHit == nullptr) isTofRT = false;
       if (isTofRT) isTofRT = CbmLitGlobalElectronId::GetInstance().IsTofElectron(iGTrack, cand.fMomentum.Mag());
     }
 
     if (isRichRT || isTrdRT || isTofRT) {
-      if (!(cand.fRichInd >= 0 && cand.fTrdInd >= 0 && cand.fTofInd >= 0)) { fRTCandidates.push_back(cand); }
+      if (!(cand.fRichInd >= 0 && cand.fTrdInd >= 0 && cand.fTofInd >= 0)) { fRTCands.push_back(cand); }
     }
-  }  //gTracks
-  cout << "fSTCandidates.size() = " << fSTCandidates.size() << endl;
-  cout << "fRTCandidates.size() = " << fRTCandidates.size() << endl;
+  }
+  LOG(info) << "fSTCands.size = " << fSTCands.size();
+  LOG(info) << "fRTCands.size = " << fRTCands.size();
 
-  AssignMcToTopologyCandidates(fSTCandidates);
-  AssignMcToTopologyCandidates(fRTCandidates);
+  AssignMcToTopologyCands(fSTCands);
+  AssignMcToTopologyCands(fRTCands);
 }
 
-void CbmAnaDielectronTask::FillCandidates()
+void LmvmTask::FillCands()
 {
-  fCandidates.clear();
-  fTTCandidates.clear();
-  Int_t nGTracks = fGlobalTracks->GetEntriesFast();
-  fCandidates.reserve(nGTracks);
-
-  for (Int_t iGTrack = 0; iGTrack < nGTracks; iGTrack++) {
-    CbmLmvmCandidate cand;
-    cand.fIsElectron        = false;
-    cand.fIsGamma           = false;
-    cand.fIsStCutElectron   = false;
-    cand.fIsTtCutElectron   = false;
-    cand.fIsRtCutElectron   = false;
-    cand.fIsMvd1CutElectron = true;
-    cand.fIsMvd2CutElectron = true;
-    cand.fEventNumber       = fEventNumber;
+  fCands.clear();
+  fTTCands.clear();
+  int nGTracks = fGlobalTracks->GetEntriesFast();
+  fCands.reserve(nGTracks);
+
+  for (int iGTrack = 0; iGTrack < nGTracks; iGTrack++) {
+    LmvmCand cand;
+    // if MVD is not used set mvd cuts to true
+    cand.fIsMvd1Cut   = !fUseMvd;
+    cand.fIsMvd2Cut   = !fUseMvd;
+    cand.fEventNumber = fEventNumber;
+
+    CbmGlobalTrack* gTrack = static_cast<CbmGlobalTrack*>(fGlobalTracks->At(iGTrack));
+    if (gTrack == nullptr) continue;
 
-    CbmGlobalTrack* gTrack = (CbmGlobalTrack*) fGlobalTracks->At(iGTrack);
-    if (NULL == gTrack) continue;
     // STS
     cand.fStsInd = gTrack->GetStsTrackIndex();
     if (cand.fStsInd < 0) continue;
-    CbmStsTrack* stsTrack = (CbmStsTrack*) fStsTracks->At(cand.fStsInd);
-    if (stsTrack == NULL) continue;
+    CbmStsTrack* stsTrack = static_cast<CbmStsTrack*>(fStsTracks->At(cand.fStsInd));
+    if (stsTrack == nullptr) continue;
 
-    CbmLmvmUtils::CalculateAndSetTrackParamsToCandidate(&cand, stsTrack, fKFVertex);
+    LmvmUtils::CalculateAndSetTrackParams(&cand, stsTrack, fKFVertex);
+    cand.fIsChi2Prim = fCuts.IsChi2PrimaryOk(cand.fChi2Prim);
+    cand.fIsPtCut    = fCuts.IsPtCutOk(cand.fMomentum.Perp());
 
     // Add all pions from STS for pion misidentification level study
     if (fPionMisidLevel >= 0.0) {
       CbmTrackMatchNew* stsMatch = (CbmTrackMatchNew*) fStsTrackMatches->At(cand.fStsInd);
-      if (stsMatch == NULL) continue;
-      if (stsMatch->GetNofLinks() == 0) continue;
+      if (stsMatch == nullptr || stsMatch->GetNofLinks() == 0) continue;
       cand.fStsMcTrackId = stsMatch->GetMatchedLink().GetIndex();
       if (cand.fStsMcTrackId < 0) continue;
-      CbmMCTrack* mcTrack1 = (CbmMCTrack*) fMCTracks->At(cand.fStsMcTrackId);
-      if (mcTrack1 == NULL) continue;
-      Int_t pdg = TMath::Abs(mcTrack1->GetPdgCode());
+      CbmMCTrack* mcTrack1 = static_cast<CbmMCTrack*>(fMCTracks->At(cand.fStsMcTrackId));
+      if (mcTrack1 == nullptr) continue;
 
       //check that pion track has track projection onto the photodetector plane
-      const FairTrackParam* richProjection = (FairTrackParam*) (fRichProj->At(iGTrack));
-      if (richProjection == NULL || richProjection->GetX() == 0 || richProjection->GetY() == 0) continue;
+      const FairTrackParam* richProj = static_cast<FairTrackParam*>(fRichProj->At(iGTrack));
+      if (richProj == nullptr || richProj->GetX() == 0 || richProj->GetY() == 0) continue;
 
-      if (pdg == 211) {
-        IsElectron(iGTrack, cand.fMomentum.Mag(), &cand);
-        fCandidatesTotal.push_back(cand);
-        fCandidates.push_back(cand);
+      if (std::abs(mcTrack1->GetPdgCode()) == 211) {
+        LmvmUtils::IsElectronMc(&cand, fMCTracks, fPionMisidLevel);
+        fCands.push_back(cand);
         continue;
       }
     }
 
-    // RICH
+    // RICH - TRD - TOF
     cand.fRichInd = gTrack->GetRichRingIndex();
-    if (cand.fRichInd < 0) continue;
-    // CbmRichRing* richRing = (CbmRichRing*) fRichRings->At(cand.fRichInd); (FU) unused
-
-    // TRD
-    CbmTrdTrack* trdTrack = NULL;
-    if (fUseTrd == true) {
-      cand.fTrdInd = gTrack->GetTrdTrackIndex();
-      if (cand.fTrdInd < 0) continue;
-      trdTrack = (CbmTrdTrack*) fTrdTracks->At(cand.fTrdInd);
-      if (trdTrack == NULL) continue;
-    }
-
-    // ToF
-    cand.fTofInd = gTrack->GetTofHitIndex();
-    if (cand.fTofInd < 0) continue;
-    CbmTofHit* tofHit = (CbmTofHit*) fTofHits->At(cand.fTofInd);
-    if (tofHit == NULL) continue;
+    cand.fTrdInd  = gTrack->GetTrdTrackIndex();
+    cand.fTofInd  = gTrack->GetTofHitIndex();
+    if (cand.fRichInd < 0 || cand.fTrdInd < 0 || cand.fTofInd < 0) continue;
 
-    IsElectron(iGTrack, cand.fMomentum.Mag(), &cand);
+    CbmRichRing* richRing = static_cast<CbmRichRing*>(fRichRings->At(cand.fRichInd));
+    CbmTrdTrack* trdTrack = static_cast<CbmTrdTrack*>(fTrdTracks->At(cand.fTrdInd));
+    CbmTofHit* tofHit     = static_cast<CbmTofHit*>(fTofHits->At(cand.fTofInd));
+    if (richRing == nullptr || trdTrack == nullptr || tofHit == nullptr) continue;
 
-    fCandidates.push_back(cand);
-    fCandidatesTotal.push_back(cand);
+    LmvmUtils::IsElectron(iGTrack, cand.fMomentum.Mag(), fCuts.fMomentumCut, &cand);
 
-    if (!cand.fIsElectron && cand.fChi2Prim < fCuts.fChiPrimCut) fTTCandidates.push_back(cand);
+    fCands.push_back(cand);
 
-  }  // global tracks
-  cout << "fCandidates.size() = " << fCandidates.size() << endl;
-  cout << "fTTCandidates.size() = " << fTTCandidates.size() << endl;
+    if (!cand.fIsElectron && cand.fIsChi2Prim) fTTCands.push_back(cand);
+  }
+  LOG(info) << "fTTCands.size = " << fTTCands.size();
+  LOG(info) << "fCands.size = " << fCands.size();
 
-  AssignMcToCandidates(fCandidates);
-  AssignMcToCandidates(fCandidatesTotal);
-  AssignMcToTopologyCandidates(fTTCandidates);
+  AssignMcToCands(fCands);
+  AssignMcToTopologyCands(fTTCands);
 }
 
-void CbmAnaDielectronTask::CombinatorialPairs()
+void LmvmTask::CombinatorialPairs()
 {
-  int nofEvents = fh_event_number->GetEntries();
-  cout << "Number of Events = " << nofEvents << endl;
-  int nCand     = fCandidatesTotal.size();
-  int nSigCand1 = 0;
-  int nSigCand2 = 0;
-  int nChiPrim  = 0;
-  int nIsEl     = 0;
-  int nGammaCut = 0;
-  int nStCut    = 0;
-  int nRtCut    = 0;
-  int nTtCut    = 0;
-  int nPtCut    = 0;
-
-  for (int iCand1 = 0; iCand1 < nCand - 1; iCand1++) {  // Before: iCand1 < nCand - 2
-    int nEvent1      = fCandidatesTotal[iCand1].fEventNumber;
-    int charge1      = fCandidatesTotal[iCand1].fCharge;
-    Bool_t isSignal1 = (fCandidatesTotal[iCand1].fIsMcSignalElectron);
-    if (isSignal1) nSigCand1++;
-
-    for (int iCand2 = iCand1 + 1; iCand2 < nCand; iCand2++) {
-      int nEvent2      = fCandidatesTotal[iCand2].fEventNumber;
-      int charge2      = fCandidatesTotal[iCand2].fCharge;
-      Bool_t isSignal2 = (fCandidatesTotal[iCand2].fIsMcSignalElectron);
-      if (isSignal2) nSigCand2++;
-      if (isSignal1 xor isSignal2)
-        continue;  // since in FillPairHists() this case is not considered as well; to have same behaviour here as there
-      double weight = (isSignal1 && isSignal2) ? fWeight : 1.;
-
-      CbmLmvmKinematicParams pRec =
-        CbmLmvmKinematicParams::KinematicParamsWithCandidates(&fCandidatesTotal[iCand1], &fCandidatesTotal[iCand2]);
-
-      Bool_t isChiPrimary = (fCandidatesTotal[iCand1].fChi2Prim < fCuts.fChiPrimCut
-                             && fCandidatesTotal[iCand2].fChi2Prim < fCuts.fChiPrimCut);
-      Bool_t isEl         = (fCandidatesTotal[iCand1].fIsElectron && fCandidatesTotal[iCand2].fIsElectron);
-      Bool_t isGammaCut   = (!fCandidatesTotal[iCand1].fIsGamma && !fCandidatesTotal[iCand2].fIsGamma);
-      Bool_t isStCut      = (fCandidatesTotal[iCand1].fIsStCutElectron && fCandidatesTotal[iCand2].fIsStCutElectron);
-      Bool_t isRtCut      = (fCandidatesTotal[iCand1].fIsRtCutElectron && fCandidatesTotal[iCand2].fIsRtCutElectron);
-      Bool_t isTtCut      = (fCandidatesTotal[iCand1].fIsTtCutElectron && fCandidatesTotal[iCand2].fIsTtCutElectron);
-      Bool_t isPtCut      = (fCandidatesTotal[iCand1].fMomentum.Perp() > fCuts.fPtCut
-                        && fCandidatesTotal[iCand2].fMomentum.Perp() > fCuts.fPtCut);
-      Bool_t isMvd1Cut = (fCandidatesTotal[iCand1].fIsMvd1CutElectron && fCandidatesTotal[iCand2].fIsMvd1CutElectron);
-      Bool_t isMvd2Cut = (fCandidatesTotal[iCand1].fIsMvd2CutElectron && fCandidatesTotal[iCand2].fIsMvd2CutElectron);
-
-      if (isChiPrimary) nChiPrim++;
-      if (isChiPrimary && isEl) nIsEl++;
-      if (isChiPrimary && isEl && isGammaCut) nGammaCut++;
-      if (isChiPrimary && isEl && isGammaCut && isStCut) nStCut++;
-      if (isChiPrimary && isEl && isGammaCut && isStCut && isRtCut) nRtCut++;
-      if (isChiPrimary && isEl && isGammaCut && isStCut && isRtCut && isTtCut) nTtCut++;
-      if (isChiPrimary && isEl && isGammaCut && isStCut && isRtCut && isTtCut && isPtCut) nPtCut++;
-
-      if (!fUseMvd) isMvd1Cut = true;
-      if (!fUseMvd) isMvd2Cut = true;
-
-      // step: reco
-      if (charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kReco]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kReco]->Fill(pRec.fMinv, weight);
-      }
-      if (charge1 < 0 && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kReco]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kReco]->Fill(pRec.fMinv, weight);
-      }
-      if (charge1 > 0 && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kReco]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kReco]->Fill(pRec.fMinv, weight);
-      }
-
-      // step: chi2prim
-      if (isChiPrimary && charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kChi2Prim]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kChi2Prim]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && charge1 < 0 && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kChi2Prim]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kChi2Prim]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && charge1 > 0 && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kChi2Prim]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kChi2Prim]->Fill(pRec.fMinv, weight);
-      }
-
-      // step: elID
-      if (isChiPrimary && isEl && charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kElId]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kElId]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && charge1 < 0 && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kElId]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kElId]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && charge1 > 0 && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kElId]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kElId]->Fill(pRec.fMinv, weight);
-      }
-
-      // step: gamma cut
-      if (isChiPrimary && isEl && isGammaCut && charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kGammaCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kGammaCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && charge1 < 0 && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kGammaCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kGammaCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && charge1 > 0 && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kGammaCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kGammaCut]->Fill(pRec.fMinv, weight);
-      }
-
-      // step: MVD1 cut
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kMvd1Cut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kMvd1Cut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && charge1 < 0 && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kMvd1Cut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kMvd1Cut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && charge1 > 0 && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kMvd1Cut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kMvd1Cut]->Fill(pRec.fMinv, weight);
-      }
-
-      // step: MVD2 cut
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kMvd2Cut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kMvd2Cut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && charge1 < 0 && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kMvd2Cut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kMvd2Cut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && charge1 > 0 && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kMvd2Cut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kMvd2Cut]->Fill(pRec.fMinv, weight);
-      }
-
-      // step: ST cut
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kStCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kStCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && charge1 < 0 && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kStCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kStCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && charge1 > 0 && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kStCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kStCut]->Fill(pRec.fMinv, weight);
-      }
-
-      // step: RT cut
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kRtCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kRtCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && charge1 < 0
-          && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kRtCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kRtCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && charge1 > 0
-          && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kRtCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kRtCut]->Fill(pRec.fMinv, weight);
-      }
-
-      // step: TT cut
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut
-          && charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kTtCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kTtCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut && charge1 < 0
-          && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kTtCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kTtCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut && charge1 > 0
-          && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kTtCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kTtCut]->Fill(pRec.fMinv, weight);
-      }
-
-      // step: Pt cut
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut && isPtCut
-          && charge1 * charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPM_minv_sameEvent[kPtCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPM_minv_mixedEvents[kPtCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut && isPtCut
-          && charge1 < 0 && charge2 < 0) {
-        if (nEvent1 == nEvent2) fh_combPairsMM_minv_sameEvent[kPtCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsMM_minv_mixedEvents[kPtCut]->Fill(pRec.fMinv, weight);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut && isPtCut
-          && charge1 > 0 && charge2 > 0) {
-        if (nEvent1 == nEvent2) fh_combPairsPP_minv_sameEvent[kPtCut]->Fill(pRec.fMinv, weight);
-        if (nEvent1 != nEvent2) fh_combPairsPP_minv_mixedEvents[kPtCut]->Fill(pRec.fMinv, weight);
+  size_t nCand = fCandsTotal.size();
+  for (size_t iC1 = 0; iC1 < nCand; iC1++) {
+    const auto& cand1 = fCandsTotal[iC1];
+    // for the moment remove signal from combinatorics.
+    // TODO: Discuss if we need to include signal with weight
+    if (cand1.IsMcSignal()) continue;
+
+    for (size_t iC2 = iC1 + 1; iC2 < nCand; iC2++) {
+      const auto& cand2 = fCandsTotal[iC2];
+      if (cand2.IsMcSignal()) continue;
+      //double weight = (cand1.IsMcSignal() || cand2.IsMcSignal()) ? fW : 1.;
+
+      CbmLmvmKinematicParams pRec = CbmLmvmKinematicParams::Create(&cand1, &cand2);
+      bool isSameEvent            = (cand1.fEventNumber == cand2.fEventNumber);
+      for (auto step : fH.fAnaSteps) {
+        if (step == ELmvmAnaStep::Mc || step == ELmvmAnaStep::Acc) continue;
+        if (cand1.IsCutTill(step) && cand2.IsCutTill(step)) {
+          if (cand1.fCharge * cand2.fCharge < 0) {
+            if (isSameEvent) fH.FillH1("hMinvCombPM_sameEv", step, pRec.fMinv);
+            else
+              fH.FillH1("hMinvCombPM_mixedEv", step, pRec.fMinv);
+          }
+          if (cand1.fCharge < 0 && cand2.fCharge < 0) {
+            if (isSameEvent) fH.FillH1("hMinvCombMM_sameEv", step, pRec.fMinv);
+            else
+              fH.FillH1("hMinvCombMM_mixedEv", step, pRec.fMinv);
+          }
+          if (cand1.fCharge > 0 && cand2.fCharge > 0) {
+            if (isSameEvent) fH.FillH1("hMinvCombPP_sameEv", step, pRec.fMinv);
+            else
+              fH.FillH1("hMinvCombPP_mixedEv", step, pRec.fMinv);
+          }
+        }
       }
-
-    }  // FOR cand2
-  }    // FOR cand1
-
-  cout << "fCandidatesTotal.size() = " << fCandidatesTotal.size() << endl;
-  cout << "nSigCand1 = " << nSigCand1 << ", nSigCand2 = " << nSigCand2 << endl;
-  cout << "nChiPrim = " << nChiPrim << ", nIsEl = " << nIsEl << ", nGammaCut = " << nGammaCut
-       << ", nSt/Rt/TtCut = " << nStCut << "/" << nRtCut << "/" << nTtCut << ", nPtCut = " << nPtCut << endl;
+    }
+  }
 }
 
-void CbmAnaDielectronTask::AssignMcToCandidates(vector<CbmLmvmCandidate>& candVector)
+void LmvmTask::AssignMcToCands(vector<LmvmCand>& cands)
 {
-  int nCand = candVector.size();
-  for (int i = 0; i < nCand; i++) {
-    if (candVector[i].fEventNumber != fEventNumber) continue;
-    candVector[i].ResetMcParams();
-
-    //STS
-    //MCTrackId of the candidate is defined by STS track
-    int stsInd                 = candVector[i].fStsInd;
-    CbmTrackMatchNew* stsMatch = (CbmTrackMatchNew*) fStsTrackMatches->At(stsInd);
-    if (stsMatch == NULL) continue;
-    if (stsMatch->GetNofLinks() == 0) continue;
-    candVector[i].fStsMcTrackId = stsMatch->GetMatchedLink().GetIndex();
-    if (candVector[i].fStsMcTrackId < 0) continue;
-    CbmMCTrack* mcTrack1 = (CbmMCTrack*) fMCTracks->At(candVector[i].fStsMcTrackId);
-    if (mcTrack1 == NULL) continue;
-    int pdg                   = TMath::Abs(mcTrack1->GetPdgCode());
-    int motherId              = mcTrack1->GetMotherId();
-    candVector[i].fMcMotherId = motherId;
-    candVector[i].fMcPdg      = pdg;
-
-    if (pdg == 211 && fPionMisidLevel >= 0.) continue;
+  for (auto& cand : cands) {
+    cand.ResetMcParams();
+
+    //STS. MCTrackId of the candidate is defined by STS track
+    CbmTrackMatchNew* stsMatch = static_cast<CbmTrackMatchNew*>(fStsTrackMatches->At(cand.fStsInd));
+    if (stsMatch == nullptr || stsMatch->GetNofLinks() == 0) continue;
+    cand.fStsMcTrackId = stsMatch->GetMatchedLink().GetIndex();
+    if (cand.fStsMcTrackId < 0) continue;
+    CbmMCTrack* mct = static_cast<CbmMCTrack*>(fMCTracks->At(cand.fStsMcTrackId));
+    if (mct == nullptr) continue;
+    cand.fMcMotherId = mct->GetMotherId();
+    cand.fMcPdg      = mct->GetPdgCode();
+    cand.fMcSrc      = LmvmUtils::GetMcSrc(mct, fMCTracks);
+
+    if (std::abs(cand.fMcPdg) == 211 && fPionMisidLevel >= 0.) continue;
 
     // RICH
-    int richInd                 = candVector[i].fRichInd;
-    CbmTrackMatchNew* richMatch = (CbmTrackMatchNew*) fRichRingMatches->At(richInd);
-    if (richMatch == NULL) continue;
-    candVector[i].fRichMcTrackId = richMatch->GetMatchedLink().GetIndex();
-
-    candVector[i].fIsMcSignalElectron = CbmLmvmUtils::IsMcSignalElectron(mcTrack1);
-    candVector[i].fIsMcPi0Electron    = CbmLmvmUtils::IsMcPi0Electron(mcTrack1, fMCTracks);
-    candVector[i].fIsMcGammaElectron  = CbmLmvmUtils::IsMcGammaElectron(mcTrack1, fMCTracks);
-    candVector[i].fIsMcEtaElectron    = CbmLmvmUtils::IsMcEtaElectron(mcTrack1, fMCTracks);
+    CbmTrackMatchNew* richMatch = static_cast<CbmTrackMatchNew*>(fRichRingMatches->At(cand.fRichInd));
+    if (richMatch == nullptr) continue;
+    cand.fRichMcTrackId = richMatch->GetMatchedLink().GetIndex();
 
     // TRD
-    //      CbmTrdTrack* trdTrack = NULL;
-    if (fUseTrd == true) {
-      int trdInd                 = candVector[i].fTrdInd;
-      CbmTrackMatchNew* trdMatch = (CbmTrackMatchNew*) fTrdTrackMatches->At(trdInd);
-      if (trdMatch == NULL) continue;
-      candVector[i].fTrdMcTrackId = trdMatch->GetMatchedLink().GetIndex();
-    }
+    CbmTrackMatchNew* trdMatch = static_cast<CbmTrackMatchNew*>(fTrdTrackMatches->At(cand.fTrdInd));
+    if (trdMatch == nullptr) continue;
+    cand.fTrdMcTrackId = trdMatch->GetMatchedLink().GetIndex();
 
     // ToF
-    int tofInd = candVector[i].fTofInd;
-    if (tofInd < 0) continue;
-    CbmTofHit* tofHit = (CbmTofHit*) fTofHits->At(tofInd);
-    if (tofHit == NULL) continue;
-    CbmMatch* tofHitMatch = static_cast<CbmMatch*>(fTofHitsMatches->At(tofInd));
-    if (tofHitMatch == NULL) continue;
-    Int_t tofPointIndex = tofHitMatch->GetMatchedLink().GetIndex();
+    if (cand.fTofInd < 0) continue;
+    CbmTofHit* tofHit = static_cast<CbmTofHit*>(fTofHits->At(cand.fTofInd));
+    if (tofHit == nullptr) continue;
+    CbmMatch* tofHitMatch = static_cast<CbmMatch*>(fTofHitsMatches->At(cand.fTofInd));
+    if (tofHitMatch == nullptr) continue;
+    int tofPointIndex = tofHitMatch->GetMatchedLink().GetIndex();
     if (tofPointIndex < 0) continue;
-    FairMCPoint* tofPoint = (FairMCPoint*) fTofPoints->At(tofPointIndex);
-    if (tofPoint == NULL) continue;
-    candVector[i].fTofMcTrackId = tofPoint->GetTrackID();
+    FairMCPoint* tofPoint = static_cast<FairMCPoint*>(fTofPoints->At(tofPointIndex));
+    if (tofPoint == nullptr) continue;
+    cand.fTofMcTrackId = tofPoint->GetTrackID();
   }
 }
 
-void CbmAnaDielectronTask::AssignMcToTopologyCandidates(vector<CbmLmvmCandidate>& cutCandidates)
+void LmvmTask::AssignMcToTopologyCands(vector<LmvmCand>& topoCands)
 {
-  int nCand = cutCandidates.size();
-  for (int i = 0; i < nCand; i++) {
-    cutCandidates[i].ResetMcParams();
-
-    int stsInd = cutCandidates[i].fStsInd;
-    if (stsInd < 0) continue;
-    CbmTrackMatchNew* stsMatch = (CbmTrackMatchNew*) fStsTrackMatches->At(stsInd);
-    if (stsMatch == NULL) continue;
-    if (stsMatch->GetNofLinks() == 0) continue;
-    int stsMcTrackId               = stsMatch->GetMatchedLink().GetIndex();
-    cutCandidates[i].fStsMcTrackId = stsMcTrackId;
-    if (stsMcTrackId < 0) continue;
-    CbmMCTrack* mcTrack1 = (CbmMCTrack*) fMCTracks->At(stsMcTrackId);
-    if (mcTrack1 == NULL) continue;
-
-    int pdg                      = TMath::Abs(mcTrack1->GetPdgCode());
-    int motherId                 = mcTrack1->GetMotherId();
-    cutCandidates[i].fMcMotherId = motherId;
-    cutCandidates[i].fMcPdg      = pdg;
-
-    cutCandidates[i].fIsMcSignalElectron = CbmLmvmUtils::IsMcSignalElectron(mcTrack1);
-    cutCandidates[i].fIsMcPi0Electron    = CbmLmvmUtils::IsMcPi0Electron(mcTrack1, fMCTracks);
-    cutCandidates[i].fIsMcGammaElectron  = CbmLmvmUtils::IsMcGammaElectron(mcTrack1, fMCTracks);
-    cutCandidates[i].fIsMcEtaElectron    = CbmLmvmUtils::IsMcEtaElectron(mcTrack1, fMCTracks);
+  for (auto& cand : topoCands) {
+    cand.ResetMcParams();
+    if (cand.fStsInd < 0) continue;
+    CbmTrackMatchNew* stsMatch = static_cast<CbmTrackMatchNew*>(fStsTrackMatches->At(cand.fStsInd));
+    if (stsMatch == nullptr || stsMatch->GetNofLinks() == 0) continue;
+    cand.fStsMcTrackId = stsMatch->GetMatchedLink().GetIndex();
+    if (cand.fStsMcTrackId < 0) continue;
+    CbmMCTrack* mct = static_cast<CbmMCTrack*>(fMCTracks->At(cand.fStsMcTrackId));
+    if (mct == nullptr) continue;
+
+    cand.fMcMotherId = mct->GetMotherId();
+    cand.fMcPdg      = mct->GetPdgCode();
+    cand.fMcSrc      = LmvmUtils::GetMcSrc(mct, fMCTracks);
   }
 }
 
-void CbmAnaDielectronTask::PairSource(CbmLmvmCandidate* candP, CbmLmvmCandidate* candM, CbmLmvmAnalysisSteps step,
-                                      CbmLmvmKinematicParams* parRec)
+void LmvmTask::PairSource(const LmvmCand& candP, const LmvmCand& candM, ELmvmAnaStep step,
+                          const CbmLmvmKinematicParams& parRec)
 {
-  Bool_t isSignal = candP->fIsMcSignalElectron && candM->fIsMcSignalElectron;
-  Bool_t isPi0    = (candP->fIsMcPi0Electron && candM->fIsMcPi0Electron && candP->fMcMotherId == candM->fMcMotherId);
-  Bool_t isEta    = (candP->fIsMcEtaElectron && candM->fIsMcEtaElectron && candP->fMcMotherId == candM->fMcMotherId);
-  Bool_t isGamma = (candP->fIsMcGammaElectron && candM->fIsMcGammaElectron && candP->fMcMotherId == candM->fMcMotherId);
-  Bool_t isBg    = (!isEta) && (!isGamma) && (!isPi0) && (!(candP->fIsMcSignalElectron || candM->fIsMcSignalElectron));
-
-
-  if (isSignal) fh_opening_angle[kSignal][step]->Fill(parRec->fAngle, fWeight);
-  if (isBg) fh_opening_angle[kBg][step]->Fill(parRec->fAngle);
-  if (isPi0) fh_opening_angle[kPi0][step]->Fill(parRec->fAngle);
-  if (isGamma) fh_opening_angle[kGamma][step]->Fill(parRec->fAngle);
-
-
-  int binNum = (double) step + 0.5;
-  // Fill BG source pair histograms
-  if (isBg) {
-    TH2D* hsp = fh_source_pairs_epem[step];
-    if (candM->fIsMcGammaElectron) {
-      if (candP->fIsMcGammaElectron && candP->fMcMotherId != candM->fMcMotherId) {
-        hsp->Fill(0.5, 0.5);
-        fh_source_bg_minv[0][step]->Fill(parRec->fMinv);  //g-g
-        fh_source_pairs->Fill(binNum, 0.5);
-      }
-      else if (candP->fIsMcPi0Electron) {
-        hsp->Fill(1.5, 0.5);
-        fh_source_bg_minv[3][step]->Fill(parRec->fMinv);  //g-p
-        fh_source_pairs->Fill(binNum, 3.5);
-      }
-      else {
-        hsp->Fill(2.5, 0.5);
-        fh_source_bg_minv[4][step]->Fill(parRec->fMinv);  //g-o
-        fh_source_pairs->Fill(binNum, 4.5);
-      }
-    }
-    else if (candM->fIsMcPi0Electron) {
-      if (candP->fIsMcGammaElectron) {
-        hsp->Fill(0.5, 1.5);
-        fh_source_bg_minv[3][step]->Fill(parRec->fMinv);  //g-p
-        fh_source_pairs->Fill(binNum, 3.5);
-      }
-      else if (candP->fIsMcPi0Electron && candP->fMcMotherId != candM->fMcMotherId) {
-        hsp->Fill(1.5, 1.5);
-        fh_source_bg_minv[1][step]->Fill(parRec->fMinv);  //p-p
-        fh_source_pairs->Fill(binNum, 1.5);
-      }
-      else {
-        hsp->Fill(2.5, 1.5);
-        fh_source_bg_minv[5][step]->Fill(parRec->fMinv);  //p-o
-        fh_source_pairs->Fill(binNum, 5.5);
-      }
-    }
-    else {
-      if (candP->fIsMcGammaElectron) {
-        hsp->Fill(0.5, 2.5);
-        fh_source_bg_minv[4][step]->Fill(parRec->fMinv);  //g-o
-        fh_source_pairs->Fill(binNum, 4.5);
-      }
-      else if (candP->fIsMcPi0Electron) {
-        hsp->Fill(1.5, 2.5);
-        fh_source_bg_minv[5][step]->Fill(parRec->fMinv);  //p-o
-        fh_source_pairs->Fill(binNum, 5.5);
-      }
-      else {
-        hsp->Fill(2.5, 2.5);
-        fh_source_bg_minv[2][step]->Fill(parRec->fMinv);  //o-o
-        fh_source_pairs->Fill(binNum, 2.5);
-      }
+  ELmvmSrc src = LmvmUtils::GetMcPairSrc(candP, candM);
+  fH.FillH1("hAnglePair", src, step, parRec.fAngle, fW);
+
+  if (src == ELmvmSrc::Bg) {
+    // gamma=0.5, pi0=1.5, other=2.5
+    double indM = candM.IsMcGamma() ? 0.5 : (candM.IsMcPi0() ? 1.5 : 2.5);
+    double indP = candP.IsMcGamma() ? 0.5 : (candP.IsMcPi0() ? 1.5 : 2.5);
+    fH.FillH2("hSrcBgPairsEpEm", step, indP, indM);
+
+    ELmvmBgPairSrc bgSrc = LmvmUtils::GetBgPairSrc(candP, candM);
+    if (bgSrc != ELmvmBgPairSrc::Undefined) {
+      string name = fH.GetName("hMinvBgSource_" + fH.fBgPairSrcNames[static_cast<int>(bgSrc)], step);
+      fH.FillH1(name, parRec.fMinv);
+      fH.FillH2("hSrcBgPairs", static_cast<int>(step) + 0.5, static_cast<double>(bgSrc) + 0.5);
     }
   }
 }
 
-void CbmAnaDielectronTask::TrackSource(CbmLmvmCandidate* cand, CbmLmvmAnalysisSteps step, Int_t pdg)
+void LmvmTask::TrackSource(const LmvmCand& cand, ELmvmAnaStep step, int pdg)
 {
-  int binNum   = (double) step + 0.5;
-  Double_t mom = cand->fMomentum.Mag();
-  Double_t pt  = cand->fMomentum.Perp();
-  if (cand->fIsMcSignalElectron) {
-    fh_nof_el_tracks->Fill(binNum, fWeight);
-    fh_source_mom[kSignal][step]->Fill(mom, fWeight);
-    fh_source_pt[kSignal][step]->Fill(pt, fWeight);
-  }
+  // mo need to fill histograms for MC and Acc steps
+  if (step == ELmvmAnaStep::Mc || step == ELmvmAnaStep::Acc) return;
+
+  double stepBin = static_cast<double>(step) + 0.5;
+
+  FillMomHists(nullptr, &cand, cand.fMcSrc, step);
+
+  if (cand.IsMcSignal()) { fH.FillH1("hNofSignalTracks", stepBin, fW); }
   else {
-    if (IsMismatch(cand)) fh_nof_mismatches->Fill(binNum);
-    if (cand->fStsMcTrackId != cand->fRichMcTrackId) fh_nof_mismatches_rich->Fill(binNum);
-    if (fUseTrd && cand->fStsMcTrackId != cand->fTrdMcTrackId) fh_nof_mismatches_trd->Fill(binNum);
-    if (cand->fStsMcTrackId != cand->fTofMcTrackId) fh_nof_mismatches_tof->Fill(binNum);
-    if (IsGhost(cand)) fh_nof_ghosts->Fill(binNum);
-    fh_nof_bg_tracks->Fill(binNum);
-    fh_source_mom[kBg][step]->Fill(mom);
-    fh_source_pt[kBg][step]->Fill(pt);
-    if (cand->fIsMcGammaElectron) {
-      fh_source_tracks->Fill(binNum, 0.5);
-      fh_source_mom[kGamma][step]->Fill(mom);
-      fh_source_pt[kGamma][step]->Fill(pt);
-
-      // e+/- from gamma conversion vertex
-      int mcTrackId       = cand->fStsMcTrackId;
-      CbmMCTrack* mctrack = (CbmMCTrack*) fMCTracks->At(mcTrackId);
-      if (NULL != mctrack) {
+    if (LmvmUtils::IsMismatch(cand)) fH.FillH1("hNofMismatches_all", stepBin);
+    if (cand.fStsMcTrackId != cand.fRichMcTrackId) fH.FillH1("hNofMismatches_rich", stepBin);
+    if (cand.fStsMcTrackId != cand.fTrdMcTrackId) fH.FillH1("hNofMismatches_trd", stepBin);
+    if (cand.fStsMcTrackId != cand.fTofMcTrackId) fH.FillH1("hNofMismatches_tof", stepBin);
+    if (LmvmUtils::IsGhost(cand)) fH.FillH1("hNofGhosts", stepBin);
+    fH.FillH1("hNofBgTracks", stepBin);
+
+    if (cand.IsMcGamma()) {
+      CbmMCTrack* mctrack = static_cast<CbmMCTrack*>(fMCTracks->At(cand.fStsMcTrackId));
+      if (mctrack != nullptr) {
         TVector3 v;
         mctrack->GetStartVertex(v);
-        fh_vertex_el_gamma_xz[step]->Fill(v.Z(), v.X());
-        fh_vertex_el_gamma_yz[step]->Fill(v.Z(), v.Y());
-        fh_vertex_el_gamma_xy[step]->Fill(v.X(), v.Y());
-        fh_vertex_el_gamma_rz[step]->Fill(v.Z(), sqrt(v.X() * v.X() + v.Y() * v.Y()));
+        fH.FillH2("hVertexGammaXZ", step, v.Z(), v.X());
+        fH.FillH2("hVertexGammaYZ", step, v.Z(), v.Y());
+        fH.FillH2("hVertexGammaXY", step, v.X(), v.Y());
+        fH.FillH2("hVertexGammaRZ", step, v.Z(), sqrt(v.X() * v.X() + v.Y() * v.Y()));
       }
     }
-    else if (cand->fIsMcPi0Electron) {
-      fh_source_tracks->Fill(binNum, 1.5);
-      fh_source_mom[kPi0][step]->Fill(mom);
-      fh_source_pt[kPi0][step]->Fill(pt);
-    }
-    else if (pdg == 211 || pdg == -211) {
-      fh_source_tracks->Fill(binNum, 2.5);
-    }
-    else if (pdg == 2212) {
-      fh_source_tracks->Fill(binNum, 3.5);
-    }
-    else if (pdg == 321 || pdg == -321) {
-      fh_source_tracks->Fill(binNum, 4.5);
-    }
-    else if ((pdg == 11 || pdg == -11) && !cand->fIsMcGammaElectron && !cand->fIsMcPi0Electron
-             && !cand->fIsMcSignalElectron) {
-      fh_source_tracks->Fill(binNum, 5.5);
-    }
-    else {
-      fh_source_tracks->Fill(binNum, 6.5);
-    }
+
+    double srcBin = 0.0;
+    if (cand.IsMcGamma()) srcBin = 0.5;
+    else if (cand.IsMcPi0())
+      srcBin = 1.5;
+    else if (std::abs(pdg) == 211)
+      srcBin = 2.5;
+    else if (pdg == 2212)
+      srcBin = 3.5;
+    else if (std::abs(pdg) == 321)
+      srcBin = 4.5;
+    else if ((std::abs(pdg) == 11) && !cand.IsMcGamma() && !cand.IsMcPi0() && !cand.IsMcSignal())
+      srcBin = 5.5;
+    else
+      srcBin = 6.5;
+    fH.FillH2("hBgSrcTracks", stepBin, srcBin);
   }
 }
 
-void CbmAnaDielectronTask::FillPairHists(CbmLmvmCandidate* candP, CbmLmvmCandidate* candM,
-                                         CbmLmvmKinematicParams* parMc, CbmLmvmKinematicParams* parRec,
-                                         CbmLmvmAnalysisSteps step)
+void LmvmTask::FillPairHists(const LmvmCand& candP, const LmvmCand& candM, const CbmLmvmKinematicParams& parMc,
+                             const CbmLmvmKinematicParams& parRec, ELmvmAnaStep step)
 {
-  Bool_t isSignal = candP->fIsMcSignalElectron && candM->fIsMcSignalElectron;
-  Bool_t isPi0    = (candP->fIsMcPi0Electron && candM->fIsMcPi0Electron && candP->fMcMotherId == candM->fMcMotherId);
-  Bool_t isEta    = (candP->fIsMcEtaElectron && candM->fIsMcEtaElectron && candP->fMcMotherId == candM->fMcMotherId);
-  Bool_t isGamma = (candP->fIsMcGammaElectron && candM->fIsMcGammaElectron && candP->fMcMotherId == candM->fMcMotherId);
-  Bool_t isBG    = (!isEta) && (!isGamma) && (!isPi0) && (!(candP->fIsMcSignalElectron || candM->fIsMcSignalElectron));
-  Bool_t isMismatch = (IsMismatch(candP) || IsMismatch(candM));
-
-  double weight = fWeight;
-
-  if (isSignal) fh_signal_pty[step]->Fill(parMc->fRapidity, parMc->fPt, weight);
-  if (isSignal) fh_signal_mom[step]->Fill(parMc->fMomentumMag, weight);
-  if (isSignal) fh_signal_minv[step]->Fill(parRec->fMinv, weight);
-  if (isSignal) fh_signal_minv_pt[step]->Fill(parRec->fMinv, parMc->fPt, weight);
-  if (isBG) fh_bg_minv[step]->Fill(parRec->fMinv);
+  // mo need to fill histograms for MC and Acc steps
+  if (step == ELmvmAnaStep::Mc || step == ELmvmAnaStep::Acc) return;
+  bool isMismatch = (LmvmUtils::IsMismatch(candP) || LmvmUtils::IsMismatch(candM));
+  ELmvmSrc src    = LmvmUtils::GetMcPairSrc(candP, candM);
+
+  fH.FillH1("hMinv", src, step, parRec.fMinv, fW);
+  fH.FillH2("hMinvPt", src, step, parRec.fMinv, parMc.fPt, fW);
+
   PairSource(candP, candM, step, parRec);
-  if (isPi0) fh_pi0_minv[step]->Fill(parRec->fMinv);
-  if (isEta) fh_eta_minv[step]->Fill(parRec->fMinv);
-  if (isPi0) fh_pi0_minv_pt[step]->Fill(parRec->fMinv, parMc->fPt);
-  if (isEta) fh_eta_minv_pt[step]->Fill(parRec->fMinv, parMc->fPt);
-  if (isGamma) fh_gamma_minv[step]->Fill(parRec->fMinv);
-  if (isBG && isMismatch) fh_bg_mismatch_minv[step]->Fill(parRec->fMinv);
-  if (isBG && !isMismatch) {
-    fh_bg_truematch_minv[step]->Fill(parRec->fMinv);
-    if (candP->fMcPdg == 11 && candM->fMcPdg == 11) fh_bg_truematch_el_minv[step]->Fill(parRec->fMinv);
-    if (candP->fMcPdg != 11 || candM->fMcPdg != 11) fh_bg_truematch_notel_minv[step]->Fill(parRec->fMinv);
+
+  if (src == ELmvmSrc::Signal) {
+    fH.FillH2("hPtYPairSignal", step, parMc.fRapidity, parMc.fPt, fW);
+    fH.FillH1("hMomPairSignal", step, parMc.fMomentumMag, fW);
+  }
+  if (src == ELmvmSrc::Bg) {
+    if (isMismatch) { fH.FillH1("hMinvBgMatch_mismatch", step, parRec.fMinv); }
+    else {
+      fH.FillH1("hMinvBgMatch_trueMatch", step, parRec.fMinv);
+      if (std::abs(candP.fMcPdg) == 11 && std::abs(candM.fMcPdg) == 11)
+        fH.FillH1("hMinvBgMatch_trueMatchEl", step, parRec.fMinv);
+      if (std::abs(candP.fMcPdg) != 11 || std::abs(candM.fMcPdg) != 11)
+        fH.FillH1("hMinvBgMatch_trueMatchNotEl", step, parRec.fMinv);
+    }
   }
 }
 
-void CbmAnaDielectronTask::SignalAndBgReco()
+void LmvmTask::SignalAndBgReco()
 {
   CheckGammaConvAndPi0();
-  CheckTopologyCut("ST", fSTCandidates, fh_stcut, fh_stcut_pion, fh_stcut_truepair, fCuts.fStCutAngle, fCuts.fStCutPP);
-  CheckTopologyCut("TT", fTTCandidates, fh_ttcut, fh_ttcut_pion, fh_ttcut_truepair, fCuts.fTtCutAngle, fCuts.fTtCutPP);
-  CheckTopologyCut("RT", fRTCandidates, fh_rtcut, fh_rtcut_pion, fh_rtcut_truepair, fCuts.fRtCutAngle, fCuts.fRtCutPP);
+  CheckTopologyCut(ELmvmTopologyCut::ST, "hStCut");
+  CheckTopologyCut(ELmvmTopologyCut::TT, "hTtCut");
+  CheckTopologyCut(ELmvmTopologyCut::RT, "hRtCut");
   if (fUseMvd) {
-    CheckClosestMvdHit(1, fh_mvd1cut, fh_mvd1cut_qa);
-    CheckClosestMvdHit(2, fh_mvd2cut, fh_mvd2cut_qa);
+    CheckClosestMvdHit(1, "hMvdCut_1", "hMvdCutQa_1");
+    CheckClosestMvdHit(2, "hMvdCut_2", "hMvdCutQa_2");
   }
 
-  Int_t ncand = fCandidates.size();
-  for (Int_t i = 0; i < ncand; i++) {
-    Int_t pdg = 0;
-    if (fCandidates[i].fStsMcTrackId > 0) {
-      CbmMCTrack* mcTrack = (CbmMCTrack*) fMCTracks->At(fCandidates[i].fStsMcTrackId);
-      if (NULL != mcTrack) pdg = mcTrack->GetPdgCode();
+  for (const auto& cand : fCands) {
+    int pdg = 0;
+    if (cand.fStsMcTrackId > 0) {
+      CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(fMCTracks->At(cand.fStsMcTrackId));
+      if (mcTrack != nullptr) pdg = mcTrack->GetPdgCode();
+    }
+    for (auto step : fH.fAnaSteps) {
+      if (cand.IsCutTill(step)) TrackSource(cand, step, pdg);
     }
-
-    Bool_t isChi2Prim = (fCandidates[i].fChi2Prim < fCuts.fChiPrimCut);
-    Bool_t isEl       = (fCandidates[i].fIsElectron);
-    Bool_t isGammaCut = (!fCandidates[i].fIsGamma);
-    Bool_t isMvd1Cut  = fCandidates[i].fIsMvd1CutElectron;
-    Bool_t isMvd2Cut  = fCandidates[i].fIsMvd2CutElectron;
-    Bool_t isStCut    = (fCandidates[i].fIsStCutElectron);
-    Bool_t isRtCut    = (fCandidates[i].fIsRtCutElectron);
-    Bool_t isTtCut    = (fCandidates[i].fIsTtCutElectron);
-    Bool_t isPtCut    = (fCandidates[i].fMomentum.Perp() > fCuts.fPtCut);
-    if (!fUseMvd) isMvd1Cut = true;
-    if (!fUseMvd) isMvd2Cut = true;
-
-    TrackSource(&fCandidates[i], kReco, pdg);
-    if (isChi2Prim) TrackSource(&fCandidates[i], kChi2Prim, pdg);
-    if (isChi2Prim && isEl) TrackSource(&fCandidates[i], kElId, pdg);
-    if (isChi2Prim && isEl && isGammaCut) TrackSource(&fCandidates[i], kGammaCut, pdg);
-    if (isChi2Prim && isEl && isGammaCut && isMvd1Cut) TrackSource(&fCandidates[i], kMvd1Cut, pdg);
-    if (isChi2Prim && isEl && isGammaCut && isMvd1Cut && isMvd2Cut) TrackSource(&fCandidates[i], kMvd2Cut, pdg);
-    if (isChi2Prim && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut)
-      TrackSource(&fCandidates[i], kStCut, pdg);
-    if (isChi2Prim && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut)
-      TrackSource(&fCandidates[i], kRtCut, pdg);
-    if (isChi2Prim && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut)
-      TrackSource(&fCandidates[i], kTtCut, pdg);
-    if (isChi2Prim && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut && isPtCut)
-      TrackSource(&fCandidates[i], kPtCut, pdg);
   }
 
-  for (Int_t iP = 0; iP < ncand; iP++) {
-    if (fCandidates[iP].fCharge < 0) continue;
-    CbmMCTrack* mctrackP = NULL;
-    if (fCandidates[iP].fStsMcTrackId >= 0) mctrackP = (CbmMCTrack*) fMCTracks->At(fCandidates[iP].fStsMcTrackId);
-    for (Int_t iM = 0; iM < ncand; iM++) {
-      if (fCandidates[iM].fCharge > 0) continue;
-      CbmMCTrack* mctrackM = NULL;
-      if (fCandidates[iM].fStsMcTrackId >= 0) mctrackM = (CbmMCTrack*) fMCTracks->At(fCandidates[iM].fStsMcTrackId);
-      if (iM == iP) continue;
-
-      CbmLmvmKinematicParams pMC;
-      if (mctrackP != NULL && mctrackM != NULL)
-        pMC = CbmLmvmKinematicParams::KinematicParamsWithMcTracks(mctrackP, mctrackM);
-
-      CbmLmvmKinematicParams pRec =
-        CbmLmvmKinematicParams::KinematicParamsWithCandidates(&fCandidates[iP], &fCandidates[iM]);
-
-      Bool_t isChiPrimary =
-        (fCandidates[iP].fChi2Prim < fCuts.fChiPrimCut && fCandidates[iM].fChi2Prim < fCuts.fChiPrimCut);
-      Bool_t isEl       = (fCandidates[iP].fIsElectron && fCandidates[iM].fIsElectron);
-      Bool_t isGammaCut = (!fCandidates[iP].fIsGamma && !fCandidates[iM].fIsGamma);
-      Bool_t isStCut    = (fCandidates[iP].fIsStCutElectron && fCandidates[iM].fIsStCutElectron);
-      Bool_t isRtCut    = (fCandidates[iP].fIsRtCutElectron && fCandidates[iM].fIsRtCutElectron);
-      Bool_t isTtCut    = (fCandidates[iP].fIsTtCutElectron && fCandidates[iM].fIsTtCutElectron);
-      Bool_t isPtCut =
-        (fCandidates[iP].fMomentum.Perp() > fCuts.fPtCut && fCandidates[iM].fMomentum.Perp() > fCuts.fPtCut);
-      //            Bool_t isAngleCut = (pRec.fAngle > fCuts.fAngleCut);
-      Bool_t isMvd1Cut = (fCandidates[iP].fIsMvd1CutElectron && fCandidates[iM].fIsMvd1CutElectron);
-      Bool_t isMvd2Cut = (fCandidates[iP].fIsMvd2CutElectron && fCandidates[iM].fIsMvd2CutElectron);
-      if (!fUseMvd) isMvd1Cut = true;
-      if (!fUseMvd) isMvd2Cut = true;
-
-      FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kReco);
-      if (isChiPrimary) { FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kChi2Prim); }
-      if (isChiPrimary && isEl) { FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kElId); }
-      if (isChiPrimary && isEl && isGammaCut) {
-        FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kGammaCut);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut) {
-        FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kMvd1Cut);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut) {
-        FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kMvd2Cut);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut) {
-        FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kStCut);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut) {
-        FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kRtCut);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut) {
-        FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kTtCut);
-      }
-      if (isChiPrimary && isEl && isGammaCut && isMvd1Cut && isMvd2Cut && isStCut && isRtCut && isTtCut && isPtCut) {
-        FillPairHists(&fCandidates[iP], &fCandidates[iM], &pMC, &pRec, kPtCut);
+  for (const auto& candP : fCands) {
+    if (candP.fCharge < 0) continue;
+    CbmMCTrack* mctrackP =
+      (candP.fStsMcTrackId >= 0) ? static_cast<CbmMCTrack*>(fMCTracks->At(candP.fStsMcTrackId)) : nullptr;
+    for (const auto& candM : fCands) {
+      if (candM.fCharge > 0) continue;
+      CbmMCTrack* mctrackM =
+        (candM.fStsMcTrackId >= 0) ? static_cast<CbmMCTrack*>(fMCTracks->At(candM.fStsMcTrackId)) : nullptr;
+
+      CbmLmvmKinematicParams pMC  = CbmLmvmKinematicParams::Create(mctrackP, mctrackM);
+      CbmLmvmKinematicParams pRec = CbmLmvmKinematicParams::Create(&candP, &candM);
+
+      for (auto step : fH.fAnaSteps) {
+        if (candP.IsCutTill(step) && candM.IsCutTill(step)) FillPairHists(candP, candM, pMC, pRec, step);
       }
-    }  // iM
-  }    // iP
+    }
+  }
 }
 
-void CbmAnaDielectronTask::CheckGammaConvAndPi0()
+void LmvmTask::CheckGammaConvAndPi0()
 {
-  Int_t ncand = fCandidates.size();
-  for (Int_t iP = 0; iP < ncand; iP++) {
-    if (fCandidates[iP].fCharge < 0) continue;
-    for (Int_t iM = 0; iM < ncand; iM++) {
-      if (fCandidates[iM].fCharge > 0) continue;
-      if (iM == iP) continue;
-      if ((fCandidates[iP].fChi2Prim < fCuts.fChiPrimCut && fCandidates[iP].fIsElectron)
-          && (fCandidates[iM].fChi2Prim < fCuts.fChiPrimCut && fCandidates[iM].fIsElectron)) {
-        CbmLmvmKinematicParams pRec =
-          CbmLmvmKinematicParams::KinematicParamsWithCandidates(&fCandidates[iP], &fCandidates[iM]);
-        if (pRec.fMinv < fCuts.fGammaCut) {
-          fCandidates[iM].fIsGamma = true;
-          fCandidates[iP].fIsGamma = true;
+  for (auto& candP : fCands) {
+    if (candP.fCharge < 0) continue;
+    for (auto& candM : fCands) {
+      if (candM.fCharge > 0) continue;
+      if (candP.IsCutTill(ELmvmAnaStep::ElId) && candM.IsCutTill(ELmvmAnaStep::ElId)) {
+        CbmLmvmKinematicParams pRec = CbmLmvmKinematicParams::Create(&candP, &candM);
+        if (fCuts.IsGammaCutOk(pRec.fMinv)) {
+          candM.fIsGammaCut = true;
+          candP.fIsGammaCut = true;
         }
       }
     }
   }
 }
 
-void CbmAnaDielectronTask::CheckTopologyCut(const string& cutName, const vector<CbmLmvmCandidate>& cutCandidates,
-                                            const vector<TH2D*>& hcut, const vector<TH2D*>& hcutPion,
-                                            const vector<TH2D*>& hcutTruepair, Double_t angleCut, Double_t ppCut)
+void LmvmTask::CheckTopologyCut(ELmvmTopologyCut cut, const string& name)
 {
-  vector<Double_t> angles, mom, candInd;
-  Int_t nCand    = fCandidates.size();
-  Int_t nCandTot = fCandidatesTotal.size();
-  Int_t nCutCand = cutCandidates.size();
-
-  int nJump = 0;
-  for (int i = 0; i < nCandTot; i++) {
-    if (fCandidatesTotal[i].fEventNumber != fEventNumber) nJump++;
-    if (fCandidatesTotal[i].fEventNumber == fEventNumber) {
-      cout << "nJump = " << nJump << endl;
-      break;
-    }
+  string hcut         = name + "_all";
+  string hcutPion     = name + "_pion";
+  string hcutTruePair = name + "_truePair";
+
+  vector<LmvmDataAngMomInd> dataV;
+
+  vector<LmvmCand>& tpCands = fSTCands;
+  if (cut == ELmvmTopologyCut::ST) { tpCands = fSTCands; }
+  else if (cut == ELmvmTopologyCut::RT) {
+    tpCands = fRTCands;
+  }
+  else if (cut == ELmvmTopologyCut::TT) {
+    tpCands = fTTCands;
+  }
+  else {
+    LOG(error) << "LmvmTask::CheckTopologyCut cut is not defined.";
   }
 
-  for (Int_t iP = 0; iP < nCand; iP++) {
-    if (fCandidates[iP].fChi2Prim < fCuts.fChiPrimCut && fCandidates[iP].fIsElectron) {
-      angles.clear();
-      mom.clear();
-      candInd.clear();
-      for (Int_t iM = 0; iM < nCutCand; iM++) {
+  for (auto& cand : fCands) {
+    if (cand.IsCutTill(ELmvmAnaStep::ElId)) {
+      dataV.clear();
+      for (size_t iM = 0; iM < tpCands.size(); iM++) {
         // different charges, charge iM != charge iP
-        if (cutCandidates[iM].fCharge != fCandidates[iP].fCharge) {
-          CbmLmvmKinematicParams pRec =
-            CbmLmvmKinematicParams::KinematicParamsWithCandidates(&fCandidates[iP], &cutCandidates[iM]);
-          angles.push_back(pRec.fAngle);
-          mom.push_back(cutCandidates[iM].fMomentum.Mag());
-          candInd.push_back(iM);
-        }  // if
-      }    // iM
+        if (tpCands[iM].fCharge != cand.fCharge) {
+          CbmLmvmKinematicParams pRec = CbmLmvmKinematicParams::Create(&cand, &tpCands[iM]);
+          dataV.emplace_back(pRec.fAngle, tpCands[iM].fMomentum.Mag(), iM);
+        }
+      }
       //find min opening angle
-      Double_t minAng = 360.;
-      Int_t minInd    = -1;
-      for (UInt_t i = 0; i < angles.size(); i++) {
-        if (minAng > angles[i]) {
-          minAng = angles[i];
+      double minAng = 360.;
+      int minInd    = -1;
+      for (size_t i = 0; i < dataV.size(); i++) {
+        if (minAng > dataV[i].fAngle) {
+          minAng = dataV[i].fAngle;
           minInd = i;
         }
       }
       if (minInd == -1) {
-        if (cutName == "TT") {
-          fCandidates[iP].fIsTtCutElectron              = true;
-          fCandidatesTotal[iP + nJump].fIsTtCutElectron = true;
-        }
-        if (cutName == "ST") {
-          fCandidates[iP].fIsStCutElectron              = true;
-          fCandidatesTotal[iP + nJump].fIsStCutElectron = true;
-        }
-        if (cutName == "RT") {
-          fCandidates[iP].fIsRtCutElectron              = true;
-          fCandidatesTotal[iP + nJump].fIsRtCutElectron = true;
-        }
+        cand.SetIsTopologyCutElectron(cut, true);
         continue;
       }
-      Double_t sqrt_mom = TMath::Sqrt(fCandidates[iP].fMomentum.Mag() * mom[minInd]);
-      Double_t val      = -1. * (angleCut / ppCut) * sqrt_mom + angleCut;
-      if (!(sqrt_mom < ppCut && val > minAng)) {
-        if (cutName == "TT") {
-          fCandidates[iP].fIsTtCutElectron              = true;
-          fCandidatesTotal[iP + nJump].fIsTtCutElectron = true;
-        }
-        if (cutName == "ST") {
-          fCandidates[iP].fIsStCutElectron              = true;
-          fCandidatesTotal[iP + nJump].fIsStCutElectron = true;
-        }
-        if (cutName == "RT") {
-          fCandidates[iP].fIsRtCutElectron              = true;
-          fCandidatesTotal[iP + nJump].fIsRtCutElectron = true;
-        }
-      }
+      bool isCut = fCuts.IsTopologyCutOk(cut, cand.fMomentum.Mag(), dataV[minInd].fMom, minAng);
+      cand.SetIsTopologyCutElectron(cut, isCut);
 
-      int stsInd = cutCandidates[candInd[minInd]].fStsInd;
+      // histogramms
+      double sqrt_mom = TMath::Sqrt(cand.fMomentum.Mag() * dataV[minInd].fMom);
+      int cutCandInd  = dataV[minInd].fInd;
+      int stsInd      = tpCands[cutCandInd].fStsInd;
       if (stsInd < 0) continue;
-      int pdg      = TMath::Abs(cutCandidates[candInd[minInd]].fMcPdg);
-      int motherId = cutCandidates[candInd[minInd]].fMcMotherId;
+      int pdgAbs   = std::abs(tpCands[cutCandInd].fMcPdg);
+      int motherId = tpCands[cutCandInd].fMcMotherId;
 
-      if (fCandidates[iP].fIsMcSignalElectron) {
-        hcut[kSignal]->Fill(sqrt_mom, minAng, fWeight);
-        if (pdg == 211) hcutPion[kSignal]->Fill(sqrt_mom, minAng, fWeight);
-        if (motherId == fCandidates[iP].fMcMotherId) hcutTruepair[kSignal]->Fill(sqrt_mom, minAng, fWeight);
+      fH.FillH2(hcut, cand.fMcSrc, sqrt_mom, minAng, fW);
+      if (pdgAbs == 211) fH.FillH2(hcutPion, cand.fMcSrc, sqrt_mom, minAng, fW);
+      if (cand.IsMcSignal()) {
+        if (motherId == cand.fMcMotherId) fH.FillH2(hcutTruePair, cand.fMcSrc, sqrt_mom, minAng, fW);
       }
       else {
-        hcut[kBg]->Fill(sqrt_mom, minAng);
-        if (pdg == 211) hcutPion[kBg]->Fill(sqrt_mom, minAng);
-        ;
-        if (motherId != -1 && motherId == fCandidates[iP].fMcMotherId) hcutTruepair[kBg]->Fill(sqrt_mom, minAng);
-        ;
-      }
-      if (fCandidates[iP].fIsMcPi0Electron) {
-        hcut[kPi0]->Fill(sqrt_mom, minAng);
-        if (pdg == 211) hcutPion[kPi0]->Fill(sqrt_mom, minAng);
-        ;
-        if (motherId != -1 && motherId == fCandidates[iP].fMcMotherId) hcutTruepair[kPi0]->Fill(sqrt_mom, minAng);
-        ;
-      }
-      if (fCandidates[iP].fIsMcGammaElectron) {
-        hcut[kGamma]->Fill(sqrt_mom, minAng);
-        if (pdg == 211) hcutPion[kGamma]->Fill(sqrt_mom, minAng);
-        ;
-        if (motherId != -1 && motherId == fCandidates[iP].fMcMotherId) hcutTruepair[kGamma]->Fill(sqrt_mom, minAng);
-        ;
+        if (motherId != -1 && motherId == cand.fMcMotherId) fH.FillH2(hcutTruePair, cand.fMcSrc, sqrt_mom, minAng, fW);
       }
-    }  //if electron
-  }    //iP
-  /*
-    cout << "Opening angles between cand and cutCand: " << endl;
-    for(int i = 0; i < angles.size(); i++){
-        cout << angles[i] << ", ";
     }
-    cout << endl;
-*/
+  }
 }
 
-void CbmAnaDielectronTask::CalculateNofTopologyPairs(TH1D* h_nof_pairs, const string& source)
+void LmvmTask::CalculateNofTopologyPairs(const string& name, ELmvmSrc src)
 {
-  UInt_t nCand = fCandidates.size();
-  vector<bool> isAdded;
-  isAdded.resize(nCand);
-  for (UInt_t iP = 0; iP < nCand; iP++) {
-    isAdded[iP] = false;
-  }
-  for (UInt_t iP = 0; iP < nCand; iP++) {
-    if (fCandidates[iP].fMcMotherId == -1) continue;
-    if (source == "pi0" && !fCandidates[iP].fIsMcPi0Electron) continue;
-    if (source == "gamma" && !fCandidates[iP].fIsMcGammaElectron) continue;
-
-    if (!(fCandidates[iP].fChi2Prim < fCuts.fChiPrimCut && fCandidates[iP].fIsElectron)) continue;
-
-    if (isAdded[iP]) continue;
-
-    for (UInt_t iM = 0; iM < fSTCandidates.size(); iM++) {
-      if (fSTCandidates[iM].fMcMotherId == fCandidates[iP].fMcMotherId) {
-        h_nof_pairs->Fill(4.5);
-        isAdded[iP] = true;
-        break;
-      }
-    }
-    if (isAdded[iP]) continue;
-
-    for (UInt_t iM = 0; iM < fRTCandidates.size(); iM++) {
-      if (fRTCandidates[iM].fMcMotherId == fCandidates[iP].fMcMotherId) {
-        h_nof_pairs->Fill(5.5);
-        isAdded[iP] = true;
-        break;
+  size_t nCand = fCands.size();
+  for (size_t iP = 0; iP < nCand; iP++) {
+    const LmvmCand& cand = fCands[iP];
+    if (cand.fMcMotherId == -1) continue;
+    if (src != cand.fMcSrc) continue;
+    if (!cand.IsCutTill(ELmvmAnaStep::ElId)) continue;
+
+    bool isAdded = false;
+
+    // 3 topology cuts: ST, RT, TT
+    for (int i = 0; i < 3; i++) {
+      if (isAdded) continue;
+      vector<LmvmCand>& cands = fSTCands;
+      double binNum           = 4.5;
+      if (i == 1) {
+        cands  = fRTCands;
+        binNum = 5.5;
+      }
+      else if (i == 2) {
+        cands  = fTTCands;
+        binNum = 6.5;
+      }
+      for (const auto& candT : cands) {
+        if (candT.fMcMotherId == cand.fMcMotherId) {
+          fH.FillH1(name, binNum);
+          isAdded = true;
+          break;
+        }
       }
     }
-    if (isAdded[iP]) continue;
+    if (isAdded) continue;
 
-    for (UInt_t iM = 0; iM < fTTCandidates.size(); iM++) {
-      if (fTTCandidates[iM].fMcMotherId == fCandidates[iP].fMcMotherId) {
-        h_nof_pairs->Fill(6.5);
-        isAdded[iP] = true;
-        break;
-      }
-    }
-    if (isAdded[iP]) continue;
-
-    for (UInt_t iM = 0; iM < fCandidates.size(); iM++) {
-      if (iM != iP && fCandidates[iM].fMcMotherId == fCandidates[iP].fMcMotherId
-          && fCandidates[iM].fChi2Prim < fCuts.fChiPrimCut && fCandidates[iM].fIsElectron) {
-        h_nof_pairs->Fill(7.5);
-        isAdded[iP] = true;
-        isAdded[iM] = true;
+    for (size_t iM = 0; iM < fCands.size(); iM++) {
+      if (iM != iP && fCands[iM].fMcMotherId == cand.fMcMotherId && fCands[iM].IsCutTill(ELmvmAnaStep::ElId)) {
+        fH.FillH1(name, 7.5);
+        isAdded = true;
         break;
       }
     }
-
-    if (isAdded[iP]) continue;
-    Int_t nofPointsSts = 0;
-    Int_t nofMcTracks  = fMCTracks->GetEntriesFast();
-    for (Int_t iMCTrack = 0; iMCTrack < nofMcTracks; iMCTrack++) {
-      const CbmMCTrack* mcTrack = static_cast<const CbmMCTrack*>(fMCTracks->At(iMCTrack));
-      if (mcTrack->GetMotherId() != fCandidates[iP].fMcMotherId) continue;
-      if (iMCTrack == fCandidates[iP].fStsMcTrackId) continue;
-
-      if (!CbmLitMCTrackCreator::Instance()->TrackExists(FairRun::Instance()->GetEventHeader()->GetMCEntryNumber(),
-                                                         iMCTrack))
-        continue;
-      const CbmLitMCTrack& litMCTrack =
-        CbmLitMCTrackCreator::Instance()->GetTrack(FairRun::Instance()->GetEventHeader()->GetMCEntryNumber(), iMCTrack);
-      nofPointsSts = litMCTrack.GetNofPointsInDifferentStations(ECbmModuleId::kSts);
+    if (isAdded) continue;
+
+    int nofStsPoints = 0;
+    int nofMcTracks  = fMCTracks->GetEntriesFast();
+    for (int iMc = 0; iMc < nofMcTracks; iMc++) {
+      const CbmMCTrack* mcTrack = static_cast<const CbmMCTrack*>(fMCTracks->At(iMc));
+      if (mcTrack == nullptr || mcTrack->GetMotherId() != cand.fMcMotherId || iMc == cand.fStsMcTrackId) continue;
+
+      int eventId = FairRun::Instance()->GetEventHeader()->GetMCEntryNumber();
+      if (!CbmLitMCTrackCreator::Instance()->TrackExists(eventId, iMc)) continue;
+      const CbmLitMCTrack& litMCTrack = CbmLitMCTrackCreator::Instance()->GetTrack(eventId, iMc);
+      nofStsPoints                    = litMCTrack.GetNofPointsInDifferentStations(ECbmModuleId::kSts);
       break;
     }
-    if (nofPointsSts == 0) h_nof_pairs->Fill(0.5);
-    if (nofPointsSts >= 1 && nofPointsSts <= 3) h_nof_pairs->Fill(1.5);
-    if (nofPointsSts >= 4 && nofPointsSts <= 5) h_nof_pairs->Fill(2.5);
-    if (nofPointsSts >= 6) h_nof_pairs->Fill(3.5);
-  }
-}
-
-Bool_t CbmAnaDielectronTask::IsMismatch(CbmLmvmCandidate* cand)
-{
-  bool isTrdOk = (fUseTrd) ? (cand->fStsMcTrackId == cand->fTrdMcTrackId) : true;
-  if (cand->fStsMcTrackId == cand->fRichMcTrackId && isTrdOk && cand->fStsMcTrackId == cand->fTofMcTrackId
-      && cand->fStsMcTrackId != -1)
-    return false;
-  return true;
-}
-
-Bool_t CbmAnaDielectronTask::IsGhost(CbmLmvmCandidate* cand)
-{
-  if (cand->fStsMcTrackId == -1 || cand->fRichMcTrackId == -1 || cand->fTrdMcTrackId == -1 || cand->fTofMcTrackId == -1)
-    return true;
-  return false;
-}
-
-void CbmAnaDielectronTask::IsElectron(Int_t globalTrackIndex, Double_t momentum, CbmLmvmCandidate* cand)
-{
-  if (fPionMisidLevel < 0.) {
-    Bool_t richEl  = CbmLitGlobalElectronId::GetInstance().IsRichElectron(globalTrackIndex, momentum);
-    cand->fRichAnn = CbmLitGlobalElectronId::GetInstance().GetRichAnn(globalTrackIndex, momentum);
-
-    Bool_t trdEl  = CbmLitGlobalElectronId::GetInstance().IsTrdElectron(globalTrackIndex, momentum);
-    cand->fTrdAnn = CbmLitGlobalElectronId::GetInstance().GetTrdAnn(globalTrackIndex, momentum);
-
-    Bool_t tofEl = CbmLitGlobalElectronId::GetInstance().IsTofElectron(globalTrackIndex, momentum);
-    //cout << "tof momentum: " << momentum << endl;
-    Bool_t momCut = (fCuts.fMomentumCut > 0.) ? (momentum < fCuts.fMomentumCut) : true;
-
-    if (richEl && trdEl && tofEl && momCut) { cand->fIsElectron = true; }
-    else {
-      cand->fIsElectron = false;
-    }
-  }
-  else {
-    // PID using MC information, a certain pi supression level can be set
-    if (cand->fStsMcTrackId < 0 || cand->fStsMcTrackId >= fMCTracks->GetEntries()) { cand->fIsElectron = false; }
-    else {
-      CbmMCTrack* mcTrack = (CbmMCTrack*) fMCTracks->At(cand->fStsMcTrackId);
-      Int_t pdg           = mcTrack->GetPdgCode();
-      if (pdg == 11 || pdg == -11) { cand->fIsElectron = true; }
-      else {
-        Double_t r = fRandom3->Rndm();
-        if (r < fPionMisidLevel) { cand->fIsElectron = true; }
-        else {
-          cand->fIsElectron = false;
-        }
-      }
-    }
+    if (nofStsPoints == 0) fH.FillH1(name, 0.5);
+    if (nofStsPoints >= 1 && nofStsPoints <= 3) fH.FillH1(name, 1.5);
+    if (nofStsPoints >= 4 && nofStsPoints <= 5) fH.FillH1(name, 2.5);
+    if (nofStsPoints >= 6) fH.FillH1(name, 3.5);
   }
 }
 
-void CbmAnaDielectronTask::DifferenceSignalAndBg()
+void LmvmTask::DifferenceSignalAndBg()
 {
-  //ID cuts
-  Int_t nCand = fCandidates.size();
-  for (Int_t i = 0; i < nCand; i++) {
-    if (fCandidates[i].fIsMcSignalElectron) { fh_chi2prim[kSignal]->Fill(fCandidates[i].fChi2Prim, fWeight); }
-    else {
-      fh_chi2prim[kBg]->Fill(fCandidates[i].fChi2Prim);
-    }
-    if (fCandidates[i].fIsMcGammaElectron) { fh_chi2prim[kGamma]->Fill(fCandidates[i].fChi2Prim); }
-    if (fCandidates[i].fIsMcPi0Electron) fh_chi2prim[kPi0]->Fill(fCandidates[i].fChi2Prim);
+  for (const auto& cand : fCands) {
+    fH.FillH1("hChi2PrimVertex", cand.fMcSrc, cand.fChi2Prim, fW);
 
-    if (fCandidates[i].fChi2Prim > fCuts.fChiPrimCut) continue;
+    if (!cand.fIsChi2Prim) continue;
+    fH.FillH1("hRichAnn", cand.fMcSrc, cand.fRichAnn, fW);
+    fH.FillH1("hTrdAnn", cand.fMcSrc, cand.fTrdAnn, fW);
+    fH.FillH2("hTofM2", cand.fMcSrc, cand.fMomentum.Mag(), cand.fMass2, fW);
 
-    if (fCandidates[i].fIsMcSignalElectron) {
-      fh_richann[kSignal]->Fill(fCandidates[i].fRichAnn, fWeight);
-      fh_trdann[kSignal]->Fill(fCandidates[i].fTrdAnn, fWeight);
-      fh_tofm2[kSignal]->Fill(fCandidates[i].fMomentum.Mag(), fCandidates[i].fMass2, fWeight);
-      //cout << "tof m2: " << fCandidates[i].fMass2 << endl;
-      //cout << "Signal tofm2: " << fCandidates[i].fMass2 << ", fWeight: " << fWeight << endl;
-    }
-    else {
-      fh_richann[kBg]->Fill(fCandidates[i].fRichAnn);
-      fh_trdann[kBg]->Fill(fCandidates[i].fTrdAnn);
-      fh_tofm2[kBg]->Fill(fCandidates[i].fMomentum.Mag(), fCandidates[i].fMass2);
-      //cout << "Bg tofm2: " << fCandidates[i].fMass2 << endl;
-    }
-    if (fCandidates[i].fIsMcGammaElectron) {
-      fh_richann[kGamma]->Fill(fCandidates[i].fRichAnn);
-      fh_trdann[kGamma]->Fill(fCandidates[i].fTrdAnn);
-      fh_tofm2[kGamma]->Fill(fCandidates[i].fMomentum.Mag(), fCandidates[i].fMass2);
-      //cout << "Gamma tofm2: " << fCandidates[i].fMass2 << endl;
-    }
-    if (fCandidates[i].fIsMcPi0Electron) {
-      fh_richann[kPi0]->Fill(fCandidates[i].fRichAnn);
-      fh_trdann[kPi0]->Fill(fCandidates[i].fTrdAnn);
-      fh_tofm2[kPi0]->Fill(fCandidates[i].fMomentum.Mag(), fCandidates[i].fMass2);
-      //cout << "Pi0Elec tofm2: " << fCandidates[i].fMass2 << endl;
-    }
-  }  // loop over candidates
+    if (!cand.IsCutTill(ELmvmAnaStep::ElId)) continue;
+    //fH.FillSourceH1("hPt", cand.fMcSrc, cand.fMomentum.Perp(), fW);
+    //fH.FillSourceH1("hMom", cand.fMcSrc, cand.fMomentum.Mag(), fW);
+    fH.FillH1("hChi2Sts", cand.fMcSrc, cand.fChi2sts, fW);
 
-  for (Int_t i = 0; i < nCand; i++) {
-    if (!(fCandidates[i].fChi2Prim < fCuts.fChiPrimCut && fCandidates[i].fIsElectron)) continue;
+    CbmStsTrack* stsTrack = static_cast<CbmStsTrack*>(fStsTracks->At(cand.fStsInd));
+    if (stsTrack == nullptr) continue;
+    fH.FillH1("hNofStsHits", cand.fMcSrc, stsTrack->GetNofHits(), fW);
 
-    if (fCandidates[i].fIsMcSignalElectron) {
-      fh_pt[kSignal]->Fill(fCandidates[i].fMomentum.Perp(), fWeight);
-      fh_mom[kSignal]->Fill(fCandidates[i].fMomentum.Mag(), fWeight);
-      fh_chi2sts[kSignal]->Fill(fCandidates[i].fChi2sts, fWeight);
-    }
-    else {
-      fh_pt[kBg]->Fill(fCandidates[i].fMomentum.Perp());
-      fh_mom[kBg]->Fill(fCandidates[i].fMomentum.Mag());
-      fh_chi2sts[kBg]->Fill(fCandidates[i].fChi2sts);
-    }
-    if (fCandidates[i].fIsMcGammaElectron) {
-      fh_pt[kGamma]->Fill(fCandidates[i].fMomentum.Perp());
-      fh_mom[kGamma]->Fill(fCandidates[i].fMomentum.Mag());
-      fh_chi2sts[kGamma]->Fill(fCandidates[i].fChi2sts);
-    }
-    if (fCandidates[i].fIsMcPi0Electron) {
-      fh_pt[kPi0]->Fill(fCandidates[i].fMomentum.Perp());
-      fh_mom[kPi0]->Fill(fCandidates[i].fMomentum.Mag());
-      fh_chi2sts[kPi0]->Fill(fCandidates[i].fChi2sts);
-    }
-  }  // loop over candidates
-
-  if (fUseMvd) {
-    //number of STS and MVD hits and distributions for the MVD
-    for (int i = 0; i < nCand; i++) {
-      if (!(fCandidates[i].fChi2Prim < fCuts.fChiPrimCut && fCandidates[i].fIsElectron)) continue;
-
-      CbmStsTrack* track = (CbmStsTrack*) fStsTracks->At(fCandidates[i].fStsInd);
-      if (NULL == track) continue;
-      int nofMvdHits = track->GetNofMvdHits();
-      int nofStsHits = track->GetNofHits();
+    if (fUseMvd) {
       double mvd1x = 0., mvd1y = 0., mvd2x = 0., mvd2y = 0.;
-
-      for (Int_t ith = 0; ith < nofMvdHits; ith++) {
-        Int_t iHit       = track->GetMvdHitIndex(ith);
-        CbmMvdHit* pmh   = (CbmMvdHit*) fMvdHits->At(iHit);
-        Int_t stationNum = pmh->GetStationNr();
-        if (NULL == pmh) continue;
-        if (stationNum == 1) {
-          mvd1x = pmh->GetX();
-          mvd1y = pmh->GetY();
+      for (int iM = 0; iM < stsTrack->GetNofMvdHits(); iM++) {
+        CbmMvdHit* mvdHit = static_cast<CbmMvdHit*>(fMvdHits->At(stsTrack->GetMvdHitIndex(iM)));
+        if (mvdHit == nullptr) continue;
+        if (mvdHit->GetStationNr() == 1) {
+          mvd1x = mvdHit->GetX();
+          mvd1y = mvdHit->GetY();
         }
-        else if (stationNum == 2) {
-          mvd2x = pmh->GetX();
-          mvd2y = pmh->GetY();
+        else if (mvdHit->GetStationNr() == 2) {
+          mvd2x = mvdHit->GetX();
+          mvd2y = mvdHit->GetY();
         }
       }
       double mvd1r = sqrt(mvd1x * mvd1x + mvd1y * mvd1y);
       double mvd2r = sqrt(mvd2x * mvd2x + mvd2y * mvd2y);
 
-      if (fCandidates[i].fIsMcSignalElectron) {
-        fh_nofMvdHits[kSignal]->Fill(nofMvdHits, fWeight);
-        fh_nofStsHits[kSignal]->Fill(nofStsHits, fWeight);
-        fh_mvd1xy[kSignal]->Fill(mvd1x, mvd1y, fWeight);
-        fh_mvd1r[kSignal]->Fill(mvd1r, fWeight);
-        fh_mvd2xy[kSignal]->Fill(mvd2x, mvd2y, fWeight);
-        fh_mvd2r[kSignal]->Fill(mvd2r, fWeight);
-      }
-      else {
-        fh_nofMvdHits[kBg]->Fill(nofMvdHits);
-        fh_nofStsHits[kBg]->Fill(nofStsHits);
-        fh_mvd1xy[kBg]->Fill(mvd1x, mvd1y);
-        fh_mvd1r[kBg]->Fill(mvd1r);
-        fh_mvd2xy[kBg]->Fill(mvd2x, mvd2y);
-        fh_mvd2r[kBg]->Fill(mvd2r);
-      }
-      if (fCandidates[i].fIsMcGammaElectron) {
-        fh_nofMvdHits[kGamma]->Fill(nofMvdHits);
-        fh_nofStsHits[kGamma]->Fill(nofStsHits);
-        fh_mvd1xy[kGamma]->Fill(mvd1x, mvd1y);
-        fh_mvd1r[kGamma]->Fill(mvd1r);
-        fh_mvd2xy[kGamma]->Fill(mvd2x, mvd2y);
-        fh_mvd2r[kGamma]->Fill(mvd2r);
-      }
-      if (fCandidates[i].fIsMcPi0Electron) {
-        fh_nofMvdHits[kPi0]->Fill(nofMvdHits);
-        fh_nofStsHits[kPi0]->Fill(nofStsHits);
-        fh_mvd1xy[kPi0]->Fill(mvd1x, mvd1y);
-        fh_mvd1r[kPi0]->Fill(mvd1r);
-        fh_mvd2xy[kPi0]->Fill(mvd2x, mvd2y);
-        fh_mvd2r[kPi0]->Fill(mvd2r);
-      }
+      fH.FillH1("hNofMvdHits", cand.fMcSrc, stsTrack->GetNofMvdHits(), fW);
+      fH.FillH2("hMvdXY_1", cand.fMcSrc, mvd1x, mvd1y, fW);
+      fH.FillH1("hMvdR_1", cand.fMcSrc, mvd1r, fW);
+      fH.FillH2("hMvdXY_2", cand.fMcSrc, mvd2x, mvd2y, fW);
+      fH.FillH1("hMvdR_2", cand.fMcSrc, mvd2r, fW);
     }
   }
 }
 
-void CbmAnaDielectronTask::CheckClosestMvdHit(Int_t mvdStationNum, vector<TH2D*>& hist, vector<TH1D*>& histQa)
+void LmvmTask::CheckClosestMvdHit(int mvdStationNum, const string& hist, const string& histQa)
 {
-  vector<float> mvdX;
-  vector<float> mvdY;
-  vector<int> mvdInd;
-  vector<float> candX;
-  vector<float> candY;
-  vector<int> candInd;
-
-  //   CbmKF *KF = CbmKF::Instance();
-
-  Int_t nMvdHit = fMvdHits->GetEntriesFast();
-  for (Int_t iHit = 0; iHit < nMvdHit; iHit++) {
-    CbmMvdHit* pmh = (CbmMvdHit*) fMvdHits->At(iHit);
-    if (NULL == pmh) continue;
-    Int_t stationNum = pmh->GetStationNr();
-    if (stationNum == mvdStationNum) {
-      mvdX.push_back(pmh->GetX());
-      mvdY.push_back(pmh->GetY());
-      mvdInd.push_back(iHit);
+  vector<LmvmDataXYInd> mvdV;
+  vector<LmvmDataXYInd> candV;
+
+  for (int iHit = 0; iHit < fMvdHits->GetEntriesFast(); iHit++) {
+    CbmMvdHit* mvdHit = static_cast<CbmMvdHit*>(fMvdHits->At(iHit));
+    if (mvdHit != nullptr && mvdHit->GetStationNr() == mvdStationNum) {
+      mvdV.emplace_back(mvdHit->GetX(), mvdHit->GetY(), iHit);
     }
   }
 
-  Int_t nCand = fCandidates.size();
-  for (Int_t i = 0; i < nCand; i++) {
-    if (fCandidates[i].fChi2Prim < fCuts.fChiPrimCut && fCandidates[i].fIsElectron) {
-      CbmStsTrack* track = (CbmStsTrack*) fStsTracks->At(fCandidates[i].fStsInd);
-      if (NULL == track) continue;
-      Int_t nhits = track->GetNofMvdHits();
-      for (Int_t ith = 0; ith < nhits; ith++) {
-        Int_t iHit       = track->GetMvdHitIndex(ith);
-        CbmMvdHit* pmh   = (CbmMvdHit*) fMvdHits->At(iHit);
-        Int_t stationNum = pmh->GetStationNr();
-        if (NULL == pmh) continue;
-        if (stationNum == mvdStationNum) {
-          candX.push_back(pmh->GetX());
-          candY.push_back(pmh->GetY());
-          candInd.push_back(i);
+  for (size_t iC = 0; iC < fCands.size(); iC++) {
+    if (fCands[iC].IsCutTill(ELmvmAnaStep::ElId)) {
+      CbmStsTrack* stsTrack = static_cast<CbmStsTrack*>(fStsTracks->At(fCands[iC].fStsInd));
+      if (stsTrack == nullptr) continue;
+      for (int iM = 0; iM < stsTrack->GetNofMvdHits(); iM++) {
+        CbmMvdHit* candHit = static_cast<CbmMvdHit*>(fMvdHits->At(stsTrack->GetMvdHitIndex(iM)));
+        if (candHit != nullptr && candHit->GetStationNr() == mvdStationNum) {
+          candV.emplace_back(candHit->GetX(), candHit->GetY(), iC);
         }
       }
     }
-  }  // iCand
-
-  for (UInt_t iT = 0; iT < candInd.size(); iT++) {
-    Float_t mind    = 9999999.;
-    Int_t minMvdInd = -1;
-    for (UInt_t iH = 0; iH < mvdX.size(); iH++) {
-      Float_t dx = mvdX[iH] - candX[iT];
-      Float_t dy = mvdY[iH] - candY[iT];
-      Float_t d2 = dx * dx + dy * dy;
+  }
+
+  for (size_t iC = 0; iC < candV.size(); iC++) {
+    LmvmCand& cand = fCands[candV[iC].fInd];
+    double minD    = 9999999.;
+    int minMvdInd  = -1;
+    for (size_t iH = 0; iH < mvdV.size(); iH++) {
+      double d2 = LmvmUtils::Distance2(mvdV[iH].fX, mvdV[iH].fY, candV[iC].fX, candV[iC].fY);
       if (d2 < 1.e-9) continue;
-      if (d2 < mind) {
-        minMvdInd = mvdInd[iH];
-        mind      = d2;
+      if (d2 < minD) {
+        minMvdInd = mvdV[iH].fInd;
+        minD      = d2;
       }
-    }  // iHit
-    Double_t dmvd = sqrt(mind);
+    }
+    double dmvd = sqrt(minD);
 
     // Check MVD cut quality
     double bin               = -1.;
     const CbmMatch* hitMatch = static_cast<const CbmMatch*>(fMvdHitMatches->At(minMvdInd));
-    if (NULL != hitMatch) {
-      int mcMvdHitId   = hitMatch->GetMatchedLink().GetIndex();
-      CbmMCTrack* mct1 = (CbmMCTrack*) fMCTracks->At(mcMvdHitId);
+    if (hitMatch != nullptr) {
+      CbmMCTrack* mct1 = static_cast<CbmMCTrack*>(fMCTracks->At(hitMatch->GetMatchedLink().GetIndex()));
       int mcMvdHitPdg  = TMath::Abs(mct1->GetPdgCode());
       int mvdMotherId  = mct1->GetMotherId();
 
-      int stsMcTrackId = fCandidates[candInd[iT]].fStsMcTrackId;
-      int stsMotherId  = -2;
-      if (stsMcTrackId >= 0) {
-        CbmMCTrack* mct2 = (CbmMCTrack*) fMCTracks->At(stsMcTrackId);
-        stsMotherId      = mct2->GetMotherId();
+      int stsMotherId = -2;
+      if (cand.fStsMcTrackId >= 0) {
+        CbmMCTrack* mct2 = static_cast<CbmMCTrack*>(fMCTracks->At(cand.fStsMcTrackId));
+        stsMotherId      = (mct2 != nullptr) ? mct2->GetMotherId() : -2;
       }
 
-      //cout << mvdStationNum << " " << mvdMotherId << " " << stsMotherId << endl;
-      if (mvdMotherId != -1 && mvdMotherId == stsMotherId) {
-        bin = 0.5;  // correct assignment
-      }
-      else {
-        bin = 1.5;  // not correct assignment
-      }
-
-      if (fCandidates[candInd[iT]].fIsMcSignalElectron) {
-        if (mvdMotherId == stsMotherId && mcMvdHitPdg == 11) {
-          bin = 0.5;  // correct assignment
-        }
-        else {
-          bin = 1.5;
-        }
+      bin = (mvdMotherId != -1 && mvdMotherId == stsMotherId) ? 0.5 : bin = 1.5;  // correct or wrong assignment
+      if (cand.IsMcSignal()) {
+        bin = (mvdMotherId == stsMotherId && mcMvdHitPdg == 11) ? 0.5 : 1.5;  // correct or wrong assignment
       }
     }
-    //cout << "MVD cut correctness " << bin << endl;
 
     // Fill histograms
-    fCandidates[candInd[iT]].fDSts = dmvd;
-    if (fCandidates[candInd[iT]].fIsMcSignalElectron) {
-      hist[kSignal]->Fill(dmvd, fCandidates[candInd[iT]].fMomentum.Mag(), fWeight);
-      histQa[kSignal]->Fill(bin, fWeight);
-    }
-    else {
-      hist[kBg]->Fill(dmvd, fCandidates[candInd[iT]].fMomentum.Mag());
-      histQa[kBg]->Fill(bin);
-    }
-    if (fCandidates[candInd[iT]].fIsMcGammaElectron) {
-      hist[kGamma]->Fill(dmvd, fCandidates[candInd[iT]].fMomentum.Mag());
-      histQa[kGamma]->Fill(bin);
-    }
-    if (fCandidates[candInd[iT]].fIsMcPi0Electron) {
-      hist[kPi0]->Fill(dmvd, fCandidates[candInd[iT]].fMomentum.Mag());
-      histQa[kPi0]->Fill(bin);
-    }
+    fH.FillH1(histQa, cand.fMcSrc, bin, fW);
+    fH.FillH2(hist, cand.fMcSrc, dmvd, cand.fMomentum.Mag(), fW);
 
     // Apply MVD cut
-    if (mvdStationNum == 1) {
-      Double_t mom = fCandidates[candInd[iT]].fMomentum.Mag();
-      Double_t val = -1. * (fCuts.fMvd1CutP / fCuts.fMvd1CutD) * dmvd + fCuts.fMvd1CutP;
-      if (!(dmvd < fCuts.fMvd1CutD && val > mom)) { fCandidates[candInd[iT]].fIsMvd1CutElectron = true; }
-      else {
-        fCandidates[candInd[iT]].fIsMvd1CutElectron = false;
-      }
-    }
-    if (mvdStationNum == 2) {
-      Double_t mom = fCandidates[candInd[iT]].fMomentum.Mag();
-      Double_t val = -1. * (fCuts.fMvd2CutP / fCuts.fMvd2CutD) * dmvd + fCuts.fMvd2CutP;
-      if (!(dmvd < fCuts.fMvd2CutD && val > mom)) { fCandidates[candInd[iT]].fIsMvd2CutElectron = true; }
-      else {
-        fCandidates[candInd[iT]].fIsMvd2CutElectron = false;
-      }
-    }
-  }  // iTrack
+    bool isMvdCut = fCuts.IsMvdCutOk(mvdStationNum, dmvd, cand.fMomentum.Mag());
+    if (mvdStationNum == 1) cand.fIsMvd1Cut = isMvdCut;
+    else if (mvdStationNum == 2)
+      cand.fIsMvd2Cut = isMvdCut;
+  }
 }
 
-void CbmAnaDielectronTask::MvdCutMcDistance()
+void LmvmTask::MvdCutMcDistance()
 {
   if (!fUseMvd) return;
-  Int_t nCand = fCandidates.size();
-  for (Int_t i = 0; i < nCand; i++) {
-    if (fCandidates[i].fChi2Prim < fCuts.fChiPrimCut && fCandidates[i].fIsElectron) {
-      CbmStsTrack* track = (CbmStsTrack*) fStsTracks->At(fCandidates[i].fStsInd);
-      if (NULL == track) continue;
-      int stsMcTrackId = fCandidates[i].fStsMcTrackId;
-      Int_t nhits      = track->GetNofMvdHits();
-      for (Int_t ith = 0; ith < nhits; ith++) {
-        Int_t iHit      = track->GetMvdHitIndex(ith);
-        CbmMvdHit* pmh1 = (CbmMvdHit*) fMvdHits->At(iHit);
-        if (NULL == pmh1) continue;
-        Int_t stationNum = pmh1->GetStationNr();
-
-        int nofMvdHits = fMvdHitMatches->GetEntriesFast();
-        for (int iMvd = 0; iMvd < nofMvdHits; iMvd++) {
-          const CbmMatch* hitMatch = static_cast<const CbmMatch*>(fMvdHitMatches->At(iMvd));
-          if (NULL == hitMatch) continue;
-          int mcMvdHitId = hitMatch->GetMatchedLink().GetIndex();
-          if (stsMcTrackId != mcMvdHitId) continue;
-          CbmMvdHit* pmh2 = (CbmMvdHit*) fMvdHits->At(iMvd);
-          if (pmh2->GetStationNr() != stationNum) continue;
-          double dx = pmh1->GetX() - pmh2->GetX();
-          double dy = pmh1->GetY() - pmh2->GetY();
-          double d  = sqrt(dx * dx + dy * dy);
-          if (stationNum == 1) {
-            if (fCandidates[i].fIsMcGammaElectron) fh_mvd1cut_mc_dist_gamma->Fill(d);
-            if (fCandidates[i].fIsMcPi0Electron) fh_mvd1cut_mc_dist_pi0->Fill(d);
-          }
-          else if (stationNum == 1) {
-            if (fCandidates[i].fIsMcGammaElectron) fh_mvd2cut_mc_dist_gamma->Fill(d);
-            if (fCandidates[i].fIsMcPi0Electron) fh_mvd2cut_mc_dist_pi0->Fill(d);
-          }
+  for (const auto& cand : fCands) {
+    if (!cand.IsCutTill(ELmvmAnaStep::ElId)) continue;
+    CbmStsTrack* stsTrack = static_cast<CbmStsTrack*>(fStsTracks->At(cand.fStsInd));
+    if (stsTrack == nullptr) continue;
+    for (int iM = 0; iM < stsTrack->GetNofMvdHits(); iM++) {
+      CbmMvdHit* mvdHit1 = static_cast<CbmMvdHit*>(fMvdHits->At(stsTrack->GetMvdHitIndex(iM)));
+      if (mvdHit1 == nullptr) continue;
+
+      int nofMvdHits = fMvdHitMatches->GetEntriesFast();
+      for (int iMvd = 0; iMvd < nofMvdHits; iMvd++) {
+        const CbmMatch* hitMatch = static_cast<const CbmMatch*>(fMvdHitMatches->At(iMvd));
+        if (hitMatch == nullptr) continue;
+        if (cand.fStsMcTrackId != hitMatch->GetMatchedLink().GetIndex()) continue;
+        CbmMvdHit* mvdHit2 = static_cast<CbmMvdHit*>(fMvdHits->At(iMvd));
+        if (mvdHit2 == nullptr || mvdHit2->GetStationNr() != mvdHit1->GetStationNr()) continue;
+        double d = LmvmUtils::Distance(mvdHit1->GetX(), mvdHit1->GetY(), mvdHit2->GetX(), mvdHit2->GetY());
+        if (mvdHit1->GetStationNr() == 1) { fH.FillH1("hMvdMcDist_1", cand.fMcSrc, d, fW); }
+        else if (mvdHit1->GetStationNr() == 2) {
+          fH.FillH1("hMvdMcDist_2", cand.fMcSrc, d, fW);
         }
       }
     }
-  }  // iCan
+  }
 }
 
-void CbmAnaDielectronTask::Finish()
+void LmvmTask::Finish()
 {
   CombinatorialPairs();
   TDirectory* oldir = gDirectory;
   TFile* outFile    = FairRootManager::Instance()->GetOutFile();
-  if (outFile != NULL) {
+  if (outFile != nullptr) {
     outFile->cd();
-    // Write histograms to a file
-    for (UInt_t i = 0; i < fHistoList.size(); i++) {
-      fHistoList[i]->Write();
-    }
+    fH.WriteToFile();
   }
   gDirectory->cd(oldir->GetPath());
 }
 
-void CbmAnaDielectronTask::SetEnergyAndPlutoParticle(const string& energy, const string& particle)
+void LmvmTask::SetEnergyAndPlutoParticle(const string& energy, const string& particle)
 {
-  // names of particles in common production differ from our names
-  if (particle == "rho0") {
-    this->SetEnergyAndPlutoParticle(energy, "inmed");
-    return;
-  }
-  else if (particle == "wdalitz") {
-    this->SetEnergyAndPlutoParticle(energy, "omegadalitz");
-    return;
-  }
-  else if (particle == "w") {
-    this->SetEnergyAndPlutoParticle(energy, "omegaepem");
-    return;
-  }
-  else if (particle == "qgp_epem") {
-    this->SetEnergyAndPlutoParticle(energy, "qgp");
-    return;
-  }
-
-  // Au+Au centr old scaling factors
-  /* if (energy == "8gev" || energy == "10gev") {
-        // weight rho0 = Multiplicity * Branching Ratio = 9 * 4.7e-5 for 10 AGeV beam energy
-        if (particle == "rho0") this->SetWeight(9 * 4.7e-5);
-        // weight omega = Multiplicity * Branching Ratio = 19 * 7.28e-5 for 10 AGeV beam energy
-        if (particle == "omegaepem" ) this->SetWeight(19 * 7.28e-5);
-        // weight omega = Multiplicity * Branching Ratio = 19 * 7.7e-4 for 10 AGeV beam energy
-        if (particle == "omegadalitz") this->SetWeight(19 * 7.7e-4);
-        // weight phi = Multipli0city * Branching Ratio = 0.12 * 2.97e-4 for 10 AGeV beam energy
-        if (particle == "phi") this->SetWeight(0.12 * 2.97e-4);
-        // weight in medium rho. 0.5 is a scaling factor for 8AGev from 25AGeV
-        if (particle == "inmed") this->SetWeight(0.5 * 4.45e-2);
-        // weight qgp radiation  0.5 is a scaling factor for 8AGev from 25AGeV
-	if (particle == "qgp") this->SetWeight(0.5 * 1.15e-2);
-                                                                                                      //either old or new!!!
-    // Au+Au centr new scaling factors
-    }*/
-  if (energy == "8gev"
-      || energy
-           == "12gev") {  // TODO: 12 GeV was added only to check common production; must add weights for this energy
-    // weight omega = Multiplicity * Branching Ratio = 19 * 7.28e-5 for 8 AGeV beam energy
-    if (particle == "omegaepem") this->SetWeight(2.5 * 7.28e-5);
-    // weight omega = Multiplicity * Branching Ratio = 19 * 7.7e-4 for 8 AGeV beam energy
-    if (particle == "omegadalitz") this->SetWeight(2.5 * 7.7e-4);
-    // weight phi = Multipli0city * Branching Ratio = 0.12 * 2.97e-4 for 8 AGeV beam energy
-    if (particle == "phi") this->SetWeight(0.365 * 2.97e-4);
-    // weight in medium rho. 0.5 is a scaling factor for 8AGev from 25AGeV
-    if (particle == "inmed") this->SetWeight(0.5 * 4.45e-2);
-    // weight qgp radiation  0.5 is a scaling factor for 8AGev from 25AGeV
-    if (particle == "qgp") this->SetWeight(0.5 * 1.15e-2);
-  }
-  else if (energy == "25gev") {
-    // weight rho0 = Multiplicity * Branching Ratio = 23 * 4.7e-5 for 25 AGeV beam energy
-    if (particle == "rho0") this->SetWeight(23 * 4.7e-5);
-    // weight omega = Multiplicity * Branching Ratio = 38 * 7.28e-5 for 25 AGeV beam energy
-    if (particle == "omegaepem") this->SetWeight(38 * 7.28e-5);
-    // weight omega = Multiplicity * Branching Ratio = 38 * 7.7e-4 for 25 AGeV beam energy
-    if (particle == "omegadalitz") this->SetWeight(38 * 7.7e-4);
-    // weight phi = Multiplicity * Branching Ratio = 1.28 * 2.97e-4 for 25 AGeV beam energy
-    if (particle == "phi") this->SetWeight(1.28 * 2.97e-4);
-    // weight in medium rho.
-    if (particle == "inmed") this->SetWeight(4.45e-2);
-    // weight qgp radiation
-    if (particle == "qgp") this->SetWeight(1.15e-2);
-  }
-  else if (energy == "3.5gev") {
-    // weight rho0 = Multiplicity * Branching Ratio = 1.0 * 4.7e-5 for 25 AGeV beam energy
-    if (particle == "rho0") this->SetWeight(1.0 * 4.7e-5);
-    // weight omega = Multiplicity * Branching Ratio = 1.2 * 7.28e-5 for 25 AGeV beam energy
-    if (particle == "omegaepem") this->SetWeight(1.2 * 7.28e-5);
-    // weight omega = Multiplicity * Branching Ratio = 1.2 * 5.9e-4 for 25 AGeV beam energy
-    if (particle == "omegadalitz") this->SetWeight(1.2 * 7.7e-5);
-    // weight phi = Multiplicity * Branching Ratio = 0.1 * 2.97e-4 for 25 AGeV beam energy
-    if (particle == "phi") this->SetWeight(0.1 * 2.97e-4);
-
-    //Ag+Ag mbias!!
-    /*    } else if (energy == "4.5gev"){
-        // weight omegadalitz = Multiplicity * Branching Ratio =    for 4.5 AGeV beam energy
-        if(particle == "omegadalitz") this->SetWeight(5.8*7.7e-6);
-        // weight omegaepem = Multiplicity * Branching Ratio =    for 4.5 AGeV beam energy
-        if(particle == "omegaepem") this->SetWeight(5.8*7.28e-7);
-        // weight pi0 = Multiplicity * Branching Ratio =    for 4.5 AGeV beam energy
-        if(particle == "phi") this->SetWeight(5.8*2.97e-7);
-	// weight inmed = Multiplicity * Branching Ratio =    for 4.5 AGeV beam energy
-         if(particle == "inmed") this->SetWeight(8.2*10e-4);
-*/
-    //Ag+Ag 40%                                                                                             either mbias or 40%!!!
-  }
-  else if (energy == "4.5gev") {
-    // weight omegadalitz = Multiplicity * Branching Ratio =    for 4.5 AGeV beam energy
-    if (particle == "omegadalitz") this->SetWeight(1.2 * 7.7e-5);
-    // weight omegaepem = Multiplicity * Branching Ratio =    for 4.5 AGeV beam energy
-    if (particle == "omegaepem") this->SetWeight(1.2 * 7.28e-6);
-    // weight pi0 = Multiplicity * Branching Ratio =    for 4.5 AGeV beam energy
-    if (particle == "phi") this->SetWeight(1.2 * 2.97e-6);
-    // weight inmed = Multiplicity * Branching Ratio =    for 4.5 AGeV beam energy
-    if (particle == "inmed") this->SetWeight(2.4 * 10e-3);
-  }
-  else {
-    cout << "-ERROR- CbmAnaDielectronTask::SetEnergyAndParticle energy or "
-            "particle is not correct, energy:"
-         << energy << " particle:" << particle << endl;
-  }
+  this->SetWeight(LmvmSimParam::GetWeight(energy, particle));
 }
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmTask.h b/analysis/PWGDIL/dielectron/lmvm/LmvmTask.h
old mode 100755
new mode 100644
index 7926e15075c15db6732873e50143f2ddd70ba4be..dde2477b2c0e396c6bcba8e0bda8b958da960f93
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmTask.h
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmTask.h
@@ -1,31 +1,16 @@
-/* Copyright (C) 2010-2020 UGiessen, JINR-LIT
+/* Copyright (C) 2010-2021 UGiessen, JINR-LIT
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev [committer], Elena Lebedeva, Florian Uhlig */
 
-/** CbmAnaDielectronTask.h
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2010
- * @version 3.0
-**/
+#ifndef LMVM_TASK_H
+#define LMVM_TASK_H
 
-#ifndef CBM_ANA_DIELECTRON_TASK_H
-#define CBM_ANA_DIELECTRON_TASK_H
-
-#include "CbmGlobalTrack.h"
 #include "CbmKFVertex.h"
-#include "CbmLmvmCandidate.h"
-#include "CbmLmvmCuts.h"
-#include "CbmLmvmHist.h"
 #include "CbmLmvmKinematicParams.h"
-#include "CbmMCTrack.h"
 #include "CbmStsKFTrackFitter.h"
-#include "CbmStsTrack.h"
-#include "CbmTrdTrack.h"
-#include "CbmVertex.h"
-#include "cbm/qa/mc/CbmLitMCTrackCreator.h"
 
-#include "FairBaseParSet.h"
 #include "FairMCEventHeader.h"
+#include "FairRootManager.h"
 #include "FairTask.h"
 
 #include <fstream>
@@ -33,26 +18,30 @@
 #include <string>
 #include <vector>
 
+#include "LmvmCand.h"
+#include "LmvmCuts.h"
+#include "LmvmDef.h"
+#include "LmvmHist.h"
+
 class TClonesArray;
 class TH2D;
 class TH1D;
 class TH2F;
 class TRandom3;
-class FairRootManager;
 
 
-class CbmAnaDielectronTask : public FairTask {
+class LmvmTask : public FairTask {
 
 public:
   /*
     * \brief Standard constructor.
     */
-  CbmAnaDielectronTask();
+  LmvmTask();
 
   /*
      * \brief Standard destructor.
      */
-  virtual ~CbmAnaDielectronTask();
+  virtual ~LmvmTask();
 
   /*
      * \brief Inherited from FairTask.
@@ -64,70 +53,15 @@ public:
      */
   virtual void Exec(Option_t* option);
 
-  /*
-     * \brief Creates 1D histograms for each analysis step.
-     * \param[in,out] hist Vector if the histograms for each analysis step.
-     * \param[in] name Base name of the histograms.
-     * \param[in] axisX X axis title.
-     * \param[in] axisY Y axis title.
-     * \param[in] nBins Number of bins in the histogram.
-     * \param[in] min Minimum value.
-     * \param[in] max Maximum value.
-     */
-  void CreateAnalysisStepsH1(std::vector<TH1D*>& hist, const std::string& name, const std::string& axisX,
-                             const std::string& axisY, double nBins, double min, double max);
-
-
-  /*
-     * \brief Creates 2D histograms for each analysis step.
-     * \param[in,out] hist Vector if the histograms for each analysis step.
-     * \param[in] name Base name of the histograms.
-     * \param[in] axisX X axis title.
-     * \param[in] axisY Y axis title.
-     * \param[in] axisZ Z axis title.
-     * \param[in] nBinsX Number of bins for X axis in the histogram.
-     * \param[in] minX Minimum value for X axis.
-     * \param[in] maxX Maximum value for X axis.
-     * \param[in] nBinsY Number of bins for Y axis in the histogram.
-     * \param[in] minY Minimum value for Y axis.
-     * \param[in] maxY Maximum value for Y axis.
-     */
-  void CreateAnalysisStepsH2(std::vector<TH2D*>& hist, const std::string& name, const std::string& axisX,
-                             const std::string& axisY, const std::string& axisZ, double nBinsX, double minX,
-                             double maxX, double nBinsY, double minY, double maxY);
-
-  /*
-     * \brief Creates 1D histograms for different track source types.
-     * \param[in,out] hist Vector if the histograms for each analysis step.
-     * \param[in] name Base name of the histograms.
-     * \param[in] axisX X axis title.
-     * \param[in] axisY Y axis title.
-     * \param[in] nBins Number of bins in the histogram.
-     * \param[in] min Minimum value.
-     * \param[in] max Maximum value.
-     */
-  void CreateSourceTypesH1(std::vector<TH1D*>& hist, const std::string& name, const std::string& axisX,
-                           const std::string& axisY, double nBins, double min, double max);
-
-
-  /*
-     * \brief Creates 2D histograms for different track source types.
-     * \param[in,out] hist Vector if the histograms for each analysis step.
-     * \param[in] name Base name of the histograms.
-     * \param[in] axisX X axis title.
-     * \param[in] axisY Y axis title.
-     * \param[in] axisZ Z axis title.
-     * \param[in] nBinsX Number of bins for X axis in the histogram.
-     * \param[in] minX Minimum value for X axis.
-     * \param[in] maxX Maximum value for X axis.
-     * \param[in] nBinsY Number of bins for Y axis in the histogram.
-     * \param[in] minY Minimum value for Y axis.
-     * \param[in] maxY Maximum value for Y axis.
-     */
-  void CreateSourceTypesH2(std::vector<TH2D*>& hist, const std::string& name, const std::string& axisX,
-                           const std::string& axisY, const std::string& axisZ, double nBinsX, double minX, double maxX,
-                           double nBinsY, double minY, double maxY);
-
+  template<typename T>
+  T* InitOrFatal(const std::string& name)
+  {
+    FairRootManager* ioman = FairRootManager::Instance();
+    if (ioman == nullptr) { LOG(fatal) << "LmvmTask::Init No FairRootManager!"; }
+    T* array = static_cast<T*>(ioman->GetObject(name.c_str()));
+    if (array == nullptr) { LOG(fatal) << "LmvmTask::Init No " << name << " object!"; }
+    return array;
+  }
 
   /*
      * \brief Fills histograms for pairs.
@@ -136,8 +70,8 @@ public:
      * \param[in] step Enumeration AnalysisSteps, specify analysis step.
      * \param[in] parRec Kinematic parameters for reconstructed pair.
      */
-  void PairSource(CbmLmvmCandidate* candP, CbmLmvmCandidate* candM, CbmLmvmAnalysisSteps step,
-                  CbmLmvmKinematicParams* parRec);
+  void PairSource(const LmvmCand& candP, const LmvmCand& candM, ELmvmAnaStep step,
+                  const CbmLmvmKinematicParams& parRec);
 
   /*
      *  \brief Fills minv, pty, mom histograms for specified analysis step.
@@ -147,32 +81,30 @@ public:
      * \param[in] parRec Reconstructed kinematic parameters.
      * \param[in] step Enumeration AnalysisSteps, specify analysis step.
      */
-  void FillPairHists(CbmLmvmCandidate* candP, CbmLmvmCandidate* candM, CbmLmvmKinematicParams* parMc,
-                     CbmLmvmKinematicParams* parRec, CbmLmvmAnalysisSteps step);
+  void FillPairHists(const LmvmCand& candP, const LmvmCand& candM, const CbmLmvmKinematicParams& parMc,
+                     const CbmLmvmKinematicParams& parRec, ELmvmAnaStep step);
 
-  void TrackSource(CbmLmvmCandidate* cand, CbmLmvmAnalysisSteps step, Int_t pdg);
+  void FillMomHists(const CbmMCTrack* mct, const LmvmCand* cand, ELmvmSrc src, ELmvmAnaStep step);
 
-  void SingleParticleAcceptance();
+  void TrackSource(const LmvmCand& cand, ELmvmAnaStep step, int pdg);
 
-  void FillRichRingNofHits();
+  void DoMcTrack();
 
-  Bool_t IsMcTrackAccepted(Int_t mcTrackInd);
+  void DoMcPair();
 
-  void RichPmtXY();
+  void FillRichRingNofHits();
 
-  void MCPairs();
+  bool IsMcTrackAccepted(int mcTrackInd);
 
-  void PairMcAndAcceptance();
+  void RichPmtXY();
 
-  void FillTopologyCandidates();
+  void FillTopologyCands();
 
-  void FillCandidates();
+  void FillCands();
 
-  void AssignMcToCandidates(std::vector<CbmLmvmCandidate>& candVector);
-  //void AssignMcToCandidates();
-  //void AssignMcToCandidatesTotal();
+  void AssignMcToCands(std::vector<LmvmCand>& cands);
 
-  void AssignMcToTopologyCandidates(std::vector<CbmLmvmCandidate>& cutCandidates);
+  void AssignMcToTopologyCands(std::vector<LmvmCand>& topoCands);
 
   void DifferenceSignalAndBg();
 
@@ -185,302 +117,87 @@ public:
 
   void CheckGammaConvAndPi0();
 
-  void FillNofChargedParticles();
-
   /*
      * \brief
      * \param[in] mvdStationNum MVD station number.
      * \param[in, out] hist Vector of histograms for different source types.
      */
-  void CheckClosestMvdHit(Int_t mvdStationNum, std::vector<TH2D*>& hist, std::vector<TH1D*>& histQa);
-
-  /*
-     * \brief Set cut values and fill histograms for topology cut
-     * \param[in] cutName ST or TT
-     */
-  void CheckTopologyCut(const std::string& cutName, const std::vector<CbmLmvmCandidate>& cutCandidates,
-                        const std::vector<TH2D*>& hcut, const std::vector<TH2D*>& hcutPion,
-                        const std::vector<TH2D*>& hcutTruepair, Double_t angleCut, Double_t ppCut);
+  void CheckClosestMvdHit(int mvdStationNum, const std::string& hist, const std::string& histQa);
 
   /*
      * \brief Set cut values and fill histograms for topology cut
      * \param[in] cutName ST or TT
      */
-  // void CheckTopologyCutTotal(const std::string& cutName, const std::vector<CbmLmvmCandidate>& cutCandidates, Double_t angleCut, Double_t ppCut);
+  void CheckTopologyCut(ELmvmTopologyCut cut, const std::string& name);
 
-  void CalculateNofTopologyPairs(TH1D* h_nof_pairs, const std::string& source);
+  void CalculateNofTopologyPairs(const std::string& name, ELmvmSrc src);
 
   void MvdCutMcDistance();
 
-  // Likelihood vs Momentum
-  void FillMomLikeHist();
-
   void CombinatorialPairs();
 
   virtual void Finish();
 
-  void FillElPiMomHist();
+  void FillPionsHist();
 
 
-  ClassDef(CbmAnaDielectronTask, 1);
+  ClassDef(LmvmTask, 1);
 
 private:
-  CbmAnaDielectronTask(const CbmAnaDielectronTask&);
-  CbmAnaDielectronTask& operator=(const CbmAnaDielectronTask&);
-
-  Bool_t IsMismatch(CbmLmvmCandidate* cand);
-
-  Bool_t IsGhost(CbmLmvmCandidate* cand);
-
-  void IsElectron(Int_t globalTrackIndex, Double_t momentum, CbmLmvmCandidate* cand);
-
-  FairMCEventHeader* fMCEventHeader;
-  TClonesArray* fMCTracks;
-  TClonesArray* fRichRings;
-  TClonesArray* fRichProj;
-  TClonesArray* fRichPoints;
-  TClonesArray* fRichRingMatches;
-  TClonesArray* fRichHits;
-  TClonesArray* fGlobalTracks;
-  TClonesArray* fStsTracks;
-  TClonesArray* fStsTrackMatches;
-  TClonesArray* fStsHits;
-  TClonesArray* fMvdHits;
-  TClonesArray* fMvdPoints;
-  TClonesArray* fMvdHitMatches;
-  TClonesArray* fTrdTracks;
-  TClonesArray* fTrdHits;
-  TClonesArray* fTrdTrackMatches;
-  TClonesArray* fTofHits;
-  TClonesArray* fTofHitsMatches;
-  TClonesArray* fTofPoints;
-  CbmVertex* fPrimVertex;
+  LmvmTask(const LmvmTask&);
+  LmvmTask& operator=(const LmvmTask&);
+
+  FairMCEventHeader* fMCEventHeader = nullptr;
+  TClonesArray* fMCTracks           = nullptr;
+  TClonesArray* fRichRings          = nullptr;
+  TClonesArray* fRichProj           = nullptr;
+  TClonesArray* fRichPoints         = nullptr;
+  TClonesArray* fRichRingMatches    = nullptr;
+  TClonesArray* fRichHits           = nullptr;
+  TClonesArray* fGlobalTracks       = nullptr;
+  TClonesArray* fStsTracks          = nullptr;
+  TClonesArray* fStsTrackMatches    = nullptr;
+  TClonesArray* fStsHits            = nullptr;
+  TClonesArray* fMvdHits            = nullptr;
+  TClonesArray* fMvdPoints          = nullptr;
+  TClonesArray* fMvdHitMatches      = nullptr;
+  TClonesArray* fTrdTracks          = nullptr;
+  TClonesArray* fTrdHits            = nullptr;
+  TClonesArray* fTrdTrackMatches    = nullptr;
+  TClonesArray* fTofHits            = nullptr;
+  TClonesArray* fTofHitsMatches     = nullptr;
+  TClonesArray* fTofPoints          = nullptr;
+  CbmVertex* fPrimVertex            = nullptr;
   CbmKFVertex fKFVertex;
   CbmStsKFTrackFitter fKFFitter;
 
-  //CbmLitMCTrackCreator* fMCTrackCreator; // MC track creator tool
-
-  Bool_t fUseMvd;
-  Bool_t fUseRich;
-  Bool_t fUseTrd;
-  Bool_t fUseTof;
-
-  std::vector<CbmLmvmCandidate> fCandidates;
-  std::vector<CbmLmvmCandidate> fCandidatesTotal;
-  std::vector<CbmLmvmCandidate> fSTCandidates;  // STCut Segmented tracks, reconstructed only in STS
-  std::vector<CbmLmvmCandidate>
-    fTTCandidates;  // TTCut Reconstructed tracks, reconstructed in all detectors but not identified as electrons
-  std::vector<CbmLmvmCandidate>
-    fRTCandidates;  // RTCut Reconstructed tracks, reconstructed in STS + at least in one of the  detectro (RICH, TRD, TOF)
-
-  Double_t fWeight;  //Multiplicity*BR
-
-  Double_t fPionMisidLevel;  // For the ideal particle identification cases, set to -1 for real PID
-  TRandom3* fRandom3;
-
-  Int_t fEventNumber;  // number of current event
-
-  //Bool_t fUseMcMomentum;
-
-  CbmLmvmCuts fCuts;  // electorn identification and analisys cuts
-
-  std::vector<TH1*> fHistoList;  //list of all histograms
-
-  // Number of hits in the MC RICH ring
-  std::map<Int_t, Int_t> fNofHitsInRingMap;
-
-  TH2D* fh_mc_signal_mom_angle;  // angle vs. sqrt(mom1*mom2) with MCTracks
-
-  TH1D* fh_nof_charged_particles;      // charged UrQMD particles
-  TH1D* fh_nof_charged_particles_acc;  // accepted charged UrQMD particles
-
-  TH1D* fh_mc_mother_pdg;   //mother pdg code for e-/e+
-  TH1D* fh_acc_mother_pdg;  //mother pdg code for accepted e-/e+
-
-  // X-Y distribution of MC pints on the RICH PMT plane
-  TH2D* fh_signal_pmtXY;
-  TH2D* fh_pi0_pmtXY;
-  TH2D* fh_gamma_pmtXY;
-
-  // Vertex of secondary electron from gamma conversion for different analysis step
-  //Index is the analysis step: [0]-mc, [1]-acc, [2]-reco, [3]-chi2prim, [4]-elid,
-  // [5]-gamma cut, [6]-mvd1cut, [7]-mvd2cut, [8]-stcut, [9]-ttcut, [10]-ptcut.
-  std::vector<TH2D*> fh_vertex_el_gamma_xz;
-  std::vector<TH2D*> fh_vertex_el_gamma_yz;
-  std::vector<TH2D*> fh_vertex_el_gamma_xy;
-  std::vector<TH2D*> fh_vertex_el_gamma_rz;  //r=sqrt(x^2+y^2)
-
-  //Index is the analysis step: [0]-mc, [1]-acc, [2]-reco, [3]-chi2prim, [4]-elid,
-  // [5]-gamma cut, [6]-mvd1cut, [7]-mvd2cut, [8]-stcut, [9]-ttcut, [10]-ptcut.
-  //Use AnalysisSteps enumeration for access.
-  //MC and ACC histograms are not filled sometimes.
-  std::vector<TH1D*> fh_signal_minv;  // Invariant mass for Signal
-  std::vector<TH1D*> fh_bg_minv;      // Invariant mass for BG
-
-  std::vector<TH1D*> fh_combPairsPM_minv_sameEvent;    // Invariant mass for comb. Pairs of e+/e-
-  std::vector<TH1D*> fh_combPairsPP_minv_sameEvent;    // Invariant mass for comb. Pairs of e+/e+
-  std::vector<TH1D*> fh_combPairsMM_minv_sameEvent;    // Invariant mass for comb. Pairs of e-/e-
-  std::vector<TH1D*> fh_combPairsPM_minv_mixedEvents;  // Invariant mass for comb. Pairs of e+/e-
-  std::vector<TH1D*> fh_combPairsPP_minv_mixedEvents;  // Invariant mass for comb. Pairs of e+/e+
-  std::vector<TH1D*> fh_combPairsMM_minv_mixedEvents;  // Invariant mass for comb. Pairs of e-/e-
-
-  std::vector<TH1D*> fh_nof_plutoElectrons;       // nof electrons / positrons vs. momentum
-  std::vector<TH1D*> fh_nof_plutoPositrons;       // nof electrons / positrons vs. momentum
-  std::vector<TH1D*> fh_nof_urqmdElectrons;       // nof electrons / positrons vs. momentum
-  std::vector<TH1D*> fh_nof_urqmdPositrons;       // nof electrons / positrons vs. momentum
-  std::vector<TH2D*> fh_nof_plutoElectrons_p_pt;  // nof electrons / positrons vs. momentum and Pt
-  std::vector<TH2D*> fh_nof_plutoPositrons_p_pt;  // nof electrons / positrons vs. momentum and Pt
-  std::vector<TH2D*> fh_nof_urqmdElectrons_p_pt;  // nof electrons / positrons vs. momentum and Pt
-  std::vector<TH2D*> fh_nof_urqmdPositrons_p_pt;  // nof electrons / positrons vs. momentum and Pt
-
-  std::vector<TH1D*>
-    fh_nof_particles_acc;  // To compare accepted with created PLUTO and UrQMD particles for various detector combinations
-
-  // Number of points the electrons and positrons left in various detectors
-  //[0]=Pluto-El STS, [1]=Pluto-Pos STS, [2]=Pluto-El RICH,  [3]=Pluto-Pos RICH,  [4]=Pluto-El TRD,  [5]=Pluto-Pos TRD,  [6]=Pluto-El ToF,  [7]=Pluto-Pos ToF
-  //[8]=UrQMD-El STS, [9]=UrQMD-Pos STS, [10]=UrQMD-El RICH, [11]=UrQMD-Pos RICH, [12]=UrQMD-El TRD, [13]=UrQMD-Pos TRD, [14]=UrQMD-El ToF, [15]=UrQMD-Pos ToF
-  std::vector<TH1D*> fh_nof_points;
-
-  std::vector<TH1D*> fh_pi0_minv;        // Invariant mass for Pi0
-  std::vector<TH1D*> fh_eta_minv;        // Invariant mass for Eta
-  std::vector<TH1D*> fh_gamma_minv;      // Invariant mass for Eta
-  std::vector<TH1D*> fh_signal_mom;      // Signal momentum distribution
-  std::vector<TH2D*> fh_signal_pty;      // Pt/y distribution for signal
-  std::vector<TH2D*> fh_signal_minv_pt;  // Invariant mass vs. MC Pt
-  std::vector<TH2D*> fh_eta_minv_pt;     // Invariant mass vs. MC Pt
-  std::vector<TH2D*> fh_pi0_minv_pt;     // Invariant mass vs. MC Pt
-
-  std::vector<TH1D*> fh_bg_truematch_minv;        // Invariant mass for truly matched tracks
-  std::vector<TH1D*> fh_bg_truematch_el_minv;     // Invariant mass for truly matched electron tracks
-  std::vector<TH1D*> fh_bg_truematch_notel_minv;  // Invariant mass for truly matched tracks, not 2 electrons
-  std::vector<TH1D*> fh_bg_mismatch_minv;         // Invariant mass for mis matches tracks
-
-  //G-Gamma, P-Pi0, O-other
-  //e-e+
-  //[0]=G-G, [1]=P-P, [2]=O-O, [3]=G-P, [4]=G-O, [5]=P-O
-  std::vector<std::vector<TH1D*>> fh_source_bg_minv;  // Invariant mass for different source
-
-
-  //Index is the source type: [0]-signal, [1]-bg, [2]-pi0, [3]-gamma
-  //Use SourceTypes enumeration for access.
-  std::vector<TH1D*> fh_pt;        // Transverse momentum of single track distribution
-  std::vector<TH1D*> fh_mom;       //Momentum of the single track
-  std::vector<TH1D*> fh_chi2sts;   // Chi2 of the STS tracks
-  std::vector<TH1D*> fh_chi2prim;  // Chi2 of the primary vertex
-  std::vector<TH2D*> fh_ttcut;     // TT cut
-  std::vector<TH2D*> fh_stcut;     // ST cut
-  std::vector<TH2D*> fh_rtcut;     // RT cut
-  std::vector<TH2D*> fh_mvd1cut;   // MVD cut at the first station
-  std::vector<TH2D*> fh_mvd2cut;   // MVD cut at the second station
-  std::vector<TH1D*> fh_richann;   // RICH ANN
-  std::vector<TH1D*> fh_trdann;    // TRD ANN
-  std::vector<TH2D*> fh_tofm2;     // TOF m2
-  std::vector<TH2D*> fh_ttcut_pion;
-  std::vector<TH2D*> fh_ttcut_truepair;
-  std::vector<TH2D*> fh_stcut_pion;
-  std::vector<TH2D*> fh_stcut_truepair;
-  std::vector<TH2D*> fh_rtcut_pion;
-  std::vector<TH2D*> fh_rtcut_truepair;
-
-  std::vector<TH1D*> fh_nofMvdHits;  // number of MVD hits
-  std::vector<TH1D*> fh_nofStsHits;  // number of STS hits
-  std::vector<TH2D*> fh_mvd1xy;      // hit distribution in the first MVD station
-  std::vector<TH1D*> fh_mvd1r;       // r = x^2+y^2
-  std::vector<TH2D*> fh_mvd2xy;      // hit distribution in the second MVD station
-  std::vector<TH1D*> fh_mvd2r;       // r = x^2+y^2
-
-  //Distant to MVD hit from the same  MotherId
-  TH1D* fh_mvd1cut_mc_dist_gamma;
-  TH1D* fh_mvd1cut_mc_dist_pi0;
-  TH1D* fh_mvd2cut_mc_dist_gamma;
-  TH1D* fh_mvd2cut_mc_dist_pi0;
-
-  std::vector<TH1D*> fh_mvd1cut_qa;  // MVD 1 cut quality
-  std::vector<TH1D*> fh_mvd2cut_qa;  // MVD 2 cut quality
-
-  //source of BG pairs 2D.
-  //second index is the analysis step: [0]-mc, [1]-acc, [2]-reco, [3]-chi2prim, [4]-elid,
-  // [5]-gamma cut, [6]-mvd1cut, [7]-mvd2cut, [8]-stcut, [9]-ttcut, [10]-ptcut.
-  //Use AnalysisSteps enumeration for access.
-  std::vector<TH2D*> fh_source_pairs_epem;
-
-  //X axis: analysis step
-  //Y axis: [0]=G-G, [1]=P-P, [2]=O-O, [3]=G-P, [4]=G-O, [5]=P-O
-  TH2D* fh_source_pairs;
-
-  //store event number
-  TH1D* fh_event_number;
-  TH1D* fh_event_number_mixed;  // number of involved mixed events
-
-  //nof signal and bg tracks after each cut
-  TH1D* fh_nof_bg_tracks;
-  TH1D* fh_nof_el_tracks;
-  TH2D* fh_source_tracks;
-
-  TH1D* fh_nof_topology_pairs_gamma;
-  TH1D* fh_nof_topology_pairs_pi0;
-
-  //nof gamma and pi0 pairs for different track categories : global, only STS or partially reconstructed
-  TH1D* fh_nof_rec_pairs_gamma;
-  TH1D* fh_nof_rec_pairs_pi0;
-
-  //nof gamma and pi0 tracks for different track categories : global, only STS or partially reconstructed
-  TH1D* fh_nof_rec_gamma;
-  TH1D* fh_nof_rec_pi0;
-
-  TH1D* fh_nof_mismatches;
-  TH1D* fh_nof_mismatches_rich;
-  TH1D* fh_nof_mismatches_trd;
-  TH1D* fh_nof_mismatches_tof;
-  TH1D* fh_nof_ghosts;
-
-  //First index is the source type: [0]-signal, [1]-bg, [2]-pi0, [3]-gamma
-  //Use SourceTypes enumeration for access.
-  //second index is the analysis step: [0]-mc, [1]-acc, [2]-reco, [3]-chi2prim, [4]-elid,
-  // [5]-gamma cut, [6]-mvd1cut, [7]-mvd2cut, [8]-stcut, [9]-ttcut, [10]-ptcut.
-  //Use AnalysisSteps enumeration for access.
-  //Track momentum distribution for different sources after each cut.
-  std::vector<std::vector<TH1D*>> fh_source_mom;
-  //Pt distribution for different sources after each cut.
-  std::vector<std::vector<TH1D*>> fh_source_pt;
-  //Opening angle distribution for different sources after each cut.
-  std::vector<std::vector<TH1D*>> fh_opening_angle;
-
-  //Pions vs momentum
-  TH1D* fh_pi_mom_mc;
-  TH1D* fh_pi_mom_acc;
-  TH1D* fh_pi_mom_rec;
-  TH1D* fh_pi_mom_rec_only_sts;
-  TH1D* fh_pi_mom_rec_sts_rich_trd;
-  TH1D* fh_pi_mom_rec_sts_rich_trd_tof;
-  TH1D* fh_pi_rapidity_mc;
-
-  //Pions vs momentum for primary pions v < 0.1 cm
-  TH1D* fh_piprim_mom_mc;
-  TH1D* fh_piprim_mom_acc;
-  TH1D* fh_piprim_mom_rec;
-  TH1D* fh_piprim_mom_rec_only_sts;
-  TH1D* fh_piprim_mom_rec_sts_rich_trd;
-  TH1D* fh_piprim_mom_rec_sts_rich_trd_tof;
-
-  TH1D* fh_piprim_plus_rapidity_mc;
-  TH1D* fh_piprim_minus_rapidity_mc;
-  TH1D* fh_pi0prim_rapidity_mc;
-  TH1D* fh_etaprim_rapidity_mc;
-
-  // Likelihood vs Momentum
-  TH2D* fh_mom_likelihood_El;
-  TH2D* fh_mom_likelihood_Pi;
+  bool fUseMvd = false;
+
+  std::vector<LmvmCand> fCands;
+  std::vector<LmvmCand> fCandsTotal;
+  // STCut Segmented tracks, reconstructed only in STS
+  std::vector<LmvmCand> fSTCands;
+  // TTCut Reconstructed tracks, reconstructed in all detectors but not identified as electrons
+  std::vector<LmvmCand> fTTCands;
+  // RTCut Reconstructed tracks, reconstructed in STS + at least in one of the  detectro (RICH, TRD, TOF)
+  std::vector<LmvmCand> fRTCands;
+
+  double fW = 0.;  //Multiplicity*BR
+
+  double fPionMisidLevel = -1.;  // For the ideal particle identification cases, set to -1 for real PID
+
+  int fEventNumber = 0;  // number of current event
+  LmvmCuts fCuts;        // electorn identification and analisys cuts
+
+  LmvmHist fH;  // histogram manager
+
+  std::map<int, int> fNofHitsInRingMap;  // Number of hits in the MC RICH ring
 
 public:
-  void SetUseMvd(Bool_t use) { fUseMvd = use; };
-  void SetUseRich(Bool_t use) { fUseRich = use; };
-  void SetUseTrd(Bool_t use) { fUseTrd = use; };
-  void SetUseTof(Bool_t use) { fUseTof = use; };
-  void SetWeight(Double_t weight) { fWeight = weight; };
-  void SetEnergyAndPlutoParticle(const string& energy, const string& particle);
-  void SetPionMisidLevel(Double_t level) { fPionMisidLevel = level; }
-  // void SetMomentumCut(Double_t mom) {fMomentumCut = mom;}
+  void SetUseMvd(bool use) { fUseMvd = use; }
+  void SetWeight(double w) { fW = w; }
+  void SetEnergyAndPlutoParticle(const std::string& energy, const std::string& particle);
+  void SetPionMisidLevel(double level) { fPionMisidLevel = level; }
 };
 
 #endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmUtils.cxx b/analysis/PWGDIL/dielectron/lmvm/LmvmUtils.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ef6f2028f750bc835a73b2e7532802d8c3a365c4
--- /dev/null
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmUtils.cxx
@@ -0,0 +1,276 @@
+/* Copyright (C) 2021 Justus-Liebig-Universitaet Giessen, Giessen
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Semen Lebedev [committer]*/
+
+#include "LmvmUtils.h"
+
+#include "CbmKFVertex.h"
+#include "CbmL1PFFitter.h"
+#include "CbmMCTrack.h"
+#include "CbmStsTrack.h"
+#include "cbm/elid/CbmLitGlobalElectronId.h"
+
+#include "TClonesArray.h"
+#include "TDatabasePDG.h"
+#include "TMCProcess.h"
+#include "TRandom3.h"
+
+#include <iostream>
+
+#include "L1Field.h"
+#include "LmvmCand.h"
+#include "LmvmDef.h"
+
+using std::string;
+using std::vector;
+
+ClassImp(LmvmUtils);
+
+void LmvmUtils::CalculateAndSetTrackParams(LmvmCand* cand, CbmStsTrack* stsTrack, CbmKFVertex& kfVertex)
+{
+  CbmL1PFFitter fPFFitter;
+  vector<CbmStsTrack> stsTracks;
+  stsTracks.resize(1);
+  stsTracks[0] = *stsTrack;
+  vector<L1FieldRegion> vField;
+  vector<float> chiPrim;
+  fPFFitter.GetChiToVertex(stsTracks, vField, chiPrim, kfVertex, 3e6);
+  cand->fChi2sts                 = stsTracks[0].GetChiSq() / stsTracks[0].GetNDF();
+  cand->fChi2Prim                = chiPrim[0];
+  const FairTrackParam* vtxTrack = stsTracks[0].GetParamFirst();
+
+  vtxTrack->Position(cand->fPosition);
+  vtxTrack->Momentum(cand->fMomentum);
+
+  cand->fMass     = TDatabasePDG::Instance()->GetParticle(11)->Mass();
+  cand->fCharge   = (vtxTrack->GetQp() > 0) ? 1 : -1;
+  cand->fEnergy   = sqrt(cand->fMomentum.Mag2() + cand->fMass * cand->fMass);
+  cand->fRapidity = 0.5 * TMath::Log((cand->fEnergy + cand->fMomentum.Z()) / (cand->fEnergy - cand->fMomentum.Z()));
+}
+
+void LmvmUtils::CalculateArmPodParams(LmvmCand* cand1, LmvmCand* cand2, double& alpha, double& ptt)
+{
+  alpha = ptt = 0.;
+  double spx  = cand1->fMomentum.X() + cand2->fMomentum.X();
+  double spy  = cand1->fMomentum.Y() + cand2->fMomentum.Y();
+  double spz  = cand1->fMomentum.Z() + cand2->fMomentum.Z();
+  double sp   = sqrt(spx * spx + spy * spy + spz * spz);
+
+  if (sp == 0.0) return;
+  double pn, /*pp,*/ pln, plp;
+  if (cand1->fCharge < 0.) {
+    pn = cand1->fMomentum.Mag();
+    //pp = cand2->fMomentum.Mag();
+    pln = (cand1->fMomentum.X() * spx + cand1->fMomentum.Y() * spy + cand1->fMomentum.Z() * spz) / sp;
+    plp = (cand2->fMomentum.X() * spx + cand2->fMomentum.Y() * spy + cand2->fMomentum.Z() * spz) / sp;
+  }
+  else {
+    pn = cand2->fMomentum.Mag();
+    //pp = cand1->fMomentum.Mag();
+    pln = (cand2->fMomentum.X() * spx + cand2->fMomentum.Y() * spy + cand2->fMomentum.Z() * spz) / sp;
+    plp = (cand1->fMomentum.X() * spx + cand1->fMomentum.Y() * spy + cand1->fMomentum.Z() * spz) / sp;
+  }
+  if (pn == 0.0) return;
+  double ptm = (1. - ((pln / pn) * (pln / pn)));
+  ptt        = (ptm >= 0.) ? pn * sqrt(ptm) : 0;
+  alpha      = (plp - pln) / (plp + pln);
+}
+
+ELmvmSrc LmvmUtils::GetMcSrc(CbmMCTrack* mctrack, TClonesArray* mcTracks)
+{
+  if (IsMcSignalEl(mctrack)) return ELmvmSrc::Signal;
+  if (IsMcPi0El(mctrack, mcTracks)) return ELmvmSrc::Pi0;
+  if (IsMcGammaEl(mctrack, mcTracks)) return ELmvmSrc::Gamma;
+  if (IsMcEtaEl(mctrack, mcTracks)) return ELmvmSrc::Eta;
+  return ELmvmSrc::Bg;  // all bg track wich are not pi0, gamma, eta electrons
+}
+
+bool LmvmUtils::IsMcSignalEl(const CbmMCTrack* mct)
+{
+  if (mct != nullptr && mct->GetGeantProcessId() == kPPrimary && std::abs(mct->GetPdgCode()) == 11) return true;
+  return false;
+}
+
+bool LmvmUtils::IsMcGammaEl(const CbmMCTrack* mct, TClonesArray* mcTracks)
+{
+  if (mct == nullptr || std::abs(mct->GetPdgCode()) != 11 || mct->GetMotherId() < 0) return false;
+  CbmMCTrack* mct1 = static_cast<CbmMCTrack*>(mcTracks->At(mct->GetMotherId()));
+  if (mct1 != nullptr && mct1->GetPdgCode() == 22) return true;
+  return false;
+}
+
+bool LmvmUtils::IsMcPi0El(const CbmMCTrack* mct, TClonesArray* mcTracks)
+{
+  if (mct == nullptr || std::abs(mct->GetPdgCode()) != 11 || mct->GetMotherId() < 0) return false;
+  CbmMCTrack* mct1 = static_cast<CbmMCTrack*>(mcTracks->At(mct->GetMotherId()));
+  if (mct1 != nullptr && mct1->GetPdgCode() == 111) return true;
+  return false;
+}
+
+bool LmvmUtils::IsMcEtaEl(const CbmMCTrack* mct, TClonesArray* mcTracks)
+{
+  if (mct == nullptr || std::abs(mct->GetPdgCode()) != 11 || mct->GetMotherId() < 0) return false;
+  CbmMCTrack* mct1 = static_cast<CbmMCTrack*>(mcTracks->At(mct->GetMotherId()));
+  if (mct1 != NULL && mct1->GetPdgCode() == 221) return true;
+  return false;
+}
+
+bool LmvmUtils::IsMcPairSignal(const CbmMCTrack* mctP, const CbmMCTrack* mctM)
+{
+  return (IsMcSignalEl(mctM) && IsMcSignalEl(mctP));
+}
+
+bool LmvmUtils::IsMcPairPi0(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks)
+{
+  return ((mctM->GetMotherId() == mctP->GetMotherId()) && IsMcPi0El(mctM, mcTracks) && IsMcPi0El(mctP, mcTracks));
+}
+
+bool LmvmUtils::IsMcPairEta(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks)
+{
+  return ((mctM->GetMotherId() == mctP->GetMotherId()) && IsMcEtaEl(mctM, mcTracks) && IsMcEtaEl(mctP, mcTracks));
+}
+
+bool LmvmUtils::IsMcPairGamma(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks)
+{
+  return ((mctM->GetMotherId() == mctP->GetMotherId()) && IsMcGammaEl(mctM, mcTracks) && IsMcGammaEl(mctP, mcTracks));
+}
+
+bool LmvmUtils::IsMcPairBg(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks)
+{
+  bool isGamma = IsMcPairGamma(mctP, mctM, mcTracks);
+  bool isEta   = IsMcPairEta(mctP, mctM, mcTracks);
+  bool isPi0   = IsMcPairPi0(mctP, mctM, mcTracks);
+  return (!isEta) && (!isGamma) && (!isPi0) && (!(IsMcSignalEl(mctP) || IsMcSignalEl(mctM)));
+}
+
+ELmvmSrc LmvmUtils::GetMcPairSrc(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks)
+{
+  if (IsMcPairSignal(mctP, mctM)) return ELmvmSrc::Signal;
+  if (IsMcPairGamma(mctP, mctM, mcTracks)) return ELmvmSrc::Gamma;
+  if (IsMcPairPi0(mctP, mctM, mcTracks)) return ELmvmSrc::Pi0;
+  if (IsMcPairEta(mctP, mctM, mcTracks)) return ELmvmSrc::Eta;
+  if (IsMcPairBg(mctP, mctM, mcTracks)) return ELmvmSrc::Bg;
+
+  return ELmvmSrc::Undefined;
+}
+
+
+bool LmvmUtils::IsMcPairSignal(const LmvmCand& candP, const LmvmCand& candM)
+{
+  return (candP.IsMcSignal() && candM.IsMcSignal());
+}
+
+bool LmvmUtils::IsMcPairPi0(const LmvmCand& candP, const LmvmCand& candM)
+{
+  return (candP.IsMcPi0() && candM.IsMcPi0() && candP.fMcMotherId == candM.fMcMotherId);
+}
+
+bool LmvmUtils::IsMcPairEta(const LmvmCand& candP, const LmvmCand& candM)
+{
+  return (candP.IsMcEta() && candM.IsMcEta() && candP.fMcMotherId == candM.fMcMotherId);
+}
+
+bool LmvmUtils::IsMcPairGamma(const LmvmCand& candP, const LmvmCand& candM)
+{
+  return (candP.IsMcGamma() && candM.IsMcGamma() && candP.fMcMotherId == candM.fMcMotherId);
+}
+
+bool LmvmUtils::IsMcPairBg(const LmvmCand& candP, const LmvmCand& candM)
+{
+  bool isGamma = IsMcPairGamma(candP, candM);
+  bool isEta   = IsMcPairEta(candP, candM);
+  bool isPi0   = IsMcPairPi0(candP, candM);
+  return (!isEta) && (!isGamma) && (!isPi0) && (!(candP.IsMcSignal() || candM.IsMcSignal()));
+}
+
+ELmvmSrc LmvmUtils::GetMcPairSrc(const LmvmCand& candP, const LmvmCand& candM)
+{
+  if (IsMcPairSignal(candP, candM)) return ELmvmSrc::Signal;
+  if (IsMcPairGamma(candP, candM)) return ELmvmSrc::Gamma;
+  if (IsMcPairPi0(candP, candM)) return ELmvmSrc::Pi0;
+  if (IsMcPairEta(candP, candM)) return ELmvmSrc::Eta;
+  if (IsMcPairBg(candP, candM)) return ELmvmSrc::Bg;
+
+  return ELmvmSrc::Undefined;
+}
+
+ELmvmBgPairSrc LmvmUtils::GetBgPairSrc(const LmvmCand& candP, const LmvmCand& candM)
+{
+  if (candM.IsMcGamma()) {
+    if (candP.IsMcGamma() && candP.fMcMotherId != candM.fMcMotherId) return ELmvmBgPairSrc::GG;
+    if (candP.IsMcPi0()) return ELmvmBgPairSrc::GP;
+    return ELmvmBgPairSrc::GO;
+  }
+  else if (candM.IsMcPi0()) {
+    if (candP.IsMcGamma()) return ELmvmBgPairSrc::GP;
+    if (candP.IsMcPi0() && candP.fMcMotherId != candM.fMcMotherId) return ELmvmBgPairSrc::PP;
+    return ELmvmBgPairSrc::PO;
+  }
+  else {
+    if (candP.IsMcGamma()) return ELmvmBgPairSrc::GO;
+    if (candP.IsMcPi0()) return ELmvmBgPairSrc::PO;
+    return ELmvmBgPairSrc::OO;
+  }
+
+  return ELmvmBgPairSrc::Undefined;
+}
+
+bool LmvmUtils::IsMismatch(const LmvmCand& cand)
+{
+  if (cand.fStsMcTrackId == cand.fRichMcTrackId && cand.fStsMcTrackId == cand.fTrdMcTrackId
+      && cand.fStsMcTrackId == cand.fTofMcTrackId && cand.fStsMcTrackId != -1)
+    return false;
+  return true;
+}
+
+bool LmvmUtils::IsGhost(const LmvmCand& cand)
+{
+  if (cand.fStsMcTrackId == -1 || cand.fRichMcTrackId == -1 || cand.fTrdMcTrackId == -1 || cand.fTofMcTrackId == -1)
+    return true;
+  return false;
+}
+
+double LmvmUtils::Distance(double x1, double y1, double x2, double y2) { return std::sqrt(Distance2(x1, y1, x2, y2)); }
+
+double LmvmUtils::Distance2(double x1, double y1, double x2, double y2)
+{
+  return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
+}
+
+void LmvmUtils::IsElectron(int globalTrackIndex, double momentum, double momentumCut, LmvmCand* cand)
+{
+  bool richEl    = CbmLitGlobalElectronId::GetInstance().IsRichElectron(globalTrackIndex, momentum);
+  cand->fRichAnn = CbmLitGlobalElectronId::GetInstance().GetRichAnn(globalTrackIndex, momentum);
+  bool trdEl     = CbmLitGlobalElectronId::GetInstance().IsTrdElectron(globalTrackIndex, momentum);
+  cand->fTrdAnn  = CbmLitGlobalElectronId::GetInstance().GetTrdAnn(globalTrackIndex, momentum);
+  bool tofEl     = CbmLitGlobalElectronId::GetInstance().IsTofElectron(globalTrackIndex, momentum);
+  cand->fMass2   = CbmLitGlobalElectronId::GetInstance().GetTofM2(globalTrackIndex, momentum);
+  bool isMomCut  = (momentumCut > 0.) ? (momentum < momentumCut) : true;
+
+  cand->fIsElectron = (richEl && trdEl && tofEl && isMomCut);
+}
+
+void LmvmUtils::IsElectronMc(LmvmCand* cand, TClonesArray* mcTracks, double pionMisidLevel)
+{
+  // Use MC information for PID to set a required level of pion suppression
+  if (cand->fStsMcTrackId < 0 || cand->fStsMcTrackId >= mcTracks->GetEntriesFast()) { cand->fIsElectron = false; }
+  else {
+    CbmMCTrack* mcTrack = static_cast<CbmMCTrack*>(mcTracks->At(cand->fStsMcTrackId));
+    if (std::abs(mcTrack->GetPdgCode()) == 11) { cand->fIsElectron = true; }
+    else {
+      cand->fIsElectron = (gRandom->Rndm() < pionMisidLevel);
+    }
+  }
+}
+
+string LmvmUtils::GetChargeStr(const LmvmCand* cand)
+{
+  if (cand->fCharge == 0) return "0";
+  return (cand->fCharge > 0) ? "+" : "-";
+}
+
+string LmvmUtils::GetChargeStr(const CbmMCTrack* mct)
+{
+  if (mct->GetCharge() == 0) return "0";
+  return (mct->GetCharge() > 0) ? "+" : "-";
+}
diff --git a/analysis/PWGDIL/dielectron/lmvm/LmvmUtils.h b/analysis/PWGDIL/dielectron/lmvm/LmvmUtils.h
index 21faaf740c7e44be305a91502b3d916405739311..27e79ee656d884d56eaaec2b7a4a998270d4a27b 100644
--- a/analysis/PWGDIL/dielectron/lmvm/LmvmUtils.h
+++ b/analysis/PWGDIL/dielectron/lmvm/LmvmUtils.h
@@ -1,151 +1,100 @@
-/* Copyright (C) 2015-2016 Justus-Liebig-Universitaet Giessen, Giessen
+/* Copyright (C) 2015-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Elena Lebedeva [committer] */
+   Authors: Elena Lebedeva [committer], Semen Lebedev */
 
-/**
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2015
- * @version 1.0
- **/
+#ifndef LMVM_UTILS_H
+#define LMVM_UTILS_H
 
+#include "LmvmDef.h"
 
-#ifndef CBM_LMVM_UTILS_H
-#define CBM_LMVM_UTILS_H
+class CbmKFVertex;
+class LmvmCand;
+class CbmMCTrack;
+class TClonesArray;
+class CbmStsTrack;
 
-#include "CbmKFVertex.h"
-#include "CbmL1PFFitter.h"
-#include "CbmLmvmCandidate.h"
-#include "CbmMCTrack.h"
-#include "CbmStsTrack.h"
-
-#include "TClonesArray.h"
-#include "TDatabasePDG.h"
-#include "TMCProcess.h"
-
-class CbmLmvmUtils {
+class LmvmUtils {
 public:
+  LmvmUtils() { ; }
+  virtual ~LmvmUtils() { ; }
+
   /*
-	 * Calculates and set track parameters to CbmLmvmCandidate.
+	 * Calculates and set track parameters to LmvmCand.
 	 * The following parameters are set: fChi2sts, fChi2Prim, fPosition, fMomentum, fMass, fCharge, fEnergy, fRapidity
 	 */
-  static void CalculateAndSetTrackParamsToCandidate(CbmLmvmCandidate* cand, CbmStsTrack* stsTrack,
-                                                    CbmKFVertex& kfVertex)
-  {
-    CbmL1PFFitter fPFFitter;
-    vector<CbmStsTrack> stsTracks;
-    stsTracks.resize(1);
-    stsTracks[0] = *stsTrack;
-    vector<L1FieldRegion> vField;
-    vector<float> chiPrim;
-    fPFFitter.GetChiToVertex(stsTracks, vField, chiPrim, kfVertex, 3e6);
-    cand->fChi2sts                 = stsTracks[0].GetChiSq() / stsTracks[0].GetNDF();
-    cand->fChi2Prim                = chiPrim[0];
-    const FairTrackParam* vtxTrack = stsTracks[0].GetParamFirst();
-
-    vtxTrack->Position(cand->fPosition);
-    vtxTrack->Momentum(cand->fMomentum);
-
-    cand->fMass     = TDatabasePDG::Instance()->GetParticle(11)->Mass();
-    cand->fCharge   = (vtxTrack->GetQp() > 0) ? 1 : -1;
-    cand->fEnergy   = sqrt(cand->fMomentum.Mag2() + cand->fMass * cand->fMass);
-    cand->fRapidity = 0.5 * TMath::Log((cand->fEnergy + cand->fMomentum.Z()) / (cand->fEnergy - cand->fMomentum.Z()));
-  }
+  static void CalculateAndSetTrackParams(LmvmCand* cand, CbmStsTrack* stsTrack, CbmKFVertex& kfVertex);
 
   /*
 	 * Armenteros - Podolansky plot
 	 */
-  static void CalculateArmPodParams(CbmLmvmCandidate* cand1, CbmLmvmCandidate* cand2, Double_t& alpha, Double_t& ptt)
-  {
-    alpha = ptt  = 0.;
-    Double_t spx = cand1->fMomentum.X() + cand2->fMomentum.X();
-    Double_t spy = cand1->fMomentum.Y() + cand2->fMomentum.Y();
-    Double_t spz = cand1->fMomentum.Z() + cand2->fMomentum.Z();
-    Double_t sp  = sqrt(spx * spx + spy * spy + spz * spz);
-
-    if (sp == 0.0) return;
-    Double_t pn, /*pp,*/ pln, plp;
-    if (cand1->fCharge < 0.) {
-      pn = cand1->fMomentum.Mag();
-      //pp = cand2->fMomentum.Mag();
-      pln = (cand1->fMomentum.X() * spx + cand1->fMomentum.Y() * spy + cand1->fMomentum.Z() * spz) / sp;
-      plp = (cand2->fMomentum.X() * spx + cand2->fMomentum.Y() * spy + cand2->fMomentum.Z() * spz) / sp;
-    }
-    else {
-      pn = cand2->fMomentum.Mag();
-      //pp = cand1->fMomentum.Mag();
-      pln = (cand2->fMomentum.X() * spx + cand2->fMomentum.Y() * spy + cand2->fMomentum.Z() * spz) / sp;
-      plp = (cand1->fMomentum.X() * spx + cand1->fMomentum.Y() * spy + cand1->fMomentum.Z() * spz) / sp;
-    }
-    if (pn == 0.0) return;
-    Double_t ptm = (1. - ((pln / pn) * (pln / pn)));
-    ptt          = (ptm >= 0.) ? pn * sqrt(ptm) : 0;
-    alpha        = (plp - pln) / (plp + pln);
-  }
+  static void CalculateArmPodParams(LmvmCand* cand1, LmvmCand* cand2, double& alpha, double& ptt);
+
+  static ELmvmSrc GetMcSrc(CbmMCTrack* mctrack, TClonesArray* mcTracks);
 
   /*
 	 * \brief Return true if MC track is signal primary electron.
 	 */
-  static Bool_t IsMcSignalElectron(CbmMCTrack* mctrack)
-  {
-    if (mctrack == NULL) return false;
-    Int_t pdg = TMath::Abs(mctrack->GetPdgCode());
-    if (mctrack->GetGeantProcessId() == kPPrimary && pdg == 11) return true;
-    return false;
-  }
+  static bool IsMcSignalEl(const CbmMCTrack* mct);
 
   /*
 	 * \brief Return true if MC track is electron from gamma conversion.
 	 */
-  static Bool_t IsMcGammaElectron(CbmMCTrack* mctrack, TClonesArray* mcTracks)
-  {
-    if (mctrack == NULL) return false;
-    Int_t pdg = TMath::Abs(mctrack->GetPdgCode());
-    if (pdg != 11) return false;
-    Int_t motherId = mctrack->GetMotherId();
-    if (motherId < 0) { return false; }
-    else {
-      CbmMCTrack* mct1 = static_cast<CbmMCTrack*>(mcTracks->At(motherId));
-      Int_t motherPdg  = mct1->GetPdgCode();
-      if (mct1 != NULL && motherPdg == 22 && pdg == 11) { return true; }
-    }
-    return false;
-  }
+  static bool IsMcGammaEl(const CbmMCTrack* mct, TClonesArray* mcTracks);
 
   /*
 	 * \brief Return true if MC track is electron from Pi0 dalitz decay.
 	 */
-  static Bool_t IsMcPi0Electron(CbmMCTrack* mctrack, TClonesArray* mcTracks)
-  {
-    if (mctrack == NULL) return false;
-    Int_t pdg = TMath::Abs(mctrack->GetPdgCode());
-    if (pdg != 11) return false;
-    Int_t motherId = mctrack->GetMotherId();
-    if (motherId < 0) { return false; }
-    else {
-      CbmMCTrack* mct1 = static_cast<CbmMCTrack*>(mcTracks->At(motherId));
-      Int_t motherPdg  = mct1->GetPdgCode();
-      if (mct1 != NULL && motherPdg == 111 && pdg == 11 && mctrack->GetGeantProcessId() != kPPrimary) { return true; }
-    }
-    return false;
-  }
+  static bool IsMcPi0El(const CbmMCTrack* mct, TClonesArray* mcTracks);
 
   /*
 	 * \brief Return true if MC track is electron from Eta decay.
 	 */
-  static Bool_t IsMcEtaElectron(CbmMCTrack* mctrack, TClonesArray* mcTracks)
-  {
-    if (mctrack == NULL) return false;
-    Int_t pdg = TMath::Abs(mctrack->GetPdgCode());
-    if (pdg != 11) return false;
-    Int_t motherId = mctrack->GetMotherId();
-    if (motherId < 0) { return false; }
-    else {
-      CbmMCTrack* mct1 = static_cast<CbmMCTrack*>(mcTracks->At(motherId));
-      Int_t motherPdg  = mct1->GetPdgCode();
-      if (mct1 != NULL && motherPdg == 221 && pdg == 11) { return true; }
-    }
-    return false;
-  }
+  static bool IsMcEtaEl(const CbmMCTrack* mct, TClonesArray* mcTracks);
+
+  static bool IsMcPairSignal(const CbmMCTrack* mctP, const CbmMCTrack* mctM);
+
+  static bool IsMcPairPi0(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks);
+
+  static bool IsMcPairEta(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks);
+
+  static bool IsMcPairGamma(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks);
+
+  static bool IsMcPairBg(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks);
+
+  static ELmvmSrc GetMcPairSrc(const CbmMCTrack* mctP, const CbmMCTrack* mctM, TClonesArray* mcTracks);
+
+
+  static bool IsMcPairSignal(const LmvmCand& candP, const LmvmCand& candM);
+
+  static bool IsMcPairPi0(const LmvmCand& candP, const LmvmCand& candM);
+
+  static bool IsMcPairEta(const LmvmCand& candP, const LmvmCand& candM);
+
+  static bool IsMcPairGamma(const LmvmCand& candP, const LmvmCand& candM);
+
+  static bool IsMcPairBg(const LmvmCand& candP, const LmvmCand& candM);
+
+  static ELmvmSrc GetMcPairSrc(const LmvmCand& candP, const LmvmCand& candM);
+
+  static ELmvmBgPairSrc GetBgPairSrc(const LmvmCand& candP, const LmvmCand& candM);
+
+  static bool IsMismatch(const LmvmCand& cand);
+
+  static bool IsGhost(const LmvmCand& cand);
+
+  static double Distance(double x1, double y1, double x2, double y2);
+
+  static double Distance2(double x1, double y1, double x2, double y2);
+
+  static void IsElectron(int globalTrackIndex, double momentum, double momentumCut, LmvmCand* cand);
+
+  static void IsElectronMc(LmvmCand* cand, TClonesArray* mcTracks, double pionMisidLevel);
+
+  static std::string GetChargeStr(const LmvmCand* cand);
+
+  static std::string GetChargeStr(const CbmMCTrack* mct);
+
+  ClassDef(LmvmUtils, 1);
 };
 
 #endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronReports.cxx b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronReports.cxx
index edf968d6aa41357e716c856ab50954a8912fe4f4..2c55fe8e497c902a0e592bed23ab6bb599472d87 100644
--- a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronReports.cxx
+++ b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronReports.cxx
@@ -2,11 +2,6 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev [committer] */
 
-/**
- * \file CbmAnaDielectronReports.cxx
- * \author Semen Lebedev <s.lebedev@gsi.de>
- * \date 2012
- */
 #include "CbmAnaDielectronReports.h"
 
 #include "CbmAnaDielectronStudyReportAll.h"
diff --git a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronReports.h b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronReports.h
index 7fd55d5317bd4e263b5e176afc9366c15b0e2615..7d1b83f0558fbdfe5bc4b04ab2b345076f595fd3 100644
--- a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronReports.h
+++ b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronReports.h
@@ -2,12 +2,6 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev [committer] */
 
-/**
- * \file CbmAnaDielectronReports.h
- * \brief Main class wrapper for report generation.
- * \author Semen Lebedev <s.lebedev@gsi.de>
- * \date 2012
- */
 #ifndef CBM_ANA_DIELECTRON_REPORTS
 #define CBM_ANA_DIELECTRON_REPORTS
 
diff --git a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronStudyReportAll.cxx b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronStudyReportAll.cxx
index e00de9a53d5c8572b56fa9d96ec61c1a0f092b23..5942e4f9e9c9249158b5eb3260bd705673ddd65c 100644
--- a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronStudyReportAll.cxx
+++ b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronStudyReportAll.cxx
@@ -6,7 +6,6 @@
 
 #include "CbmDrawHist.h"
 #include "CbmHistManager.h"
-#include "CbmLmvmHist.h"
 #include "CbmReportElement.h"
 #include "CbmUtils.h"
 
@@ -15,6 +14,8 @@
 #include <boost/assign/list_of.hpp>
 
 #include <sstream>
+
+#include "LmvmHist.h"
 using boost::assign::list_of;
 using std::string;
 using std::stringstream;
@@ -41,13 +42,12 @@ void CbmAnaDielectronStudyReportAll::Draw()
 {
   SetDefaultDrawStyle();
   DrawBgMinv();
-  DrawSBgMinv();
 }
 
 void CbmAnaDielectronStudyReportAll::DrawBgMinv()
 {
   Int_t nofStudies = HM().size();
-  CreateCanvas("lmvm_study_report_bg_minv_ptcut", "lmvm_study_report_bg_minv_ptcut", 600, 600);
+  CreateCanvas("lmvmStudyAll_minvBg_ptcut", "lmvmStudyAll_minvBg_ptcut", 1000, 1000);
   vector<TH1*> histos1(nofStudies);
   vector<string> legendNames;
   for (Int_t iStudy = 0; iStudy < nofStudies; iStudy++) {
@@ -60,19 +60,3 @@ void CbmAnaDielectronStudyReportAll::DrawBgMinv()
   }
   DrawH1(histos1, legendNames, kLinear, kLinear, true, 0.6, 0.75, 0.99, 0.99);
 }
-
-void CbmAnaDielectronStudyReportAll::DrawSBgMinv()
-{
-  Int_t nofStudies = HM().size();
-  CreateCanvas("lmvm_study_report_sbg_vs_minv_ptcut", "lmvm_study_report_sbg_vs_minv_ptcut", 600, 600);
-  vector<TH1*> histos1(nofStudies);
-  vector<string> legendNames;
-  for (Int_t iStudy = 0; iStudy < nofStudies; iStudy++) {
-    histos1[iStudy] = HM()[iStudy]->H1("fh_sbg_vs_minv_ptcut");
-    // histos1[iStudy]->Rebin(4);;
-    // histos1[iStudy]->Scale(1./4.);
-    histos1[iStudy]->GetXaxis()->SetRangeUser(0, 2.);
-    legendNames.push_back(GetStudyNames()[iStudy]);
-  }
-  DrawH1(histos1, legendNames, kLinear, kLog, true, 0.6, 0.75, 0.99, 0.99);
-}
diff --git a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronStudyReportAll.h b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronStudyReportAll.h
index 83eae4832da4948412e6fcd2a673de00fb356d64..19f68b5b4cf7639e73cfb9df4bda01c30aab0fda 100644
--- a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronStudyReportAll.h
+++ b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaDielectronStudyReportAll.h
@@ -39,11 +39,6 @@ protected:
    * \brief Draw Invariant mass of combinatorial BG.
    */
   void DrawBgMinv();
-
-  /**
-   * \brief Draw S/Bg ratio vs invariant mass.
-   */
-  void DrawSBgMinv();
 };
 
 #endif
diff --git a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaLmvmDrawStudy.cxx b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaLmvmDrawStudy.cxx
index 8f2b22bd4fd219c96e8cc1b636703a945a7fdf9f..21962ac43cc256069e8d3b01504223385ce45238 100644
--- a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaLmvmDrawStudy.cxx
+++ b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaLmvmDrawStudy.cxx
@@ -2,12 +2,6 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Elena Lebedeva [committer] */
 
-/** CbmAnaLmvmDrawStudy.cxx
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2011
- * @version 2.0
- **/
-
 #include "CbmAnaLmvmDrawStudy.h"
 
 #include "CbmDrawHist.h"
@@ -57,8 +51,6 @@ void CbmAnaLmvmDrawStudy::DrawFromFile(const vector<string>& fileNames, const ve
     fHM[i]      = new CbmHistManager();
     TFile* file = new TFile(fileNames[i].c_str());
     fHM[i]->ReadFromFile(file);
-    Int_t fNofEvents = (int) H1(i, "fh_event_number")->GetEntries();
-    fHM[i]->ScaleByPattern(".*", 1. / fNofEvents);
   }
 
   // files with mean histograms
@@ -70,15 +62,6 @@ void CbmAnaLmvmDrawStudy::DrawFromFile(const vector<string>& fileNames, const ve
   fStudyNames = studyNames;
 
   DrawMinv();
-  DrawNofBgTracks();
-  DrawBgSourceTracks();
-  DrawBgSourcePairs();
-  DrawBgSourceMinv();
-  DrawDistributions("lmvm_study_source_mom_", "fh_source_mom_", kTtCut, kPi0);
-  DrawDistributions("lmvm_study_source_mom_", "fh_source_mom_", kTtCut, kGamma);
-
-  DrawDistributions("lmvm_study_source_pt_", "fh_source_pt_", kTtCut, kPi0);
-  DrawDistributions("lmvm_study_source_pt_", "fh_source_pt_", kTtCut, kGamma);
 
   SaveCanvasToImage();
 
@@ -87,27 +70,6 @@ void CbmAnaLmvmDrawStudy::DrawFromFile(const vector<string>& fileNames, const ve
   gDirectory = oldDir;
 }
 
-TCanvas* CbmAnaLmvmDrawStudy::CreateCanvas(const string& name, const string& title, int width, int height)
-{
-  TCanvas* c = new TCanvas(name.c_str(), title.c_str(), width, height);
-  fCanvas.push_back(c);
-  return c;
-}
-
-void CbmAnaLmvmDrawStudy::DrawTextOnHist(const string& text, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
-{
-  TLegend* leg = new TLegend(x1, y1, x2, y2);
-  leg->AddEntry(new TH2D(), text.c_str(), "");
-  leg->SetFillColor(kWhite);
-  leg->SetFillStyle(0);
-  leg->SetBorderSize(0);
-  leg->Draw();
-}
-
-TH1D* CbmAnaLmvmDrawStudy::H1(int studyNum, const string& name) { return (TH1D*) fHM[studyNum]->H1(name); }
-
-TH2D* CbmAnaLmvmDrawStudy::H2(int studyNum, const string& name) { return (TH2D*) fHM[studyNum]->H1(name); }
-
 void CbmAnaLmvmDrawStudy::SaveCanvasToImage()
 {
   for (unsigned int i = 0; i < fCanvas.size(); i++) {
@@ -115,14 +77,6 @@ void CbmAnaLmvmDrawStudy::SaveCanvasToImage()
   }
 }
 
-void CbmAnaLmvmDrawStudy::SetAnalysisStepLabels(TH1* h)
-{
-  h->GetXaxis()->SetLabelSize(0.06);
-  for (Int_t step = 0; step < CbmLmvmHist::fNofAnaSteps; step++) {
-    h->GetXaxis()->SetBinLabel(step + 1, CbmLmvmHist::fAnaStepsLatex[step].c_str());
-  }
-}
-
 void CbmAnaLmvmDrawStudy::DrawMinv()
 {
   /// Save old global file and folder pointer to avoid messing with FairRoot
@@ -144,180 +98,17 @@ void CbmAnaLmvmDrawStudy::DrawMinv()
     hPtCut[i]->SetMinimum(1e-6);
     //f->Close();
   }
-  CreateCanvas("lmvm_study_minv_bg_ttcut", "lmvm_study_minv_bg_ttcut", 600, 600);
+  fHM[0]->CreateCanvas("lmvm_study_minv_bg_ttcut", "lmvm_study_minv_bg_ttcut", 600, 600);
   DrawH1(hTtCut, fStudyNames, kLinear, kLog, true, 0.70, 0.55, 0.99, 0.99, "");
 
-  CreateCanvas("lmvm_study_minv_bg_ptcut", "lmvm_study_minv_bg_ptcut", 600, 600);
+  fHM[0]->CreateCanvas("lmvm_study_minv_bg_ptcut", "lmvm_study_minv_bg_ptcut", 600, 600);
   DrawH1(hPtCut, fStudyNames, kLinear, kLog, true, 0.70, 0.55, 0.99, 0.99, "");
 
 
-  /* TCanvas *c1 = CreateCanvas("lmvm_study_minv_urqmd", "lmvm_study_minv_urqmd", 900, 900);
-   vector<TH1*> hbg;
-   hbg.resize(fNofStudies);
-   for (int i = 0; i < fNofStudies; i++){
-      hbg[i] = (TH1D*)H1(i, "fh_bg_minv_ptcut")->Clone();
-      hbg[i]->Rebin(20);
-     // hbg[i]->GetYaxis()->SetTitle("Tracks/event x10^{-1}");
-      //hbg[i]->GetXaxis()->SetRange(kElId + 1, kPtCut + 1);
-      hbg[i]->SetMinimum(1e-6);
-   }
-   //SetAnalysisStepLabels(hbg[0]);
-   DrawH1(hbg, fStudyNames, kLinear, kLog, true, 0.70, 0.75, 0.99, 0.99, "");
-   for (int i = 0; i < fNofStudies; i++){
-      hbg[i]->SetLineWidth(3.);
-   */
-
   /// Restore old global file and folder pointer to avoid messing with FairRoot
   gFile      = oldFile;
   gDirectory = oldDir;
 }
 
-void CbmAnaLmvmDrawStudy::DrawNofBgTracks()
-{
-  CreateCanvas("lmvm_study_nof_bg_tracks", "lmvm_study_nof_bg_tracks", 600, 600);
-  vector<TH1*> hbg;
-  hbg.resize(fNofStudies);
-  for (int i = 0; i < fNofStudies; i++) {
-    hbg[i] = (TH1D*) H1(i, "fh_nof_bg_tracks")->Clone();
-    hbg[i]->Scale(10);
-    hbg[i]->GetYaxis()->SetTitle("Tracks/event x10^{-1}");
-    hbg[i]->GetXaxis()->SetRange(kElId + 1, kPtCut + 1);
-    hbg[i]->SetMinimum(0.0);
-  }
-  SetAnalysisStepLabels(hbg[0]);
-  DrawH1(hbg, fStudyNames, kLinear, kLinear, true, 0.70, 0.75, 0.99, 0.99, "");
-  for (int i = 0; i < fNofStudies; i++) {
-    hbg[i]->SetLineWidth(3.);
-  }
-}
-
-void CbmAnaLmvmDrawStudy::DrawBgSourceTracks()
-{
-  TCanvas* c = CreateCanvas("lmvm_study_source_tracks_abs", "lmvm_study_source_tracks_abs", 1200, 400);
-  c->Divide(3, 1);
-  for (int iP = 0; iP < 3; iP++) {
-    c->cd(iP + 1);
-    vector<TH1*> habsPx;
-    habsPx.resize(fNofStudies);
-    for (int i = 0; i < fNofStudies; i++) {
-      TH2D* habs = (TH2D*) H2(i, "fh_source_tracks")->Clone();
-      int min    = iP + 1;
-      int max    = iP + 1;
-      if (iP == 2) max = 9;
-      stringstream ss;
-      ss << "fh_source_tracks_" << i << "_" << min << "_" << max;
-      habsPx[i] = habs->ProjectionX(ss.str().c_str(), min, max);
-      habsPx[i]->GetXaxis()->SetRange(kElId + 1, kPtCut + 1);
-      habsPx[i]->GetYaxis()->SetTitle("Tracks per event x10^{-2}");
-      habsPx[i]->Scale(100);
-    }
-    DrawH1(habsPx, fStudyNames, kLinear, kLinear, true, 0.70, 0.75, 0.99, 0.99, "");
-    SetAnalysisStepLabels(habsPx[0]);
-    for (int i = 0; i < fNofStudies; i++) {
-      habsPx[i]->SetMinimum(0.);
-      habsPx[i]->SetLineWidth(3.);
-    }
-    string txt = "#gamma";
-    if (iP == 1) txt = "#pi^{0}";
-    if (iP == 2) txt = "oth.";
-    DrawTextOnHist(txt, 0.5, 0.9, 0.6, 0.99);
-  }
-}
-
-void CbmAnaLmvmDrawStudy::DrawBgSourcePairs()
-{
-  TCanvas* c = CreateCanvas("lmvm_study_source_pairs_abs", "lmvm_study_source_pairs_abs", 1200, 800);
-  c->Divide(3, 2);
-  for (int iP = 0; iP < 6; iP++) {
-    c->cd(iP + 1);
-    vector<TH1*> habsPx;
-    habsPx.resize(fNofStudies);
-    for (int i = 0; i < fNofStudies; i++) {
-      TH2D* habs = (TH2D*) H2(i, "fh_source_pairs")->Clone();
-      int min    = iP + 1;
-      int max    = iP + 1;
-      stringstream ss;
-      ss << "fh_source_pairs_" << i << "_" << min << "_" << max;
-      habsPx[i] = habs->ProjectionX(ss.str().c_str(), min, max);
-      habsPx[i]->GetXaxis()->SetRange(kElId + 1, kPtCut + 1);
-      habsPx[i]->GetYaxis()->SetTitle("Pairs per event x10^{-3}");
-      habsPx[i]->Scale(1000);
-    }
-    DrawH1(habsPx, fStudyNames, kLinear, kLinear, true, 0.70, 0.75, 0.99, 0.99, "");
-    SetAnalysisStepLabels(habsPx[0]);
-    for (int i = 0; i < fNofStudies; i++) {
-      habsPx[i]->SetMinimum(0.);
-      habsPx[i]->SetLineWidth(3.);
-    }
-    DrawTextOnHist(CbmLmvmHist::fBgPairSourceLatex[iP], 0.4, 0.9, 0.6, 0.99);
-  }
-
-  DrawBgSourcePairsStep(kPtCut);
-  DrawBgSourcePairsStep(kTtCut);
-}
-
-void CbmAnaLmvmDrawStudy::DrawBgSourcePairsStep(int step)
-{
-  stringstream ssC;
-  ssC << "lmvm_study_source_pairs_" << CbmLmvmHist::fAnaSteps[step];
-  CreateCanvas(ssC.str().c_str(), ssC.str().c_str(), 600, 600);
-  vector<TH1*> habsPx;
-  habsPx.resize(fNofStudies);
-  for (int i = 0; i < fNofStudies; i++) {
-    TH2D* habs = (TH2D*) H2(i, "fh_source_pairs")->Clone();
-    stringstream ss;
-    ss << "fh_source_pairs_" << i << "_" << CbmLmvmHist::fAnaSteps[step];
-    habsPx[i] = habs->ProjectionY(ss.str().c_str(), step + 1, step + 1);
-    habsPx[i]->GetYaxis()->SetTitle("Pairs per event x10^{-3}");
-    habsPx[i]->Scale(1000);
-  }
-  DrawH1(habsPx, fStudyNames, kLinear, kLinear, true, 0.70, 0.75, 0.99, 0.99, "");
-  for (int i = 0; i < fNofStudies; i++) {
-    habsPx[i]->SetMinimum(0.);
-    habsPx[i]->SetLineWidth(3.);
-    for (UInt_t y = 1; y <= CbmLmvmHist::fBgPairSourceLatex.size(); y++) {
-      habsPx[i]->GetXaxis()->SetBinLabel(y, CbmLmvmHist::fBgPairSourceLatex[y - 1].c_str());
-    }
-  }
-}
-
-void CbmAnaLmvmDrawStudy::DrawDistributions(const string& canvasName, const string& histName, int step, int sourceType)
-{
-  stringstream ssC;
-  ssC << canvasName << CbmLmvmHist::fAnaSteps[step] << "_" << CbmLmvmHist::fSourceTypes[sourceType];
-  CreateCanvas(ssC.str().c_str(), ssC.str().c_str(), 900, 900);
-
-  string s = histName + CbmLmvmHist::fAnaSteps[step] + "_" + CbmLmvmHist::fSourceTypes[sourceType];
-  vector<TH1*> h;
-  h.resize(fNofStudies);
-  for (int i = 0; i < fNofStudies; i++) {
-    h[i] = (TH1D*) H1(i, s)->Clone();
-    h[i]->GetXaxis()->SetRangeUser(0., 3.);
-  }
-  DrawH1(h, fStudyNames, kLinear, kLinear, true, 0.70, 0.75, 0.99, 0.99, "");
-}
-
-void CbmAnaLmvmDrawStudy::DrawBgSourceMinv()
-{
-  TCanvas* c = CreateCanvas("lmvm_study_source_minv_ptcut", "lmvm_study_source_minv_ptcut", 1200, 800);
-  c->Divide(3, 2);
-  for (int iP = 0; iP < CbmLmvmHist::fNofBgPairSources; iP++) {
-    stringstream ss;
-    ss << "fh_source_bg_minv_" << iP << "_" << CbmLmvmHist::fAnaSteps[kPtCut];
-    c->cd(iP + 1);
-    vector<TH1*> habs;
-    habs.resize(fNofStudies);
-    for (int i = 0; i < fNofStudies; i++) {
-      habs[i] = (TH1D*) H1(i, ss.str())->Clone();
-      habs[i]->Rebin(40);
-    }
-    DrawH1(habs, fStudyNames, kLinear, kLinear, true, 0.70, 0.75, 0.99, 0.99, "");
-    for (int i = 0; i < fNofStudies; i++) {
-      habs[i]->SetMinimum(0.);
-      habs[i]->SetLineWidth(3.);
-    }
-    DrawTextOnHist(CbmLmvmHist::fBgPairSourceLatex[iP], 0.4, 0.9, 0.6, 0.99);
-  }
-}
 
 ClassImp(CbmAnaLmvmDrawStudy);
diff --git a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaLmvmDrawStudy.h b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaLmvmDrawStudy.h
index d27c1dfd4417cebd9e32e9805c424505a0259c6d..b49405a95074efe8004b24efae67f3ece96b486c 100644
--- a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaLmvmDrawStudy.h
+++ b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmAnaLmvmDrawStudy.h
@@ -2,22 +2,16 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Elena Lebedeva [committer], Florian Uhlig */
 
-/** CbmAnaLmvmDrawStudy.h
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2012
- * @version 1.0
- **/
-
 #ifndef CBM_ANA_LMVM_DRAW_STUDY
 #define CBM_ANA_LMVM_DRAW_STUDY
 
-#include "CbmLmvmHist.h"
-
 #include "TObject.h"
 
 #include <string>
 #include <vector>
 
+#include "LmvmHist.h"
+
 class TH1;
 class TH2D;
 class TH1D;
@@ -61,25 +55,9 @@ private:
 
   std::string fOutputDir;  // output directory for figures and .json file
 
-  TCanvas* CreateCanvas(const std::string& name, const std::string& title, int width, int height);
-
-  void DrawTextOnHist(const std::string& text, Double_t x1, Double_t y1, Double_t x2, Double_t y2);
-
-  TH1D* H1(int studyNum, const std::string& name);
-
-  TH2D* H2(int studyNum, const std::string& name);
-
   void SaveCanvasToImage();
 
-  void SetAnalysisStepLabels(TH1* h);
-
   void DrawMinv();
-  void DrawNofBgTracks();
-  void DrawBgSourceTracks();
-  void DrawBgSourcePairsStep(int step);
-  void DrawBgSourcePairs();
-  void DrawBgSourceMinv();
-  void DrawDistributions(const std::string& canvasName, const std::string& histName, int step, int sourceType);
 
   ClassDef(CbmAnaLmvmDrawStudy, 1);
 };
diff --git a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmHaddBase.h b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmHaddBase.h
index 9b887f51fed467086aed1901941ce90490de847b..4857aa6e03720e7c5859bb638852c6e5c9322c8e 100644
--- a/analysis/PWGDIL/dielectron/lmvm/legacy/CbmHaddBase.h
+++ b/analysis/PWGDIL/dielectron/lmvm/legacy/CbmHaddBase.h
@@ -2,13 +2,6 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev, Elena Lebedeva [committer] */
 
-/**
- * @author Elena Lebedeva <e.lebedeva@gsi.de>
- * @since 2015
- * @version 1.0
- **/
-
-
 #ifndef CBM_HADD_BASE_H
 #define CBM_HADD_BASE_H
 
diff --git a/core/base/CbmHistManager.h b/core/base/CbmHistManager.h
index 1cc64d1a7d6270e484a4cb7cd52c7504abc6283d..5294f3325adb7ef18df457729a592ecf681043cf 100644
--- a/core/base/CbmHistManager.h
+++ b/core/base/CbmHistManager.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011-2020 GSI/JINR-LIT, Darmstadt/Dubna
+/* Copyright (C) 2011-2021 GSI/JINR-LIT, Darmstadt/Dubna
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev, Andrey Lebedev [committer], Florian Uhlig */
 
@@ -134,6 +134,15 @@ public:
     Add(name, h);
   }
 
+  TNamed* GetObject(const std::string& name) const
+  {
+    if (fMap.count(name) == 0) {  // Temporarily used for debugging
+      LOG(error) << "CbmHistManager::GetObject(name): name=" << name;
+    }
+    assert(fMap.count(name) != 0);
+    return fMap.find(name)->second;
+  }
+
   /**
     * \brief Return pointer to TH1 histogram.
     * \param[in] name Name of histogram.
diff --git a/core/base/utils/CbmUtils.cxx b/core/base/utils/CbmUtils.cxx
index b45fab1cf5b69e80d4f7ae2a1c8e413cf7482991..c4448298030302f83ba26ee7ae2645e217939500 100644
--- a/core/base/utils/CbmUtils.cxx
+++ b/core/base/utils/CbmUtils.cxx
@@ -1,4 +1,4 @@
-/* Copyright (C) 2010-2020 GSI/JINR-LIT, Darmstadt/Dubna
+/* Copyright (C) 2010-2021 GSI/JINR-LIT, Darmstadt/Dubna
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Andrey Lebedev [committer], Florian Uhlig */
 
@@ -11,35 +11,38 @@
 #include <TH2.h>         // for TH2, TH2D
 #include <TSystem.h>     // for TSystem, gSystem
 
+#include "boost/filesystem.hpp"
+
 #include <string>  // for operator+, allocator, operator!=, char_traits
 #include <vector>  // for vector
 
 #include <stddef.h>  // for size_t
 
+using boost::filesystem::path;
 using std::string;
 using std::vector;
 
 namespace Cbm
 {
 
-  void SaveCanvasAsImage(TCanvas* c, const std::string& dir, const std::string& option)
+  void SaveCanvasAsImage(TCanvas* c, const string& dir, const string& option)
   {
     if (dir == "") return;
-    if (option.find("eps") != std::string::npos) {
-      string dir2 = dir + "/eps/";
-      gSystem->mkdir(dir2.c_str(),
-                     true);  // create directory if it does not exist
-      c->SaveAs(std::string(dir2 + std::string(c->GetTitle()) + ".eps").c_str());
-    }
-    if (option.find("png") != std::string::npos) {
-      string dir2 = dir + "/png/";
-      gSystem->mkdir(dir2.c_str(), true);
-      c->SaveAs(std::string(dir2 + std::string(c->GetTitle()) + ".png").c_str());
-    }
-    if (option.find("gif") != std::string::npos) {
-      string dir2 = dir + "/gif/";
-      gSystem->mkdir(dir2.c_str(), true);
-      c->SaveAs(std::string(dir2 + std::string(c->GetTitle()) + ".gif").c_str());
+    SaveCanvasAsImageImpl("eps", c, dir, option);
+    SaveCanvasAsImageImpl("png", c, dir, option);
+    SaveCanvasAsImageImpl("gif", c, dir, option);
+  }
+
+  void SaveCanvasAsImageImpl(const string& imageType, TCanvas* c, const string& dir, const string& option)
+  {
+    if (dir == "") return;
+    if (option.find(imageType) != string::npos) {
+      path fullPath  = path(dir + "/" + imageType + "/" + string(c->GetTitle()) + "." + imageType);
+      string fullDir = fullPath.parent_path().string();
+      if (fullDir.length() > 0) {
+        gSystem->mkdir(fullDir.c_str(), true);  // create directory if it does not exist
+      }
+      c->SaveAs(fullPath.c_str());
     }
   }
 
diff --git a/core/base/utils/CbmUtils.h b/core/base/utils/CbmUtils.h
index 2e7f67f1495f88afa77ad758c4eca1c2274a60ba..cb486b2ecc3948f389b438ddfc77e60fee575b40 100644
--- a/core/base/utils/CbmUtils.h
+++ b/core/base/utils/CbmUtils.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2010-2020 GSI/JINR-LIT, Darmstadt/Dubna
+/* Copyright (C) 2010-2021 GSI/JINR-LIT, Darmstadt/Dubna
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Andrey Lebedev [committer], Florian Uhlig */
 
@@ -47,6 +47,8 @@ namespace Cbm
   }
 
   void SaveCanvasAsImage(TCanvas* c, const std::string& dir, const std::string& option = "eps;png;gif");
+  void SaveCanvasAsImageImpl(const std::string& imageType, TCanvas* c, const std::string& dir,
+                             const std::string& option);
 
   std::string FindAndReplace(const std::string& name, const std::string& oldSubstr, const std::string& newSubstr);
 
diff --git a/macro/analysis/dielectron/batch_job.py b/macro/analysis/dielectron/batch_job.py
index 826203a3c51611ce8bb01945f17bc6fb8ab29ab9..07563982797cc0467eb6fae1b054f84631207db8 100755
--- a/macro/analysis/dielectron/batch_job.py
+++ b/macro/analysis/dielectron/batch_job.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python3
 
-import os     #operating system interfaces
-import sys    #provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter
-import shutil #offers a number of high level operations on files and collections of files
+import os     
+import sys    
+import shutil
 
 def main():
   dataDir = sys.argv[1]
@@ -10,7 +10,7 @@ def main():
   plutoParticle = sys.argv[3]
   cbmrootConfigPath = "/lustre/nyx/cbm/users/criesen/build/config.sh"
   macroDir = "/lustre/nyx/cbm/users/criesen/cbmroot/macro/analysis/dielectron/"
-  nofEvents = 100
+  nofEvents = 1000
 
   taskId = os.environ.get('SLURM_ARRAY_TASK_ID')
   jobId = os.environ.get('SLURM_ARRAY_JOB_ID')
@@ -27,26 +27,29 @@ def main():
   os.makedirs(workDir)
   os.chdir(workDir)
 
-  #plutoFile = ""
-  plutoFile = getPlutoPath(colSystem, colEnergy, plutoParticle, taskId) #this one was activated before
-  #plutoFile = getPlutoPath("auau", "8gev", plutoParticle, taskId)
+  plutoFile = getPlutoPath(colSystem, colEnergy, plutoParticle, taskId)
 
-  urqmdFile = "/lustre/nyx/cbm/prod/gen/urqmd/auau/" + colEnergy + "/centr/urqmd.auau.8gev.centr." + str(taskId).zfill(5) + ".root"
-  #urqmdFile = "/lustre/nyx/cbm/prod/gen/urqmd/auau/8gev/centr/urqmd.auau.8gev.centr.00001.root"
+  urqmdFile = "/lustre/nyx/cbm/prod/gen/urqmd/auau/" + colEnergy + "/centr/urqmd.auau."+ colEnergy + ".centr." + str(taskId).zfill(5) + ".root"
 
-  mcFile = dataDir + "/mc." + taskId + ".root"
+  traFile = dataDir + "/tra." + taskId + ".root"
   parFile = dataDir + "/param." + taskId + ".root"
   digiFile = dataDir + "/digi." + taskId + ".root"
   recoFile = dataDir + "/reco." + taskId + ".root"
   litQaFile = dataDir + "/litqa." + taskId + ".root"
   analysisFile = dataDir + "/analysis." + taskId + ".root"
   geoSimFile = dataDir + "/geosim." + taskId + ".root"
-  sEvBuildRaw = "Ideal"
-  #os.system(('root -l -b -q {}/run_sim.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, urqmdFile, plutoFile, mcFile, parFile, geoSimFile, geoSetup, nofEvents))
-  #os.system(('root -l -b -q {}/run_digi.C\(\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, mcFile, parFile, digiFile, nofEvents))
-  os.system(('root -l -b -q {}/run_reco.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, mcFile, parFile, digiFile, recoFile, geoSetup, sEvBuildRaw, nofEvents))
-  os.system(('root -l -b -q {}/run_litqa.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, mcFile, parFile, digiFile, recoFile, litQaFile, geoSetup, nofEvents))
-  os.system(('root -l -b -q {}/run_analysis.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, mcFile, parFile, digiFile, recoFile, analysisFile, plutoParticle, colSystem, colEnergy, geoSetup, nofEvents))
+
+  traCmd = ('root -l -b -q {}/run_transport.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, urqmdFile, plutoFile, traFile, parFile, geoSimFile, geoSetup, nofEvents)
+  digiCmd = ('root -l -b -q {}/run_digi.C\(\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, traFile, parFile, digiFile, nofEvents)
+  recoCmd = ('root -l -b -q {}/run_reco.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, traFile, parFile, digiFile, recoFile, geoSetup, nofEvents)
+  qaCmd = ('root -l -b -q {}/run_litqa.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, traFile, parFile, digiFile, recoFile, litQaFile, geoSetup, nofEvents)
+  anaCmd = ('root -l -b -q {}/run_analysis.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, traFile, parFile, digiFile, recoFile, analysisFile, plutoParticle, colSystem, colEnergy, geoSetup, nofEvents)
+
+  os.system((". /{} -a; {}").format(cbmrootConfigPath, traCmd))
+  os.system((". /{} -a; {}").format(cbmrootConfigPath, digiCmd))
+  os.system((". /{} -a; {}").format(cbmrootConfigPath, recoCmd))
+  os.system((". /{} -a; {}").format(cbmrootConfigPath, qaCmd))
+  os.system((". /{} -a; {}").format(cbmrootConfigPath, anaCmd))
 
 def getPlutoPath(colSystem, colEnergy, plutoParticle, taskId):
   if plutoParticle == "rho0":
diff --git a/macro/analysis/dielectron/batch_job_common.py b/macro/analysis/dielectron/batch_job_common.py
deleted file mode 100755
index 90b06b28e2c350ffad16d017035d640206b6aaae..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/batch_job_common.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python3
-
-import os     #operating system interfaces
-import sys    #provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter
-import shutil #offers a number of high - level operations on files and collections of files
-
-
-def main():
-  recoDataDirIn = sys.argv[1]
-  dataDirOut = sys.argv[2]
-  geoSetup = sys.argv[3]
-  plutoParticle = sys.argv[4]
-  
-  cbmrootConfigPath = "/lustre/nyx/cbm/users/criesen/build/config.sh"
-  macroDir = "/lustre/nyx/cbm/users/criesen/cbmroot/macro/analysis/dielectron/"
-  nofEvents = 100
-
-  taskId = os.environ.get('SLURM_ARRAY_TASK_ID')
-  jobId = os.environ.get('SLURM_ARRAY_JOB_ID')
-  colEnergy = "12gev"
-  colEnergyDir = "12agev"
-  colSystem = "auau"
-
-  print("recoDataDirIn:" + recoDataDirIn)
-  print("dataDirOut:" + dataDirOut)
-  os.system(("source {}").format(cbmrootConfigPath))
-  workDirOut = dataDirOut + "/workdir/" + jobId + "_" + taskId + "/"
-  
-  if os.path.exists(workDirOut):
-    shutil.rmtree(workDirOut)
-  os.makedirs(workDirOut)
-  os.chdir(workDirOut)
-
-  #offset describes the name of the folder with lowest number - 1 in dataIn directory
-  if plutoParticle == "rho0":
-    offset = 4000
-    offsetId = offset + int(taskId)
-
-  if plutoParticle == "w":
-    offset = 0
-    offsetId = offset + int(taskId)
-
-  if plutoParticle == "wdalitz":
-    offset = 1000
-    offsetId = offset + int(taskId)
-
-  if plutoParticle == "phi":
-    offset = 3000
-    offsetId = offset + int(taskId)
-
-  if plutoParticle == "qgp_epem":
-    offset = 7500
-    offsetId = offset + int(taskId)
-
-  #unlike others, paths of w and wdalitz do not contain '/TGeant4/'
-  if plutoParticle == "w" or plutoParticle == "wdalitz":
-    mcFile = recoDataDirIn + colSystem + "/" + colEnergyDir + "/centr_0_10/sis100_electron_target_25_mkm/" + str(offsetId) + "/" + str(offsetId) + ".tra.root" 
-    parFile = recoDataDirIn + colSystem + "/" + colEnergyDir + "/centr_0_10/sis100_electron_target_25_mkm/" + str(offsetId) + "/" + str(offsetId) + ".par.root"
-    digiFile = recoDataDirIn + colSystem + "/" + colEnergyDir + "/centr_0_10/sis100_electron_target_25_mkm/" + str(offsetId) + "/" + str(offsetId) + ".event.raw.root"
-    recoFile = recoDataDirIn + colSystem + "/" + colEnergyDir + "/centr_0_10/sis100_electron_target_25_mkm/" + str(offsetId) + "/" + str(offsetId) + ".rec.root"
-  else:
-    mcFile = recoDataDirIn + colSystem + "/" + colEnergyDir + "/centr_0_10/sis100_electron_target_25_mkm/TGeant4/" + str(offsetId) + "/" + str(offsetId) + ".tra.root"
-    parFile = recoDataDirIn + colSystem + "/" + colEnergyDir + "/centr_0_10/sis100_electron_target_25_mkm/TGeant4/" + str(offsetId) + "/" + str(offsetId) + ".par.root"
-    digiFile = recoDataDirIn + colSystem + "/" + colEnergyDir + "/centr_0_10/sis100_electron_target_25_mkm/TGeant4/" + str(offsetId) + "/" + str(offsetId) + ".event.raw.root"
-    recoFile = recoDataDirIn + colSystem + "/" + colEnergyDir + "/centr_0_10/sis100_electron_target_25_mkm/TGeant4/" + str(offsetId) + "/" + str(offsetId) + ".rec.root"
-  
-  litQaFile = dataDirOut + "/litqa." + taskId + ".root"
-  analysisFile = dataDirOut + "/analysis." + taskId + ".root"
-
-  #geoSimFile = dataDir + "/geosim." + taskId + ".root"     #needed ?
-  #it is assumed to take mc, digi, par and reco files from common folder, so only litqa and ana have to be run
-  os.system(('root -l -b -q {}/run_litqa.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, mcFile, parFile, digiFile, recoFile, litQaFile, geoSetup, nofEvents))
-  os.system(('root -l -b -q {}/run_analysis.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(macroDir, mcFile, parFile, digiFile, recoFile, analysisFile, plutoParticle, colSystem, colEnergy, geoSetup, nofEvents))
-  
-  def getPlutoPath(colSystem, colEnergy, plutoParticle, taskId):
-    if plutoParticle == "rho0":
-      return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/" + colEnergy + "/rho0/epem/pluto.auau." + colEnergy + ".rho0.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "omegaepem":
-      return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/" + colEnergy + "/omega/epem/pluto.auau." + colEnergy + ".omega.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "omegadalitz":
-      return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/" + colEnergy + "/omega/pi0epem/pluto.auau." + colEnergy + ".omega.pi0epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "phi":
-      return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/" + colEnergy + "/phi/epem/pluto.auau." + colEnergy + ".phi.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "pi0":
-      return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/" + colEnergy + "/pi0/gepem/pluto.auau." + colEnergy + ".pi0.gepem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "inmed":
-      return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktRapp/" + colEnergy + "/rapp.inmed/epem/pluto.auau." + colEnergy + ".rapp.inmed.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "qgp":
-      return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktRapp/" + colEnergy + "/rapp.qgp/epem/pluto.auau." + colEnergy + ".rapp.qgp.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "urqmd":
-      return ""
-
-if __name__ == '__main__':
-    main()
diff --git a/macro/analysis/dielectron/batch_send.py b/macro/analysis/dielectron/batch_send.py
index 76e92301068d406eb209a6267f5bb6583f7be93b..b1817cca2dd7a78762194cf8aea5066e34251da2 100755
--- a/macro/analysis/dielectron/batch_send.py
+++ b/macro/analysis/dielectron/batch_send.py
@@ -7,16 +7,12 @@ def main():
   nofJobs = 100
   timeLimit = "08:00:00"
   geoSetup = "sis100_electron"
-  plutoParticles =["inmed", "omegadalitz", "omegaepem", "phi", "qgp"];
+  plutoParticles =["inmed", "omegadalitz", "omegaepem", "phi", "qgp"]
 
-  #ADDED
-  mirrorRotation = 15
-  dataDir = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/"
-  jobName = "RICH" + str(mirrorRotation)
+  dataDir = "/lustre/nyx/cbm/users/criesen/data/lmvm/"
 
   #All data in data dir will be removed
   removeData = False
-  #jobName  = "LMVM"
   if removeData:
     print("All data in dataDir will be removed. Dir:" + dataDir)
     print("Removing...")
@@ -25,6 +21,7 @@ def main():
   os.makedirs(dataDir,exist_ok = True)
 
   for plutoParticle in plutoParticles:
+    jobName = "LMVM" + plutoParticle
     dataDirPluto = dataDir + plutoParticle
     logFile = dataDirPluto + "/log/log_slurm-%A_%a.out"
     errorFile = dataDirPluto + "/error/error_slurm-%A_%a.out"
@@ -32,9 +29,9 @@ def main():
     makeLogErrorDirs(logFile, errorFile, workDir)
 
     #- p debug
-    commandStr =('sbatch --job-name={} --time={} --output={} --error={} --array=1-{} -- ./batch_job.py {} {} {}').format(jobName, timeLimit, logFile, errorFile, nofJobs, dataDirPluto, geoSetup, plutoParticle)
+    cmd =('sbatch --job-name={} --time={} --output={} --error={} --array=1-{} -- ./batch_job.py {} {} {}').format(jobName, timeLimit, logFile, errorFile, nofJobs, dataDirPluto, geoSetup, plutoParticle)
 
-    os.system(commandStr)
+    os.system(cmd)
 
 def makeLogErrorDirs(logFile, errorFile, workDir):
   if os.path.exists(os.path.dirname(logFile)):
diff --git a/macro/analysis/dielectron/batch_send_common.py b/macro/analysis/dielectron/batch_send_common.py
deleted file mode 100755
index 10352ace63d38ba16b190684d8eb4154df1e6a05..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/batch_send_common.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import shutil
-
-def main():
-    nofJobs = 100
-    timeLimit="08:00:00"
-    geoSetup="sis100_electron"
-    plutoParticles = ["rho0", "wdalitz", "w", "phi", "qgp_epem"]
-    
-    recoDataDirIn = "/lustre/nyx/cbm/pwg/common/mc/cbmsim/apr20_fr_18.2.1_fs_jun19p1/urqmd_pluto_"
-    dataDirOut = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm_CommonData/"
-    
-    jobName = "LMVM"
-
-    #All data in data dir will be removed
-    removeData = False
-    if removeData:
-        print("All data in dataDirOut will be removed. Dir:" + dataDirOut)
-        print("Removing...")
-        if os.path.exists(dataDirOut):
-            shutil.rmtree(dataDirOut)
-    os.makedirs(dataDirOut,exist_ok=True)
-        
-    for plutoParticle in plutoParticles:
-        recoDataDirInPluto  = recoDataDirIn + plutoParticle + "/"           
-        dataDirOutPluto = dataDirOut + plutoParticle + "/"
-        logFile = dataDirOutPluto + "/log/log_slurm-%A_%a.out"
-        errorFile = dataDirOutPluto + "/error/error_slurm-%A_%a.out"
-        workDir = dataDirOutPluto + "/workdir/"        
-        makeLogErrorDirs(logFile, errorFile, workDir)
-
-        #- p debug
-        commandStr=('sbatch --job-name={} --time={} --output={} --error={} --array=1-{} -- ./batch_job_common.py {} {} {} {}').format(jobName, timeLimit, logFile, errorFile, nofJobs, recoDataDirInPluto, dataDirOutPluto, geoSetup, plutoParticle)
-
-        os.system(commandStr)
-
-
-def makeLogErrorDirs(logFile, errorFile, workDir):
-    if os.path.exists(os.path.dirname(logFile)):
-        shutil.rmtree(os.path.dirname(logFile))
-    os.makedirs(os.path.dirname(logFile),exist_ok=True)
-
-    if os.path.exists(os.path.dirname(errorFile)):
-        shutil.rmtree(os.path.dirname(errorFile))
-    os.makedirs(os.path.dirname(errorFile),exist_ok=True)
-    
-    if os.path.exists(os.path.dirname(workDir)):
-        shutil.rmtree(os.path.dirname(workDir))
-    os.makedirs(os.path.dirname(workDir),exist_ok=True)
-
-if __name__ == '__main__':
-    main()
diff --git a/macro/analysis/dielectron/copy_files.sh b/macro/analysis/dielectron/copy_files.sh
deleted file mode 100755
index c55c8a9a1c0368cd49f9eb67010f0be784d45b59..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/copy_files.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#####!/bin/sh
-# Copyright (C) 2012 UGiessen,JINR-LIT
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Semen Lebedev
-
-
-#mainDirFrom=/lustre/nyx/cbm/users/slebedev/cbm/data/lmvm/agagtest/3.5gev/
-#mainDirTo=/u/slebedev/Baykal/lmvm/agagtest/3.5gev/
-mainDirFrom=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/august18_1kk_field50/8gev/
-mainDirTo=/u/gpitsch/lmvm/august18_1kk_field50/8gev/
-#fileNameAna=analysis.agag.4.5gev.mbias.all.root
-#fileNameLitqa=litqa.agag.4.5gev.mbias.all.root
-fileNameAna=analysis.auau.8gev.centr.all.root
-fileNameLitqa=litqa.auau.8gev.centr.all.root
-
-copy_func() {
-   dirFrom=${1}
-   dirTo=${2}
-   fileName=${3}
-   plutoParticle=${4}
-   mkdir -p ${dirTo}/${plutoParticle}/
-   cp ${dirFrom}/${plutoParticle}/${fileName} ${dirTo}/${plutoParticle}/
-}
-
-copy_all_pluto_particles() {
-  #copy_func ${1} ${2} ${3} rho0
-  copy_func ${1} ${2} ${3} omegaepem
-  copy_func ${1} ${2} ${3} omegadalitz
-  copy_func ${1} ${2} ${3} phi 
-  copy_func ${1} ${2} ${3} inmed
-  copy_func ${1} ${2} ${3} qgp
-#  copy_func ${1} ${2} ${3} urqmd
-}
-
-
-rm -rf ${mainDirTo}
-copy_all_pluto_particles ${mainDirFrom}/ ${mainDirTo}/ ${fileNameAna}
-copy_all_pluto_particles ${mainDirFrom}/ ${mainDirTo}/ ${fileNameLitqa}
-
-
diff --git a/macro/analysis/dielectron/copy_files_agag.sh b/macro/analysis/dielectron/copy_files_agag.sh
deleted file mode 100755
index f198cf9513b263bbd47739c771f986f15b5a864f..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/copy_files_agag.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#####!/bin/sh
-# Copyright (C) 2018 Justus-Liebig-Universitaet Giessen, Giessen
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Gregor Pitsch
-
-
-#mainDirFrom=/lustre/nyx/cbm/users/slebedev/cbm/data/lmvm/agagtest/3.5gev/
-#mainDirTo=/u/slebedev/Baykal/lmvm/agagtest/3.5gev/
-mainDirFrom=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/agag/august18_2kk_field60/4.5gev/
-#mainDirTo=/u/gpitsch/lmvm/agag/central/august18_2kk_field60/4.5gev/
-mainDirTo=/u/gpitsch/lmvm/agag/central/august18_2kk_field60/4.5gev/
-fileNameAna=analysis.agag.4.5gev.mbias.all.root
-fileNameLitqa=litqa.agag.4.5gev.mbias.all.root
-#fileNameAna=analysis.auau.8gev.centr.all.root
-#fileNameLitqa=litqa.auau.8gev.centr.all.root
-
-copy_func() {
-   dirFrom=${1}
-   dirTo=${2}
-   fileName=${3}
-   plutoParticle=${4}
-   mkdir -p ${dirTo}/${plutoParticle}/
-   cp ${dirFrom}/${plutoParticle}/${fileName} ${dirTo}/${plutoParticle}/
-}
-
-copy_all_pluto_particles() {
-  #copy_func ${1} ${2} ${3} rho0
-  copy_func ${1} ${2} ${3} omegaepem
-  copy_func ${1} ${2} ${3} omegadalitz
-  copy_func ${1} ${2} ${3} phi 
-  copy_func ${1} ${2} ${3} inmed
-#  copy_func ${1} ${2} ${3} qgp
-#  copy_func ${1} ${2} ${3} urqmd
-}
-
-
-rm -rf ${mainDirTo}
-copy_all_pluto_particles ${mainDirFrom}/ ${mainDirTo}/ ${fileNameAna}
-copy_all_pluto_particles ${mainDirFrom}/ ${mainDirTo}/ ${fileNameLitqa}
-
-
diff --git a/macro/analysis/dielectron/draw_all.py b/macro/analysis/dielectron/draw_all.py
index e5847052d16d2af2dd5f11aa38f0c6ba303687c7..bfa69559f744dfb9f29373cc2d20970e76b836a6 100755
--- a/macro/analysis/dielectron/draw_all.py
+++ b/macro/analysis/dielectron/draw_all.py
@@ -4,26 +4,35 @@ import os, shutil
 
 def main():
   plutoParticles = ["inmed", "omegadalitz", "omegaepem", "phi", "qgp"]
-  dataDir = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/"
-  dataDirHistos = dataDir + "histograms/"
-  macroDir = "/lustre/cbm/users/criesen/cbmroot/macro/analysis/dielectron"
+  dataDir = "/lustre/nyx/cbm/users/criesen/data/lmvm/"
+  dataDirOut = dataDir + "/results/"
+  macroDir = "/lustre/cbm/users/criesen/cbmroot/macro/analysis/dielectron/"
+  useMvd = True
+  drawSig = True
   
-  if os.path.exists(dataDirHistos):
-    shutil.rmtree(dataDirHistos)
-  os.mkdir(dataDirHistos)
+  if os.path.exists(dataDirOut):
+    shutil.rmtree(dataDirOut)
+  os.mkdir(dataDirOut)
+
   
   for plutoParticle in plutoParticles:
-    outFile = dataDirHistos + plutoParticle
-    inFilesAna = dataDir + plutoParticle + "/analysis.all.root"
-    uMvd = True
-    drawSig = True
-    os.system(('root -l -b -q {}/draw_analysis.C\(\\"{}\\",\\"{}\\"\)').format(macroDir, inFilesAna, outFile, uMvd, drawSig))
+    resultDir = dataDirOut + plutoParticle
+    resultDirAna = resultDir + "/lmvm/"
+    inRootAna = dataDir + plutoParticle + "/analysis.all.root"
+    os.system(('root -l -b -q {}/draw_analysis.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\"\)').format(macroDir, inRootAna, resultDirAna, useMvd, drawSig))
     
-    inFilesLitqa = dataDir + plutoParticle + "/litqa.all.root"
-    os.system(('root -l -b -q {}/draw_litqa.C\(\\"{}\\",\\"{}\\"\)').format(macroDir, inFilesLitqa, outFile))
+    resultDirLitqa = resultDir + "/litqa/"
+    inRootLitqa = dataDir + plutoParticle + "/litqa.all.root"
+    os.system(('root -l -b -q {}/draw_litqa.C\(\\"{}\\",\\"{}\\"\)').format(macroDir, inRootLitqa, resultDirLitqa))
     
-  print("===== DRAW ALL =====")
-  os.system(('root -l -b -q {}/draw_analysis_all.C').format(macroDir))
+
+  allInmed  = dataDir + "/inmed/analysis.all.root"
+  allQgp = dataDir + "/qgp/analysis.all.root"
+  allOmega = dataDir + "/omegaepem/analysis.all.root"
+  allPhi = dataDir + "/phi/analysis.all.root"
+  allOmegaD = dataDir + "/omegadalitz/analysis.all.root"
+  resultDirAll = dataDirOut + "/lmvm_all/"
+  os.system(('root -l -b -q {}/draw_analysis_all.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\"\)').format(macroDir, allInmed, allQgp, allOmega, allPhi, allOmegaD, resultDirAll, useMvd))
 
 if __name__ == '__main__':
   main()
diff --git a/macro/analysis/dielectron/draw_analysis.C b/macro/analysis/dielectron/draw_analysis.C
old mode 100755
new mode 100644
index 0dce36af3c7acfe1b54e78a8430c341f54ddd620..29a4e7efdba6f10020b393dcebc023a187f18eaf
--- a/macro/analysis/dielectron/draw_analysis.C
+++ b/macro/analysis/dielectron/draw_analysis.C
@@ -1,18 +1,17 @@
-/* Copyright (C) 2010-2020 Justus-Liebig-Universitaet Giessen, Giessen
+/* Copyright (C) 2010-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Elena Lebedeva [committer], Semen Lebedev, Andrey Lebedev */
 
 //#include <experimental/filesystem>
 
-void draw_analysis(const string& histRootFile = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/analysis.all.root",
-                   const string& resultDir    = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/histograms/inmed/",
-                   Bool_t useMvd = false, Bool_t drawSignificance = true)
+void draw_analysis(
+  const string& histRootFile = "/Users/slebedev/Development/cbm/data/lmvm/nov21/analysis.inmed.all.root",
+  const string& resultDir = "/Users/slebedev/Development/cbm/data/lmvm/nov21/results/", Bool_t useMvd = true,
+  Bool_t drawSignificance = true)
 
 {
-  string outputDir = resultDir + "lmvm_results/";
-  //std::filesystem::remove(outputDir);
-  gSystem->mkdir(outputDir.c_str(), true);
+  gSystem->mkdir(resultDir.c_str(), true);
 
-  CbmAnaDielectronTaskDraw* draw = new CbmAnaDielectronTaskDraw();
-  draw->DrawHistFromFile(histRootFile, outputDir, useMvd, drawSignificance);
+  LmvmDraw* draw = new LmvmDraw();
+  draw->DrawHistFromFile(histRootFile, resultDir, useMvd, drawSignificance);
 }
diff --git a/macro/analysis/dielectron/draw_analysis_all.C b/macro/analysis/dielectron/draw_analysis_all.C
old mode 100755
new mode 100644
index a0d889a74e869f657bdcc542d7d7e19d0672a167..e7bc5c2efc3e124af82157bfd2fa8dc110014450
--- a/macro/analysis/dielectron/draw_analysis_all.C
+++ b/macro/analysis/dielectron/draw_analysis_all.C
@@ -1,17 +1,16 @@
-/* Copyright (C) 2011-2020 Justus-Liebig-Universitaet Giessen, Giessen
+/* Copyright (C) 2011-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Elena Lebedeva [committer], Semen Lebedev */
 
 void draw_analysis_all(
-  const string& fileInmed  = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/analysis.all.root",
-  const string& fileQgp    = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/qgp/analysis.all.root",
-  const string& fileOmega  = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/omegaepem/analysis.all.root",
-  const string& filePhi    = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/phi/analysis.all.root",
-  const string& fileOmegaD = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/omegadalitz/analysis.all.root",
-  const string& resultDir  = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/histograms/results_all/",
-  Bool_t useMvd            = false)
+  const string& fileInmed  = "/Users/slebedev/Development/cbm/data/lmvm/nov21/analysis.inmed.all.root",
+  const string& fileQgp    = "/Users/slebedev/Development/cbm/data/lmvm/nov21/analysis.qgp.all.root",
+  const string& fileOmega  = "/Users/slebedev/Development/cbm/data/lmvm/nov21/analysis.omega.all.root",
+  const string& filePhi    = "/Users/slebedev/Development/cbm/data/lmvm/nov21/analysis.phi.all.root",
+  const string& fileOmegaD = "/Users/slebedev/Development/cbm/data/lmvm/nov21/analysis.omegaD.all.root",
+  const string& resultDir = "/Users/slebedev/Development/cbm/data/lmvm/nov21/results_all/", Bool_t useMvd = false)
 
 {
-  CbmAnaDielectronTaskDrawAll* draw = new CbmAnaDielectronTaskDrawAll();
-  draw->DrawHistosFromFile(fileInmed, fileQgp, fileOmega, filePhi, fileOmegaD, resultDir, useMvd);
+  LmvmDrawAll* draw = new LmvmDrawAll();
+  draw->DrawHistFromFile(fileInmed, fileQgp, fileOmega, filePhi, fileOmegaD, resultDir, useMvd);
 }
diff --git a/macro/analysis/dielectron/draw_analysis_study.C b/macro/analysis/dielectron/draw_analysis_study.C
deleted file mode 100644
index b423a11c8d193c95f31715df4b9178d111b0d2b3..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/draw_analysis_study.C
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright (C) 2012-2013 Justus-Liebig-Universitaet Giessen, Giessen
-   SPDX-License-Identifier: GPL-3.0-only
-   Authors: Elena Lebedeva [committer] */
-
-using namespace std;
-void draw_analysis_study()
-{
-  gROOT->LoadMacro("$VMCWORKDIR/gconfig/basiclibs.C");
-  basiclibs();
-
-  gROOT->LoadMacro("$VMCWORKDIR/macro/rich/cbmlibs.C");
-  cbmlibs();
-
-  gSystem->Load("libAnalysis");
-
-  //std::string fileName = "analysis.pimisid.0.01.auau.8gev.centr.all.root";
-  std::string energy   = "25gev";
-  std::string fileName = "analysis." + energy + ".centr.all.root";
-  Bool_t useMvd        = false;
-
-  std::string outputDir = "/Users/slebedev/Development/cbm/data/lmvm/feb13_new/" + energy + "/results_field/";
-  // std::string outputDir = "results/25gev/study/";
-
-  /*  vector<string> files;
-   string dir = "/Users/slebedev/Development/cbm/data/lmvm/feb13_new/"+energy+"/1.0field/nomvd/rho0/";
-   files.push_back(dir + "analysis.pisupp0.01."+energy+".centr.all.root");
-   files.push_back(dir + "analysis.pisupp0.002."+energy+".centr.all.root");
-   files.push_back(dir + "analysis.pisupp0.001."+energy+".centr.all.root");
-   files.push_back(dir + "analysis.pisupp0.0004."+energy+".centr.all.root");
-   files.push_back(dir + "analysis.pisupp0.0002."+energy+".centr.all.root");
-   files.push_back(dir + "analysis.pisupp0.0001."+energy+".centr.all.root");
-   files.push_back(dir + "analysis.pisupp0.0."+energy+".centr.all.root");
-
-   vector<string> filesMean;
-   string dir = "/Users/slebedev/Development/cbm/data/lmvm/feb13_new/"+energy+"/1.0field/nomvd/results_all/";
-   filesMean.push_back(string(dir + "pisupp0.01/mean_hist.root"));
-   filesMean.push_back(string(dir + "pisupp0.002/mean_hist.root"));
-   filesMean.push_back(string(dir + "pisupp0.001/mean_hist.root"));
-   filesMean.push_back(string(dir + "pisupp0.0004/mean_hist.root"));
-   filesMean.push_back(string(dir + "pisupp0.0002/mean_hist.root"));
-   filesMean.push_back(string(dir + "pisupp0.0001/mean_hist.root"));
-   filesMean.push_back(string(dir + "pisupp0.0/mean_hist.root"));
-
-   vector<string> studyNames;
-   studyNames.push_back("1/100");
-   studyNames.push_back("1/500");
-   studyNames.push_back("1/1000");
-   studyNames.push_back("1/2500");
-   studyNames.push_back("1/5000");
-   studyNames.push_back("1/10000");
-   studyNames.push_back("ideal");*/
-
-  vector<string> files;
-  string dir = "/Users/slebedev/Development/cbm/data/lmvm/feb13_new/" + energy;
-  files.push_back(dir + "/0.7field/nomvd/rho0/" + "analysis." + energy + ".centr.all.root");
-  files.push_back(dir + "/1.0field/nomvd/rho0/" + "analysis." + energy + ".centr.all.root");
-
-  vector<string> filesMean;
-  string dir = "/Users/slebedev/Development/cbm/data/lmvm/feb13_new/" + energy;
-  filesMean.push_back(string(dir + "/0.7field/nomvd/results_all/" + "mean_hist.root"));
-  filesMean.push_back(string(dir + "/1.0field/nomvd/results_all/realpid/" + "mean_hist.root"));
-
-  vector<string> studyNames;
-  studyNames.push_back("70% B-field");
-  studyNames.push_back("100% B-field");
-
-  CbmAnaLmvmDrawStudy* draw = new CbmAnaLmvmDrawStudy();
-  draw->DrawFromFile(files, filesMean, studyNames, outputDir);
-}
diff --git a/macro/analysis/dielectron/draw_litqa.C b/macro/analysis/dielectron/draw_litqa.C
index df0eaaa77f26787b751fb4174558e229ca695f9d..d11a2438964ef113270c167982d4223735965fc5 100644
--- a/macro/analysis/dielectron/draw_litqa.C
+++ b/macro/analysis/dielectron/draw_litqa.C
@@ -1,18 +1,18 @@
-/* Copyright (C) 2014-2020 Justus-Liebig-Universitaet Giessen, Giessen
+/* Copyright (C) 2014-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Elena Lebedeva [committer], Andrey Lebedev */
+   Authors: Elena Lebedeva [committer], Semen Lebedev */
 
-void draw_litqa(const string& histRootFile = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/litqa.all.root",
-                const string& resultDir    = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/histograms/inmed/")
+void draw_litqa(const string& histRootFile = "/Users/slebedev/Development/cbm/data/lmvm/nov21/litqa.phi100k.all.root",
+                const string& resultDir    = "/Users/slebedev/Development/cbm/data/lmvm/nov21/litqa/")
 
 {
-  string outputDirTracking = resultDir + "results_litqa_tracking/";
+  string outputDirTracking = resultDir + "/tracking/";
   gSystem->mkdir(outputDirTracking.c_str(), true);
 
   CbmSimulationReport* trackingQaReport = new CbmLitTrackingQaReport();
   trackingQaReport->Create(histRootFile, outputDirTracking);
 
-  string outputDirClustering = resultDir + "results_litqa_clustering/";
+  string outputDirClustering = resultDir + "/clustering/";
   gSystem->mkdir(outputDirClustering.c_str(), true);
 
   CbmSimulationReport* clusteringQaReport = new CbmLitClusteringQaReport();
diff --git a/macro/analysis/dielectron/draw_many.py b/macro/analysis/dielectron/draw_many.py
deleted file mode 100755
index 4fd301b5466bc5ed7146e148d09765dcf9fb5728..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/draw_many.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import sys
-import shutil
-
-
-def main():
-    
-    print ("Use 'draw_all.py' instead!")
-
-    """
-    dataDir = sys.argv[1]
-    geoSetup = sys.argv[2]
-    plutoParticle = sys.argv[3]
-    cbmrootConfigPath = "/lustre/nyx/cbm/users/slebedev/cbm/trunk/build/config.sh"
-    macroDir = "/lustre/nyx/cbm/users/slebedev/cbm/trunk/cbmroot/macro/analysis/dielectron/"
-    nofEvents = 10
-    taskId = os.environ.get('SLURM_ARRAY_TASK_ID')
-    jobId = os.environ.get('SLURM_ARRAY_JOB_ID')
-    colEnergy = "8gev"
-    colSystem = "auau"
-    print("dataDir:" + dataDir)
-
-    os.system(("source {}").format(cbmrootConfigPath))
-
-    workDir = dataDir + "/workdir/" + jobId + "_" + taskId + "/"
-    if os.path.exists(workDir):
-        shutil.rmtree(workDir)
-    os.makedirs(workDir)
-    os.chdir(workDir)
-
-    plutoFile = getPlutoPath(colSystem, colEnergy, plutoParticle, taskId)
-    urqmdFile = "/lustre/nyx/cbm/prod/gen/urqmd/auau/"+colEnergy+"/centr/urqmd.auau.8gev.centr." + str(taskId).zfill(5) + ".root"
-    mcFile = dataDir + "/mc." + taskId + ".root"
-    parFile = dataDir + "/param." + taskId + ".root"
-    digiFile = dataDir + "/digi." + taskId + ".root"
-    recoFile = dataDir + "/reco." + taskId + ".root"
-    litQaFile = dataDir + "/litqa." + taskId + ".root"
-    analysisFile = dataDir + "/analysis." + taskId + ".root"
-    geoSimFile = dataDir + "/geosim." + taskId + ".root"
-    os.system(('root -l -b -q {}/run_sim.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(
-        macroDir, urqmdFile, plutoFile, mcFile, parFile, geoSimFile, geoSetup, nofEvents))
-    os.system(('root -l -b -q {}/run_digi.C\(\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(
-        macroDir, mcFile, parFile, digiFile, nofEvents))
-    os.system(('root -l -b -q {}/run_reco.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(
-        macroDir, mcFile, parFile, digiFile, recoFile, geoSetup, nofEvents))
-    os.system(('root -l -b -q {}/run_litqa.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(
-        macroDir, mcFile, parFile, digiFile, recoFile, litQaFile, geoSetup, nofEvents))
-    os.system(('root -l -b -q {}/run_analysis.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(
-        macroDir, mcFile, parFile, digiFile, recoFile, analysisFile, plutoParticle, colSystem, colEnergy, geoSetup, nofEvents))
-
-
-def getPlutoPath(colSystem, colEnergy, plutoParticle, taskId):
-    if plutoParticle == "rho0":
-       return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/"+colEnergy+"/rho0/epem/pluto.auau."+colEnergy+".rho0.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "omegaepem":
-        return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/"+colEnergy+"/omega/epem/pluto.auau."+colEnergy+".omega.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "omegadalitz":
-        return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/"+colEnergy+"/omega/pi0epem/pluto.auau."+colEnergy+".omega.pi0epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "phi":
-        return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/"+colEnergy+"/phi/epem/pluto.auau."+colEnergy+".phi.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "pi0":
-        return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/"+colEnergy+"/pi0/gepem/pluto.auau."+colEnergy+".pi0.gepem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "inmed":
-        return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktRapp/"+colEnergy+"/rapp.inmed/epem/pluto.auau."+colEnergy+".rapp.inmed.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "qgp":
-        return "/lustre/nyx/cbm/prod/gen/pluto/auau/cktRapp/"+colEnergy+"/rapp.qgp/epem/pluto.auau."+colEnergy+".rapp.qgp.epem." + str(taskId).zfill(4) + ".root"
-    elif plutoParticle == "urqmd":
-        return ""
-"""
-
-if __name__ == '__main__':
-    main()
-    
-
diff --git a/macro/analysis/dielectron/draw_many.sh b/macro/analysis/dielectron/draw_many.sh
deleted file mode 100644
index 894fe361f8017dea01d6ef9447d925c8f1588b77..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/draw_many.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2015 Justus-Liebig-Universitaet Giessen, Giessen
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Elena Lebedeva
-
-export SCRIPT=yes
-
-draw_litqa() 
-{
-	export LMVM_LITQA_FILE_NAME=${2}
-	export LMVM_MAIN_DIR=${1}/${3}
-	root -b -l -q draw_litqa.C
-}
-
-draw_ana()
-{
-	export LMVM_ANA_FILE_NAME=${2}
-	export LMVM_MAIN_DIR=${1}/${3}
-	root -b -l -q draw_analysis.C
-}
-
-draw_ana_all()
-{
-	export LMVM_ANA_FILE_NAME=${2}
-	export LMVM_MAIN_DIR=${1}
-	root -b -l -q draw_analysis_all.C
-}
-
-draw_all()
-{
-	main_dir=${1}
-	ana_file=analysis${2}
-	litqa_file=litqa${2}
-	echo "main_dir:" ${main_dir}
-	echo "ana_file:" ${ana_file}
-	echo "litqa_file:" ${litqa_file}
-	
-	echo "Draw LITQA"
-	draw_litqa ${main_dir} ${litqa_file} rho0/
-	#draw_litqa ${main_dir} ${litqa_file} omegaepem/
-	#draw_litqa ${main_dir} ${litqa_file} phi/
-	#draw_litqa ${main_dir} ${litqa_file} omegadalitz/
-	
-	echo "Draw ANALYSIS"
-	draw_ana ${main_dir} ${ana_file} rho0/
-	draw_ana ${main_dir} ${ana_file} omegaepem/
-	draw_ana ${main_dir} ${ana_file} phi/
-	draw_ana ${main_dir} ${ana_file} omegadalitz/
-	
-	echo "Draw ANALYSIS ALL"
-	draw_ana_all ${main_dir} ${ana_file}
-}
-
-
-draw_all /Users/slebedev/Development/cbm/data/lmvm/test6/8gev/ .auau.8gev.centr.all.root
-
-
-export SCRIPT=no
diff --git a/macro/analysis/dielectron/draw_mvd_xy_delta.C b/macro/analysis/dielectron/draw_mvd_xy_delta.C
deleted file mode 100644
index 5aa25a092f3af9b095aa8a706dc6788614d44861..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/draw_mvd_xy_delta.C
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2012 UGiessen, JINR-LIT
-   SPDX-License-Identifier: GPL-3.0-only
-   Authors: Semen Lebedev [committer] */
-
-void draw_mvd_xy_delta()
-{
-  TString fileName = "/lustre/cbm/user/ebelolap/aug11/25gev/70field/deltasource/mc.delta.root";
-  TFile* file      = new TFile(fileName);
-
-  gStyle->SetCanvasColor(kWhite);
-  gStyle->SetFrameFillColor(kWhite);
-  gStyle->SetPadColor(kWhite);
-  gStyle->SetStatColor(kWhite);
-  gStyle->SetTitleFillColor(kWhite);
-  gStyle->SetPalette(1);
-  gStyle->SetOptStat(0);
-  gStyle->SetOptTitle(0);
-
-  TString fileName    = "delta_xy_mvd1_70";
-  TString fileNameGif = fileName + ".png";
-  TString fileNameEps = fileName + ".eps";
-
-  cbmsim->Draw("MvdPoint.fY:MvdPoint.fX", "MvdPoint.fZ<6", "COLZ");
-  TH2F* htemp = (TH2F*) gPad->GetPrimitive("htemp");  // empty, but has axes
-  htemp->GetXaxis()->SetTitle("X [cm]");
-  htemp->GetYaxis()->SetTitle("Y [cm]");
-  htemp->SetMaximum(250);
-  gPad->SetGridx(true);
-  gPad->SetGridy(true);
-
-  c1->SaveAs(fileNameGif);
-  c1->SaveAs(fileNameEps);
-}
diff --git a/macro/analysis/dielectron/draw_separate.py b/macro/analysis/dielectron/draw_separate.py
deleted file mode 100644
index 44212da019074934db49b7153e7b237a68045bec..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/draw_separate.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import os
-import sys
-import shutil
-
-def main()
-   particle = sys.argv[1]
-   histDir =  "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm"
-   histDirPart = histDir + "/sepHists/" + particle
-   os.makedirs(histDirPart)
-   os.chdir(histDirPart)
-   os.system(('root -l -b -q {}/draw_sep_ana.C\(\\"{}\\}').format(histDirPart, particle))
-   os.system(('root -l -b -q {}/draw_sep_litqa.C\(\\"{}\\}').format(histDirPart, particle))
-
-
-
-if __name__ == '__main__':
-    main()
diff --git a/macro/analysis/dielectron/hadd_many.py b/macro/analysis/dielectron/hadd_many.py
index e65ba53bd1eb14be8e1558ffdbdbd47ff4fddcbc..a4c6a0a23eba7ad33a35f3067980b43133756ab4 100755
--- a/macro/analysis/dielectron/hadd_many.py
+++ b/macro/analysis/dielectron/hadd_many.py
@@ -3,7 +3,7 @@ import shutil
 
 def main():
   plutoParticles =["inmed", "omegadalitz", "omegaepem", "phi", "qgp"]
-  dataDir = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm"
+  dataDir = "/lustre/nyx/cbm/users/criesen/data/lmvm/"
   
   for plutoParticle in plutoParticles:
     dataDirPluto = dataDir + "/" + plutoParticle
diff --git a/macro/analysis/dielectron/hadd_many.sh b/macro/analysis/dielectron/hadd_many.sh
deleted file mode 100755
index 0c22e40e5a705f2ff1e7ac0df7a621829e667ac9..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/hadd_many.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2016 UGiessen,JINR-LIT
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Semen Lebedev
-
-fileSizeLimit=50000
-nofEventsInFile=1000
-
-#for plutoParticle in omegadalitz; do
-for plutoParticle in inmed qgp omegaepem omegadalitz phi; do
-	
-	dir=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/august18_1kk_field50/8gev/${plutoParticle}/
-	#filePatternAna=${dir}/analysis.agag.4.5gev.mbias.*.root
-	filePatternAna=${dir}/analysis.auau.8gev.centr.*.root
-	outputFileAna=${dir}/analysis.auau.8gev.centr.all.root
-	#outputFileAna=${dir}/analysis.agag.4.5gev.mbias.all.root
-        rm -rf ${outputFileAna}
-	xterm -hold -e "root -l -b -q 'hadd.C(\"${filePatternAna}\", \"${outputFileAna}\", ${fileSizeLimit}, ${nofEventsInFile})'"&
-	
-        #filePatternLitqa=litqa.agag.4.5gev.mbias.*.root
-	#outputFileLitqa=${dir}/litqa.agag.4.5gev.mbias.all.root
-        filePatternLitqa=litqa.auau.8gev.centr.*.root
-	outputFileLitqa=${dir}/litqa.auau.8gev.centr.all.root
-	rm -rf ${outputFileLitqa}
-	xterm -hold -e "root -l -b -q 'hadd.C(\"${dir}/${filePatternLitqa}\", \"${outputFileLitqa}\", ${fileSizeLimit}, ${nofEventsInFile})'"&
-done
diff --git a/macro/analysis/dielectron/hadd_many_agag.sh b/macro/analysis/dielectron/hadd_many_agag.sh
deleted file mode 100755
index 7a5e2886da43bd6491aa03c6f608e6c827afdc0d..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/hadd_many_agag.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018 Justus-Liebig-Universitaet Giessen, Giessen
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Gregor Pitsch
-
-fileSizeLimit=50000
-nofEventsInFile=10000
-
-#for plutoParticle in omegaepem; do
-for plutoParticle in inmed omegaepem omegadalitz phi; do
-	
-	dir=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/agag/august18_2kk_field60/4.5gev/${plutoParticle}/
-	filePatternAna=${dir}/analysis.agag.4.5gev.mbias.*.root
-	#filePatternAna=${dir}/analysis.auau.8gev.centr.*.root
-	#outputFileAna=${dir}/analysis.auau.8gev.centr.all.root
-	outputFileAna=${dir}/analysis.agag.4.5gev.mbias.all.root
-        rm -rf ${outputFileAna}
-	xterm -hold -e "root -l -b -q 'hadd.C(\"${filePatternAna}\", \"${outputFileAna}\", ${fileSizeLimit}, ${nofEventsInFile})'"&
-	
-        filePatternLitqa=litqa.agag.4.5gev.mbias.*.root
-	outputFileLitqa=${dir}/litqa.agag.4.5gev.mbias.all.root
-        #filePatternLitqa=litqa.auau.8gev.centr.*.root
-	#outputFileLitqa=${dir}/litqa.auau.8gev.centr.all.root
-	rm -rf ${outputFileLitqa}
-	xterm -hold -e "root -l -b -q 'hadd.C(\"${dir}/${filePatternLitqa}\", \"${outputFileLitqa}\", ${fileSizeLimit}, ${nofEventsInFile})'"&
-done
diff --git a/macro/analysis/dielectron/qa_study_lmvm.C b/macro/analysis/dielectron/qa_study_lmvm.C
deleted file mode 100644
index 92f33a6523c9bb813b9a06e4141f552eb08183c6..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/qa_study_lmvm.C
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 2012-2016 UGiessen, JINR-LIT
-   SPDX-License-Identifier: GPL-3.0-only
-   Authors: Semen Lebedev [committer] */
-
-/**
- * \file qa_study_lmvm.C
- * \brief Macro for generation of summary reports for LMVM analysis.
- * \author Semen Lebedev <s.lebedev@gsi.de>
- * \date 2012
- */
-
-void qa_study_lmvm()
-{
-  gROOT->LoadMacro("$VMCWORKDIR/gconfig/basiclibs.C");
-  basiclibs();
-  gROOT->LoadMacro("$VMCWORKDIR/macro/rich/cbmlibs.C");
-  cbmlibs();
-  gSystem->Load("libAnalysis");
-
-  std::vector<std::string> results, names;
-  std::string outputDir;
-
-  std::string dir = "/Users/slebedev/Development/cbm/data/lmvm/";
-  results.push_back(dir
-                    + "apr16/apr16_trdtofclustering/8gev/geosetup_v1512_8gev/"
-                      "lmvm_results_all/draw_all_hist.root");
-  results.push_back(dir
-                    + "apr16/apr16_trdclustering/8gev/geosetup_v1512_8gev//"
-                      "lmvm_results_all/draw_all_hist.root");
-  results.push_back(dir
-                    + "apr16/apr16_tofclustering/8gev/geosetup_v1512_8gev//"
-                      "lmvm_results_all/draw_all_hist.root");
-  results.push_back(dir
-                    + "apr16/apr16_trdtofsmearing/8gev/geosetup_v1512_8gev//"
-                      "lmvm_results_all/draw_all_hist.root");
-
-  names.push_back("TRD&TOF clustering");
-  names.push_back("TRD clustering");
-  names.push_back("TOF clustering");
-  names.push_back("TRD&TOF smearing");
-
-  outputDir = "/Users/slebedev/Development/cbm/data/lmvm/apr16_lmvm_study_report_8gev/";
-
-  CbmAnaDielectronReports reports;
-  reports.CreateStudyReport("LMVM", results, names, outputDir);
-}
diff --git a/macro/analysis/dielectron/remove_files.sh b/macro/analysis/dielectron/remove_files.sh
deleted file mode 100755
index 4ed400aa46e4c11efb7ed369400f82d5ec32da0e..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/remove_files.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2012 UGiessen,JINR-LIT
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Semen Lebedev
-
-
-export DIR=/hera/cbm/users/slebedev/mc/dielectron/feb15/3.5gev/stsv13d/richv14a_1e/trd4/tofv13/1.0field/nomvd/
-
-function remove_func {
-   echo ${DIR}/${1}
-   
-   #rm -r -f ${DIR}/${1}/log/*.log
-   
-   rm -r -f ${DIR}/${1}/analysis.*.root
-   rm -r -f ${DIR}/${1}/FairRunInfo_analysis.*.root
-   
- #  rm -r -f ${DIR}/${1}/reco.*.root
-  # rm -r -f ${DIR}/${1}/litqa.*.root
-  # rm -r ${DIR}/${1}/FairRunInfo_reco.*.root
-   
-  # rm -r -f ${DIR}/${1}/litqa.*.root    
-  # rm -r ${DIR}/${1}/FairRunInfo_litqa.*.root 
-  # rm -r ${DIR}/${1}/reco.delta.0*.root
-  # rm -r ${DIR}/${1}/mc.0*.root
-}
-
-remove_func phi
-remove_func rho0
-remove_func omegadalitz
-remove_func omegaepem
-#remove_func urqmd
-
-
diff --git a/macro/analysis/dielectron/run_analysis.C b/macro/analysis/dielectron/run_analysis.C
old mode 100755
new mode 100644
index 5464c5a4a362b2a6596b428ab31e0b63cc485753..37e6a65860eb0af2576729cbecb35db9759174ba
--- a/macro/analysis/dielectron/run_analysis.C
+++ b/macro/analysis/dielectron/run_analysis.C
@@ -1,38 +1,24 @@
-/* Copyright (C) 2010-2020 UGiessen, JINR-LIT
+/* Copyright (C) 2010-2021 UGiessen, JINR-LIT
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Andrey Lebedev, Semen Lebedev [committer] */
-
-void run_analysis(const string& mcFile        = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/mc.1.root",
-                  const string& parFile       = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/param.1.root",
-                  const string& digiFile      = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/digi.1.root",
-                  const string& recoFile      = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/reco.1.root",
-                  const string& analysisFile  = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/analysis.1.root",
-                  const string& plutoParticle = "inmed", const string& colSystem = "auau",
-                  const string& colEnergy = "8gev", const string& geoSetup = "sis100_electron", int nEvents = 1000)
-{
-  /*cout << "Here: just entered run_ana.C" << endl;
-  Int_t Interval=10;
-  Int_t PID=gSystem->GetPid();
-  cout<<"PID: "<<PID<<endl;
-  TString cmdline="$VMCWORKDIR/macro/analysis/dielectron/check_memory.sh ";
-  cmdline+= PID;
-  cmdline+= " ";
-  cmdline+= Interval;
-  cmdline+= "  &";
-  cout<<cmdline<<endl;
-  gSystem->Exec(cmdline);*/
-
+   Authors: Semen Lebedev [committer] */
 
+// Run this macro with run_local.py for local test and with batch_send(job).py for large productions
+void run_analysis(const std::string& traFile, const std::string& parFile, const std::string& digiFile,
+                  const std::string& recoFile, const std::string& analysisFile, const std::string& plutoParticle,
+                  const std::string& colSystem, const std::string& colEnergy, const std::string& geoSetup, int nEvents)
+{
   TTree::SetMaxTreeSize(90000000000);
-
-  TString myName = "run_analysis";
+  FairLogger::GetLogger()->SetLogScreenLevel("INFO");
+  FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
   TString srcDir = gSystem->Getenv("VMCWORKDIR");
 
   remove(analysisFile.c_str());
 
-  CbmSetup::Instance()->LoadSetup(geoSetup.c_str());
+  CbmSetup* geo = CbmSetup::Instance();
+  geo->LoadSetup(geoSetup.c_str());
+
+  bool useMvd = geo->IsActive(ECbmModuleId::kMvd);
 
-  std::cout << std::endl << "-I- " << myName << ": Defining parameter files " << std::endl;
   TList* parFileList = new TList();
 
   TStopwatch timer;
@@ -41,17 +27,14 @@ void run_analysis(const string& mcFile        = "/lustre/nyx/cbm/users/criesen/c
 
   FairRunAna* run             = new FairRunAna();
   FairFileSource* inputSource = new FairFileSource(digiFile.c_str());
-  inputSource->AddFriend(mcFile.c_str());
+  inputSource->AddFriend(traFile.c_str());
   inputSource->AddFriend(recoFile.c_str());
   run->SetSource(inputSource);
   run->SetOutputFile(analysisFile.c_str());
   run->SetGenerateRunInfo(kFALSE);
 
-  FairLogger::GetLogger()->SetLogScreenLevel("INFO");
-  FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
-
   CbmMCDataManager* mcManager = new CbmMCDataManager("MCManager", 1);
-  mcManager->AddFile(mcFile.c_str());
+  mcManager->AddFile(traFile.c_str());
   run->AddTask(mcManager);
 
   CbmKF* kalman = new CbmKF();
@@ -59,17 +42,31 @@ void run_analysis(const string& mcFile        = "/lustre/nyx/cbm/users/criesen/c
   CbmL1* l1 = new CbmL1();
   run->AddTask(l1);
 
-  CbmAnaDielectronTask* task = new CbmAnaDielectronTask();
+  // --- Material budget file names
+  TString mvdGeoTag;
+  if (useMvd && geo->GetGeoTag(ECbmModuleId::kMvd, mvdGeoTag)) {
+    TString parFile = gSystem->Getenv("VMCWORKDIR");
+    parFile += "/parameters/mvd/mvd_matbudget_" + mvdGeoTag + ".root";
+    std::cout << "Using material budget file " << parFile << std::endl;
+    l1->SetMvdMaterialBudgetFileName(parFile.Data());
+  }
+  TString stsGeoTag;
+  if (geo->GetGeoTag(ECbmModuleId::kSts, stsGeoTag)) {
+    TString parFile = gSystem->Getenv("VMCWORKDIR");
+    parFile += "/parameters/sts/sts_matbudget_" + stsGeoTag + ".root";
+    std::cout << "Using material budget file " << parFile << std::endl;
+    l1->SetStsMaterialBudgetFileName(parFile.Data());
+  }
+
+  LmvmTask* task = new LmvmTask();
   task->SetEnergyAndPlutoParticle(colEnergy, plutoParticle);
-  task->SetUseMvd(false);
-  task->SetUseRich(true);
-  task->SetUseTrd(true);
-  task->SetUseTof(true);
+  task->SetUseMvd(useMvd);
   // task->SetPionMisidLevel(pionMisidLevel);
   // task->SetTrdAnnCut(0.85);
   // task->SetRichAnnCut(-0.4);
   run->AddTask(task);
-  std::cout << std::endl << std::endl << "-I- " << myName << ": Set runtime DB" << std::endl;
+
+
   FairRuntimeDb* rtdb        = run->GetRuntimeDb();
   FairParRootFileIo* parIo1  = new FairParRootFileIo();
   FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
@@ -79,14 +76,14 @@ void run_analysis(const string& mcFile        = "/lustre/nyx/cbm/users/criesen/c
     parIo2->open(parFileList, "in");
     rtdb->setSecondInput(parIo2);
   }
-  std::cout << std::endl << "-I- " << myName << ": Initialise run" << std::endl;
+
   run->Init();
   rtdb->setOutput(parIo1);
   rtdb->saveOutput();
   rtdb->print();
 
-  std::cout << "-I- " << myName << ": Starting run" << std::endl;
   run->Run(0, nEvents);
+
   timer.Stop();
   std::cout << std::endl << std::endl;
   std::cout << "Macro finished succesfully." << std::endl;
diff --git a/macro/analysis/dielectron/run_digi.C b/macro/analysis/dielectron/run_digi.C
index b9082c51a0f099fc964415694893159486dd7c89..ee218f3ca9e3800ab1f5635471b27a7427838015 100644
--- a/macro/analysis/dielectron/run_digi.C
+++ b/macro/analysis/dielectron/run_digi.C
@@ -1,20 +1,18 @@
-/* Copyright (C) 2020 UGiessen, JINR-LIT
+/* Copyright (C) 2020-2021 UGiessen, JINR-LIT
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev [committer] */
 
-void run_digi(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/mc.2.root",
-              const string& parFile  = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/param.2.root",
-              const string& digiFile = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/digi.2.root",
-              int nEvents            = 1000)
+// Run this macro with run_local.py for local test and with batch_send(job).py for large productions
+void run_digi(const std::string& traFile, const std::string& parFile, const std::string& digiFile, int nEvents)
 {
   TTree::SetMaxTreeSize(90000000000);
   FairLogger::GetLogger()->SetLogScreenLevel("INFO");
   FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
 
-  Double_t eventRate       = 1.e7;
-  Double_t timeSliceLength = 1.e4;
-  Bool_t eventMode         = true;
-  Bool_t overwrite         = true;
+  double eventRate       = 1.e7;
+  double timeSliceLength = 1.e4;
+  bool eventMode         = true;
+  bool overwrite         = true;
 
   remove(digiFile.c_str());
 
@@ -22,7 +20,7 @@ void run_digi(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/l
   timer.Start();
 
   CbmDigitization run;
-  run.AddInput(mcFile.c_str(), eventRate);
+  run.AddInput(traFile.c_str(), eventRate);
   run.SetOutputFile(digiFile.c_str(), overwrite);
   run.SetParameterRootFile(parFile.c_str());
   run.SetTimeSliceLength(timeSliceLength);
diff --git a/macro/analysis/dielectron/run_litqa.C b/macro/analysis/dielectron/run_litqa.C
index 2c46dd2e4ee2b650080ccfd44fe497d321d428eb..c3f1a6a8cb21d5e7cdb192cf94c9647914529964 100644
--- a/macro/analysis/dielectron/run_litqa.C
+++ b/macro/analysis/dielectron/run_litqa.C
@@ -1,26 +1,23 @@
-/* Copyright (C) 2014-2020 Justus-Liebig-Universitaet Giessen, Giessen
+/* Copyright (C) 2014-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Andrey Lebedev, Semen Lebedev, Elena Lebedeva [committer] */
 
-void run_litqa(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/mc.2.root",
-               const string& parFile  = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/param.2.root",
-               const string& digiFile = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/digi.2.root",
-               const string& recoFile = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/reco.2.root",
-               const string& qaFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/litqa.2.root",
-               const string& geoSetup = "sis100_electron", int nEvents = 1000)
+// Run this macro with run_local.py for local test and with batch_send(job).py for large productions
+void run_litqa(const std::string& traFile, const std::string& parFile, const std::string& digiFile,
+               const std::string& recoFile, const std::string& qaFile, const std::string& geoSetup, int nEvents)
 {
   TTree::SetMaxTreeSize(90000000000);
-
-  TString myName = "run_litqa";
+  FairLogger::GetLogger()->SetLogScreenLevel("INFO");
+  FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
   TString srcDir = gSystem->Getenv("VMCWORKDIR");
 
   remove(qaFile.c_str());
 
   CbmSetup::Instance()->LoadSetup(geoSetup.c_str());
 
-  std::cout << std::endl << "-I- " << myName << ": Defining parameter files " << std::endl;
   TList* parFileList = new TList();
   TString geoTag;
+
   // - TRD digitisation parameters
   if (CbmSetup::Instance()->GetGeoTag(ECbmModuleId::kTrd, geoTag)) {
     const Char_t* npar[4] = {"asic", "digi", "gas", "gain"};
@@ -28,38 +25,32 @@ void run_litqa(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/
     for (Int_t i(0); i < 4; i++) {
       trdParFile = new TObjString(srcDir + "/parameters/trd/trd_" + geoTag + "." + npar[i] + ".par");
       parFileList->Add(trdParFile);
-      std::cout << "-I- " << myName << ": Using parameter file " << trdParFile->GetString() << std::endl;
+      std::cout << "-I- "
+                << ": Using parameter file " << trdParFile->GetString() << std::endl;
     }
   }
 
   // - TOF digitisation parameters
   if (CbmSetup::Instance()->GetGeoTag(ECbmModuleId::kTof, geoTag)) {
-    //TObjString* tofFile = new TObjString(srcDir + "/parameters/tof/tof_" + geoTag + ".digi.par");
-    //parFileList->Add(tofFile);
-    //std::cout << "-I- " << myName << ": Using parameter file " << tofFile->GetString() << std::endl;
     TObjString* tofBdfFile = new TObjString(srcDir + "/parameters/tof/tof_" + geoTag + ".digibdf.par");
     parFileList->Add(tofBdfFile);
-    std::cout << "-I- " << myName << ": Using parameter file " << tofBdfFile->GetString() << std::endl;
+    std::cout << "-I- "
+              << ": Using parameter file " << tofBdfFile->GetString() << std::endl;
   }
+
   TStopwatch timer;
   timer.Start();
-  gDebug = 0;
 
   FairRunAna* run             = new FairRunAna();
   FairFileSource* inputSource = new FairFileSource(digiFile.c_str());
-  inputSource->AddFriend(mcFile.c_str());
+  inputSource->AddFriend(traFile.c_str());
   inputSource->AddFriend(recoFile.c_str());
   run->SetSource(inputSource);
   run->SetOutputFile(qaFile.c_str());
   run->SetGenerateRunInfo(kFALSE);
 
-
-  FairLogger::GetLogger()->SetLogScreenLevel("INFO");
-  FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
-
-
   CbmMCDataManager* mcManager = new CbmMCDataManager("MCManager", 1);
-  mcManager->AddFile(mcFile.c_str());
+  mcManager->AddFile(traFile.c_str());
   run->AddTask(mcManager);
 
   // RICH reco QA
@@ -108,7 +99,6 @@ void run_litqa(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/
   tofQa->SetOutputDir(std::string(""));
   // run->AddTask(tofQa);
 
-  std::cout << std::endl << std::endl << "-I- " << myName << ": Set runtime DB" << std::endl;
   FairRuntimeDb* rtdb        = run->GetRuntimeDb();
   FairParRootFileIo* parIo1  = new FairParRootFileIo();
   FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
@@ -118,14 +108,12 @@ void run_litqa(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/
     parIo2->open(parFileList, "in");
     rtdb->setSecondInput(parIo2);
   }
-  std::cout << std::endl << "-I- " << myName << ": Initialise run" << std::endl;
-  run->Init();
 
+  run->Init();
   rtdb->setOutput(parIo1);
   rtdb->saveOutput();
   rtdb->print();
 
-  std::cout << "-I- " << myName << ": Starting run" << std::endl;
   run->Run(0, nEvents);
 
   timer.Stop();
diff --git a/macro/analysis/dielectron/run_local.py b/macro/analysis/dielectron/run_local.py
new file mode 100755
index 0000000000000000000000000000000000000000..7614628a3efa7bf020c3a8b128433cd3281cacb0
--- /dev/null
+++ b/macro/analysis/dielectron/run_local.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+
+import os   
+import sys 
+import shutil
+
+def main():
+
+  cbmrootConfigPath = "/Users/slebedev/Development/cbm/git/build/config.sh"
+  urqmdFile = "/Users/slebedev/Development/cbm/data/urqmd/auau/8gev/centr/urqmd.auau.8gev.centr.00001.root"
+  plutoFile = "/Users/slebedev/Development/cbm/data/pluto/auau/8gev/omega/epem/pluto.auau.8gev.omega.epem.0001.root"
+  dataDir = "/Users/slebedev/Development/cbm/data/lmvm/test/"
+  
+  runId = "0"
+  geoSetup = "sis100_electron"
+  nEvents = 10
+  colEnergy = "8gev"
+  colSystem = "auau"
+  plutoParticle = "omegaepem"
+
+  traFile = dataDir + "/tra." + runId + ".root"  
+  parFile = dataDir + "/param." + runId + ".root"
+  digiFile = dataDir + "/digi." + runId + ".root"
+  recoFile = dataDir + "/reco." + runId + ".root"
+  litQaFile = dataDir + "/litqa." + runId + ".root"
+  analysisFile = dataDir + "/analysis." + runId + ".root"
+  geoSimFile = dataDir + "/geosim." + runId + ".root"
+
+  traCmd = ('root -l -b -q run_transport.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(urqmdFile, plutoFile, traFile, parFile, geoSimFile, geoSetup, nEvents)
+  digiCmd = ('root -l -b -q run_digi.C\(\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(traFile, parFile, digiFile, nEvents)
+  recoCmd = ('root -l -b -q run_reco.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(traFile, parFile, digiFile, recoFile, geoSetup, nEvents)
+  qaCmd = ('root -l -b -q run_litqa.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(traFile, parFile, digiFile, recoFile, litQaFile, geoSetup, nEvents)
+  anaCmd = ('root -l -b -q run_analysis.C\(\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",\\"{}\\",{}\)').format(traFile, parFile, digiFile, recoFile, analysisFile, plutoParticle, colSystem, colEnergy, geoSetup, nEvents)
+
+  
+  #os.system((". /{} -a; {}").format(cbmrootConfigPath, traCmd))
+  #os.system((". /{} -a; {}").format(cbmrootConfigPath, digiCmd))
+  #os.system((". /{} -a; {}").format(cbmrootConfigPath, recoCmd))
+  #os.system((". /{} -a; {}").format(cbmrootConfigPath, qaCmd))
+  os.system((". /{} -a; {}").format(cbmrootConfigPath, anaCmd))
+  
+if __name__ == '__main__':
+  main()
diff --git a/macro/analysis/dielectron/run_reco.C b/macro/analysis/dielectron/run_reco.C
old mode 100755
new mode 100644
index 29434b23a6d7a017b883fcd715ed6582f3d92841..24f7bc9c0ecfddec29815a9738fb37744736618c
--- a/macro/analysis/dielectron/run_reco.C
+++ b/macro/analysis/dielectron/run_reco.C
@@ -1,120 +1,31 @@
-/* Copyright (C) 2020-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+/* Copyright (C) 2011-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Volker Friese [committer], Dominik Smith */
-
-/** @file run_reco.C
- ** @author Volker Friese <v.friese@gsi.de>
- ** @since 14 November 2020
- **/
-
-
-// --- Includes needed for IDE
-#include <RtypesCore.h>
-#if !defined(__CLING__)
-#include "CbmBuildEventsFromTracksReal.h"
-#include "CbmBuildEventsIdeal.h"
-#include "CbmBuildEventsQa.h"
-#include "CbmDefs.h"
-#include "CbmFindPrimaryVertex.h"
-#include "CbmKF.h"
-#include "CbmL1.h"
-#include "CbmL1StsTrackFinder.h"
-#include "CbmLitFindGlobalTracks.h"
-#include "CbmMCDataManager.h"
-#include "CbmMatchRecoToMC.h"
-#include "CbmMuchFindHitsGem.h"
-#include "CbmMvdClusterfinder.h"
-#include "CbmMvdHitfinder.h"
-#include "CbmPVFinderKF.h"
-#include "CbmPrimaryVertexFinder.h"
-#include "CbmPsdHitProducer.h"
-#include "CbmRecoSts.h"
-#include "CbmRichHitProducer.h"
-#include "CbmRichReconstruction.h"
-#include "CbmSetup.h"
-#include "CbmStsFindTracks.h"
-#include "CbmStsFindTracksEvents.h"
-#include "CbmStsTrackFinder.h"
-#include "CbmTaskBuildRawEvents.h"
-#include "CbmTofSimpClusterizer.h"
-#include "CbmTrdClusterFinder.h"
-#include "CbmTrdHitProducer.h"
-
-#include <FairFileSource.h>
-#include <FairMonitor.h>
-#include <FairParAsciiFileIo.h>
-#include <FairParRootFileIo.h>
-#include <FairRunAna.h>
-#include <FairRuntimeDb.h>
-#include <FairSystemInfo.h>
-
-#include <TStopwatch.h>
-#endif
-
-/*void run_reco(TString input = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/mc.1.root",
-			  Int_t nTimeSlices = -1, Int_t firstTimeSlice = 0, TString output = "",
-              TString sEvBuildRaw = "", TString setup = "sis100_electron", TString paramFile = "", Bool_t useMC = false)
-{*/ // original
-
-void run_reco(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/mc.1.root",
-              const string& parFile  = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/param.1.root",
-              const string& digiFile = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/digi.1.root",
-              const string& recoFile = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/reco.1.root",
-              const string& setup = "sis100_electron", const string& sEvBuildRaw = "", int nEvents = 1000)
-{  // old
-
-  //TTree::SetMaxTreeSize(90000000000);
-  //remove(recoFile.c_str());  // was few lines below before; see commented line there
-
-
-  // --- Logger settings ----------------------------------------------------
-  TString logLevel     = "INFO";
-  TString logVerbosity = "LOW";
-  // ------------------------------------------------------------------------
+   Authors: Semen Lebedev [committer]*/
 
+// Run this macro with run_local.py for local test and with batch_send(job).py for large productions
+void run_reco(const string& traFile, const string& parFile, const string& digiFile, const string& recoFile,
+              const string& setup, int nEvents)
+{
+  TString sEvBuildRaw = "ideal";
 
-  // -----   Environment   --------------------------------------------------
-  TString myName = "run_reco";
+  TTree::SetMaxTreeSize(90000000000);
+  FairLogger::GetLogger()->SetLogScreenLevel("INFO");
+  FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
   TString srcDir = gSystem->Getenv("VMCWORKDIR");
-  // ------------------------------------------------------------------------
-
 
-  // -----   In- and output file names   ------------------------------------
-  /*if (input.IsNull()) input = "test";
-  TString rawFile = input + ".raw.root";
-  TString traFile = input + ".tra.root";
-  if (output.IsNull()) output = input;
-  TString outFile = output + ".reco.root";
-  TString monFile = output + ".moni_reco.root";
-  if (paramFile.IsNull()) paramFile = input;
-  TString parFile = paramFile + ".par.root";
-  std::cout << "Inputfile " << rawFile << std::endl;
-  std::cout << "Outfile " << outFile << std::endl;
-  std::cout << "Parfile " << parFile << std::endl;*/
+  remove(recoFile.c_str());
 
-
-  // -----   Load the geometry setup   -------------------------------------
-  std::cout << std::endl << "-I- " << myName << ": Loading setup " << setup << std::endl;
   CbmSetup* geo = CbmSetup::Instance();
   geo->LoadSetup(setup.c_str());
-  // ------------------------------------------------------------------------
 
-
-  // -----   Some global switches   -----------------------------------------
   Bool_t eventBased = !(sEvBuildRaw == "");
   Bool_t useMC      = true;
   Bool_t useMvd     = geo->IsActive(ECbmModuleId::kMvd);
   Bool_t useSts     = geo->IsActive(ECbmModuleId::kSts);
   Bool_t useRich    = geo->IsActive(ECbmModuleId::kRich);
-  Bool_t useMuch    = geo->IsActive(ECbmModuleId::kMuch);
   Bool_t useTrd     = geo->IsActive(ECbmModuleId::kTrd);
   Bool_t useTof     = geo->IsActive(ECbmModuleId::kTof);
-  Bool_t usePsd     = geo->IsActive(ECbmModuleId::kPsd);
-  // ------------------------------------------------------------------------
 
-
-  // -----   Parameter files as input to the runtime database   -------------
-  std::cout << std::endl << "-I- " << myName << ": Defining parameter files " << std::endl;
   TList* parFileList = new TList();
   TString geoTag;
 
@@ -125,7 +36,8 @@ void run_reco(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/l
     for (Int_t i(0); i < 4; i++) {
       trdParFile = new TObjString(srcDir + "/parameters/trd/trd_" + geoTag + "." + npar[i] + ".par");
       parFileList->Add(trdParFile);
-      std::cout << "-I- " << myName << ": Using parameter file " << trdParFile->GetString() << std::endl;
+      std::cout << "-I- "
+                << ": Using parameter file " << trdParFile->GetString() << std::endl;
     }
   }
 
@@ -133,153 +45,60 @@ void run_reco(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/l
   if (CbmSetup::Instance()->GetGeoTag(ECbmModuleId::kTof, geoTag)) {
     TObjString* tofBdfFile = new TObjString(srcDir + "/parameters/tof/tof_" + geoTag + ".digibdf.par");
     parFileList->Add(tofBdfFile);
-    std::cout << "-I- " << myName << ": Using parameter file " << tofBdfFile->GetString() << std::endl;
+    std::cout << "-I- "
+              << ": Using parameter file " << tofBdfFile->GetString() << std::endl;
   }
 
-  // -----   Timer   --------------------------------------------------------
   TStopwatch timer;
   timer.Start();
-  // ------------------------------------------------------------------------
 
-
-  // -----   FairRunAna   ---------------------------------------------------
   FairRunAna* run             = new FairRunAna();
-  FairFileSource* inputSource = new FairFileSource(digiFile);  // original: FairFileSource(rawFile);
-  if (useMC) { inputSource->AddFriend(mcFile); }               // original: AddFriend(traFile); }
+  FairFileSource* inputSource = new FairFileSource(digiFile.c_str());
+  if (useMC) { inputSource->AddFriend(traFile.c_str()); }
   run->SetSource(inputSource);
   run->SetOutputFile(recoFile.c_str());
-  run->SetGenerateRunInfo(kTRUE);
-  //FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monFile); monFile not yet defined here
-  // ------------------------------------------------------------------------
 
-  // -----   MCDataManager  -----------------------------------
   if (useMC) {
-    CbmMCDataManager* mcManager = new CbmMCDataManager("MCDataManager", 0);  // TODO: ("MCDataManager", 0)??
-    mcManager->AddFile(mcFile.c_str());
+    CbmMCDataManager* mcManager = new CbmMCDataManager("MCDataManager", 0);
+    mcManager->AddFile(traFile.c_str());
     run->AddTask(mcManager);
   }
-  // ------------------------------------------------------------------------
-
-  // -----   Logger settings   ----------------------------------------------
-  FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data());
-  FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data());
-  // ------------------------------------------------------------------------
 
-
-  // -----   Raw event building from digis   --------------------------------
+  // only eventBased Ideal
   if (eventBased) {
-    if (sEvBuildRaw == "Ideal" || sEvBuildRaw == "ideal" || sEvBuildRaw == "IDEAL") {
+    if (sEvBuildRaw.EqualTo("Ideal", TString::ECaseCompare::kIgnoreCase)) {
       FairTask* evBuildRaw = new CbmBuildEventsIdeal();
       run->AddTask(evBuildRaw);
-      std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName() << std::endl;
-      eventBased = kTRUE;
-    }  //? Ideal raw event building
-    else if (sEvBuildRaw == "Real" || sEvBuildRaw == "real" || sEvBuildRaw == "REAL") {
-      CbmTaskBuildRawEvents* evBuildRaw = new CbmTaskBuildRawEvents();
-
-      //Choose between NoOverlap, MergeOverlap, AllowOverlap
-      evBuildRaw->SetEventOverlapMode(EOverlapModeRaw::AllowOverlap);
-
-      // Remove detectors where digis not found
-      if (!useRich) evBuildRaw->RemoveDetector(kRawEventBuilderDetRich);
-      if (!useMuch) evBuildRaw->RemoveDetector(kRawEventBuilderDetMuch);
-      if (!usePsd) evBuildRaw->RemoveDetector(kRawEventBuilderDetPsd);
-      if (!useTof) evBuildRaw->RemoveDetector(kRawEventBuilderDetTof);
-      if (!useTrd) evBuildRaw->RemoveDetector(kRawEventBuilderDetTrd);
-      if (!useSts) {
-        std::cerr << "-E- " << myName << ": Sts must be present for raw event "
-                  << "building using ''Real2019'' option. Terminating macro." << std::endl;
-        return;
-      }
-      // Set STS as reference detector
-      evBuildRaw->SetReferenceDetector(kRawEventBuilderDetSts);
-      evBuildRaw->SetTsParameters(0.0, 1.e7, 0.0);
-
-      // Use CbmMuchDigi instead of CbmMuchBeamtimeDigi
-      evBuildRaw->ChangeMuchBeamtimeDigiFlag(kFALSE);
-
-      evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kSts, 1000);
-      evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kSts, -1);
-      evBuildRaw->SetTriggerWindow(ECbmModuleId::kSts, -500, 500);
-
-      run->AddTask(evBuildRaw);
-      std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName() << std::endl;
       eventBased = kTRUE;
-    }  //? Real raw event building
-    else {
-      std::cerr << "-E- " << myName << ": Unknown option " << sEvBuildRaw
-                << " for raw event building! Terminating macro execution." << std::endl;
-      return;
     }
-  }  //? event-based reco
-  // ------------------------------------------------------------------------
-
+  }
 
-  // ----------- QA for raw event builder -----------------------------------
   if (eventBased && useMC) {
     CbmBuildEventsQa* evBuildQA = new CbmBuildEventsQa();
     run->AddTask(evBuildQA);
   }
-  // ------------------------------------------------------------------------
 
-
-  // -----   Local reconstruction in MVD   ----------------------------------
   if (useMvd) {
-
     CbmMvdClusterfinder* mvdCluster = new CbmMvdClusterfinder("MVD Cluster Finder", 0, 0);
     run->AddTask(mvdCluster);
-    std::cout << "-I- : Added task " << mvdCluster->GetName() << std::endl;
 
     CbmMvdHitfinder* mvdHit = new CbmMvdHitfinder("MVD Hit Finder", 0, 0);
     mvdHit->UseClusterfinder(kTRUE);
     run->AddTask(mvdHit);
-    std::cout << "-I- " << myName << ": Added task " << mvdHit->GetName() << std::endl;
   }
-  // ------------------------------------------------------------------------
-
 
-  // -----   Local reconstruction in STS   ----------------------------------
   if (useSts) {
     CbmRecoSts* stsReco = new CbmRecoSts(kCbmRecoTimeslice);
     if (eventBased) stsReco->SetMode(kCbmRecoEvent);
     run->AddTask(stsReco);
-    std::cout << "-I- " << myName << ": Added task " << stsReco->GetName() << std::endl;
   }
-  // ------------------------------------------------------------------------
-
 
-  // -----   Local reconstruction in RICH   ---------------------------------
   if (useRich) {
     CbmRichHitProducer* richHitProd = new CbmRichHitProducer();
     run->AddTask(richHitProd);
-    std::cout << "-I- " << myName << ": Added task " << richHitProd->GetName() << std::endl;
-  }
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction in MUCH   ---------------------------------
-  if (useMuch) {
-
-    // --- Parameter file name
-    TString geoTag;
-    geo->GetGeoTag(ECbmModuleId::kMuch, geoTag);
-    Int_t muchFlag  = (geoTag.Contains("mcbm") ? 1 : 0);
-    TString parFile = gSystem->Getenv("VMCWORKDIR");
-    parFile += "/parameters/much/much_" + geoTag(0, 4) + "_digi_sector.root";
-    std::cout << "Using parameter file " << parFile << std::endl;
-
-    // --- Hit finder for GEMs
-    FairTask* muchReco = new CbmMuchFindHitsGem(parFile.Data(), muchFlag);
-    run->AddTask(muchReco);
-    std::cout << "-I- " << myName << ": Added task " << muchReco->GetName() << " with parameter file " << parFile
-              << std::endl;
   }
-  // ------------------------------------------------------------------------
-
 
-  // -----   Local reconstruction in TRD   ----------------------------------
   if (useTrd) {
-
     Double_t triggerThreshold       = 0.5e-6;  // SIS100
     CbmTrdClusterFinder* trdCluster = new CbmTrdClusterFinder();
     if (eventBased) trdCluster->SetTimeBased(kFALSE);
@@ -294,35 +113,19 @@ void run_reco(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/l
     // trdCluster->SetUseOnlyEventDigis(kFALSE);
 
     run->AddTask(trdCluster);
-    std::cout << "-I- " << myName << ": Added task " << trdCluster->GetName() << std::endl;
 
     CbmTrdHitProducer* trdHit = new CbmTrdHitProducer();
     run->AddTask(trdHit);
-    std::cout << "-I- " << myName << ": Added task " << trdHit->GetName() << std::endl;
   }
-  // ------------------------------------------------------------------------
-
 
-  // -----   Local reconstruction in TOF   ----------------------------------
   if (useTof) {
     CbmTofSimpClusterizer* tofCluster = new CbmTofSimpClusterizer("TofSimpClusterizer", 0);
     tofCluster->SetOutputBranchPersistent("TofHit", kTRUE);
     tofCluster->SetOutputBranchPersistent("TofDigiMatch", kTRUE);
     run->AddTask(tofCluster);
-    std::cout << "-I- " << myName << ": Added task " << tofCluster->GetName() << std::endl;
-  }
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction in PSD   ----------------------------------
-  if (usePsd) {
-    CbmPsdHitProducer* psdHit = new CbmPsdHitProducer();
-    run->AddTask(psdHit);
-    std::cout << "-I- " << myName << ": Added task " << psdHit->GetName() << std::endl;
   }
 
 
-  // -----   Track finding in STS (+ MVD)   ----------------------------------
   if (useMvd || useSts) {
     CbmKF* kalman = new CbmKF();
     run->AddTask(kalman);
@@ -348,77 +151,49 @@ void run_reco(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/l
       l1->SetStsMaterialBudgetFileName(parFile.Data());
     }
     run->AddTask(l1);
-    std::cout << "-I- " << myName << ": Added task " << l1->GetName() << std::endl;
 
     CbmStsTrackFinder* stsTrackFinder = new CbmL1StsTrackFinder();
     if (eventBased) {
       FairTask* stsFindTracks = new CbmStsFindTracksEvents(stsTrackFinder, useMvd);
       run->AddTask(stsFindTracks);
-      std::cout << "-I- " << myName << ": Added task " << stsFindTracks->GetName() << std::endl;
     }
     else {
       FairTask* stsFindTracks = new CbmStsFindTracks(0, stsTrackFinder, useMvd);
       run->AddTask(stsFindTracks);
-      std::cout << "-I- " << myName << ": Added task " << stsFindTracks->GetName() << std::endl;
     }
   }
-  // ------------------------------------------------------------------------
-
-
-  // ==== From here on, the time-based and the event-based reconstruction
-  // ==== chains differ, since time-based version of primary vertex finding
-  // ==== and global tracking are not yet available. For time-based
-  // ==== reconstruction, a track-based event finder is used; no global
-  // ==== tracks are produced.
-
-  if (eventBased) {
 
-    // -----   Primary vertex finding   -------------------------------------
-    CbmPrimaryVertexFinder* pvFinder = new CbmPVFinderKF();
-    CbmFindPrimaryVertex* findVertex = new CbmFindPrimaryVertex(pvFinder);
-    run->AddTask(findVertex);
-    std::cout << "-I- " << myName << ": Added task " << findVertex->GetName() << std::endl;
-    // ----------------------------------------------------------------------
+  // Support only event-based reco
 
+  CbmPrimaryVertexFinder* pvFinder = new CbmPVFinderKF();
+  CbmFindPrimaryVertex* findVertex = new CbmFindPrimaryVertex(pvFinder);
+  run->AddTask(findVertex);
 
-    // ---   Global track finding   -----------------------------------------
-    CbmLitFindGlobalTracks* finder = new CbmLitFindGlobalTracks();
-    finder->SetTrackingType("branch");
-    finder->SetMergerType("nearest_hit");
-    run->AddTask(finder);
-    std::cout << "-I- : Added task " << finder->GetName() << std::endl;
-    // ----------------------------------------------------------------------
-
-
-    // -----   RICH reconstruction   ----------------------------------------
-    if (useRich) {
-      CbmRichReconstruction* richReco = new CbmRichReconstruction();
-      run->AddTask(richReco);
-      std::cout << "-I- : Added task " << richReco->GetName() << std::endl;
-    }
-    // ----------------------------------------------------------------------
-
-  }  //? event-based reco
+  CbmLitFindGlobalTracks* finder = new CbmLitFindGlobalTracks();
+  finder->SetTrackingType("branch");
+  finder->SetMergerType("nearest_hit");
+  run->AddTask(finder);
 
-  else {
-
-    // -----   Event building from STS tracks   -----------------------------
-    run->AddTask(new CbmBuildEventsFromTracksReal());
-    // ----------------------------------------------------------------------
+  if (useTrd) {
+    CbmTrdSetTracksPidLike* trdLI = new CbmTrdSetTracksPidLike("TRDLikelihood", "TRDLikelihood");
+    trdLI->SetUseMCInfo(kTRUE);
+    trdLI->SetUseMomDependence(kTRUE);
+    run->AddTask(trdLI);
+    std::cout << "-I- : Added task " << trdLI->GetName() << std::endl;
+    // ------------------------------------------------------------------------
+  }
 
-  }  //? time-based reco
 
+  if (useRich) {
+    CbmRichReconstruction* richReco = new CbmRichReconstruction();
+    run->AddTask(richReco);
+  }
 
-  // -----  Match reco to MC  ------------------------------------------------
   if (useMC) {
     CbmMatchRecoToMC* match1 = new CbmMatchRecoToMC();
     run->AddTask(match1);
   }
 
-
-  // -----  Parameter database   --------------------------------------------
-  std::cout << std::endl << std::endl;
-  std::cout << "-I- " << myName << ": Set runtime DB" << std::endl;
   FairRuntimeDb* rtdb        = run->GetRuntimeDb();
   FairParRootFileIo* parIo1  = new FairParRootFileIo();
   FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
@@ -428,17 +203,11 @@ void run_reco(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/l
     parIo2->open(parFileList, "in");
     rtdb->setSecondInput(parIo2);
   }
-  // ------------------------------------------------------------------------
 
-
-  // -----   Run initialisation   -------------------------------------------
-  std::cout << std::endl;
-  std::cout << "-I- " << myName << ": Initialise run" << std::endl;
   run->Init();
   rtdb->setOutput(parIo1);
   rtdb->saveOutput();
   rtdb->print();
-  // ------------------------------------------------------------------------
 
 
   // -----   Register light ions (d, t, He3, He4)   -------------------------
@@ -450,38 +219,13 @@ void run_reco(const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/l
   gROOT->ProcessLine("registerLightIons()");
   // ------------------------------------------------------------------------
 
-  // -----   Start run   ----------------------------------------------------
-  std::cout << std::endl << std::endl;
-  std::cout << "-I- " << myName << ": Starting run" << std::endl;
-  run->Run(0, nEvents);  // original: run->Run(firstTimeSlice, nTimeSlices);
-  // ------------------------------------------------------------------------
-
+  run->Run(0, nEvents);
 
-  // -----   Finish   -------------------------------------------------------
   timer.Stop();
-  FairMonitor::GetMonitor()->Print();
   Double_t rtime = timer.RealTime();
   Double_t ctime = timer.CpuTime();
-  std::cout << std::endl << std::endl;
   std::cout << "Macro finished successfully." << std::endl;
   std::cout << "Output file is    " << recoFile << std::endl;
   std::cout << "Parameter file is " << parFile << std::endl;
   std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl;
-  FairSystemInfo sysInfo;
-  Float_t maxMemory = sysInfo.GetMaxMemory();
-  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
-  std::cout << maxMemory;
-  std::cout << "</DartMeasurement>" << std::endl;
-  Float_t cpuUsage = ctime / rtime;
-  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
-  std::cout << cpuUsage;
-  std::cout << "</DartMeasurement>" << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   This is to prevent a malloc error when exiting ROOT   ----------
-  // The source of the error is unknown. Related to TGeoManager.
-  //RemoveGeoManager();  // TODO: comment this out?
-  // ------------------------------------------------------------------------
-
-}  // End of main macro function
+}
diff --git a/macro/analysis/dielectron/run_sim.sh b/macro/analysis/dielectron/run_sim.sh
deleted file mode 100755
index b9a7e7aedf95201dbdac1c2e67264aa276b34df0..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/run_sim.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2012 Justus-Liebig-Universitaet Giessen, Giessen
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Elena Lebedeva
-
-
-#inmed, qgp, rho0, omegaepem, omegadalitz, phi
-
-nofJobs=1000
-dataDir=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/august18_1kk_field50/
-#set full path to geo setup macro
-geoSetupMacroPath=/lustre/nyx/cbm/users/gpitsch/CbmRoot/trunk/macro/analysis/dielectron/geosetup/diel_setup_sis100.C
-collEnergy=8gev
-
-
-for plutoParticle in inmed qgp omegaepem omegadalitz phi; do
-#for plutoParticle in omegaepem; do
-
-outdir=${dataDir}/${collEnergy}/${plutoParticle}
-logFile=${outdir}/log/log_slurm-%A_%a.out
-errorFile=${outdir}/error/error_slurm-%A_%a.out
-jobName=${collEnergy}_${plutoParticle}
-#directories must be created by user
-mkdir -p $(dirname "${logFile}")
-mkdir -p $(dirname "${errorFile}")
-
-sbatch --job-name=${jobName} --time=8:00:00 --workdir=${outdir} --output=${logFile} --error=${errorFile} --array=1-${nofJobs} sim.sh ${outdir} ${collEnergy} ${plutoParticle} ${geoSetupMacroPath} ${XXXX}
-done
-
-
diff --git a/macro/analysis/dielectron/run_sim_agag.sh b/macro/analysis/dielectron/run_sim_agag.sh
deleted file mode 100755
index be9439c3f92609a3bade5999ca552858e86d4843..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/run_sim_agag.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2018 Justus-Liebig-Universitaet Giessen, Giessen
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Gregor Pitsch
-
-
-#inmed, qgp, rho0, omegaepem, omegadalitz, phi
-
-nofJobs=200
-#dataDir=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/auautest/
-dataDir=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/agag/august18_2kk_field60/
-#dataDir=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/august18_1kk_field50/
-#set full path to geo setup macro
-geoSetupMacroPath=/lustre/nyx/cbm/users/gpitsch/CbmRoot/trunk/macro/analysis/dielectron/geosetup/diel_setup_sis100_field60.C
-collEnergy=4.5gev
-
-#for plutoParticle in inmed; do
-for plutoParticle in inmed omegaepem omegadalitz phi; do
-if [ ${plutoParticle} = "inmed" ] ; then
-nofJobs=400
-else
-nofJobs=200
-fi
-outdir=${dataDir}/${collEnergy}/${plutoParticle}
-logFile=${outdir}/log/log_slurm-%A_%a.out
-errorFile=${outdir}/error/error_slurm-%A_%a.out
-jobName=${collEnergy}_${plutoParticle}
-#directories must be created by user
-mkdir -p $(dirname "${logFile}")
-mkdir -p $(dirname "${errorFile}")
-
-sbatch --job-name=${jobName} --time=8:00:00 --workdir=${outdir} --output=${logFile} --error=${errorFile} --array=1-${nofJobs} sim_agag.sh ${outdir} ${collEnergy} ${plutoParticle} ${geoSetupMacroPath}
-
-done
diff --git a/macro/analysis/dielectron/run_transport.C b/macro/analysis/dielectron/run_transport.C
index a5b87939f5e8e9c0842b89476c244c6464dd56d3..447015d501fe1fbf9a43b46c1d843c5db5553011 100644
--- a/macro/analysis/dielectron/run_transport.C
+++ b/macro/analysis/dielectron/run_transport.C
@@ -1,46 +1,43 @@
-/* Copyright (C) 2011-2020 Justus-Liebig-Universitaet Giessen, Giessen
+/* Copyright (C) 2011-2021 Justus-Liebig-Universitaet Giessen, Giessen
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev, Elena Lebedeva [committer] */
 
-void run_sim(const string& urqmdFile = "/lustre/nyx/cbm/prod/gen/urqmd/auau/8gev/centr/"
-                                       "urqmd.auau.8gev.centr.00001.root",  // if "", no urqmd
-             const string& plutoFile =
-               "/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/8gev/omega/epem/"
-               "pluto.auau.8gev.omega.epem.0001.root",  // if "", no pluto particles are embedded into event
-             const string& mcFile   = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/mc.2.root",
-             const string& parFile  = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/param.2.root",
-             const string& geoFile  = "/lustre/nyx/cbm/users/criesen/cbm/data/lmvm/inmed/geosim.2.root",
-             const string& geoSetup = "sis100_electron", int nEvents = 1000)
+// Run this macro with run_local.py for local test and with batch_send(job).py for large productions
+void run_transport(const std::string& urqmdFile,  // if "", no urqmd
+                   const std::string& plutoFile,  // if "", no pluto particles are embedded into event
+                   const std::string& traFile, const std::string& parFile, const std::string& geoFile,
+                   const std::string& geoSetup, int nEvents)
 {
+
   TTree::SetMaxTreeSize(90000000000);
   FairLogger::GetLogger()->SetLogScreenLevel("INFO");
   FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
 
   remove(parFile.c_str());
-  remove(mcFile.c_str());
+  remove(traFile.c_str());
   remove(geoFile.c_str());
 
   TStopwatch timer;
   timer.Start();
 
   CbmTransport run;
-
   if (urqmdFile.length() > 0) { run.AddInput(urqmdFile.c_str()); }
-
   if (plutoFile.length() > 0) { run.AddInput(plutoFile.c_str(), kPluto); }
-
-  run.SetOutFileName(mcFile.c_str());
+  run.SetOutFileName(traFile.c_str());
   run.SetParFileName(parFile.c_str());
   run.SetGeoFileName(geoFile.c_str());
   run.LoadSetup(geoSetup.c_str());
   run.SetTarget("Gold", 0.0025, 2.5);  // for lmvm thickness = 0.0025; // 25 mum
   run.SetBeamPosition(0., 0., 0.1, 0.1);
+  //run.SetEngine(kGeant4);
+  //run.SetRandomEventPlane();
   run.Run(nEvents);
 
+
   timer.Stop();
   std::cout << std::endl << std::endl;
   std::cout << "Macro finished successfully." << std::endl;
-  std::cout << "Output file is " << mcFile << std::endl;
+  std::cout << "Output file is " << traFile << std::endl;
   std::cout << "Parameter file is " << parFile << std::endl;
   std::cout << "Geometry file is " << geoFile << std::endl;
   std::cout << "Real time " << timer.RealTime() << " s, CPU time " << timer.CpuTime() << "s" << std::endl;
diff --git a/macro/analysis/dielectron/sim.sh b/macro/analysis/dielectron/sim.sh
deleted file mode 100755
index 2a9e9c8e920825a9b60afc7863a98104fee94ca1..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/sim.sh
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2012 Justus-Liebig-Universitaet Giessen, Giessen
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Elena Lebedeva
-
-
-# get parameters of the script
-outdir=${1}
-collEnergy=${2}
-plutoParticle=${3}
-geoSetupMacroPath=${4}
-#XXXX=${5}
-#plutoEnergy=8gev
-#cbmrootConfigPath=/lustre/nyx/cbm/users/slebedev/cbm/trunk/build/config.sh
-#macro_dir=/lustre/nyx/cbm/users/slebedev/cbm/trunk/cbmroot/macro/analysis/dielectron/
-
-cbmrootConfigPath=/lustre/nyx/cbm/users/gpitsch/CbmRoot/trunk/build/config.sh
-macro_dir=/lustre/nyx/cbm/users/gpitsch/CbmRoot/trunk/macro/analysis/dielectron/
-
-#comment for single simulations
-
-XXXXX=$(printf "%05d" "$SLURM_ARRAY_TASK_ID")
-#XXXX=$(printf "%04d" "$SLURM_ARRAY_TASK_ID")
-
-
-# Needed to run macro via script
-export SCRIPT=yes
-
-# Number of events to run
-nevents=1000
-
-# setup the run environment
-source ${cbmrootConfigPath}
- 
-# This line is needed, otherwise root will crash
-export DISPLAY=localhost:0.0
-
-export URQMD_FILE=/lustre/nyx/cbm/prod/gen/urqmd/auau/${collEnergy}/centr/urqmd.auau.${collEnergy}.centr.${XXXXX}.root
-#export URQMD_FILE=/lustre/nyx/cbm/prod/gen/urqmd/auau/${collEnergy}/centr/urqmd.auau.${collEnergy}.centr.0${XXXX}.root
-
-#auau simulation
-
-export MC_FILE=${outdir}/mc.auau.${collEnergy}.centr.${XXXXX}.root
-export PAR_FILE=${outdir}/params.auau.${collEnergy}.centr.${XXXXX}.root
-export RECO_FILE=${outdir}/reco.auau.${collEnergy}.centr.${XXXXX}.root
-export LITQA_FILE=${outdir}/litqa.auau.${collEnergy}.centr.${XXXXX}.root
-export ANALYSIS_FILE=${outdir}/analysis.auau.${collEnergy}.centr.${XXXXX}.root
-
-#export MC_FILE=${outdir}/mc.auau.${collEnergy}.centr.0${XXXX}.root
-#export PAR_FILE=${outdir}/params.auau.${collEnergy}.centr.0${XXXX}.root
-#export RECO_FILE=${outdir}/reco.auau.${collEnergy}.centr.0${XXXX}.root
-#export LITQA_FILE=${outdir}/litqa.auau.${collEnergy}.centr.0${XXXX}.root
-#export ANALYSIS_FILE=${outdir}/analysis.auau.${collEnergy}.centr.0${XXXX}.root
-
-#agag analysis
-
-#export MC_FILE=/lustre/nyx/cbm/prod/mc/r13109/omega_epem/sis100_electron.${XXXXX}.tra.root
-#export PAR_FILE=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/testUhlig/sis100_electron.${XXXXX}.par.root
-#export RECO_FILE=${outdir}/reco.agag.${collEnergy}.mbias.${XXXXX}.root
-#export LITQA_FILE=${outdir}/litqa.agag.${collEnergy}.mbias.${XXXXX}.root
-#export ANALYSIS_FILE=${outdir}/analysis.agag.${collEnergy}.mbias.${XXXXX}.root
-
-
-export RESULT_DIR=
-
-#Simulation parameters
-#--------------------------------------------------
-# number of embedded electrons
-export NOF_ELECTRONS=0
-# number of embedded positrons
-export NOF_POSITRONS=0
-# If "yes" than UrQMD will be used as background
-export URQMD=yes
-# If "yes" PLUTO particles will be embedded
-export PLUTO=yes
-#Collision energy: set proper weight into analysis
-export ENERGY=${collEnergy}
-#export ENERGY=3.5gev #for agag analysis as long no multiplicities available
-
-#Geometry setup macro
-export GEO_SETUP_FILE=${geoSetupMacroPath}
-
-export SETUP_FUNCT="do_setup()"
-
-export PLUTO_PARTICLE=${plutoParticle}
-export PLUTO=yes
-
-if [ ${plutoParticle} = "rho0" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/rho0/epem/pluto.auau.${collEnergy}.rho0.epem.${XXXX}.root
-elif [ ${plutoParticle} = "omegaepem" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/omega/epem/pluto.auau.${collEnergy}.omega.epem.${XXXX}.root
-elif [ ${plutoParticle} = "omegadalitz" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/omega/pi0epem/pluto.auau.${collEnergy}.omega.pi0epem.${XXXX}.root
-elif [ ${plutoParticle} = "phi" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/phi/epem/pluto.auau.${collEnergy}.phi.epem.${XXXX}.root
-elif [ ${plutoParticle} = "pi0" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/pi0/gepem/pluto.auau.${collEnergy}.pi0.gepem.${XXXX}.root
-elif [ ${plutoParticle} = "inmed" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktRapp/${collEnergy}/rapp.inmed/epem/pluto.auau.${collEnergy}.rapp.inmed.epem.${XXXX}.root
-elif [ ${plutoParticle} = "qgp" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktRapp/${collEnergy}/rapp.qgp/epem/pluto.auau.${collEnergy}.rapp.qgp.epem.${XXXX}.root
-elif [ ${plutoParticle} = "urqmd" ] ; then 
-   export PLUTO=no
-fi 
-
-# run the root simulation
-#root -b -l -q "${macro_dir}/run_sim.C(${nevents})"
-#root -b -l -q "${macro_dir}/run_reco.C(${nevents})"
-#root -b -l -q "${macro_dir}/run_litqa.C(${nevents})"
-root -b -l -q "${macro_dir}/run_analysis.C(${nevents})"
-
-
-export SCRIPT=no
diff --git a/macro/analysis/dielectron/sim_agag.sh b/macro/analysis/dielectron/sim_agag.sh
deleted file mode 100755
index 654ca50c6ea556964ba340da48d0169dc1240890..0000000000000000000000000000000000000000
--- a/macro/analysis/dielectron/sim_agag.sh
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2018 Justus-Liebig-Universitaet Giessen, Giessen
-# SPDX-License-Identifier: GPL-3.0-only
-# First commited by Gregor Pitsch
-
-
-# get parameters of the script
-outdir=${1}
-collEnergy=${2}
-plutoParticle=${3}
-geoSetupMacroPath=${4}
-#plutoEnergy=8gev
-#cbmrootConfigPath=/lustre/nyx/cbm/users/slebedev/cbm/trunk/build/config.sh
-#macro_dir=/lustre/nyx/cbm/users/slebedev/cbm/trunk/cbmroot/macro/analysis/dielectron/
-
-cbmrootConfigPath=/lustre/nyx/cbm/users/gpitsch/CbmRoot/trunk/build/config.sh
-macro_dir=/lustre/nyx/cbm/users/gpitsch/CbmRoot/trunk/macro/analysis/dielectron/
-
-XXXXX=$(printf "%05u" "$SLURM_ARRAY_TASK_ID")
-XXXX=$(printf "%04u" "$SLURM_ARRAY_TASK_ID")
-
-# Needed to run macro via script
-export SCRIPT=yes
-
-# Number of events to run
-nevents=10000
-
-# setup the run environment
-source ${cbmrootConfigPath}
- 
-# This line is needed, otherwise root will crash
-export DISPLAY=localhost:0.0
-
-#export URQMD_FILE=/lustre/nyx/cbm/prod/gen/urqmd/auau/${collEnergy}/centr/urqmd.auau.${collEnergy}.centr.${XXXXX}.root
-
-#auau simulation
-if [ ${plutoParticle} = "omegaepem" ] ; then
-   mcFilesDir="omega_epem"
-   YYYYY=${XXXXX}
-elif [ ${plutoParticle} = "omegadalitz" ] ; then
-   mcFilesDir="omega_pi0epem"
-   YYYYY=$(printf "%05u" $(($SLURM_ARRAY_TASK_ID + 200)))
-elif [ ${plutoParticle} = "phi" ] ; then
-   mcFilesDir="phi_epem"
-   YYYYY=$(printf "%05u" $(($SLURM_ARRAY_TASK_ID + 400)))
-elif [ ${plutoParticle} = "inmed" ] ; then
-   mcFilesDir="inmed_epem"
-      YYYYY=$(printf "%05u" $(($SLURM_ARRAY_TASK_ID + 600)))
-fi   
-#export MC_FILE=${outdir}/mc.auau.${collEnergy}.centr.${XXXXX}.root
-#export PAR_FILE=${outdir}/params.auau.${collEnergy}.centr.${XXXXX}.root
-#export RECO_FILE=${outdir}/reco.auau.${collEnergy}.centr.${XXXXX}.root
-#export LITQA_FILE=${outdir}/litqa.auau.${collEnergy}.centr.${XXXXX}.root
-#export ANALYSIS_FILE=${outdir}/analysis.auau.${collEnergy}.centr.${XXXXX}.root
-
-#agag analysis
-
-
-export MC_FILE=/lustre/nyx/cbm/prod/mc/r13109/${mcFilesDir}/sis100_electron.${YYYYY}.tra.root
-export PAR_FILE=/lustre/nyx/cbm/users/gpitsch/CbmRoot/data/lmvm/testUhlig/${mcFilesDir}/sis100_electron.${YYYYY}.par.root
-export RECO_FILE=${outdir}/reco.agag.${collEnergy}.mbias.${XXXXX}.root
-export LITQA_FILE=${outdir}/litqa.agag.${collEnergy}.mbias.${XXXXX}.root
-export ANALYSIS_FILE=${outdir}/analysis.agag.${collEnergy}.mbias.${XXXXX}.root
-
-echo $SLURM_ARRAY_TASK_ID
-echo $MC_FILE
-echo $PAR_FILE
-echo $RECO_FILE
-echo $LITQA_FILE
-echo $ANALYSIS_FILE
-
-export RESULT_DIR=
-
-#Simulation parameters
-#--------------------------------------------------
-# number of embedded electrons
-export NOF_ELECTRONS=0
-# number of embedded positrons
-export NOF_POSITRONS=0
-# If "yes" than UrQMD will be used as background
-export URQMD=yes
-# If "yes" PLUTO particles will be embedded
-export PLUTO=yes
-#Collision energy: set proper weight into analysis
-export ENERGY=${collEnergy}
-#export ENERGY=3.5gev #for agag analysis as long no multiplicities available
-
-#Geometry setup macro
-export GEO_SETUP_FILE=${geoSetupMacroPath}
-
-export SETUP_FUNCT="do_setup()"
-
-export PLUTO_PARTICLE=${plutoParticle}
-export PLUTO=yes
-
-if [ ${plutoParticle} = "rho0" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/rho0/epem/pluto.auau.${collEnergy}.rho0.epem.${XXXX}.root
-elif [ ${plutoParticle} = "omegaepem" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/omega/epem/pluto.auau.${collEnergy}.omega.epem.${XXXX}.root
-elif [ ${plutoParticle} = "omegadalitz" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/omega/pi0epem/pluto.auau.${collEnergy}.omega.pi0epem.${XXXX}.root
-elif [ ${plutoParticle} = "phi" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/phi/epem/pluto.auau.${collEnergy}.phi.epem.${XXXX}.root
-elif [ ${plutoParticle} = "pi0" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktA/${collEnergy}/pi0/gepem/pluto.auau.${collEnergy}.pi0.gepem.${XXXX}.root
-elif [ ${plutoParticle} = "inmed" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktRapp/${collEnergy}/rapp.inmed/epem/pluto.auau.${collEnergy}.rapp.inmed.epem.${XXXX}.root
-elif [ ${plutoParticle} = "qgp" ] ; then 
-   export PLUTO_FILE=/lustre/nyx/cbm/prod/gen/pluto/auau/cktRapp/${collEnergy}/rapp.qgp/epem/pluto.auau.${collEnergy}.rapp.qgp.epem.${XXXX}.root
-elif [ ${plutoParticle} = "urqmd" ] ; then 
-   export PLUTO=no
-fi 
-
-# run the root simulation
-#root -b -l -q "${macro_dir}/run_sim.C(${nevents})"
-#root -b -l -q "${macro_dir}/run_reco.C(${nevents})"
-root -b -l -q "${macro_dir}/run_litqa.C(${nevents})"
-root -b -l -q "${macro_dir}/run_analysis.C(${nevents})"
-
-export SCRIPT=no
diff --git a/reco/littrack/cbm/elid/CbmLitGlobalElectronId.cxx b/reco/littrack/cbm/elid/CbmLitGlobalElectronId.cxx
index 7d5daffd65805d01eebd3ca65180449134cd813f..5872fa6221d550ec1ffe8ebacb55bbf341f74639 100644
--- a/reco/littrack/cbm/elid/CbmLitGlobalElectronId.cxx
+++ b/reco/littrack/cbm/elid/CbmLitGlobalElectronId.cxx
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011-2020 UGiessen/JINR-LIT, Giessen/Dubna
+/* Copyright (C) 2011-2021 UGiessen/JINR-LIT, Giessen/Dubna
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Semen Lebedev [committer], Andrey Lebedev */
 
@@ -24,6 +24,8 @@
 #include "TString.h"
 #include "TSystem.h"
 
+#include <iostream>
+
 #include <cmath>
 
 CbmLitGlobalElectronId::CbmLitGlobalElectronId()
@@ -100,18 +102,10 @@ Bool_t CbmLitGlobalElectronId::IsTrdElectron(Int_t globalTrackIndex, Double_t mo
     return false;
 }
 
-Bool_t CbmLitGlobalElectronId::IsTofElectron(Int_t globalTrackIndex, Double_t momentum)
+Bool_t CbmLitGlobalElectronId::IsTofElectron(Int_t globalTrackIndex, Double_t momentum, Double_t eventTime)
 {
-  if (NULL == fGlobalTracks || NULL == fTofHits) return false;
-  const CbmGlobalTrack* globalTrack = static_cast<const CbmGlobalTrack*>(fGlobalTracks->At(globalTrackIndex));
-  Double_t trackLength              = globalTrack->GetLength() / 100.;
-  Int_t tofId                       = globalTrack->GetTofHitIndex();
-  if (tofId < 0) return false;
-  CbmTofHit* tofHit = (CbmTofHit*) fTofHits->At(tofId);
-  if (NULL == tofHit) return false;
-
-  Double_t time  = 0.2998 * tofHit->GetTime();  // time in ns -> transfrom to ct in m
-  Double_t mass2 = TMath::Power(momentum, 2.) * (TMath::Power(time / trackLength, 2) - 1);
+  Double_t mass2 = GetTofM2(globalTrackIndex, momentum, eventTime);
+  if (mass2 == -1.) return false;
 
   if (momentum >= 1.) {
     if (mass2 < (0.013 * momentum - 0.003)) { return true; }
@@ -141,4 +135,21 @@ Double_t CbmLitGlobalElectronId::GetTrdAnn(Int_t globalTrackIndex, Double_t mome
   return trdTrack->GetPidLikeEL();
 }
 
+Double_t CbmLitGlobalElectronId::GetTofM2(Int_t globalTrackIndex, Double_t momentum, Double_t eventTime)
+{
+  if (NULL == fGlobalTracks || NULL == fTofHits) return -1.;
+  const CbmGlobalTrack* globalTrack = static_cast<const CbmGlobalTrack*>(fGlobalTracks->At(globalTrackIndex));
+  Double_t trackLength              = globalTrack->GetLength() / 100.;
+  Int_t tofId                       = globalTrack->GetTofHitIndex();
+  if (tofId < 0) return -1.;
+  CbmTofHit* tofHit = (CbmTofHit*) fTofHits->At(tofId);
+  if (NULL == tofHit) return -1.;
+
+  Double_t noOffsetTime = tofHit->GetTime() - eventTime;
+  Double_t time         = 0.2998 * noOffsetTime;  // time in ns -> transfrom to ct in m
+  Double_t mass2        = momentum * momentum * (TMath::Power(time / trackLength, 2) - 1);
+
+  return mass2;
+}
+
 ClassImp(CbmLitGlobalElectronId);
diff --git a/reco/littrack/cbm/elid/CbmLitGlobalElectronId.h b/reco/littrack/cbm/elid/CbmLitGlobalElectronId.h
index 04f7c85b525a9dbe6c712ed326cd9cf8cafcb93a..fdd21551bd6a5bd0d4aef2994583749a2e0ffc15 100644
--- a/reco/littrack/cbm/elid/CbmLitGlobalElectronId.h
+++ b/reco/littrack/cbm/elid/CbmLitGlobalElectronId.h
@@ -1,13 +1,7 @@
-/* Copyright (C) 2011-2017 UGiessen/JINR-LIT, Giessen/Dubna
+/* Copyright (C) 2011-2021 UGiessen/JINR-LIT, Giessen/Dubna
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Andrey Lebedev, Semen Lebedev [committer] */
 
-/**
- * \file CbmLitReconstructionQa.h
- * \author Semen Lebedev <s.lebedev@gsi.de>
- * \date 2011
- **/
-
 #ifndef CBMLITGLOBALELECTRONID_H_
 #define CBMLITGLOBALELECTRONID_H_
 
@@ -66,7 +60,8 @@ public:
     * \param[in] momentum Momentum of track.
     * \return true if track is identified as electron otherwise return false.
     */
-  Bool_t IsTofElectron(Int_t globalTrackIndex, Double_t momentum);
+  // TODO: 1000 ns is a hardcoded offset for even-by-even mode
+  Bool_t IsTofElectron(Int_t globalTrackIndex, Double_t momentum, Double_t eventTime = 1000.);
 
   /**
     * \brief Identify electron in RICH detector.
@@ -96,6 +91,14 @@ public:
 	*/
   Double_t GetTrdAnn(Int_t globalTrackindex, Double_t momentum);
 
+
+  /**
+	 * \brief Return TOF m2 value.
+	*/
+  // TODO: 1000 ns is a hardcoded offset for even-by-even mode
+  Double_t GetTofM2(Int_t globalTrackIndex, Double_t momentum, Double_t eventTime = 1000.);
+
+
   /**
 	 * \brief Set cut on TRD ANN output value.
 	 */
diff --git a/reco/littrack/cbm/qa/tracking/CbmLitTrackingQa.cxx b/reco/littrack/cbm/qa/tracking/CbmLitTrackingQa.cxx
index 8403cb7e848b3c816d61add61bdb73e12e073666..3b76658f1e99cecc13bb957bb318fb272ef688c8 100644
--- a/reco/littrack/cbm/qa/tracking/CbmLitTrackingQa.cxx
+++ b/reco/littrack/cbm/qa/tracking/CbmLitTrackingQa.cxx
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2020 GSI/JINR-LIT, Darmstadt/Dubna
+/* Copyright (C) 2007-2021 GSI/JINR-LIT, Darmstadt/Dubna
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Andrey Lebedev [committer], Florian Uhlig */
 
@@ -228,15 +228,16 @@ void CbmLitTrackingQa::ReadDataBranches()
 
 void CbmLitTrackingQa::FillDefaultTrackCategories()
 {
-  vector<string> tmp = list_of("All")("Primary")("Secondary")("Reference")(
-    fDet.GetElectronSetup() ? "Electron" : "Muon")("Proton")("PionPlus")("PionMinus")("KaonPlus")("KaonMinus");
+  string elMu = fDet.GetElectronSetup() ? "Electron" : "Muon";
+  vector<string> tmp {"All",    "Primary",  "Secondary", "Reference", elMu,
+                      "Proton", "PionPlus", "PionMinus", "KaonPlus",  "KaonMinus"};
   fTrackCategories = tmp;
 }
 
 void CbmLitTrackingQa::FillDefaultRingCategories()
 {
-  vector<string> tmp = list_of("All")("AllReference")("Electron")("ElectronReference")("Pion")("PionReference");
-  fRingCategories    = tmp;
+  vector<string> tmp {"All", "AllReference", "Electron", "ElectronReference", "Pion", "PionReference"};
+  fRingCategories = tmp;
 }
 
 void CbmLitTrackingQa::FillDefaultTrackPIDCategories()
@@ -1111,10 +1112,10 @@ Bool_t CbmLitTrackingQa::ElectronId(Int_t mcEventId, Int_t mcId, const multimap<
                             ? CbmLitGlobalElectronId::GetInstance().IsRichElectron(globalTrackIndex, mom.Mag())
                             : true;
   Bool_t isTrdElectron  = (fDet.GetDet(ECbmModuleId::kTrd) && (effName.find("Trd") != string::npos))
-                            ? CbmLitGlobalElectronId::GetInstance().IsRichElectron(globalTrackIndex, mom.Mag())
+                            ? CbmLitGlobalElectronId::GetInstance().IsTrdElectron(globalTrackIndex, mom.Mag())
                             : true;
   Bool_t isTofElectron  = (fDet.GetDet(ECbmModuleId::kTof) && (effName.find("Tof") != string::npos))
-                            ? CbmLitGlobalElectronId::GetInstance().IsRichElectron(globalTrackIndex, mom.Mag())
+                            ? CbmLitGlobalElectronId::GetInstance().IsTofElectron(globalTrackIndex, mom.Mag())
                             : true;
   return isRichElectron && isTrdElectron && isTofElectron;
 }