BOSS 7.0.8
BESIII Offline Software System
Loading...
Searching...
No Matches
TrkPocaBase.cxx
Go to the documentation of this file.
1//--------------------------------------------------------------------------
2// File and Version Information:
3// $Id: TrkPocaBase.cxx,v 1.4 2006/03/28 01:02:36 zhangy Exp $
4//
5// Description:
6//
7// Environment:
8// Software developed for the BaBar Detector at the SLAC B-Factory.
9//
10// Author(s): Steve Schaffner
11//
12// Modifications:
13// - Jan 2003 (WDH)
14//------------------------------------------------------------------------
15#include "TrkBase/TrkPocaBase.h"
16#include "TrkBase/TrkPoca.h"
17#include "CLHEP/Vector/ThreeVector.h"
18#include "CLHEP/Geometry/Point3D.h"
19#include "MdcGeom/Trajectory.h"
20#include <math.h>
21#include <assert.h>
22#include <iomanip>
23#include <algorithm>
24
25TrkPocaBase::TrkPocaBase(double f1, double f2, double prec)
26 : _precision(prec), _flt1(f1), _flt2(f2),_status(TrkErrCode::fail)
27{
28 assert(prec > 0.);
29}
30
31void
32TrkPocaBase::minimize(const Trajectory& traj1, double f1,
33 const Trajectory& traj2, double f2)
34{
35 // Last revision: Jan 2003, WDH
36 const int maxnOscillStep = 5 ;
37 const int maxnDivergingStep = 5 ;
38
39 // initialize
41 _flt1 = f1;
42 _flt2 = f2;
43
44 static HepPoint3D newPos1, newPos2 ;
45 double delta(0), prevdelta(0) ;
46 int nOscillStep(0) ;
47 int nDivergingStep(0) ;
48 bool finished = false ;
49 int istep(0) ;
50
51 for (istep=0; istep < _maxTry && !finished; ++istep) {
52 double prevflt1 = flt1();
53 double prevflt2 = flt2() ;
54 double prevprevdelta = prevdelta ;
55 prevdelta = delta;
56
57 stepTowardPoca(traj1, traj2);
58 if( status().failure() ) {
59 // failure in stepTowardPoca
60 finished=true ;
61 } else {
62 newPos1 = traj1.position(flt1());
63 newPos2 = traj2.position(flt2());
64 delta = (newPos1 - newPos2).mag();
65 double step1 = flt1() - prevflt1;
66 double step2 = flt2() - prevflt2;
67 int pathDir1 = (step1 > 0.) ? 1 : -1;
68 int pathDir2 = (step2 > 0.) ? 1 : -1;
69
70 // Can we stop stepping?
71 double distToErr1 = traj1.distTo1stError(prevflt1, precision(), pathDir1);
72 double distToErr2 = traj2.distTo1stError(prevflt2, precision(), pathDir2);
73
74 // converged if very small steps, or if parallel
75 finished =
76 (fabs(step1) < distToErr1 && fabs(step2) < distToErr2 ) ||
77 (status().success() == 3) ;
78
79 // we have to catch some problematic cases
80 if( !finished && istep>2 && delta > prevdelta) {
81 if( prevdelta > prevprevdelta) {
82 // diverging
83 if(++nDivergingStep>maxnDivergingStep) {
84 _status.setFailure(2) ; // code for `Failed to converge'
85 finished = true ;
86 }
87 } else {
88 nDivergingStep=0;
89 // oscillating
90 if(++nOscillStep>maxnOscillStep) {
91 // bail out of oscillation. since the previous step was
92 // better, use that one.
93 _flt1 = prevflt1 ;
94 _flt2 = prevflt2 ;
95 _status.setSuccess(21, "Oscillating poca.") ;
96 finished = true ;
97 } else {
98 // we might be oscillating, but we could also just have
99 // stepped over the minimum. choose a solution `in
100 // between'.
101 _flt1 = prevflt1 + 0.5*step1 ;
102 _flt2 = prevflt2 + 0.5*step2 ;
103 newPos1 = traj1.position(_flt1) ;
104 newPos2 = traj2.position(_flt2) ;
105 delta = (newPos1 - newPos2).mag() ;
106 }
107 }
108 }
109 }
110 }
111 if(!finished) _status.setSuccess(2) ; // code for 'not converged' (yet)
112}
113
114TrkPocaBase::TrkPocaBase(double f1, double prec)
115 : _precision(prec), _flt1(f1), _flt2(0), _status(TrkErrCode::fail)
116{
117}
118
119void
121 const HepPoint3D& pt )
122{
124 _flt1 = f1;
125 int pathDir = 1; // which way are we stepping (+/- 1)
126
127 int nTinyStep = 0; // number of consecutive tiny steps -- oscillation test
128 int nOscills = 0;
129 double fltLast = 0., fltBeforeLast = 0.; // another check for oscillation
130 for (int i = 0; i < _maxTry; i++) {
131 fltLast = flt1();
132 stepToPointPoca(traj, pt);
133 if (status().failure()) return;
134 double step = flt1() - fltLast;
135 pathDir = (step > 0.) ? 1 : -1;
136 // Can we stop stepping?
137 double distToErr = traj.distTo1stError(fltLast, precision(), pathDir);
138 bool mustStep = (fabs(step) > distToErr && step != 0.);
139 // Crude test for oscillation (around cusp point of piecewise traj, I hope)
140 if (fabs(step) < 0.5 * precision()) {
141 nTinyStep++;
142 } else {
143 nTinyStep = 0;
144 if (i > 1) {
145 if (fabs(step) >= fabs(fltBeforeLast-fltLast) &&
146 fabs(fltBeforeLast-flt1()) <= fabs(step)) {
147 nOscills++;
148 double halfway = (fltBeforeLast + fltLast) / 2.;
149 if ((traj.position(flt1()) - pt).mag() >
150 (traj.position(halfway) - pt).mag()) _flt1 = halfway;
151 }
152 }
153 }
154 if (nTinyStep > 3) mustStep = false;
155 if (nOscills > 2) {
156 mustStep = false;
157#ifdef MDCPATREC_WARNING
158 std::cout<<" ErrMsg(warning) "<< "Alleged oscillation detected. "
159 << step << " " << fltLast-fltBeforeLast
160 << " " << i << " " << std::endl;
161#endif
162 }
163 if (!mustStep) return;
164 fltBeforeLast = fltLast;
165 }
166 // Ran off the end of the loop
168}
169
170
172{}
173
174
175void
177{
178 // Last revision: Jan 2003, WDH
179
180 // A bunch of unsightly uninitialized variables:
181 static Hep3Vector dir1, dir2;
182 static Hep3Vector delDir1, delDir2;
183 static HepPoint3D pos1, pos2;
184
185 traj1.getInfo(flt1(), pos1, dir1, delDir1);
186 traj2.getInfo(flt2(), pos2, dir2, delDir2);
187 Hep3Vector delta = ((CLHEP::Hep3Vector)pos1) - ((CLHEP::Hep3Vector)pos2);
188 double ua = -delta.dot(dir1);
189 double ub = delta.dot(dir2);
190 double caa = dir1.mag2() + delta.dot(delDir1);
191 double cbb = dir2.mag2() - delta.dot(delDir2);
192 double cab = -dir1.dot(dir2);
193 double det = caa * cbb - cab * cab;
194
195 if(det<0) {
196 // get rid of second order terms
197 caa = dir1.mag2() ;
198 cbb = dir2.mag2() ;
199 det = caa * cbb - cab * cab;
200 }
201
202 if ( det < 1.e-8) {
203 // If they are parallel (in quadratic approximation) give up
205 return;
206 }
207
208 double df1 = (ua * cbb - ub * cab)/det;
209 int pathDir1 = (df1 > 0) ? 1 : -1;
210 double df2 = (ub * caa - ua * cab)/det;
211 int pathDir2 = (df2 > 0) ? 1 : -1;
212
213 // Don't try going farther than worst parabolic approximation will
214 // allow: Since ` _extrapToler' is large, this cut effectively only
215 // takes care that we don't make large jumps past the kink in a
216 // piecewise trajectory.
217
218 double distToErr1 = traj1.distTo2ndError(flt1(), _extrapToler, pathDir1);
219 double distToErr2 = traj2.distTo2ndError(flt2(), _extrapToler, pathDir2);
220
221 // Factor to push just over border of piecewise traj (essential!)
222 const double smudge = 1.01 ;
223 if( fabs(df1) > smudge*distToErr1 ) {
224 // choose solution for which df1 steps just over border
225 df1 = smudge*distToErr1 * pathDir1 ;
226 // now recalculate df2, given df1:
227 df2 = (ub - df1*cab)/cbb ;
228 }
229
230 if( fabs(df2) > smudge*distToErr2 ) {
231 // choose solution for which df2 steps just over border
232 df2 = smudge*distToErr2 * pathDir2 ;
233 // now recalculate df1, given df2:
234 df1 = (ua - df2*cab)/cbb ;
235 // if still not okay,
236 if( fabs(df1) > smudge*distToErr1 ) {
237 df1 = smudge*distToErr1 * pathDir1 ;
238 }
239 }
240
241 _flt1 += df1;
242 _flt2 += df2;
243
244 // another check for parallel trajectories
245 if (fabs(flt1()) > _maxDist && fabs(flt2()) > _maxDist)
247}
248
249void
251{
252 // Unsightly uninitialized variables:
253 static Hep3Vector dir, delDir;
254 static HepPoint3D trajPos;
255
256 traj.getInfo(flt1(), trajPos, dir, delDir);
257 Hep3Vector delta = ((CLHEP::Hep3Vector)trajPos) - ((CLHEP::Hep3Vector)pt);
258 double denom = 1. + delta.dot(delDir);
259 if (fabs(denom)*_maxDist < 1. ) {
260 _status.setFailure(11, "TrkPoca::ambiguous tight looper.");
261 return;
262 }
263 double df = -delta.dot(dir) / fabs(denom);
264 int pathDir = (df > 0.) ? 1 : -1;
265
266 // Don't try going farther than worst parabolic approximation will allow:
267 double distToErr = traj.distTo2ndError(flt1(), _extrapToler, pathDir);
268 if (fabs(df)>distToErr) df = (df>0?distToErr:-distToErr);
269 // Make the step slightly longer -- prevents quitting at kinks
270 df += 0.001 * pathDir * precision();
271 _flt1 += df;
272}
273
274double TrkPocaBase::_maxDist = 1.e7;
275
276int TrkPocaBase::_maxTry = 500;
277
278double TrkPocaBase::_extrapToler = 2.;
const double delta
TFile * f1
virtual HepPoint3D position(double) const =0
virtual double distTo2ndError(double s, double tol, int pathDir) const =0
virtual void getInfo(double fltLen, HepPoint3D &pos, Hep3Vector &direction) const =0
virtual double distTo1stError(double s, double tol, int pathDir) const =0
int success() const
Definition: TrkErrCode.h:62
void setSuccess(int i, const char *str=0)
Definition: TrkErrCode.h:84
void setFailure(int i, const char *str=0)
Definition: TrkErrCode.h:79
TrkErrCode _status
Definition: TrkPocaBase.h:42
void stepToPointPoca(const Trajectory &traj, const HepPoint3D &pt)
static double _extrapToler
Definition: TrkPocaBase.h:54
TrkPocaBase(double flt1, double flt2, double precision)
Definition: TrkPocaBase.cxx:25
const TrkErrCode & status() const
Definition: TrkPocaBase.h:62
double precision()
Definition: TrkPocaBase.h:59
void minimize(const Trajectory &traj1, double f1, const Trajectory &traj2, double f2)
Definition: TrkPocaBase.cxx:32
double flt2() const
Definition: TrkPocaBase.h:68
virtual ~TrkPocaBase()
void stepTowardPoca(const Trajectory &traj1, const Trajectory &traj2)
double _flt2
Definition: TrkPocaBase.h:41
static double _maxDist
Definition: TrkPocaBase.h:52
double flt1() const
Definition: TrkPocaBase.h:65
double _flt1
Definition: TrkPocaBase.h:40
static int _maxTry
Definition: TrkPocaBase.h:53