diff --git a/modules/geom/pymod/export_vec3.cc b/modules/geom/pymod/export_vec3.cc
index 6ac28a6147e726f25d229da3ad100472ad349600..9a9b8f47c0850448a80a8033eb67c5df007b86e2 100644
--- a/modules/geom/pymod/export_vec3.cc
+++ b/modules/geom/pymod/export_vec3.cc
@@ -92,5 +92,7 @@ void export_Vec3()
     .add_property("center", &Vec3List::GetCenter)
     .add_property("inertia", &Vec3List::GetInertia)
     .add_property("principal_axes", &Vec3List::GetPrincipalAxes)
+    .def("GetODRLine", &Vec3List::GetODRLine)
+    .def("FitCylinder", &Vec3List::FitCylinder)
   ;
 }
diff --git a/modules/geom/src/composite3_op.cc b/modules/geom/src/composite3_op.cc
index 09fb2c72e7430c2fc938534ff4167052485a4b24..672896f0d9aaec18fad77a24aa8065c7c43e34e4 100644
--- a/modules/geom/src/composite3_op.cc
+++ b/modules/geom/src/composite3_op.cc
@@ -178,5 +178,50 @@ bool IsInSphere(const Sphere& s, const Vec3& v){
   return Length(s.GetOrigin()-v)<=s.GetRadius();
 }
 
+Line3 Vec3List::FitCylinder(){
+  Line3 axis=this->GetODRLine(),axis_old;
+  Real radius,res_sum_old,res_sum,delta=0.01,prec=0.001,err;
+  unsigned long n_step=1000, n_res=this->size();
+  Vec3 v,gradient;
+  radius=0.0;
+  for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+    radius+=geom::Distance(axis,(*i));
+  }
+  radius/=Real(n_res);
+  res_sum=0.0;
+  for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+    res_sum+=pow(Distance(axis,(*i))-radius,2.);
+  }
+  unsigned long k=0;
+  err=2.0*prec;
+  while (err>prec and k<n_step) {
+    res_sum_old=res_sum;
+    axis_old=axis;
+    for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+      radius+=Distance(axis,(*i));
+    }
+    radius/=Real(n_res);
+    for (int j=0; j!=3; ++j){
+      res_sum=0.0;
+      v=Vec3(0.0,0.0,0.0);
+      v[j]=delta;
+      axis=Line3(axis_old.GetOrigin(),axis_old.GetOrigin()+axis_old.GetDirection()+v);
+      for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+        res_sum+=pow(Distance(axis,(*i))-radius,2.);
+      }
+      gradient[j]=res_sum-res_sum_old;
+    }
+    gradient=Normalize(gradient);
+    axis=Line3(axis_old.GetOrigin(),axis_old.GetOrigin()+axis_old.GetDirection()-delta*gradient);
+    res_sum=0.0;
+    for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+      res_sum+=pow(Distance(axis,(*i))-radius,2.);
+    }
+    err=fabs((res_sum-res_sum_old)/float(n_res));
+    k++;
+  }
+  return axis;
+}
+
 } // ns
 
diff --git a/modules/geom/src/vec3.cc b/modules/geom/src/vec3.cc
index 84467ced5a4ddf66dd5ae23e1de054c7cb8e175d..bcc62d42ad0bb0814581f96b9750730e4a84ce7c 100644
--- a/modules/geom/src/vec3.cc
+++ b/modules/geom/src/vec3.cc
@@ -68,5 +68,12 @@ Vec3 Vec3List::GetCenter() const
   return center/=this->size();
 }
 
+Line3 Vec3List::GetODRLine()
+{
+  Vec3 center=this->GetCenter();
+  Vec3 direction=this->GetPrincipalAxes().GetRow(2);
+  return Line3(center,center+direction);
+}
+
 
 }
