BOSS 7.1.0
BESIII Offline Software System
Loading...
Searching...
No Matches
TrkDifPieceTraj.cxx
Go to the documentation of this file.
1// ---------------------------------------------------------------------------
2// File and Version Information:
3// $Id: TrkDifPieceTraj.cxx,v 1.4 2010/03/25 09:56:26 zhangy Exp $
4//
5// Description:
6// Differential form of the Piecewise compound trajectory base class.
7//
8// Copyright Information:
9// Copyright (C) 1996 Lawrence Berkeley Laboratory
10//
11// Authors: Dave Brown, 3/17/97
12//----------------------------------------------------------------------------
14#include "CLHEP/Matrix/Matrix.h"
15#include "CLHEP/Vector/ThreeVector.h"
16#include "CLHEP/Geometry/Point3D.h"
19#include "TrkBase/TrkPoca.h"
20#include "TrkBase/TrkErrCode.h"
21#include <iostream>
23using namespace std;
24
25static const double STEPEPSILON = 1.0e-6; // .1 micron step
26static const double _TOL = 1.0e-5; // poca tolerance
27//
28// Size the vectors to a reasonable number of terms
29//
30TrkDifPieceTraj::TrkDifPieceTraj(const TrkSimpTraj& seed,const double lowlim,const double hilim) :
31 TrkDifTraj(lowlim,hilim), _lastIndex(-1)
32{
33 // _localtraj.reserve(16); _globalrange.reserve(16);
34 _localtraj.push_back((TrkSimpTraj*)seed.clone());
35 assert(lowlim < hilim);
36 _globalrange.push_back(lowlim);
37 _globalrange.push_back(hilim);
38// don't assume the local trajectory has the same range, but do respect it's starting point
39 double locrange[2];
40 locrange[0] = seed.lowRange();
41 locrange[1] = hilim-lowlim+locrange[0];
42 _localtraj.front()->setFlightRange(locrange);
43}
44
45TrkDifPieceTraj::TrkDifPieceTraj(TrkSimpTraj* seed,const double lowlim,const double hilim) :
46 TrkDifTraj(lowlim,hilim), _lastIndex(-1)
47{
48 // _localtraj.reserve(16); _globalrange.reserve(16);
49 assert(lowlim < hilim);
50 _globalrange.push_back(lowlim);
51 _globalrange.push_back(hilim);
52// don't assume the local trajectory has the same range, but do respect it's starting point
53 double locrange[2];
54 locrange[0] = seed->lowRange();
55 locrange[1] = hilim-lowlim+locrange[0];
56 seed->setFlightRange(locrange);
57 _localtraj.push_back(seed);
58}
59
60//
62 TrkDifTraj(other.lowRange(),other.hiRange()),
63 _globalrange(other._globalrange),
64 _lastIndex(other._lastIndex)
65{
66//
67// deep-copy all the trajectory pieces
68//
69 // _localtraj.reserve(other._localtraj.size());
70 typedef std::deque<TrkSimpTraj *>::const_iterator iter_t;
71 iter_t end = other._localtraj.end();
72 for(iter_t i=other._localtraj.begin();i!=end; ++i)
73 _localtraj.push_back( (TrkSimpTraj*) (*i)->clone());
74}
75
76TrkDifPieceTraj::TrkDifPieceTraj(const std::vector<TrkSimpTraj*>& trajs)
77{
78 // _localtraj.reserve(trajs.size());_globalrange.reserve(trajs.size()+1);
79// intialize
80 TrkSimpTraj* prevtraj(0);
81 for(std::vector<TrkSimpTraj*>::const_iterator itraj=trajs.begin();itraj!=trajs.end();++itraj){
82 TrkSimpTraj* newtraj = (*itraj)->clone();
83 assert(newtraj != 0);
84 if(prevtraj != 0){
85// Hopefully the trajs are in order
86 TrkErrCode add;
87 double gap;
88 if(newtraj->lowRange() > prevtraj->lowRange())
89 add = append(newtraj,gap);
90 else
91 add = prepend(newtraj,gap);
92 if(add.failure()){
93#ifdef MDCPATREC_WARNING
94 std::cout<<"ErrMsg(warning) "
95 << "construction from vector of trajs failed"
96 << add << std::endl;
97#endif
98 delete newtraj;
99 break;
100 }
101 } else {
102// Initial global flightlength is defined by the first trajectory
103 _localtraj.push_back(newtraj);
104 _globalrange.push_back(newtraj->lowRange());
105 _globalrange.push_back(newtraj->hiRange());
106// set the global range
107 flightrange[0] = _globalrange.front();
108 flightrange[1] = _globalrange.back();
109 }
110 prevtraj = _localtraj[itraj-trajs.begin()];
111 }
112}
113
115{
116 std::for_each(_localtraj.begin(),
117 _localtraj.end(),
119}
120
121void
122TrkDifPieceTraj::getDFInfo(double flightdist, DifPoint& pos, DifVector& direction,
123 DifVector& delDirect) const
124{
125//
126// First, find the right trajectory piece, then give the local position
127//
128 double localflight(0.0);
129 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
130 loctraj->getDFInfo(localflight,pos,direction,delDirect);
131}
132
133void
134TrkDifPieceTraj::getDFInfo2(double flightdist, DifPoint& pos,
135 DifVector& direction) const
136{
137//
138// First, find the right trajectory piece, then give the local position
139//
140 double localflight(0.0);
141 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
142 loctraj->getDFInfo2(localflight,pos,direction);
143}
144//- assignment operator
147{
148 if (&other == this) return *this;
149 flightrange[0] = other.flightrange[0];
150 flightrange[1] = other.flightrange[1];
151 _globalrange = other._globalrange;
152//
153// deep-copy all the trajectory pieces
154//
155 std::for_each(_localtraj.begin(),_localtraj.end(),bes::Collection::DeleteObject());
156 _localtraj.clear(); // _localtraj.reserve(other._localtraj.size());
157 typedef std::deque<TrkSimpTraj*>::const_iterator iter_t;
158 for(iter_t i=other._localtraj.begin();i!=other._localtraj.end();++i)
159 _localtraj.push_back((*i)->clone());
160 return *this;
161}
162// Append a new trajectory at a given global flight length. This makes a linear
163// interpolation to set the range of the new trajectory to match the position
164// of the existing last piece.
165//
166const TrkErrCode&
167TrkDifPieceTraj::append(double glen,TrkSimpTraj* nexttraj,double& gap)
168{
169 static TrkErrCode retval;
171// simple range checks
172 if(glen >= lowRange()){
173// resize the end if necessary
174 int nremoved = resize(glen,trkOut);
175 if(nremoved > 0) {
176#ifdef MDCPATREC_WARNING
177 std::cout<<"ErrMsg(warning)" << "append removed "
178 << nremoved << " old trajectories" << std::endl;
179#endif
180 }
181// Compute POCA for this trajectory to the point at the end of the existing trajectory
182 HepPoint3D endpoint = position(glen);
183 HepPoint3D newend = nexttraj->position(nexttraj->lowRange());
184 gap = newend.distance(endpoint);
185 double range[2];
186 range[0] = nexttraj->lowRange();
187 range[1] = nexttraj->hiRange();
188 double delta = max(hiRange() - glen,range[1]-range[0]);
189 if(gap > _TOL){ // Don't invoke POCA if the point is too close
190 TrkPoca endpoca(*nexttraj,nexttraj->lowRange(),endpoint,_TOL);
191 if(endpoca.status().failure()){
192 retval = TrkErrCode(TrkErrCode::fail,7,"poca failure");
193 return retval;
194 }
195 range[0] = endpoca.flt1();
196 gap = endpoca.doca();
197 }
198// make sure the global range stays at least as long as before
199 range[1] = range[0] + delta;
200// resize it
201 nexttraj->setFlightRange(range);
202// append the trajectory
203 _localtraj.push_back(nexttraj);
204// append the new global range
205 _globalrange.push_back(glen+delta);
206 flightrange[1] = glen+delta;
207 } else
208 retval = TrkErrCode(TrkErrCode::fail,6," cannot append before minimum flight range");
209 return retval;
210}
211// similair code for prepending
212const TrkErrCode&
213TrkDifPieceTraj::prepend(double glen,TrkSimpTraj* nexttraj,double& gap)
214{
215 static TrkErrCode retval;
217// simple range checks
218 if(glen <= hiRange()){
219// resize
220 int nremoved = resize(glen,trkIn);
221 if(nremoved > 0) {
222#ifdef MDCPATREC_WARNING
223 std::cout<<"ErrMsg(warning) "<< " prepend removed "
224 << nremoved << " old trajectories" << std::endl;
225#endif
226 }
227// Compute POCA for this trajectory to the point at the end of the existing trajectory
228 HepPoint3D endpoint = position(glen);
229 HepPoint3D newend = nexttraj->position(nexttraj->hiRange());
230 gap = newend.distance(endpoint);
231 double range[2];
232 range[0] = nexttraj->lowRange();
233 range[1] = nexttraj->hiRange();
234 double delta = max(glen -lowRange(),range[1]-range[0]);
235 if(gap > _TOL){ // Don't invoke POCA if the point is too close
236 TrkPoca endpoca(*nexttraj,nexttraj->hiRange(),endpoint,_TOL);
237 if(endpoca.status().failure()){
238 retval = TrkErrCode(TrkErrCode::fail,7,"poca failure");
239 return retval;
240 }
241 range[1] = endpoca.flt1();
242 gap = endpoca.doca();
243 }
244// make sure the global range stays at least as long as before
245 range[0] = range[1] - delta;
246// resize it
247 nexttraj->setFlightRange(range);
248// prepend the trajectory
249 _localtraj.push_front(nexttraj);
250// prepend the new global range
251 _globalrange.push_front(glen-delta);
252 flightrange[0] = glen-delta;
253 } else
254 retval = TrkErrCode(TrkErrCode::fail,6," cannot prepend after maximum flight range");
255 return retval;
256}
257
258const TrkErrCode&
259TrkDifPieceTraj::append(double glen,const TrkSimpTraj& nexttraj,double& gap)
260{
261 return append(glen,nexttraj.clone(),gap);
262}
263
264const TrkErrCode&
265TrkDifPieceTraj::prepend(double glen,const TrkSimpTraj& nexttraj,double& gap)
266{
267 return prepend(glen,nexttraj.clone(),gap);
268}
269
270// append an entire TrkDifTraj
271const TrkErrCode&
272TrkDifPieceTraj::append(double glen,const TrkDifPieceTraj& other,double& gap)
273{
274 static TrkErrCode retval;
276// find POCA between the trajectories.
277 double mylen = glen;
278 HepPoint3D myend = position(mylen);
279 double otherlen = other.lowRange();
280 HepPoint3D otherstart = other.position(otherlen);
281 gap = otherstart.distance(myend);
282 if(gap > _TOL){ // Don't invoke POCA if the point is too close
283 TrkPoca endpoca(other,other.lowRange(),myend,_TOL);
284 if(endpoca.status().failure()){
285 retval = TrkErrCode(TrkErrCode::fail,7,"poca failure");
286 return retval;
287 }
288 gap = endpoca.doca();
289 otherlen = endpoca.flt1();
290 }
291// get the local trajectory piece at this fltlen
292 double loclen(0);
293 double piecegap;
294// loop over segments in the other trajectory
295 for(int itraj = other.trajIndex(otherlen,loclen);
296 itraj < other._localtraj.size();itraj++){
297// append the piece from the other trajectory
298 retval = append(mylen,*(other._localtraj[itraj]),piecegap);
299 if(retval.failure())
300 break;
301// move forward
302 mylen = hiRange();
303 }
304 return retval;
305}
306// prepend an entire TrkDifTraj
307const TrkErrCode&
308TrkDifPieceTraj::prepend(double glen,const TrkDifPieceTraj& other,double& gap)
309{
310 static TrkErrCode retval;
312// find POCA between the trajectories.
313 double mylen = glen;
314 HepPoint3D mystart = position(mylen);
315 double otherlen = other.hiRange();
316 HepPoint3D otherend = other.position(otherlen);
317 gap = otherend.distance(mystart);
318 if(gap > _TOL){ // Don't invoke POCA if the point is too close
319 TrkPoca endpoca(other,other.hiRange(),mystart,_TOL);
320 if(endpoca.status().failure()){
321 retval = TrkErrCode(TrkErrCode::fail,7,"poca failure");
322 return retval;
323 }
324 gap = endpoca.doca();
325 otherlen = endpoca.flt1();
326 }
327// get the local trajectory piece at this fltlen
328 double loclen(0);
329 double piecegap;
330// loop over segments in the other trajectory
331 for(int itraj = other.trajIndex(otherlen,loclen);
332 itraj >= 0;itraj--) {
333// prepend the piece from the other trajectory
334 retval = prepend(mylen,*(other._localtraj[itraj]),piecegap);
335 if(retval.failure())
336 break;
337// move backwards
338 mylen = lowRange();
339 }
340 return retval;
341}
342// in-place flight-range inverter. A traj with range A -> B will end up with
343// range -B -> -A, with all the pieces correctly re-ranged as well.
346{
347// make local copies & clear data members
348 std::deque<TrkSimpTraj*> trajcopy; trajcopy.swap(_localtraj);
349 std::deque<double> rangecopy; rangecopy.swap(_globalrange);
350 assert(_localtraj.size()==0);
351 assert(_globalrange.size()==0);
352// global range starts at the end of the old range
353 _globalrange.push_back(-rangecopy.back());
354// loop over the trajectory pieces in backwards order
355 for(int itraj=trajcopy.size()-1;itraj>=0;itraj--){
356// invert the simptraj and re-append it
357 _localtraj.push_back(&(trajcopy[itraj]->invert()));
358// set the global range
359 _globalrange.push_back(-rangecopy[itraj]);
360 }
361// reset this traj's range
362 double range[2];
363 range[0] = -hiRange();
364 range[1] = -lowRange();
366 return *this;
367}
368
369// trajectory index from flight range
370int
371TrkDifPieceTraj::trajIndex(const double& flightdist,double& localflight) const
372{
373 int index(0); // true when there's only 1 entry
374 if (_localtraj.size() > 1) {
375 if(validFlightDistance(flightdist)){
376// explicitly check cached value from last call
377 if ( _lastIndex >= 0 && _lastIndex < _localtraj.size()-1 &&
378 flightdist > _globalrange[_lastIndex] && flightdist <
380 index = _lastIndex;
381 } else {
382//
383// simple binary search algorithm
384//
385 int hirange = _localtraj.size() - 1;
386 int lorange = 0;
387 index = hirange/2;
388 int oldindex = -1;
389 while(index != oldindex){
390 oldindex = index;
391 if(flightdist < _globalrange[index]){
392 hirange = index;
393 index -= max(1,(index-lorange)/2);
394 } else if(flightdist > _globalrange[index+1]){
395 lorange = index;
396 index += max(1,(hirange-index)/2);
397 }
398 }
399 }
400 } else {
401//
402// Return the appropriate end if the requested flightdistance is outside the
403// global range
404//
405 index = (flightdist < lowRange()?0:(_localtraj.size()-1));
406 }
407 }
408 localflight = localDist(index,flightdist);
409// cache value for next time
410 _lastIndex = index;
411 return index;
412}
413
415TrkDifPieceTraj::position(double flightdist) const
416{
417//
418// First, find the right trajectory piece, then give the local position
419//
420 double localflight(0.0);
421 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
422 return loctraj->position(localflight);
423}
424
425Hep3Vector
426TrkDifPieceTraj::direction(double flightdist) const
427{
428//
429// First, find the right trajectory piece, then give the local direction
430//
431 double localflight(0.0);
432 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
433 return loctraj->direction(localflight);
434}
435
436double
437TrkDifPieceTraj::curvature(double flightdist) const
438{
439//
440// First, find the right trajectory piece, then give the local curvature
441//
442 double localflight(0.0);
443 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
444 return loctraj->curvature(localflight);
445}
446
447Hep3Vector
448TrkDifPieceTraj::delDirect(double flightdist) const
449{
450//
451// First, find the right trajectory piece, then give the local value
452//
453 double localflight(0.0);
454 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
455 return loctraj->delDirect(localflight);
456}
457
458void
459TrkDifPieceTraj::getInfo(double flightdist,
460 HepPoint3D& point,
461 Hep3Vector& dir) const
462{
463//
464// First, find the right trajectory piece, then call the local function
465//
466 double localflight(0.0);
467 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
468 loctraj->getInfo(localflight,point,dir);
469}
470
471void
472TrkDifPieceTraj::getInfo(double flightdist,
473 HepPoint3D& point,
474 Hep3Vector& dir,
475 Hep3Vector& deldirect) const
476{
477//
478// First, find the right trajectory piece, then call the local function
479//
480 double localflight(0.0);
481 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
482 loctraj->getInfo(localflight,point,dir,deldirect);
483}
484
485double
486TrkDifPieceTraj::distTo1stError(double flightdist,double tol,int dir) const
487{
488//
489// First, find the right trajectory piece
490//
491 double localflight(0.0);
492 int index = trajIndex(flightdist,localflight);
493 const TrkSimpTraj* loctraj = _localtraj[index];
494//
495// Ask the local piece for it's dist, and take the minimum of this or the
496// distance to the next trajectory piece
497//
498 double localdist = loctraj->distTo1stError(localflight,tol,dir);
499//
500// Take the minimum of this distance and the distance to the next trajectory
501 double dist = localdist;
502 if (dir > 0){
503 if(index < _localtraj.size()-1)
504 dist = min(localdist,_globalrange[index+1]-flightdist) + STEPEPSILON;
505 } else {
506 if(index > 0)
507 dist = min(localdist,flightdist - _globalrange[index]) + STEPEPSILON;
508 }
509 return dist;
510}
511
512double
513TrkDifPieceTraj::distTo2ndError(double flightdist,double tol,int dir) const
514{
515//
516// First, find the right trajectory piece
517//
518 double localflight(0.0);
519 int index = trajIndex(flightdist,localflight);
520 const TrkSimpTraj* loctraj = _localtraj[index];
521//
522// Ask the local piece for it's dist, and take the minimum of this or the
523// distance to the next trajectory piece
524//
525 double localdist = loctraj->distTo2ndError(localflight,tol,dir);
526//
527// Take the minimum of this distance and the distance to the next trajectory
528 double dist = localdist;
529 if (dir > 0){
530 if(index < _localtraj.size()-1)
531 dist = min(localdist,_globalrange[index+1]-flightdist) + STEPEPSILON;
532 } else {
533 if(index > 0)
534 dist = min(localdist,flightdist - _globalrange[index]) + STEPEPSILON;
535 }
536 return dist;
537}
538
539
540const TrkSimpTraj*
541TrkDifPieceTraj::localTrajectory(double flightdist,double& localflight) const
542{
543//
544// Find and return the right trajectory piece
545//
546 int index = trajIndex(flightdist,localflight);
547 return _localtraj[index];
548}
549//
550// Re-size the trajectory in the given direction
551//
552int
554{
555 int nremoved(0);
556 TrkSimpTraj* trajpiece;
557 double oldend,locdist;
558 double lrange[2];
559 int ipiece = trajIndex(len,locdist);
560 switch(tdir) {
561 case trkIn:
562//
563// Reset the range. Delete trajectory pieces till we're in range.
564// This will leave the trajectory with a starting range different from
565// 0, but it'll still be self-consistent
566//
567 while(ipiece > 0){
568 nremoved++;
569 trajpiece = _localtraj.front(); _localtraj.pop_front();
570 delete trajpiece;
571 oldend = _globalrange.front(); _globalrange.pop_front();
572 ipiece = trajIndex(len,locdist);
573 }
574// reset the global range
575 flightrange[0] = len;
576 _globalrange[ipiece] = len;
577// reset the local traj piece range
578 lrange[0] = locdist;
579 lrange[1] = _localtraj[ipiece]->hiRange();
580 _localtraj[ipiece]->setFlightRange(lrange);
581 break;
582 case trkOut:
583 while(ipiece < _localtraj.size() - 1){
584 nremoved++;
585 trajpiece = _localtraj.back(); _localtraj.pop_back();
586 delete trajpiece;
587 oldend = _globalrange.back(); _globalrange.pop_back();
588 ipiece = trajIndex(len,locdist);
589 }
590 flightrange[1] = len;
591 _globalrange[ipiece+1] = len;
592 lrange[0] = _localtraj[ipiece]->lowRange();
593 lrange[1] = locdist;
594 _localtraj[ipiece]->setFlightRange(lrange);
595 break;
596 }
597 return nremoved;
598}
599//
600// Print functions
601//
602void
603TrkDifPieceTraj::print(ostream& os) const
604{
605 os << "TrkDifPieceTraj has " << _localtraj.size() << " pieces "
606 << ", total flight range of " << hiRange();
607}
608
609void
611{
612 os << "TrkDifPieceTraj has " << _localtraj.size() << " pieces "
613 << ", total flight range from "
614 << lowRange() << " to " << hiRange() << endl;
615 for(int ipiece=0;ipiece<_localtraj.size();ipiece++){
616 TrkSimpTraj* tpiece = _localtraj[ipiece];
617 double plow = tpiece->lowRange();
618 double phi = tpiece->hiRange();
619 os << "Piece " << ipiece << " has global range from "
620 << _globalrange[ipiece] << " to " << _globalrange[ipiece+1]
621 << " and local range from " << plow << " to " << phi << endl;
622 HepPoint3D start = tpiece->position(plow);
623 HepPoint3D end = tpiece->position(phi);
624 const HepPoint3D& refp = tpiece->referencePoint();
625 os << "Piece " << ipiece << " starts at point "
626 << start.x() <<","<< start.y()<<","<< start.z()
627 << " and ends at point "
628 << end.x()<<"," << end.y()<<"," << end.z()
629 << " and references point "
630 << refp.x()<<"," << refp.y()<<"," << refp.z()
631 << endl;
632 }
633}
634//
635// Range functions
636//
637void
639{
640 double oldend;
641 double lrange[2];
642 TrkSimpTraj* trajpiece;
643//
644// Check for pathological cases
645//
646 if( newrange[1] > newrange[0] &&
647 newrange[0] < flightrange[1] &&
648 newrange[1] > flightrange[0] ) {
649 resize(newrange[0],trkIn);
650 resize(newrange[1],trkOut);
651 } else if(newrange[1] < newrange[0] ){
652#ifdef MDCPATREC_ERROR
653 std::cout<<"ErrMsg(error) "<< "cannot resize -- invalid range" << std::endl;
654#endif
655 } else {
656//
657// Here the new range is completely discontinuous from the
658// old. We'll just take the first (or last) traj piece,
659// clear out everything else, and reset the ranges.
660//
661 if( newrange[0] > flightrange[1]){
662 while(_localtraj.size()>1){
663 trajpiece = _localtraj.front(); _localtraj.pop_front();
664 delete trajpiece;
665 oldend = _globalrange.front(); _globalrange.pop_front();
666 }
667 } else {
668 while(_localtraj.size()>1){
669 trajpiece = _localtraj.back(); _localtraj.pop_back();
670 delete trajpiece;
671 oldend = _globalrange.back(); _globalrange.pop_back();
672 }
673 }
674 lrange[0] = localDist(0,newrange[0]);
675 lrange[1] = localDist(0,newrange[1]);
676 flightrange[0] = newrange[0];
677 flightrange[1] = newrange[1];
678 _globalrange[0] = newrange[0];
679 _globalrange[1] = newrange[1];
680 _localtraj[0]->setFlightRange(lrange);
681 }
682}
683//
684// KalDeriv functions
685//
686HepMatrix
688{
689 double localflight(0.0);
690 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
691 return loctraj->derivDeflect(localflight,idir);
692}
693
694HepMatrix
696{
697 double localflight(0.0);
698 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
699 return loctraj->derivDisplace(localflight,idir);
700}
701
702HepMatrix
703TrkDifPieceTraj::derivPFract(double flightdist) const
704{
705 double localflight(0.0);
706 const TrkSimpTraj* loctraj = localTrajectory(flightdist,localflight);
707 return loctraj->derivPFract(localflight);
708}
709
710const TrkErrCode&
712{
713 static TrkErrCode retval;
715// find out where this piece is relative to the existing pieces.
716 HepPoint3D end = newtraj->position(newtraj->lowRange());
717 TrkPoca poca(*this,newtraj->lowRange(),end,_TOL);
718 if(poca.status().success()){
719// find the local trajectory pieces at either end
720 double local;
721 int index = trajIndex(poca.flt1(),local);
722 TrkSimpTraj* oldtraj = _localtraj[index];
723// Make sure we're beyond the end of the existing trajectory
724 if( index == _localtraj.size()-1 &&
725 poca.flt1() > hiRange()){
726// we want to split the gap between the traj pieces evenly,
727 double gapstart = globalDist(index,oldtraj->hiRange());
728 double gapend = poca.flt1();
729 double gapmid = (gapend+gapstart)/2.0;
730 HepPoint3D mid = position(gapmid);
731// approximate initial (local) fltlen for poca
732 double locmid = newtraj->lowRange() - gapend + gapmid;
733 TrkPoca midpoca(*newtraj,locmid,mid,_TOL);
734 if(midpoca.status().success()){
735// create a 0-length copy of the new traj to associate with the midpoint.
736// This insures correct coverage of the global flight range
737 TrkSimpTraj* gaptraj = (TrkSimpTraj*)(newtraj->clone());
738 assert(gaptraj != 0);
739 double range[2];
740 range[0] = midpoca.flt1();
741 range[1] = range[0];
742 gaptraj->setFlightRange(range);
743// insert the trajectories
744 _localtraj.push_back(gaptraj);
745 _localtraj.push_back(newtraj);
746// append the new global range
747 _globalrange.back() = gapmid;
748 _globalrange.push_back(gapend);
749 _globalrange.push_back(gapend+newtraj->range());
750// extend the piece-trajs own range
751 flightrange[1] = _globalrange.back();
752// measure the gap at the midpoint
753 gap = mid.distance(newtraj->position(midpoca.flt1()));
754 } else
755 retval = TrkErrCode(TrkErrCode::fail,7,"poca failure");
756 } else
757 retval = TrkErrCode(TrkErrCode::fail,8,"invalid range");
758 } else
759 retval = TrkErrCode(TrkErrCode::fail,7,"poca failure");
760 return retval;
761}
762
763
764const TrkErrCode&
766{
767 static TrkErrCode retval;
769// find out where this piece is relative to the existing pieces.
770 HepPoint3D end = newtraj->position(newtraj->hiRange());
771 TrkPoca poca(*this,newtraj->hiRange(),end,_TOL);
772 if(poca.status().success()){
773// find the local trajectory pieces at either end
774 double local;
775 int index = trajIndex(poca.flt1(),local);
776 TrkSimpTraj* oldtraj = _localtraj[index];
777// Make sure we're beyond the end of the existing trajectory
778 if( index == 0 && poca.flt1() < lowRange()){
779// we want to split the gap between the traj pieces evenly,
780 double gapstart = poca.flt1();
781 double gapend = globalDist(index,oldtraj->hiRange());
782 double gapmid = (gapend+gapstart)/2.0;
783 HepPoint3D mid = position(gapmid);
784// approximate initial (local) fltlen for poca
785 double locmid = newtraj->hiRange() - gapstart + gapmid;
786 TrkPoca midpoca(*newtraj,locmid,mid,_TOL);
787 if(midpoca.status().success()){
788// create a 0-length copy of the new traj to associate with the midpoint.
789// This insures correct coverage of the global flight range
790 TrkSimpTraj* gaptraj = (TrkSimpTraj*)(newtraj->clone());
791 assert(gaptraj != 0);
792 double range[2];
793 range[0] = midpoca.flt1();
794 range[1] = range[0];
795 gaptraj->setFlightRange(range);
796// insert the trajectories
797 _localtraj.push_front(gaptraj);
798 _localtraj.push_front(newtraj);
799// append the new global range
800 _globalrange.push_front(gapmid);
801 _globalrange.push_front(gapstart-newtraj->range());
802// extend the piece-trajs own range
803 flightrange[0] = _globalrange.front();
804// measure the gap at the midpoint
805 gap = mid.distance(newtraj->position(midpoca.flt1()));
806 } else
807 retval = TrkErrCode(TrkErrCode::fail,7,"poca failure");
808 } else
809 retval = TrkErrCode(TrkErrCode::fail,8,"invalid range");
810 } else
811 retval = TrkErrCode(TrkErrCode::fail,7,"poca failure");
812 return retval;
813}
814
815bool
816TrkDifPieceTraj::locallyValid(double glen,double tol) const
817{
818 double localflight(0.0);
819 const TrkSimpTraj* loctraj = localTrajectory(glen,localflight);
820 return loctraj != 0 &&
821 localflight-tol <= loctraj->hiRange() &
822 localflight+tol >= loctraj->lowRange();
823}
824
825bool
827 bool retval(true);
828 if(retval) retval = _globalrange == other._globalrange;
829 if(retval) retval = _localtraj.size() == other._localtraj.size();
830// loop over component trajs
831 std::deque<TrkSimpTraj*>::const_iterator miter = _localtraj.begin();
832 std::deque<TrkSimpTraj*>::const_iterator oiter = other._localtraj.begin();
833 while(retval && miter != _localtraj.end() && oiter != other._localtraj.end()){
834 retval = (*oiter)->parameters()->parameter() == (*miter)->parameters()->parameter() &&
835 (*oiter)->parameters()->covariance() == (*miter)->parameters()->covariance();
836 miter++;oiter++;
837 }
838 return retval;
839}
const double delta
trkDirection
Definition: TrkDirection.h:23
@ trkOut
Definition: TrkDirection.h:23
@ trkIn
Definition: TrkDirection.h:23
deflectDirection
Definition: TrkKalDeriv.h:24
double flightrange[2]
Definition: Trajectory.h:83
virtual HepPoint3D position(double) const =0
double range() const
Definition: Trajectory.h:93
virtual double distTo2ndError(double s, double tol, int pathDir) const =0
virtual Hep3Vector delDirect(double) const =0
double lowRange() const
Definition: Trajectory.h:91
virtual void getInfo(double fltLen, HepPoint3D &pos, Hep3Vector &direction) const =0
virtual double distTo1stError(double s, double tol, int pathDir) const =0
virtual void setFlightRange(double newrange[2])
Definition: Trajectory.cxx:57
virtual Hep3Vector direction(double) const =0
bool validFlightDistance(double f, double tolerance=0.0) const
Definition: Trajectory.h:88
virtual double curvature(double) const =0
double hiRange() const
Definition: Trajectory.h:92
void printAll(std::ostream &os) const
TrkDifPieceTraj(const TrkSimpTraj &, const double lowlim, const double hilim)
HepPoint3D position(double) const
Hep3Vector direction(double) const
HepMatrix derivDeflect(double fltlen, deflectDirection) const
int trajIndex(const double &global, double &local) const
void getDFInfo(double fltLen, DifPoint &pos, DifVector &direction, DifVector &delDirect) const
TrkDifPieceTraj & invert()
std::deque< TrkSimpTraj * > _localtraj
void getInfo(double fltLen, HepPoint3D &, Hep3Vector &direction) const
int resize(double len, trkDirection)
double globalDist(int index, double locdist) const
std::deque< double > _globalrange
void getDFInfo2(double fltlen, DifPoint &pos, DifVector &direction) const
double curvature(double f=0.) const
double distTo2ndError(double s, double tol, int pathDir) const
TrkDifPieceTraj & operator=(const TrkDifPieceTraj &)
bool locallyValid(double glen, double tol=0.0) const
void print(std::ostream &os) const
double localDist(int index, double globdist) const
Hep3Vector delDirect(double) const
double distTo1stError(double s, double tol, int pathDir) const
virtual ~TrkDifPieceTraj()
const TrkErrCode & append(double gfltlen, const TrkSimpTraj &, double &gap)
HepMatrix derivPFract(double fltlen) const
const TrkSimpTraj * localTrajectory(double, double &) const
HepMatrix derivDisplace(double fltlen, deflectDirection idir) const
const TrkErrCode & prepend(double gfltlen, const TrkSimpTraj &, double &gap)
void setFlightRange(double newrange[2])
bool operator==(const TrkDifPieceTraj &other) const
virtual void getDFInfo2(double fltLen, DifPoint &pos, DifVector &direction) const
Definition: TrkDifTraj.cxx:25
virtual void getDFInfo(double fltLen, DifPoint &pos, DifVector &direction, DifVector &delDirect) const =0
int success() const
Definition: TrkErrCode.h:62
int failure() const
Definition: TrkErrCode.h:61
virtual HepMatrix derivDeflect(double fltlen, deflectDirection idir) const =0
virtual HepMatrix derivDisplace(double fltlen, deflectDirection idir) const =0
virtual HepMatrix derivPFract(double fltlen) const =0
const TrkErrCode & status() const
Definition: TrkPocaBase.h:62
double flt1() const
Definition: TrkPocaBase.h:65
double doca() const
Definition: TrkPoca.h:56
const HepPoint3D & referencePoint() const
Definition: TrkSimpTraj.h:84
virtual TrkSimpTraj * clone() const =0