15# if defined(__EXTENSIONS__)
18# define __EXTENSIONS__
22#elif defined(__GNUC__)
23# if defined(_XOPEN_SOURCE)
32#define HEP_SHORT_NAMES
36#include "MdcTables/MdcTables.h"
37#include "CLHEP/Matrix/Vector.h"
38#include "CLHEP/Matrix/SymMatrix.h"
39#include "CLHEP/Matrix/DiagMatrix.h"
40#include "CLHEP/Matrix/Matrix.h"
41#include "TrkReco/THelixFitter.h"
42#include "TrkReco/TTrack.h"
44#include "MdcCalibFunSvc/IMdcCalibFunSvc.h"
45#include "MdcCalibFunSvc/MdcCalibFunSvc.h"
47#include "GaudiKernel/ISvcLocator.h"
48#include "GaudiKernel/Bootstrap.h"
50#include "GaudiKernel/StatusCode.h"
51#include "GaudiKernel/IInterface.h"
52#include "GaudiKernel/Kernel.h"
53#include "GaudiKernel/Service.h"
54#include "GaudiKernel/ISvcLocator.h"
55#include "GaudiKernel/SvcFactory.h"
56#include "GaudiKernel/IDataProviderSvc.h"
57#include "GaudiKernel/Bootstrap.h"
58#include "GaudiKernel/MsgStream.h"
59#include "GaudiKernel/SmartDataPtr.h"
60#include "GaudiKernel/IMessageSvc.h"
63#include "EventModel/EventModel.h"
64#include "EvTimeEvent/RecEsTime.h"
67using CLHEP::HepVector;
68using CLHEP::HepSymMatrix;
69using CLHEP::HepDiagMatrix;
70using CLHEP::HepMatrix;
103#define Convergence 1.0e-5
150THelixFitter::main(
TTrackBase & b,
float t0Offset,
151 double *pre_chi2,
double *fitted_chi2)
const {
237 _pre_chi2 = _fitted_chi2 = 0.;
238 if(pre_chi2)*pre_chi2 = _pre_chi2;
239 if(fitted_chi2)*fitted_chi2 = _fitted_chi2;
251 cout<<__FILE__<<
" cores in helix = "<<cores.length()<<endl;
254 unsigned nCores = cores.length();
258 bool fitBy2D = _fit2D;
259 if (! fitBy2D) fitBy2D = (! nStereoCores);
263 if ((nStereoCores < 2) || (nCores - nStereoCores < 3))
283 bool allAxial =
true;
294 unsigned nInitBadWires = 0;
297 for (
unsigned j = 0; j < 5; ++j) initBadDchi2da[j] = 0.;
298 double initBadChi2 = 0.;
306 for (
unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
311 cout<<
"helix fitter a5 "<<
t.helix().a()<<
" cores.length "<<cores.length()<<endl;
315 while (
TMLink * l = cores[i++]) {
322 t.approach(* l, _sag);
323 double dPhi = l->dPhi();
324 const HepPoint3D & onTrack = l->positionOnTrack();
325 const HepPoint3D & onWire = l->positionOnWire();
326 unsigned leftRight = (onWire.cross(onTrack).z() < 0.)
332 drift(
t, * l, t0Offset, distance, eDistance);
333 l->drift(distance,0);
334 l->drift(distance,1);
335 l->dDrift(eDistance,0);
336 l->dDrift(eDistance,1);
339 double inv_eDistance2 = 1. / (eDistance * eDistance);
343 double vmag =
v.mag();
345 std::cout<<
"THelixFitter::eDistance-----"<<eDistance<<endl;
346 cout<<
" vmag = "<<vmag<<
" distance = "<<distance<<
" eDistance = "<<eDistance<<endl;
348 double dDistance = vmag - distance;
351 this->dxda(* l,
t.helix(), dPhi, dxda, dyda, dzda);
359 double vwxy = vw[0]*vw[1];
360 double vwyz = vw[1]*vw[2];
361 double vwzx = vw[2]*vw[0];
363 ? ((
v.x() * (1. - vw[0] * vw[0]) -
364 v.y() * vwxy -
v.z() * vwzx)
366 (
v.y() * (1. - vw[1] * vw[1]) -
367 v.z() * vwyz -
v.x() * vwxy)
369 (
v.z() * (1. - vw[2] * vw[2]) -
370 v.x() * vwzx -
v.y() * vwyz)
374 std::cout <<
" in fit " << onTrack <<
", " << onWire;
377 double pChi2 = dDistance * dDistance * inv_eDistance2;
379 std::cout<<
"THelixFitter::dDistance"<<dDistance<<
" inv_eDistance2 "<<inv_eDistance2<<endl;
380 cout<<
"Liuqg check ... .. pChi2 = "<<pChi2<<endl;
384 if (flagBad && nTrial == 0) {
386 initBadWires.append(l);
387 initBadDchi2da += (dDistance * inv_eDistance2) * dDda;
388 initBadD2chi2d2a += vT_times_v(dDda) * inv_eDistance2;
389 initBadChi2 += pChi2;
393 dchi2da += (dDistance * inv_eDistance2) * dDda;
394 d2chi2d2a += vT_times_v(dDda) * inv_eDistance2;
398 l->update(onTrack, onWire, leftRight, pChi2);
422 if (flagBad && nTrial == 0) {
423 if ((initBadWires.length() == 1 || initBadWires.length() == 2) &&
425 chi2 / (
double)(nCores - initBadWires.length()) < 10.) {
426 cores.remove(initBadWires);
427 nInitBadWires = initBadWires.length();
429 else if (initBadWires.length() != 0) {
430 dchi2da += initBadDchi2da;
431 d2chi2d2a += initBadD2chi2d2a;
446 double change = chi2Old -
chi2;
447#ifdef TRKRECO_DEBUG_DETAIL
448 std::cout<<
" chi2 change "<<change <<
" convergence "<<convergence <<
" break? "<<(fabs(change) < convergence ==
true)<<std::endl;
450 if (fabs(change) < convergence)
break;
461 f = dchi2da.sub(1, 3);
462 e = d2chi2d2a.sub(1, 3);
471 da = solve(d2chi2d2a, dchi2da);
481 if( fabs(a[3]) > 1000. ){
487#ifdef TRKRECO_DEBUG_DETAIL
488 std::cout <<
" fit " << nTrial-1<<
" : " <<
chi2 <<
" : "
489 << change << std::endl;
522 Eb = d2chi2d2a.sub(1, 3);
523 Ec = Eb.inverse(err);
533 Ea = d2chi2d2a.inverse(err);
546 t._charge = copysign(1., a[2]);
547 t._ndf = nCores - dim -nInitBadWires;
552 for (
unsigned i = 0; i < nInitBadWires; i++) {
553 TMLink * l = initBadWires[i];
554 t.approach(* l, _sag);
555 double dPhi = l->
dPhi();
559 double vmag =
v.mag();
560 unsigned leftRight = (onWire.cross(onTrack).z() < 0.)
564 drift(
t, * l, t0Offset, distance, eDistance);
565 l->
drift(distance,0);
566 l->
drift(distance,1);
571 double inv_eDistance2 = 1. / (eDistance * eDistance);
572 double dDistance = vmag - distance;
573 double pChi2 = dDistance * dDistance * inv_eDistance2;
574 l->
update(onTrack, onWire, leftRight, pChi2);
576#ifdef TRKRECO_DEBUG_DETAIL
577 std::cout <<
" HelixFitter : # of rejected hits="
578 << nInitBadWires << endl;
582 if (pre_chi2) * pre_chi2 = _pre_chi2;
583 if (fitted_chi2) * fitted_chi2 = _fitted_chi2;
589THelixFitter::main(
TTrackBase & b,
float t0Offset,
590 double *pre_chi2,
double *fitted_chi2)
const {
591#ifdef TRKRECO_DEBUG_DETAIL
608 _pre_chi2 = _fitted_chi2 = 0.;
609 if(pre_chi2)*pre_chi2 = _pre_chi2;
610 if(fitted_chi2)*fitted_chi2 = _fitted_chi2;
622 unsigned nCores = cores.length();
626 bool fitBy2D = _fit2D;
627 if (! fitBy2D) fitBy2D = (! nStereoCores);
631 if ((nStereoCores < 2) || (nCores - nStereoCores < 3))
651 bool allAxial =
true;
659 unsigned nInitBadWires = 0;
662 for (
unsigned j = 0; j < 5; ++j) initBadDchi2da[j] = 0.;
663 double initBadChi2 = 0.;
671 for (
unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
676 while (
TMLink * l = cores[i++]) {
680 t.approach(* l, _sag);
681 double dPhi = l->
dPhi();
685 if (onWire.cross(onTrack).z() < 0.) leftRight =
WireHitLeft;
690 drift(
t, * l, t0Offset, distance, eDistance);
693 double eDistance2 = eDistance * eDistance;
697 double vmag =
v.mag();
698 double dDistance = vmag - distance;
701 this->dxda(* l,
t.helix(), dPhi, dxda, dyda, dzda);
707 ? ((
v.x() * (1. - vw.x() * vw.x()) -
708 v.y() * vw.x() * vw.y() -
v.z() * vw.x() * vw.z())
710 (
v.y() * (1. - vw.y() * vw.y()) -
711 v.z() * vw.y() * vw.z() -
v.x() * vw.y() * vw.x())
713 (
v.z() * (1. - vw.z() * vw.z()) -
714 v.x() * vw.z() * vw.x() -
v.y() * vw.z() * vw.y())
718 std::cout <<
" in fit " << onTrack <<
", " << onWire;
721 double pChi2 = dDistance * dDistance / eDistance2;
723 if(nTrial == 0 && pChi2 > 1500.){
724 initBadWires.append(l);
725 initBadDchi2da += (dDistance / eDistance2) * dDda;
726 initBadD2chi2d2a += vT_times_v(dDda) / eDistance2;
727 initBadChi2 += pChi2;
729 dchi2da += (dDistance / eDistance2) * dDda;
730 d2chi2d2a += vT_times_v(dDda) / eDistance2;
733 l->
update(onTrack, onWire, leftRight, pChi2);
736 dchi2da += (dDistance / eDistance2) * dDda;
737 d2chi2d2a += vT_times_v(dDda) / eDistance2;
740 l->
update(onTrack, onWire, leftRight, pChi2);
746 (initBadWires.length() == 1 ||
747 initBadWires.length() == 2) &&
749 chi2/(
double)(nCores-initBadWires.length()) < 10.){
750 cores.remove(initBadWires);
751 nInitBadWires = initBadWires.length();
752 }
else if(nTrial == 0 && initBadWires.length() != 0){
753 dchi2da += initBadDchi2da;
754 d2chi2d2a += initBadD2chi2d2a;
763 }
else _fitted_chi2 =
chi2;
766 double change = chi2Old -
chi2;
767 if (fabs(change) < convergence)
break;
778 f = dchi2da.sub(1, 3);
779 e = d2chi2d2a.sub(1, 3);
788 da = solve(d2chi2d2a, dchi2da);
798 if( fabs(a[3]) > 1000. ){
804#ifdef TRKRECO_DEBUG_DETAIL
805 std::cout <<
" fit " << nTrial-1<<
" : " <<
chi2 <<
" : "
806 << change << std::endl;
810#ifdef TRKRECO_DEBUG_DETAIL
824 Eb = d2chi2d2a.sub(1, 3);
825 Ec = Eb.inverse(err);
835 Ea = d2chi2d2a.inverse(err);
848 t._charge = copysign(1., a[2]);
849 t._ndf = nCores - dim -nInitBadWires;
852 if(pre_chi2)*pre_chi2 = _pre_chi2;
853 if(fitted_chi2)*fitted_chi2 = _fitted_chi2;
862THelixFitter::dxda(
const TMLink & link,
871 std::cout<<
" ERROR: THelixFitter::dxda 1st m_pmgnIMF == NULL "<<std::endl;
877 const double dRho = a[0];
878 const double phi0 = a[1];
879 const double kappa = a[2];
884 const double rho = 333.564095/(kappa * Bz);
885 const double tanLambda = a[4];
887 const double sinPhi0 =
sin(phi0);
888 const double cosPhi0 =
cos(phi0);
891 const double sinPhi0dPhi =
sin(phi0+dPhi);
892 const double cosPhi0dPhi =
cos(phi0+dPhi);
898 HepPoint3D wireBackwardPosition =
w.backwardPosition();
903 wireBackwardPosition,
946 const double v_dot_wireBackwardPosition =
v.x()*wireBackwardPosition.x()
947 +
v.y()*wireBackwardPosition.y()
948 +
v.z()*wireBackwardPosition.z();
949 const double c[3] = {
w.backwardPosition().x()-v_dot_wireBackwardPosition*
v.x(),
950 w.backwardPosition().y()-v_dot_wireBackwardPosition*
v.y(),
951 w.backwardPosition().z()-v_dot_wireBackwardPosition*
v.z() };
954 const double x_minus_c[3] = {
x[0]-c[0],
x[1]-c[1],
x[2]-c[2] };
957 const double dxdphi[3] = { rho*sinPhi0dPhi, -rho*cosPhi0dPhi, -rho*tanLambda };
960 const double d2xdphi2[3] = { -dxdphi[1], dxdphi[0], 0. };
962 double dxdphi_dot_v = (dxdphi[0] *
v.x() +
965 double x_dot_v =
x[0] *
v.x() +
x[1] *
v.y() +
x[2] *
v.z();
966 double inv_dfdphi = -1./(( dxdphi[0] - dxdphi_dot_v*
v.x()) * dxdphi[0]
967 +(dxdphi[1] - dxdphi_dot_v*
v.y()) * dxdphi[1]
968 +(dxdphi[2] - dxdphi_dot_v*
v.z()) * dxdphi[2]
969 +(x_minus_c[0] - x_dot_v*
v.x()) * d2xdphi2[0]
970 +(x_minus_c[1] - x_dot_v*
v.y()) * d2xdphi2[1]);
974 const double rho_per_kappa = rho/kappa;
975 const double dRho_plus_rho = dRho+rho;
976 const double &rhoSinPhi0dPhi = dxdphi[0];
977 const double rhoCosPhi0dPhi = -dxdphi[1];
978 const double rhoTanLambda = -dxdphi[2];
983 dxda_phi[0] = cosPhi0;
984 dxda_phi[1] = -dRho_plus_rho*sinPhi0+rhoSinPhi0dPhi;
985 dxda_phi[2] = -rho_per_kappa*(cosPhi0-cosPhi0dPhi);
991 dyda_phi[0] = sinPhi0;
992 dyda_phi[1] = dRho_plus_rho*cosPhi0-rhoCosPhi0dPhi;
993 dyda_phi[2] = -rho_per_kappa*(sinPhi0-sinPhi0dPhi);
1001 dzda_phi[2] = rho_per_kappa*tanLambda*dPhi;
1003 dzda_phi[4] = -rho*dPhi;
1006 double d2xdphida[5];
1008 d2xdphida[1] = rhoCosPhi0dPhi;
1009 d2xdphida[2] = -rho_per_kappa*sinPhi0dPhi;
1014 double d2ydphida[5];
1016 d2ydphida[1] = rhoSinPhi0dPhi;
1017 d2ydphida[2] = rho_per_kappa*cosPhi0dPhi;
1022 double d2zdphida[5];
1025 d2zdphida[2] = rho_per_kappa*tanLambda;
1027 d2zdphida[4] = -rho;
1031 for(
int i = 0; i < 5; ++i) {
1032 double d_dot_v = (
v.x() * dxda_phi[i] +
1033 v.y() * dyda_phi[i] +
1034 v.z() * dzda_phi[i]);
1035 dfda[i] = (- (dxda_phi[i] - d_dot_v *
v.x()) * dxdphi[0]
1036 - (dyda_phi[i] - d_dot_v *
v.y()) * dxdphi[1]
1037 - (dzda_phi[i] - d_dot_v *
v.z()) * dxdphi[2]
1038 - (x_minus_c[0] - x_dot_v *
v.x()) * d2xdphida[i]
1039 - (x_minus_c[1] - x_dot_v *
v.y()) * d2ydphida[i]
1040 - (x_minus_c[2] - x_dot_v *
v.z()) * d2zdphida[i]);
1041 dphida[i] = -dfda[i]*inv_dfdphi;
1044 dxda[0] = cosPhi0+rhoSinPhi0dPhi*dphida[0];
1045 dxda[1] = -dRho_plus_rho*sinPhi0+rhoSinPhi0dPhi*(1.+dphida[1]);
1046 dxda[2] = -rho_per_kappa*(cosPhi0-cosPhi0dPhi)+rhoSinPhi0dPhi*dphida[2];
1047 dxda[3] = rhoSinPhi0dPhi*dphida[3];
1048 dxda[4] = rhoSinPhi0dPhi*dphida[4];
1050 dyda[0] = sinPhi0-rhoCosPhi0dPhi*dphida[0];
1051 dyda[1] = dRho_plus_rho*cosPhi0-rhoCosPhi0dPhi*(1.+dphida[1]);
1052 dyda[2] = -rho_per_kappa*(sinPhi0-sinPhi0dPhi)-rhoCosPhi0dPhi*dphida[2];
1053 dyda[3] = -rhoCosPhi0dPhi*dphida[3];
1054 dyda[4] = -rhoCosPhi0dPhi*dphida[4];
1056 dzda[0] = -rhoTanLambda*dphida[0];
1057 dzda[1] = -rhoTanLambda*dphida[1];
1058 dzda[2] = rho_per_kappa*tanLambda*dPhi-rhoTanLambda*dphida[2];
1059 dzda[3] = 1.-rhoTanLambda*dphida[3];
1060 dzda[4] = -rho*dPhi-rhoTanLambda*dphida[4];
1071THelixFitter::dxda(
const TMLink & link,
1084 double kappa = a[2];
1090 std::cout<<
" ERROR: THelixFitter::dxda 1st m_pmgnIMF == NULL "<<std::endl;
1093 double rho = 333.564095/(-1000*(m_pmgnIMF->
getReferField())) / kappa;
1095 double tanLambda = a[4];
1097 double sinPhi0 =
sin(phi0);
1098 double cosPhi0 =
cos(phi0);
1101 double sinPhi0dPhi =
sin(phi0 + dPhi);
1102 double cosPhi0dPhi =
cos(phi0 + dPhi);
1107 HepPoint3D wireBackwardPosition =
w.backwardPosition();
1112 wireBackwardPosition,
1139 c =
HepPoint3D(
w.backwardPosition() - (
v * wireBackwardPosition) *
v);
1145 dxdphi[0] = rho * sinPhi0dPhi;
1146 dxdphi[1] = - rho * cosPhi0dPhi;
1147 dxdphi[2] = - rho * tanLambda;
1150 d2xdphi2[0] = rho * cosPhi0dPhi;
1151 d2xdphi2[1] = rho * sinPhi0dPhi;
1154 double dxdphi_dot_v = (dxdphi[0] *
v.x() +
1157 double x_dot_v =
x[0] *
v.x() +
x[1] *
v.y() +
x[2] *
v.z();
1158 double dfdphi = - (dxdphi[0] - dxdphi_dot_v*
v.x()) * dxdphi[0]
1159 - (dxdphi[1] - dxdphi_dot_v*
v.y()) * dxdphi[1]
1160 - (dxdphi[2] - dxdphi_dot_v*
v.z()) * dxdphi[2]
1161 - (x[0] - c[0] - x_dot_v*
v.x()) * d2xdphi2[0]
1162 - (x[1] - c[1] - x_dot_v*
v.y()) * d2xdphi2[1];
1168 dxda_phi[0] = cosPhi0;
1169 dxda_phi[1] = - (dRho + rho) * sinPhi0 + rho * sinPhi0dPhi;
1170 dxda_phi[2] = - (rho / kappa) * (cosPhi0 - cosPhi0dPhi);
1175 dyda_phi[0] = sinPhi0;
1176 dyda_phi[1] = (dRho + rho) * cosPhi0 - rho * cosPhi0dPhi;
1177 dyda_phi[2] = - (rho / kappa) * (sinPhi0 - sinPhi0dPhi);
1184 dzda_phi[2] = (rho / kappa) * tanLambda * dPhi;
1186 dzda_phi[4] = - rho * dPhi;
1190 d2xdphida[1] = rho * cosPhi0dPhi;
1191 d2xdphida[2] = - (rho / kappa) * sinPhi0dPhi;
1197 d2ydphida[1] = rho * sinPhi0dPhi;
1198 d2ydphida[2] = (rho / kappa) * cosPhi0dPhi;
1205 d2zdphida[2] = (rho / kappa) * tanLambda;
1207 d2zdphida[4] = - rho;
1210 for(
int i = 0; i < 5; i++) {
1211 double d_dot_v = (
v.x() * dxda_phi[i] +
1212 v.y() * dyda_phi[i] +
1213 v.z() * dzda_phi[i]);
1214 dfda[i] = (- (dxda_phi[i] - d_dot_v *
v.x()) * dxdphi[0]
1215 - (dyda_phi[i] - d_dot_v *
v.y()) * dxdphi[1]
1216 - (dzda_phi[i] - d_dot_v *
v.z()) * dxdphi[2]
1217 - (x[0] - c[0] - x_dot_v *
v.x()) * d2xdphida[i]
1218 - (x[1] - c[1] - x_dot_v *
v.y()) * d2ydphida[i]
1219 - (x[2] - c[2] - x_dot_v *
v.z()) * d2zdphida[i]);
1220 dphida[i] = - dfda[i] / dfdphi;
1224 dxda[0] = cosPhi0 + rho * sinPhi0dPhi * dphida[0];
1225 dxda[1] = - (dRho + rho) * sinPhi0 + rho * sinPhi0dPhi * (1. + dphida[1]);
1226 dxda[2] = - rho / kappa * (cosPhi0 - cosPhi0dPhi)
1227 + rho * sinPhi0dPhi * dphida[2];
1228 dxda[3] = rho * sinPhi0dPhi * dphida[3];
1229 dxda[4] = rho * sinPhi0dPhi * dphida[4];
1231 dyda[0] = sinPhi0 - rho * cosPhi0dPhi * dphida[0];
1232 dyda[1] = (dRho + rho) * cosPhi0 - rho * cosPhi0dPhi * (1. + dphida[1]);
1233 dyda[2] = - rho / kappa * (sinPhi0 - sinPhi0dPhi)
1234 - rho * cosPhi0dPhi * dphida[2];
1235 dyda[3] = - rho * cosPhi0dPhi * dphida[3];
1236 dyda[4] = - rho * cosPhi0dPhi * dphida[4];
1238 dzda[0] = - rho * tanLambda * dphida[0];
1239 dzda[1] = - rho * tanLambda * dphida[1];
1240 dzda[2] = rho / kappa * tanLambda * dPhi - rho * tanLambda * dphida[2];
1241 dzda[3] = 1. - rho * tanLambda * dphida[3];
1242 dzda[4] = - rho * dPhi - rho * tanLambda * dphida[4];
1253THelixFitter::drift(
const TTrack &
t,
1257 double & err)
const {
1264 if (onWire.cross(onTrack).z() < 0.) leftRight =
WireHitLeft;
1265 int charge = (
t.helix().a()[2]>0) ? 1: -1;
1267 if(NULL == m_pmgnIMF) {
1268 Gaudi::svcLocator()->service(
"MagneticFieldSvc",m_pmgnIMF);
1269 if(NULL == m_pmgnIMF) {
1270 std::cout<< __FILE__<<
" "<<__LINE__<<
" Unable to open Magnetic field service"<<std::endl;
1275 std::cout <<
" orignal ambig "<<leftRight<<
" charge "<< charge <<
" Bz "<<Bz<<std::endl;
1285 std::cout <<
" new ambig "<<leftRight<<std::endl;
1290 if ((t0Offset == 0.) && (! _propagation) && (! _tof)) {
1291 distance = h.
drift(leftRight);
1292 err = h.
dDrift(leftRight);
1303 float tl =
t.helix().a()[4];
1304 float f = sqrt(1. + tl * tl);
1305 float s = fabs(
t.helix().curv()) * fabs(l.
dPhi()) * f;
1306 float p = f / fabs(
t.helix().a()[2]);
1308 float Mass[5] = {0.000511,0.105,0.140,0.493677,0.98327};
1309 tof =
s/29.98*sqrt(1.0+(Mass[imass-1]/p)*(Mass[imass-1]/p));
1327 int side = leftRight;
1337 int prop = _propagation;
1339 const double x0 =
t.helix().pivot().x();
1340 const double y0 =
t.helix().pivot().y();
1341 Hep3Vector pivot_helix(x0,y0,0);
1342 const double dr =
t.helix().a()[0];
1343 const double phi0 =
t.helix().a()[1];
1344 const double kappa =
t.helix().a()[2];
1345 const double dz =
t.helix().a()[3];
1346 const double tanl =
t.helix().a()[4];
1354 const double cox = x0 + dr*
cos(phi0) +
alpha*
cos(phi0)/kappa;
1355 const double coy = y0 + dr*
sin(phi0) +
alpha*
sin(phi0)/kappa;
1358 unsigned nHits =
t.links().length();
1359 unsigned nStereos = 0;
1360 unsigned firstLyr = 44;
1361 unsigned lastLyr = 0;
1366 HepPoint3D dir(ontrack.y()-coy,cox-ontrack.x(),0);
1367 double pos_phi=onwire.phi();
1368 double dir_phi=dir.phi();
1369 while(pos_phi>
pi){pos_phi-=
pi;}
1370 while(pos_phi<0){pos_phi+=
pi;}
1371 while(dir_phi>
pi){dir_phi-=
pi;}
1372 while(dir_phi<0){dir_phi+=
pi;}
1373 double entrangle=dir_phi-pos_phi;
1374 while(entrangle>
pi/2)entrangle-=
pi;
1375 while(entrangle<(-1)*
pi/2)entrangle+=
pi;
1377 double zhit = onWire.z();
1380 std::cout<<
" onWire: "<<onWire<<std::endl;
1381 std::cout<<
" zhit: "<<zhit<<std::endl;
1384 const double vinner = 220.0e8;
1385 const double vouter = 240.0e8;
1386 double vprop = 300.0e9;
1400 Gaudi::svcLocator()->service(
"MessageSvc",
msgSvc);
1401 MsgStream log(
msgSvc,
"TCosmicFitter");
1403 IDataProviderSvc* eventSvc = NULL;
1404 Gaudi::svcLocator()->service(
"EventDataSvc", eventSvc);
1406 SmartDataPtr<RecEsTimeCol> aevtimeCol (eventSvc,
"/Event/Recon/RecEsTimeCol");
1408 RecEsTimeCol::iterator iter_evt = aevtimeCol->begin();
1409 EsT0 = (*iter_evt)->getTest();
1411 log << MSG::WARNING <<
"Could not find RecEsTimeCol" << endreq;
1414 double rawTime = 0.;
1424 Gaudi::svcLocator() -> service(
"MdcCalibFunSvc", l_mdcCalFunSvc);
1426 double tprop = l_mdcCalFunSvc->
getTprop(layerId,zhit*10.);
1428 double timeWalk = l_mdcCalFunSvc->
getTimeWalk(layerId, rawadc);
1430 double T0 = l_mdcCalFunSvc->
getT0(layerId,wire);
1431 double drifttime = rawTime -
tof - tprop - timeWalk -T0;
1435 std::cout<<
"timewalk is : "<< timeWalk << std::endl ;
1436 std::cout<<
"T0 is : "<< T0 << std::endl ;
1437 std::cout<<
"EsT0 is : "<< EsT0 << std::endl ;
1438 std::cout<<
"tprop is : "<< tprop << std::endl ;
1439 std::cout<<
"tof is : "<<
tof << std::endl ;
1440 std::cout<<
"rawTime is : "<< rawTime << std::endl ;
1441 std::cout<<
"driftTime is : "<< drifttime << std::endl ;
1444 dist = l_mdcCalFunSvc->
driftTimeToDist(drifttime,layerId, wire, side, entrangle);
1445 edist = l_mdcCalFunSvc->
getSigma(layerId, side, dist, entrangle,
tanl,zhit*10,rawadc);
1471THelixFitter::main(
TTrackBase & b,
float & tev,
float & tev_err,
1472 double *pre_chi2,
double *fitted_chi2)
const {
1475 _pre_chi2 = _fitted_chi2 = 0.;
1476 if(pre_chi2)*pre_chi2 = _pre_chi2;
1477 if(fitted_chi2)*fitted_chi2 = _fitted_chi2;
1489 unsigned nCores = cores.length();
1493 bool fitBy2D = _fit2D;
1494 if (! fitBy2D) fitBy2D = (! nStereoCores);
1498 if ((nStereoCores < 2) || (nCores - nStereoCores < 3))
1508 for (
unsigned j = 0; j < 5; j++) a[j] =
t.helix().a()[j];
1521 const double convergence = 1.0e-4;
1522 bool allAxial =
true;
1526 double factor = 1.0;
1529 unsigned nTrial = 0;
1534 for (
unsigned j = 0; j < 6; j++) dchi2da[j] = 0.;
1539 while (
TMLink * l = cores[i++]) {
1543 t.approach(* l, _sag);
1544 double dPhi = l->
dPhi();
1553 drift(
t, * l, tev, distance, eDistance, dddt);
1560 double inv_eDistance2 = 1./(eDistance * eDistance);
1565 double vmag =
v.mag();
1566 double dDistance = vmag - distance;
1569 this->dxda(* l,
t.helix(), dPhi, dxda, dyda, dzda);
1576 double vwxy = vw[0]*vw[1];
1577 double vwyz = vw[1]*vw[2];
1578 double vwzx = vw[2]*vw[0];
1579 dDda_5dim = (vmag > 0.)
1580 ? ((
v.x() * (1. - vw[0] * vw[0]) -
1581 v.y() * vwxy -
v.z() * vwzx)
1583 (
v.y() * (1. - vw[1] * vw[1]) -
1584 v.z() * vwyz -
v.x() * vwxy)
1586 (
v.z() * (1. - vw[2] * vw[2]) -
1587 v.x() * vwzx -
v.y() * vwyz)
1591 std::cout <<
" in fit " << onTrack <<
", " << onWire;
1595 dDda[0] = dDda_5dim[0];
1596 dDda[1] = dDda_5dim[1];
1597 dDda[2] = dDda_5dim[2];
1598 dDda[3] = dDda_5dim[3];
1599 dDda[4] = dDda_5dim[4];
1602 dchi2da += (dDistance * inv_eDistance2) * dDda;
1603 d2chi2d2a += vT_times_v(dDda) * inv_eDistance2;
1604 double pChi2 = dDistance * dDistance * inv_eDistance2;
1608 l->
update(onTrack, onWire, leftRight, pChi2);
1614 _fitted_chi2 =
chi2;
1615 }
else _fitted_chi2 =
chi2;
1618 double change = chi2Old -
chi2;
1619 if (fabs(change) < convergence)
break;
1634 f = dchi2da.sub(1, 4);
1635 e = d2chi2d2a.sub(1, 4);
1645 da = solve(d2chi2d2a, dchi2da);
1656 t._helix->a(a_5dim);
1664 std::cout <<
"fit " << nTrial-1<<
" : " <<
chi2 <<
" : " << change << std::endl;
1674 Eb = d2chi2d2a.sub(1, 4);
1675 Ec = Eb.inverse(err);
1676 Ea[0][0] = Ec[0][0];
1677 Ea[0][1] = Ec[0][1];
1678 Ea[0][2] = Ec[0][2];
1679 Ea[0][3] = Ec[0][3];
1680 Ea[1][1] = Ec[1][1];
1681 Ea[1][2] = Ec[1][2];
1682 Ea[1][3] = Ec[1][3];
1683 Ea[2][2] = Ec[2][2];
1684 Ea[2][3] = Ec[2][3];
1685 Ea[3][3] = Ec[3][3];
1689 Ea = d2chi2d2a.inverse(err);
1696 for (
unsigned j = 0; j < 5; j++) a_5dim[j] = a[j];
1698 Ea_5dim = Ea.sub(1, 5);
1699 t._helix->a(a_5dim);
1700 t._helix->Ea(Ea_5dim);
1702 tev_err = sqrt(Ea[5][5]);
1716 t._ndf = nCores - dim;
1719 if(pre_chi2)*pre_chi2 = _pre_chi2;
1720 if(fitted_chi2)*fitted_chi2 = _fitted_chi2;
1727THelixFitter::main(
TTrackBase & b,
float & tev,
float & tev_err,
1728 double *pre_chi2,
double *fitted_chi2)
const {
1731 _pre_chi2 = _fitted_chi2 = 0.;
1732 if(pre_chi2)*pre_chi2 = _pre_chi2;
1733 if(fitted_chi2)*fitted_chi2 = _fitted_chi2;
1745 unsigned nCores = cores.length();
1749 bool fitBy2D = _fit2D;
1750 if (! fitBy2D) fitBy2D = (! nStereoCores);
1754 if ((nStereoCores < 2) || (nCores - nStereoCores < 3))
1764 for (
unsigned j = 0; j < 5; j++) a[j] =
t.helix().a()[j];
1777 const double convergence = 1.0e-4;
1778 bool allAxial =
true;
1782 double factor = 1.0;
1785 unsigned nTrial = 0;
1790 for (
unsigned j = 0; j < 6; j++) dchi2da[j] = 0.;
1795 while (
TMLink * l = cores[i++]) {
1799 t.approach(* l, _sag);
1800 double dPhi = l->
dPhi();
1804 if (onWire.cross(onTrack).z() < 0.) leftRight =
WireHitLeft;
1810 drift(
t, * l, tev, distance, eDistance, dddt);
1813 double eDistance2 = eDistance * eDistance;
1817 double vmag =
v.mag();
1818 double dDistance = vmag - distance;
1821 this->dxda(* l,
t.helix(), dPhi, dxda, dyda, dzda);
1826 dDda_5dim = (vmag > 0.)
1827 ? ((
v.x() * (1. - vw.x() * vw.x()) -
1828 v.y() * vw.x() * vw.y() -
v.z() * vw.x() * vw.z())
1830 (
v.y() * (1. - vw.y() * vw.y()) -
1831 v.z() * vw.y() * vw.z() -
v.x() * vw.y() * vw.x())
1833 (
v.z() * (1. - vw.z() * vw.z()) -
1834 v.x() * vw.z() * vw.x() -
v.y() * vw.z() * vw.y())
1838 std::cout <<
" in fit " << onTrack <<
", " << onWire;
1842 dDda[0] = dDda_5dim[0];
1843 dDda[1] = dDda_5dim[1];
1844 dDda[2] = dDda_5dim[2];
1845 dDda[3] = dDda_5dim[3];
1846 dDda[4] = dDda_5dim[4];
1849 dchi2da += (dDistance / eDistance2) * dDda;
1850 d2chi2d2a += vT_times_v(dDda) / eDistance2;
1851 double pChi2 = dDistance * dDistance / eDistance2;
1855 l->
update(onTrack, onWire, leftRight, pChi2);
1861 _fitted_chi2 =
chi2;
1862 }
else _fitted_chi2 =
chi2;
1865 double change = chi2Old -
chi2;
1866 if (fabs(change) < convergence)
break;
1880 f = dchi2da.sub(1, 4);
1881 e = d2chi2d2a.sub(1, 4);
1891 da = solve(d2chi2d2a, dchi2da);
1902 t._helix->a(a_5dim);
1910 std::cout <<
"fit " << nTrial-1<<
" : " <<
chi2 <<
" : " << change << std::endl;
1920 Eb = d2chi2d2a.sub(1, 4);
1921 Ec = Eb.inverse(err);
1922 Ea[0][0] = Ec[0][0];
1923 Ea[0][1] = Ec[0][1];
1924 Ea[0][2] = Ec[0][2];
1925 Ea[0][3] = Ec[0][3];
1926 Ea[1][1] = Ec[1][1];
1927 Ea[1][2] = Ec[1][2];
1928 Ea[1][3] = Ec[1][3];
1929 Ea[2][2] = Ec[2][2];
1930 Ea[2][3] = Ec[2][3];
1931 Ea[3][3] = Ec[3][3];
1935 Ea = d2chi2d2a.inverse(err);
1942 for (
unsigned j = 0; j < 5; j++) a_5dim[j] = a[j];
1944 Ea_5dim = Ea.sub(1, 5);
1945 t._helix->a(a_5dim);
1946 t._helix->Ea(Ea_5dim);
1948 tev_err = sqrt(Ea[5][5]);
1961 t._ndf = nCores - dim;
1964 if(pre_chi2)*pre_chi2 = _pre_chi2;
1965 if(fitted_chi2)*fitted_chi2 = _fitted_chi2;
1973THelixFitter::drift(
const TTrack &
t,
1978 double & dddt)
const {
1985 if (onWire.cross(onTrack).z() < 0.) leftRight =
WireHitLeft;
1988 if ((tev == 0.) && (! _propagation) && (! _tof)) {
1989 distance = h.
drift(leftRight);
1990 err = h.
dDrift(leftRight);
1998 float tl =
t.helix().a()[4];
1999 float f = sqrt(1. + tl * tl);
2000 float s = fabs(
t.helix().curv()) * fabs(l.
dPhi()) * f;
2001 float p = f / fabs(
t.helix().a()[2]);
2003 float Mass[5] = {0.000511,0.105,0.140,0.493677,0.98327};
2004 tof =
s/29.98*sqrt(1.0+(Mass[imass-1]/p)*(Mass[imass-1]/p));
2012 int side = leftRight;
2016 const double zhit = onWire.z();
2017 const double vinner = 220.0e8;
2018 const double vouter = 240.0e8;
2021 const double vprop = (layerId<8) ? vinner : vouter;
2022 if (0 == layerId%2){
2046 Gaudi::svcLocator()->service(
"MessageSvc",
msgSvc);
2047 MsgStream log(
msgSvc,
"TCosmicFitter");
2049 IDataProviderSvc* eventSvc = NULL;
2050 Gaudi::svcLocator()->service(
"EventDataSvc", eventSvc);
2052 SmartDataPtr<RecEsTimeCol> aevtimeCol (eventSvc,
"/Event/Recon/RecEsTimeCol");
2054 RecEsTimeCol::iterator iter_evt = aevtimeCol->begin();
2055 EsT0 = (*iter_evt)->getTest();
2057 log << MSG::WARNING <<
"Could not find RecEsTimeCol" << endreq;
2060 double rawTime = 0.;
2070 Gaudi::svcLocator() -> service(
"MdcCalibFunSvc", l_mdcCalFunSvc);
2072 double timeWalk = l_mdcCalFunSvc->
getTimeWalk(layerId, rawadc);
2073 double drifttime = rawTime -
tof - 1.0e9*tprop - EsT0 - timeWalk;
2080 int prop = _propagation;
2111 float time_tmp =
time;
2115 Gaudi::svcLocator() -> service(
"MdcCalibFunSvc", l_mdcCalFunSvc);
2117 dist = l_mdcCalFunSvc->
driftTimeToDist(time_tmp,layerId, wire, side,0.0);
2118 edist = l_mdcCalFunSvc->
getSigma(layerId, side, dist, 0.0);
2127 float time_p =
time - 0.1;
2128 float time_m =
time + 0.1;
HepGeom::Point3D< double > HepPoint3D
double sin(const BesAngle a)
double cos(const BesAngle a)
CLHEP::HepSymMatrix SymMatrix
#define WireHitPatternLeft
#define WireHitPatternRight
#define TFitAlreadyFitted
AList< TMLink > AxialHits(const AList< TMLink > &links)
returns axial hits.
unsigned NStereoHits(const AList< TMLink > &links)
returns # of stereo hits.
float TrkRecoHelixFitterChisqMax
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v
float TrkRecoHelixFitterChisqMax
const HepVector & a(void) const
returns helix parameters.
virtual double getReferField()=0
virtual double driftTimeToDist(double drifttime, int layid, int cellid, int lr, double entrance=0.0) const =0
virtual double getSigma(int layid, int lr, double dist, double entrance=0.0, double tanlam=0.0, double z=0.0, double Q=1000.0) const =0
virtual double getTprop(int lay, double z) const =0
virtual double getT0(int layid, int cellid) const =0
virtual double getTimeWalk(int layid, double Q) const =0
double chi2(void) const
returns sum of chi2 aftter fit.
virtual ~THelixFitter()
Destructor.
bool tof(void) const
sets/returns propagation-delay correction flag.
THelixFitter(const std::string &name)
Constructor.
bool tanl(void) const
sets/returns tanLambda correction flag.
struct MdcRec_wirhit * reccdc(void) const
returns a pointer to RECMDC_WIRHIT.
void dump(const std::string &message=std::string(""), const std::string &prefix=std::string("")) const
dumps debug information.
unsigned state(void) const
returns state.
float dDrift(unsigned) const
returns drift distance error.
float drift(unsigned) const
returns drift distance.
const TMDCWire *const wire(void) const
returns a pointer to a TMDCWire.
A class to represent a wire in MDC.
unsigned localId(void) const
returns local id in a wire layer.
unsigned layerId(void) const
returns layer id.
const HepVector3D & direction(void) const
returns direction vector of the wire.
const HepPoint3D & forwardPosition(void) const
returns position in forward endplate.
const HepPoint3D & backwardPosition(void) const
returns position in backward endplate.
std::string name(void) const
returns name.
A class to fit a TTrackBase object.
A class to relate TMDCWireHit and TTrack objects.
void setDriftTime(double)
add by jialk returns timeDrift after prop correction
const HepPoint3D & positionOnWire(void) const
returns the closest point on wire to a track.
const HepPoint3D & positionOnTrack(void) const
returns the closest point on track to wire.
const TMDCWireHit * hit(void) const
returns a pointer to a hit.
void update(const HepPoint3D &onTrack, const HepPoint3D &onWire, unsigned leftRight, double pull)
sets results of fitting.
float dDrift(void) const
returns/sets drift distance error.
double dPhi(void) const
returns dPhi to the closest point.
float drift(void) const
returns/sets drift distance.
const TMDCWire *const wire(void) const
returns a pointer to a wire.
A virtual class for a track class in tracking.
virtual unsigned objectType(void) const
returns object type.
A class to represent a track in tracking.