BmnRoot 26.10.0-210-gc52d34b0
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnAlignResult.h
Go to the documentation of this file.
1/*
2 BM@N alignment routine
3 BM@N experiment at NICA complex, JINR, 2025
4
5 Department: Math & Soft Group of HEP lab
6 Author: Igor Polev, polev@jinr.int
7
8 BmnAlignResult class header-only implementation
9 Stores results of alignment iteration
10*/
11
12#ifndef BMNALIGNRESULT_H
13#define BMNALIGNRESULT_H
14
15#include "BmnAlignDefines.h"
16
17#include <TH1D.h>
18#include <TH2D.h>
19#include <TMatrixD.h>
20#include <TMatrixDSym.h>
21#include <TVectorD.h>
22#include <algorithm>
23#include <atomic>
24#include <stdexcept>
25
26/*
27 * All per-parameter quantities below live in the *full* parameter layout the
28 * detector model's hierarchy defines: every element followed by every
29 * composite node, six corrections each (see BmnParamLayout). A leaf entry
30 * holds the *effective* correction - the element's own share plus everything
31 * its ancestors contribute - while a composite entry holds that node's own
32 * share; SolveGlobal() maintains the identity between them. Keeping the two
33 * levels in one vector is what lets an error or a covariance be quoted for a
34 * composite node at all.
35 */
37{
38 private:
39 // Binning of the histograms this class owns. Ranges are in cm and chosen for
40 // the residual scale the alignment works at, so they belong to these
41 // histograms and to nothing else.
42 static constexpr Int_t RESIDUALS_BINS{201};
43 static constexpr Double_t RESIDUALS_RANGE_X{0.2};
44 static constexpr Double_t RESIDUALS_RANGE_Y{0.4};
45 static constexpr Double_t TARGET_Z{0.0}; // measured Z position of the target
46 static constexpr Double_t TARGET_THICKNESS{1.75}; // thickness of the target (along Z axis)
47
48 VecSVectLC_t fAlpha; // local parameters for each track
49 TVectorD fParams, // corrections, full layout (see above)
50 fErrors, // their 1-sigma errors (diagonal of V = C^-1); populated only
51 // by the non-regularized SolveGlobal call (mirrors SVDSig/SVDv)
52 fGlCorr; // global correlation coefficients, same layout
53 VecSVectGL_t fA; // per-element copy of the leaf block, for the per-hit
54 // code that wants one element's six corrections together
55 TVectorD fL, // Lagrange multipliers for global parameters constrains
56 fSVDSig; // singular values vector from SVD decomposition of MNE
57 TMatrixD fSVDv; // right singular vectors (columns) of the non-regularized MNE
58 TMatrixDSym fCov; // covariance in the full layout; 0x0 if not available.
59 // Stored only on the latest iteration result.
60 TH1D fResidualsX, // histogram of residuals by X coordinate
61 fResidualsY, // histogram of residuals by Y coordinate
62 fVertexZ; // histogram of primary vertex distribution by Z coordinate
63 TH2D fResidualsSX, // "syntetic" histogram of X residuals for visualization
64 fResidualsSY; // "syntetic" histogram of Y residuals for visualization
65 Double_t fMSEtotal; // total value of target function at current solution
66 Int_t fAlphaCount; // number of tracks (set in constructor)
67 Int_t fElements; // alignable detector elements, i.e. leaf nodes
68
69 public:
70 BmnAlignResult(Int_t TrackCount, Double_t MaxZvalue, Int_t Elements, Int_t AllParams);
71 BmnAlignResult(const BmnAlignResult& other);
73 ~BmnAlignResult() = default;
74 // default constructor is required for ROOT serialization and not intended to be used
77
78 // non-const accessors
79
80 VecSVectLC_t& Alpha() noexcept { return fAlpha; };
81 SVectLC& Alpha(Int_t index) noexcept { return fAlpha[index]; };
82 SVectGL& A(Int_t index) noexcept { return fA[index]; };
83 TVectorD& A() noexcept { return fParams; };
84 TVectorD& AErr() noexcept { return fErrors; };
85 Double_t& AErr(Int_t index) noexcept { return fErrors(index); };
86 TVectorD& AglCorr() noexcept { return fGlCorr; };
87 Double_t& AglCorr(Int_t index) noexcept { return fGlCorr(index); };
88 TVectorD& L() noexcept { return fL; };
89 TVectorD& SVDSig() noexcept { return fSVDSig; };
90 TMatrixD& SVDv() noexcept { return fSVDv; };
91 TMatrixDSym& Cov() noexcept { return fCov; };
92
93 TH1D& ResidualsX() noexcept { return fResidualsX; };
94 TH1D& ResidualsY() noexcept { return fResidualsY; };
95 TH1D& VertexZ() noexcept { return fVertexZ; };
96 TH2D& ResidualsSX() noexcept { return fResidualsSX; };
97 TH2D& ResidualsSY() noexcept { return fResidualsSY; };
98
99 // const getters
100
101 const VecSVectLC_t& Alpha() const noexcept { return fAlpha; };
102 const SVectLC& Alpha(Int_t index) const noexcept { return fAlpha[index]; };
103 const SVectGL& A(Int_t index) const noexcept { return fA[index]; };
104 const TVectorD& A() const noexcept { return fParams; };
105 const TVectorD& AErr() const noexcept { return fErrors; };
106 const Double_t& AErr(Int_t index) const noexcept { return fErrors(index); };
107 const TVectorD& AglCorr() const noexcept { return fGlCorr; };
108 const Double_t& AglCorr(Int_t index) const noexcept { return fGlCorr(index); };
109 const TVectorD& L() const noexcept { return fL; };
110 const TVectorD& SVDSig() const noexcept { return fSVDSig; };
111 const TMatrixD& SVDv() const noexcept { return fSVDv; };
112 const TMatrixDSym& Cov() const noexcept { return fCov; };
113
114 const TH1D& ResidualsX() const noexcept { return fResidualsX; };
115 const TH1D& ResidualsY() const noexcept { return fResidualsY; };
116 const TH1D& VertexZ() const noexcept { return fVertexZ; };
117 const TH2D& ResidualsSX() const noexcept { return fResidualsSX; };
118 const TH2D& ResidualsSY() const noexcept { return fResidualsSY; };
119
120 Double_t GetValueMSE() const noexcept { return fMSEtotal; };
121 Int_t GetAlphaCount() const noexcept { return fAlphaCount; };
122 ULong_t GetHistCounter() const noexcept;
123
124 void AddValueMSE(Double_t val) noexcept { fMSEtotal += val; };
125 void ResetValueMSE() noexcept { fMSEtotal = 0.0; };
126
127 void SeparateA();
128 void ConcatenateA();
129};
130
131// Inline implementations
132
133inline BmnAlignResult::BmnAlignResult(Int_t TrackCount, Double_t MaxZvalue, Int_t Elements, Int_t AllParams)
134 : fAlpha(TrackCount)
135 , fParams(AllParams)
136 , fErrors(AllParams)
137 , fGlCorr(AllParams)
138 , fA(Elements)
139 , fL()
140 , fSVDSig()
141 , fSVDv()
142 , fCov(AllParams)
143 , fResidualsX(Form("residualsX_%lu", GetHistCounter()),
144 "Total residuals by X (red: aligned)",
148 , fResidualsY(Form("residualsY_%lu", GetHistCounter()),
149 "Total residuals by Y (red: aligned)",
153 , fVertexZ(Form("vertexZ_%lu", GetHistCounter()),
154 "Primary vertex distribution;Z, cm;tracks",
158 , fResidualsSX(Form("residualsSX_%lu", GetHistCounter()),
159 "Review of X residuals along beam axis in FSD region;Z, cm;X residual, cm",
160 RESIDUALS_BINS * 10,
161 14.0,
162 49.0, // Z range to cover all FSD stations
166 , fResidualsSY(Form("residualsSY_%lu", GetHistCounter()),
167 "Review of Y residuals along beam axis in FSD region;Z, cm;Y residual, cm",
168 RESIDUALS_BINS * 10,
169 14.0,
170 49.0, // Z range to cover all FSD stations
174 , fMSEtotal(0.0)
175 , fAlphaCount(TrackCount)
176 , fElements(Elements)
177{}
178
180 : fAlpha(other.fAlpha)
181 , fParams(other.fParams)
182 , fErrors(other.fErrors)
183 , fGlCorr(other.fGlCorr)
184 , fA(other.fA)
185 , fL(other.fL)
186 , fSVDSig(other.fSVDSig)
187 , fSVDv(other.fSVDv)
188 , fCov(other.fCov)
189 , fResidualsX(other.fResidualsX)
190 , fResidualsY(other.fResidualsY)
191 , fVertexZ(other.fVertexZ)
194 , fMSEtotal(other.fMSEtotal)
195 , fAlphaCount(other.fAlphaCount)
196 , fElements(other.fElements)
197{
198 // Update histogram names to be unique using common counter
199 fResidualsX.SetName(Form("residualsX_%lu", GetHistCounter()));
200 fResidualsY.SetName(Form("residualsY_%lu", GetHistCounter()));
201 fVertexZ.SetName(Form("vertexZ_%lu", GetHistCounter()));
202 fResidualsSX.SetName(Form("residualsSX_%lu", GetHistCounter()));
203 fResidualsSY.SetName(Form("residualsSY_%lu", GetHistCounter()));
204}
205
207{
208 if (this == &other)
209 return *this;
210 if (fAlphaCount != other.fAlphaCount)
211 throw std::runtime_error("BmnAlignResult: assignment between objects with different alphaCount");
212
213 fL.ResizeTo(other.fL);
214 fParams.ResizeTo(other.fParams);
215 fErrors.ResizeTo(other.fErrors);
216 fGlCorr.ResizeTo(other.fGlCorr);
217 fSVDSig.ResizeTo(other.fSVDSig);
218 fSVDv.ResizeTo(other.fSVDv);
219 fCov.ResizeTo(other.fCov);
220 fAlpha = other.fAlpha;
221 fParams = other.fParams;
222 fErrors = other.fErrors;
223 fGlCorr = other.fGlCorr;
224 fA = other.fA;
225 fL = other.fL;
226 fSVDSig = other.fSVDSig;
227 fSVDv = other.fSVDv;
228 fCov = other.fCov;
229 fResidualsX = other.fResidualsX;
230 fResidualsY = other.fResidualsY;
231 fVertexZ = other.fVertexZ;
234 fMSEtotal = other.fMSEtotal;
235 fElements = other.fElements;
236
237 return *this;
238}
239
240// fA duplicates the leaf block of fParams so that the per-hit code can take a
241// whole element at once. The two directions below are the sync points; the leaf
242// block is the authoritative copy.
244{
245 const Double_t* src{fParams.GetMatrixArray()};
246 for (Int_t i = 0; i < fElements; i++, src += BMN_GLOBAL_PARAMS_PD)
247 fA[i].SetElements(src, BMN_GLOBAL_PARAMS_PD);
248}
249
251{
252 Double_t* dst{fParams.GetMatrixArray()};
253 for (Int_t i = 0; i < fElements; i++, dst += BMN_GLOBAL_PARAMS_PD)
254 std::copy(fA[i].begin(), fA[i].end(), dst);
255}
256
258{
259 // Common counter for all histograms in all BmnAlignResult instances.
260 // Atomic because CalculateMSEpart() calls this concurrently from worker threads.
261 static std::atomic<ULong_t> sHistCounter{0};
262 return ++sHistCounter;
263};
264
265#endif // BMNALIGNRESULT_H
std::vector< SVectLC > VecSVectLC_t
std::vector< SVectGL > VecSVectGL_t
RM::SVector< Double_t, BMN_LOCAL_PARAMS_PT > SVectLC
RM::SVector< Double_t, BMN_GLOBAL_PARAMS_PD > SVectGL
#define BMN_GLOBAL_PARAMS_PD
int i
Definition P4_F32vec4.h:22
int Int_t
unsigned long ULong_t
double Double_t
TMatrixTSym< Double_t > TMatrixDSym
TMatrixT< Double_t > TMatrixD
char * Form(const char *fmt,...)
TVectorT< Double_t > TVectorD
TMatrixDSym fCov
const TH1D & ResidualsY() const noexcept
const VecSVectLC_t & Alpha() const noexcept
const TMatrixDSym & Cov() const noexcept
static constexpr Double_t RESIDUALS_RANGE_X
VecSVectGL_t fA
const TH1D & ResidualsX() const noexcept
const TVectorD & L() const noexcept
const TVectorD & A() const noexcept
TVectorD & SVDSig() noexcept
const TVectorD & AErr() const noexcept
TH1D & VertexZ() noexcept
BmnAlignResult(Int_t TrackCount, Double_t MaxZvalue, Int_t Elements, Int_t AllParams)
SVectGL & A(Int_t index) noexcept
const TH2D & ResidualsSY() const noexcept
SVectLC & Alpha(Int_t index) noexcept
TMatrixD & SVDv() noexcept
static constexpr Double_t TARGET_THICKNESS
TH1D & ResidualsX() noexcept
TVectorD & L() noexcept
~BmnAlignResult()=default
const Double_t & AglCorr(Int_t index) const noexcept
const TVectorD & SVDSig() const noexcept
const SVectLC & Alpha(Int_t index) const noexcept
const SVectGL & A(Int_t index) const noexcept
const TMatrixD & SVDv() const noexcept
void AddValueMSE(Double_t val) noexcept
void ResetValueMSE() noexcept
const TVectorD & AglCorr() const noexcept
Double_t & AglCorr(Int_t index) noexcept
TH1D & ResidualsY() noexcept
const TH1D & VertexZ() const noexcept
TH2D & ResidualsSX() noexcept
TH2D & ResidualsSY() noexcept
Double_t & AErr(Int_t index) noexcept
static constexpr Int_t RESIDUALS_BINS
BmnAlignResult & operator=(const BmnAlignResult &other)
TVectorD & AErr() noexcept
Int_t GetAlphaCount() const noexcept
Double_t GetValueMSE() const noexcept
static constexpr Double_t RESIDUALS_RANGE_Y
VecSVectLC_t & Alpha() noexcept
VecSVectLC_t fAlpha
TMatrixDSym & Cov() noexcept
TVectorD & A() noexcept
ULong_t GetHistCounter() const noexcept
static constexpr Double_t TARGET_Z
const Double_t & AErr(Int_t index) const noexcept
TVectorD & AglCorr() noexcept
const TH2D & ResidualsSX() const noexcept