diff --git a/modules/geom/src/vec3.hh b/modules/geom/src/vec3.hh
index db2b8bb7097dc76d0b74c7906a0ea4a63bda5929..2a27d500a8a0c5ca9c66127de47f0cf37f48f932 100644
--- a/modules/geom/src/vec3.hh
+++ b/modules/geom/src/vec3.hh
@@ -34,7 +34,7 @@ namespace geom {
 // fw decl
 class Vec2;
 class Vec4;
-
+class Line3;
 
 /// \brief Three dimensional vector class, using Real precision.
 class DLLEXPORT_OST_GEOM Vec3:
@@ -193,6 +193,7 @@ inline std::ostream& operator<<(std::ostream& os, const Vec3& v)
 #include <ost/geom/vec2.hh>
 #include <ost/geom/vec4.hh>
 #include <ost/geom/mat3.hh>
+#include <ost/geom/composite3.hh>
 
 namespace geom {
 
@@ -216,6 +217,9 @@ public:
   Vec3 GetCenter() const;
   
   Mat3 GetPrincipalAxes() const;
+  Line3 GetODRLine();
+  Line3 FitCylinder();
+
 };
 
 
diff --git a/modules/mol/alg/pymod/export_trajectory_analysis.cc b/modules/mol/alg/pymod/export_trajectory_analysis.cc
index 31377016a874dc6dcc42cc702d11a3a4058f0934..d53559215907bd13049e0afe2ab1bed29a9470c3 100644
--- a/modules/mol/alg/pymod/export_trajectory_analysis.cc
+++ b/modules/mol/alg/pymod/export_trajectory_analysis.cc
@@ -46,4 +46,6 @@ void export_TrajectoryAnalysis()
   def("AnalyzeMinDistance", &AnalyzeMinDistance, (arg("traj"), arg("view1"), arg("view2"), arg("stride")=1));
   def("AnalyzeMinDistanceBetwCenterOfMassAndView", &AnalyzeMinDistanceBetwCenterOfMassAndView, (arg("traj"), arg("view_cm"), arg("view_atoms"), arg("stride")=1));
   def("AnalyzeAromaticRingInteraction", &AnalyzeAromaticRingInteraction, (arg("traj"), arg("view_ring1"), arg("view_ring2"), arg("stride")=1));
+  def("AnalyzeAlphaHelixAxis", &AnalyzeAlphaHelixAxis, (arg("traj"), arg("protein_segment"), arg("directions"), arg("centers"), arg("stride")=1));
+  def("AnalyzeBestFitLine", &AnalyzeBestFitLine, (arg("traj"), arg("protein_segment"), arg("directions"), arg("centers"), arg("stride")=1));
 }
diff --git a/modules/mol/alg/src/trajectory_analysis.cc b/modules/mol/alg/src/trajectory_analysis.cc
index 2c1225e753ba76adacfa3ccfd8dc6a2ccce18a95..89b46a525c23c1776e157672390eb977337536b3 100644
--- a/modules/mol/alg/src/trajectory_analysis.cc
+++ b/modules/mol/alg/src/trajectory_analysis.cc
@@ -230,4 +230,51 @@ std::vector<Real> AnalyzeAromaticRingInteraction(const CoordGroupHandle& traj, c
   }
   return dist;  
   }
+
+  void AnalyzeAlphaHelixAxis(const CoordGroupHandle& traj, const EntityView& prot_seg, geom::Vec3List& directions,
+                             geom::Vec3List& centers, unsigned int stride)
+  {
+    CheckHandleValidity(traj);
+    if (prot_seg.GetAtomCount()==0){
+      throw std::runtime_error("EntityView is empty");
+    }
+    std::vector<unsigned long> indices_ca;
+    geom::Line3 axis;
+    directions.reserve(ceil(traj.GetFrameCount()/float(stride)));
+    centers.reserve(ceil(traj.GetFrameCount()/float(stride)));
+    GetCaIndices(prot_seg, indices_ca);
+    for (size_t i=0; i<traj.GetFrameCount(); i+=stride) {
+      CoordFramePtr frame=traj.GetFrame(i);
+      axis=frame->FitCylinder(indices_ca);
+      directions.push_back(axis.GetDirection());
+      centers.push_back(axis.GetOrigin());
+    }
+    return;
+  }
+ 
+  //std::vector<geom::Line3> AnalyzeBestFitLine(const CoordGroupHandle& traj, const EntityView& prot_seg,
+  //                                               unsigned int stride)
+  void AnalyzeBestFitLine(const CoordGroupHandle& traj, const EntityView& prot_seg, geom::Vec3List& directions,
+                          geom::Vec3List& centers, unsigned int stride)
+  {
+    CheckHandleValidity(traj);
+    if (prot_seg.GetAtomCount()==0){
+      throw std::runtime_error("EntityView is empty");
+    }
+    std::vector<unsigned long> indices_ca;
+    geom::Line3 axis;
+    directions.reserve(ceil(traj.GetFrameCount()/float(stride)));
+    centers.reserve(ceil(traj.GetFrameCount()/float(stride)));
+    GetCaIndices(prot_seg, indices_ca);
+    for (size_t i=0; i<traj.GetFrameCount(); i+=stride) {
+      CoordFramePtr frame=traj.GetFrame(i);
+      axis=frame->GetODRLine(indices_ca);
+      directions.push_back(axis.GetDirection());
+      centers.push_back(axis.GetOrigin());
+    }
+    return;
+  }
+ 
+
+
 }}} //ns
