16#if !defined(PACKAGE_LPAR_H_INCLUDED)
17#define PACKAGE_LPAR_H_INCLUDED
23#include "TrackUtil/Helix.h"
24#include "GaudiKernel/StatusCode.h"
25#include "GaudiKernel/IInterface.h"
26#include "GaudiKernel/Kernel.h"
27#include "GaudiKernel/Service.h"
28#include "GaudiKernel/ISvcLocator.h"
29#include "GaudiKernel/SvcFactory.h"
30#include "GaudiKernel/IDataProviderSvc.h"
31#include "GaudiKernel/Bootstrap.h"
33#include "MagneticField/IMagneticFieldSvc.h"
34#include "MagneticField/MagneticFieldSvc.h"
37#include "CLHEP/Matrix/Vector.h"
38#include "CLHEP/Matrix/Matrix.h"
39#ifndef CLHEP_POINT3D_H
40#include "CLHEP/Geometry/Point3D.h"
42#ifndef ENABLE_BACKWARDS_COMPATIBILITY
69 void circle(
double x1,
double y1,
double x2,
double y2,
70 double x3,
double y3);
73 double kappa()
const {
return m_kappa; }
74 double radius()
const {
return 0.5/std::fabs(m_kappa);}
76 double s(
double x,
double y)
const;
77 inline double d(
double x,
double y)
const;
78 inline double dr(
double x,
double y)
const;
79 double s(
double r,
int dir=0)
const;
80 double phi(
double r,
int dir=0)
const;
81 inline int sd(
double r,
double x,
double y,
82 double limit,
double &
s,
double &
d)
const;
100 double xi()
const{
return 1 + 2 * m_cu * m_da; }
101 double sfi()
const {
return m_sfi; }
102 double cfi()
const {
return m_cfi; }
103 double da()
const {
return m_da; }
104 double cu()
const {
return m_cu; }
105 double fi()
const {
return m_fi; }
122 void scale(
double s) { m_kappa /=
s; m_gamma *=
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;
169 StatusCode scmgn = Gaudi::svcLocator()->service(
"MagneticFieldSvc",m_pmgnIMF);
170 if(scmgn!=StatusCode::SUCCESS) {
171 std::cout<<
"Unable to open Magnetic field service"<<std::endl;
192inline void Lpar::rotate(
double c,
double s) {
193 double aLpar = c * m_alpha +
s * m_beta;
194 double betar = -
s * m_alpha + c * m_beta;
199inline void Lpar::move (
double x,
double y) {
200 m_gamma += m_kappa * (
x *
x + y * y ) + m_alpha * x + m_beta * y;
201 m_alpha += 2 * m_kappa *
x;
202 m_beta += 2 * m_kappa * y;
205inline double Lpar::check()
const {
206 return m_alpha * m_alpha + m_beta * m_beta - 4 * m_kappa * m_gamma - 1;
216inline double Lpar::d0(
double x,
double y)
const {
217 return m_alpha *
x + m_beta * y + m_gamma + m_kappa * (
x *
x + y * y);
220inline double Lpar::d(
double x,
double y)
const {
222 const double approx_limit = 0.2;
223 if(std::fabs(m_kappa*dd)>approx_limit)
return -1;
224 return dd * ( 1 - m_kappa * dd );
227inline double Lpar::dr(
double x,
double y)
const {
228 double dx = xc() -
x;
229 double dy = yc() - y;
230 double r = 0.5/std::fabs(m_kappa);
231 return std::fabs(std::sqrt(dx * dx + dy * dy) - r);
234inline double Lpar::r_max()
const {
235 if (m_kappa==0)
return 100000000.0;
236 if (m_gamma==0)
return 1/std::fabs(m_kappa);
237 return std::fabs(2*m_gamma/(std::sqrt(1+4*m_gamma*m_kappa)-1));
240inline double Lpar::arcfun(
double xh,
double yh)
const {
244 double r2kap = 2.0 * m_kappa;
245 double xi = std::sqrt(xi2());
246 double xinv = 1.0 / xi;
247 double ar2kap = std::fabs(r2kap);
248 double cross = m_alpha * yh - m_beta * xh;
249 double a1 = ar2kap *
cross * xinv;
250 double a2 = r2kap * (m_alpha * xh + m_beta * yh) * xinv + xi;
251 if (a1>=0 && a2>0 && a1<0.3) {
253 return cross * ( 1.0 + arg2 * (1./6. + arg2 * (3./40.))) * xinv;
255 double at2 = std::atan2(a1,a2);
256 if (at2<0) at2 += (2*
M_PI);
261inline int Lpar::sd(
double r,
double x,
double y,
262 double limit,
double &
s,
double &
d)
const{
263 if ((x*yc()-y*xc())*m_kappa<0)
return 0;
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;
284 double m_alpha = 10000. / 2.99792458 / m_bField;
285 double dd = d0(pivot.x(),pivot.y());
286 a(1) = dd * ( m_kappa * dd - 1 );
287 a(2) = (m_kappa>0) ? 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;
bool operator==(const EventID &lhs, const EventID &rhs)
bool operator!=(const EventID &lhs, const EventID &rhs)
double abs(const EvtComplex &c)
EvtVector3R cross(const EvtVector3R &p1, const EvtVector3R &p2)
HepGeom::Point3D< double > HepPoint3D
virtual double getReferField()=0
double dr(double x, double y) const
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
friend std::ostream & operator<<(std::ostream &o, Lpar &)
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