diff --git a/modules/geom/pymod/export_vec3.cc b/modules/geom/pymod/export_vec3.cc
index 0df8101549767a5c3a7af43bdde4bd33da3b9dd2..0bd91ba68991fef784ee76508e569a9139c2a6ec 100644
--- a/modules/geom/pymod/export_vec3.cc
+++ b/modules/geom/pymod/export_vec3.cc
@@ -21,9 +21,11 @@
 #include <ost/geom/vec3.hh>
 #include <ost/geom/geom.hh>
 #include <ost/geom/export_helper/vector.hh>
+#include <ost/export_helper/pair_to_tuple_conv.hh>
 
 using namespace boost::python;
 
+
 const Real Vec3_getitem(const geom::Vec3& v, int i) {
   return v.At(i);
 }
@@ -116,4 +118,6 @@ void export_Vec3()
     .def("GetODRLine", &Vec3List::GetODRLine)
     .def("FitCylinder", &Vec3List::FitCylinder)
   ;
+  to_python_converter<std::pair<geom::Line3, Real>,
+  ost::PairToTupleConverter<geom::Line3, Real> >();
 }
diff --git a/modules/geom/src/vec3.cc b/modules/geom/src/vec3.cc
index 8909ce8b8648879741c01965ef13961614223e6b..a36db7122a72a7f043a6a3cc160788987fd8088c 100644
--- a/modules/geom/src/vec3.cc
+++ b/modules/geom/src/vec3.cc
@@ -91,76 +91,96 @@ Plane Vec3List::GetODRPlane() const
   Vec3 normal=this->GetPrincipalAxes().GetRow(0);
   return Plane(origin,normal);
 }
-  
-Line3 Vec3List::FitCylinder(const Vec3& initial_direction, const Vec3& center) const
-{
-  Line3 axis=Line3(center,center+initial_direction), axis_old;
-  Real radius,res_sum_old,res_sum,delta_0=0.01,prec=0.0000001,err,norm,delta;
-  unsigned long n_step=1000, n_res=this->size();
-  Vec3 v,gradient;
-  
-  radius=0.0;
-  delta=delta_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) {
-    Real r=Distance(axis,(*i))-radius;
-    res_sum+=r*r;
-  }
-  unsigned long k=0;
-  err=2.0*prec;
-  while (err>prec && k<n_step) {
-    res_sum_old=res_sum;
-    axis_old=axis;
+
+std::pair<Line3, Real> Vec3List::FitCylinder(const Vec3& initial_direction) const
+  { 
+    Vec3 center=this->GetCenter();
+    Line3 axis=Line3(center,center+initial_direction), axis_old;
+    Real radius,res_sum_old,res_sum,delta_0=0.01,prec=0.0000001,err,norm,delta;
+    unsigned long n_step=1000, n_res=this->size();
+    Vec3 v,gradient_dir,gradient_center;
+    
     radius=0.0;
-    if (k>50) {
-      delta=delta_0*50.0*50.0/(k*k);
-    }
+    delta=delta_0;
     for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
-      radius+=Distance(axis,(*i));
+      radius+=geom::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);
+    res_sum=0.0;
+    for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+      Real r=Distance(axis,(*i))-radius;
+      res_sum+=r*r;
+    }
+    unsigned long k=0;
+    err=2.0*prec;
+    while (err>prec && k<n_step) {
+      res_sum_old=res_sum;
+      axis_old=axis;
+      //radius=0.0;
+      if (k>50) {
+        delta=delta_0*50.0*50.0/(k*k);
+      }
+      //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);
+        radius=0.0;
+        for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+          radius+=Distance(axis,(*i));
+        }
+        radius/=Real(n_res);
+        for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+          Real r=Distance(axis,(*i))-radius;
+          res_sum+=r*r;
+        }
+        gradient_dir[j]=(res_sum-res_sum_old)/delta;
+      }
+      norm=Dot(gradient_dir,gradient_dir);
+      if (norm>1.) {
+        gradient_dir=Normalize(gradient_dir);
+      }
+      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()+v,axis_old.GetOrigin()+axis_old.GetDirection()+v);
+        radius=0.0;
+        for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+          radius+=Distance(axis,(*i));
+        }
+        radius/=Real(n_res);
+        for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
+          Real r=Distance(axis,(*i))-radius;
+          res_sum+=r*r;
+        }
+        gradient_center[j]=(res_sum-res_sum_old)/delta;
+      }
+      norm=Dot(gradient_center,gradient_center);
+      if (norm>1.) {
+        gradient_center=Normalize(gradient_center);
+      }      
+      axis=Line3(axis_old.GetOrigin()-50*delta*gradient_center,axis_old.GetOrigin()-50*delta*gradient_center+axis_old.GetDirection()-delta*gradient_dir);
       radius=0.0;
       for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
         radius+=Distance(axis,(*i));
       }
       radius/=Real(n_res);
