| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

PiecewiseTrajectory.cpp

Go to the documentation of this file.
00001 #include "Kernel/PiecewiseTrajectory.h"
00002 #include "boost/lambda/lambda.hpp"
00003 #include "boost/lambda/bind.hpp"
00004 #include "boost/lambda/construct.hpp"
00005 #include "boost/lambda/core.hpp"
00006 #include <cassert>
00007 
00008 //using boost::lambda::_1;
00009 //using boost::lambda::_2;
00010 using boost::lambda::bind;
00011 using boost::lambda::var;
00012 using boost::lambda::delete_ptr;
00013 
00014 namespace {
00015     class dist2point {
00016         public:
00017             dist2point (const LHCb::Trajectory::Point& p) : m_p(p), m_dist2(-1),m_mu(0) {;} 
00018             template <typename T> void operator()(const T& t) 
00019             { 
00020               // make sure mu isn't beyond the local traj valid range...
00021               double mu = std::min(std::max(t.first->beginRange(),
00022                                             t.first->muEstimate(m_p)),
00023                                             t.first->endRange());
00024               double dist2 = ( t.first->position(mu) - m_p ).Mag2();
00025               if ( m_dist2 < 0 || dist2 < m_dist2) {
00026                 m_dist2 = dist2; 
00027                 // m_mu should be wrt. global traj, not the local piece
00028                 m_mu    = t.second+(mu-t.first->beginRange());
00029               }
00030             }
00031             double muEstimate() const { return m_mu; }
00032         private:
00033             const LHCb::Trajectory::Point& m_p;
00034             double m_dist2,m_mu;
00035     };
00036     struct order2mu {
00037         template <typename T> bool operator()(double s, const T& t)  
00038         { return s < t.second; }
00039         template <typename T> bool operator()(const T& t, double s)  
00040         { return t.second < s; }
00041     };
00042 };
00043 
00044 std::auto_ptr<LHCb::Trajectory> LHCb::PiecewiseTrajectory::clone() const
00045 {
00046   return std::auto_ptr<LHCb::Trajectory>(new LHCb::PiecewiseTrajectory(*this));
00047 }
00048 
00049 LHCb::PiecewiseTrajectory::PiecewiseTrajectory(const PiecewiseTrajectory& lhs)
00050     :LHCb::Trajectory(lhs) 
00051 {
00052   Trajs::const_iterator iter = lhs.m_traj.begin();
00053   for(; iter != lhs.m_traj.end() ; ++iter) {
00054     append(iter->first->clone().release());
00055   }
00056 }
00057 
00058 LHCb::PiecewiseTrajectory::~PiecewiseTrajectory()
00059 {
00060    std::for_each(m_traj.begin(),
00061                  m_traj.end(),
00062                  bind(delete_ptr(),bind(&Trajs::value_type::first,boost::lambda::_1)));
00063 }
00064 
00065 void 
00066 LHCb::PiecewiseTrajectory::append(LHCb::Trajectory *t) 
00067 {
00068    m_traj.push_back(std::make_pair(t,endRange()));
00069    setRange(beginRange(),endRange()+t->endRange()-t->beginRange());
00070 }
00071 
00072 void 
00073 LHCb::PiecewiseTrajectory::prepend(LHCb::Trajectory *t) 
00074 {
00075     double newBeginRange = beginRange()-(t->endRange()-t->beginRange());
00076     m_traj.push_front(std::make_pair(t,newBeginRange));
00077     setRange(newBeginRange,endRange());
00078 }
00079 
00080 // pair of (local traj, local mu)
00081 std::pair<const LHCb::Trajectory*,double>
00082 LHCb::PiecewiseTrajectory::loc(double mu) const
00083 {
00084    assert(!m_traj.empty());
00085    Trajs::const_iterator i = std::lower_bound(m_traj.begin(),
00086                                               m_traj.end(),
00087                                               mu,
00088                                               order2mu());
00089    if (i==m_traj.end()) --i;
00090    return std::make_pair(i->first,i->first->beginRange()+(mu-i->second));
00091 }
00092 
00093 LHCb::Trajectory::Point
00094 LHCb::PiecewiseTrajectory::position(double s) const
00095 {
00096    return local<Point>(s,bind(&Trajectory::position,boost::lambda::_1,boost::lambda::_2));
00097 }
00098 
00099 LHCb::Trajectory::Vector 
00100 LHCb::PiecewiseTrajectory::direction(double s) const{
00101    return local<Vector>(s,bind(&Trajectory::direction,boost::lambda::_1,boost::lambda::_2));
00102 }
00103  
00104 LHCb::Trajectory::Vector
00105 LHCb::PiecewiseTrajectory::curvature(double s) const
00106 {
00107    return local<Vector>(s,bind(&Trajectory::curvature,boost::lambda::_1,boost::lambda::_2));
00108 }
00109 
00110 void 
00111 LHCb::PiecewiseTrajectory::expansion( double s,
00112                                       Point& p,
00113                                       Vector& dp,
00114                                       Vector& ddp ) const
00115 {
00116    local<void>(s, bind(&Trajectory::expansion,
00117                        boost::lambda::_1,boost::lambda::_2,var(p),var(dp),var(ddp)));
00118 }
00119 
00120 double
00121 LHCb::PiecewiseTrajectory::muEstimate(const Point& p) const 
00122 {
00123     return for_each(m_traj.begin(),m_traj.end(), dist2point(p) ).muEstimate();
00124 }
00125 
00126 double 
00127 LHCb::PiecewiseTrajectory::distTo1stError( double s,
00128                                            double tolerance, 
00129                                            int pathDirection) const 
00130 {
00131     return distToError(s,tolerance,pathDirection,&Trajectory::distTo1stError);
00132 }
00133 
00134 double 
00135 LHCb::PiecewiseTrajectory::distTo2ndError( double s,
00136                                            double tolerance, 
00137                                            int pathDirection) const 
00138 {
00139     return distToError(s,tolerance,pathDirection,&Trajectory::distTo2ndError);
00140 }
00141   
00142 double 
00143 LHCb::PiecewiseTrajectory::distToError( double s,
00144                                         double tolerance, 
00145                                         int pathDirection,
00146                                         distFun f) const 
00147 {
00148   std::pair<const Trajectory*,double> l = loc(s);
00149   double dist = (l.first->*f)(l.second,tolerance,pathDirection);
00150   if ( (l.first!=m_traj.back().first  && pathDirection>0) || 
00151        (l.first!=m_traj.front().first && pathDirection<0) ) {  // we're moving amongst 
00152                                                                // the internal pieces
00153       double endOfLocalRange = ( pathDirection>0 ? l.first->endRange() 
00154                                                  : l.first->beginRange() ) ;
00155       // make sure we don't run beyond the current piece...
00156       dist = std::min(dist, std::abs( endOfLocalRange - l.second ));
00157   }
00158   return dist;
00159 }
00160 
00161 std::ostream& 
00162 LHCb::PiecewiseTrajectory::print(std::ostream& os) const
00163 {
00164    for (Trajs::const_iterator i=m_traj.begin();i != m_traj.end();++i) {
00165         double pieceRange = i->first->endRange() - i->first->beginRange();
00166         os << "   BeginPoint[global/local] : " << i->first->beginPoint() << " [" << i->second << "/" << i->first->beginRange() << "]\n"
00167            << " ->  EndPoint[global/local] : " << i->first->endPoint() << " [" << i->second+pieceRange << "/" << i->first->endRange() << "]\n" << std::endl;
00168    }
00169    return os;
00170 
00171 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:03:13 2011 for LHCbKernel by doxygen 1.4.7