diff --git a/modules/mol/alg/pymod/wrap_mol_alg.cc b/modules/mol/alg/pymod/wrap_mol_alg.cc
index fd2b9eb2d8fc97c886f0be1f8e133c3f03c2a2f3..0f5ac5190a7c23fb73d2cc234450322dacb86995 100644
--- a/modules/mol/alg/pymod/wrap_mol_alg.cc
+++ b/modules/mol/alg/pymod/wrap_mol_alg.cc
@@ -234,6 +234,28 @@ ost::mol::alg::GlobalRDMap prepare_lddt_global_rdmap_wrapper(const list& ref_lis
  return mol::alg::PreparelDDTGlobalRDMap(ref_list_vector, settings);
 }
 
+list get_lddt_per_residue_stats_wrapper(mol::EntityHandle& model,
+                                        ost::mol::alg::GlobalRDMap& glob_dist_list,
+                                        ost::mol::alg::lDDTSettings& settings) {
+  std::vector<mol::alg::lDDTLocalScore> scores = GetlDDTPerResidueStats(model, glob_dist_list, settings);
+  list local_scores_list;
+  for (std::vector<mol::alg::lDDTLocalScore>::const_iterator sit = scores.begin(); sit != scores.end(); ++sit) {
+    local_scores_list.append(*sit);
+  }
+  return local_scores_list;
+}
+
+void print_lddt_per_residue_stats_wrapper(list& scores, mol::alg::lDDTSettings settings){
+  int scores_length = boost::python::extract<int>(scores.attr("__len__")());
+  std::vector<mol::alg::lDDTLocalScore> scores_vector(scores_length);
+  
+  for (int i=0; i<scores_length; i++) {
+    scores_vector[i] = boost::python::extract<mol::alg::lDDTLocalScore>(scores[i]);
+  }
+ 
+ return mol::alg::PrintlDDTPerResidueStats(scores_vector, settings);
+}
+  
 }
 
 
@@ -315,6 +337,18 @@ BOOST_PYTHON_MODULE(_ost_mol_alg)
     .def_readwrite("consistency_checks", &mol::alg::lDDTSettings::consistency_checks)
     .def_readwrite("cutoffs", &mol::alg::lDDTSettings::cutoffs)
     .def_readwrite("label", &mol::alg::lDDTSettings::label);
+
+  class_<mol::alg::lDDTLocalScore>("lDDTLocalScore", init<String, String, int, String, String, Real, int, int>())
+    .def("ToString", &mol::alg::lDDTLocalScore::ToString)
+    .def("GetHeader", &mol::alg::lDDTLocalScore::GetHeader)
+    .def_readwrite("cname", &mol::alg::lDDTLocalScore::cname)
+    .def_readwrite("rname", &mol::alg::lDDTLocalScore::rname)
+    .def_readwrite("rnum", &mol::alg::lDDTLocalScore::rnum)
+    .def_readwrite("is_assessed", &mol::alg::lDDTLocalScore::is_assessed)
+    .def_readwrite("quality_problems", &mol::alg::lDDTLocalScore::quality_problems)
+    .def_readwrite("local_lddt", &mol::alg::lDDTLocalScore::local_lddt)
+    .def_readwrite("conserved_dist", &mol::alg::lDDTLocalScore::conserved_dist)
+    .def_readwrite("total_dist", &mol::alg::lDDTLocalScore::total_dist);
   
   def("FillClashingDistances",&fill_clashing_distances_wrapper);
   def("FillStereoChemicalParams",&fill_stereochemical_params_wrapper);
@@ -329,9 +363,12 @@ BOOST_PYTHON_MODULE(_ost_mol_alg)
       &mol::alg::CheckStructure,
       (arg("ent"), arg("bond_table"), arg("angle_table"), arg("nonbonded_table"),
        arg("bond_tolerance"), arg("angle_tolerance")));
