Skip to content

Commit 6e4bba4

Browse files
authored
ITS alignment monitoring (check with QCv20240903), revised 20240919 (#2418)
* ITS alignment monitoring (check with QCv20240903) * ITS alignment monitoring (check with QCv20240903), revised 20240919(5) * ITS alignment monitoring (check with QCv20240903), revised 20240919(6) * ITS alignment monitoring (check with QCv20240903), revised 20241021(1) * ITS alignment monitoring (check with QCv20240903), revised 20241024(1), clang-format applied, TH2I->TH2F * ITS alignment monitoring (check with QCv20240903), revised 20241028(1), clang-format applied, TH2I->TH2F
1 parent 699425c commit 6e4bba4

4 files changed

Lines changed: 754 additions & 4 deletions

File tree

Modules/ITS/include/ITS/ITSTrackTask.h

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525
#include <TTree.h>
2626
#include "Common/TH1Ratio.h"
2727
#include "Common/TH2Ratio.h"
28+
#include <Fit/Fitter.h>
29+
#include <Math/Functor.h>
30+
#include <TMatrixD.h>
31+
#include <TVector3.h>
32+
#include "TMath.h"
33+
#include <cassert>
34+
#include "ITS/ITSHelpers.h"
2835

2936
class TH1;
3037
class TH2;
@@ -118,6 +125,152 @@ class ITSTrackTask : public TaskInterface
118125
double ptBins[141]; // pt bins
119126

120127
o2::itsmft::TopologyDictionary* mDict;
128+
129+
private:
130+
// analysis for its-only residual
131+
o2::its::GeometryTGeo* mGeom;
132+
133+
std::vector<double> FitStepSize{ 0.3, 1.0e-5, 1.0e-5, 1.0e-5 };
134+
135+
double FitTolerance = 1.0e-8;
136+
double ITS_AbsBz = 0.5; // T
137+
138+
double inputG_C[3 * NLayer];
139+
double FitparXY[6];
140+
double FitparDZ[2];
141+
ROOT::Fit::Fitter fitterA;
142+
ROOT::Fit::Fitter fitterB;
143+
Int_t mAlignmentMonitor = 0;
144+
Int_t mDefaultMomResPar = 0;
145+
Int_t mResMonNclMin = 0;
146+
float mResMonTrackMinPt = 0;
147+
148+
std::array<std::unique_ptr<TH2F>, NLayer> hResidualXY{}; //[NLayer];
149+
std::array<std::unique_ptr<TH2F>, NLayer> hResidualZD{}; //[NLayer];
150+
151+
void circleFitXY(double* input, double* par, double& MSEvalue, std::vector<bool> hitUpdate, int step = 0);
152+
153+
// default setting
154+
// function Object to be minimized
155+
struct se_circlefitXY {
156+
// the TGraph is a data member of the object
157+
std::vector<TVector3> fHits;
158+
double thetaR;
159+
double Bz;
160+
double sigma_meas[2][NLayer] = { { 45, 45, 45, 55, 55, 55, 55 }, { 40, 40, 40, 40, 40, 40, 40 } }; // um unit
161+
double sigma_msc[2][NLayer] = { { 30, 30, 30, 110, 110, 110, 110 }, { 25, 25, 25, 75, 75, 75, 75 } }; // um unit
162+
163+
se_circlefitXY() = default;
164+
se_circlefitXY(std::vector<TVector3>& h, double tR, double bz)
165+
{
166+
fHits = h;
167+
thetaR = tR;
168+
Bz = bz;
169+
};
170+
171+
void loadparameters(double arrpar_meas[][NLayer], double arrpar_msc[][NLayer])
172+
{
173+
for (int a = 0; a < 2; a++) {
174+
for (int l = 0; l < NLayer; l++) {
175+
sigma_meas[a][l] = arrpar_meas[a][l];
176+
sigma_msc[a][l] = arrpar_msc[a][l];
177+
}
178+
}
179+
};
180+
181+
void init()
182+
{
183+
fHits.clear();
184+
thetaR = 0;
185+
Bz = 0;
186+
};
187+
188+
void set(std::vector<TVector3>& h, double tR, double bz)
189+
{
190+
fHits = h;
191+
thetaR = tR;
192+
Bz = bz;
193+
};
194+
195+
double getsigma(double R, int L, double B, int axis)
196+
{
197+
// R : cm
198+
// B : T
199+
if (L < 0 || L >= NLayer)
200+
return 1;
201+
double aL = sigma_meas[axis][L] * 1e-4; // um -> cm
202+
double bL = sigma_msc[axis][L] * 1e-4; // um -> cm
203+
double Beff = 0.299792458 * B;
204+
double sigma = std::sqrt(std::pow(aL, 2) + std::pow(bL, 2) / (std::pow(Beff, 2) * std::pow(R * 1e-2, 2)));
205+
206+
return sigma;
207+
};
208+
209+
// calculate distance line-point
210+
double distance2(double x, double y, const double* p, double tR, int charge)
211+
{
212+
213+
double R = std::abs(1 / p[0]);
214+
215+
double Xc = p[0] > 0 ? R * std::cos(p[1] + tR + 0.5 * TMath::Pi()) : R * std::cos(p[1] + tR - 0.5 * TMath::Pi());
216+
double Yc = p[0] > 0 ? R * std::sin(p[1] + tR + 0.5 * TMath::Pi()) : R * std::sin(p[1] + tR - 0.5 * TMath::Pi());
217+
218+
double dx = x - (Xc + p[2]);
219+
double dy = y - (Yc + p[3]);
220+
double dxy = R - std::sqrt(dx * dx + dy * dy);
221+
222+
double d2 = dxy * dxy;
223+
return d2;
224+
};
225+
226+
// implementation of the function to be minimized
227+
double operator()(const double* par)
228+
{ // const double -> double
229+
assert(fHits != 0);
230+
231+
int nhits = fHits.size();
232+
double sum = 0;
233+
234+
double charge = par[0] > 0 ? +1 : -1;
235+
double RecRadius = std::abs(1 / par[0]);
236+
237+
double Sigma_tot[NLayer];
238+
double sum_Sigma_tot = 0;
239+
for (int l = 0; l < nhits; l++) {
240+
Sigma_tot[l] = getsigma(RecRadius, fHits[l].Z(), Bz, 1);
241+
sum_Sigma_tot += 1 / (std::pow(Sigma_tot[l], 2));
242+
}
243+
244+
for (int l = 0; l < nhits; l++) {
245+
double d = distance2(fHits[l].X(), fHits[l].Y(), par, thetaR, charge) / (std::pow(Sigma_tot[l], 2));
246+
sum += d;
247+
}
248+
sum = sum / sum_Sigma_tot;
249+
250+
return sum;
251+
};
252+
};
253+
254+
se_circlefitXY fitfuncXY;
255+
256+
void lineFitDZ(double* zIn, double* betaIn, double* parz, double Radius, bool vertex, std::vector<bool> hitUpdate);
257+
258+
double mSigmaMeas[2][NLayer] = { { 45, 45, 45, 55, 55, 55, 55 }, { 40, 40, 40, 40, 40, 40, 40 } }; // um unit
259+
double mSigmaMsc[2][NLayer] = { { 30, 30, 30, 110, 110, 110, 110 }, { 25, 25, 25, 75, 75, 75, 75 } }; // um unit
260+
261+
double getsigma(double R, int L, double B, int axis)
262+
{
263+
// R : cm
264+
// B : T
265+
if (L < 0 || L >= NLayer)
266+
return 1;
267+
double aL = mSigmaMeas[axis][L] * 1e-4; // um -> cm
268+
double bL = mSigmaMsc[axis][L] * 1e-4; // um -> cm
269+
double Beff = 0.299792458 * B;
270+
double sigma = std::sqrt(std::pow(aL, 2) + std::pow(bL, 2) / (std::pow(Beff, 2) * std::pow(R * 1e-2, 2)));
271+
272+
return sigma;
273+
};
121274
};
122275
} // namespace o2::quality_control_modules::its
123276