diff --git a/modules/mol/alg/src/trajectory_analysis.hh b/modules/mol/alg/src/trajectory_analysis.hh
index faa6c8ea06d657afe169ac688c8cd8e6b8148b11..6837e9fb3171a353167bb20b02210bea43a57ec6 100644
--- a/modules/mol/alg/src/trajectory_analysis.hh
+++ b/modules/mol/alg/src/trajectory_analysis.hh
@@ -43,5 +43,7 @@ namespace ost { namespace mol { namespace alg {
   std::vector<Real> DLLEXPORT_OST_MOL_ALG AnalyzeMinDistance(const CoordGroupHandle& traj, const EntityView& view1, const EntityView& view2,unsigned int stride=1);
   std::vector<Real> DLLEXPORT_OST_MOL_ALG AnalyzeMinDistanceBetwCenterOfMassAndView(const CoordGroupHandle& traj, const EntityView& view_cm, const EntityView& view_atoms,unsigned int stride=1);
   std::vector<Real> DLLEXPORT_OST_MOL_ALG AnalyzeAromaticRingInteraction(const CoordGroupHandle& traj, const EntityView& view_ring1, const EntityView& view_ring2,unsigned int stride=1);
+  void  DLLEXPORT_OST_MOL_ALG AnalyzeAlphaHelixAxis(const CoordGroupHandle& traj, const EntityView& prot_seg, geom::Vec3List& directions, geom::Vec3List& centers, unsigned int stride=1);
+  void  DLLEXPORT_OST_MOL_ALG AnalyzeBestFitLine(const CoordGroupHandle& traj, const EntityView& prot_seg, geom::Vec3List& directions, geom::Vec3List& centers, unsigned int stride=1);
 }}}//ns
 #endif
diff --git a/modules/mol/base/pymod/export_coord_frame.cc b/modules/mol/base/pymod/export_coord_frame.cc
index fdb41fce60b8032ecb6f527256b4b9c90d7cc5e1..5ec6f157b0212409cdc8d78b435208e20b814a9c 100644
--- a/modules/mol/base/pymod/export_coord_frame.cc
+++ b/modules/mol/base/pymod/export_coord_frame.cc
@@ -46,6 +46,7 @@ void export_CoordFrame()
     .def("GetDistanceBetwCenterOfMass", get_dist_cm)
     .def("GetRMSD",get_rmsd)
     .def("GetMinDistance",get_min_dist)
+    .def("GetODRLine",&geom::Vec3List::GetODRLine)
   ;
   def("CreateCoordFrame",CreateCoordFrame);
 }
diff --git a/modules/mol/base/src/coord_frame.cc b/modules/mol/base/src/coord_frame.cc
index 80ef4f58f3ea3aed2b1ae691b6cc35c70107faf0..01db3f0a2990d7cbd866e6aeb3c0922d7b91303c 100644
--- a/modules/mol/base/src/coord_frame.cc
+++ b/modules/mol/base/src/coord_frame.cc
@@ -84,6 +84,22 @@ namespace ost { namespace mol {
       indices.push_back(i->GetIndex());
     }
   }
