16#if !defined( PACKAGE_LPAR_H_INCLUDED )
17# define PACKAGE_LPAR_H_INCLUDED
20# include "GaudiKernel/Bootstrap.h"
21# include "GaudiKernel/IDataProviderSvc.h"
22# include "GaudiKernel/IInterface.h"
23# include "GaudiKernel/ISvcLocator.h"
24# include "GaudiKernel/Kernel.h"
25# include "GaudiKernel/Service.h"
26# include "GaudiKernel/StatusCode.h"
27# include "TrackUtil/Helix.h"
32# include "MagneticFieldSvc/IBesMagFieldSvc.h"
35# include "CLHEP/Matrix/Matrix.h"
36# include "CLHEP/Matrix/Vector.h"
37# ifndef CLHEP_POINT3D_H
38# include "CLHEP/Geometry/Point3D.h"
40# ifndef ENABLE_BACKWARDS_COMPATIBILITY
67 void circle(
double x1,
double y1,
double x2,
double y2,
double x3,
double y3 );
70 double kappa()
const {
return m_kappa; }
71 double radius()
const {
return 0.5 / std::fabs( m_kappa ); }
73 double s(
double x,
double y )
const;
74 inline double d(
double x,
double y )
const;
75 inline double dr(
double x,
double y )
const;
76 double s(
double r,
int dir = 0 )
const;
77 double phi(
double r,
int dir = 0 )
const;
78 inline int sd(
double r,
double x,
double y,
double limit,
double&
s,
double&
d )
const;
96 double xi()
const {
return 1 + 2 * m_cu * m_da; }
97 double sfi()
const {
return m_sfi; }
98 double cfi()
const {
return m_cfi; }
99 double da()
const {
return m_da; }
100 double cu()
const {
return m_cu; }
101 double fi()
const {
return m_fi; }
119 void scale(
double s ) {
123 inline void rotate(
double c,
double s );
124 inline void move(
double x,
double y );
127 double alpha()
const {
return m_alpha; }
128 double beta()
const {
return m_beta; }
129 double gamma()
const {
return m_gamma; }
130 inline double check()
const;
131 HepMatrix dldc()
const;
132 inline double d0(
double x,
double y )
const;
133 double kr2g(
double r )
const {
return m_kappa * r * r + m_gamma; }
134 double x(
double r )
const;
135 double y(
double r )
const;
136 void xhyh(
double x,
double y,
double& xh,
double& yh )
const;
137 double xi2()
const {
return 1 + 4 * m_kappa * m_gamma; }
138 bool xy(
double,
double&,
double&,
int dir = 0 )
const;
139 inline double r_max()
const;
140 double xc()
const {
return -m_alpha / 2 / m_kappa; }
141 double yc()
const {
return -m_beta / 2 / m_kappa; }
142 double da()
const {
return 2 * gamma() / ( std::sqrt( xi2() ) + 1 ); }
143 inline double arcfun(
double xh,
double yh )
const;
167 StatusCode scmgn = Gaudi::svcLocator()->service(
"MagneticFieldSvc", m_pmgnIMF );
168 if ( scmgn != StatusCode::SUCCESS )
169 { std::cout <<
"Unable to open Magnetic field service" << std::endl; }
190inline void Lpar::rotate(
double c,
double s ) {
191 double aLpar = c * m_alpha +
s * m_beta;
192 double betar = -
s * m_alpha + c * m_beta;
197inline void Lpar::move(
double x,
double y ) {
198 m_gamma += m_kappa * ( x * x + y * y ) + m_alpha * x + m_beta * y;
199 m_alpha += 2 * m_kappa * x;
200 m_beta += 2 * m_kappa * y;
203inline double Lpar::check()
const {
204 return m_alpha * m_alpha + m_beta * m_beta - 4 * m_kappa * m_gamma - 1;
214inline double Lpar::d0(
double x,
double y )
const {
215 return m_alpha * x + m_beta * y + m_gamma + m_kappa * ( x * x + y * y );
218inline double Lpar::d(
double x,
double y )
const {
219 double dd = d0( x, y );
220 const double approx_limit = 0.2;
221 if ( std::fabs( m_kappa * dd ) > approx_limit )
return -1;
222 return dd * ( 1 - m_kappa * dd );
225inline double Lpar::dr(
double x,
double y )
const {
226 double dx = xc() - x;
227 double dy = yc() - y;
228 double r = 0.5 / std::fabs( m_kappa );
229 return std::fabs( std::sqrt( dx * dx + dy * dy ) - r );
232inline double Lpar::r_max()
const {
233 if ( m_kappa == 0 )
return 100000000.0;
234 if ( m_gamma == 0 )
return 1 / std::fabs( m_kappa );
235 return std::fabs( 2 * m_gamma / ( std::sqrt( 1 + 4 * m_gamma * m_kappa ) - 1 ) );
238inline double Lpar::arcfun(
double xh,
double yh )
const {
242 double r2kap = 2.0 * m_kappa;
243 double xi = std::sqrt( xi2() );
244 double xinv = 1.0 / xi;
245 double ar2kap = std::fabs( r2kap );
246 double cross = m_alpha * yh - m_beta * xh;
247 double a1 = ar2kap *
cross * xinv;
248 double a2 = r2kap * ( m_alpha * xh + m_beta * yh ) * xinv + xi;
249 if ( a1 >= 0 && a2 > 0 && a1 < 0.3 )
251 double arg2 = a1 * a1;
252 return cross * ( 1.0 + arg2 * ( 1. / 6. + arg2 * ( 3. / 40. ) ) ) * xinv;
256 double at2 = std::atan2( a1, a2 );
257 if ( at2 < 0 ) at2 += ( 2 *
M_PI );
262inline int Lpar::sd(
double r,
double x,
double y,
double limit,
double&
s,
double&
d )
const {
263 if ( ( x * yc() - y * xc() ) * m_kappa < 0 )
return 0;
264 double dd = d0( x, y );
265 d = dd * ( 1 - m_kappa * dd );
266 double d_cross_limit =
d * limit;
267 if ( d_cross_limit < 0 || d_cross_limit > limit * limit )
return 0;
268 double rc = std::sqrt( m_alpha * m_alpha + m_beta * m_beta ) / ( 2 * m_kappa );
269 double rho = 1. / ( -2 * m_kappa );
270 double cosPhi = ( rc * rc + rho * rho - r * r ) / ( -2 * rc * rho );
271 double phi = std::acos( cosPhi );
272 s = std::fabs( rho ) *
phi;
273 d *= r / ( std::fabs( rc ) * std::sin(
phi ) );
274 if (
abs(
d ) >
abs( limit ) )
return 0;
275 d_cross_limit =
d * limit;
276 if ( d_cross_limit > limit * limit )
return 0;
282 double m_bField = -10000 * ( m_pmgnIMF->getReferField() );
283 double m_alpha = 10000. / 2.99792458 / m_bField;
284 double dd = d0( pivot.x(), pivot.y() );
285 a( 1 ) = dd * ( m_kappa * dd - 1 );
286 a( 2 ) = ( m_kappa > 0 )
287 ? std::atan2( yc() - pivot.y(), xc() - pivot.x() ) +
M_PI
288 : std::atan2( pivot.y() - yc(), pivot.x() - xc() ) -
M_PI + 2 *
M_PI;
290 a( 3 ) = -2.0 * m_alpha * m_kappa;
HepGeom::Point3D< double > HepPoint3D
bool operator!=(const DataPtr< T > &lhs, const DataPtr< T > &rhs)
EvtVector3R cross(const EvtVector3R &p1, const EvtVector3R &p2)
HepGeom::Point3D< double > HepPoint3D
bool operator==(const double &x, const ICache::ID64 &y)
double dr(double x, double y) const
friend std::ostream & operator<<(std::ostream &o, Lpar &)
double d(double x, double y) const
friend int intersect(const Lpar &, const Lpar &, HepVector &, HepVector &)
double s(double r, int dir=0) const
HepVector Hpar(const HepPoint3D &pivot) const
int sd(double r, double x, double y, double limit, double &s, double &d) const
void circle(double x1, double y1, double x2, double y2, double x3, double y3)
double s(double x, double y) const
const Lpar & operator=(const Lpar &)
double phi(double r, int dir=0) const