Modules/ITS/include/ITS/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Analysis for ITS-only residual
2+
3+
We use the Weighted Least Square(WLS) fit and calculate the residuals from each cluster positions to the fitted trajectory.
4+
5+
## Circular Fit in the XY plane : circleFitXY
6+
7+
In the XY plane, the trajectory of particle under the magnetic field in z-axis can be fitted with circular model.
8+
There are 4 fit parameters : radius(R), direction at origin($$\theta_R$$), estimated vertex X(vx), and estimated vertex Y(vy).
9+
10+
$$ x_c = R \cdot cos(\theta_R + \frac{R}{|R|} \cdot \pi/2) $$
11+
12+
$$ y_c = R \cdot sin(\theta_R + \frac{R}{|R|} \cdot \pi/2) $$
13+
14+
$$ (x - (x_c + v_x))^2 + (y - (y_c + v_y))^2 = |R|^2 $$
15+
16+
For the fit stability,
17+
1. A simple algorithm to determine seeds of fit parameters(radius and direction at origin) is applied.
18+
2. Circular fit is performed for both (+) and (-) signs of the circular trajectory (even if we have approximated seeds from 1.), the one with the lower chi2(sum of weighted residuals) is finally adopted. This procedure ensures the stability in case of hard(high pT) tracks.
19+
20+
## Linear Fit in the DZ plane : lineFitDZ
21+
22+
After 4 fit parameters of circular trajectory is determined, we can describe the fit positions of associated clusters as well as the global positions.
23+
This makes it possible to represent each cluster position in the poloar coordinates $$(r, \beta)$$, whose origin is $$(x_c, y_c)$$.
24+
25+
One of the simplest residual in z direction can be calculated in the RZ plane, where $$r = \sqrt(x^2 + y^2)$$.
26+
However, in this case, the fitting stability cannot be guaranteed if the collision position is not located in the same quadrant.
27+
28+
On the other hand, another parameter beta determined above the equation of the circle determined (in the XY plane) corresponds to the distance of the particle moving(=D) in the XY plane.
29+
In this case, the fitting stability can be guaranteed even if the collision position is not located in the same quadrant.
30+
31+
So we proceed with the linear fit in the DZ plane.

Modules/ITS/itsTrack.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,16 @@
4545
"nBCbins": "103",
4646
"dicttimestamp" : "0",
4747
"doNorm" : "1",
48-
"InvMasses" : "0"
48+
"InvMasses" : "0",
49+
"doAlignmentMonitor" : "1",
50+
"UseDefaultMomResPar" : "0",
51+
"MomResParMEAS1": "45, 45, 45, 55, 55, 55, 55",
52+
"MomResParMEAS2": "40, 40, 40, 40, 40, 40, 40",
53+
"MomResParMSC1": "30, 30, 30, 110, 110, 110, 110",
54+
"MomResParMSC2": "25, 25, 25, 75, 75, 75, 75",
55+
"ResidualMonitorNclMin" : "5",
56+
"ResidualMonitorTrackMinPt" : "0.00"
4957
}
50-
5158
}
5259
},
5360
"checks" : {

0 commit comments

Comments
 (0)