+
+  void GetCaIndices(const EntityView& segment, std::vector<unsigned long>& indices_ca){
+    mol::AtomView ca;
+    ResidueViewList residues=segment.GetResidueList();
+    indices_ca.reserve(residues.size());
+    //for (ResidueViewList::const_iterator res=residues.begin()+1,
+    //     e=residues.end(); res!=e-1; ++res){
+    //  if (!InSequence((*res).GetHandle(),(*(res+1)).GetHandle())) throw std::runtime_error("Residues are not in a continuous sequence");
+    //}
+    for (ResidueViewList::const_iterator res=residues.begin(),
+         e=residues.end(); res!=e; ++res) {
+      ca=res->FindAtom("CA");
+      CheckHandleValidity(ca);
+      indices_ca.push_back(ca.GetIndex());
+      }
+  }
   
   void GetMasses(const EntityView& sele, std::vector<Real>& masses){
   // This function returns a vector containing the atom masses of the atoms in an EntityView
@@ -218,5 +234,29 @@ namespace ost { namespace mol {
     GetIndicesAndMasses(view_cm,indices_cm,masses_cm);
     return this->GetMinDistBetwCenterOfMassAndView(indices_cm,masses_cm,indices_atoms);
   }
+
+  geom::Line3 CoordFrame::GetODRLine(std::vector<unsigned long>& indices_ca){
+  //Returns the best fit line to atoms with indices in indices_ca
+    geom::Vec3List atoms_pos_list;
+    atoms_pos_list.reserve(indices_ca.size());
+    for (std::vector<unsigned long>::const_iterator i1=indices_ca.begin(),e=indices_ca.end(); i1!=e; ++i1) {
+      atoms_pos_list.push_back((*this)[*i1]);
+    }
+    return atoms_pos_list.GetODRLine();
+  }
+ 
+  geom::Line3 CoordFrame::FitCylinder(std::vector<unsigned long>& indices_ca){
+  //Returns a line which is the axis of a fitted cylinder to the atoms with indices given in indices_ca
+    geom::Vec3List atoms_pos_list;
+    atoms_pos_list.reserve(indices_ca.size());
+    for (std::vector<unsigned long>::const_iterator i1=indices_ca.begin(),e=indices_ca.end(); i1!=e; ++i1) {
+      atoms_pos_list.push_back((*this)[*i1]);
+    }
+    return atoms_pos_list.FitCylinder();
+  }
+ 
+ 
+
+
 }}//ns
 
diff --git a/modules/mol/base/src/coord_frame.hh b/modules/mol/base/src/coord_frame.hh
index 8b34cc52acb31086b8ee02d074fe0aac526e22f8..fe94ecc9f67bd4995927239aff5fd87656bcf82c 100644
--- a/modules/mol/base/src/coord_frame.hh
+++ b/modules/mol/base/src/coord_frame.hh
@@ -60,13 +60,16 @@ public:
   Real GetMinDistBetwCenterOfMassAndView(std::vector<unsigned long>& indices_cm, std::vector<Real>& masses_cm,
                                          std::vector<unsigned long>& indices_atoms);
   Real GetMinDistBetwCenterOfMassAndView(const mol::EntityView& view_cm, const mol::EntityView& view_atoms);
+  geom::Line3 GetODRLine(std::vector<unsigned long>& indices_ca);
+  geom::Line3 FitCylinder(std::vector<unsigned long>& indices_ca);
 };
   
   void GetIndices(const EntityView& sele, std::vector<unsigned long>& indices);
   void GetMasses(const EntityView& sele, std::vector<Real>& masses);
   void GetIndicesAndMasses(const EntityView& sele, std::vector<unsigned long>& indices,std::vector<Real>& masses);
   void GetPositions(const EntityView& sele, std::vector<geom::Vec3>& ref_pos);
-  
+  void GetCaIndices(const EntityView& segment, std::vector<unsigned long>& indices_ca);
+
 typedef boost::shared_ptr<CoordFrame> CoordFramePtr;
 typedef std::vector<CoordFramePtr> CoordFrameList;