Estimate signed momentum for two segments by fitting 2 segments to one approximate track model
53{
54
57
58
59 ATH_MSG_VERBOSE(
" Executing MuonSegmentMomentumTool fitMomentum2Segments ");
60
62
63
64
65
69 covT.setIdentity();
75 ym.setIdentity();
76
78 resi.setIdentity();
79
80
83 double z_end = 15000.;
84 double cos_barrel = std::cos(std::atan2(radius_cylinder,z_cylinder));
85 int imeth;
86
87
91
92
93 double thesp = atan2(
rs, zs);
94
95 double era1 = 0.002;
96
100
101
102 double thespe = atan2( rse,zse);
103 double era2 = 0.002;
104 ATH_MSG_DEBUG(
" radius1 " <<
rs <<
" radius2 " << rse <<
" z1 " << zs <<
" z2 " << zse <<
" theta1 " << thetas <<
" theta2 " << thetase <<
" thetasp1 " << thesp <<
" thetasp2 " << thespe);
105
107 if (fabs(
cos(thesp)) < cos_barrel || fabs(
cos(thespe)) < cos_barrel )
barrel =
true;
108 bool forward = false;
109 if (fabs(
cos(thesp)) > cos_barrel || fabs(
cos(thespe)) > cos_barrel ) forward =
true;
110
111 double scf = 20.;
113 if (forward) scf = 2*scf;
114 double scfn = 20.0;
115 if (forward) scfn = 2*scfn;
116
117
118
119
120
121 double ers2 = 0.1*0.1+scf*scf+scfn*scfn;
122 double ebs2 = 50*50*fabs(
sin(thetas)*
sin(thetase))+ers2;
123 double ets21 = era1*era1 + 0.002*0.002*scf*scf;
124 double ets22 = era2*era2 + 0.002*0.002*scf*scf;
125
126
127
129
131 if ( zs < 0 )
sign = -1.;
132
134 imeth = 0;
135
147
148
149 ym(0,0) = 0.;
150 ym(1,0) = zs;
151 ym(2,0)=
cos(thetas)/
sin(thetas);
152 ym(3,0) = zse;
153 ym(4,0)=
cos(thetase)/
sin(thetase);
154 } else {
155 imeth = 1;
157
169
170 if (fabs(zs) > z_end+2000) {
175 }
176 if (fabs(zse) > z_end+2000) {
181 }
182
183
184 ym(0,0) = 0.;
186 ym(2,0)=
tan(thetas);
187 ym(3,0) = rse;
188 ym(4,0)=
tan(thetase);
189
190 }
191 ATH_MSG_DEBUG(
" distance segments " << sqrt((zs-zse)*(zs-zse)+(
rs-rse)*(
rs-rse)) );
192
193 for(
int i = 0;
i <3 ; ++
i ) {
194 v(i,0)=
model(0,i)*ym(0,0)/ebs2 +
model(1,i)*ym(1,0)/ers2 +
model(2,i)*ym(2,0)/ets21
195 +
model(3,i)*ym(3,0)/ers2 +
model(4,i)*ym(4,0)/ets22;
196 }
197
199 covTI.setIdentity();
200 for(
int i = 0;
i <3 ; ++
i ) {
201 for(
int j = 0;
j <3 ; ++
j ) {
207 }
208 }
209
210 covT = covTI.inverse();
212
213
214 double theta=0.;
double invcurvature=0.;
215 if (imeth == 0) {
218 } else if (imeth == 1) {
219 theta = atan2(1.,1./
t(1,0));
221 }
222
223 signedMomentum = (1./invcurvature)/10.;
224
225 ATH_MSG_DEBUG(
" MuonSegmentMomentum in MeV " << (1./invcurvature)/10. <<
" theta fit " <<
theta <<
" cos theta " <<
cos(
theta) );
226
227
228 for(
int i = 0;
i <5 ; ++
i ) {
230 }
231 double chi2 = resi(0,0)*resi(0,0)/ebs2 + resi(1,0)*resi(1,0)/ers2 + resi(2,0)*resi(2,0)/ets21
232 + resi(3,0)*resi(3,0)/ers2 + resi(4,0)*resi(4,0)/ets22;
234 ATH_MSG_DEBUG(
" Track parameters Matrix T00 " <<
t(0,0) <<
" T10 " <<
t(1,0) <<
" T20 " <<
t(2,0) );
235
236
237
238
240 for(
int i = 0;
i<4 ; ++
i ) {
242 }
243
244 std::vector <double>
pull(4);
245
246 bool toobig = false;
247 for(
int i = 0;
i <4 ; ++
i ) {
249 if ( i==1 )
pull[
i] =
res[
i]/sqrt(ets21);
251 if ( i==3 )
pull[
i] =
res[
i]/sqrt(ets22);
252 if ( fabs( pull[i] ) > 5 ) toobig = true;
253 }
254
255 if (toobig) {
256 ATH_MSG_DEBUG(
" Pull too BIGFIT " <<
" rad pos1 " <<
rs <<
" rad pos2 " << rse <<
" ang1 " << thetas <<
" ang2 " << thetase );
259 ATH_MSG_DEBUG(
" z pos1 " << zs <<
" z pos2 " << zse <<
" phi pos 1 " << phisp <<
" phi pos 2 " << phispe );
260
264 }
265 ATH_MSG_DEBUG(
" Fit2MomentumSegments: residual 0 " <<
res[0] <<
" pull 0 " << pull[0] <<
" residual 1 " <<
res[1] <<
" pull 1 " << pull[1] );
266 ATH_MSG_DEBUG(
" Fit2MomentumSegments: residual 2 " <<
res[2] <<
" pull 2 " << pull[2] <<
" residual 3 " <<
res[3] <<
" pull 3 " << pull[3] );
267 ATH_MSG_DEBUG(
" radius 1 " << ym(1,0) <<
" cottan theta 1 " << ym(2,0) <<
" radius 2 " << ym(3,0)
268 << " cottan theta 2 " << ym(4,0) );
269 ATH_MSG_DEBUG(
" radius fit 1 " << -(
res[0]+ym(1,0)) <<
" cottan theta fit 1 " << -(
res[1]+ym(2,0)) <<
" radius 2 fit " << -(
res[2]+ym(3,0))
270 <<
" cottan theta 2 fit " << -(
res[3]+ym(4,0)) );
271}
Scalar theta() const
theta method
#define ATH_MSG_VERBOSE(x)
std::pair< std::vector< unsigned int >, bool > res
Gaudi::Property< bool > m_cosmics
flag for use of cosmics, straight line model will be used, no interaction point constraint
const Amg::Vector3D & globalDirection() const
global direction
virtual const Amg::Vector3D & globalPosition() const override final
global position
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
constexpr double radius_cylinder
radius of cylinder
constexpr double z_cylinder
length of cylinder
constexpr double z_end
z value whereafter no magnetic field / curvature
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)