+      res_sum=0.0;
       for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
         Real r=Distance(axis,(*i))-radius;
         res_sum+=r*r;
       }
-      gradient[j]=(res_sum-res_sum_old)/delta;
-    }
-    norm=Dot(gradient,gradient);
-    if (norm>1.) {
-      gradient=Normalize(gradient);
+      err=fabs((res_sum-res_sum_old)/float(n_res));
+      k++;
     }
-    axis=Line3(axis_old.GetOrigin(),axis_old.GetOrigin()+axis_old.GetDirection()-delta*gradient);
-    radius=0.0;
-    for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
-      radius+=Distance(axis,(*i));
+    if (err>prec) {
+      std::cout<<"axis fitting did not converge"<<std::endl;
     }
-    radius/=Real(n_res);
-    res_sum=0.0;
-    for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) {
-      Real r=Distance(axis,(*i))-radius;
-      res_sum+=r*r;
-    }
-    err=fabs((res_sum-res_sum_old)/float(n_res));
-    k++;
+    return std::make_pair(axis,radius);
   }
-  if (err>prec) {
-    std::cout<<"axis fitting did not converge"<<std::endl;
-  }
-  return axis;
-}
-
 }
diff --git a/modules/geom/src/vec3.hh b/modules/geom/src/vec3.hh
index 58e63b89258294462a34e9ab28311ddde59a9670..1626bb2d5064df6b1873e799a16b1564143f5dee 100644
--- a/modules/geom/src/vec3.hh
+++ b/modules/geom/src/vec3.hh
@@ -316,10 +316,13 @@ public:
   Plane GetODRPlane() const;
 
   //This function fits a cylinder to the positions in Vec3List
-  //It takes as argument an initial guess for the direction and the geometric
-  //center of the atoms. The center is not changed during optimisation as the
-  //best fitting cylinder can be shown to have its axis pass through the geometric center
-  Line3 FitCylinder(const Vec3& initial_direction, const Vec3& center) const;
+  //It takes as argument an initial guess for the direction.
+  //The center is set to the geometric centero of the atoms
+  //and is not changed during optimisation as the best fitting cylinder
+  //can be shown to have its axis pass through the geometric center
+  //It returns a pair containing a line3, giving the direction of the Cylinder
+  //and a Real containing the radius.
+  std::pair<Line3, Real> FitCylinder(const Vec3& initial_direction) const;
 };
 } // ns geom
 
diff --git a/modules/mol/alg/pymod/structure_analysis.py b/modules/mol/alg/pymod/structure_analysis.py
index a9f600bca0a16ea181e2f9780c085208d7b8a7d6..3e013e4791a975f7bbb38f7f15021da9992292ac 100644
--- a/modules/mol/alg/pymod/structure_analysis.py
+++ b/modules/mol/alg/pymod/structure_analysis.py
@@ -127,7 +127,7 @@ def CalculateHelixAxis(sele1):
     return
   eh=sele1.GetHandle()
   f=GetFrameFromEntity(eh)
-  return f.FitCylinder(sele1)
+  return f.FitCylinder(sele1)[0]
 
 
 def CalculateDistanceDifferenceMatrix(sele1,sele2):
diff --git a/modules/mol/alg/src/trajectory_analysis.cc b/modules/mol/alg/src/trajectory_analysis.cc
index 96dd5fabb0599b77fb68fa4d9ca8dea94a8de313..359530f7cf63f18778acb40507c251df01a81567 100644
--- a/modules/mol/alg/src/trajectory_analysis.cc
+++ b/modules/mol/alg/src/trajectory_analysis.cc
@@ -242,6 +242,7 @@ std::vector<Real> AnalyzeAromaticRingInteraction(const CoordGroupHandle& traj, c
       throw Error("EntityView is empty");
     }
     std::vector<unsigned long> indices_ca;
+    std::pair<geom::Line3, Real> cylinder;
     geom::Line3 axis;
     Real sign;
     directions.reserve(ceil(traj.GetFrameCount()/float(stride)));
