25 ATH_MSG_VERBOSE(
" Executing MuonSegmentMomentumTool fitMomentumVectorSegments ");
26 ATH_MSG_DEBUG(
" fitMomentumVectorSegments " << segments.size() <<
" segments ");
28 std::vector<const Muon::MuonSegment*>::const_iterator it = segments.begin();
29 std::vector<const Muon::MuonSegment*>::const_iterator it2 = segments.begin();
30 std::vector<const Muon::MuonSegment*>::const_iterator it_end = segments.end();
32 double pmin = 10000000000.;
33 for(; it < it_end ; ++it ) {
34 for(it2 = it; it2 < it_end ; ++it2 ) {
35 if (it == it2)
continue;
38 ATH_MSG_DEBUG(
" Fit pair of segments signed momentum " << smom);
39 if (fabs(smom) < fabs(pmin)) pmin = smom;
43 signedMomentum = pmin;
44 if (signedMomentum < 100. && signedMomentum > 0 ) signedMomentum = 100.;
45 if (signedMomentum > -100. && signedMomentum <= 0 ) signedMomentum = -100.;
47 ATH_MSG_DEBUG(
" Estimated signed momentum " << signedMomentum);
59 ATH_MSG_VERBOSE(
" Executing MuonSegmentMomentumTool fitMomentum2Segments ");
81 double radius_cylinder = 4000.;
82 double z_cylinder = 6000.;
83 double z_end = 15000.;
84 double cos_barrel = std::cos(std::atan2(radius_cylinder,z_cylinder));
93 double thesp = atan2(
rs, zs);
102 double thespe = atan2( rse,zse);
104 ATH_MSG_DEBUG(
" radius1 " <<
rs <<
" radius2 " << rse <<
" z1 " << zs <<
" z2 " << zse <<
" theta1 " << thetas <<
" theta2 " << thetase <<
" thetasp1 " << thesp <<
" thetasp2 " << thespe);
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;
113 if (forward) scf = 2*scf;
115 if (forward) scfn = 2*scfn;
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;
131 if ( zs < 0 )
sign = -1.;
139 model(1,2) = (
rs-radius_cylinder)*(
rs-radius_cylinder);
141 model(2,2) = 2*(
rs-radius_cylinder);
144 model(3,2) = (rse-radius_cylinder)*(rse-radius_cylinder);
146 model(4,2) = 2*(rse-radius_cylinder);
151 ym(2,0)= cos(thetas)/sin(thetas);
153 ym(4,0)= cos(thetase)/sin(thetase);
161 model(1,2) =
sign*(zs-
sign*z_cylinder)*(zs-
sign*z_cylinder);
163 model(2,2) =
sign*2*(zs-
sign*z_cylinder);
166 model(3,2) =
sign*(zse-
sign*z_cylinder)*(zse-
sign*z_cylinder);
168 model(4,2) =
sign*2*(zse-
sign*z_cylinder);
170 if (fabs(zs) > z_end+2000) {
171 model(1,2) =
sign*(-z_end*z_end + z_cylinder*z_cylinder + 2*zs*
sign*(z_end-z_cylinder)
172 + (zs-
sign*z_end)*(zs-
sign*z_end)/5.);
174 + (zs-
sign*z_end)/5.);
176 if (fabs(zse) > z_end+2000) {
177 model(3,2) =
sign*(-z_end*z_end + z_cylinder*z_cylinder + 2*zse*
sign*(z_end-z_cylinder)
178 + (zse-
sign*z_end)*(zse-
sign*z_end)/5.);
180 + (zse-
sign*z_end)/5.);
186 ym(2,0)= tan(thetas);
188 ym(4,0)= tan(thetase);
191 ATH_MSG_DEBUG(
" distance segments " << sqrt((zs-zse)*(zs-zse)+(
rs-rse)*(
rs-rse)) );
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;
200 for(
int i = 0; i <3 ; ++i ) {
201 for(
int j = 0; j <3 ; ++j ) {
202 covTI(i,j) += model(0,i)*model(0,j)/ebs2;
203 covTI(i,j) += model(1,i)*model(1,j)/ers2;
204 covTI(i,j) += model(2,i)*model(2,j)/ets21;
205 covTI(i,j) += model(3,i)*model(3,j)/ers2;
206 covTI(i,j) += model(4,i)*model(4,j)/ets22;
210 covT = covTI.inverse();
214 double theta=0.;
double invcurvature=0.;
216 theta = atan2(1.,t(1,0));
217 invcurvature = t(2,0)*sin(
theta);
218 }
else if (imeth == 1) {
219 theta = atan2(1.,1./t(1,0));
220 invcurvature = -t(2,0)*fabs(cos(
theta));
223 signedMomentum = (1./invcurvature)/10.;
225 ATH_MSG_DEBUG(
" MuonSegmentMomentum in MeV " << (1./invcurvature)/10. <<
" theta fit " <<
theta <<
" cos theta " << cos(
theta) );
228 for(
int i = 0; i <5 ; ++i ) {
229 resi(i,0)= model(i,0)*t(0,0) + model(i,1)*t(1,0) + model(i,2)*t(2,0) - ym(i,0);
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) );
240 for(
int i = 0; i<4 ; ++i ) {
244 std::vector <double> pull(4);
247 for(
int i = 0; i <4 ; ++i ) {
248 if ( i==0 ) pull[i] =
res[i]/sqrt(ers2);
249 if ( i==1 ) pull[i] =
res[i]/sqrt(ets21);
250 if ( i==2 ) pull[i] =
res[i]/sqrt(ers2);
251 if ( i==3 ) pull[i] =
res[i]/sqrt(ets22);
252 if ( fabs( pull[i] ) > 5 ) toobig =
true;
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 );
263 ATH_MSG_DEBUG(
" diff phi " << d1.x()*d2.y() - d1.y()*d2.x() );
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)) );