-  def("PrintlDDTPerResidueStats",
-      &mol::alg::PrintlDDTPerResidueStats,
+  def("GetlDDTPerResidueStats",
+      &get_lddt_per_residue_stats_wrapper,
       (arg("model"), arg("glob_dist_list"), arg("settings")));
+  def("PrintlDDTPerResidueStats",
+      &print_lddt_per_residue_stats_wrapper,
+      (arg("scores"), arg("settings")));
 
  
   class_<mol::alg::PDBize>("PDBize",
diff --git a/modules/mol/alg/src/lddt.cc b/modules/mol/alg/src/lddt.cc
index 357e766906e7ad97151830c9ec7eb926b50199af..7c8079d567b23a587426950c5bc27991e78e18a6 100644
--- a/modules/mol/alg/src/lddt.cc
+++ b/modules/mol/alg/src/lddt.cc
@@ -340,7 +340,9 @@ int main (int argc, char **argv)
     Real lddt = LocalDistDiffTest(model_view, ref_list, glob_dist_list, settings);
 
     // prints the residue-by-residue statistics
-    PrintlDDTPerResidueStats(model, glob_dist_list, settings);
+    std::vector<lDDTLocalScore> local_scores;
+    local_scores = GetlDDTPerResidueStats(model, glob_dist_list, settings);
+    PrintlDDTPerResidueStats(local_scores, settings);
   }
   return 0;
 }
diff --git a/modules/mol/alg/src/local_dist_diff_test.cc b/modules/mol/alg/src/local_dist_diff_test.cc
index a019251b96492d54585a3c0fa81055d8fe15ac3b..9c988d1005c1ca2614a48fbf74e7258a07caf135 100644
--- a/modules/mol/alg/src/local_dist_diff_test.cc
+++ b/modules/mol/alg/src/local_dist_diff_test.cc
@@ -477,6 +477,55 @@ void lDDTSettings::PrintParameters() {
   std::cout << ToString();
 }
 
