13#include "TrkReco/TRunge.h"
14#include "TrkReco/TMDCWire.h"
15#include "TrkReco/TRungeFitter.h"
16#include "TrkReco/TTrack.h"
20#include "CLHEP/Matrix/Matrix.h"
21#include "GaudiKernel/Bootstrap.h"
22#include "GaudiKernel/IDataProviderSvc.h"
23#include "GaudiKernel/IInterface.h"
24#include "GaudiKernel/IMessageSvc.h"
25#include "GaudiKernel/ISvcLocator.h"
26#include "GaudiKernel/Kernel.h"
27#include "GaudiKernel/MsgStream.h"
28#include "GaudiKernel/Service.h"
29#include "GaudiKernel/SmartDataPtr.h"
30#include "GaudiKernel/StatusCode.h"
42const double EPS = 1.0e-6;
62 , m_pmgnIMF( nullptr ) {
65 fitter( &TRunge::_fitter );
72 _mass2 = _mass * _mass;
84 , _pivot(
a.getPivot() )
97 , m_pmgnIMF( nullptr ) {
100 fitter( &TRunge::_fitter );
105 if ( _a[2] < 0 ) _charge = -1;
110 _mass2 = _mass * _mass;
137 , m_pmgnIMF( nullptr ) {
140 fitter( &TRunge::_fitter );
145 if ( _a[2] < 0 ) _charge = -1;
150 _mass2 = _mass * _mass;
165 , _pivot( h.
pivot() )
178 , m_pmgnIMF( nullptr ) {
181 fitter( &TRunge::_fitter );
186 if ( _a[2] < 0 ) _charge = -1;
191 _mass2 = _mass * _mass;
216 , m_pmgnIMF( nullptr ) {
219 fitter( &TRunge::_fitter );
224 if ( _a[2] < 0 ) _charge = -1;
229 _mass2 = _mass * _mass;
231 for (
unsigned i = 0; i < 6; i++ ) _yscal[i] =
a.Yscal()[i];
262 std::cout <<
"error at TRunge::reducedchi2 ndf=0" << std::endl;
265 return ( _chi2 / _ndf );
285 tHelix.
pivot( newpivot );
295 if ( _a[2] < 0 ) _charge = -1;
311 return ( _bfieldID );
317 return ( _stepSize );
321 for (
unsigned i = 0; i < 6; i++ ) _yscal[i] = y[i];
333 return ( _stepSizeMax );
338 return ( _stepSizeMin );
343 _mass2 = _mass * _mass;
348 if ( length > 0 ) _maxflightlength = length;
351 return ( _maxflightlength );
357 return (
approach( l, tof, p, material, doSagCorrection ) );
361 bool doSagCorrection ) {
366 double onWire_x, onWire_y, onWire_z, zwf, zwb;
369 wireBackwardPosition =
w.backwardPosition();
372 unsigned stepNum = 0;
373 if (
approach_line( l, wireBackwardPosition,
v, onWire, onTrack, tof, p, material,
379 zwf =
w.forwardPosition().z();
380 zwb =
w.backwardPosition().z();
382 if ( onWire.z() > zwf )
w.wirePosition( zwf, onWire, wireBackwardPosition, (
HepVector3D&)
v );
383 else if ( onWire.z() < zwb )
384 w.wirePosition( zwb, onWire, wireBackwardPosition, (
HepVector3D&)
v );
388 if ( !doSagCorrection )
392 double phipoint = atan( ( onTrack.y() - _pivot.y() ) / onTrack.x() - _pivot.x() );
400 onWire_y = onWire.y();
401 onWire_z = onWire.z();
404 while ( nTrial < 100 )
407 w.wirePosition( onWire_z, xw, wireBackwardPosition, (
HepVector3D&)
v );
408 if (
approach_line( l, wireBackwardPosition,
v, onWire, onTrack, tof, p, material,
411 if ( fabs( onWire_y - onWire.y() ) < 0.0001 )
break;
412 onWire_y = onWire.y();
413 onWire_z += ( onWire.z() - onWire_z ) / 2;
415 if ( onWire_z > zwf ) onWire_z = zwf;
416 else if ( onWire_z < zwb ) onWire_z = zwb;
431 return (
approach_line( l, w0,
v, onLine, onTrack, tof, p, material ) );
437 unsigned stepNum = 0;
438 return (
approach_line( l, w0,
v, onLine, onTrack, tof, p, material, stepNum ) );
447 if ( _stepSize == 0 )
Fly_SC();
448 else Fly( material );
452 const double w0x = w0.x();
453 const double w0y = w0.y();
454 const double w0z = w0.z();
456 const double vx =
v.x();
457 const double vy =
v.y();
458 const double vz =
v.z();
459 const double v_2 = vx * vx + vy * vy + vz * vz;
461 const float clight = 29.9792458;
464 const float p2 = _y[0][3] * _y[0][3] + _y[0][4] * _y[0][4] + _y[0][5] * _y[0][5];
465 const float tof_factor = 1. / clight * sqrt( 1 + _mass2 /
p2 );
470 if ( stepNum > _Nstep ) stepNum = 0;
473 if ( stepNum == 0 && _stepSize != 0 )
475 const double dx = _y[0][0] - w0x;
476 const double dy = _y[0][1] - w0y;
477 stepNum = (unsigned)( sqrt( ( dx * dx + dy * dy ) * ( 1 + _a[4] * _a[4] ) ) / _stepSize );
480 if ( _stepSize == 0 )
486 mergin = (unsigned)( 1.0 / _stepSize );
488 if ( stepNum > mergin ) stepNum -= mergin;
490 if ( stepNum >= _Nstep ) stepNum = _Nstep - 1;
493 unsigned inc = ( mergin >> 1 ) + 1;
498 const double dx = _y[stepNumHi][0] - w0x;
499 const double dy = _y[stepNumHi][1] - w0y;
500 const double dz = _y[stepNumHi][2] - w0z;
501 const double t = ( dx * vx + dy * vy +
dz * vz ) / v_2;
509 pp.setX( _y[stepNumHi][0] );
510 pp.setY( _y[stepNumHi][1] );
511 pp.setZ( _y[stepNumHi][2] );
512 double zwire = hitv.dot( zvec ) + w0z;
513 double dtl =
DisToWire( l, zwire, pp, onw );
514 const double l2 = dtl * dtl;
515 if ( l2 > l2_old )
break;
517 stepNumLo = stepNumHi;
520 if ( stepNumHi >= _Nstep )
527 while ( stepNumHi - stepNumLo > 1 )
529 unsigned j = ( stepNumHi + stepNumLo ) >> 1;
530 const double dx = _y[j][0] - w0x;
531 const double dy = _y[j][1] - w0y;
532 const double dz = _y[j][2] - w0z;
533 const double t = ( dx * vx + dy * vy +
dz * vz ) / v_2;
541 point.setX( _y[j][0] );
542 point.setY( _y[j][1] );
543 point.setZ( _y[j][2] );
544 double zwir = hitv.dot( zv ) + w0z;
545 double dtll =
DisToWire( l, zwir, point, onwir );
546 const double l2 = dtll * dtll;
547 if ( l2 > l2_old ) { stepNumHi = j; }
574 if ( _stepSize == 0 )
577 for (
unsigned i = 0; i < stepNum; i++ ) dstep += _h[i];
578 tof = dstep * tof_factor;
580 else { tof = stepNum * _stepSize * tof_factor; }
692 for (
unsigned i = 0; i < 6; i++ ) y[i] = _y[stepNum][i];
695 const double A[3][3] = { { 1 - vx * vx / v_2, -vx * vy / v_2, -vx * vz / v_2 },
696 { -vy * vx / v_2, 1 - vy * vy / v_2, -vy * vz / v_2 },
697 { -vz * vx / v_2, -vz * vy / v_2, 1 - vz * vz / v_2 } };
701 double Af[3], Af2[3];
704 for ( i = 0; i < 10; i++ )
707 const double dx = y[0] - w0x;
708 const double dy = y[1] - w0y;
709 const double dz = y[2] - w0z;
710 const double t = ( dx * vx + dy * vy +
dz * vz ) / v_2;
711 const double d[3] = { dx -
t * vx, dy -
t * vy,
dz -
t * vz };
721 double zwir = hitv.dot( zv ) + w0z;
722 double dtll =
DisToWire( l, zwir, point, onwir );
723 const double l2 = dtll * dtll;
724 for ( j = 0; j < 3; j++ )
727 for ( k = 0; k < 3; k++ ) g[j] += A[j][k] * d[k];
736 for ( j = 0; j < 3; j++ ) Y += y[j + 3] * g[j];
738 for ( j = 0; j < 3; j++ ) dYds +=
f[j + 3] * g[j];
740 for ( j = 0; j < 3; j++ )
745 for ( j = 0; j < 3; j++ )
749 for ( k = 0; k < 3; k++ ) Af[j] += ( A[j][k] *
f[k] );
750 for ( k = 0; k < 3; k++ ) Af2[j] += ( A[j][k] * Af[k] );
751 dYds += y[j + 3] * Af2[j];
755 const double step = -Y / dYds * factor;
757 if ( fabs( step ) < 0.00001 )
break;
758 if ( l2 > l2_old ) factor /= 2;
764 tof += step2 * tof_factor;
766 onTrack.setX( y[0] );
767 onTrack.setY( y[1] );
768 onTrack.setZ( y[2] );
773 const double dx = y[0] - w0x;
774 const double dy = y[1] - w0y;
775 const double dz = y[2] - w0z;
776 const double s = ( dx * vx + dy * vy +
dz * vz ) / v_2;
780 onLine.setX( onwir.x() );
781 onLine.setY( onwir.y() );
782 onLine.setZ( onwir.z() );
790 if ( _stepSize == 0 )
Fly_SC();
791 else Fly( material );
805 for ( stepNum = 0; stepNum < _Nstep; stepNum++ )
807 double l2 = ( _y[stepNum][0] - x0 ) * ( _y[stepNum][0] - x0 ) +
808 ( _y[stepNum][1] - y0 ) * ( _y[stepNum][1] - y0 ) +
809 ( _y[stepNum][2] - z0 ) * ( _y[stepNum][2] - z0 );
810 if ( l2 > l2_old )
break;
817 if ( stepNum >= _Nstep )
return ( -1 );
821 double y[6], y_old[6];
822 for (
unsigned i = 0; i < 6; i++ ) y[i] = _y[stepNum][i];
823 double step = _stepSize;
826 for (
unsigned i = 0; i < 6; i++ ) y_old[i] = y[i];
828 double l2 = ( y[0] - x0 ) * ( y[0] - x0 ) + ( y[1] - y0 ) * ( y[1] - y0 ) +
829 ( y[2] - z0 ) * ( y[2] - z0 );
832 for (
unsigned i = 0; i < 6; i++ ) y[i] = y_old[i];
841 if ( step < 0.0001 )
break;
844 onTrack.setX( y[0] );
845 onTrack.setY( y[1] );
846 onTrack.setZ( y[2] );
862 for (
unsigned j = 0; j < 6; j++ ) _y[
Nstep][j] = y[j];
867 if ( y[2] > 160 || y[2] < -80 || ( y[0] * y[0] + y[1] * y[1] ) > 8100 )
break;
871 flightlength += _stepSize;
872 if ( flightlength > _maxflightlength )
break;
874 _h[
Nstep] = _stepSize;
882 double f1[6], f2[6], f3[6], f4[6], yt[6];
886 const double mpi = 0.13957;
887 double me = 0.000511;
892 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + hh *
f1[i];
901 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + hh * f2[i];
910 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + step * f3[i];
921 for ( i = 0; i < 6; i++ ) y[i] += h6 * (
f1[i] + 2 * f2[i] + 2 * f3[i] + f4[i] );
948 pos.setX( (
float)y[0] );
949 pos.setY( (
float)y[1] );
950 pos.setZ( (
float)y[2] );
955 getPmgnIMF()->fieldVector( 10 * pos, B );
956 pmag = sqrt( y[3] * y[3] + y[4] * y[4] + y[5] * y[5] );
965 double Bmag = sqrt( B.x() * B.x() + B.y() * B.y() + B.z() * B.z() );
966 factor = ( (double)_charge ) / ( 0.333564095 );
970 f[3] = factor * (
f[1] * B.z() -
f[2] * B.y() );
971 f[4] = factor * (
f[2] * B.x() -
f[0] * B.z() );
972 f[5] = factor * (
f[0] * B.y() -
f[1] * B.x() );
977 const double cosPhi0 =
cos( _a[1] );
978 const double sinPhi0 =
sin( _a[1] );
979 const double invKappa = 1 /
abs( _a[2] );
981 y[0] = _pivot.x() + _a[0] * cosPhi0;
982 y[1] = _pivot.y() + _a[0] * sinPhi0;
983 y[2] = _pivot.z() + _a[3];
984 y[3] = -sinPhi0 * invKappa;
985 y[4] = cosPhi0 * invKappa;
986 y[5] = _a[4] * invKappa;
995 if ( stepNum >= _Nstep || stepNum >=
TRunge_MAXstep )
return ( -1 );
997 for (
unsigned i = 0; i < 6; i++ ) y[i] = _y[stepNum][i];
1001 if ( stepNum >= _Nstep || stepNum >=
TRunge_MAXstep )
return ( -1 );
1009 double f2[6], f3[6], f4[6], yt[6];
1015 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + hh * dydx[i];
1024 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + hh * f2[i];
1033 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + step * f3[i];
1044 for ( i = 0; i < 6; i++ ) yout[i] = y[i] + h6 * ( dydx[i] + 2 * f2[i] + 2 * f3[i] + f4[i] );
1060#define FCOR 0.06666666
1062#define ERRCON 6.0e-4
1064 const double&
eps,
const double yscal[6],
double& stepdid,
1065 double& stepnext ) {
1067 double ysav[6], dysav[6], ytemp[6];
1068 double h, hh, errmax, temp;
1071 for ( i = 0; i < 6; i++ ) ysav[i] = y[i];
1073 for ( i = 0; i < 6; i++ ) dysav[i] = dydx[i];
1087 for ( i = 0; i < 6; i++ )
1089 ytemp[i] = y[i] - ytemp[i];
1090 temp = fabs( ytemp[i] / yscal[i] );
1091 if ( errmax < temp ) errmax = temp;
1095 if ( errmax <= 1.0 )
1103 for ( i = 0; i < 6; i++ ) y[i] += ytemp[i] *
FCOR;
1115 double y[6], dydx[6], yscal[6];
1117 double step, stepdid, stepnext;
1119 double flightlength;
1133 for ( i = 0; i < 6; i++ ) _y[
Nstep][i] = y[i];
1139 Propagate_QC( y, dydx, step, _eps, _yscal, stepdid, stepnext );
1141 if ( y[2] > 160 || y[2] < -80 || ( y[0] * y[0] + y[1] * y[1] ) > 8100 )
break;
1145 flightlength += stepdid;
1146 if ( flightlength > _maxflightlength )
break;
1148 _h[
Nstep] = stepdid;
1150 if ( stepnext < _stepSizeMin ) step = _stepSizeMin;
1151 else if ( stepnext > _stepSizeMax ) step = _stepSizeMax;
1152 else step = stepnext;
1170 const double Bz = 1000 * getPmgnIMF()->getReferField();
1171 double rho = 333.564095 / ( hel.
kappa() * Bz );
1177 for (
int j = 0; j <
cores.length(); j++ )
1188 for (
int i = 0; i < 10; i++ )
1192 if (
abs( th.
dz() ) < 0.1 )
1216 const double vCrs = v0.x() * v1.y() - v0.y() * v1.x();
1217 const double vDot = v0.x() * v1.x() + v0.y() * v1.y();
1218 double phi = atan2( vCrs, vDot );
1220 double tz = hel.
x( phi ).z();
1223 if ( phi > phi_max ) phi_max = phi;
1224 if ( phi < phi_min ) phi_min = phi;
1232 abs( rho * ( phi_max - phi_min ) * sqrt( 1 +
tanl *
tanl ) ) * 1.2;
1234 return ( _maxflightlength );
1247 onwire.setX( point.x() );
1248 onwire.setY( point.y() );
1254 sqrt( ( point.x() -
a.x() ) * ( point.x() -
a.x() ) +
1255 ( point.y() -
a.y() ) * ( point.y() -
a.y() ) + ( z -
a.z() ) * ( z -
a.z() ) );
1268 double Density = 0.00085144;
1269 double coeff = Density * z /
a;
1271 double isq = i * i * 1e-18;
1286 const double Me = 0.000510999;
1288 double bsq = psq / ( psq +
mass *
mass );
1289 double esq = psq / (
mass *
mass );
1291 double s = Me /
mass;
1292 double w = ( 4 * Me * esq / ( 1 + 2 *
s * sqrt( 1 + esq ) +
s *
s ) );
1296 cc = 1 + 2 * log( sqrt( isq ) / ( 28.8E-09 * sqrt( coeff ) ) );
1297 if ( cc < 5.215 ) x0 = 0.2;
1298 else x0 = 0.326 * cc - 1.5;
1299 double x1( 3 ), xa( cc / 4.606 ), aa;
1300 aa = 4.606 * ( xa - x0 ) / ( ( x1 - x0 ) * ( x1 - x0 ) * ( x1 - x0 ) );
1302 double x( log10( sqrt( esq ) ) );
1305 delta = 4.606 * x - cc;
1306 if ( x < x1 ) delta = delta + aa * ( x1 - x ) * ( x1 - x ) * ( x1 - x );
1310 float f1, f2, f3, f4, f5, ce;
1314 f4 = (
f1 * 0.42237 + f2 * 0.0304 - f3 * 0.00038 ) * 1E12;
1315 f5 = (
f1 * 3.858 - f2 * 0.1668 + f3 * 0.00158 ) * 1E18;
1316 ce = f4 * isq + f5 * isq * sqrt( isq );
1318 return ( 0.0001535 * coeff / bsq *
1319 ( log( Me * esq *
w / isq ) - 2 * bsq - delta - 2.0 * ce / z ) ) *
1324 double psq = y[5] * y[5] + y[3] * y[3] + y[4] * y[4];
1326 double p = sqrt( psq );
1328 double dE = materiral->
dE(
mass, path, p );
1329 if ( index > 0 ) psq += dE * ( dE + 2 * sqrt(
mass *
mass + psq ) );
1330 else psq += dE * ( dE - 2 * sqrt(
mass *
mass + psq ) );
1331 double pnew = sqrt( psq );
1332 double coeff = pnew / p;
1334 y[3] = y[3] * coeff;
1335 y[4] = y[4] * coeff;
1336 y[5] = y[5] * coeff;
1341 double cosPhi = ( m_rad * m_rad + l * l - r * r ) / ( 2 * m_rad * l );
1343 if ( cosPhi < -1 || cosPhi > 1 )
return 0.;
1346 if ( dPhi < -
M_PI ) dPhi += 2 *
M_PI;
1353 double d = r * r - ( y - xc.y() ) * ( y - xc.y() );
1354 if ( d < 0 )
return 0;
1357 if ( xx > 0 ) xx -= sqrt( d );
1358 else xx += sqrt( d );
1360 double l = ( plane.inverse() *
HepPoint3D( xx, y, 0 ) ).perp();
1368 double d = r * r - ( x - xc.x() ) * ( x - xc.x() );
1369 if ( d < 0 )
return 0;
1372 if ( yy > 0 ) yy -= sqrt( d );
1373 else yy += sqrt( d );
1375 double l = ( plane.inverse() *
HepPoint3D( x, yy, 0 ) ).perp();
1387 if (
nullptr == m_pmgnIMF )
1389 StatusCode sc = Gaudi::svcLocator()->service(
"MagneticFieldSvc", m_pmgnIMF );
1390 if ( sc.isFailure() )
1391 { std::cout <<
"Unable to open Magnetic field service" << std::endl; }
TFile f("ana_bhabha660a_dqa_mcPat_zy_old.root")
EvtComplex exp(const EvtComplex &c)
EvtTensor3C eps(const EvtVector3R &v)
HepGeom::Transform3D HepTransform3D
double sin(const BesAngle a)
double cos(const BesAngle a)
CLHEP::HepSymMatrix SymMatrix
const HepPoint3D ORIGIN
Constants.
**********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
HepGeom::Point3D< double > HepPoint3D
HepGeom::Vector3D< double > HepVector3D
const double default_maxflightlength
const double default_stepSize0
const double default_stepSizeMin
const double default_stepSize
const double default_stepSizeMax
static Bfield * getBfield(int)
returns Bfield object.
const HepPoint3D & center(void) const
returns position of helix center(z = 0.);
const HepSymMatrix & Ea(void) const
returns error matrix.
HepPoint3D x(double dPhi=0.) const
returns position after rotating angle dPhi in phi direction.
double radius(void) const
returns radious of helix.
const HepVector & a(void) const
returns helix parameters.
const HepPoint3D & pivot(void) const
returns pivot position.
double dE(double mass, double path, double p) const
Calculate energy loss.
A class to represent a wire in MDC.
void wirePosition(float zPosition, HepPoint3D &xyPosition, HepPoint3D &backwardPosition, HepVector3D &direction) const
calculates position and direction vector with sag correction.
A class to relate TMDCWireHit and TTrack objects.
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 TMDCWire *const wire(void) const
returns a pointer to a wire.
A class to fit a TTrackBase object to a 3D line.
double dr(void) const
Track parameters (at pivot).
int GetXP(unsigned stepNum, double y[6]) const
double MaxFlightLength(void) const
return max flight length
Helix helix(void) const
returns helix class
void SetFirst(double y[6]) const
set first point (position, momentum) s=0, phi=0
unsigned Nstep(void) const
access to trajectory cache
double intersect_yz_plane(const HepTransform3D &plane, double x) const
const Vector & a(void) const
returns helix parameter
void eloss(double path, const RkFitMaterial *material, double mass, double y[6], int index) const
double intersect_xy_plane(double z) const
double SetFlightLength(void)
set flight length using wire hits
int approach_point(TMLink &, const HepPoint3D &, HepPoint3D &onTrack, const RkFitMaterial material)
caluculate closest point between a point and this track
double intersect_zx_plane(const HepTransform3D &plane, double y) const
double DisToWire(TMLink &, double, HepPoint3D, HepPoint3D &)
void Propagate_QC(double y[6], double dydx[6], const double &steptry, const double &eps, const double yscal[6], double &stepdid, double &stepnext)
int approach(TMLink &, const RkFitMaterial, bool sagCorrection=true)
void Propagate1(const double y[6], const double dydx[6], const double &step, double yout[6])
double StepSize(void) const
returns step size
const double * Yscal(void) const
return error parameters for fitting with step size control
double StepSizeMax(void) const
int approach_line(TMLink &, const HepPoint3D &, const HepVector3D &, HepPoint3D &onLine, HepPoint3D &onTrack, const RkFitMaterial material)
caluculate closest points between a line and this track
const SymMatrix & Ea(void) const
returns error matrix
const HepPoint3D & pivot(void) const
pivot position
void Propagate(double y[6], const double &step, const RkFitMaterial material)
propagate the track using 4th-order Runge-Kutta method
double reducedchi2(void) const
returns reduced-chi2
float Mass(void) const
return mass
int BfieldID(void) const
returns B field ID
void Function(const double y[6], double f[6])
double StepSizeMin(void) const
int GetStep(unsigned stepNum, double &step) const
double dEpath(double, double, double) const
unsigned Fly(const RkFitMaterial material)
make the trajectory in cache, return the number of step
unsigned ndf(void) const
returns NDF
double chi2(void) const
returns chi2.
double intersect_cylinder(double r) const
const TMFitter *const fitter(void) const
returns a pointer to a default fitter.
const AList< TMLink > & cores(unsigned mask=0) const
returns a list of masked TMLinks for fit. 'mask' will be applied if mask is not 0.
A class to represent a track in tracking.