00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #ifndef ST_HELIX_HH
00049 #define ST_HELIX_HH
00050
00051 #include <math.h>
00052 #include <utility>
00053 #include <algorithm>
00054 #include "StThreeVector.hh"
00055 #if !defined(ST_NO_NAMESPACES)
00056 using std::pair;
00057 using std::swap;
00058 using std::max;
00059 #endif
00060
00061 class StHelix {
00062 public:
00064 StHelix(double c, double dip, double phase,
00065 const StThreeVector<double>& o, int h=-1);
00066
00067 virtual ~StHelix();
00068
00069
00070
00071 double dipAngle() const;
00072 double curvature() const;
00073 double phase() const;
00074 double xcenter() const;
00075 double ycenter() const;
00076 int h() const;
00077
00078 const StThreeVector<double>& origin() const;
00079
00080 void setParameters(double c, double dip, double phase, const StThreeVector<double>& o, int h);
00081
00083 double x(double s) const;
00084 double y(double s) const;
00085 double z(double s) const;
00086
00087 StThreeVector<double> at(double s) const;
00088
00090 double cx(double s) const;
00091 double cy(double s) const;
00092 double cz(double s = 0) const;
00093
00094 StThreeVector<double> cat(double s) const;
00095
00097 double period() const;
00098
00100 pair<double, double> pathLength(double r) const;
00101
00103 pair<double, double> pathLength(double r, double x, double y);
00104
00106 double pathLength(const StThreeVector<double>& p, bool scanPeriods = true) const;
00107
00109 double pathLength(const StThreeVector<double>& r,
00110 const StThreeVector<double>& n) const;
00111
00113 double pathLength(double x, double y) const;
00114
00116 pair<double, double> pathLengths(const StHelix&) const;
00117
00119 double distance(const StThreeVector<double>& p, bool scanPeriods = true) const;
00120
00122 bool valid(double world = 1.e+5) const {return !bad(world);}
00123 int bad(double world = 1.e+5) const;
00124
00126 virtual void moveOrigin(double s);
00127
00128 static const double NoSolution;
00129
00130 protected:
00131 StHelix();
00132
00133 void setCurvature(double);
00134 void setPhase(double);
00135 void setDipAngle(double);
00136
00138 double fudgePathLength(const StThreeVector<double>&) const;
00139
00140 protected:
00141 bool mSingularity;
00142 StThreeVector<double> mOrigin;
00143 double mDipAngle;
00144 double mCurvature;
00145 double mPhase;
00146 int mH;
00147
00148 double mCosDipAngle;
00149 double mSinDipAngle;
00150 double mCosPhase;
00151 double mSinPhase;
00152 #ifdef __ROOT__
00153 ClassDef(StHelix,1)
00154 #endif
00155 };
00156
00157
00158
00159
00160 int operator== (const StHelix&, const StHelix&);
00161 int operator!= (const StHelix&, const StHelix&);
00162 ostream& operator<<(ostream&, const StHelix&);
00163
00164
00165
00166
00167 inline int StHelix::h() const {return mH;}
00168
00169 inline double StHelix::dipAngle() const {return mDipAngle;}
00170
00171 inline double StHelix::curvature() const {return mCurvature;}
00172
00173 inline double StHelix::phase() const {return mPhase;}
00174
00175 inline double StHelix::x(double s) const
00176 {
00177 if (mSingularity)
00178 return mOrigin.x() - s*mCosDipAngle*mSinPhase;
00179 else
00180 return mOrigin.x() + (cos(mPhase + s*mH*mCurvature*mCosDipAngle)-mCosPhase)/mCurvature;
00181 }
00182
00183 inline double StHelix::y(double s) const
00184 {
00185 if (mSingularity)
00186 return mOrigin.y() + s*mCosDipAngle*mCosPhase;
00187 else
00188 return mOrigin.y() + (sin(mPhase + s*mH*mCurvature*mCosDipAngle)-mSinPhase)/mCurvature;
00189 }
00190
00191 inline double StHelix::z(double s) const
00192 {
00193 return mOrigin.z() + s*mSinDipAngle;
00194 }
00195
00196 inline double StHelix::cx(double s) const
00197 {
00198 if (mSingularity)
00199 return -mCosDipAngle*mSinPhase;
00200 else
00201 return -sin(mPhase + s*mH*mCurvature*mCosDipAngle)*mH*mCosDipAngle;
00202 }
00203
00204 inline double StHelix::cy(double s) const
00205 {
00206 if (mSingularity)
00207 return mCosDipAngle*mCosPhase;
00208 else
00209 return cos(mPhase + s*mH*mCurvature*mCosDipAngle)*mH*mCosDipAngle;
00210 }
00211
00212 inline double StHelix::cz(double ) const
00213 {
00214 return mSinDipAngle;
00215 }
00216
00217 inline const StThreeVector<double>& StHelix::origin() const {return mOrigin;}
00218
00219 inline StThreeVector<double> StHelix::at(double s) const
00220 {
00221 return StThreeVector<double>(x(s), y(s), z(s));
00222 }
00223
00224 inline StThreeVector<double> StHelix::cat(double s) const
00225 {
00226 return StThreeVector<double>(cx(s), cy(s), cz(s));
00227 }
00228
00229 inline double StHelix::pathLength(double X, double Y) const
00230 {
00231 return fudgePathLength(StThreeVector<double>(X, Y, 0));
00232 }
00233 inline int StHelix::bad(double WorldSize) const
00234 {
00235
00236 int ierr;
00237 if (!::finite(mDipAngle )) return 11;
00238 if (!::finite(mCurvature )) return 12;
00239
00240 ierr = mOrigin.bad(WorldSize);
00241 if (ierr) return 3+ierr*100;
00242
00243 if (::fabs(mDipAngle) >1.58) return 21;
00244 double qwe = ::fabs(::fabs(mDipAngle)-M_PI/2);
00245 if (qwe < 1./WorldSize ) return 31;
00246
00247 if (::fabs(mCurvature) > WorldSize) return 22;
00248 if (mCurvature < 0 ) return 32;
00249
00250 if (abs(mH) != 1 ) return 24;
00251
00252 return 0;
00253 }
00254
00255 #endif