+// Default constructor is neccessary for boost exposure
+lDDTLocalScore::lDDTLocalScore(): cname(""),
+                                  rname(""),
+                                  rnum(-1),
+                                  is_assessed(""),
+                                  quality_problems(""),
+                                  local_lddt(-1.0),
+                                  conserved_dist(-1),
+                                  total_dist(-1) {}
+
+lDDTLocalScore::lDDTLocalScore(String init_cname,
+                               String init_rname,
+                               int init_rnum,
+                               String init_is_assessed,
+                               String init_quality_problems,
+                               Real init_local_lddt,
+                               int init_conserved_dist,
+                               int init_total_dist): 
+                                       cname(init_cname),
+                                       rname(init_rname),
+                                       rnum(init_rnum),
+                                       is_assessed(init_is_assessed),
+                                       quality_problems(init_quality_problems),
+                                       local_lddt(init_local_lddt),
+                                       conserved_dist(init_conserved_dist),
+                                       total_dist(init_total_dist) {}
+
+String lDDTLocalScore::ToString(bool structural_checks) const {
+  std::stringstream stkeylddt;
+  std::stringstream outstr;
+  stkeylddt << "(" << conserved_dist << "/" << total_dist << ")";
+  String dist_string = stkeylddt.str();
+  if (structural_checks) {
+    outstr << cname << "\t" << rname << "\t" << rnum << '\t' << is_assessed  << '\t' << quality_problems << '\t' << local_lddt << "\t" << dist_string;
+  } else {
+    outstr << cname << "\t" << rname << "\t" << rnum << '\t' << is_assessed  << '\t' << local_lddt << "\t" << dist_string;
+  }
+  return outstr.str();
+}
+
+String lDDTLocalScore::GetHeader(bool structural_checks, int cutoffs_length) {
+  std::stringstream outstr;
+  if (structural_checks) {
+    outstr << "Chain\tResName\tResNum\tAsses.\tQ.Prob.\tScore\t(Conserved/Total, over " << cutoffs_length << " thresholds)";
+  } else {
+    outstr << "Chain\tResName\tResNum\tAsses.\tScore\t(Conserved/Total, over " << cutoffs_length << " thresholds)";
+  }
+  return outstr.str();
+}
 
 GlobalRDMap CreateDistanceList(const EntityView& ref,Real max_dist)
 {
@@ -782,36 +831,28 @@ void CheckStructure(EntityView& ent,
   std::cout << "Distances shorter than tolerance are on average shorter by: " << std::fixed << std::setprecision(5) << clash_info.GetAverageOffset() << std::endl;
 }
 
-void PrintlDDTPerResidueStats(EntityHandle& model, GlobalRDMap& glob_dist_list, lDDTSettings& settings){
+std::vector<lDDTLocalScore> GetlDDTPerResidueStats(EntityHandle& model, GlobalRDMap& glob_dist_list, lDDTSettings& settings){
+  std::vector<lDDTLocalScore> scores;
   EntityView outv = model.GetChainList()[0].Select("peptide=true");
-  if (settings.structural_checks) {
-    std::cout << "Local LDDT Scores:" << std::endl;
-    std::cout << "(A 'Yes' in the 'Quality Problems' column stands for problems" << std::endl;
-    std::cout << "in the side-chain of a residue, while a 'Yes+' for problems" << std::endl;
-    std::cout << "in the backbone)" << std::endl;
-  } else {
-    std::cout << "Local LDDT Scores:" << std::endl;
-  }
-  if (settings.structural_checks) {
-    std::cout << "Chain\tResName\tResNum\tAsses.\tQ.Prob.\tScore\t(Conserved/Total, over " << settings.cutoffs.size() << " thresholds)" << std::endl;
-  } else {
-    std::cout << "Chain\tResName\tResNum\tAsses.\tScore\t(Conserved/Total, over " << settings.cutoffs.size() << " thresholds)" << std::endl;
-  }
   for (ChainViewList::const_iterator ci = outv.GetChainList().begin(),
        ce = outv.GetChainList().end(); ci != ce; ++ci) {
     for (ResidueViewList::const_iterator rit = ci->GetResidueList().begin(),
          re = ci->GetResidueList().end(); rit != re; ++rit) {
-   
+
       ResidueView ritv=*rit;
       ResNum rnum = ritv.GetNumber();
       bool assessed = false;
       String assessed_string="No";
-      String quality_problems_string="No";
+      String quality_problems_string;
+      if (settings.structural_checks) {
+        quality_problems_string="No";
+      } else {
+        quality_problems_string="NA";
+      }
       Real lddt_local = -1;
       String lddt_local_string="-";
       int conserved_dist = -1;
       int total_dist = -1;
-      String dist_string = "-";
       if (IsResnumInGlobalRDMap(rnum,glob_dist_list)) {
         assessed = true;
         assessed_string="Yes";
@@ -833,25 +874,43 @@ void PrintlDDTPerResidueStats(EntityHandle& model, GlobalRDMap& glob_dist_list,
           lddt_local_string=stkeylddt.str();
           conserved_dist=ritv.GetIntProp(settings.label+"_conserved");
           total_dist=ritv.GetIntProp(settings.label+"_total");
-          std::stringstream stkeydist;
-          stkeydist << "("<< conserved_dist << "/" << total_dist << ")";
-          dist_string=stkeydist.str();
         } else {
           std::cout << settings.label << std::endl;
           lddt_local = 0;
           lddt_local_string="0.0000";
           conserved_dist = 0;
           total_dist = 0;
-          dist_string="(0/0)";
         }
       }
-      if (settings.structural_checks) {
-        std::cout << ritv.GetChain() << "\t" << ritv.GetName() << "\t" << ritv.GetNumber() << '\t' << assessed_string  << '\t' << quality_problems_string << '\t' << lddt_local_string << "\t" << dist_string << std::endl;
-      } else {
-        std::cout << ritv.GetChain() << "\t" << ritv.GetName() << "\t" << ritv.GetNumber() << '\t' << assessed_string  << '\t' << lddt_local_string << "\t" << dist_string << std::endl;
-      }
+      // std::tuple<String, String, int, String, String, Real, int, int>
+      lDDTLocalScore row(ritv.GetChain().GetName(),
+                         ritv.GetName(),
+                         ritv.GetNumber().GetNum(),
+                         assessed_string,
+                         quality_problems_string,
+                         lddt_local,
+                         conserved_dist,
+                         total_dist);
+      scores.push_back(row);
     }
   }
+
+  return scores;
+}
+
+void PrintlDDTPerResidueStats(std::vector<lDDTLocalScore>& scores, lDDTSettings& settings){
+  if (settings.structural_checks) {
+    std::cout << "Local LDDT Scores:" << std::endl;
+    std::cout << "(A 'Yes' in the 'Quality Problems' column stands for problems" << std::endl;
+    std::cout << "in the side-chain of a residue, while a 'Yes+' for problems" << std::endl;
+    std::cout << "in the backbone)" << std::endl;
+  } else {
+    std::cout << "Local LDDT Scores:" << std::endl;
+  }
+  std::cout << lDDTLocalScore::GetHeader(settings.structural_checks, settings.cutoffs.size()) << std::endl;
+  for (std::vector<lDDTLocalScore>::const_iterator sit = scores.begin(); sit != scores.end(); ++sit) {
+    std::cout << sit->ToString(settings.structural_checks) << std::endl;
+  }
   std::cout << std::endl;
 }
 
diff --git a/modules/mol/alg/src/local_dist_diff_test.hh b/modules/mol/alg/src/local_dist_diff_test.hh
index f44d972a22fbc1398232926ed9ec6329b14c08b3..21aee5a1d7a035ae21450b05c84212bc103a1b9d 100644
--- a/modules/mol/alg/src/local_dist_diff_test.hh
+++ b/modules/mol/alg/src/local_dist_diff_test.hh
@@ -54,6 +54,32 @@ struct lDDTSettings {
   std::string ToString();
 };
 
+struct lDDTLocalScore {
+  String cname;
+  String rname;
+  int rnum;
+  String is_assessed;
+  String quality_problems;
+  Real local_lddt;
+  int conserved_dist;
+  int total_dist;
+
+  lDDTLocalScore();
+
+  lDDTLocalScore(String init_cname,
+                 String init_rname,
+                 int init_rnum,
+                 String init_is_assessed,
+                 String init_quality_problems,
+                 Real init_local_lddt,
+                 int init_conserved_dist,
+                 int init_total_dist);
+
+  String ToString(bool structural_checks) const;
+
+  static String GetHeader(bool structural_checks, int cutoffs_length);
+};
+
 std::pair<int,int> DLLEXPORT_OST_MOL_ALG ComputeCoverage(const EntityView& v,const GlobalRDMap& glob_dist_list);
 
 bool DLLEXPORT_OST_MOL_ALG IsResnumInGlobalRDMap(const ResNum& resnum, const GlobalRDMap& glob_dist_list);
@@ -188,9 +214,12 @@ void DLLEXPORT_OST_MOL_ALG CheckStructure(EntityView& ent,
                                           Real bond_tolerance,
                                           Real angle_tolerance);
 
-void PrintlDDTPerResidueStats(EntityHandle& model,
-                              GlobalRDMap& glob_dist_list,
-                              lDDTSettings& settings);
+std::vector<lDDTLocalScore> DLLEXPORT_OST_MOL_ALG GetlDDTPerResidueStats(EntityHandle& model,
+                                              GlobalRDMap& glob_dist_list,
+                                              lDDTSettings& settings);
+
+void DLLEXPORT_OST_MOL_ALG PrintlDDTPerResidueStats(std::vector<lDDTLocalScore>& scores,
+                                                    lDDTSettings& settings);
 
 }}}