@@ -250,7 +251,8 @@ std::vector<Real> AnalyzeAromaticRingInteraction(const CoordGroupHandle& traj, c
     unsigned int n_atoms=indices_ca.size();
     for (size_t i=0; i<traj.GetFrameCount(); i+=stride) {
       CoordFramePtr frame=traj.GetFrame(i);
-      axis=frame->FitCylinder(indices_ca);
+      cylinder=frame->FitCylinder(indices_ca);
+      axis=cylinder.first;
       sign=geom::Dot(axis.GetDirection(),(*frame)[indices_ca[n_atoms-1]]-axis.GetOrigin());
       sign=sign/fabs(sign);
       directions.push_back(sign*axis.GetDirection());
diff --git a/modules/mol/base/pymod/export_coord_frame.cc b/modules/mol/base/pymod/export_coord_frame.cc
index 7ea3c2f3ad83467e148489c8db779a2e07d27aee..70ccadd92054bab3e54931c3a362c63e57290619 100644
--- a/modules/mol/base/pymod/export_coord_frame.cc
+++ b/modules/mol/base/pymod/export_coord_frame.cc
@@ -43,7 +43,7 @@ Real (CoordFrame::*get_min_dist)(const mol::EntityView&, const mol::EntityView&)
 Real (CoordFrame::*get_alpha)(const mol::EntityView&) const = &CoordFrame::GetAlphaHelixContent;
 geom::Line3 (CoordFrame::*get_odr_line)(const mol::EntityView&) const = &CoordFrame::GetODRLine;
 geom::Plane (CoordFrame::*get_odr_plane)(const mol::EntityView&) const = &CoordFrame::GetODRPlane;
-geom::Line3 (CoordFrame::*fit_cylinder)(const mol::EntityView&) const = &CoordFrame::FitCylinder;
+std::pair<geom::Line3,Real> (CoordFrame::*fit_cylinder)(const mol::EntityView&) const = &CoordFrame::FitCylinder;
 // TODO: move to geom
 geom::Line3 (CoordFrame::*get_odr_line2)() const = &geom::Vec3List::GetODRLine;
 
diff --git a/modules/mol/base/src/coord_frame.cc b/modules/mol/base/src/coord_frame.cc
index ff04e00d8ba4660298d52f8e04e23d863b7a0309..49c294fcee0fc4ac784e79cd02935d4d4f66e2c6 100644
--- a/modules/mol/base/src/coord_frame.cc
+++ b/modules/mol/base/src/coord_frame.cc
@@ -235,7 +235,7 @@ namespace ost { namespace mol {
     return this->GetODRPlane(indices);
   }  
   
-  geom::Line3 CoordFrame::FitCylinder(std::vector<unsigned long>& indices_ca) const {
+  std::pair<geom::Line3, Real> CoordFrame::FitCylinder(std::vector<unsigned long>& indices_ca) const {
     geom::Vec3List atoms_pos_list;
     int n_atoms=indices_ca.size();
     atoms_pos_list.reserve(n_atoms);
@@ -243,7 +243,7 @@ namespace ost { namespace mol {
       atoms_pos_list.push_back((*this)[*i1]);
     }
     //Initial guess
-    geom::Vec3 initial_axis=geom::Vec3(0.0,0.0,0.0),center=geom::Vec3(0.0,0.0,0.0);
+    geom::Vec3 initial_axis=geom::Vec3(0.0,0.0,0.0);
     if (n_atoms<5) {
       initial_axis=atoms_pos_list[n_atoms-1]-atoms_pos_list[0];
     }
@@ -252,14 +252,10 @@ namespace ost { namespace mol {
         initial_axis+=(*(i+4))-(*i);
       }
     }
-    for (geom::Vec3List::const_iterator i=atoms_pos_list.begin(),e=atoms_pos_list.end(); i!=e; ++i) {
-      center+=(*i);
-    }
-    center/=atoms_pos_list.size();
-    return atoms_pos_list.FitCylinder(initial_axis,center);
+    return atoms_pos_list.FitCylinder(initial_axis);
   }
 
-  geom::Line3 CoordFrame::FitCylinder(const mol::EntityView& view1) const {
+  std::pair<geom::Line3, Real> CoordFrame::FitCylinder(const mol::EntityView& view1) const {
     CheckHandleValidity(view1);
     std::vector<unsigned long> indices_ca;
     GetCaIndices(view1, indices_ca);
diff --git a/modules/mol/base/src/coord_frame.hh b/modules/mol/base/src/coord_frame.hh
index f319e1a3beb325a697ca72223dce688098fdb240..33d24d1d402999d3c0e24bc4afa0a587d047e377 100644
--- a/modules/mol/base/src/coord_frame.hh
+++ b/modules/mol/base/src/coord_frame.hh
@@ -182,10 +182,10 @@ public:
     It is assumed that we fit an alpha-helix and that the CA atoms are oredered sequentially
     This is used for the initial guess of the helix axis
   */
-  geom::Line3 FitCylinder(std::vector<unsigned long>& indices_ca) const;
+  std::pair<geom::Line3, Real> FitCylinder(std::vector<unsigned long>& indices_ca) const;
 
   //! see FitCylinder(std::vector<unsigned long>&)
-  geom::Line3 FitCylinder(const mol::EntityView& view1) const;
+  std::pair<geom::Line3, Real> FitCylinder(const mol::EntityView& view1) const;
 
   /*!
     Returns the percentage of residues in the EntityView (segment) that are in an alpha-helix